SCALE_BM.TXT


Message #44/119 in SWE: Algoritmer         [FIDO] [EchoMail]
Info   : #49 ->
From   : Johan Selbing    [POST 10-Aug-1993 13:14]
To     : All
Subject: Bresenham - Assembler

Jaha. Nu får vi hoppas att alla blir glada, för här kommer
Assembler-versionen av bitmap-skalad-olika-i-kanterna-rutinen.
Den kanske är lite svårläst, men jag hoppas att det ska vara optimerad
till max. (Inga onödiga uträkningar av skärmpositioner etc.)
Koden får användas i vilket program som helst, ingen copyright,
ingen registrering, ingenting! (Fast det vore ju kul om man nämndes
i "credits" iaf.) Jag kanske ska nämna att jag har tagit bort de flesta
variablerna, men de står kvar i kommentarerna för att koden ska bli
lite mer lättläst (det är inte så kul att hålla reda på massor av
register) Koden är DELVIS i TP och bitmappen ska lagras liggande och
har inga transparenta färger. Exemplet gäller för grafikläge
13h (320*200*256) och alla register utom DS förändras.
Och säg gärna till om ni kan optimera här och där... bla...bla...bla...

{KLIPP}
procedure DrawBitMap(x1,y1,x2,y2,h1:integer;image:bitmapptr); assembler;
var step:integer;
    deltax,deltay,saveoffs,ofstep:integer;
    { TX,TY,TH = räknare för att hålla reda på skalning }
    { W,H,H1 = bildens bredd och höjd (för tillfället samt i högerkant) }
    { STARTY = position där den vertikala remsan börjar }
    { STEP = Adderas till höjden, +1 eller -1
             beroende på vilken kant som är längst }
    { OFSTEP = Adderas till DI, +320 eller -320
               beroende på vilken kant som är längst }
    { DELTAX,DELTAY = skillnaden mellan koordinaterna }
    { SAVEOFFS = sparat offset i bitmappen }
    { AX används som temporär uträknare, färgminne(AL)}
    { BX används som omväxlande TY och TH }
    { CX används som räknare }
    { DX används som TX }
    { ES:DI är pekaren till bildminnet }
    { DS:SI är pekaren till bitmappen }

label narrow,widen,pixelcolumn,column,nocolumn,slant,noslant
      ,row,norow,pixelrow;
asm
      push ds

      lds si,image

      mov ax,$a000
      mov es,ax
      mov ax,y1
      mov cx,320
      mul cx
      add ax,x1        {Räkna ut startoffset på skärmen}
      mov di,ax

      mov dx,32        {tx:=64 div 2}

      mov bx,h1
      shr bx,1         {th:=h1 div 2}

      mov ax,x2
      sub ax,x1
      mov deltax,ax    {deltax:=x2-x1}

      mov cx,64        {64 stycken kolumner i bitmappen}

      mov ax,y1
      cmp ax,y2         {Jämför y-koordinater}
      jle narrow
widen:                  {Bitmappen vidgas med ökande x}
      mov step,1       {step:=1}
      mov ofstep,320   {ofstep:=320}
      mov ax,y1
      sub ax,y2
      mov deltay,ax    {deltay:=y1-y2}
      jmp pixelcolumn

narrow:                 {Bitmappen avsmalnar med ökande x}
      mov step,-1      {step:=-1}
      mov ofstep,-320  {ofstep:=-320}
      mov ax,y2
      sub ax,y1
      mov deltay,ax     {deltay:=y2-y1}

pixelcolumn:
      push cx

      sub dx,deltax    {tx:=tx-deltax}

      jg nocolumn
column:
      mov saveoffs,si   {Spara offset i bitmappen}

      add bx,deltay     {th:=th+deltay}
      cmp bx,deltax
      jna noslant
slant:
      mov ax,h1
      add ax,step
      add ax,step
      mov h1,ax         {inc(h1,step*2)}

      sub di,ofstep     {Öka eller minska vertikala skärmpositionen }

      sub bx,deltax     {th:=th-deltax}
      cmp bx,deltax
      ja slant

noslant:
      push di          {Spara adressstart av bitmappen}
      push bx          {I följande kod används BX som ty}

      mov bx,32        {ty:=32}
      mov cx,64        {64 stycken rader i bitmappen}

pixelrow:
      lodsb           {AL = pixelfärg att sätta ut}
      sub bx,h1        {ty:=ty-h1}
      jz row
      jns norow
row:
      stosb            {Sätt ut pixel}
      add di,319       {Ej 320! DI har ju avancerat ett steg redan.}
      add bx,64        {ty:=ty+64}

      jle row           {Om ty<=0 så rita mer}
norow:
      loop pixelrow

      pop bx
      pop di
      inc di           {Öka skärmpositionen med en pixel}

      mov si,saveoffs  {Ladda sparat offset i bitmappen}

      add dx,64        {tx:=tx+64}

      jle column       {Om tx<=0 så rita mer}

nocolumn:

      add si,64        {avancera en pixelkolumn framåt i bitmappen}

      pop cx
      dec cx

      jge pixelcolumn

      pop ds
end;
{KLIPP}

Och en sak till... Det finns inget stöd för skärm-klippning, så om
bitmappen blir för stor (större än skärmen alltså) kommer dess hörn att
dyka upp på de mest oväntade ställen. Men det är ju inte så svårt att
lägga in, eller hur? Nu vill jag se att någon gör en grov modell
över hur ett system för att vandra omkring i 3D-världen skulle kunna
se ut.

Mvh. Johan


 * Origin: ** Nordic BBS #1 ** 46-13-50524 (2:204/429)