View Single Post
Old 02 September 2011, 12:22   #17
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
I had a little time today so just for fun (and the chance to learn something new too ) I knocked up my own version of a software (ie. no blitter) Bresenham line draw routine:

Code:
.draw_line:         move.w              d1,d4
                    move.w              d3,d6
                    sub.w               d4,d6
                    beq.b               .horizontal
                    bpl.b               .drw_ln_upwards
                    exg.l               d1,d3
                    exg.l               d0,d2
                    neg.w               d6

.drw_ln_upwards:    move.w              d0,d4
                    move.w              d2,d5
                    sub.w               d4,d5
                    beq.b               .vertical
                    bpl.b               .inc_x
                    movea.w             #-1,a3
                    subq.w              #1,d2
                    neg.w               d5
                    bra.b               .chk_deltas
.inc_x:             movea.w             #1,a3
                    addq.w              #1,d2

.chk_deltas:        cmp.w               d5,d6
                    bls.b               .dx_larger

                    move.w              d5,d4
                    add.w               d5,d5
                    move.w              d5,d7
                    sub.w               d6,d7
                    sub.w               d6,d4
                    add.w               d4,d4
                    move.b              #1,d6
                    bra.b               .plot_line

.dx_larger:         add.w               d6,d6
                    move.w              d6,d7
                    sub.w               d5,d7
                    add.w               d5,d5
                    move.w              d6,d4
                    sub.w               d5,d4
                    move.w              d6,d5
                    move.b              #0,d6
                    bra.b               .plot_line

.horizontal:        movea.l             screentwo_ptr(a5),a0
                    add.w               d1,d1
                    adda.w              0(a1,d1.w),a0
                    cmp.w               d2,d0
                    blt.b               .lft_to_rt
                    exg.l               d0,d2
.lft_to_rt:         movea.l             a0,a1
                    move.w              d0,d4
                    add.w               d4,d4
                    add.w               d4,d4
                    adda.w              0(a2,d4.w),a1
                    move.w              2(a2,d4.w),d4
                    or.w                d4,(a1)
                    addq.w              #1,d0
                    cmp.w               d2,d0
                    ble.b               .lft_to_rt
                    rts

.vertical:          movea.l             screentwo_ptr(a5),a0
                    add.w               d0,d0
                    add.w               d0,d0
                    adda.w              0(a2,d0.w),a0
                    cmp.w               d3,d1
                    blt.b               .dwn_to_up
                    exg.l               d1,d3
.dwn_to_up:         movea.l             a0,a3
                    move.w              d1,d4
                    add.w               d4,d4
                    adda.w              0(a1,d4.w),a3
                    move.w              2(a2,d0.w),d4
                    or.w                d4,(a3)
                    addq.w              #1,d1
                    cmp.w               d3,d1
                    ble.b               .dwn_to_up
                    rts

.plot_line:         movea.l             screentwo_ptr(a5),a0
                    move.w              d1,a4
                    add.w               d1,d1
                    adda.w              0(a1,d1.w),a0
                    move.w              d0,a6
                    add.w               d0,d0
                    add.w               d0,d0
                    adda.w              0(a2,d0.w),a0
                    move.w              2(a2,d0.w),d0
                    or.w                d0,(a0)
                    move.w              a4,d1
                    move.w              a6,d0
                    tst.w               d7
                    bmi.b               .error_neg
                    add.w               a3,d0
                    addq.w              #1,d1
                    add.w               d4,d7
                    bra.b               .check_eol
.error_neg:         tst.b               d6
                    bne.b               .adjust_y
                    add.w               a3,d0
                    bra.b               .update_error
.adjust_y:          addq.w              #1,d1
.update_error:      add.w               d5,d7
.check_eol:         tst.b               d6
                    bne.b               .check_y_eol
                    cmp.w               d0,d2
                    bne.b               .plot_line
                    bra.b               .line_drawn
.check_y_eol:       cmp.w               d1,d3
                    bne.b               .plot_line
.line_drawn:        rts
This code seems bug free in that all the lines I tested got drawn correctly.

It draws a worst case line (one corner of the screen to the other) in 127 raster lines on 68000. Doesn't matter from which corner to which corner the line's drawn, the performance is about the same.

The shorter the line, the quicker it's drawn (obviously) and horizontal and vertical lines are drawn quicker still.

Anyone got any suggestions as to whether there're obvious ways for the speed of the above to be improved further?

EDIT: did some testing and used this routine to draw the lines for a spinning wireframe 3d cube. It works but is slooooooow, as would be expected in comparison to the blitter. Also, there must be a problem with the horizontal and vertical shortcut routines. Although they worked OK in my pre-testing, they didn't work OK in my test wireframe cube routine. If I commented out the checks for horizontal and vertical lines though the routine still drew those lines OK under the normal plot_line routine.

Last edited by pmc; 02 September 2011 at 15:44. Reason: Spotted a speedup myself :D
pmc is offline  
 
Page generated in 0.05255 seconds with 11 queries