[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]

{ ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
  º °°Proc°°°°°°°°°°°°°°°° PutPic °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° º
  ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ}
Procedure PutPic(X: Word;Y:Byte;VAR sprt;W,H:Byte;Where:Word); ASSEMBLER;
  {W=Width of sprite, H=Height Sprt=an array of pixels}
  { This puts an sprite, EXCEPT it's color 0 (black) pixels, onto the screen
    "where"(VAddr1/VGA etc.), at position X,Y }
label
  _Redraw, _DrawLoop, _Exit, _LineLoop, _NextLine, _Ignore;

asm
    push  ds     { Save DS for later }
    and   bl, 0
    mov   es, where   {Move segment address of Where into ES:DI's segment}
    lds   si, Sprt    { loads the address of Sprt into DS:SI }
    mov   di, x       { Move x location into DI }

    {Work out (y*320)+x}
    mov   bh, y       { bx = y*256 }
    mov   ax, bx      { make another copy of y in ax}
    shr   ax, 2       { y2 = y2 * 64}
    add   bx, ax      { Work out y location : y = y1+y2 (y=y*320) }
    add   di, bx      { finalise location  (Y*320)+X }

    mov   ah, H       { ah = Height of sprite }
    cld               {Clear direction flag (DI inc's)}
    and   ch, 0
    mov   al, W       {Move in width }
    {Register usage:
           AX = HHWW
           BX = Comparison of byte
           CX = Across counter
           DX = 'Pushed' DI}
_DrawLoop:
    mov   dx,di        { Store offset for later }
    mov   cl,al       { move width into CX }
_LineLoop:
    mov   bl,byte ptr [si]
    or    bl,bl       { checks if zero }
    jz    _Ignore     {if Color=0 then ignore it}
    movsb
    loop   _LineLoop   {Repeat CX times (Repeat for the width of sprite)}
    jmp    _NextLine   {Then go on to next line}

_Ignore:
    inc    si          {DS:SI = Sprite Array (inc SI = Next pixel)}
    inc    di          {Inc Mem locs ES:DI = incr. target location}
    loop  _LineLoop    {Continues reading the line}

_NextLine:
    mov   di,dx        {Restore x/y Vid.mem loc.}
    dec   ah           {Decrease height (Move down a line)}
    jz    _Exit        {If Height=0(Reached end of sprite) then exit }
    add   di,140h      {else : di = Move to next line in Vid.Mem }
    jmp   _DrawLoop    {Jump back to the draw loop}

_Exit:
    pop   ds     { Restore DS }
end;


[Back to GRAPHICS SWAG index]  [Back to Main SWAG index]  [Original]