Last active
July 2, 2017 11:53
-
-
Save BalorPrice/37d98504ec3792c9eca76cbcd6235854 to your computer and use it in GitHub Desktop.
Rotational coords test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; MATHS ROUTINES | |
;-------------------------------------------- | |
math.multDEBC: | |
; Input: DE = Multiplier, BC = Multiplicand | |
; Output: DE:HL = Product | |
; By Baze of 3SC. http://map.grauw.nl/sources/external/z80bits.html | |
ld hl,0 | |
sla e | |
rl d | |
jr nc,@+skip | |
ld h,b | |
ld l,c | |
@skip: | |
@mult_loop: equ for 14 | |
add hl,hl | |
rl e | |
rl d | |
jr nc,$+6 | |
add hl,bc | |
jr nc,$+3 | |
inc de | |
next @mult_loop | |
add hl,hl ; Optimised last iteration | |
rl e | |
rl d | |
ret nc | |
add hl,bc | |
ret nc | |
inc de | |
ret | |
;-------------------------------------------- | |
math.cosA: | |
add 64 | |
math.sinA: | |
; Return DE = Sin A in 8.8 format. Return absolute value to make scaling easier. | |
ld h,math.sin_table/256 | |
ld l,a | |
res 7,l | |
ld e,(hl) | |
set 7,l | |
ld d,(hl) | |
ret | |
ds align 256 | |
math.sin_table: | |
; Sine table of 128 words for full period of angles. 128 bytes of LSBs, then 128 bytes of MSBs. | |
db 0,6,13,19,25,31,38,44,50,56,62,68,74,80,86,92,98,104,109,115,121,126,132,137,142,147,152,157,162,167,172,177,181,185,190,194,198,202,206,209,213,216,220,223,226,229,231,234,237,239,241,243,245,247,248,250,251,252,253,254,255,255,0,0,0,0,0,255,255,254,253,252,251,250,248,247,245,243,241,239,237,234,231,229,226,223,220,216,213,209,206,202,198,194,190,185,181,177,172,167,162,157,152,147,142,137,132,126,121,115,109,104,98,92,86,80,74,68,62,56,50,44,38,31,25,19,13,6 | |
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
;-------------------------------------------- | |
math.rotateABC: | |
; Rotate angular coord with length BC, to angle 0<=A=<255. Output into (IX) as a coordinate with origin at ship centre. | |
; Round fractional lengths. | |
push hl | |
push bc | |
@get_x: ; x = BC.sinA | |
call math.sinA ; DE = sinA in 1.8 format (1 bit of unit data in D, 8 bits of fractional data in E) | |
call math.multDEBC ; Get product in DE.HL (HL is fractional part) | |
@round_pos: | |
bit 7,h ; Round DE | |
jp z,@+correct_sign | |
inc e | |
@correct_sign: ; Fix sign of result | |
push af | |
or a | |
ld a,e | |
jp p,@+store | |
neg | |
@store: | |
ld (ix),a | |
pop af | |
@get_y: ; Repeat with y = BC.cosA | |
pop bc | |
call math.cosA | |
call math.multDEBC | |
@round_pos: | |
bit 7,h | |
jp z,@+correct_sign | |
inc e | |
@correct_sign: | |
or a | |
ld a,e | |
jp m,@+store ; Y value negated to allow angle 0 to be top | |
neg | |
@store: | |
ld (ix+1),a | |
@end: | |
pop hl | |
ret | |
;-------------------------------------------- | |
math.vectorABC: | |
; Rotate angular coord with length BC, to angle 0<=A=<255. Output into math.vector.x and math.vector.y | |
push bc | |
@get_x: ; dx = BC.sinA | |
call math.sinA ; DE = sinA in 1.8 format (1 bit of unit data in D, 8 bits of fractional data in E) | |
call math.multDEBC | |
@round: | |
bit 7,l | |
jp z,@+convert | |
inc h | |
@convert: ; Convert from 16.16 to 8.8 format | |
ld l,h | |
ld h,e | |
@correct_sign: ; Fix sign of result | |
or a | |
jp p,@+store | |
@neg_hl: | |
ex de,hl | |
ld hl,0 | |
and a | |
sbc hl,de | |
@store: | |
ld (math.vector.x),hl | |
pop bc | |
@get_y: ; Repeat with dy = BC.cosA | |
call math.cosA ; Return A=A+&40 for easy checking for cos sign. | |
call math.multDEBC | |
@round: | |
bit 7,l | |
jp z,@+convert | |
inc h | |
@convert: | |
ld l,h | |
ld h,e | |
@correct_sign: | |
or a | |
jp m,@+store ; Y value negated to allow angle 0 to be top | |
@neg_hl: | |
ex de,hl | |
ld hl,0 | |
and a | |
sbc hl,de | |
@store: | |
ld (math.vector.y),hl | |
ret | |
math.vector.x: dw 0 | |
math.vector.y: dw 0 |
Updates:
- Further optimisation of last iteration of math.multDEBC. Actually this can be made much quicker as I always junk last 8 bits of data.
- Absolute sine table tweaked to remove duplicate period
- math.vectorABC included as more accurate version of math.rotateABC, with one byte of fractional data. (ASIDE: How to you say "accurate to 8 decimal places" when you're talking about binary numbers?)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very likely to be buggy, corrections as I get to them.