#17437 - Gordon - Mon Mar 08, 2004 5:14 am
Need a ASM Draw Horizontal Line function in Mode3
Miked0801 wrote: |
Need a poly filler next? |
Code: |
@******************************* @* GBA Graphics Library * @* by Jeff Frohwein * @* http://www.devrs.com * @******************************* @ v1.0223 - Original release @ v1.0225 - Speeded up angular line draw with optimization @ suggestion from Dennis Ranke (exoticorn/icebird) @ v1.0315 - No longer saving r14 on stack since not required. @ @ This version, on average, has the same rendering speed @ as line3.s but it has the accuracy of line2.s. @ Even length horizontal lines are now almost twice as fast. @ It is now the preferred code. @ Vertical lines - 3 instrs/pixel @ Horizontal lines - 3 instr/2 pixels @ Angular lines - 6 instrs/pixel @ Draw a solid line in GBA graphics modes 3/5 in ARM asm @ Entry: x1 = pixel x1 coordinate @ y1 = pixel y1 coordinate @ x2 = pixel x2 coordinate @ y2 = pixel y2 coordinate @ color = pixel color @ addr = screen base address @ (void) gfxLine (u8 x1, u8 y1, u8 x2, u8 y2, u16 color, u32 addr); .ARM .ALIGN .GLOBL gfxLine @ r0 = x1 @ r1 = y1 @ r2 = x2 / pixel color @ r3 = y2 / pixel address @ r4 = temp / de @ r5 = deldx @ r6 = deldy @ r7 = dy / @ r8 = total pixel count @ r9 = delsx @ r10 = delsy @ r11 = delse @ r12 = delde gfxLine: sub sp,sp,#8 @ protect the stack so color @ doesn't get overwritten. cmp r1,r3 @ Is the line horizontal ? beq _2 @ yes cmp r0,r2 @ Is the line vertical ? beq _8 @ yes stmfd r13!,{r0-r12} mov r5,#2 @ deldx mov r6,#480 @ deldy subs r7,r3,r1 @ delp = y2 - y1 rsbmi r6,r6,#0 @ di=-1 if r7 is negative rsbmi r7,r7,#0 @ make r7 positive mov r10,r6 @ delsy subs r8,r2,r0 @ r8 = x2 - x1 rsbmi r5,r5,#0 @ di=-1 if r8 is negative rsbmi r8,r8,#0 @ make r8 positive mov r9,r5 @ delsx subs r4,r8,r7 movmi r4,r8,lsl #0 @ exchange r7 & r8 if r8 is smaller movmi r8,r7,lsl #0 movmi r7,r4,lsl #0 movmi r9,#0 movpl r10,#0 movmi r6,#0 @@@@ to support new angular line loop movpl r5,#0 @@@@ to support new angular line loop mov r11,r7,lsl #1 @ delse = delp * 2 sub r4,r11,r8 @ de = delse - dels sub r12,r4,r8 @ delde = delse - (dels * 2) sub r4,r12,r8 @ error = delse - (dels * 3) sub r12,r12,r11 @@@@ to support new angular line loop add r8,r8,#1 @ r8 = total pixel count ldr r2,[r13,#60] @ r2 = color off stack add r9,r9,r10 @ r9 = straight pixel move add r5,r5,r6 @ r5 = diagonal pixel move ldr r6,[r13,#64] @ Get the screen base address @ calculate pixel address mov r3,#480 mul r7,r3,r1 add r7,r7,r0,lsl #1 add r3,r7,r6 @ r3 = start pixel addr _0: strh r2,[r3],r9 @ store pixel and move straight adds r4,r4,r11 @ update error value addpl r4,r4,r12 @ update again if error positive addpl r3,r3,r5 @ move diagonal if error positive subs r8,r8,#1 @ dec counter bne _0 ldmfd r13!,{r0-r12} add sp,sp,#8 bx lr @ ******** Draw a horizontal line ******** _2: stmfd r13!,{r2-r8} mov r5,r0 mov r6,r1 subs r4,r2,r0 rsbmi r4,r4,#0 @ make r4 positive movmi r5,r2 movmi r6,r3 @ make r5,r6 left most point add r4,r4,#1 @ r4 = pixel count ldr r2,[r13,#36] @ Get the color off stack ldr r8,[r13,#40] @ Get the screen base address @ calculate pixel address mov r3,#480 mul r7,r3,r6 add r7,r7,r5,lsl #1 add r3,r7,r8 mov r6,#4 add r2,r2,r2,lsl #16 mov r5,r4 tsts r3,#2 @ Is the start position 4 byte aligned? bne _5 @ no @ 4 byte aligned movs r4,r4,lsr #1 @ Is there only 1 pixel? beq _h1p @ yes, exit @ Plot pixel [r3] with color r2 _3: str r2,[r3],r6 subs r4,r4,#1 bne _3 tsts r5,#1 @ Is there an even number of pixels? beq _4 @ yes _h1p: strh r2,[r3] @ plot one pixel _4: ldmfd r13!,{r2-r8} add sp,sp,#8 bx lr @ not 4 byte aligned _5: strh r2,[r3],#2 @ plot first pixel movs r4,r4,lsr #1 @ Is there only 1 pixel? beq _7 @ yes, exit cmps r5,#2 @ Is there 2 pixels? beq _h2p @ yes @ Plot pixel [r3] with color r2 _6: str r2,[r3],r6 subs r4,r4,#1 bne _6 tsts r5,#1 @ Is there an odd number of pixels? bne _7 @ yes _h2p: strh r2,[r3] @ plot one pixel _7: ldmfd r13!,{r2-r8} add sp,sp,#8 bx lr @ ******** Draw a vertical line ******** _8: stmfd r13!,{r2-r8} mov r5,r0 mov r6,r1 subs r4,r3,r1 rsbmi r4,r4,#0 @ make r4 positive movmi r5,r2 movmi r6,r3 @ make r5,r6 top most point add r4,r4,#1 @ r4 = pixel count ldr r2,[r13,#36] @ Get the color off stack ldr r8,[r13,#40] @ Get the screen base address @ calculate pixel address mov r3,#480 mul r7,r3,r6 add r7,r7,r5,lsl #1 add r3,r7,r8 mov r5,#480 @ Plot pixel [r3] with color r2 _9: strh r2,[r3],r5 subs r4,r4,#1 bne _9 ldmfd r13!,{r2-r8} add sp,sp,#8 bx lr @ r0 = line length @ send bit 7 of r0 to c flag @ stmcsia r1!,{r2-r9} <- do 8 times @ send bit 6 of r0 to c flag @ stmcsia r1!,{r2-r9} <- do 4 times @ send bit 5 of r0 to c flag @ stmcsia r1!,{r2-r9} <- do 2 times @ ... @ send bit 0 of r0 to c flag @ strcsh r2,{r1},#2 |
Code: |
@ ******** Draw a vertical line ********
_8: stmfd r13!,{r2-r3} @ r0=r2=X1=X2, r1=Y1, r3=Y2 subs r2,r3,r1 @ r2=height rsbmi r2,r2,#0 @ make r2 positive movmi r1,r3 @ make r1 top most Y value @ calculate pixel address rsb r1,r1,r1,lsl #4 @ r1=Y*15 add r0,r0,r1,lsl #4 @ r0=Y*240 + X ldr r1,[r13,#20] @ Get the screen base address (changes depending on stack pointer) add r0,r1,r0,lsl #1 @ r0=Y*480 + X*2 + base ldr r1,[r13,#16] @ Get the color off stack (changes depending on stack pointer) mov r3,#480 @ bytes per row @ Plot pixel [r0] with color r4 _9: strh r1,[r0],r3 subs r2,r2,#1 bpl _9 @ instead of bne so a lenght of 0 doesn't screw up the loop ldmfd r13!,{r2-r3} add sp,sp,#8 bx lr |