Keep documentation in sync with new WRAM labels
This commit is contained in:
@@ -8,8 +8,9 @@ These are parts of the code that do not work *incorrectly*, like [bugs and glitc
|
||||
- [Pic banks are offset by `PICS_FIX`](#pic-banks-are-offset-by-pics_fix)
|
||||
- [`PokemonPicPointers` and `UnownPicPointers` are assumed to start at the same address](#pokemonpicpointers-and-unownpicpointers-are-assumed-to-start-at-the-same-address)
|
||||
- [Footprints are split into top and bottom halves](#footprints-are-split-into-top-and-bottom-halves)
|
||||
- [Pokédex entry banks are derived from their species IDs](#pokédex-entry-banks-are-derived-from-their-species-ids)
|
||||
- [`ITEM_C3` and `ITEM_DC` break up the continuous sequence of TM items](#item_c3-and-item_dc-break-up-the-continuous-sequence-of-tm-items)
|
||||
- [Pokédex entry banks are derived from their species IDs](#pokédex-entry-banks-are-derived-from-their-species-ids)
|
||||
- [Identical sine wave code and data is repeated five times](#identical-sine-wave-code-and-data-is-repeated-five-times)
|
||||
- [`GetForestTreeFrame` works, but it's still bad](#getforesttreeframe-works-but-its-still-bad)
|
||||
|
||||
|
||||
@@ -109,15 +110,15 @@ ROMX $49
|
||||
Two routines in [engine/load_pics.asm](/engine/load_pics.asm) make this assumption; `GetFrontpicPointer`:
|
||||
|
||||
```asm
|
||||
ld a, [CurPartySpecies]
|
||||
ld a, [wCurPartySpecies]
|
||||
cp UNOWN
|
||||
jr z, .unown
|
||||
ld a, [CurPartySpecies]
|
||||
ld a, [wCurPartySpecies]
|
||||
ld d, BANK(PokemonPicPointers)
|
||||
jr .ok
|
||||
|
||||
.unown
|
||||
ld a, [UnownLetter]
|
||||
ld a, [wUnownLetter]
|
||||
ld d, BANK(UnownPicPointers)
|
||||
|
||||
.ok
|
||||
@@ -130,9 +131,7 @@ Two routines in [engine/load_pics.asm](/engine/load_pics.asm) make this assumpti
|
||||
And `GetMonBackpic`:
|
||||
|
||||
```asm
|
||||
; These are assumed to be at the same
|
||||
; address in their respective banks.
|
||||
GLOBAL PokemonPicPointers, UnownPicPointers
|
||||
; These are assumed to be at the same address in their respective banks.
|
||||
ld hl, PokemonPicPointers ; UnownPicPointers
|
||||
ld a, b
|
||||
ld d, BANK(PokemonPicPointers)
|
||||
@@ -153,16 +152,16 @@ Don't enforce `org $4000` in pokecrystal.link.
|
||||
Modify `GetFrontpicPointer`:
|
||||
|
||||
```asm
|
||||
ld a, [CurPartySpecies]
|
||||
ld a, [wCurPartySpecies]
|
||||
cp UNOWN
|
||||
jr z, .unown
|
||||
ld a, [CurPartySpecies]
|
||||
ld a, [wCurPartySpecies]
|
||||
ld hl, PokemonPicPointers
|
||||
ld d, BANK(PokemonPicPointers)
|
||||
jr .ok
|
||||
|
||||
.unown
|
||||
ld a, [UnownLetter]
|
||||
ld a, [wUnownLetter]
|
||||
ld hl, UnownPicPointers
|
||||
ld d, BANK(UnownPicPointers)
|
||||
|
||||
@@ -175,7 +174,6 @@ Modify `GetFrontpicPointer`:
|
||||
And `GetMonBackpic`:
|
||||
|
||||
```asm
|
||||
GLOBAL PokemonPicPointers, UnownPicPointers
|
||||
ld a, b
|
||||
ld hl, PokemonPicPointers
|
||||
ld d, BANK(PokemonPicPointers)
|
||||
@@ -234,7 +232,7 @@ INCBIN "gfx/footprints/wartortle.1bpp", footprint_bottom
|
||||
push hl
|
||||
ld e, l
|
||||
ld d, h
|
||||
ld hl, VTiles2 tile $62
|
||||
ld hl, vTiles2 tile $62
|
||||
lb bc, BANK(Footprints), 2
|
||||
call Request1bpp
|
||||
pop hl
|
||||
@@ -246,7 +244,7 @@ INCBIN "gfx/footprints/wartortle.1bpp", footprint_bottom
|
||||
|
||||
ld e, l
|
||||
ld d, h
|
||||
ld hl, VTiles2 tile $64
|
||||
ld hl, vTiles2 tile $64
|
||||
lb bc, BANK(Footprints), 2
|
||||
call Request1bpp
|
||||
```
|
||||
@@ -272,136 +270,28 @@ Modify `Pokedex_LoadAnyFootprint`:
|
||||
```asm
|
||||
ld e, l
|
||||
ld d, h
|
||||
ld hl, VTiles2 tile $62
|
||||
ld hl, vTiles2 tile $62
|
||||
lb bc, BANK(Footprints), 4
|
||||
call Request1bpp
|
||||
```
|
||||
|
||||
|
||||
## Pokédex entry banks are derived from their species IDs
|
||||
|
||||
`PokedexDataPointerTable` in [data/pokemon/dex_entry_pointers.asm](/data/pokemon/dex_entry_pointers.asm) is a table of `dw`, not `dba`, yet there are four banks used for Pokédex entries. The correct bank is derived from the species ID at the beginning of each Pokémon's base stats. (This is the only use the base stat species ID has.)
|
||||
|
||||
Three separate routines do the same derivation; `GetDexEntryPointer` in [engine/pokedex/pokedex_2.asm](/engine/pokedex/pokedex_2.asm):
|
||||
|
||||
```asm
|
||||
GetDexEntryPointer: ; 44333
|
||||
; return dex entry pointer b:de
|
||||
push hl
|
||||
ld hl, PokedexDataPointerTable
|
||||
ld a, b
|
||||
dec a
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
add hl, de
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
push de
|
||||
rlca
|
||||
rlca
|
||||
and $3
|
||||
ld hl, .PokedexEntryBanks
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
ld b, [hl]
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.PokedexEntryBanks: ; 44351
|
||||
|
||||
GLOBAL PokedexEntries1
|
||||
GLOBAL PokedexEntries2
|
||||
GLOBAL PokedexEntries3
|
||||
GLOBAL PokedexEntries4
|
||||
|
||||
db BANK(PokedexEntries1)
|
||||
db BANK(PokedexEntries2)
|
||||
db BANK(PokedexEntries3)
|
||||
db BANK(PokedexEntries4)
|
||||
```
|
||||
|
||||
`GetPokedexEntryBank` in [engine/item_effects.asm](/engine/item_effects.asm):
|
||||
|
||||
```asm
|
||||
GetPokedexEntryBank:
|
||||
push hl
|
||||
push de
|
||||
ld a, [EnemyMonSpecies]
|
||||
rlca
|
||||
rlca
|
||||
and 3
|
||||
ld hl, .PokedexEntryBanks
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.PokedexEntryBanks:
|
||||
|
||||
GLOBAL PokedexEntries1
|
||||
GLOBAL PokedexEntries2
|
||||
GLOBAL PokedexEntries3
|
||||
GLOBAL PokedexEntries4
|
||||
|
||||
db BANK(PokedexEntries1)
|
||||
db BANK(PokedexEntries2)
|
||||
db BANK(PokedexEntries3)
|
||||
db BANK(PokedexEntries4)
|
||||
```
|
||||
|
||||
And `PokedexShow_GetDexEntryBank` in [engine/radio.asm](/engine/radio.asm):
|
||||
|
||||
```asm
|
||||
PokedexShow_GetDexEntryBank:
|
||||
push hl
|
||||
push de
|
||||
ld a, [CurPartySpecies]
|
||||
dec a
|
||||
rlca
|
||||
rlca
|
||||
and 3
|
||||
ld hl, .pokedexbanks
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.pokedexbanks
|
||||
db BANK(PokedexEntries1)
|
||||
db BANK(PokedexEntries2)
|
||||
db BANK(PokedexEntries3)
|
||||
db BANK(PokedexEntries4)
|
||||
```
|
||||
|
||||
**Fix:** Use `dba` instead of `dw` in `PokedexDataPointerTable`, and modify the code that accesses it to match.
|
||||
|
||||
|
||||
## `ITEM_C3` and `ITEM_DC` break up the continuous sequence of TM items
|
||||
|
||||
[constants/item_constants.asm](/constants/item_constants.asm) defined the 50 TMs in order with `add_tm`, but `ITEM_C3` and `ITEM_DC` break up that sequence.
|
||||
|
||||
```asm
|
||||
add_tm DYNAMICPUNCH ; $BF
|
||||
add_tm DYNAMICPUNCH ; bf
|
||||
...
|
||||
add_tm ROLLOUT ; $C2
|
||||
const ITEM_C3 ; $C3
|
||||
add_tm ROAR ; $C4
|
||||
add_tm ROLLOUT ; c2
|
||||
const ITEM_C3 ; c3
|
||||
add_tm ROAR ; c4
|
||||
...
|
||||
add_tm DIG ; $DB
|
||||
const ITEM_DC ; $DC
|
||||
add_tm PSYCHIC_M ; $DD
|
||||
add_tm DIG ; db
|
||||
const ITEM_DC ; dc
|
||||
add_tm PSYCHIC_M ; dd
|
||||
...
|
||||
add_tm NIGHTMARE ; $F2
|
||||
add_tm NIGHTMARE ; f2
|
||||
NUM_TMS = const_value - TM01 - 2 ; discount ITEM_C3 and ITEM_DC
|
||||
```
|
||||
|
||||
@@ -469,6 +359,360 @@ GetNumberedTMHM: ; d417
|
||||
```
|
||||
|
||||
|
||||
## Pokédex entry banks are derived from their species IDs
|
||||
|
||||
`PokedexDataPointerTable` in [data/pokemon/dex_entry_pointers.asm](/data/pokemon/dex_entry_pointers.asm) is a table of `dw`, not `dba`, yet there are four banks used for Pokédex entries. The correct bank is derived from the species ID at the beginning of each Pokémon's base stats. (This is the only use the base stat species ID has.)
|
||||
|
||||
Three separate routines do the same derivation; `GetDexEntryPointer` in [engine/pokedex/pokedex_2.asm](/engine/pokedex/pokedex_2.asm):
|
||||
|
||||
```asm
|
||||
GetDexEntryPointer: ; 44333
|
||||
; return dex entry pointer b:de
|
||||
push hl
|
||||
ld hl, PokedexDataPointerTable
|
||||
ld a, b
|
||||
dec a
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
add hl, de
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
push de
|
||||
rlca
|
||||
rlca
|
||||
maskbits NUM_DEX_ENTRY_BANKS
|
||||
ld hl, .PokedexEntryBanks
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
ld b, [hl]
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.PokedexEntryBanks:
|
||||
db BANK(PokedexEntries1)
|
||||
db BANK(PokedexEntries2)
|
||||
db BANK(PokedexEntries3)
|
||||
db BANK(PokedexEntries4)
|
||||
```
|
||||
|
||||
`GetPokedexEntryBank` in [engine/item_effects.asm](/engine/item_effects.asm):
|
||||
|
||||
```asm
|
||||
GetPokedexEntryBank:
|
||||
push hl
|
||||
push de
|
||||
ld a, [wEnemyMonSpecies]
|
||||
rlca
|
||||
rlca
|
||||
maskbits NUM_DEX_ENTRY_BANKS
|
||||
ld hl, .PokedexEntryBanks
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.PokedexEntryBanks:
|
||||
db BANK(PokedexEntries1)
|
||||
db BANK(PokedexEntries2)
|
||||
db BANK(PokedexEntries3)
|
||||
db BANK(PokedexEntries4)
|
||||
```
|
||||
|
||||
And `PokedexShow_GetDexEntryBank` in [engine/radio.asm](/engine/radio.asm):
|
||||
|
||||
```asm
|
||||
PokedexShow_GetDexEntryBank:
|
||||
push hl
|
||||
push de
|
||||
ld a, [wCurPartySpecies]
|
||||
dec a
|
||||
rlca
|
||||
rlca
|
||||
maskbits NUM_DEX_ENTRY_BANKS
|
||||
ld hl, .PokedexEntryBanks
|
||||
ld d, 0
|
||||
ld e, a
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.PokedexEntryBanks:
|
||||
db BANK(PokedexEntries1)
|
||||
db BANK(PokedexEntries2)
|
||||
db BANK(PokedexEntries3)
|
||||
db BANK(PokedexEntries4)
|
||||
```
|
||||
|
||||
**Fix:** Use `dba` instead of `dw` in `PokedexDataPointerTable`, and modify the code that accesses it to match.
|
||||
|
||||
|
||||
## Identical sine wave code and data is repeated five times
|
||||
|
||||
`_Sine` in [engine/routines/sine.asm](/engine/routines/sine.asm):
|
||||
|
||||
```asm
|
||||
_Sine:: ; 84d9
|
||||
; A simple sine function.
|
||||
; Return d * sin(e) in hl.
|
||||
|
||||
; e is a signed 6-bit value.
|
||||
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
|
||||
```
|
||||
|
||||
`Sprites_Cosine` and `Sprites_Sine` in [engine/sprites.asm](/engine/sprites.asm):
|
||||
|
||||
```asm
|
||||
Sprites_Cosine: ; 8e72a
|
||||
; a = d * cos(a * pi/32)
|
||||
add %010000
|
||||
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
|
||||
```
|
||||
|
||||
`BattleAnim_Cosine` and `BattleAnim_Sine` in [engine/battle_anims/functions.asm](/engine/battle_anims/functions.asm):
|
||||
|
||||
```asm
|
||||
BattleAnim_Cosine: ; ce732 (33:6732)
|
||||
; a = d * cos(a * pi/32)
|
||||
add %010000
|
||||
BattleAnim_Sine: ; ce734 (33:6734)
|
||||
; 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:
|
||||
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
|
||||
; ce7bf
|
||||
```
|
||||
|
||||
`StartTrainerBattle_DrawSineWave` in [engine/battle/battle_transition.asm](/engine/battle/battle_transition.asm):
|
||||
|
||||
```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
|
||||
; 8c768
|
||||
```
|
||||
|
||||
And `CelebiEvent_Cosine` in [engine/events/celebi.asm](/engine/events/celebi.asm):
|
||||
|
||||
```asm
|
||||
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
|
||||
; 49bae
|
||||
```
|
||||
|
||||
**Fix:** Call a single shared copy of the (co)sine code in bank 0.
|
||||
|
||||
|
||||
## `GetForestTreeFrame` works, but it's still bad
|
||||
|
||||
In [engine/tileset_anims.asm](/engine/tileset_anims.asm):
|
||||
|
Reference in New Issue
Block a user