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)