shithub: pokecrystal

Download patch

ref: 73ea7c6326f16f84de1cf74193705328d1664645
parent: 271aa20b73f699819351e787c58d0d14694eb135
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Sat Feb 3 16:11:55 EST 2018

Macro factors out sine code, just like sine data, since it's used 5 times

--- a/docs/design_flaws.md
+++ b/docs/design_flaws.md
@@ -461,53 +461,9 @@
 
 ```asm
 _Sine:: ; 84d9
-; A simple sine function.
-; Return d * sin(e) in hl.
-
-; e is a signed 6-bit value.
+; a = d * sin(e * pi/32)
 	ld a, e
-	and %111111
-	cp  %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-
-.ApplySineWave: ; 84ef
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-; Factor amplitude
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-
-.sinewave ; 850b
-; A 32-word table representing a sine wave.
-; sin(90 degrees) is index $10 with an amplitude of $100.
-	sine_wave 32
+	calc_sine_wave
 ```
 
 `Sprites_Cosine` and `Sprites_Sine` in [engine/sprites.asm](/engine/sprites.asm):
@@ -515,50 +471,11 @@
 ```asm
 Sprites_Cosine: ; 8e72a
 ; a = d * cos(a * pi/32)
-	add %010000
+	add %010000 ; cos(x) = sin(x + pi/2)
+	; fallthrough
 Sprites_Sine: ; 8e72c
 ; a = d * sin(a * pi/32)
-	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-; 8e741
-
-.ApplySineWave: ; 8e741
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-; 8e75d
-
-.sinewave ; 8e75d
-	sine_wave 32
+	calc_sine_wave
 ```
 
 `BattleAnim_Cosine` and `BattleAnim_Sine` in [engine/battle_anims/functions.asm](/engine/battle_anims/functions.asm):
@@ -566,50 +483,16 @@
 ```asm
 BattleAnim_Cosine: ; ce732 (33:6732)
 ; a = d * cos(a * pi/32)
-	add %010000
+	add %010000 ; cos(x) = sin(x + pi/2)
+	; fallthrough
 BattleAnim_Sine: ; ce734 (33:6734)
 ; a = d * sin(a * pi/32)
-	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
+	calc_sine_wave BattleAnimSineWave
 
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-
-.ApplySineWave:
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, BattleAnimSineWave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-
 ...
 
 BattleAnimSineWave: ; ce77f
-	sine_wave 32
+	sine_table 32
 ; ce7bf
 ```
 
@@ -617,47 +500,7 @@
 
 ```asm
 StartTrainerBattle_DrawSineWave: ; 8c6f7 (23:46f7)
-; a = d * sin(a * pi/32)
-	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-
-.ApplySineWave: ; 8c70c (23:470c)
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-; 8c728 (23:4728)
-
-.sinewave ; 8c728
-	sine_wave 32
+	calc_sine_wave
 ; 8c768
 ```
 
@@ -666,27 +509,39 @@
 ```asm
 CelebiEvent_Cosine: ; 49b3b (12:5b3b)
 ; a = d * cos(a * pi/32)
-	add %010000
+	add %010000 ; cos(x) = sin(x + pi/2)
+	calc_sine_wave
+; 49bae
+```
+
+They all rely on `calc_sine_wave` in [macros/code.asm](/macros/code.asm):
+
+```asm
+calc_sine_wave: MACRO
+; input: a = a signed 6-bit value
+; output: a = d * sin(a * pi/32)
 	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
+	cp  %100000
+	jr nc, .negative\@
+	call .apply\@
 	ld a, h
 	ret
-
-.negative
+.negative\@
 	and %011111
-	call .ApplySineWave
+	call .apply\@
 	ld a, h
 	xor $ff
 	inc a
 	ret
-
-.ApplySineWave: ; 49b52 (12:5b52)
+.apply\@
 	ld e, a
 	ld a, d
 	ld d, 0
-	ld hl, .sinewave
+if _NARG == 1
+	ld hl, \1
+else
+	ld hl, .sinetable\@
+endc
 	add hl, de
 	add hl, de
 	ld e, [hl]
@@ -693,24 +548,37 @@
 	inc hl
 	ld d, [hl]
 	ld hl, 0
-.multiply
+.multiply\@ ; factor amplitude
 	srl a
-	jr nc, .even
+	jr nc, .even\@
 	add hl, de
-.even
+.even\@
 	sla e
 	rl d
 	and a
-	jr nz, .multiply
+	jr nz, .multiply\@
 	ret
-; 49b6e (12:5b6e)
+if _NARG == 0
+.sinetable\@
+	sine_table 32
+endc
+ENDM
+```
 
-.sinewave ; 49b6e
-	sine_wave 32
-; 49bae
+And on `sine_table` in [macros/data.asm](/macros/data.asm):
+
+```asm
+sine_table: MACRO
+; \1 samples of sin(x) from x=0 to x<32768 (pi radians)
+x = 0
+rept \1
+	dw (sin(x) + (sin(x) & $ff)) >> 8 ; round up
+x = x + DIV(32768, \1) ; a circle has 65536 "degrees"
+endr
+ENDM
 ```
 
-**Fix:** Call a single shared copy of the (co)sine code in bank 0.
+**Fix:** Edit [home/sine.asm](/home/sine.asm) to contain a single copy of the (co)sine code in bank 0, and call it from those five sites.
 
 
 ## `GetForestTreeFrame` works, but it's still bad
--- a/engine/battle/battle_transition.asm
+++ b/engine/battle/battle_transition.asm
@@ -749,47 +749,7 @@
 
 
 StartTrainerBattle_DrawSineWave: ; 8c6f7 (23:46f7)
-; a = d * sin(a * pi/32)
-	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-
-.ApplySineWave: ; 8c70c (23:470c)
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-; 8c728 (23:4728)
-
-.sinewave ; 8c728
-	sine_wave 32
+	calc_sine_wave
 ; 8c768
 
 StartTrainerBattle_ZoomToBlack: ; 8c768 (23:4768)
--- a/engine/battle_anims/functions.asm
+++ b/engine/battle_anims/functions.asm
@@ -4125,46 +4125,12 @@
 
 BattleAnim_Cosine: ; ce732 (33:6732)
 ; a = d * cos(a * pi/32)
-	add %010000
+	add %010000 ; cos(x) = sin(x + pi/2)
+	; fallthrough
 BattleAnim_Sine: ; ce734 (33:6734)
 ; a = d * sin(a * pi/32)
-	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
+	calc_sine_wave BattleAnimSineWave
 
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-
-.ApplySineWave:
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, BattleAnimSineWave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-
 BattleAnim_Sine_e: ; ce765 (33:6765)
 	ld a, e
 	call BattleAnim_Sine
@@ -4195,5 +4161,5 @@
 ; ce77f
 
 BattleAnimSineWave: ; ce77f
-	sine_wave 32
+	sine_table 32
 ; ce7bf
--- a/engine/events/celebi.asm
+++ b/engine/events/celebi.asm
@@ -241,47 +241,8 @@
 
 CelebiEvent_Cosine: ; 49b3b (12:5b3b)
 ; a = d * cos(a * pi/32)
-	add %010000
-	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-
-.ApplySineWave: ; 49b52 (12:5b52)
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-; 49b6e (12:5b6e)
-
-.sinewave ; 49b6e
-	sine_wave 32
+	add %010000 ; cos(x) = sin(x + pi/2)
+	calc_sine_wave
 ; 49bae
 
 GetCelebiSpriteTile: ; 49bae
--- a/engine/routines/sine.asm
+++ b/engine/routines/sine.asm
@@ -1,48 +1,4 @@
 _Sine:: ; 84d9
-; A simple sine function.
-; Return d * sin(e) in hl.
-
-; e is a signed 6-bit value.
+; a = d * sin(e * pi/32)
 	ld a, e
-	and %111111
-	cp  %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-
-.ApplySineWave: ; 84ef
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-; Factor amplitude
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-
-.sinewave ; 850b
-; A 32-word table representing a sine wave.
-; sin(90 degrees) is index $10 with an amplitude of $100.
-	sine_wave 32
+	calc_sine_wave
--- a/engine/sprites.asm
+++ b/engine/sprites.asm
@@ -577,50 +577,11 @@
 
 Sprites_Cosine: ; 8e72a
 ; a = d * cos(a * pi/32)
-	add %010000
+	add %010000 ; cos(x) = sin(x + pi/2)
+	; fallthrough
 Sprites_Sine: ; 8e72c
 ; a = d * sin(a * pi/32)
-	and %111111
-	cp %100000
-	jr nc, .negative
-	call .ApplySineWave
-	ld a, h
-	ret
-
-.negative
-	and %011111
-	call .ApplySineWave
-	ld a, h
-	xor $ff
-	inc a
-	ret
-; 8e741
-
-.ApplySineWave: ; 8e741
-	ld e, a
-	ld a, d
-	ld d, 0
-	ld hl, .sinewave
-	add hl, de
-	add hl, de
-	ld e, [hl]
-	inc hl
-	ld d, [hl]
-	ld hl, 0
-.multiply
-	srl a
-	jr nc, .even
-	add hl, de
-.even
-	sla e
-	rl d
-	and a
-	jr nz, .multiply
-	ret
-; 8e75d
-
-.sinewave ; 8e75d
-	sine_wave 32
+	calc_sine_wave
 
 
 AnimateEndOfExpBar: ; 8e79d
--- a/home/sine.asm
+++ b/home/sine.asm
@@ -1,13 +1,10 @@
 Cosine:: ; 1b0f
-; Return d * cos(a) in hl
-	add %010000 ; 90 degrees
-
+; a = d * cos(a * pi/32)
+	add %010000 ; cos(x) = sin(x + pi/2)
+	; fallthrough
 Sine:: ; 1b11
-; Return d * sin(a) in hl
-; a is a signed 6-bit value.
-
+; a = d * sin(a * pi/32)
 	ld e, a
-
 	homecall _Sine
 	ret
 ; 1b1e
--- a/macros/code.asm
+++ b/macros/code.asm
@@ -52,3 +52,50 @@
 endr
 	and x
 ENDM
+
+calc_sine_wave: MACRO
+; input: a = a signed 6-bit value
+; output: a = d * sin(a * pi/32)
+	and %111111
+	cp  %100000
+	jr nc, .negative\@
+	call .apply\@
+	ld a, h
+	ret
+.negative\@
+	and %011111
+	call .apply\@
+	ld a, h
+	xor $ff
+	inc a
+	ret
+.apply\@
+	ld e, a
+	ld a, d
+	ld d, 0
+if _NARG == 1
+	ld hl, \1
+else
+	ld hl, .sinetable\@
+endc
+	add hl, de
+	add hl, de
+	ld e, [hl]
+	inc hl
+	ld d, [hl]
+	ld hl, 0
+.multiply\@ ; factor amplitude
+	srl a
+	jr nc, .even\@
+	add hl, de
+.even\@
+	sla e
+	rl d
+	and a
+	jr nz, .multiply\@
+	ret
+if _NARG == 0
+.sinetable\@
+	sine_table 32
+endc
+ENDM
--- a/macros/data.asm
+++ b/macros/data.asm
@@ -111,19 +111,19 @@
 ENDM
 
 
-sine_wave: MACRO
+bcd: MACRO
+rept _NARG
+	dn ((\1) % 100) / 10, (\1) % 10
+	shift
+endr
+ENDM
+
+
+sine_table: MACRO
 ; \1 samples of sin(x) from x=0 to x<32768 (pi radians)
 x = 0
 rept \1
 	dw (sin(x) + (sin(x) & $ff)) >> 8 ; round up
 x = x + DIV(32768, \1) ; a circle has 65536 "degrees"
-endr
-ENDM
-
-
-bcd: MACRO
-rept _NARG
-	dn ((\1) % 100) / 10, (\1) % 10
-	shift
 endr
 ENDM