one way
determine your deltas dx, dy and what their signs are
decide which has the larger magnitude
develope an index using the signs and which has the larger magnitude
ie three bits two for signs and one for x or y having the larger magnitude
that will define the octant you're moving in and can be used to look up increments
you always move in the direction with the larger magnitude
you'll keep an error accumulator, ea which gets intialized to the greater magnitude
say dy is the greater and dx is the lesser
you'd intialize the ea to dy
take a step in the y direction and subtract dx from the ea
if the ea goes through zero ie if ea is greater after you subtract
you've accumulated y worth of x's and it's time to take a step in x and add dy back into the ea
here's some batari basic code and an excerpt from the asm code it produces
in bB
f{0} = 0
sets bit 0 in variable f to 0
edit: var36 =f is some cruft, ignore it
Code:
move
temp1 = ea
if f{0} then skip
player0y = player0y + yinc[f]
ea = ea - dx
if temp1 < ea then ea = ea + dy : player0x = player0x + xinc[f]
return
skip
player0x = player0x + xinc[f]
ea = ea - dy
if temp1 < ea then ea = ea + dx : player0y = player0y + yinc[f]
return
setup_move
if x0 < x1 then f{2} = 1 : dx = x1 - x0 else f{2} = 0 : dx = x0 - x1
if y0 < y1 then f{1} = 1 : dy = y1 - y0 else f{1} = 0 : dy = y0 - y1
if dx > dy then f{0} = 1 : ea = dx else f{0} = 0 : ea = dy
var36 = f
return
data yinc
$FF, $FF, $01, $01, $FF, $FF,$01, $01
end
data xinc
$FF, $FF, $FF, $FF, $01, $01, $01, $01
end
.move
; move
.L08 ; temp1 = ea
LDA ea
STA temp1
.
;
.L09 ; if f{0} then skip
LDA f
LSR
bcs .skip
.L010 ; player0y = player0y + yinc[f]
LDA player0y
LDX f
CLC
ADC yinc,x
STA player0y
.L011 ; ea = ea - dx
LDA ea
SEC
SBC dx
STA ea
.L012 ; if temp1 < ea then ea = ea + dy : player0x = player0x + xinc[f]
LDA temp1
CMP ea
BCS .skipL012
.condpart0
LDA ea
CLC
ADC dy
STA ea
LDA player0x
LDX f
CLC
ADC xinc,x
STA player0x
.skipL012
.L013 ; return
RTS
.skip
; skip
.L014 ; player0x = player0x + xinc[f]
LDA player0x
LDX f
CLC
ADC xinc,x
STA player0x
.L015 ; ea = ea - dy
LDA ea
SEC
SBC dy
STA ea
.L016 ; if temp1 < ea then ea = ea + dx : player0y = player0y + yinc[f]
LDA temp1
CMP ea
BCS .skipL016
.condpart1
LDA ea
CLC
ADC dx
STA ea
LDA player0y
LDX f
CLC
ADC yinc,x
STA player0y
.skipL016
.L017 ; return
RTS
.
;
.
;
.
;
.setup_move
; setup_move
.L018 ; if x0 < x1 then f{2} = 1 : dx = x1 - x0 else f{2} = 0 : dx = x0 - x1
LDA x0
CMP x1
BCS .skipL018
.condpart2
LDA f
ORA #4
STA f
LDA x1
SEC
SBC x0
STA dx
jmp .skipelse0
.skipL018
LDA f
AND #251
STA f
LDA x0
SEC
SBC x1
STA dx
.skipelse0
.L019 ; if y0 < y1 then f{1} = 1 : dy = y1 - y0 else f{1} = 0 : dy = y0 - y1
LDA y0
CMP y1
BCS .skipL019
.condpart3
LDA f
ORA #2
STA f
LDA y1
SEC
SBC y0
STA dy
jmp .skipelse1
.skipL019
LDA f
AND #253
STA f
LDA y0
SEC
SBC y1
STA dy
.skipelse1
.
;
.L020 ; if dx > dy then f{0} = 1 : ea = dx else f{0} = 0 : ea = dy
LDA dy
CMP dx
BCS .skipL020
.condpart4
LDA f
ORA #1
STA f
LDA dx
STA ea
jmp .skipelse2
.skipL020
LDA f
AND #254
STA f
LDA dy
STA ea
.skipelse2
.L021 ; var36 = f
LDA f
STA var36
.L022 ; return
RTS
.
;
.L023 ; data yinc
yinc
.byte $FF, $FF, $01, $01, $FF, $FF,$01, $01
.skipL023
.
;
.L024 ; data xinc
xinc
.byte $FF, $FF, $FF, $FF, $01, $01, $01, $01
.skipL024
.
;