Ack Egad Newbie needs help with his line drawing algorithm
From: Frogbert (frogbert_at_host.sk)
Date: 05/19/04
- Next message: AlirezA: "Far jump"
- Previous message: michael: "Re: How do you do inline assembly with vector types in GCC?"
- Next in thread: Matt Taylor: "Re: Ack Egad Newbie needs help with his line drawing algorithm"
- Reply: Matt Taylor: "Re: Ack Egad Newbie needs help with his line drawing algorithm"
- Reply: pete_at_nospam.demon.co.uk: "Re: Ack Egad Newbie needs help with his line drawing algorithm"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 19 May 2004 17:38:56 +0000 (UTC)
I'm trying to write my first assembly program (well first of any
value) for my comp arch and assembler course. Basicaly my program
accepts 2 lots of x,y coodinates and then draws a line between them. I
have the input stages all correct however I can't seem to get my line
drawing algorithm to work correctly. I am porting the algorithm found
here: http://www.gamedev.net/reference/articles/article1275.asp and as
far as I can see I've done it correctly but that is not the case. I
was hopeing a fresh pair of eyes might be able to spot a logic error.
;-------------------------------------------------------------------------------------------
;DrawLine calculates the steps inbetween and then draws a line on the
screen
;-------------------------------------------------------------------------------------------
DrawLine PROC X1:word, Y1:word, X2:word, Y2:word ;Calculates and draws
a line on the screen
LOCAL deltaX:word ;Distance between the x points
LOCAL deltaY:word ;Distanve between the y points
LOCAL X:word ;X counter, starts at the first x point
LOCAL Y:word ;Y counter, starts at the first y point
LOCAL xIncrement1:word ;Two X increment variables are needed
LOCAL xIncrement2:word
LOCAL yIncrement1:word ;as are two Y increment variables
LOCAL yIncrement2:word
LOCAL den:word ;denominator
LOCAL num:word ;numerator
LOCAL numadd:word ;number add
LOCAL numPixels:word ;number of pixels
mov ax, X1 ;start off at X1
mov X, ax
mov ax, Y1 ;and start off at Y1
mov Y, ax
mov ax, X2 ;
sub ax, X1 ;
call ABS ;
mov deltaX, ax ; deltaX = abs(x2-x1)
mov ax, Y2 ;
sub ax, Y1 ;
call ABS ;
mov deltaY, ax ; deltaY = abs(y2-y1)
mov ax, X2 ;put X2 into eax register to test
cmp ax, X1 ;test to see if x values are increasing
jge xIncreasing ;if they are jump to xIncreasing
mov xIncrement1, -1 ;else x is decreasing
mov xIncrement2, -1
jmp testY ;jump to testY
xIncreasing:
mov xIncrement1, 1 ;X is increasing
mov xIncrement2, 1
testY:
mov ax, Y2
cmp ax, Y1 ;test to see if y values are increasing
jge yIncreasing ;if they are jump to yIncreasing
mov yIncrement1, 1 ;else
mov yIncrement2, 1
jmp testRatio ;jump to the test ratio part
yIncreasing:
mov yIncrement1, -1 ;Y is increasing
mov yIncrement2, -1
testRatio: ;Tests the ratio of x to y pixels
mov ax, deltaX
cmp ax, deltaY ;if deltaX >= deltaY
jge oneXforEveryY
;else
mov bx, 0
mov xIncrement1, bx
mov yIncrement2, bx
mov ax, deltaX
mov den, ax ;denominator = deltaX
shr ax, 1 ;divide deltaX by 2
mov num, ax ;and make it the numerator
mov ax, deltaY
mov numadd, ax ; numAdd = deltaY
mov ax, deltaX
mov numPixels, ax ; numPixles = deltaX
jmp drawPixels
oneXforEveryY:
mov ebx, 0
mov xIncrement2, bx
mov yIncrement1, bx
mov ax, deltaY
mov den, ax ;denominator = deltaY
shr ax, 1 ;divide deltaY by 2
mov num, ax ;and make it the numerator
mov ax, deltaX
mov numadd, ax ; numAdd = deltaX
mov ax, deltaY
mov numPixels, ax ; numPixles = deltaY
drawPixels:
mov cx, numPixels
mov ah,0Fh ; Save the current video mode
int 10h
mov saveMode,al
mov ah,0 ; Switch to a graphics mode
mov al,0Dh ; set video mode
int 10h
drawLoop:
INVOKE putPixel, X, Y ;draw pixel at x, y
mov ax, num ;increase the numerator by the top of the fraction
add ax, numadd ;add numadd to the numerator
mov num, ax ;put it back into numerator
cmp ax, den ;compare to the denominator to check if the numerator is
greater
jl changeValues ;change values
sub ax, den
mov num, ax ;numerator = numerator - denominator
mov ax, X
add ax, xIncrement1 ; increment x
mov X, ax
mov ax, Y
add ax, yIncrement1 ; increment y
mov Y, ax
changeValues:
mov ax, X
add ax, xIncrement2
mov X, ax
mov ax, Y
add ax, yIncrement2 ; increment y
mov Y, ax
loop drawLoop
mov ah,0 ;wait for a key to be pressed
int 16h
ret
DrawLine ENDP
;-------------------------------------------------------------------------------------------
;ABS calcuates the absolute value of ax
;-------------------------------------------------------------------------------------------
ABS PROC
cmp ax, 0 ;compare to zero
jge ABS_end ;if the numbers positive return
neg ax ;else times by -1 to make positive
ABS_end:
ret ;ta-da absolute value!
ABS ENDP
;-------------------------------------------------------------------------------------------
;putPixel places a pixel on the screen given two coodinates x and y
;-------------------------------------------------------------------------------------------
putPixel PROC uses cx dx, x:WORD, y:WORD ;draws a pixel to the
screen
mov ah, 0Ch ;select draw a pixel function
mov al, 2 ;colour of pixel
mov bh, 0 ;video page 0
mov cx, x ;x coords
mov dx, y ;y coords
int 10h ;draw it
ret
putPixel ENDP
Mind the comments they are a little outdated due to my tinkering (I've
converted the thing from using 32 bit registers to 16 for example so
all these references to eax mean ax).
Anyway thankyou in advance for any tips and hints, and please keep the
mocking of the slow code to a dull roar ;)
- Next message: AlirezA: "Far jump"
- Previous message: michael: "Re: How do you do inline assembly with vector types in GCC?"
- Next in thread: Matt Taylor: "Re: Ack Egad Newbie needs help with his line drawing algorithm"
- Reply: Matt Taylor: "Re: Ack Egad Newbie needs help with his line drawing algorithm"
- Reply: pete_at_nospam.demon.co.uk: "Re: Ack Egad Newbie needs help with his line drawing algorithm"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]