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.

ASM > ASM Line Drawing Routine

#15106 - frag - Sat Jan 17, 2004 6:15 am

Does anyone have an implementation of Bresenham's line algorithm (or whatever) written in asm using Mode 4 pixels, handy? (really specific request... sorry. :) )

I'm starting to run into speed problems with a mode 4 vector program I'm working on. I have a starfield in the background of the vector graphics and I don't know if a dirty rectangle scheme would be efficient with such a setup.

I'm hoping someone out there has an asm line drawing routine they'd be willing to share so I can see if that will help with the speed.

If worse comes to worse I'll just drop the starfield and use dirty rectangles but I like my starfield ;) So I want to see what other options there are first.

Any help would be greatly appreciated!

Thanks,
Frag

#15110 - momo - Sat Jan 17, 2004 10:48 am

I have written a Bresenham-Routine for Goldroad, I thinks it was for mode-4 (Because, its easy to Change it). Look at my small Homepage :)

http://www.angelfire.com/droid/goldmomo/

(Press on the English Flag, for English (or notr if you can read german :) ))

#16870 - Gordon - Thu Feb 26, 2004 5:35 am

Code:
/////////////////////Line//////////////////////////
//An implementation of the Bresenham Line algorithm
void Line(int x1, int y1, int x2, int y2, u16 color)
{
   //Variables
   int i, deltax, deltay, numpixels;
   int d, dinc1, dinc2;
   int x, xinc1, xinc2;
   int y, yinc1, yinc2;

   //Calculate deltaX and deltaY
   deltax = abs(x2 - x1);
   deltay = abs(y2 - y1);

   //Init vars
   if(deltax >= deltay)
   {
      //If x is independent variable
      numpixels = deltax + 1;
      d = (2 * deltay) - deltax;
      dinc1 = deltay << 1;
      dinc2 = (deltay - deltax) << 1;
      xinc1 = 1;
      xinc2 = 1;
      yinc1 = 0;
      yinc2 = 1;
   }
   else
   {
      //If y is independant variable
      numpixels = deltay + 1;
      d = (2 * deltax) - deltay;
      dinc1 = deltax << 1;
      dinc2 = (deltax - deltay) << 1;
      xinc1 = 0;
      xinc2 = 1;
      yinc1 = 1;
      yinc2 = 1;
   }

   //Move the right direction
   if(x1 > x2)
   {
      xinc1 = -xinc1;
      xinc2 = -xinc2;
   }
   if(y1 > y2)
   {
      yinc1 = -yinc1;
      yinc2 = -yinc2;
   }

   x = x1;
   y = y1;

   //Draw the pixels
   for(i = 1; i < numpixels; i++)
   {
      PlotPixel(x, y, color);

      if(d < 0)
      {
         d = d + dinc1;
         x = x + xinc1;
         y = y + yinc1;
      }
      else
      {
         d = d + dinc2;
         x = x + xinc2;
         y = y + yinc2;
      }
   }
}
Quote:
Code downloaded from staringmonkey's Demo Readme
Saturday, September 08, 2001
staringmonkey@hotmail.com

#16872 - poslundc - Thu Feb 26, 2004 5:40 am

No offense, Gordon, but that's not exactly assembly code... ;)

Dan.

#16875 - torne - Thu Feb 26, 2004 6:33 am

So run it through gcc -O2 -S. *grin*

#17254 - batblaster - Fri Mar 05, 2004 2:45 am

I'm Sorry to disturb but the routine showed are only for mode 3 the plotpixel function did not work on mode 4 , mode 4 are addressed like (u16*) pointer but work on 8bit color go from 0 to 255 and you need to check if the point you want to plot are odd or even... I'm writing a good plot pixel for mode 4 but at the moment did not work...
_________________
Batblaster / 7 Raven Studios Co. Ltd
------------------------------------------

#17255 - batblaster - Fri Mar 05, 2004 2:50 am

This is an asm routine to plot pixel maded by MrMr[iCE]

i founded in a collection of sources enjoy and tell me if someone make a good modify... Work on 120 x 160


.SECTION .iwram, "ax", %progbits

.GLOBAL plotPixels
.THUMB_FUNC

plotPixels:
push {r1, r2, r4, r5, r6, r7}

adr r0, pixel_pool
ldmia r0!, {r2-r5} @@ r2 = screen array, r3 = loop count, r4 = vram, r5 = address mask

pixel_loop:
ldmia r2!, {r0, r1}

cmp r0, #120 @@ quick unsigned x/y range tests
bcs next_pixel
cmp r1, #160
bcs next_pixel

ldr r6, =xbase
ldr r7, [r6]
add r7, r0
lsl r1, #8
add r7, r1
lsr r1, #4
sub r7, r1
and r7, r5

ldrh r1, [r4, r7] @@ load pixel pair from vram
mov r6, #0xFF
lsr r0, #1 @@ use x to test for odd/even masks
mov r0, #13
bcc plot2

lsl r0, #8
and r1, r6
orr r1, r0
b draw_pixel

plot2:
lsl r6, #8
and r1, r6
orr r1, r0

draw_pixel:
strh r1, [r4, r7]

next_pixel:
sub r3, #1
bne pixel_loop

pop {r1, r2, r4, r5, r6, r7}
mov pc, lr

.POOL
.ALIGN

pixel_pool:
.word screen
.word 1000
.word 0x600A000
.word 0xFFFFFFFE
_________________
Batblaster / 7 Raven Studios Co. Ltd
------------------------------------------

#17261 - Large Metal Teeth - Fri Mar 05, 2004 4:51 am

That code would be a lot better in ARM assembly. In ARM mode you can use conditional instructions to get rid of all those branches except for maybe a loop branch.

-Teeth

#17270 - batblaster - Fri Mar 05, 2004 3:22 pm

Is not mine but if you have a better rotine post here for everyone...
_________________
Batblaster / 7 Raven Studios Co. Ltd
------------------------------------------

#17273 - poslundc - Fri Mar 05, 2004 3:34 pm

Large Metal Teeth wrote:
That code would be a lot better in ARM assembly. In ARM mode you can use conditional instructions to get rid of all those branches except for maybe a loop branch.


It would also take advantage of 32-bit loading from IWRAM (since that's the section it was put in.)

Dan.