gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Newbie question: drawline

#11179 - fingalscave - Sun Sep 28, 2003 11:19 am

Hello all :)

I'm a relative newbie both to C++ and gba programming, but I'm managing, kinda...

anyways I've hit a bit of an obstacle. I've written a drawline function which is giving me problems, here is the code:

Code:
int Line(int x1, int y1, int x2, int y2, int col)
{
   int dx, dy, dif, i, tx, ty;
   dx = x2 - x1;
   dy = y2 - y1;
   if(dx>dy)
   {
      dif = dx;
   }
   else
   {
      dif = dy;
   }
   for(i = 0; i < dif; i++)
   {
      tx = dx / dif * i + x1;
      ty = dy / dif * i + y1;
      Plotpixel(tx , ty, col);
   }
}


it works fine for lines which are horizontal, vertical, or 45-diagonal, but any other gives a horizontal or vertical (whichever is longest). I think it's something to do with tx and ty being ints, but I'm not sure what to do. can anyone help?

Cheers :)
_________________
How do you let someone know of your hotcakes are selling well?

#11183 - tepples - Sun Sep 28, 2003 3:44 pm

Google results should solve your problems: bresenham line algorithm
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#11191 - Lupin - Sun Sep 28, 2003 7:59 pm

The bresenham algo isn't the fastest though, I think on an gba you would probably go better using an DDA function with reciprocal table.

You just have to find out how many Y pixels you have to go when going left 1 x pixel, this is simply done by deltay / deltax (the divide is done by using an reciprocal table which you could keep at a size of like 300 entries) and then you just go from the left point x of the line to the right point x, add the value to the left points y value and if you did everything right (and I don't talk crap here) you'll end at the y value of the right point.

I would write such an function in asm (iwram) and you could use this reciprocal function (ARM ADS version, 512 entries):

reciproc space 2048 ;1kb reciproc table

EXPORT reciproc
EXPORT reciprocal
EXPORT initreciprocal

;;;;;;;;;;;;;;
;reciprocal r0

reciprocal
movs r0,r0
rsbmi r0,r0,#0
ldr r1,=0x1FF
and r0,r0,r1 ;AND 255
ldr r1,=reciproc
ldr r0,[r1,r0,lsl#2]
rsbmi r0,r0,#0
bx lr

;;;;;;;;;;;;;;;
;initreciprocal

initreciprocal
mov r2, #0
ldr r3, =reciproc
str r2,[r3,#0]

nextvalue
add r2,r2,#1
mov r0,#65536
mov r1,r2
swi 0x60000

ldr r3, =reciproc
str r0, [r3,r2,lsl#2]

ldr r1,=511
cmp r2,r1
blt nextvalue
bx lr

#11246 - fingalscave - Tue Sep 30, 2003 12:54 am

thank you :)

think I'll stick to c++ for now...
_________________
How do you let someone know of your hotcakes are selling well?