[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]
{
> Another problem is plotting sprites with "invisible" pixels. In other
> words, all pixels in the sprite are plotted except for ones with a color
> of 255 (I think I've heard that Origin used this method in Ultima 6).
> Because of my unsuccessful try with asm earlier, I didn't even bother to
> try this in asm. Unfortunately, the following is MUCH too slow:
try this!
}
uses crt;
type SpriteType = array[0..15,0..15] of byte;
var sprite : spritetype;
f : file of spritetype; {sprite's image is stored in file}
x, y : word;
procedure putinvspriteinasm(x, y : word; sprite : spritetype);
var p : pointer;
segm, offs : word;
{these are used to calculate destination address
in video memory}
begin
p := addr(sprite[0,0]);
{this pointer is used only to cheat tp. tp doesn't allow to use addr or
@ operators in inline asm - or i don't know how to do it}
segm := $a000 + (320 * y) div 16;
offs := x;
{segm:offs is address of upper left corner of sprite in video RAM}
asm
push ds
{ds is one of the important registers in tp and must be saved}
lds si, p
{ds:si now is source address for sprite's array}
mov es, segm
mov di, offs
{es:di now is target address in VRAM}
mov bh, 16
{counter for outer loop}
@loop2: mov bl, 16
@loop1: mov al, [ds:si]
{innner loop (marked with label @loop1) is used to draw each line of
sprite}
cmp al, $ff
{make sure if pixel is $ff or not}
je @skip
{it is - so we don't draw it}
mov [es:di], al
{no, it's not - draw!}
@skip: inc si
inc di
dec bl
jnz @loop1
{we haven't finished to draw this line if bl > 0}
dec bh
{we haven't finished to draw all image if bh > 0}
jz @end
add di, 320 - 16
{calculate beginning of next line}
jmp @loop2
@end:
pop ds
end
end;
begin
asm mov ax, 0013h
int 10h
end;
assign(f, 'sprite');
reset(f);
read(f, sprite);
close(f);
randomize;
repeat
x := random(320);
y := random(200);
putinvspriteinasm(x, y, sprite);
until keypressed;
end.
{
i added into code some quick'n'dirty comments to let you understand
how assembly works. i've tested this code and found that it won't work with
Microsoft's workgrp.sys driver - the programm simply crashes when you press a
key. (workgrp.sys driver is one of the Windows for Workgroups drivers).
strange... with all other things (qemm386, lan drivers etc.) programm seems to
work fine. one more thing i must add that better is to pass to procedure
putsprite not array with sprite's data but only pointer to it - because tp
moves all this data around memory - and in this case it's 256 bytes.
}
[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]