mirror of
https://github.com/thornAvery/jep-hack.git
synced 2026-02-06 16:15:24 +13:00
First Commit
Upload literally everything from the pokecrystal16 expand-move-ID branch
This commit is contained in:
commit
2f8a41f833
4618 changed files with 480386 additions and 0 deletions
92
home/16bit.asm
Normal file
92
home/16bit.asm
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
MACRO ___conversion_table_homecall
|
||||
; macro arguments: homecall type, function label
|
||||
; all functions clobber af and hl (except for outputs) and preserve bc and de
|
||||
; homecall types:
|
||||
; - read: index to ID conversion (in: a = 8-bit ID; out: hl = 16-bit index)
|
||||
; - write: ID to index conversion (in: hl = 16-bit index; out: a = 8-bit ID)
|
||||
; - lock: ID locking (in: a = ID (or zero to unlock), l = position; out: a = preserved)
|
||||
if strcmp("\1", "read") && strcmp("\1", "write") && strcmp("\1", "lock")
|
||||
fail "16-bit homecall: invalid call type"
|
||||
endc
|
||||
|
||||
if (strcmp("\1", "write") != 0)
|
||||
ld h, a
|
||||
endc
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(\2)
|
||||
rst Bankswitch
|
||||
if (strcmp("\1", "read") == 0)
|
||||
ld a, h
|
||||
endc
|
||||
call \2
|
||||
if (strcmp("\1", "read") != 0)
|
||||
ld l, a
|
||||
endc
|
||||
pop af
|
||||
rst Bankswitch
|
||||
if (strcmp("\1", "read") != 0)
|
||||
ld a, l
|
||||
endc
|
||||
ret
|
||||
ENDM
|
||||
|
||||
MACRO ___conversion_table_homecall_readlocked
|
||||
; macro argument: table name
|
||||
; in: a = position
|
||||
; out: a = 8-bit index; everything else preserved
|
||||
push hl
|
||||
add a, LOW(\1LockedEntries)
|
||||
ld l, a
|
||||
ldh a, [rSVBK]
|
||||
ld h, a
|
||||
ld a, BANK(\1LockedEntries)
|
||||
ldh [rSVBK], a
|
||||
ld a, h
|
||||
ld h, HIGH(\1LockedEntries)
|
||||
ld l, [hl]
|
||||
ldh [rSVBK], a
|
||||
ld a, l
|
||||
pop hl
|
||||
ret
|
||||
ENDM
|
||||
|
||||
; in: a = 8-bit index
|
||||
; out: hl = 16-bit index; a clobbered
|
||||
GetPokemonIndexFromID::
|
||||
___conversion_table_homecall read, _GetPokemonIndexFromID
|
||||
|
||||
; in: hl = 16-bit index
|
||||
; out: a = 8-bit index, hl clobbered
|
||||
GetPokemonIDFromIndex::
|
||||
___conversion_table_homecall write, _GetPokemonIDFromIndex
|
||||
|
||||
; in: a = 8-bit index or zero (to clear), l = position
|
||||
; out: a = unchanged, hl = clobbered
|
||||
LockPokemonID::
|
||||
___conversion_table_homecall lock, _LockPokemonID
|
||||
|
||||
; in: a = position
|
||||
; out: a = 8-bit index; everything else preserved
|
||||
GetLockedPokemonID::
|
||||
___conversion_table_homecall_readlocked wPokemonIndexTable
|
||||
|
||||
; in: a = 8-bit index
|
||||
; out: hl = 16-bit index; a clobbered
|
||||
GetMoveIndexFromID::
|
||||
___conversion_table_homecall read, _GetMoveIndexFromID
|
||||
|
||||
; in: hl = 16-bit index
|
||||
; out: a = 8-bit index, hl clobbered
|
||||
GetMoveIDFromIndex::
|
||||
___conversion_table_homecall write, _GetMoveIDFromIndex
|
||||
|
||||
; in: a = 8-bit index or zero (to clear), l = position
|
||||
; out: a = unchanged, hl = clobbered
|
||||
LockMoveID::
|
||||
___conversion_table_homecall lock, _LockMoveID
|
||||
|
||||
; in: a = position
|
||||
; out: a = 8-bit index; everything else preserved
|
||||
GetLockedMoveID::
|
||||
___conversion_table_homecall_readlocked wMoveIndexTable
|
||||
71
home/array.asm
Normal file
71
home/array.asm
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
IsInArray::
|
||||
; Find value a for every de bytes in array hl.
|
||||
; Return index in b and carry if found.
|
||||
|
||||
ld b, 0
|
||||
ld c, a
|
||||
.loop
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .NotInArray
|
||||
cp c
|
||||
jr z, .InArray
|
||||
inc b
|
||||
add hl, de
|
||||
jr .loop
|
||||
|
||||
.NotInArray:
|
||||
and a
|
||||
ret
|
||||
|
||||
.InArray:
|
||||
scf
|
||||
ret
|
||||
|
||||
IsInWordArray_NextItem:
|
||||
add hl, de
|
||||
IsInWordArray::
|
||||
; Same as IsInArray, but for word values. The value is input in bc; index not returned.
|
||||
ld a, [hli]
|
||||
and [hl]
|
||||
inc a
|
||||
ret z
|
||||
ld a, [hld]
|
||||
cp b
|
||||
jr nz, IsInWordArray_NextItem
|
||||
ld a, [hl]
|
||||
cp c
|
||||
jr nz, IsInWordArray_NextItem
|
||||
scf
|
||||
ret
|
||||
|
||||
SkipNames::
|
||||
; Skip a names.
|
||||
ld bc, NAME_LENGTH
|
||||
and a
|
||||
ret z
|
||||
.loop
|
||||
add hl, bc
|
||||
dec a
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
AddNTimes::
|
||||
; Add bc * a to hl.
|
||||
; Preserves bc
|
||||
and a
|
||||
ret z
|
||||
|
||||
push bc
|
||||
.loop
|
||||
rra ; and a from below and above resets carry
|
||||
jr nc, .noadd
|
||||
add hl, bc
|
||||
.noadd
|
||||
sla c
|
||||
rl b
|
||||
and a
|
||||
jr nz, .loop
|
||||
.done
|
||||
pop bc
|
||||
ret
|
||||
517
home/audio.asm
Normal file
517
home/audio.asm
Normal file
|
|
@ -0,0 +1,517 @@
|
|||
; Audio interfaces.
|
||||
|
||||
InitSound::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_InitSound)
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
call _InitSound
|
||||
|
||||
pop af
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
UpdateSound::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_UpdateSound)
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
call _UpdateSound
|
||||
|
||||
pop af
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
_LoadMusicByte::
|
||||
; [wCurMusicByte] = [a:de]
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
ld a, [de]
|
||||
ld [wCurMusicByte], a
|
||||
ld a, BANK(LoadMusicByte)
|
||||
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
ret
|
||||
|
||||
PlayMusic::
|
||||
; Play music de.
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_PlayMusic) ; aka BANK(_InitSound)
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
ld a, e
|
||||
and a
|
||||
jr z, .nomusic
|
||||
|
||||
call _PlayMusic
|
||||
jr .end
|
||||
|
||||
.nomusic
|
||||
call _InitSound
|
||||
|
||||
.end
|
||||
pop af
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
PlayMusic2::
|
||||
; Stop playing music, then play music de.
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_PlayMusic)
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
push de
|
||||
ld de, MUSIC_NONE
|
||||
call _PlayMusic
|
||||
call DelayFrame
|
||||
pop de
|
||||
call _PlayMusic
|
||||
|
||||
pop af
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
PlayCry::
|
||||
; Play cry de.
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
; Cries are stuck in one bank.
|
||||
ld a, BANK(PokemonCries)
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
ld hl, PokemonCries
|
||||
rept MON_CRY_LENGTH
|
||||
add hl, de
|
||||
endr
|
||||
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
inc hl
|
||||
|
||||
ld a, [hli]
|
||||
ld [wCryPitch], a
|
||||
ld a, [hli]
|
||||
ld [wCryPitch + 1], a
|
||||
ld a, [hli]
|
||||
ld [wCryLength], a
|
||||
ld a, [hl]
|
||||
ld [wCryLength + 1], a
|
||||
|
||||
ld a, BANK(_PlayCry)
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
call _PlayCry
|
||||
|
||||
pop af
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
PlaySFX::
|
||||
; Play sound effect de.
|
||||
; Sound effects are ordered by priority (highest to lowest)
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
; Is something already playing?
|
||||
call CheckSFX
|
||||
jr nc, .play
|
||||
|
||||
; Does it have priority?
|
||||
ld a, [wCurSFX]
|
||||
cp e
|
||||
jr c, .done
|
||||
|
||||
.play
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_PlaySFX)
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
ld a, e
|
||||
ld [wCurSFX], a
|
||||
call _PlaySFX
|
||||
|
||||
pop af
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
|
||||
.done
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
WaitPlaySFX::
|
||||
call WaitSFX
|
||||
jp PlaySFX
|
||||
|
||||
WaitSFX::
|
||||
; infinite loop until sfx is done playing
|
||||
|
||||
push hl
|
||||
|
||||
.wait
|
||||
ld hl, wChannel5Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .wait
|
||||
ld hl, wChannel6Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .wait
|
||||
ld hl, wChannel7Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .wait
|
||||
ld hl, wChannel8Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .wait
|
||||
|
||||
pop hl
|
||||
ret
|
||||
|
||||
IsSFXPlaying::
|
||||
; Return carry if no sound effect is playing.
|
||||
; The inverse of CheckSFX.
|
||||
push hl
|
||||
|
||||
ld hl, wChannel5Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .playing
|
||||
ld hl, wChannel6Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .playing
|
||||
ld hl, wChannel7Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .playing
|
||||
ld hl, wChannel8Flags1
|
||||
bit 0, [hl]
|
||||
jr nz, .playing
|
||||
|
||||
pop hl
|
||||
scf
|
||||
ret
|
||||
|
||||
.playing
|
||||
pop hl
|
||||
and a
|
||||
ret
|
||||
|
||||
MaxVolume::
|
||||
ld a, MAX_VOLUME
|
||||
ld [wVolume], a
|
||||
ret
|
||||
|
||||
LowVolume::
|
||||
ld a, $33 ; 50%
|
||||
ld [wVolume], a
|
||||
ret
|
||||
|
||||
MinVolume::
|
||||
xor a
|
||||
ld [wVolume], a
|
||||
ret
|
||||
|
||||
FadeOutToMusic:: ; unreferenced
|
||||
ld a, 4
|
||||
ld [wMusicFade], a
|
||||
ret
|
||||
|
||||
FadeInToMusic::
|
||||
ld a, 4 | (1 << MUSIC_FADE_IN_F)
|
||||
ld [wMusicFade], a
|
||||
ret
|
||||
|
||||
SkipMusic::
|
||||
; Skip a frames of music.
|
||||
.loop
|
||||
and a
|
||||
ret z
|
||||
dec a
|
||||
call UpdateSound
|
||||
jr .loop
|
||||
|
||||
FadeToMapMusic::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
call GetMapMusic_MaybeSpecial
|
||||
ld a, [wMapMusic]
|
||||
cp e
|
||||
jr z, .done
|
||||
|
||||
ld a, 8
|
||||
ld [wMusicFade], a
|
||||
ld a, e
|
||||
ld [wMusicFadeID], a
|
||||
ld a, d
|
||||
ld [wMusicFadeID + 1], a
|
||||
ld a, e
|
||||
ld [wMapMusic], a
|
||||
|
||||
.done
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
PlayMapMusic::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
call GetMapMusic_MaybeSpecial
|
||||
ld a, [wMapMusic]
|
||||
cp e
|
||||
jr z, .done
|
||||
|
||||
push de
|
||||
ld de, MUSIC_NONE
|
||||
call PlayMusic
|
||||
call DelayFrame
|
||||
pop de
|
||||
ld a, e
|
||||
ld [wMapMusic], a
|
||||
call PlayMusic
|
||||
|
||||
.done
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
PlayMapMusicBike::
|
||||
; If the player's on a bike, play the bike music instead of the map music
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
|
||||
xor a
|
||||
ld [wDontPlayMapMusicOnReload], a
|
||||
ld de, MUSIC_BICYCLE
|
||||
ld a, [wPlayerState]
|
||||
cp PLAYER_BIKE
|
||||
jr z, .play
|
||||
call GetMapMusic_MaybeSpecial
|
||||
.play
|
||||
push de
|
||||
ld de, MUSIC_NONE
|
||||
call PlayMusic
|
||||
call DelayFrame
|
||||
pop de
|
||||
|
||||
ld a, e
|
||||
ld [wMapMusic], a
|
||||
call PlayMusic
|
||||
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
TryRestartMapMusic::
|
||||
ld a, [wDontPlayMapMusicOnReload]
|
||||
and a
|
||||
jr z, RestartMapMusic
|
||||
xor a
|
||||
ld [wMapMusic], a
|
||||
ld de, MUSIC_NONE
|
||||
call PlayMusic
|
||||
call DelayFrame
|
||||
xor a
|
||||
ld [wDontPlayMapMusicOnReload], a
|
||||
ret
|
||||
|
||||
RestartMapMusic::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
ld de, MUSIC_NONE
|
||||
call PlayMusic
|
||||
call DelayFrame
|
||||
ld a, [wMapMusic]
|
||||
ld e, a
|
||||
ld d, 0
|
||||
call PlayMusic
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
SpecialMapMusic::
|
||||
ld a, [wPlayerState]
|
||||
cp PLAYER_SURF
|
||||
jr z, .surf
|
||||
cp PLAYER_SURF_PIKA
|
||||
jr z, .surf
|
||||
|
||||
ld a, [wStatusFlags2]
|
||||
bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, a
|
||||
jr nz, .contest
|
||||
|
||||
.no
|
||||
and a
|
||||
ret
|
||||
|
||||
.bike ; unreferenced
|
||||
ld de, MUSIC_BICYCLE
|
||||
scf
|
||||
ret
|
||||
|
||||
.surf
|
||||
ld de, MUSIC_SURF
|
||||
scf
|
||||
ret
|
||||
|
||||
.contest
|
||||
ld a, [wMapGroup]
|
||||
cp GROUP_ROUTE_35_NATIONAL_PARK_GATE
|
||||
jr nz, .no
|
||||
ld a, [wMapNumber]
|
||||
cp MAP_ROUTE_35_NATIONAL_PARK_GATE
|
||||
jr z, .ranking
|
||||
cp MAP_ROUTE_36_NATIONAL_PARK_GATE
|
||||
jr nz, .no
|
||||
|
||||
.ranking
|
||||
ld de, MUSIC_BUG_CATCHING_CONTEST_RANKING
|
||||
scf
|
||||
ret
|
||||
|
||||
GetMapMusic_MaybeSpecial::
|
||||
call SpecialMapMusic
|
||||
ret c
|
||||
jp GetMapMusic
|
||||
|
||||
CheckSFX::
|
||||
; Return carry if any SFX channels are active.
|
||||
ld a, [wChannel5Flags1]
|
||||
bit 0, a
|
||||
jr nz, .playing
|
||||
ld a, [wChannel6Flags1]
|
||||
bit 0, a
|
||||
jr nz, .playing
|
||||
ld a, [wChannel7Flags1]
|
||||
bit 0, a
|
||||
jr nz, .playing
|
||||
ld a, [wChannel8Flags1]
|
||||
bit 0, a
|
||||
jr nz, .playing
|
||||
and a
|
||||
ret
|
||||
.playing
|
||||
scf
|
||||
ret
|
||||
|
||||
TerminateExpBarSound::
|
||||
xor a
|
||||
ld [wChannel5Flags1], a
|
||||
ld [wPitchSweep], a
|
||||
ldh [rNR10], a
|
||||
ldh [rNR11], a
|
||||
ldh [rNR12], a
|
||||
ldh [rNR13], a
|
||||
ldh [rNR14], a
|
||||
ret
|
||||
|
||||
ChannelsOff::
|
||||
; Quickly turn off music channels
|
||||
xor a
|
||||
ld [wChannel1Flags1], a
|
||||
ld [wChannel2Flags1], a
|
||||
ld [wChannel3Flags1], a
|
||||
ld [wChannel4Flags1], a
|
||||
ld [wPitchSweep], a
|
||||
ret
|
||||
|
||||
SFXChannelsOff::
|
||||
; Quickly turn off sound effect channels
|
||||
xor a
|
||||
ld [wChannel5Flags1], a
|
||||
ld [wChannel6Flags1], a
|
||||
ld [wChannel7Flags1], a
|
||||
ld [wChannel8Flags1], a
|
||||
ld [wPitchSweep], a
|
||||
ret
|
||||
273
home/battle.asm
Normal file
273
home/battle.asm
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
GetPartyParamLocation::
|
||||
; Get the location of parameter a from wCurPartyMon in hl
|
||||
push bc
|
||||
ld hl, wPartyMons
|
||||
ld c, a
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
ld a, [wCurPartyMon]
|
||||
call GetPartyLocation
|
||||
pop bc
|
||||
ret
|
||||
|
||||
GetPartyLocation::
|
||||
; Add the length of a PartyMon struct to hl a times.
|
||||
ld bc, PARTYMON_STRUCT_LENGTH
|
||||
jp AddNTimes
|
||||
|
||||
FarSkipEvolutions::
|
||||
; Calls SkipEvolutions from another bank. It can't be a farcall because it uses hl.
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(SkipEvolutions)
|
||||
rst Bankswitch
|
||||
call SkipEvolutions
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
UserPartyAttr::
|
||||
push af
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr nz, .ot
|
||||
pop af
|
||||
jr BattlePartyAttr
|
||||
.ot
|
||||
pop af
|
||||
jr OTPartyAttr
|
||||
|
||||
OpponentPartyAttr::
|
||||
push af
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .ot
|
||||
pop af
|
||||
jr BattlePartyAttr
|
||||
.ot
|
||||
pop af
|
||||
jr OTPartyAttr
|
||||
|
||||
BattlePartyAttr::
|
||||
; Get attribute a from the party struct of the active battle mon.
|
||||
push bc
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ld hl, wPartyMons
|
||||
add hl, bc
|
||||
ld a, [wCurBattleMon]
|
||||
call GetPartyLocation
|
||||
pop bc
|
||||
ret
|
||||
|
||||
OTPartyAttr::
|
||||
; Get attribute a from the party struct of the active enemy mon.
|
||||
push bc
|
||||
ld c, a
|
||||
ld b, 0
|
||||
ld hl, wOTPartyMon1Species
|
||||
add hl, bc
|
||||
ld a, [wCurOTMon]
|
||||
call GetPartyLocation
|
||||
pop bc
|
||||
ret
|
||||
|
||||
ResetDamage::
|
||||
xor a
|
||||
ld [wCurDamage], a
|
||||
ld [wCurDamage + 1], a
|
||||
ret
|
||||
|
||||
SetPlayerTurn::
|
||||
xor a
|
||||
ldh [hBattleTurn], a
|
||||
ret
|
||||
|
||||
SetEnemyTurn::
|
||||
ld a, 1
|
||||
ldh [hBattleTurn], a
|
||||
ret
|
||||
|
||||
UpdateOpponentInParty::
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, UpdateEnemyMonInParty
|
||||
jr UpdateBattleMonInParty
|
||||
|
||||
UpdateUserInParty::
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, UpdateBattleMonInParty
|
||||
jr UpdateEnemyMonInParty
|
||||
|
||||
UpdateBattleMonInParty::
|
||||
; Update level, status, current HP
|
||||
|
||||
ld a, [wCurBattleMon]
|
||||
|
||||
UpdateBattleMon::
|
||||
ld hl, wPartyMon1Level
|
||||
call GetPartyLocation
|
||||
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld hl, wBattleMonLevel
|
||||
ld bc, wBattleMonMaxHP - wBattleMonLevel
|
||||
jp CopyBytes
|
||||
|
||||
UpdateEnemyMonInParty::
|
||||
; Update level, status, current HP
|
||||
|
||||
; No wildmons.
|
||||
ld a, [wBattleMode]
|
||||
dec a
|
||||
ret z
|
||||
|
||||
ld a, [wCurOTMon]
|
||||
ld hl, wOTPartyMon1Level
|
||||
call GetPartyLocation
|
||||
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld hl, wEnemyMonLevel
|
||||
ld bc, wEnemyMonMaxHP - wEnemyMonLevel
|
||||
jp CopyBytes
|
||||
|
||||
RefreshBattleHuds::
|
||||
call UpdateBattleHuds
|
||||
ld c, 3
|
||||
call DelayFrames
|
||||
jp WaitBGMap
|
||||
|
||||
UpdateBattleHuds::
|
||||
farcall UpdatePlayerHUD
|
||||
farcall UpdateEnemyHUD
|
||||
ret
|
||||
|
||||
INCLUDE "home/battle_vars.asm"
|
||||
|
||||
FarCopyRadioText::
|
||||
inc hl
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
ld a, [hli]
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
ld a, e
|
||||
ld l, a
|
||||
ld a, d
|
||||
ld h, a
|
||||
ld de, wRadioText
|
||||
ld bc, 2 * SCREEN_WIDTH
|
||||
call CopyBytes
|
||||
pop af
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
ret
|
||||
|
||||
MobileTextBorder::
|
||||
; For mobile link battles only.
|
||||
ld a, [wLinkMode]
|
||||
cp LINK_MOBILE
|
||||
ret c
|
||||
|
||||
; Draw a cell phone icon at the
|
||||
; top right corner of the border.
|
||||
hlcoord 19, 12
|
||||
ld [hl], $5e ; top
|
||||
hlcoord 19, 13
|
||||
ld [hl], $5f ; bottom
|
||||
ret
|
||||
|
||||
BattleTextbox::
|
||||
; Open a textbox and print text at hl.
|
||||
push hl
|
||||
call SpeechTextbox
|
||||
call MobileTextBorder
|
||||
call UpdateSprites
|
||||
call ApplyTilemap
|
||||
pop hl
|
||||
call PrintTextboxText
|
||||
ret
|
||||
|
||||
StdBattleTextbox::
|
||||
; Open a textbox and print battle text at 20:hl.
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
ld a, BANK(BattleText)
|
||||
rst Bankswitch
|
||||
|
||||
call BattleTextbox
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
GetBattleAnimPointer::
|
||||
ld a, BANK(BattleAnimations)
|
||||
rst Bankswitch
|
||||
|
||||
ld a, [hli]
|
||||
ld [wBattleAnimAddress], a
|
||||
ld a, [hl]
|
||||
ld [wBattleAnimAddress + 1], a
|
||||
|
||||
; ClearBattleAnims is the only function that calls this...
|
||||
ld a, BANK(ClearBattleAnims)
|
||||
rst Bankswitch
|
||||
|
||||
ret
|
||||
|
||||
GetBattleAnimByte::
|
||||
push hl
|
||||
push de
|
||||
|
||||
ld hl, wBattleAnimAddress
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
|
||||
ld a, BANK(BattleAnimations)
|
||||
rst Bankswitch
|
||||
|
||||
ld a, [de]
|
||||
ld [wBattleAnimByte], a
|
||||
inc de
|
||||
|
||||
ld a, BANK(BattleAnimCommands)
|
||||
rst Bankswitch
|
||||
|
||||
ld [hl], d
|
||||
dec hl
|
||||
ld [hl], e
|
||||
|
||||
pop de
|
||||
pop hl
|
||||
|
||||
ld a, [wBattleAnimByte]
|
||||
ret
|
||||
|
||||
PushLYOverrides::
|
||||
ldh a, [hLCDCPointer]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld a, LOW(wLYOverridesBackup)
|
||||
ld [wRequested2bppSource], a
|
||||
ld a, HIGH(wLYOverridesBackup)
|
||||
ld [wRequested2bppSource + 1], a
|
||||
|
||||
ld a, LOW(wLYOverrides)
|
||||
ld [wRequested2bppDest], a
|
||||
ld a, HIGH(wLYOverrides)
|
||||
ld [wRequested2bppDest + 1], a
|
||||
|
||||
ld a, (wLYOverridesEnd - wLYOverrides) / LEN_2BPP_TILE
|
||||
ld [wRequested2bppSize], a
|
||||
ret
|
||||
113
home/battle_vars.asm
Normal file
113
home/battle_vars.asm
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
GetBattleVar::
|
||||
push hl
|
||||
call GetBattleVarAddr
|
||||
pop hl
|
||||
ret
|
||||
|
||||
GetBattleVarAddr::
|
||||
; Get variable from pair a, depending on whose turn it is.
|
||||
; There are 21 variable pairs.
|
||||
push bc
|
||||
|
||||
ld hl, BattleVarPairs
|
||||
ld c, a
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
; Enemy turn uses the second byte instead.
|
||||
; This lets battle variable calls be side-neutral.
|
||||
ldh a, [hBattleTurn]
|
||||
and a
|
||||
jr z, .getvar
|
||||
inc hl
|
||||
|
||||
.getvar
|
||||
; var id
|
||||
ld a, [hl]
|
||||
ld c, a
|
||||
ld b, 0
|
||||
|
||||
ld hl, BattleVarLocations
|
||||
add hl, bc
|
||||
add hl, bc
|
||||
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
ld a, [hl]
|
||||
|
||||
pop bc
|
||||
ret
|
||||
|
||||
BattleVarPairs:
|
||||
; entries correspond to BATTLE_VARS_* constants
|
||||
table_width 2, BattleVarPairs
|
||||
dw .Substatus1
|
||||
dw .Substatus2
|
||||
dw .Substatus3
|
||||
dw .Substatus4
|
||||
dw .Substatus5
|
||||
dw .Substatus1Opp
|
||||
dw .Substatus2Opp
|
||||
dw .Substatus3Opp
|
||||
dw .Substatus4Opp
|
||||
dw .Substatus5Opp
|
||||
dw .Status
|
||||
dw .StatusOpp
|
||||
dw .MoveAnim
|
||||
dw .MoveEffect
|
||||
dw .MovePower
|
||||
dw .MoveType
|
||||
dw .CurMove
|
||||
dw .LastCounter
|
||||
dw .LastCounterOpp
|
||||
dw .LastMove
|
||||
dw .LastMoveOpp
|
||||
assert_table_length NUM_BATTLE_VARS
|
||||
|
||||
; player enemy
|
||||
.Substatus1: db PLAYER_SUBSTATUS_1, ENEMY_SUBSTATUS_1
|
||||
.Substatus1Opp: db ENEMY_SUBSTATUS_1, PLAYER_SUBSTATUS_1
|
||||
.Substatus2: db PLAYER_SUBSTATUS_2, ENEMY_SUBSTATUS_2
|
||||
.Substatus2Opp: db ENEMY_SUBSTATUS_2, PLAYER_SUBSTATUS_2
|
||||
.Substatus3: db PLAYER_SUBSTATUS_3, ENEMY_SUBSTATUS_3
|
||||
.Substatus3Opp: db ENEMY_SUBSTATUS_3, PLAYER_SUBSTATUS_3
|
||||
.Substatus4: db PLAYER_SUBSTATUS_4, ENEMY_SUBSTATUS_4
|
||||
.Substatus4Opp: db ENEMY_SUBSTATUS_4, PLAYER_SUBSTATUS_4
|
||||
.Substatus5: db PLAYER_SUBSTATUS_5, ENEMY_SUBSTATUS_5
|
||||
.Substatus5Opp: db ENEMY_SUBSTATUS_5, PLAYER_SUBSTATUS_5
|
||||
.Status: db PLAYER_STATUS, ENEMY_STATUS
|
||||
.StatusOpp: db ENEMY_STATUS, PLAYER_STATUS
|
||||
.MoveAnim: db PLAYER_MOVE_ANIMATION, ENEMY_MOVE_ANIMATION
|
||||
.MoveEffect: db PLAYER_MOVE_EFFECT, ENEMY_MOVE_EFFECT
|
||||
.MovePower: db PLAYER_MOVE_POWER, ENEMY_MOVE_POWER
|
||||
.MoveType: db PLAYER_MOVE_TYPE, ENEMY_MOVE_TYPE
|
||||
.CurMove: db PLAYER_CUR_MOVE, ENEMY_CUR_MOVE
|
||||
.LastCounter: db PLAYER_COUNTER_MOVE, ENEMY_COUNTER_MOVE
|
||||
.LastCounterOpp: db ENEMY_COUNTER_MOVE, PLAYER_COUNTER_MOVE
|
||||
.LastMove: db PLAYER_LAST_MOVE, ENEMY_LAST_MOVE
|
||||
.LastMoveOpp: db ENEMY_LAST_MOVE, PLAYER_LAST_MOVE
|
||||
|
||||
BattleVarLocations:
|
||||
; entries correspond to PLAYER_* and ENEMY_* constants
|
||||
table_width 2 + 2, BattleVarLocations
|
||||
dw wPlayerSubStatus1, wEnemySubStatus1
|
||||
dw wPlayerSubStatus2, wEnemySubStatus2
|
||||
dw wPlayerSubStatus3, wEnemySubStatus3
|
||||
dw wPlayerSubStatus4, wEnemySubStatus4
|
||||
dw wPlayerSubStatus5, wEnemySubStatus5
|
||||
dw wBattleMonStatus, wEnemyMonStatus
|
||||
dw wPlayerMoveStructAnimation, wEnemyMoveStructAnimation
|
||||
dw wPlayerMoveStructEffect, wEnemyMoveStructEffect
|
||||
dw wPlayerMoveStructPower, wEnemyMoveStructPower
|
||||
dw wPlayerMoveStructType, wEnemyMoveStructType
|
||||
dw wCurPlayerMove, wCurEnemyMove
|
||||
dw wLastPlayerCounterMove, wLastEnemyCounterMove
|
||||
dw wLastPlayerMove, wLastEnemyMove
|
||||
assert_table_length NUM_BATTLE_VAR_LOCATION_PAIRS
|
||||
8
home/call_regs.asm
Normal file
8
home/call_regs.asm
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
; Register aliases
|
||||
|
||||
_hl_::
|
||||
jp hl
|
||||
|
||||
_de_::
|
||||
push de
|
||||
ret
|
||||
23
home/clear_sprites.asm
Normal file
23
home/clear_sprites.asm
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
ClearSprites::
|
||||
; Erase OAM data
|
||||
ld hl, wShadowOAM
|
||||
ld b, wShadowOAMEnd - wShadowOAM
|
||||
xor a
|
||||
.loop
|
||||
ld [hli], a
|
||||
dec b
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
HideSprites::
|
||||
; Set all OAM y-positions to 160 to hide them offscreen
|
||||
ld hl, wShadowOAMSprite00YCoord
|
||||
ld de, SPRITEOAMSTRUCT_LENGTH
|
||||
ld b, NUM_SPRITE_OAM_STRUCTS
|
||||
ld a, SCREEN_WIDTH_PX
|
||||
.loop
|
||||
ld [hl], a ; y
|
||||
add hl, de
|
||||
dec b
|
||||
jr nz, .loop
|
||||
ret
|
||||
35
home/compare.asm
Normal file
35
home/compare.asm
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
CompareBytes::
|
||||
; Compare c bytes at de and hl.
|
||||
; Return z if they all match.
|
||||
.loop
|
||||
ld a, [de]
|
||||
cp [hl]
|
||||
ret nz
|
||||
inc de
|
||||
inc hl
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
CompareBytesLong::
|
||||
; Compare bc bytes at de and hl.
|
||||
; Return carry if they all match.
|
||||
.loop
|
||||
ld a, [de]
|
||||
cp [hl]
|
||||
jr nz, .diff
|
||||
|
||||
inc de
|
||||
inc hl
|
||||
dec bc
|
||||
|
||||
ld a, b
|
||||
or c
|
||||
jr nz, .loop
|
||||
|
||||
scf
|
||||
ret
|
||||
|
||||
.diff:
|
||||
and a
|
||||
ret
|
||||
131
home/copy.asm
Normal file
131
home/copy.asm
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
CopyBytes::
|
||||
; copy bc bytes from hl to de
|
||||
inc b ; we bail the moment b hits 0, so include the last run
|
||||
inc c ; same thing; include last byte
|
||||
jr .HandleLoop
|
||||
.CopyByte:
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
.HandleLoop:
|
||||
dec c
|
||||
jr nz, .CopyByte
|
||||
dec b
|
||||
jr nz, .CopyByte
|
||||
ret
|
||||
|
||||
SwapBytes::
|
||||
; swap bc bytes between hl and de
|
||||
.Loop:
|
||||
; stash [hl] away on the stack
|
||||
ld a, [hl]
|
||||
push af
|
||||
|
||||
; copy a byte from [de] to [hl]
|
||||
ld a, [de]
|
||||
ld [hli], a
|
||||
|
||||
; retrieve the previous value of [hl]; put it in [de]
|
||||
pop af
|
||||
ld [de], a
|
||||
inc de
|
||||
|
||||
; handle loop stuff
|
||||
dec bc
|
||||
ld a, b
|
||||
or c
|
||||
jr nz, .Loop
|
||||
ret
|
||||
|
||||
ByteFill::
|
||||
; fill bc bytes with the value of a, starting at hl
|
||||
inc b ; we bail the moment b hits 0, so include the last run
|
||||
inc c ; same thing; include last byte
|
||||
jr .HandleLoop
|
||||
.PutByte:
|
||||
ld [hli], a
|
||||
.HandleLoop:
|
||||
dec c
|
||||
jr nz, .PutByte
|
||||
dec b
|
||||
jr nz, .PutByte
|
||||
ret
|
||||
|
||||
GetFarByte::
|
||||
; retrieve a single byte from a:hl, and return it in a.
|
||||
; bankswitch to new bank
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
|
||||
; get byte from new bank
|
||||
ld a, [hl]
|
||||
ldh [hFarByte], a
|
||||
|
||||
; bankswitch to previous bank
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
; return retrieved value in a
|
||||
ldh a, [hFarByte]
|
||||
ret
|
||||
|
||||
GetFarWord::
|
||||
; retrieve a word from a:hl, and return it in hl.
|
||||
; bankswitch to new bank
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
|
||||
; get word from new bank, put it in hl
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
; bankswitch to previous bank and return
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
FarCopyWRAM::
|
||||
ldh [hTempBank], a
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
ldh [rSVBK], a
|
||||
|
||||
call CopyBytes
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
|
||||
GetFarWRAMByte::
|
||||
ldh [hTempBank], a
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
ldh [rSVBK], a
|
||||
ld a, [hl]
|
||||
ldh [hFarByte], a
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ldh a, [hFarByte]
|
||||
ret
|
||||
|
||||
GetFarWRAMWord:: ; unreferenced
|
||||
ldh [hTempBank], a
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
ldh [rSVBK], a
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
36
home/copy_name.asm
Normal file
36
home/copy_name.asm
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
CopyName1::
|
||||
; Copies the name from de to wStringBuffer2
|
||||
ld hl, wStringBuffer2
|
||||
|
||||
CopyName2::
|
||||
; Copies the name from de to hl
|
||||
.loop
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld [hli], a
|
||||
cp "@"
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
CopyStringWithTerminator::
|
||||
; in: hl = source, de = destination, c = length (non-zero)
|
||||
; out: clobbers all but b
|
||||
dec c
|
||||
.copy_loop
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
cp "@"
|
||||
jr z, .clear_loop
|
||||
dec c
|
||||
jr nz, .copy_loop
|
||||
ld a, "@"
|
||||
ld [de], a
|
||||
ret
|
||||
|
||||
.clear_loop
|
||||
ld [de], a
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .clear_loop
|
||||
ret
|
||||
35
home/copy_tilemap.asm
Normal file
35
home/copy_tilemap.asm
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
LoadTilemapToTempTilemap::
|
||||
; Load wTilemap into wTempTilemap
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wTempTilemap)
|
||||
ldh [rSVBK], a
|
||||
hlcoord 0, 0
|
||||
decoord 0, 0, wTempTilemap
|
||||
ld bc, wTilemapEnd - wTilemap
|
||||
call CopyBytes
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
|
||||
SafeLoadTempTilemapToTilemap::
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
call LoadTempTilemapToTilemap
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
LoadTempTilemapToTilemap::
|
||||
; Load wTempTilemap into wTilemap
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wTempTilemap)
|
||||
ldh [rSVBK], a
|
||||
hlcoord 0, 0, wTempTilemap
|
||||
decoord 0, 0
|
||||
ld bc, wTilemapEnd - wTilemap
|
||||
call CopyBytes
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
317
home/decompress.asm
Normal file
317
home/decompress.asm
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
FarDecompress::
|
||||
; Decompress graphics data from a:hl to de.
|
||||
|
||||
ld [wLZBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, [wLZBank]
|
||||
rst Bankswitch
|
||||
|
||||
call Decompress
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
Decompress::
|
||||
; Pokemon GSC uses an lz variant (lz3) for compression.
|
||||
; This is mainly (but not necessarily) used for graphics.
|
||||
|
||||
; This function decompresses lz-compressed data from hl to de.
|
||||
|
||||
DEF LZ_END EQU $ff ; Compressed data is terminated with $ff.
|
||||
|
||||
; A typical control command consists of:
|
||||
|
||||
DEF LZ_CMD EQU %11100000 ; command id (bits 5-7)
|
||||
DEF LZ_LEN EQU %00011111 ; length n (bits 0-4)
|
||||
|
||||
; Additional parameters are read during command execution.
|
||||
|
||||
; Commands:
|
||||
|
||||
DEF LZ_LITERAL EQU 0 << 5 ; Read literal data for n bytes.
|
||||
DEF LZ_ITERATE EQU 1 << 5 ; Write the same byte for n bytes.
|
||||
DEF LZ_ALTERNATE EQU 2 << 5 ; Alternate two bytes for n bytes.
|
||||
DEF LZ_ZERO EQU 3 << 5 ; Write 0 for n bytes.
|
||||
|
||||
; Another class of commands reuses data from the decompressed output.
|
||||
DEF LZ_RW EQU 2 + 5 ; bit
|
||||
|
||||
; These commands take a signed offset to start copying from.
|
||||
; Wraparound is simulated.
|
||||
; Positive offsets (15-bit) are added to the start address.
|
||||
; Negative offsets (7-bit) are subtracted from the current position.
|
||||
|
||||
DEF LZ_REPEAT EQU 4 << 5 ; Repeat n bytes from the offset.
|
||||
DEF LZ_FLIP EQU 5 << 5 ; Repeat n bitflipped bytes.
|
||||
DEF LZ_REVERSE EQU 6 << 5 ; Repeat n bytes in reverse.
|
||||
|
||||
; If the value in the count needs to be larger than 5 bits,
|
||||
; LZ_LONG can be used to expand the count to 10 bits.
|
||||
DEF LZ_LONG EQU 7 << 5
|
||||
|
||||
; A new control command is read in bits 2-4.
|
||||
; The top two bits of the length are bits 0-1.
|
||||
; Another byte is read containing the bottom 8 bits.
|
||||
DEF LZ_LONG_HI EQU %00000011
|
||||
|
||||
; In other words, the structure of the command becomes
|
||||
; 111xxxyy yyyyyyyy
|
||||
; x: the new control command
|
||||
; y: the length
|
||||
|
||||
; Save the output address
|
||||
; for rewrite commands.
|
||||
ld a, e
|
||||
ld [wLZAddress], a
|
||||
ld a, d
|
||||
ld [wLZAddress + 1], a
|
||||
|
||||
.Main:
|
||||
ld a, [hl]
|
||||
cp LZ_END
|
||||
ret z
|
||||
|
||||
and LZ_CMD
|
||||
|
||||
cp LZ_LONG
|
||||
jr nz, .short
|
||||
|
||||
; The count is now 10 bits.
|
||||
|
||||
; Read the next 3 bits.
|
||||
; %00011100 -> %11100000
|
||||
ld a, [hl]
|
||||
add a
|
||||
add a ; << 3
|
||||
add a
|
||||
|
||||
; This is our new control code.
|
||||
and LZ_CMD
|
||||
push af
|
||||
|
||||
ld a, [hli]
|
||||
and LZ_LONG_HI
|
||||
ld b, a
|
||||
ld a, [hli]
|
||||
ld c, a
|
||||
|
||||
; read at least 1 byte
|
||||
inc bc
|
||||
jr .command
|
||||
|
||||
.short
|
||||
push af
|
||||
|
||||
ld a, [hli]
|
||||
and LZ_LEN
|
||||
ld c, a
|
||||
ld b, 0
|
||||
|
||||
; read at least 1 byte
|
||||
inc c
|
||||
|
||||
.command
|
||||
; Increment loop counts.
|
||||
; We bail the moment they hit 0.
|
||||
inc b
|
||||
inc c
|
||||
|
||||
pop af
|
||||
|
||||
bit LZ_RW, a
|
||||
jr nz, .rewrite
|
||||
|
||||
cp LZ_ITERATE
|
||||
jr z, .Iter
|
||||
cp LZ_ALTERNATE
|
||||
jr z, .Alt
|
||||
cp LZ_ZERO
|
||||
jr z, .Zero
|
||||
|
||||
; Literal
|
||||
; Read literal data for bc bytes.
|
||||
.lloop
|
||||
dec c
|
||||
jr nz, .lnext
|
||||
dec b
|
||||
jp z, .Main
|
||||
|
||||
.lnext
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
jr .lloop
|
||||
|
||||
.Iter:
|
||||
; Write the same byte for bc bytes.
|
||||
ld a, [hli]
|
||||
|
||||
.iloop
|
||||
dec c
|
||||
jr nz, .inext
|
||||
dec b
|
||||
jp z, .Main
|
||||
|
||||
.inext
|
||||
ld [de], a
|
||||
inc de
|
||||
jr .iloop
|
||||
|
||||
.Alt:
|
||||
; Alternate two bytes for bc bytes.
|
||||
dec c
|
||||
jr nz, .anext1
|
||||
dec b
|
||||
jp z, .adone1
|
||||
.anext1
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
|
||||
dec c
|
||||
jr nz, .anext2
|
||||
dec b
|
||||
jp z, .adone2
|
||||
.anext2
|
||||
ld a, [hld]
|
||||
ld [de], a
|
||||
inc de
|
||||
|
||||
jr .Alt
|
||||
|
||||
; Skip past the bytes we were alternating.
|
||||
.adone1
|
||||
inc hl
|
||||
.adone2
|
||||
inc hl
|
||||
jr .Main
|
||||
|
||||
.Zero:
|
||||
; Write 0 for bc bytes.
|
||||
xor a
|
||||
|
||||
.zloop
|
||||
dec c
|
||||
jr nz, .znext
|
||||
dec b
|
||||
jp z, .Main
|
||||
|
||||
.znext
|
||||
ld [de], a
|
||||
inc de
|
||||
jr .zloop
|
||||
|
||||
.rewrite
|
||||
; Repeat decompressed data from output.
|
||||
push hl
|
||||
push af
|
||||
|
||||
ld a, [hli]
|
||||
bit 7, a ; sign
|
||||
jr z, .positive
|
||||
|
||||
; negative
|
||||
; hl = de + -a
|
||||
and %01111111
|
||||
cpl
|
||||
add e
|
||||
ld l, a
|
||||
ld a, -1
|
||||
adc d
|
||||
ld h, a
|
||||
jr .ok
|
||||
|
||||
.positive
|
||||
; Positive offsets are two bytes.
|
||||
ld l, [hl]
|
||||
ld h, a
|
||||
; add to starting output address
|
||||
ld a, [wLZAddress]
|
||||
add l
|
||||
ld l, a
|
||||
ld a, [wLZAddress + 1]
|
||||
adc h
|
||||
ld h, a
|
||||
|
||||
.ok
|
||||
pop af
|
||||
|
||||
cp LZ_REPEAT
|
||||
jr z, .Repeat
|
||||
cp LZ_FLIP
|
||||
jr z, .Flip
|
||||
cp LZ_REVERSE
|
||||
jr z, .Reverse
|
||||
|
||||
; Since LZ_LONG is command 7,
|
||||
; only commands 0-6 are passed in.
|
||||
; This leaves room for an extra command 7.
|
||||
; However, lengths longer than 768
|
||||
; would be interpreted as LZ_END.
|
||||
|
||||
; More practically, LZ_LONG is not recursive.
|
||||
; For now, it defaults to LZ_REPEAT.
|
||||
|
||||
.Repeat:
|
||||
; Copy decompressed data for bc bytes.
|
||||
dec c
|
||||
jr nz, .rnext
|
||||
dec b
|
||||
jr z, .donerw
|
||||
|
||||
.rnext
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
jr .Repeat
|
||||
|
||||
.Flip:
|
||||
; Copy bitflipped decompressed data for bc bytes.
|
||||
dec c
|
||||
jr nz, .fnext
|
||||
dec b
|
||||
jp z, .donerw
|
||||
|
||||
.fnext
|
||||
ld a, [hli]
|
||||
push bc
|
||||
lb bc, 0, 8
|
||||
|
||||
.floop
|
||||
rra
|
||||
rl b
|
||||
dec c
|
||||
jr nz, .floop
|
||||
|
||||
ld a, b
|
||||
pop bc
|
||||
|
||||
ld [de], a
|
||||
inc de
|
||||
jr .Flip
|
||||
|
||||
.Reverse:
|
||||
; Copy reversed decompressed data for bc bytes.
|
||||
dec c
|
||||
jr nz, .rvnext
|
||||
|
||||
dec b
|
||||
jp z, .donerw
|
||||
|
||||
.rvnext
|
||||
ld a, [hld]
|
||||
ld [de], a
|
||||
inc de
|
||||
jr .Reverse
|
||||
|
||||
.donerw
|
||||
pop hl
|
||||
|
||||
bit 7, [hl]
|
||||
jr nz, .next
|
||||
inc hl ; positive offset is two bytes
|
||||
.next
|
||||
inc hl
|
||||
jp .Main
|
||||
20
home/delay.asm
Normal file
20
home/delay.asm
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
DelayFrame::
|
||||
; Wait for one frame
|
||||
ld a, 1
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
; Wait for the next VBlank, halting to conserve battery
|
||||
.halt
|
||||
halt
|
||||
nop
|
||||
ld a, [wVBlankOccurred]
|
||||
and a
|
||||
jr nz, .halt
|
||||
ret
|
||||
|
||||
DelayFrames::
|
||||
; Wait c frames
|
||||
call DelayFrame
|
||||
dec c
|
||||
jr nz, DelayFrames
|
||||
ret
|
||||
27
home/double_speed.asm
Normal file
27
home/double_speed.asm
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
; The CGB hardware introduces Double Speed Mode.
|
||||
; While active, the clock speed is doubled.
|
||||
|
||||
; The hardware can switch between normal speed
|
||||
; and double speed at any time, but LCD output
|
||||
; collapses during the switch.
|
||||
|
||||
DoubleSpeed::
|
||||
ld hl, rKEY1
|
||||
bit 7, [hl]
|
||||
jr z, SwitchSpeed
|
||||
ret
|
||||
|
||||
NormalSpeed::
|
||||
ld hl, rKEY1
|
||||
bit 7, [hl]
|
||||
ret z
|
||||
|
||||
SwitchSpeed::
|
||||
set 0, [hl]
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ldh [rIE], a
|
||||
ld a, $30
|
||||
ldh [rJOYP], a
|
||||
stop ; rgbasm adds a nop after this instruction by default
|
||||
ret
|
||||
107
home/fade.asm
Normal file
107
home/fade.asm
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
; Functions to fade the screen in and out.
|
||||
|
||||
RotateFourPalettesRight::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .dmg
|
||||
ld hl, IncGradGBPalTable_00
|
||||
ld b, 4
|
||||
jr RotatePalettesRight
|
||||
|
||||
.dmg
|
||||
ld hl, IncGradGBPalTable_08
|
||||
ld b, 4
|
||||
jr RotatePalettesRight
|
||||
|
||||
RotateThreePalettesRight::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .dmg
|
||||
ld hl, IncGradGBPalTable_05
|
||||
ld b, 3
|
||||
jr RotatePalettesRight
|
||||
|
||||
.dmg
|
||||
ld hl, IncGradGBPalTable_13
|
||||
ld b, 3
|
||||
RotatePalettesRight::
|
||||
; Rotate palettes to the right and fill with loaded colors from the left
|
||||
; If we're already at the leftmost color, fill with the leftmost color
|
||||
push de
|
||||
ld a, [hli]
|
||||
call DmgToCgbBGPals
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
call DmgToCgbObjPals
|
||||
ld c, 8
|
||||
call DelayFrames
|
||||
pop de
|
||||
dec b
|
||||
jr nz, RotatePalettesRight
|
||||
ret
|
||||
|
||||
RotateFourPalettesLeft::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .dmg
|
||||
ld hl, IncGradGBPalTable_04 - 1
|
||||
ld b, 4
|
||||
jr RotatePalettesLeft
|
||||
|
||||
.dmg
|
||||
ld hl, IncGradGBPalTable_12 - 1
|
||||
ld b, 4
|
||||
jr RotatePalettesLeft
|
||||
|
||||
RotateThreePalettesLeft::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .dmg
|
||||
ld hl, IncGradGBPalTable_07 - 1
|
||||
ld b, 3
|
||||
jr RotatePalettesLeft
|
||||
|
||||
.dmg
|
||||
ld hl, IncGradGBPalTable_15 - 1
|
||||
ld b, 3
|
||||
RotatePalettesLeft::
|
||||
; Rotate palettes to the left and fill with loaded colors from the right
|
||||
; If we're already at the rightmost color, fill with the rightmost color
|
||||
push de
|
||||
ld a, [hld]
|
||||
ld d, a
|
||||
ld a, [hld]
|
||||
ld e, a
|
||||
call DmgToCgbObjPals
|
||||
ld a, [hld]
|
||||
call DmgToCgbBGPals
|
||||
ld c, 8
|
||||
call DelayFrames
|
||||
pop de
|
||||
dec b
|
||||
jr nz, RotatePalettesLeft
|
||||
ret
|
||||
|
||||
IncGradGBPalTable_00:: dc 3,3,3,3, 3,3,3,3, 3,3,3,3
|
||||
IncGradGBPalTable_01:: dc 3,3,3,2, 3,3,3,2, 3,3,3,2
|
||||
IncGradGBPalTable_02:: dc 3,3,2,1, 3,3,2,1, 3,3,2,1
|
||||
IncGradGBPalTable_03:: dc 3,2,1,0, 3,2,1,0, 3,2,1,0
|
||||
|
||||
IncGradGBPalTable_04:: dc 3,2,1,0, 3,2,1,0, 3,2,1,0
|
||||
IncGradGBPalTable_05:: dc 2,1,0,0, 2,1,0,0, 2,1,0,0
|
||||
IncGradGBPalTable_06:: dc 1,0,0,0, 1,0,0,0, 1,0,0,0
|
||||
|
||||
IncGradGBPalTable_07:: dc 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
; bgp obp1 obp2
|
||||
IncGradGBPalTable_08:: dc 3,3,3,3, 3,3,3,3, 3,3,3,3
|
||||
IncGradGBPalTable_09:: dc 3,3,3,2, 3,3,3,2, 3,3,2,0
|
||||
IncGradGBPalTable_10:: dc 3,3,2,1, 3,2,1,0, 3,2,1,0
|
||||
IncGradGBPalTable_11:: dc 3,2,1,0, 3,1,0,0, 3,2,0,0
|
||||
|
||||
IncGradGBPalTable_12:: dc 3,2,1,0, 3,1,0,0, 3,2,0,0
|
||||
IncGradGBPalTable_13:: dc 2,1,0,0, 2,0,0,0, 2,1,0,0
|
||||
IncGradGBPalTable_14:: dc 1,0,0,0, 1,0,0,0, 1,0,0,0
|
||||
|
||||
IncGradGBPalTable_15:: dc 0,0,0,0, 0,0,0,0, 0,0,0,0
|
||||
48
home/farcall.asm
Normal file
48
home/farcall.asm
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
FarCall_de::
|
||||
; Call a:de.
|
||||
; Preserves other registers.
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
call FarCall_JumpToDE
|
||||
jr ReturnFarCall
|
||||
|
||||
FarCall_JumpToDE:
|
||||
push de
|
||||
ret
|
||||
|
||||
FarCall_hl::
|
||||
; Call a:hl.
|
||||
; Preserves other registers.
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
call FarCall_JumpToHL
|
||||
; fallthrough
|
||||
|
||||
ReturnFarCall::
|
||||
; We want to retain the contents of f.
|
||||
; To do this, we can pop to bc instead of af.
|
||||
ld a, b
|
||||
ld [wFarCallBC], a
|
||||
ld a, c
|
||||
ld [wFarCallBC + 1], a
|
||||
|
||||
; Restore the working bank.
|
||||
pop bc
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
|
||||
; Restore the contents of bc.
|
||||
ld a, [wFarCallBC]
|
||||
ld b, a
|
||||
ld a, [wFarCallBC + 1]
|
||||
ld c, a
|
||||
ret
|
||||
|
||||
FarCall_JumpToHL::
|
||||
jp hl
|
||||
113
home/flag.asm
Normal file
113
home/flag.asm
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
ResetMapBufferEventFlags::
|
||||
xor a
|
||||
ld hl, wEventFlags
|
||||
ld [hli], a
|
||||
ret
|
||||
|
||||
ResetBikeFlags::
|
||||
xor a
|
||||
ld hl, wBikeFlags
|
||||
ld [hli], a
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
ResetFlashIfOutOfCave::
|
||||
ld a, [wEnvironment]
|
||||
cp ROUTE
|
||||
jr z, .outdoors
|
||||
cp TOWN
|
||||
jr z, .outdoors
|
||||
ret
|
||||
|
||||
.outdoors
|
||||
ld hl, wStatusFlags
|
||||
res STATUSFLAGS_FLASH_F, [hl]
|
||||
ret
|
||||
|
||||
EventFlagAction::
|
||||
ld hl, wEventFlags
|
||||
call FlagAction
|
||||
ret
|
||||
|
||||
FlagAction::
|
||||
; Perform action b on bit de in flag array hl.
|
||||
|
||||
; inputs:
|
||||
; b: function
|
||||
; 0 RESET_FLAG clear bit
|
||||
; 1 SET_FLAG set bit
|
||||
; 2 CHECK_FLAG check bit
|
||||
; de: bit number
|
||||
; hl: pointer to the flag array
|
||||
|
||||
; get index within the byte
|
||||
ld a, e
|
||||
and 7
|
||||
|
||||
; shift de right by three bits (get the index within memory)
|
||||
rept 3
|
||||
srl d
|
||||
rr e
|
||||
endr
|
||||
add hl, de
|
||||
|
||||
; implement a decoder
|
||||
ld c, 1
|
||||
rrca
|
||||
jr nc, .one
|
||||
rlc c
|
||||
.one
|
||||
rrca
|
||||
jr nc, .two
|
||||
rlc c
|
||||
rlc c
|
||||
.two
|
||||
rrca
|
||||
jr nc, .three
|
||||
swap c
|
||||
.three
|
||||
|
||||
; check b's value: 0, 1, 2
|
||||
ld a, b
|
||||
cp SET_FLAG
|
||||
jr c, .clearbit ; RESET_FLAG
|
||||
jr z, .setbit ; SET_FLAG
|
||||
|
||||
; check bit
|
||||
ld a, [hl]
|
||||
and c
|
||||
ld c, a
|
||||
ret
|
||||
|
||||
.setbit
|
||||
; set bit
|
||||
ld a, [hl]
|
||||
or c
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
.clearbit
|
||||
; clear bit
|
||||
ld a, c
|
||||
cpl
|
||||
and [hl]
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
CheckReceivedDex::
|
||||
ld de, ENGINE_POKEDEX
|
||||
ld b, CHECK_FLAG
|
||||
farcall EngineFlagAction
|
||||
ld a, c
|
||||
and a
|
||||
ret
|
||||
|
||||
xor_a::
|
||||
xor a
|
||||
ret
|
||||
|
||||
xor_a_dec_a::
|
||||
xor a
|
||||
dec a
|
||||
ret
|
||||
|
||||
118
home/game_time.asm
Normal file
118
home/game_time.asm
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
ResetGameTime::
|
||||
xor a
|
||||
ld [wGameTimeCap], a
|
||||
ld [wGameTimeHours], a
|
||||
ld [wGameTimeHours + 1], a
|
||||
ld [wGameTimeMinutes], a
|
||||
ld [wGameTimeSeconds], a
|
||||
ld [wGameTimeFrames], a
|
||||
ret
|
||||
|
||||
GameTimer::
|
||||
nop
|
||||
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wGameTime)
|
||||
ldh [rSVBK], a
|
||||
|
||||
call .Function
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
|
||||
.Function:
|
||||
; Increment the game timer by one frame.
|
||||
; The game timer is capped at 999:59:59.00.
|
||||
|
||||
; Don't update if game logic is paused.
|
||||
ld a, [wGameLogicPaused]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; Is the timer paused?
|
||||
ld hl, wGameTimerPaused
|
||||
bit GAME_TIMER_PAUSED_F, [hl]
|
||||
ret z
|
||||
|
||||
; Is the timer already capped?
|
||||
ld hl, wGameTimeCap
|
||||
bit 0, [hl]
|
||||
ret nz
|
||||
|
||||
; +1 frame
|
||||
ld hl, wGameTimeFrames
|
||||
ld a, [hl]
|
||||
inc a
|
||||
|
||||
cp 60 ; frames/second
|
||||
jr nc, .second
|
||||
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
.second
|
||||
xor a
|
||||
ld [hl], a
|
||||
|
||||
; +1 second
|
||||
ld hl, wGameTimeSeconds
|
||||
ld a, [hl]
|
||||
inc a
|
||||
|
||||
cp 60 ; seconds/minute
|
||||
jr nc, .minute
|
||||
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
.minute
|
||||
xor a
|
||||
ld [hl], a
|
||||
|
||||
; +1 minute
|
||||
ld hl, wGameTimeMinutes
|
||||
ld a, [hl]
|
||||
inc a
|
||||
|
||||
cp 60 ; minutes/hour
|
||||
jr nc, .hour
|
||||
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
.hour
|
||||
xor a
|
||||
ld [hl], a
|
||||
|
||||
; +1 hour
|
||||
ld a, [wGameTimeHours]
|
||||
ld h, a
|
||||
ld a, [wGameTimeHours + 1]
|
||||
ld l, a
|
||||
inc hl
|
||||
|
||||
; Cap the timer after 1000 hours.
|
||||
ld a, h
|
||||
cp HIGH(1000)
|
||||
jr c, .ok
|
||||
|
||||
ld a, l
|
||||
cp LOW(1000)
|
||||
jr c, .ok
|
||||
|
||||
ld hl, wGameTimeCap
|
||||
set 0, [hl]
|
||||
|
||||
ld a, 59 ; 999:59:59.00
|
||||
ld [wGameTimeMinutes], a
|
||||
ld [wGameTimeSeconds], a
|
||||
ret
|
||||
|
||||
.ok
|
||||
ld a, h
|
||||
ld [wGameTimeHours], a
|
||||
ld a, l
|
||||
ld [wGameTimeHours + 1], a
|
||||
ret
|
||||
392
home/gfx.asm
Normal file
392
home/gfx.asm
Normal file
|
|
@ -0,0 +1,392 @@
|
|||
DEF TILES_PER_CYCLE EQU 8
|
||||
DEF MOBILE_TILES_PER_CYCLE EQU 6
|
||||
|
||||
Get2bppViaHDMA::
|
||||
ldh a, [rLCDC]
|
||||
bit rLCDC_ENABLE, a
|
||||
jp z, Copy2bpp
|
||||
|
||||
homecall HDMATransfer2bpp
|
||||
|
||||
ret
|
||||
|
||||
Get1bppViaHDMA::
|
||||
ldh a, [rLCDC]
|
||||
bit rLCDC_ENABLE, a
|
||||
jp z, Copy1bpp
|
||||
|
||||
homecall HDMATransfer1bpp
|
||||
|
||||
ret
|
||||
|
||||
FarCopyBytesDouble_DoubleBankSwitch::
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
|
||||
call FarCopyBytesDouble
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
SafeHDMATransfer: ; unreferenced
|
||||
dec c
|
||||
ldh a, [hBGMapMode]
|
||||
push af
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
|
||||
.loop
|
||||
; load the source and target MSB and LSB
|
||||
ld a, d
|
||||
ldh [rHDMA1], a ; source MSB
|
||||
ld a, e
|
||||
and $f0
|
||||
ldh [rHDMA2], a ; source LSB
|
||||
ld a, h
|
||||
and $1f
|
||||
ldh [rHDMA3], a ; target MSB
|
||||
ld a, l
|
||||
and $f0
|
||||
ldh [rHDMA4], a ; target LSB
|
||||
; stop when c < TILES_PER_CYCLE
|
||||
ld a, c
|
||||
cp TILES_PER_CYCLE
|
||||
jr c, .done
|
||||
; decrease c by TILES_PER_CYCLE
|
||||
sub TILES_PER_CYCLE
|
||||
ld c, a
|
||||
; DMA transfer state
|
||||
ld a, $f
|
||||
ldh [hDMATransfer], a
|
||||
call DelayFrame
|
||||
; add $100 to hl and de
|
||||
ld a, l
|
||||
add LOW($100)
|
||||
ld l, a
|
||||
ld a, h
|
||||
adc HIGH($100)
|
||||
ld h, a
|
||||
ld a, e
|
||||
add LOW($100)
|
||||
ld e, a
|
||||
ld a, d
|
||||
adc HIGH($100)
|
||||
ld d, a
|
||||
jr .loop
|
||||
|
||||
.done
|
||||
ld a, c
|
||||
and $7f ; pretty silly, considering at most bits 0-2 would be set
|
||||
ldh [hDMATransfer], a
|
||||
call DelayFrame
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
pop af
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
UpdatePlayerSprite::
|
||||
farcall _UpdatePlayerSprite
|
||||
ret
|
||||
|
||||
LoadStandardFont::
|
||||
farcall _LoadStandardFont
|
||||
ret
|
||||
|
||||
LoadFontsBattleExtra::
|
||||
farcall _LoadFontsBattleExtra
|
||||
ret
|
||||
|
||||
LoadFontsExtra::
|
||||
farcall _LoadFontsExtra1
|
||||
farcall _LoadFontsExtra2
|
||||
ret
|
||||
|
||||
LoadFontsExtra2: ; unreferenced
|
||||
farcall _LoadFontsExtra2
|
||||
ret
|
||||
|
||||
DecompressRequest2bpp::
|
||||
push de
|
||||
ld a, BANK(sScratch)
|
||||
call OpenSRAM
|
||||
push bc
|
||||
|
||||
ld de, sScratch
|
||||
ld a, b
|
||||
call FarDecompress
|
||||
|
||||
pop bc
|
||||
pop hl
|
||||
|
||||
ld de, sScratch
|
||||
call Request2bpp
|
||||
call CloseSRAM
|
||||
ret
|
||||
|
||||
FarCopyBytes::
|
||||
; copy bc bytes from a:hl to de
|
||||
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
|
||||
call CopyBytes
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
FarCopyBytesDouble:
|
||||
; Copy bc bytes from a:hl to bc*2 bytes at de,
|
||||
; doubling each byte in the process.
|
||||
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
|
||||
; switcheroo, de <> hl
|
||||
ld a, h
|
||||
ld h, d
|
||||
ld d, a
|
||||
ld a, l
|
||||
ld l, e
|
||||
ld e, a
|
||||
|
||||
inc b
|
||||
inc c
|
||||
jr .dec
|
||||
|
||||
.loop
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld [hli], a
|
||||
ld [hli], a
|
||||
.dec
|
||||
dec c
|
||||
jr nz, .loop
|
||||
dec b
|
||||
jr nz, .loop
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
Request2bpp::
|
||||
; Load 2bpp at b:de to occupy c tiles of hl.
|
||||
ldh a, [hBGMapMode]
|
||||
push af
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
|
||||
ldh a, [hTilesPerCycle]
|
||||
push af
|
||||
ld a, TILES_PER_CYCLE
|
||||
ldh [hTilesPerCycle], a
|
||||
|
||||
ld a, [wLinkMode]
|
||||
cp LINK_MOBILE
|
||||
jr nz, .NotMobile
|
||||
ldh a, [hMobile]
|
||||
and a
|
||||
jr nz, .NotMobile
|
||||
ld a, MOBILE_TILES_PER_CYCLE
|
||||
ldh [hTilesPerCycle], a
|
||||
|
||||
.NotMobile:
|
||||
ld a, e
|
||||
ld [wRequested2bppSource], a
|
||||
ld a, d
|
||||
ld [wRequested2bppSource + 1], a
|
||||
ld a, l
|
||||
ld [wRequested2bppDest], a
|
||||
ld a, h
|
||||
ld [wRequested2bppDest + 1], a
|
||||
.loop
|
||||
ld a, c
|
||||
ld hl, hTilesPerCycle
|
||||
cp [hl]
|
||||
jr nc, .cycle
|
||||
|
||||
ld [wRequested2bppSize], a
|
||||
.wait
|
||||
call DelayFrame
|
||||
ld a, [wRequested2bppSize]
|
||||
and a
|
||||
jr nz, .wait
|
||||
|
||||
pop af
|
||||
ldh [hTilesPerCycle], a
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
pop af
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
.cycle
|
||||
ldh a, [hTilesPerCycle]
|
||||
ld [wRequested2bppSize], a
|
||||
|
||||
.wait2
|
||||
call DelayFrame
|
||||
ld a, [wRequested2bppSize]
|
||||
and a
|
||||
jr nz, .wait2
|
||||
|
||||
ld a, c
|
||||
ld hl, hTilesPerCycle
|
||||
sub [hl]
|
||||
ld c, a
|
||||
jr .loop
|
||||
|
||||
Request1bpp::
|
||||
; Load 1bpp at b:de to occupy c tiles of hl.
|
||||
ldh a, [hBGMapMode]
|
||||
push af
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
|
||||
ldh a, [hTilesPerCycle]
|
||||
push af
|
||||
ld a, TILES_PER_CYCLE
|
||||
ldh [hTilesPerCycle], a
|
||||
|
||||
ld a, [wLinkMode]
|
||||
cp LINK_MOBILE
|
||||
jr nz, .NotMobile
|
||||
ldh a, [hMobile]
|
||||
and a
|
||||
jr nz, .NotMobile
|
||||
ld a, MOBILE_TILES_PER_CYCLE
|
||||
ldh [hTilesPerCycle], a
|
||||
|
||||
.NotMobile:
|
||||
ld a, e
|
||||
ld [wRequested1bppSource], a
|
||||
ld a, d
|
||||
ld [wRequested1bppSource + 1], a
|
||||
ld a, l
|
||||
ld [wRequested1bppDest], a
|
||||
ld a, h
|
||||
ld [wRequested1bppDest + 1], a
|
||||
.loop
|
||||
ld a, c
|
||||
ld hl, hTilesPerCycle
|
||||
cp [hl]
|
||||
jr nc, .cycle
|
||||
|
||||
ld [wRequested1bppSize], a
|
||||
.wait
|
||||
call DelayFrame
|
||||
ld a, [wRequested1bppSize]
|
||||
and a
|
||||
jr nz, .wait
|
||||
|
||||
pop af
|
||||
ldh [hTilesPerCycle], a
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
pop af
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
.cycle
|
||||
ldh a, [hTilesPerCycle]
|
||||
ld [wRequested1bppSize], a
|
||||
|
||||
.wait2
|
||||
call DelayFrame
|
||||
ld a, [wRequested1bppSize]
|
||||
and a
|
||||
jr nz, .wait2
|
||||
|
||||
ld a, c
|
||||
ld hl, hTilesPerCycle
|
||||
sub [hl]
|
||||
ld c, a
|
||||
jr .loop
|
||||
|
||||
Get2bpp::
|
||||
; copy c 2bpp tiles from b:de to hl
|
||||
ldh a, [rLCDC]
|
||||
bit rLCDC_ENABLE, a
|
||||
jp nz, Request2bpp
|
||||
; fallthrough
|
||||
|
||||
Copy2bpp:
|
||||
push hl
|
||||
ld h, d
|
||||
ld l, e
|
||||
pop de
|
||||
|
||||
; bank
|
||||
ld a, b
|
||||
|
||||
; bc = c * LEN_2BPP_TILE
|
||||
push af
|
||||
swap c
|
||||
ld a, $f
|
||||
and c
|
||||
ld b, a
|
||||
ld a, $f0
|
||||
and c
|
||||
ld c, a
|
||||
pop af
|
||||
|
||||
jp FarCopyBytes
|
||||
|
||||
Get1bpp::
|
||||
; copy c 1bpp tiles from b:de to hl
|
||||
ldh a, [rLCDC]
|
||||
bit rLCDC_ENABLE, a
|
||||
jp nz, Request1bpp
|
||||
; fallthrough
|
||||
|
||||
Copy1bpp::
|
||||
push de
|
||||
ld d, h
|
||||
ld e, l
|
||||
|
||||
; bank
|
||||
ld a, b
|
||||
|
||||
; bc = c * LEN_1BPP_TILE
|
||||
push af
|
||||
ld h, 0
|
||||
ld l, c
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
ld b, h
|
||||
ld c, l
|
||||
pop af
|
||||
|
||||
pop hl
|
||||
jp FarCopyBytesDouble
|
||||
70
home/header.asm
Normal file
70
home/header.asm
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
; rst vectors (called through the rst instruction)
|
||||
|
||||
SECTION "rst0", ROM0[$0000]
|
||||
di
|
||||
jp Start
|
||||
|
||||
SECTION "rst8", ROM0[$0008]
|
||||
FarCall::
|
||||
jp FarCall_hl
|
||||
|
||||
SECTION "rst10", ROM0[$0010]
|
||||
Bankswitch::
|
||||
ldh [hROMBank], a
|
||||
ld [MBC3RomBank], a
|
||||
ret
|
||||
|
||||
SECTION "rst18", ROM0[$0018]
|
||||
rst $38
|
||||
|
||||
SECTION "rst20", ROM0[$0020]
|
||||
rst $38
|
||||
|
||||
SECTION "rst28", ROM0[$0028]
|
||||
JumpTable::
|
||||
push de
|
||||
ld e, a
|
||||
ld d, 0
|
||||
add hl, de
|
||||
add hl, de
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
; SECTION "rst30", ROM0[$0030]
|
||||
ld l, a
|
||||
pop de
|
||||
jp hl
|
||||
|
||||
SECTION "rst38", ROM0[$0038]
|
||||
rst $38
|
||||
|
||||
|
||||
; Game Boy hardware interrupts
|
||||
|
||||
SECTION "vblank", ROM0[$0040]
|
||||
jp VBlank
|
||||
|
||||
SECTION "lcd", ROM0[$0048]
|
||||
jp LCD
|
||||
|
||||
SECTION "timer", ROM0[$0050]
|
||||
jp MobileTimer
|
||||
|
||||
SECTION "serial", ROM0[$0058]
|
||||
jp Serial
|
||||
|
||||
SECTION "joypad", ROM0[$0060]
|
||||
jp Joypad
|
||||
|
||||
|
||||
SECTION "Header", ROM0[$0100]
|
||||
|
||||
Start::
|
||||
; Nintendo requires all Game Boy ROMs to begin with a nop ($00) and a jp ($C3)
|
||||
; to the starting address.
|
||||
nop
|
||||
jp _Start
|
||||
|
||||
; The Game Boy cartridge header data is patched over by rgbfix.
|
||||
; This makes sure it doesn't get used for anything else.
|
||||
|
||||
ds $0150 - @, $00
|
||||
28
home/hm_moves.asm
Normal file
28
home/hm_moves.asm
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
; HM moves can't be forgotten
|
||||
|
||||
IsHM::
|
||||
cp HM01
|
||||
jr c, .NotHM
|
||||
scf
|
||||
ret
|
||||
.NotHM:
|
||||
and a
|
||||
ret
|
||||
|
||||
IsHMMove::
|
||||
call GetMoveIndexFromID
|
||||
ld b, h
|
||||
ld c, l
|
||||
ld hl, .HMMoves
|
||||
ld de, 2
|
||||
jp IsInWordArray
|
||||
|
||||
.HMMoves:
|
||||
dw CUT
|
||||
dw FLY
|
||||
dw SURF
|
||||
dw STRENGTH
|
||||
dw FLASH
|
||||
dw WATERFALL
|
||||
dw WHIRLPOOL
|
||||
dw -1 ; end
|
||||
76
home/indirection.asm
Normal file
76
home/indirection.asm
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
LoadIndirectPointer::
|
||||
; in: a:hl: indirect table, bc: index
|
||||
; out: a:hl: pointer to element, b: copy of a, c: clobbered, de: preserved, zero flag: set if pointer is null
|
||||
push de
|
||||
ld d, a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, d
|
||||
rst Bankswitch
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld a, [hli]
|
||||
ld d, a
|
||||
add a, a
|
||||
jr nc, .loop
|
||||
res 7, d
|
||||
dec bc
|
||||
ld a, b
|
||||
and c
|
||||
inc a
|
||||
jr nz, .loop
|
||||
.null
|
||||
ld hl, 0
|
||||
ld b, h
|
||||
.done
|
||||
pop af
|
||||
rst Bankswitch
|
||||
pop de
|
||||
ld a, h
|
||||
or l
|
||||
ld a, b
|
||||
ret
|
||||
|
||||
.next
|
||||
inc hl
|
||||
inc hl
|
||||
inc hl
|
||||
cpl
|
||||
inc a
|
||||
add a, c
|
||||
ld c, a
|
||||
jr c, .loop ;subtracting by addition has the carry flipped
|
||||
dec b
|
||||
.loop
|
||||
ld a, [hli]
|
||||
and a
|
||||
jr z, .null
|
||||
inc b
|
||||
dec b
|
||||
jr nz, .next
|
||||
cp c
|
||||
jr c, .next
|
||||
jr z, .next
|
||||
|
||||
ld a, [hli]
|
||||
ld b, a
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
or h
|
||||
jr z, .done ;no point in setting them to zero if they already are
|
||||
ld a, c
|
||||
ld c, e
|
||||
ld e, b
|
||||
ld b, d
|
||||
call AddNTimes
|
||||
ld b, e
|
||||
jr .done
|
||||
|
||||
LoadDoubleIndirectPointer::
|
||||
; for indirect tables of near pointers to data, used for structures of varying size
|
||||
; same calling convention as LoadIndirectPointer
|
||||
call LoadIndirectPointer
|
||||
call nz, GetFarWord
|
||||
ld a, b
|
||||
ret
|
||||
216
home/init.asm
Normal file
216
home/init.asm
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
Reset::
|
||||
di
|
||||
call InitSound
|
||||
xor a
|
||||
ldh [hMapAnims], a
|
||||
call ClearPalettes
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ld a, 1 << VBLANK
|
||||
ldh [rIE], a
|
||||
ei
|
||||
|
||||
ld hl, wJoypadDisable
|
||||
set JOYPAD_DISABLE_SGB_TRANSFER_F, [hl]
|
||||
|
||||
ld c, 32
|
||||
call DelayFrames
|
||||
|
||||
jr Init
|
||||
|
||||
_Start::
|
||||
cp $11
|
||||
jr z, .cgb
|
||||
xor a ; FALSE
|
||||
jr .load
|
||||
|
||||
.cgb
|
||||
ld a, TRUE
|
||||
|
||||
.load
|
||||
ldh [hCGB], a
|
||||
ld a, TRUE
|
||||
ldh [hSystemBooted], a
|
||||
|
||||
Init::
|
||||
di
|
||||
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ldh [rIE], a
|
||||
ldh [rRP], a
|
||||
ldh [rSCX], a
|
||||
ldh [rSCY], a
|
||||
ldh [rSB], a
|
||||
ldh [rSC], a
|
||||
ldh [rWX], a
|
||||
ldh [rWY], a
|
||||
ldh [rBGP], a
|
||||
ldh [rOBP0], a
|
||||
ldh [rOBP1], a
|
||||
ldh [rTMA], a
|
||||
ldh [rTAC], a
|
||||
ld [wBetaTitleSequenceOpeningType], a
|
||||
|
||||
ld a, %100 ; Start timer at 4096Hz
|
||||
ldh [rTAC], a
|
||||
|
||||
.wait
|
||||
ldh a, [rLY]
|
||||
cp LY_VBLANK + 1
|
||||
jr nz, .wait
|
||||
|
||||
xor a
|
||||
ldh [rLCDC], a
|
||||
|
||||
; Clear WRAM bank 0
|
||||
ld hl, WRAM0_Begin
|
||||
ld bc, WRAM0_End - WRAM0_Begin
|
||||
.ByteFill:
|
||||
ld [hl], 0
|
||||
inc hl
|
||||
dec bc
|
||||
ld a, b
|
||||
or c
|
||||
jr nz, .ByteFill
|
||||
|
||||
ld sp, wStackTop
|
||||
|
||||
; Clear HRAM
|
||||
ldh a, [hCGB]
|
||||
push af
|
||||
ldh a, [hSystemBooted]
|
||||
push af
|
||||
xor a
|
||||
ld hl, HRAM_Begin
|
||||
ld bc, HRAM_End - HRAM_Begin
|
||||
call ByteFill
|
||||
pop af
|
||||
ldh [hSystemBooted], a
|
||||
pop af
|
||||
ldh [hCGB], a
|
||||
ld a, -1
|
||||
ldh [hSRAMBank], a
|
||||
|
||||
call ClearWRAM
|
||||
ld a, 1
|
||||
ldh [rSVBK], a
|
||||
call ClearVRAM
|
||||
call ClearSprites
|
||||
call ClearsScratch
|
||||
|
||||
ld a, BANK(WriteOAMDMACodeToHRAM) ; aka BANK(GameInit)
|
||||
rst Bankswitch
|
||||
|
||||
call WriteOAMDMACodeToHRAM
|
||||
|
||||
xor a
|
||||
ldh [hMapAnims], a
|
||||
ldh [hSCX], a
|
||||
ldh [hSCY], a
|
||||
ldh [rJOYP], a
|
||||
|
||||
ld a, $8 ; HBlank int enable
|
||||
ldh [rSTAT], a
|
||||
|
||||
ld a, $90
|
||||
ldh [hWY], a
|
||||
ldh [rWY], a
|
||||
|
||||
ld a, 7
|
||||
ldh [hWX], a
|
||||
ldh [rWX], a
|
||||
|
||||
ld a, LCDC_DEFAULT ; %11100011
|
||||
; LCD on
|
||||
; Win tilemap 1
|
||||
; Win on
|
||||
; BG/Win tiledata 0
|
||||
; BG Tilemap 0
|
||||
; OBJ 8x8
|
||||
; OBJ on
|
||||
; BG on
|
||||
ldh [rLCDC], a
|
||||
|
||||
ld a, CONNECTION_NOT_ESTABLISHED
|
||||
ldh [hSerialConnectionStatus], a
|
||||
|
||||
farcall InitCGBPals
|
||||
|
||||
ld a, HIGH(vBGMap1)
|
||||
ldh [hBGMapAddress + 1], a
|
||||
xor a ; LOW(vBGMap1)
|
||||
ldh [hBGMapAddress], a
|
||||
|
||||
farcall StartClock
|
||||
|
||||
xor a ; SRAM_DISABLE
|
||||
ld [MBC3LatchClock], a
|
||||
ld [MBC3SRamEnable], a
|
||||
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .no_double_speed
|
||||
call NormalSpeed
|
||||
.no_double_speed
|
||||
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ld a, IE_DEFAULT
|
||||
ldh [rIE], a
|
||||
ei
|
||||
|
||||
call DelayFrame
|
||||
|
||||
predef InitSGBBorder
|
||||
|
||||
call InitSound
|
||||
xor a
|
||||
ld [wMapMusic], a
|
||||
jp GameInit
|
||||
|
||||
ClearVRAM::
|
||||
; Wipe VRAM banks 0 and 1
|
||||
|
||||
ld a, 1
|
||||
ldh [rVBK], a
|
||||
call .clear
|
||||
|
||||
xor a ; 0
|
||||
ldh [rVBK], a
|
||||
.clear
|
||||
ld hl, VRAM_Begin
|
||||
ld bc, VRAM_End - VRAM_Begin
|
||||
xor a
|
||||
call ByteFill
|
||||
ret
|
||||
|
||||
ClearWRAM::
|
||||
; Wipe swappable WRAM banks (1-7)
|
||||
; Assumes CGB or AGB
|
||||
|
||||
ld a, 1
|
||||
.bank_loop
|
||||
push af
|
||||
ldh [rSVBK], a
|
||||
xor a
|
||||
ld hl, WRAM1_Begin
|
||||
ld bc, WRAM1_End - WRAM1_Begin
|
||||
call ByteFill
|
||||
pop af
|
||||
inc a
|
||||
cp 8
|
||||
jr c, .bank_loop
|
||||
ret
|
||||
|
||||
ClearsScratch::
|
||||
; Wipe the first 32 bytes of sScratch
|
||||
|
||||
ld a, BANK(sScratch)
|
||||
call OpenSRAM
|
||||
ld hl, sScratch
|
||||
ld bc, $20
|
||||
xor a
|
||||
call ByteFill
|
||||
call CloseSRAM
|
||||
ret
|
||||
70
home/item.asm
Normal file
70
home/item.asm
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
DoItemEffect::
|
||||
farcall _DoItemEffect
|
||||
ret
|
||||
|
||||
CheckTossableItem::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
farcall _CheckTossableItem
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
TossItem::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_TossItem)
|
||||
rst Bankswitch
|
||||
|
||||
call _TossItem
|
||||
|
||||
pop bc
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
ReceiveItem::
|
||||
push bc
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_ReceiveItem)
|
||||
rst Bankswitch
|
||||
push hl
|
||||
push de
|
||||
|
||||
call _ReceiveItem
|
||||
|
||||
pop de
|
||||
pop hl
|
||||
pop bc
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
pop bc
|
||||
ret
|
||||
|
||||
CheckItem::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_CheckItem)
|
||||
rst Bankswitch
|
||||
|
||||
call _CheckItem
|
||||
|
||||
pop bc
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
483
home/joypad.asm
Normal file
483
home/joypad.asm
Normal file
|
|
@ -0,0 +1,483 @@
|
|||
Joypad::
|
||||
; Replaced by UpdateJoypad, called from VBlank instead of the useless
|
||||
; joypad interrupt.
|
||||
|
||||
; This is a placeholder in case the interrupt is somehow enabled.
|
||||
reti
|
||||
|
||||
ClearJoypad::
|
||||
xor a
|
||||
; Pressed this frame (delta)
|
||||
ldh [hJoyPressed], a
|
||||
; Currently pressed
|
||||
ldh [hJoyDown], a
|
||||
ret
|
||||
|
||||
UpdateJoypad::
|
||||
; This is called automatically every frame in VBlank.
|
||||
; Read the joypad register and translate it to something more
|
||||
; workable for use in-game. There are 8 buttons, so we can use
|
||||
; one byte to contain all player input.
|
||||
|
||||
; Updates:
|
||||
|
||||
; hJoypadReleased: released this frame (delta)
|
||||
; hJoypadPressed: pressed this frame (delta)
|
||||
; hJoypadDown: currently pressed
|
||||
; hJoypadSum: pressed so far
|
||||
|
||||
; Any of these three bits can be used to disable input.
|
||||
ld a, [wJoypadDisable]
|
||||
and (1 << JOYPAD_DISABLE_MON_FAINT_F) | (1 << JOYPAD_DISABLE_SGB_TRANSFER_F) | (1 << 4)
|
||||
ret nz
|
||||
|
||||
; If we're saving, input is disabled.
|
||||
ld a, [wGameLogicPaused]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; We can only get four inputs at a time.
|
||||
; We take d-pad first for no particular reason.
|
||||
ld a, R_DPAD
|
||||
ldh [rJOYP], a
|
||||
; Read twice to give the request time to take.
|
||||
ldh a, [rJOYP]
|
||||
ldh a, [rJOYP]
|
||||
|
||||
; The Joypad register output is in the lo nybble (inversed).
|
||||
; We make the hi nybble of our new container d-pad input.
|
||||
cpl
|
||||
and $f
|
||||
swap a
|
||||
|
||||
; We'll keep this in b for now.
|
||||
ld b, a
|
||||
|
||||
; Buttons make 8 total inputs (A, B, Select, Start).
|
||||
; We can fit this into one byte.
|
||||
ld a, R_BUTTONS
|
||||
ldh [rJOYP], a
|
||||
; Wait for input to stabilize.
|
||||
rept 6
|
||||
ldh a, [rJOYP]
|
||||
endr
|
||||
; Buttons take the lo nybble.
|
||||
cpl
|
||||
and $f
|
||||
or b
|
||||
ld b, a
|
||||
|
||||
; Reset the joypad register since we're done with it.
|
||||
ld a, $30
|
||||
ldh [rJOYP], a
|
||||
|
||||
; To get the delta we xor the last frame's input with the new one.
|
||||
ldh a, [hJoypadDown] ; last frame
|
||||
ld e, a
|
||||
xor b
|
||||
ld d, a
|
||||
; Released this frame:
|
||||
and e
|
||||
ldh [hJoypadReleased], a
|
||||
; Pressed this frame:
|
||||
ld a, d
|
||||
and b
|
||||
ldh [hJoypadPressed], a
|
||||
|
||||
; Add any new presses to the list of collective presses:
|
||||
ld c, a
|
||||
ldh a, [hJoypadSum]
|
||||
or c
|
||||
ldh [hJoypadSum], a
|
||||
|
||||
; Currently pressed:
|
||||
ld a, b
|
||||
ldh [hJoypadDown], a
|
||||
|
||||
; Now that we have the input, we can do stuff with it.
|
||||
|
||||
; For example, soft reset:
|
||||
and A_BUTTON | B_BUTTON | SELECT | START
|
||||
cp A_BUTTON | B_BUTTON | SELECT | START
|
||||
jp z, Reset
|
||||
|
||||
ret
|
||||
|
||||
GetJoypad::
|
||||
; Update mirror joypad input from hJoypadDown (real input)
|
||||
|
||||
; hJoyReleased: released this frame (delta)
|
||||
; hJoyPressed: pressed this frame (delta)
|
||||
; hJoyDown: currently pressed
|
||||
|
||||
; bit 0 A
|
||||
; 1 B
|
||||
; 2 SELECT
|
||||
; 3 START
|
||||
; 4 RIGHT
|
||||
; 5 LEFT
|
||||
; 6 UP
|
||||
; 7 DOWN
|
||||
|
||||
push af
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
; The player input can be automated using an input stream.
|
||||
; See more below.
|
||||
ld a, [wInputType]
|
||||
cp AUTO_INPUT
|
||||
jr z, .auto
|
||||
|
||||
; To get deltas, take this and last frame's input.
|
||||
ldh a, [hJoypadDown] ; real input
|
||||
ld b, a
|
||||
ldh a, [hJoyDown] ; last frame mirror
|
||||
ld e, a
|
||||
|
||||
; Released this frame:
|
||||
xor b
|
||||
ld d, a
|
||||
and e
|
||||
ldh [hJoyReleased], a
|
||||
|
||||
; Pressed this frame:
|
||||
ld a, d
|
||||
and b
|
||||
ldh [hJoyPressed], a
|
||||
|
||||
; It looks like the collective presses got commented out here.
|
||||
ld c, a
|
||||
|
||||
; Currently pressed:
|
||||
ld a, b
|
||||
ldh [hJoyDown], a ; frame input
|
||||
|
||||
.quit
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
pop af
|
||||
ret
|
||||
|
||||
.auto
|
||||
; Use a predetermined input stream (used in the catching tutorial).
|
||||
|
||||
; Stream format: [input][duration]
|
||||
; A value of $ff will immediately end the stream.
|
||||
|
||||
; Read from the input stream.
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, [wAutoInputBank]
|
||||
rst Bankswitch
|
||||
|
||||
ld hl, wAutoInputAddress
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
; We only update when the input duration has expired.
|
||||
ld a, [wAutoInputLength]
|
||||
and a
|
||||
jr z, .updateauto
|
||||
|
||||
; Until then, don't change anything.
|
||||
dec a
|
||||
ld [wAutoInputLength], a
|
||||
pop af
|
||||
rst Bankswitch
|
||||
jr .quit
|
||||
|
||||
.updateauto
|
||||
; An input of $ff will end the stream.
|
||||
ld a, [hli]
|
||||
cp -1
|
||||
jr z, .stopauto
|
||||
ld b, a
|
||||
|
||||
; A duration of $ff will end the stream indefinitely.
|
||||
ld a, [hli]
|
||||
ld [wAutoInputLength], a
|
||||
cp -1
|
||||
jr nz, .next
|
||||
|
||||
; The current input is overwritten.
|
||||
dec hl
|
||||
dec hl
|
||||
ld b, NO_INPUT
|
||||
jr .finishauto
|
||||
|
||||
.next
|
||||
; On to the next input...
|
||||
ld a, l
|
||||
ld [wAutoInputAddress], a
|
||||
ld a, h
|
||||
ld [wAutoInputAddress + 1], a
|
||||
jr .finishauto
|
||||
|
||||
.stopauto
|
||||
call StopAutoInput
|
||||
ld b, NO_INPUT
|
||||
|
||||
.finishauto
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ld a, b
|
||||
ldh [hJoyPressed], a ; pressed
|
||||
ldh [hJoyDown], a ; input
|
||||
jr .quit
|
||||
|
||||
StartAutoInput::
|
||||
; Start reading automated input stream at a:hl.
|
||||
|
||||
ld [wAutoInputBank], a
|
||||
ld a, l
|
||||
ld [wAutoInputAddress], a
|
||||
ld a, h
|
||||
ld [wAutoInputAddress + 1], a
|
||||
; Start reading the stream immediately.
|
||||
xor a
|
||||
ld [wAutoInputLength], a
|
||||
; Reset input mirrors.
|
||||
xor a
|
||||
ldh [hJoyPressed], a ; pressed this frame
|
||||
ldh [hJoyReleased], a ; released this frame
|
||||
ldh [hJoyDown], a ; currently pressed
|
||||
|
||||
ld a, AUTO_INPUT
|
||||
ld [wInputType], a
|
||||
ret
|
||||
|
||||
StopAutoInput::
|
||||
; Clear variables related to automated input.
|
||||
xor a
|
||||
ld [wAutoInputBank], a
|
||||
ld [wAutoInputAddress], a
|
||||
ld [wAutoInputAddress + 1], a
|
||||
ld [wAutoInputLength], a
|
||||
; Back to normal input.
|
||||
ld [wInputType], a
|
||||
ret
|
||||
|
||||
JoyTitleScreenInput:: ; unreferenced
|
||||
.loop
|
||||
call DelayFrame
|
||||
|
||||
push bc
|
||||
call JoyTextDelay
|
||||
pop bc
|
||||
|
||||
; Save data can be deleted by pressing Up + B + Select.
|
||||
ldh a, [hJoyDown]
|
||||
cp D_UP | SELECT | B_BUTTON
|
||||
jr z, .keycombo
|
||||
|
||||
; Press Start or A to start the game.
|
||||
ldh a, [hJoyLast]
|
||||
and START | A_BUTTON
|
||||
jr nz, .keycombo
|
||||
|
||||
dec c
|
||||
jr nz, .loop
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
.keycombo
|
||||
scf
|
||||
ret
|
||||
|
||||
JoyWaitAorB::
|
||||
.loop
|
||||
call DelayFrame
|
||||
call GetJoypad
|
||||
ldh a, [hJoyPressed]
|
||||
and A_BUTTON | B_BUTTON
|
||||
ret nz
|
||||
call UpdateTimeAndPals
|
||||
jr .loop
|
||||
|
||||
WaitButton::
|
||||
ldh a, [hOAMUpdate]
|
||||
push af
|
||||
ld a, 1
|
||||
ldh [hOAMUpdate], a
|
||||
call WaitBGMap
|
||||
call JoyWaitAorB
|
||||
pop af
|
||||
ldh [hOAMUpdate], a
|
||||
ret
|
||||
|
||||
JoyTextDelay::
|
||||
call GetJoypad
|
||||
ldh a, [hInMenu]
|
||||
and a
|
||||
ldh a, [hJoyPressed]
|
||||
jr z, .ok
|
||||
ldh a, [hJoyDown]
|
||||
.ok
|
||||
ldh [hJoyLast], a
|
||||
ldh a, [hJoyPressed]
|
||||
and a
|
||||
jr z, .checkframedelay
|
||||
ld a, 15
|
||||
ld [wTextDelayFrames], a
|
||||
ret
|
||||
|
||||
.checkframedelay
|
||||
ld a, [wTextDelayFrames]
|
||||
and a
|
||||
jr z, .restartframedelay
|
||||
xor a
|
||||
ldh [hJoyLast], a
|
||||
ret
|
||||
|
||||
.restartframedelay
|
||||
ld a, 5
|
||||
ld [wTextDelayFrames], a
|
||||
ret
|
||||
|
||||
WaitPressAorB_BlinkCursor::
|
||||
; Show a blinking cursor in the lower right-hand
|
||||
; corner of a textbox and wait until A or B is
|
||||
; pressed.
|
||||
;
|
||||
; NOTE: The cursor has to be shown before calling
|
||||
; this function or no cursor will be shown at all.
|
||||
ldh a, [hMapObjectIndex]
|
||||
push af
|
||||
ldh a, [hObjectStructIndex]
|
||||
push af
|
||||
xor a
|
||||
ldh [hMapObjectIndex], a
|
||||
ld a, 6
|
||||
ldh [hObjectStructIndex], a
|
||||
|
||||
.loop
|
||||
push hl
|
||||
hlcoord 18, 17
|
||||
call BlinkCursor
|
||||
pop hl
|
||||
|
||||
call JoyTextDelay
|
||||
ldh a, [hJoyLast]
|
||||
and A_BUTTON | B_BUTTON
|
||||
jr z, .loop
|
||||
|
||||
pop af
|
||||
ldh [hObjectStructIndex], a
|
||||
pop af
|
||||
ldh [hMapObjectIndex], a
|
||||
ret
|
||||
|
||||
SimpleWaitPressAorB::
|
||||
.loop
|
||||
call JoyTextDelay
|
||||
ldh a, [hJoyLast]
|
||||
and A_BUTTON | B_BUTTON
|
||||
jr z, .loop
|
||||
ret
|
||||
|
||||
PromptButton::
|
||||
; Show a blinking cursor in the lower right-hand
|
||||
; corner of a textbox and wait until A or B is
|
||||
; pressed, afterwards, play a sound.
|
||||
ld a, [wLinkMode]
|
||||
and a
|
||||
jr nz, .link
|
||||
call .wait_input
|
||||
push de
|
||||
ld de, SFX_READ_TEXT_2
|
||||
call PlaySFX
|
||||
pop de
|
||||
ret
|
||||
|
||||
.link
|
||||
ld c, 65
|
||||
jp DelayFrames
|
||||
|
||||
.wait_input
|
||||
ldh a, [hOAMUpdate]
|
||||
push af
|
||||
ld a, $1
|
||||
ldh [hOAMUpdate], a
|
||||
ld a, [wInputType]
|
||||
or a
|
||||
jr z, .input_wait_loop
|
||||
farcall _DudeAutoInput_A
|
||||
|
||||
.input_wait_loop
|
||||
call .blink_cursor
|
||||
call JoyTextDelay
|
||||
ldh a, [hJoyPressed]
|
||||
and A_BUTTON | B_BUTTON
|
||||
jr nz, .received_input
|
||||
call UpdateTimeAndPals
|
||||
ld a, $1
|
||||
ldh [hBGMapMode], a
|
||||
call DelayFrame
|
||||
jr .input_wait_loop
|
||||
|
||||
.received_input
|
||||
pop af
|
||||
ldh [hOAMUpdate], a
|
||||
ret
|
||||
|
||||
.blink_cursor
|
||||
ldh a, [hVBlankCounter]
|
||||
and %00010000 ; bit 4, a
|
||||
jr z, .cursor_off
|
||||
ld a, "▼"
|
||||
jr .load_cursor_state
|
||||
|
||||
.cursor_off
|
||||
lda_coord 17, 17
|
||||
|
||||
.load_cursor_state
|
||||
ldcoord_a 18, 17
|
||||
ret
|
||||
|
||||
BlinkCursor::
|
||||
push bc
|
||||
ld a, [hl]
|
||||
ld b, a
|
||||
ld a, "▼"
|
||||
cp b
|
||||
pop bc
|
||||
jr nz, .place_arrow
|
||||
ldh a, [hMapObjectIndex]
|
||||
dec a
|
||||
ldh [hMapObjectIndex], a
|
||||
ret nz
|
||||
ldh a, [hObjectStructIndex]
|
||||
dec a
|
||||
ldh [hObjectStructIndex], a
|
||||
ret nz
|
||||
ld a, "─"
|
||||
ld [hl], a
|
||||
ld a, -1
|
||||
ldh [hMapObjectIndex], a
|
||||
ld a, 6
|
||||
ldh [hObjectStructIndex], a
|
||||
ret
|
||||
|
||||
.place_arrow
|
||||
ldh a, [hMapObjectIndex]
|
||||
and a
|
||||
ret z
|
||||
dec a
|
||||
ldh [hMapObjectIndex], a
|
||||
ret nz
|
||||
dec a
|
||||
ldh [hMapObjectIndex], a
|
||||
ldh a, [hObjectStructIndex]
|
||||
dec a
|
||||
ldh [hObjectStructIndex], a
|
||||
ret nz
|
||||
ld a, 6
|
||||
ldh [hObjectStructIndex], a
|
||||
ld a, "▼"
|
||||
ld [hl], a
|
||||
ret
|
||||
63
home/lcd.asm
Normal file
63
home/lcd.asm
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
; LCD handling
|
||||
|
||||
LCD::
|
||||
push af
|
||||
ldh a, [hLCDCPointer]
|
||||
and a
|
||||
jr z, .done
|
||||
|
||||
; At this point it's assumed we're in BANK(wLYOverrides)!
|
||||
push bc
|
||||
ldh a, [rLY]
|
||||
ld c, a
|
||||
ld b, HIGH(wLYOverrides)
|
||||
ld a, [bc]
|
||||
ld b, a
|
||||
ldh a, [hLCDCPointer]
|
||||
ld c, a
|
||||
ld a, b
|
||||
ldh [c], a
|
||||
pop bc
|
||||
|
||||
.done
|
||||
pop af
|
||||
reti
|
||||
|
||||
DisableLCD::
|
||||
; Turn the LCD off
|
||||
|
||||
; Don't need to do anything if the LCD is already off
|
||||
ldh a, [rLCDC]
|
||||
bit rLCDC_ENABLE, a
|
||||
ret z
|
||||
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ldh a, [rIE]
|
||||
ld b, a
|
||||
|
||||
; Disable VBlank
|
||||
res VBLANK, a
|
||||
ldh [rIE], a
|
||||
|
||||
.wait
|
||||
; Wait until VBlank would normally happen
|
||||
ldh a, [rLY]
|
||||
cp LY_VBLANK + 1
|
||||
jr nz, .wait
|
||||
|
||||
ldh a, [rLCDC]
|
||||
and ~(1 << rLCDC_ENABLE)
|
||||
ldh [rLCDC], a
|
||||
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ld a, b
|
||||
ldh [rIE], a
|
||||
ret
|
||||
|
||||
EnableLCD::
|
||||
ldh a, [rLCDC]
|
||||
set rLCDC_ENABLE, a
|
||||
ldh [rLCDC], a
|
||||
ret
|
||||
2248
home/map.asm
Normal file
2248
home/map.asm
Normal file
File diff suppressed because it is too large
Load diff
575
home/map_objects.asm
Normal file
575
home/map_objects.asm
Normal file
|
|
@ -0,0 +1,575 @@
|
|||
; Functions handling map objects.
|
||||
|
||||
GetSpritePalette::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ld c, a
|
||||
|
||||
farcall _GetSpritePalette
|
||||
|
||||
ld a, c
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
GetSpriteVTile::
|
||||
push hl
|
||||
push bc
|
||||
ld hl, wUsedSprites + 2
|
||||
ld c, SPRITE_GFX_LIST_CAPACITY - 1
|
||||
ld b, a
|
||||
ldh a, [hMapObjectIndex]
|
||||
cp 0
|
||||
jr z, .nope
|
||||
ld a, b
|
||||
.loop
|
||||
cp [hl]
|
||||
jr z, .found
|
||||
inc hl
|
||||
inc hl
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ld a, [wUsedSprites + 1]
|
||||
scf
|
||||
jr .done
|
||||
|
||||
.nope
|
||||
ld a, [wUsedSprites + 1]
|
||||
jr .done
|
||||
|
||||
.found
|
||||
inc hl
|
||||
xor a
|
||||
ld a, [hl]
|
||||
|
||||
.done
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
DoesSpriteHaveFacings::
|
||||
push de
|
||||
push hl
|
||||
|
||||
ld b, a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_DoesSpriteHaveFacings)
|
||||
rst Bankswitch
|
||||
|
||||
ld a, b
|
||||
call _DoesSpriteHaveFacings
|
||||
ld c, a
|
||||
|
||||
pop de
|
||||
ld a, d
|
||||
rst Bankswitch
|
||||
|
||||
pop hl
|
||||
pop de
|
||||
ret
|
||||
|
||||
GetPlayerTile::
|
||||
ld a, [wPlayerTile]
|
||||
call GetTileCollision
|
||||
ld b, a
|
||||
ret
|
||||
|
||||
CheckOnWater::
|
||||
ld a, [wPlayerTile]
|
||||
call GetTileCollision
|
||||
sub WATER_TILE
|
||||
ret z
|
||||
and a
|
||||
ret
|
||||
|
||||
GetTileCollision::
|
||||
; Get the collision type of tile a.
|
||||
|
||||
push de
|
||||
push hl
|
||||
|
||||
ld hl, TileCollisionTable
|
||||
ld e, a
|
||||
ld d, 0
|
||||
add hl, de
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(TileCollisionTable)
|
||||
rst Bankswitch
|
||||
ld e, [hl]
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ld a, e
|
||||
and $f ; lo nybble only
|
||||
|
||||
pop hl
|
||||
pop de
|
||||
ret
|
||||
|
||||
CheckGrassTile::
|
||||
ld d, a
|
||||
and $f0
|
||||
cp HI_NYBBLE_TALL_GRASS
|
||||
jr z, .check
|
||||
cp HI_NYBBLE_WATER
|
||||
jr nz, .nope
|
||||
.check
|
||||
ld a, d
|
||||
and LO_NYBBLE_GRASS
|
||||
ret z
|
||||
.nope
|
||||
scf
|
||||
ret
|
||||
|
||||
CheckSuperTallGrassTile::
|
||||
cp COLL_LONG_GRASS
|
||||
ret z
|
||||
cp COLL_LONG_GRASS_1C
|
||||
ret
|
||||
|
||||
CheckCutTreeTile::
|
||||
cp COLL_CUT_TREE
|
||||
ret z
|
||||
cp COLL_CUT_TREE_1A
|
||||
ret
|
||||
|
||||
CheckHeadbuttTreeTile::
|
||||
cp COLL_HEADBUTT_TREE
|
||||
ret z
|
||||
cp COLL_HEADBUTT_TREE_1D
|
||||
ret
|
||||
|
||||
CheckCounterTile::
|
||||
cp COLL_COUNTER
|
||||
ret z
|
||||
cp COLL_COUNTER_98
|
||||
ret
|
||||
|
||||
CheckPitTile::
|
||||
cp COLL_PIT
|
||||
ret z
|
||||
cp COLL_PIT_68
|
||||
ret
|
||||
|
||||
CheckIceTile::
|
||||
cp COLL_ICE
|
||||
ret z
|
||||
cp COLL_ICE_2B
|
||||
ret z
|
||||
scf
|
||||
ret
|
||||
|
||||
CheckWhirlpoolTile::
|
||||
nop
|
||||
cp COLL_WHIRLPOOL
|
||||
ret z
|
||||
cp COLL_WHIRLPOOL_2C
|
||||
ret z
|
||||
scf
|
||||
ret
|
||||
|
||||
CheckWaterfallTile::
|
||||
cp COLL_WATERFALL
|
||||
ret z
|
||||
cp COLL_CURRENT_DOWN
|
||||
ret
|
||||
|
||||
CheckStandingOnEntrance::
|
||||
ld a, [wPlayerTile]
|
||||
cp COLL_DOOR
|
||||
ret z
|
||||
cp COLL_DOOR_79
|
||||
ret z
|
||||
cp COLL_STAIRCASE
|
||||
ret z
|
||||
cp COLL_CAVE
|
||||
ret
|
||||
|
||||
GetMapObject::
|
||||
; Return the location of map object a in bc.
|
||||
ld hl, wMapObjects
|
||||
ld bc, MAPOBJECT_LENGTH
|
||||
call AddNTimes
|
||||
ld b, h
|
||||
ld c, l
|
||||
ret
|
||||
|
||||
CheckObjectVisibility::
|
||||
; Sets carry if the object is not visible on the screen.
|
||||
ldh [hMapObjectIndex], a
|
||||
call GetMapObject
|
||||
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .not_visible
|
||||
ldh [hObjectStructIndex], a
|
||||
call GetObjectStruct
|
||||
and a
|
||||
ret
|
||||
|
||||
.not_visible
|
||||
scf
|
||||
ret
|
||||
|
||||
CheckObjectTime::
|
||||
ld hl, MAPOBJECT_HOUR_1
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr nz, .check_hour
|
||||
ld hl, MAPOBJECT_TIMEOFDAY
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .timeofday_always
|
||||
ld hl, .TimesOfDay
|
||||
ld a, [wTimeOfDay]
|
||||
add l
|
||||
ld l, a
|
||||
jr nc, .ok
|
||||
inc h
|
||||
|
||||
.ok
|
||||
ld a, [hl]
|
||||
ld hl, MAPOBJECT_TIMEOFDAY
|
||||
add hl, bc
|
||||
and [hl]
|
||||
jr nz, .timeofday_always
|
||||
scf
|
||||
ret
|
||||
|
||||
.timeofday_always
|
||||
and a
|
||||
ret
|
||||
|
||||
.TimesOfDay:
|
||||
; entries correspond to TimeOfDay values
|
||||
db MORN
|
||||
db DAY
|
||||
db NITE
|
||||
|
||||
.check_hour
|
||||
ld hl, MAPOBJECT_HOUR_1
|
||||
add hl, bc
|
||||
ld d, [hl]
|
||||
ld hl, MAPOBJECT_HOUR_2
|
||||
add hl, bc
|
||||
ld e, [hl]
|
||||
ld hl, hHours
|
||||
ld a, d
|
||||
cp e
|
||||
ret z
|
||||
jr c, .check_timeofday
|
||||
ld a, [hl]
|
||||
cp d
|
||||
ret nc
|
||||
cp e
|
||||
ret z
|
||||
ccf
|
||||
ret
|
||||
|
||||
.check_timeofday
|
||||
ld a, e
|
||||
cp [hl]
|
||||
ret c
|
||||
ld a, [hl]
|
||||
cp d
|
||||
ret
|
||||
|
||||
UnmaskCopyMapObjectStruct::
|
||||
ldh [hMapObjectIndex], a
|
||||
call UnmaskObject
|
||||
ldh a, [hMapObjectIndex]
|
||||
call GetMapObject
|
||||
farcall CopyObjectStruct
|
||||
ret
|
||||
|
||||
ApplyDeletionToMapObject::
|
||||
ldh [hMapObjectIndex], a
|
||||
call GetMapObject
|
||||
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
ret z ; already hidden
|
||||
ld [hl], -1
|
||||
push af
|
||||
call .CheckStopFollow
|
||||
pop af
|
||||
call GetObjectStruct
|
||||
farcall DeleteMapObject
|
||||
ret
|
||||
|
||||
.CheckStopFollow:
|
||||
ld hl, wObjectFollow_Leader
|
||||
cp [hl]
|
||||
jr z, .ok
|
||||
ld hl, wObjectFollow_Follower
|
||||
cp [hl]
|
||||
ret nz
|
||||
.ok
|
||||
farcall StopFollow
|
||||
ld a, -1
|
||||
ld [wObjectFollow_Leader], a
|
||||
ld [wObjectFollow_Follower], a
|
||||
ret
|
||||
|
||||
DeleteObjectStruct::
|
||||
call ApplyDeletionToMapObject
|
||||
jp MaskObject
|
||||
|
||||
CopyPlayerObjectTemplate::
|
||||
push hl
|
||||
call GetMapObject
|
||||
ld d, b
|
||||
ld e, c
|
||||
ld a, -1
|
||||
ld [de], a
|
||||
inc de
|
||||
pop hl
|
||||
ld bc, MAPOBJECT_LENGTH - 1
|
||||
jp CopyBytes
|
||||
|
||||
LoadMovementDataPointer::
|
||||
; Load the movement data pointer for object a.
|
||||
ld [wMovementObject], a
|
||||
ldh a, [hROMBank]
|
||||
ld [wMovementDataBank], a
|
||||
ld a, l
|
||||
ld [wMovementDataAddress], a
|
||||
ld a, h
|
||||
ld [wMovementDataAddress + 1], a
|
||||
ld a, [wMovementObject]
|
||||
call CheckObjectVisibility
|
||||
ret c
|
||||
|
||||
ld hl, OBJECT_MOVEMENT_TYPE
|
||||
add hl, bc
|
||||
ld [hl], SPRITEMOVEDATA_SCRIPTED
|
||||
|
||||
ld hl, OBJECT_STEP_TYPE
|
||||
add hl, bc
|
||||
ld [hl], STEP_TYPE_RESET
|
||||
|
||||
ld hl, wVramState
|
||||
set 7, [hl]
|
||||
and a
|
||||
ret
|
||||
|
||||
FindFirstEmptyObjectStruct::
|
||||
; Returns the index of the first empty object struct in A and its address in HL, then sets carry.
|
||||
; If all object structs are occupied, A = 0 and Z is set.
|
||||
; Preserves BC and DE.
|
||||
push bc
|
||||
push de
|
||||
ld hl, wObjectStructs
|
||||
ld de, OBJECT_LENGTH
|
||||
ld c, NUM_OBJECT_STRUCTS
|
||||
.loop
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .break
|
||||
add hl, de
|
||||
dec c
|
||||
jr nz, .loop
|
||||
xor a
|
||||
jr .done
|
||||
|
||||
.break
|
||||
ld a, NUM_OBJECT_STRUCTS
|
||||
sub c
|
||||
scf
|
||||
|
||||
.done
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
|
||||
GetSpriteMovementFunction::
|
||||
ld hl, OBJECT_MOVEMENT_TYPE
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
cp NUM_SPRITEMOVEDATA
|
||||
jr c, .ok
|
||||
xor a
|
||||
|
||||
.ok
|
||||
ld hl, SpriteMovementData + SPRITEMOVEATTR_MOVEMENT
|
||||
ld e, a
|
||||
ld d, 0
|
||||
rept NUM_SPRITEMOVEDATA_FIELDS
|
||||
add hl, de
|
||||
endr
|
||||
ld a, [hl]
|
||||
ret
|
||||
|
||||
GetInitialFacing::
|
||||
push bc
|
||||
push de
|
||||
ld e, a
|
||||
ld d, 0
|
||||
ld hl, SpriteMovementData + SPRITEMOVEATTR_FACING
|
||||
rept NUM_SPRITEMOVEDATA_FIELDS
|
||||
add hl, de
|
||||
endr
|
||||
ld a, BANK(SpriteMovementData)
|
||||
call GetFarByte
|
||||
add a
|
||||
add a
|
||||
maskbits NUM_DIRECTIONS, 2
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
|
||||
CopySpriteMovementData::
|
||||
ld l, a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(SpriteMovementData)
|
||||
rst Bankswitch
|
||||
ld a, l
|
||||
push bc
|
||||
|
||||
call .CopyData
|
||||
|
||||
pop bc
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ret
|
||||
|
||||
.CopyData:
|
||||
ld hl, OBJECT_MOVEMENT_TYPE
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
|
||||
push de
|
||||
ld e, a
|
||||
ld d, 0
|
||||
ld hl, SpriteMovementData + SPRITEMOVEATTR_FACING
|
||||
rept NUM_SPRITEMOVEDATA_FIELDS
|
||||
add hl, de
|
||||
endr
|
||||
ld b, h
|
||||
ld c, l
|
||||
pop de
|
||||
|
||||
ld a, [bc]
|
||||
inc bc
|
||||
rlca
|
||||
rlca
|
||||
maskbits NUM_DIRECTIONS, 2
|
||||
ld hl, OBJECT_DIRECTION
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
|
||||
ld a, [bc]
|
||||
inc bc
|
||||
ld hl, OBJECT_ACTION
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
|
||||
ld a, [bc]
|
||||
inc bc
|
||||
ld hl, OBJECT_FLAGS1
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
|
||||
ld a, [bc]
|
||||
inc bc
|
||||
ld hl, OBJECT_FLAGS2
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
|
||||
ld a, [bc]
|
||||
inc bc
|
||||
ld hl, OBJECT_PALETTE
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
_GetMovementIndex::
|
||||
; Switch to the movement data bank
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, [hli]
|
||||
rst Bankswitch
|
||||
; Load the current script byte as given by OBJECT_MOVEMENT_INDEX, and increment OBJECT_MOVEMENT_INDEX
|
||||
ld a, [hli]
|
||||
ld d, [hl]
|
||||
ld hl, OBJECT_MOVEMENT_INDEX
|
||||
add hl, bc
|
||||
add [hl]
|
||||
ld e, a
|
||||
ld a, d
|
||||
adc 0
|
||||
ld d, a
|
||||
inc [hl]
|
||||
ld a, [de]
|
||||
ld h, a
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ld a, h
|
||||
ret
|
||||
|
||||
SetVramState_Bit0:: ; unreferenced
|
||||
ld hl, wVramState
|
||||
set 0, [hl]
|
||||
ret
|
||||
|
||||
ResetVramState_Bit0:: ; unreferenced
|
||||
ld hl, wVramState
|
||||
res 0, [hl]
|
||||
ret
|
||||
|
||||
UpdateSprites::
|
||||
ld a, [wVramState]
|
||||
bit 0, a
|
||||
ret z
|
||||
|
||||
farcall UpdateAllObjectsFrozen
|
||||
farcall _UpdateSprites
|
||||
ret
|
||||
|
||||
GetObjectStruct::
|
||||
ld bc, OBJECT_LENGTH
|
||||
ld hl, wObjectStructs
|
||||
call AddNTimes
|
||||
ld b, h
|
||||
ld c, l
|
||||
ret
|
||||
|
||||
DoesObjectHaveASprite::
|
||||
ld hl, OBJECT_SPRITE
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
and a
|
||||
ret
|
||||
|
||||
SetSpriteDirection::
|
||||
; preserves other flags
|
||||
push af
|
||||
ld hl, OBJECT_DIRECTION
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
and %11110011
|
||||
ld e, a
|
||||
pop af
|
||||
maskbits NUM_DIRECTIONS, 2
|
||||
or e
|
||||
ld [hl], a
|
||||
ret
|
||||
|
||||
GetSpriteDirection::
|
||||
ld hl, OBJECT_DIRECTION
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
maskbits NUM_DIRECTIONS, 2
|
||||
ret
|
||||
58
home/math.asm
Normal file
58
home/math.asm
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
SimpleMultiply::
|
||||
; Return a * c.
|
||||
and a
|
||||
ret z
|
||||
|
||||
push bc
|
||||
ld b, a
|
||||
xor a
|
||||
.loop
|
||||
add c
|
||||
dec b
|
||||
jr nz, .loop
|
||||
pop bc
|
||||
ret
|
||||
|
||||
SimpleDivide::
|
||||
; Divide a by c. Return quotient b and remainder a.
|
||||
ld b, 0
|
||||
.loop
|
||||
inc b
|
||||
sub c
|
||||
jr nc, .loop
|
||||
dec b
|
||||
add c
|
||||
ret
|
||||
|
||||
Multiply::
|
||||
; Multiply hMultiplicand (3 bytes) by hMultiplier. Result in hProduct.
|
||||
; All values are big endian.
|
||||
push hl
|
||||
push bc
|
||||
|
||||
callfar _Multiply
|
||||
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
Divide::
|
||||
; Divide hDividend length b (max 4 bytes) by hDivisor. Result in hQuotient.
|
||||
; All values are big endian.
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
homecall _Divide
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
SubtractAbsolute:: ; unreferenced
|
||||
; Return |a - b|, sign in carry.
|
||||
sub b
|
||||
ret nc
|
||||
cpl
|
||||
add 1
|
||||
scf
|
||||
ret
|
||||
813
home/menu.asm
Normal file
813
home/menu.asm
Normal file
|
|
@ -0,0 +1,813 @@
|
|||
Load2DMenuData::
|
||||
push hl
|
||||
push bc
|
||||
ld hl, w2DMenuData
|
||||
ld b, w2DMenuDataEnd - w2DMenuData
|
||||
.loop
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld [hli], a
|
||||
dec b
|
||||
jr nz, .loop
|
||||
|
||||
; Reset menu state
|
||||
ld a, $1
|
||||
ld [hli], a ; wMenuCursorY
|
||||
ld [hli], a ; wMenuCursorX
|
||||
xor a
|
||||
ld [hli], a ; wCursorOffCharacter
|
||||
ld [hli], a ; wCursorCurrentTile
|
||||
ld [hli], a
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
StaticMenuJoypad::
|
||||
callfar _StaticMenuJoypad
|
||||
jr GetMenuJoypad
|
||||
|
||||
ScrollingMenuJoypad::
|
||||
callfar _ScrollingMenuJoypad
|
||||
; fallthrough
|
||||
|
||||
GetMenuJoypad::
|
||||
push bc
|
||||
push af
|
||||
ldh a, [hJoyLast]
|
||||
and D_PAD
|
||||
ld b, a
|
||||
ldh a, [hJoyPressed]
|
||||
and BUTTONS
|
||||
or b
|
||||
ld b, a
|
||||
pop af
|
||||
ld a, b
|
||||
pop bc
|
||||
ret
|
||||
|
||||
PlaceHollowCursor::
|
||||
ld hl, wCursorCurrentTile
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld [hl], "▷"
|
||||
ret
|
||||
|
||||
HideCursor::
|
||||
ld hl, wCursorCurrentTile
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld [hl], " "
|
||||
ret
|
||||
|
||||
PushWindow::
|
||||
callfar _PushWindow
|
||||
ret
|
||||
|
||||
ExitMenu::
|
||||
push af
|
||||
callfar _ExitMenu
|
||||
pop af
|
||||
ret
|
||||
|
||||
InitVerticalMenuCursor::
|
||||
callfar _InitVerticalMenuCursor
|
||||
ret
|
||||
|
||||
CloseWindow::
|
||||
push af
|
||||
call ExitMenu
|
||||
call ApplyTilemap
|
||||
call UpdateSprites
|
||||
pop af
|
||||
ret
|
||||
|
||||
RestoreTileBackup::
|
||||
call MenuBoxCoord2Tile
|
||||
call .copy
|
||||
call MenuBoxCoord2Attr
|
||||
|
||||
.copy
|
||||
call GetMenuBoxDims
|
||||
inc b
|
||||
inc c
|
||||
|
||||
.row
|
||||
push bc
|
||||
push hl
|
||||
|
||||
.col
|
||||
ld a, [de]
|
||||
ld [hli], a
|
||||
dec de
|
||||
dec c
|
||||
jr nz, .col
|
||||
|
||||
pop hl
|
||||
ld bc, SCREEN_WIDTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
dec b
|
||||
jr nz, .row
|
||||
|
||||
ret
|
||||
|
||||
PopWindow::
|
||||
ld b, wMenuHeaderEnd - wMenuHeader
|
||||
ld de, wMenuHeader
|
||||
.loop
|
||||
ld a, [hld]
|
||||
ld [de], a
|
||||
inc de
|
||||
dec b
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
GetMenuBoxDims::
|
||||
ld a, [wMenuBorderTopCoord] ; top
|
||||
ld b, a
|
||||
ld a, [wMenuBorderBottomCoord] ; bottom
|
||||
sub b
|
||||
ld b, a
|
||||
ld a, [wMenuBorderLeftCoord] ; left
|
||||
ld c, a
|
||||
ld a, [wMenuBorderRightCoord] ; right
|
||||
sub c
|
||||
ld c, a
|
||||
ret
|
||||
|
||||
CopyMenuData::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
push af
|
||||
ld hl, wMenuDataPointer
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld de, wMenuData
|
||||
ld bc, wMenuDataEnd - wMenuData
|
||||
call CopyBytes
|
||||
pop af
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
GetWindowStackTop::
|
||||
ld hl, wWindowStackPointer
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
inc hl
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ret
|
||||
|
||||
PlaceVerticalMenuItems::
|
||||
call CopyMenuData
|
||||
ld hl, wMenuDataPointer
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
call GetMenuTextStartCoord
|
||||
call Coord2Tile ; hl now contains the tilemap address where we will start printing text.
|
||||
inc de
|
||||
ld a, [de] ; Number of items
|
||||
inc de
|
||||
ld b, a
|
||||
.loop
|
||||
push bc
|
||||
call PlaceString
|
||||
inc de
|
||||
ld bc, 2 * SCREEN_WIDTH
|
||||
add hl, bc
|
||||
pop bc
|
||||
dec b
|
||||
jr nz, .loop
|
||||
|
||||
ld a, [wMenuDataFlags]
|
||||
bit 4, a
|
||||
ret z
|
||||
|
||||
call MenuBoxCoord2Tile
|
||||
ld a, [de]
|
||||
ld c, a
|
||||
inc de
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
jp PlaceString
|
||||
|
||||
MenuBox::
|
||||
call MenuBoxCoord2Tile
|
||||
call GetMenuBoxDims
|
||||
dec b
|
||||
dec c
|
||||
jp Textbox
|
||||
|
||||
GetMenuTextStartCoord::
|
||||
ld a, [wMenuBorderTopCoord]
|
||||
ld b, a
|
||||
inc b
|
||||
ld a, [wMenuBorderLeftCoord]
|
||||
ld c, a
|
||||
inc c
|
||||
; bit 6: if not set, leave extra room on top
|
||||
ld a, [wMenuDataFlags]
|
||||
bit 6, a
|
||||
jr nz, .bit_6_set
|
||||
inc b
|
||||
|
||||
.bit_6_set
|
||||
; bit 7: if set, leave extra room on the left
|
||||
ld a, [wMenuDataFlags]
|
||||
bit 7, a
|
||||
ret z
|
||||
inc c
|
||||
ret
|
||||
|
||||
ClearMenuBoxInterior::
|
||||
call MenuBoxCoord2Tile
|
||||
ld bc, SCREEN_WIDTH + 1
|
||||
add hl, bc
|
||||
call GetMenuBoxDims
|
||||
dec b
|
||||
dec c
|
||||
jp ClearBox
|
||||
|
||||
ClearWholeMenuBox::
|
||||
call MenuBoxCoord2Tile
|
||||
call GetMenuBoxDims
|
||||
inc c
|
||||
inc b
|
||||
jp ClearBox
|
||||
|
||||
MenuBoxCoord2Tile::
|
||||
ld a, [wMenuBorderLeftCoord]
|
||||
ld c, a
|
||||
ld a, [wMenuBorderTopCoord]
|
||||
ld b, a
|
||||
; fallthrough
|
||||
|
||||
Coord2Tile::
|
||||
; Return the address of wTilemap(c, b) in hl.
|
||||
xor a
|
||||
ld h, a
|
||||
ld l, b
|
||||
ld a, c
|
||||
ld b, h
|
||||
ld c, l
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
add hl, bc
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
ld c, a
|
||||
xor a
|
||||
ld b, a
|
||||
add hl, bc
|
||||
bccoord 0, 0
|
||||
add hl, bc
|
||||
ret
|
||||
|
||||
MenuBoxCoord2Attr::
|
||||
ld a, [wMenuBorderLeftCoord]
|
||||
ld c, a
|
||||
ld a, [wMenuBorderTopCoord]
|
||||
ld b, a
|
||||
; fallthrough
|
||||
|
||||
Coord2Attr:: ; unreferenced
|
||||
; Return the address of wAttrmap(c, b) in hl.
|
||||
xor a
|
||||
ld h, a
|
||||
ld l, b
|
||||
ld a, c
|
||||
ld b, h
|
||||
ld c, l
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
add hl, bc
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
ld c, a
|
||||
xor a
|
||||
ld b, a
|
||||
add hl, bc
|
||||
bccoord 0, 0, wAttrmap
|
||||
add hl, bc
|
||||
ret
|
||||
|
||||
LoadMenuHeader::
|
||||
call CopyMenuHeader
|
||||
jp PushWindow
|
||||
|
||||
CopyMenuHeader::
|
||||
ld de, wMenuHeader
|
||||
ld bc, wMenuHeaderEnd - wMenuHeader
|
||||
call CopyBytes
|
||||
ldh a, [hROMBank]
|
||||
ld [wMenuDataBank], a
|
||||
ret
|
||||
|
||||
StoreMenuCursorPosition::
|
||||
ld [wMenuCursorPosition], a
|
||||
ret
|
||||
|
||||
MenuTextbox::
|
||||
push hl
|
||||
call LoadMenuTextbox
|
||||
pop hl
|
||||
jp PrintText
|
||||
|
||||
LoadMenuTextbox::
|
||||
ld hl, .MenuHeader
|
||||
jp LoadMenuHeader
|
||||
|
||||
.MenuHeader:
|
||||
db MENU_BACKUP_TILES ; flags
|
||||
menu_coords 0, 12, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
|
||||
dw vTiles0
|
||||
db 0 ; default option
|
||||
|
||||
MenuTextboxBackup::
|
||||
call MenuTextbox
|
||||
jp CloseWindow
|
||||
|
||||
LoadStandardMenuHeader::
|
||||
ld hl, .MenuHeader
|
||||
jp LoadMenuHeader
|
||||
|
||||
.MenuHeader:
|
||||
db MENU_BACKUP_TILES ; flags
|
||||
menu_coords 0, 0, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
|
||||
dw 0
|
||||
db 1 ; default option
|
||||
|
||||
VerticalMenu::
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
call MenuBox
|
||||
call UpdateSprites
|
||||
call PlaceVerticalMenuItems
|
||||
call ApplyTilemap
|
||||
call CopyMenuData
|
||||
ld a, [wMenuDataFlags]
|
||||
bit 7, a
|
||||
jr z, .cancel
|
||||
call InitVerticalMenuCursor
|
||||
call StaticMenuJoypad
|
||||
call MenuClickSound
|
||||
bit 1, a
|
||||
jr z, .okay
|
||||
.cancel
|
||||
scf
|
||||
ret
|
||||
|
||||
.okay
|
||||
and a
|
||||
ret
|
||||
|
||||
GetMenu2::
|
||||
call LoadMenuHeader
|
||||
call VerticalMenu
|
||||
call CloseWindow
|
||||
ld a, [wMenuCursorY]
|
||||
ret
|
||||
|
||||
CopyNameFromMenu::
|
||||
push hl
|
||||
push bc
|
||||
push af
|
||||
ld hl, wMenuDataPointer
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
inc hl
|
||||
inc hl
|
||||
pop af
|
||||
call GetNthString
|
||||
ld d, h
|
||||
ld e, l
|
||||
call CopyName1
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
PlaceGenericTwoOptionBox:: ; unreferenced
|
||||
call LoadMenuHeader
|
||||
jr InterpretTwoOptionMenu
|
||||
|
||||
YesNoBox::
|
||||
lb bc, SCREEN_WIDTH - 6, 7
|
||||
; fallthrough
|
||||
|
||||
PlaceYesNoBox::
|
||||
; Return nc (yes) or c (no).
|
||||
push bc
|
||||
ld hl, YesNoMenuHeader
|
||||
call CopyMenuHeader
|
||||
pop bc
|
||||
; This seems to be an overflow prevention,
|
||||
; but it was coded wrong.
|
||||
ld a, b
|
||||
cp SCREEN_WIDTH - 1 - 5
|
||||
jr nz, .okay ; should this be "jr nc"?
|
||||
ld a, SCREEN_WIDTH - 1 - 5
|
||||
ld b, a
|
||||
|
||||
.okay
|
||||
ld a, b
|
||||
ld [wMenuBorderLeftCoord], a
|
||||
add 5
|
||||
ld [wMenuBorderRightCoord], a
|
||||
ld a, c
|
||||
ld [wMenuBorderTopCoord], a
|
||||
add 4
|
||||
ld [wMenuBorderBottomCoord], a
|
||||
call PushWindow
|
||||
; fallthrough
|
||||
|
||||
InterpretTwoOptionMenu::
|
||||
call VerticalMenu
|
||||
push af
|
||||
ld c, $f
|
||||
call DelayFrames
|
||||
call CloseWindow
|
||||
pop af
|
||||
jr c, .no
|
||||
ld a, [wMenuCursorY]
|
||||
cp 2 ; no
|
||||
jr z, .no
|
||||
and a
|
||||
ret
|
||||
|
||||
.no
|
||||
ld a, 2
|
||||
ld [wMenuCursorY], a
|
||||
scf
|
||||
ret
|
||||
|
||||
YesNoMenuHeader::
|
||||
db MENU_BACKUP_TILES ; flags
|
||||
menu_coords 10, 5, 15, 9
|
||||
dw .MenuData
|
||||
db 1 ; default option
|
||||
|
||||
.MenuData:
|
||||
db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
|
||||
db 2
|
||||
db "YES@"
|
||||
db "NO@"
|
||||
|
||||
OffsetMenuHeader::
|
||||
call _OffsetMenuHeader
|
||||
jp PushWindow
|
||||
|
||||
_OffsetMenuHeader::
|
||||
push de
|
||||
call CopyMenuHeader
|
||||
pop de
|
||||
ld a, [wMenuBorderLeftCoord]
|
||||
ld h, a
|
||||
ld a, [wMenuBorderRightCoord]
|
||||
sub h
|
||||
ld h, a
|
||||
ld a, d
|
||||
ld [wMenuBorderLeftCoord], a
|
||||
add h
|
||||
ld [wMenuBorderRightCoord], a
|
||||
ld a, [wMenuBorderTopCoord]
|
||||
ld l, a
|
||||
ld a, [wMenuBorderBottomCoord]
|
||||
sub l
|
||||
ld l, a
|
||||
ld a, e
|
||||
ld [wMenuBorderTopCoord], a
|
||||
add l
|
||||
ld [wMenuBorderBottomCoord], a
|
||||
ret
|
||||
|
||||
DoNthMenu::
|
||||
call DrawVariableLengthMenuBox
|
||||
call MenuWriteText
|
||||
call InitMenuCursorAndButtonPermissions
|
||||
call GetStaticMenuJoypad
|
||||
call GetMenuJoypad
|
||||
jp MenuClickSound
|
||||
|
||||
SetUpMenu::
|
||||
call DrawVariableLengthMenuBox
|
||||
call MenuWriteText
|
||||
call InitMenuCursorAndButtonPermissions
|
||||
ld hl, w2DMenuFlags1
|
||||
set 7, [hl]
|
||||
ret
|
||||
|
||||
DrawVariableLengthMenuBox::
|
||||
call CopyMenuData
|
||||
call GetMenuIndexSet
|
||||
call AutomaticGetMenuBottomCoord
|
||||
jp MenuBox
|
||||
|
||||
MenuWriteText::
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
call GetMenuIndexSet ; sort out the text
|
||||
call RunMenuItemPrintingFunction ; actually write it
|
||||
call SafeUpdateSprites
|
||||
ldh a, [hOAMUpdate]
|
||||
push af
|
||||
ld a, $1
|
||||
ldh [hOAMUpdate], a
|
||||
call ApplyTilemap
|
||||
pop af
|
||||
ldh [hOAMUpdate], a
|
||||
ret
|
||||
|
||||
AutomaticGetMenuBottomCoord::
|
||||
ld a, [wMenuBorderLeftCoord]
|
||||
ld c, a
|
||||
ld a, [wMenuBorderRightCoord]
|
||||
sub c
|
||||
ld c, a
|
||||
ld a, [wMenuDataItems]
|
||||
add a
|
||||
inc a
|
||||
ld b, a
|
||||
ld a, [wMenuBorderTopCoord]
|
||||
add b
|
||||
ld [wMenuBorderBottomCoord], a
|
||||
ret
|
||||
|
||||
GetMenuIndexSet::
|
||||
ld hl, wMenuDataIndicesPointer
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld a, [wWhichIndexSet]
|
||||
and a
|
||||
jr z, .skip
|
||||
ld b, a
|
||||
ld c, -1
|
||||
.loop
|
||||
ld a, [hli]
|
||||
cp c
|
||||
jr nz, .loop
|
||||
dec b
|
||||
jr nz, .loop
|
||||
|
||||
.skip
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld a, [hl]
|
||||
ld [wMenuDataItems], a
|
||||
ret
|
||||
|
||||
RunMenuItemPrintingFunction::
|
||||
call MenuBoxCoord2Tile
|
||||
ld bc, 2 * SCREEN_WIDTH + 2
|
||||
add hl, bc
|
||||
.loop
|
||||
inc de
|
||||
ld a, [de]
|
||||
cp -1
|
||||
ret z
|
||||
ld [wMenuSelection], a
|
||||
push de
|
||||
push hl
|
||||
ld d, h
|
||||
ld e, l
|
||||
ld hl, wMenuDataDisplayFunctionPointer
|
||||
call ._hl_
|
||||
pop hl
|
||||
ld de, 2 * SCREEN_WIDTH
|
||||
add hl, de
|
||||
pop de
|
||||
jr .loop
|
||||
|
||||
._hl_
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
jp hl
|
||||
|
||||
InitMenuCursorAndButtonPermissions::
|
||||
call InitVerticalMenuCursor
|
||||
ld hl, wMenuJoypadFilter
|
||||
ld a, [wMenuDataFlags]
|
||||
bit 3, a
|
||||
jr z, .disallow_select
|
||||
set START_F, [hl]
|
||||
|
||||
.disallow_select
|
||||
ld a, [wMenuDataFlags]
|
||||
bit 2, a
|
||||
ret z
|
||||
set D_LEFT_F, [hl]
|
||||
set D_RIGHT_F, [hl]
|
||||
ret
|
||||
|
||||
GetScrollingMenuJoypad::
|
||||
call ScrollingMenuJoypad
|
||||
ld hl, wMenuJoypadFilter
|
||||
and [hl]
|
||||
jr ContinueGettingMenuJoypad
|
||||
|
||||
GetStaticMenuJoypad::
|
||||
xor a
|
||||
ld [wMenuJoypad], a
|
||||
call StaticMenuJoypad
|
||||
; fallthrough
|
||||
|
||||
ContinueGettingMenuJoypad:
|
||||
bit A_BUTTON_F, a
|
||||
jr nz, .a_button
|
||||
bit B_BUTTON_F, a
|
||||
jr nz, .b_start
|
||||
bit START_F, a
|
||||
jr nz, .b_start
|
||||
bit D_RIGHT_F, a
|
||||
jr nz, .d_right
|
||||
bit D_LEFT_F, a
|
||||
jr nz, .d_left
|
||||
xor a
|
||||
ld [wMenuJoypad], a
|
||||
jr .done
|
||||
|
||||
.d_right
|
||||
ld a, D_RIGHT
|
||||
ld [wMenuJoypad], a
|
||||
jr .done
|
||||
|
||||
.d_left
|
||||
ld a, D_LEFT
|
||||
ld [wMenuJoypad], a
|
||||
jr .done
|
||||
|
||||
.a_button
|
||||
ld a, A_BUTTON
|
||||
ld [wMenuJoypad], a
|
||||
|
||||
.done
|
||||
call GetMenuIndexSet
|
||||
ld a, [wMenuCursorY]
|
||||
ld l, a
|
||||
ld h, 0
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
ld [wMenuSelection], a
|
||||
ld a, [wMenuCursorY]
|
||||
ld [wMenuCursorPosition], a
|
||||
and a
|
||||
ret
|
||||
|
||||
.b_start
|
||||
ld a, B_BUTTON
|
||||
ld [wMenuJoypad], a
|
||||
ld a, -1
|
||||
ld [wMenuSelection], a
|
||||
scf
|
||||
ret
|
||||
|
||||
PlaceMenuStrings::
|
||||
push de
|
||||
ld hl, wMenuDataPointerTableAddr
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld a, [wMenuSelection]
|
||||
call GetNthString
|
||||
ld d, h
|
||||
ld e, l
|
||||
pop hl
|
||||
jp PlaceString
|
||||
|
||||
PlaceNthMenuStrings::
|
||||
push de
|
||||
ld a, [wMenuSelection]
|
||||
call GetMenuDataPointerTableEntry
|
||||
inc hl
|
||||
inc hl
|
||||
ld a, [hli]
|
||||
ld d, [hl]
|
||||
ld e, a
|
||||
pop hl
|
||||
jp PlaceString
|
||||
|
||||
MenuJumptable::
|
||||
ld a, [wMenuSelection]
|
||||
call GetMenuDataPointerTableEntry
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
jp hl
|
||||
|
||||
GetMenuDataPointerTableEntry::
|
||||
ld e, a
|
||||
ld d, 0
|
||||
ld hl, wMenuDataPointerTableAddr
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
add hl, de
|
||||
add hl, de
|
||||
add hl, de
|
||||
add hl, de
|
||||
ret
|
||||
|
||||
ClearWindowData::
|
||||
ld hl, wMenuMetadata
|
||||
call .ClearMenuData
|
||||
ld hl, wMenuHeader
|
||||
call .ClearMenuData
|
||||
ld hl, wMenuData
|
||||
call .ClearMenuData
|
||||
ld hl, wMoreMenuData
|
||||
call .ClearMenuData
|
||||
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wWindowStack)
|
||||
ldh [rSVBK], a
|
||||
|
||||
xor a
|
||||
ld hl, wWindowStackBottom
|
||||
ld [hld], a
|
||||
ld [hld], a
|
||||
ld a, l
|
||||
ld [wWindowStackPointer], a
|
||||
ld a, h
|
||||
ld [wWindowStackPointer + 1], a
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ret
|
||||
|
||||
.ClearMenuData:
|
||||
ld bc, wMenuMetadataEnd - wMenuMetadata
|
||||
assert wMenuMetadataEnd - wMenuMetadata == wMenuHeaderEnd - wMenuHeader
|
||||
assert wMenuMetadataEnd - wMenuMetadata == wMenuDataEnd - wMenuData
|
||||
assert wMenuMetadataEnd - wMenuMetadata == wMoreMenuDataEnd - wMoreMenuData
|
||||
xor a
|
||||
jp ByteFill
|
||||
|
||||
MenuClickSound::
|
||||
push af
|
||||
and A_BUTTON | B_BUTTON
|
||||
jr z, .nosound
|
||||
ld hl, wMenuFlags
|
||||
bit 3, [hl]
|
||||
jr nz, .nosound
|
||||
call PlayClickSFX
|
||||
.nosound
|
||||
pop af
|
||||
ret
|
||||
|
||||
PlayClickSFX::
|
||||
push de
|
||||
ld de, SFX_READ_TEXT_2
|
||||
call PlaySFX
|
||||
pop de
|
||||
ret
|
||||
|
||||
MenuTextboxWaitButton::
|
||||
call MenuTextbox
|
||||
call WaitButton
|
||||
jp ExitMenu
|
||||
|
||||
Place2DMenuItemName::
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
|
||||
call PlaceString
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ret
|
||||
|
||||
_2DMenu::
|
||||
ldh a, [hROMBank]
|
||||
ld [wMenuData_2DMenuItemStringsBank], a
|
||||
farcall _2DMenu_
|
||||
ld a, [wMenuCursorPosition]
|
||||
ret
|
||||
|
||||
InterpretBattleMenu::
|
||||
ldh a, [hROMBank]
|
||||
ld [wMenuData_2DMenuItemStringsBank], a
|
||||
farcall _InterpretBattleMenu
|
||||
ld a, [wMenuCursorPosition]
|
||||
ret
|
||||
|
||||
InterpretMobileMenu:: ; unreferenced
|
||||
ldh a, [hROMBank]
|
||||
ld [wMenuData_2DMenuItemStringsBank], a
|
||||
farcall _InterpretMobileMenu
|
||||
ld a, [wMenuCursorPosition]
|
||||
ret
|
||||
255
home/mobile.asm
Normal file
255
home/mobile.asm
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
MobileAPI::
|
||||
; Mobile
|
||||
cp $2
|
||||
ld [wMobileAPIIndex], a
|
||||
ld a, l
|
||||
ld [wc986], a
|
||||
ld a, h
|
||||
ld [wc987], a
|
||||
jr nz, .okay
|
||||
|
||||
ld [wc982], a
|
||||
ld a, l
|
||||
ld [wc981], a
|
||||
ld hl, wc983
|
||||
ld a, c
|
||||
ld [hli], a
|
||||
ld a, b
|
||||
ld [hl], a
|
||||
|
||||
.okay
|
||||
ld hl, wc822
|
||||
set 6, [hl]
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_MobileAPI)
|
||||
ld [wc981], a
|
||||
rst Bankswitch
|
||||
|
||||
jp _MobileAPI
|
||||
|
||||
ReturnMobileAPI::
|
||||
; Return from _MobileAPI
|
||||
ld [wc986], a
|
||||
ld a, l
|
||||
ld [wc987], a
|
||||
ld a, h
|
||||
ld [wMobileAPIIndex], a
|
||||
|
||||
pop bc
|
||||
ld a, b
|
||||
ld [wc981], a
|
||||
rst Bankswitch
|
||||
|
||||
ld hl, wc822
|
||||
res 6, [hl]
|
||||
ld hl, wc987
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld a, [wc986]
|
||||
ret
|
||||
|
||||
MobileReceive::
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_MobileReceive)
|
||||
ld [wc981], a
|
||||
rst Bankswitch
|
||||
|
||||
call _MobileReceive
|
||||
pop bc
|
||||
ld a, b
|
||||
ld [wc981], a
|
||||
rst Bankswitch
|
||||
|
||||
ret
|
||||
|
||||
MobileTimer::
|
||||
push af
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
|
||||
ldh a, [hMobile]
|
||||
and a
|
||||
jr z, .pop_ret
|
||||
|
||||
xor a
|
||||
ldh [rTAC], a
|
||||
|
||||
; Turn off timer interrupt
|
||||
ldh a, [rIF]
|
||||
and 1 << VBLANK | 1 << LCD_STAT | 1 << SERIAL | 1 << JOYPAD
|
||||
ldh [rIF], a
|
||||
|
||||
ld a, [wc86a]
|
||||
or a
|
||||
jr z, .pop_ret
|
||||
|
||||
ld a, [wc822]
|
||||
bit 1, a
|
||||
jr nz, .skip_timer
|
||||
|
||||
ldh a, [rSC]
|
||||
and 1 << rSC_ON
|
||||
jr nz, .skip_timer
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_Timer)
|
||||
ld [wc981], a
|
||||
rst Bankswitch
|
||||
|
||||
call _Timer
|
||||
|
||||
pop bc
|
||||
ld a, b
|
||||
ld [wc981], a
|
||||
rst Bankswitch
|
||||
|
||||
.skip_timer
|
||||
ldh a, [rTMA]
|
||||
ldh [rTIMA], a
|
||||
|
||||
ld a, 1 << rTAC_ON | rTAC_65536_HZ
|
||||
ldh [rTAC], a
|
||||
|
||||
.pop_ret
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
pop af
|
||||
reti
|
||||
|
||||
Function3eea::
|
||||
push hl
|
||||
push bc
|
||||
ld de, wAttrmap - wTilemap
|
||||
add hl, de
|
||||
inc b
|
||||
inc b
|
||||
inc c
|
||||
inc c
|
||||
call Function3f35
|
||||
pop bc
|
||||
pop hl
|
||||
jp MobileHome_PlaceBox
|
||||
|
||||
Function3f20::
|
||||
hlcoord 0, 0, wAttrmap
|
||||
ld b, 6
|
||||
ld c, 20
|
||||
call Function3f35
|
||||
hlcoord 0, 0
|
||||
ld b, 4
|
||||
ld c, 18
|
||||
jp MobileHome_PlaceBox
|
||||
|
||||
Function3f35::
|
||||
ld a, 6
|
||||
ld de, SCREEN_WIDTH
|
||||
.row
|
||||
push bc
|
||||
push hl
|
||||
.col
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .col
|
||||
pop hl
|
||||
add hl, de
|
||||
pop bc
|
||||
dec b
|
||||
jr nz, .row
|
||||
ret
|
||||
|
||||
MobileHome_PlaceBox:
|
||||
push bc
|
||||
call .FillTop
|
||||
pop bc
|
||||
.RowLoop:
|
||||
push bc
|
||||
call .FillMiddle
|
||||
pop bc
|
||||
dec b
|
||||
jr nz, .RowLoop
|
||||
call .FillBottom
|
||||
ret
|
||||
|
||||
.FillTop:
|
||||
ld a, $63
|
||||
ld d, $62
|
||||
ld e, $64
|
||||
jr .FillRow
|
||||
|
||||
.FillBottom:
|
||||
ld a, $68
|
||||
ld d, $67
|
||||
ld e, $69
|
||||
jr .FillRow
|
||||
|
||||
.FillMiddle:
|
||||
ld a, $7f
|
||||
ld d, $65
|
||||
ld e, $66
|
||||
|
||||
.FillRow:
|
||||
push hl
|
||||
ld [hl], d
|
||||
inc hl
|
||||
.FillLoop:
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .FillLoop
|
||||
ld [hl], e
|
||||
pop hl
|
||||
ld de, SCREEN_WIDTH
|
||||
add hl, de
|
||||
ret
|
||||
|
||||
Function3f7c::
|
||||
call MenuBoxCoord2Tile
|
||||
call GetMenuBoxDims
|
||||
dec b
|
||||
dec c
|
||||
jp Function3eea
|
||||
|
||||
Function3f88::
|
||||
ld hl, wDecompressScratch
|
||||
ld b, 0
|
||||
.row
|
||||
push bc
|
||||
ld c, 1 tiles / 2
|
||||
.col
|
||||
ld a, [de]
|
||||
inc de
|
||||
cpl
|
||||
ld [hl], 0
|
||||
inc hl
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .col
|
||||
pop bc
|
||||
dec c
|
||||
jr nz, .row
|
||||
ret
|
||||
|
||||
Function3f9f::
|
||||
ld hl, wDecompressScratch
|
||||
.row
|
||||
push bc
|
||||
ld c, 1 tiles / 2
|
||||
.col
|
||||
ld a, [de]
|
||||
inc de
|
||||
inc de
|
||||
cpl
|
||||
ld [hl], $0
|
||||
inc hl
|
||||
ld [hli], a
|
||||
dec c
|
||||
jr nz, .col
|
||||
pop bc
|
||||
dec c
|
||||
jr nz, .row
|
||||
ret
|
||||
128
home/movement.asm
Normal file
128
home/movement.asm
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
InitMovementBuffer::
|
||||
ld [wMovementBufferObject], a
|
||||
xor a
|
||||
ld [wMovementBufferCount], a
|
||||
ld [wUnusedMovementBufferBank], a
|
||||
ld a, LOW(wMovementBuffer)
|
||||
ld [wUnusedMovementBufferPointer], a
|
||||
ld a, HIGH(wMovementBuffer)
|
||||
ld [wUnusedMovementBufferPointer + 1], a
|
||||
ret
|
||||
|
||||
DecrementMovementBufferCount::
|
||||
ld a, [wMovementBufferCount]
|
||||
and a
|
||||
ret z
|
||||
dec a
|
||||
ld [wMovementBufferCount], a
|
||||
ret
|
||||
|
||||
AppendToMovementBuffer::
|
||||
push hl
|
||||
push de
|
||||
ld hl, wMovementBufferCount
|
||||
ld e, [hl]
|
||||
inc [hl]
|
||||
ld d, 0
|
||||
ld hl, wMovementBuffer
|
||||
add hl, de
|
||||
ld [hl], a
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
AppendToMovementBufferNTimes::
|
||||
push af
|
||||
ld a, c
|
||||
and a
|
||||
jr nz, .okay
|
||||
pop af
|
||||
ret
|
||||
|
||||
.okay
|
||||
pop af
|
||||
.loop
|
||||
call AppendToMovementBuffer
|
||||
dec c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
ComputePathToWalkToPlayer::
|
||||
push af
|
||||
; compare x coords, load left/right into h, and x distance into d
|
||||
ld a, b
|
||||
sub d
|
||||
ld h, LEFT
|
||||
jr nc, .got_x_distance
|
||||
dec a
|
||||
cpl
|
||||
ld h, RIGHT
|
||||
|
||||
.got_x_distance
|
||||
ld d, a
|
||||
; compare y coords, load up/down into l, and y distance into e
|
||||
ld a, c
|
||||
sub e
|
||||
ld l, UP
|
||||
jr nc, .got_y_distance
|
||||
dec a
|
||||
cpl
|
||||
ld l, DOWN
|
||||
|
||||
.got_y_distance
|
||||
ld e, a
|
||||
; if the x distance is less than the y distance, swap h and l, and swap d and e
|
||||
cp d
|
||||
jr nc, .done
|
||||
ld a, h
|
||||
ld h, l
|
||||
ld l, a
|
||||
ld a, d
|
||||
ld d, e
|
||||
ld e, a
|
||||
|
||||
.done
|
||||
pop af
|
||||
ld b, a
|
||||
; Add movement in the longer direction first...
|
||||
ld a, h
|
||||
call .GetMovementData
|
||||
ld c, d
|
||||
call AppendToMovementBufferNTimes
|
||||
; ... then add the shorter direction.
|
||||
ld a, l
|
||||
call .GetMovementData
|
||||
ld c, e
|
||||
call AppendToMovementBufferNTimes
|
||||
ret
|
||||
|
||||
.GetMovementData:
|
||||
push de
|
||||
push hl
|
||||
ld l, b
|
||||
ld h, 0
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
ld e, a
|
||||
ld d, 0
|
||||
add hl, de
|
||||
ld de, .MovementData
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
pop hl
|
||||
pop de
|
||||
ret
|
||||
|
||||
.MovementData:
|
||||
slow_step DOWN
|
||||
slow_step UP
|
||||
slow_step LEFT
|
||||
slow_step RIGHT
|
||||
step DOWN
|
||||
step UP
|
||||
step LEFT
|
||||
step RIGHT
|
||||
big_step DOWN
|
||||
big_step UP
|
||||
big_step LEFT
|
||||
big_step RIGHT
|
||||
36
home/moves.asm
Normal file
36
home/moves.asm
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
GetMoveAttribute::
|
||||
; Return attribute a of move l in a; clobbers hl.
|
||||
; Replaces the old GetMoveAttr (renamed to avoid confusion).
|
||||
sub 1
|
||||
push bc
|
||||
ld c, a
|
||||
ld a, l
|
||||
jr c, .done
|
||||
call GetMoveAddress
|
||||
ld b, 0
|
||||
add hl, bc
|
||||
call GetFarByte
|
||||
.done
|
||||
pop bc
|
||||
ret
|
||||
|
||||
GetMoveAddress::
|
||||
; Get the far address for move a's attributes in a:hl.
|
||||
; This structure will not contain the animation byte! All MOVE_* constants must be reduced by 1 when indexing.
|
||||
push bc
|
||||
call GetMoveIndexFromID
|
||||
ld b, h
|
||||
ld c, l
|
||||
ld hl, Moves
|
||||
ld a, BANK(Moves)
|
||||
call LoadIndirectPointer
|
||||
pop bc
|
||||
ret
|
||||
|
||||
GetMoveData::
|
||||
; Copy move struct a to de.
|
||||
ld [de], a
|
||||
inc de
|
||||
call GetMoveAddress
|
||||
ld bc, MOVE_LENGTH - 1
|
||||
jp FarCopyBytes
|
||||
284
home/names.asm
Normal file
284
home/names.asm
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
NamesPointers::
|
||||
; entries correspond to GetName constants (see constants/text_constants.asm); MON_NAME and MOVE_NAME are not handled by this table
|
||||
dba ItemNames ; ITEM_NAME
|
||||
dbw 0, wPartyMonOTs ; PARTY_OT_NAME
|
||||
dbw 0, wOTPartyMonOTs ; ENEMY_OT_NAME
|
||||
dba TrainerClassNames ; TRAINER_NAME
|
||||
|
||||
GetName::
|
||||
; Return name wCurSpecies from name list wNamedObjectType in wStringBuffer1.
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
push hl
|
||||
push bc
|
||||
push de
|
||||
|
||||
ld a, [wCurSpecies]
|
||||
ld [wNamedObjectIndex], a
|
||||
|
||||
ld a, [wNamedObjectType]
|
||||
dec a ; MON_NAME
|
||||
ld hl, GetPokemonName
|
||||
jr z, .go
|
||||
dec a ; MOVE_NAME
|
||||
ld hl, GetMoveName
|
||||
jr z, .go
|
||||
dec a
|
||||
ld hl, .generic_function
|
||||
.go
|
||||
call _hl_
|
||||
|
||||
pop de
|
||||
pop bc
|
||||
pop hl
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
.generic_function
|
||||
ld l, a
|
||||
add a, a
|
||||
add a, l
|
||||
add a, LOW(NamesPointers)
|
||||
ld l, a
|
||||
ld a, HIGH(NamesPointers)
|
||||
adc 0
|
||||
ld h, a
|
||||
ld a, [hli]
|
||||
rst Bankswitch
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
ld a, [wCurSpecies]
|
||||
dec a
|
||||
call GetNthString
|
||||
|
||||
ld de, wStringBuffer1
|
||||
ld bc, ITEM_NAME_LENGTH
|
||||
jp CopyBytes
|
||||
|
||||
GetNthString16::
|
||||
; Like GetNthString, but with a 16-bit index in bc
|
||||
inc b
|
||||
jr .handle_loop
|
||||
|
||||
.loop
|
||||
xor a
|
||||
call GetNthString.loop ; will act as a = $100
|
||||
.handle_loop
|
||||
dec b
|
||||
jr nz, .loop
|
||||
ld a, c
|
||||
; fallthrough
|
||||
|
||||
GetNthString::
|
||||
; Return the address of the
|
||||
; ath string starting from hl.
|
||||
|
||||
and a
|
||||
ret z
|
||||
|
||||
.loop
|
||||
push bc
|
||||
ld b, a
|
||||
ld c, "@"
|
||||
.readChar
|
||||
ld a, [hli]
|
||||
cp c
|
||||
jr nz, .readChar
|
||||
dec b
|
||||
jr nz, .readChar
|
||||
pop bc
|
||||
ret
|
||||
|
||||
GetBasePokemonName::
|
||||
; Discards gender (Nidoran).
|
||||
|
||||
push hl
|
||||
call GetPokemonName
|
||||
|
||||
ld hl, wStringBuffer1
|
||||
.loop
|
||||
ld a, [hl]
|
||||
cp "@"
|
||||
jr z, .quit
|
||||
cp "♂"
|
||||
jr z, .end
|
||||
cp "♀"
|
||||
jr z, .end
|
||||
inc hl
|
||||
jr .loop
|
||||
.end
|
||||
ld [hl], "@"
|
||||
.quit
|
||||
pop hl
|
||||
ret
|
||||
|
||||
GetPokemonName::
|
||||
; Get Pokemon name for wNamedObjectIndex.
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
push hl
|
||||
ld a, BANK(PokemonNames)
|
||||
rst Bankswitch
|
||||
|
||||
; Each name is ten characters
|
||||
ld a, [wNamedObjectIndex]
|
||||
call GetPokemonIndexFromID
|
||||
ld e, l
|
||||
ld d, h
|
||||
add hl, hl
|
||||
add hl, hl
|
||||
add hl, de
|
||||
add hl, hl
|
||||
ld de, PokemonNames - 10
|
||||
add hl, de
|
||||
|
||||
; Terminator
|
||||
ld de, wStringBuffer1
|
||||
push de
|
||||
ld bc, MON_NAME_LENGTH - 1
|
||||
call CopyBytes
|
||||
ld hl, wStringBuffer1 + MON_NAME_LENGTH - 1
|
||||
ld [hl], "@"
|
||||
pop de
|
||||
|
||||
pop hl
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
GetItemName::
|
||||
; Get item name for wNamedObjectIndex.
|
||||
|
||||
push hl
|
||||
push bc
|
||||
ld a, [wNamedObjectIndex]
|
||||
|
||||
cp TM01
|
||||
jr nc, .TM
|
||||
|
||||
ld [wCurSpecies], a
|
||||
ld a, ITEM_NAME
|
||||
ld [wNamedObjectType], a
|
||||
call GetName
|
||||
jr .Copied
|
||||
.TM:
|
||||
call GetTMHMName
|
||||
.Copied:
|
||||
ld de, wStringBuffer1
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
|
||||
GetTMHMName::
|
||||
; Get TM/HM name for item wNamedObjectIndex.
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
ld a, [wNamedObjectIndex]
|
||||
push af
|
||||
|
||||
; TM/HM prefix
|
||||
cp HM01
|
||||
push af
|
||||
jr c, .TM
|
||||
|
||||
ld hl, .HMText
|
||||
ld bc, .HMTextEnd - .HMText
|
||||
jr .copy
|
||||
|
||||
.TM:
|
||||
ld hl, .TMText
|
||||
ld bc, .TMTextEnd - .TMText
|
||||
|
||||
.copy
|
||||
ld de, wStringBuffer1
|
||||
call CopyBytes
|
||||
|
||||
; TM/HM number
|
||||
push de
|
||||
ld a, [wNamedObjectIndex]
|
||||
ld c, a
|
||||
callfar GetTMHMNumber
|
||||
pop de
|
||||
|
||||
; HM numbers start from 51, not 1
|
||||
pop af
|
||||
ld a, c
|
||||
jr c, .not_hm
|
||||
sub NUM_TMS
|
||||
.not_hm
|
||||
|
||||
; Divide and mod by 10 to get the top and bottom digits respectively
|
||||
ld b, "0"
|
||||
.mod10
|
||||
sub 10
|
||||
jr c, .done_mod
|
||||
inc b
|
||||
jr .mod10
|
||||
|
||||
.done_mod
|
||||
add 10
|
||||
push af
|
||||
ld a, b
|
||||
ld [de], a
|
||||
inc de
|
||||
pop af
|
||||
|
||||
ld b, "0"
|
||||
add b
|
||||
ld [de], a
|
||||
|
||||
; End the string
|
||||
inc de
|
||||
ld a, "@"
|
||||
ld [de], a
|
||||
|
||||
pop af
|
||||
ld [wNamedObjectIndex], a
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
.TMText:
|
||||
db "TM"
|
||||
.TMTextEnd:
|
||||
db "@"
|
||||
|
||||
.HMText:
|
||||
db "HM"
|
||||
.HMTextEnd:
|
||||
db "@"
|
||||
|
||||
INCLUDE "home/hm_moves.asm"
|
||||
|
||||
GetMoveName::
|
||||
push hl
|
||||
push bc
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(MoveNames)
|
||||
rst Bankswitch
|
||||
ld a, [wNamedObjectIndex]
|
||||
call GetMoveIndexFromID
|
||||
dec hl
|
||||
ld b, h
|
||||
ld c, l
|
||||
ld hl, MoveNames
|
||||
call GetNthString16
|
||||
ld de, wStringBuffer1
|
||||
push de
|
||||
ld bc, MOVE_NAME_LENGTH
|
||||
call CopyBytes
|
||||
pop de
|
||||
pop af
|
||||
rst Bankswitch
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
329
home/palettes.asm
Normal file
329
home/palettes.asm
Normal file
|
|
@ -0,0 +1,329 @@
|
|||
; Functions dealing with palettes.
|
||||
|
||||
UpdatePalsIfCGB::
|
||||
; update bgp data from wBGPals2
|
||||
; update obp data from wOBPals2
|
||||
; return carry if successful
|
||||
|
||||
; check cgb
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
ret z
|
||||
|
||||
UpdateCGBPals::
|
||||
; return carry if successful
|
||||
; any pals to update?
|
||||
ldh a, [hCGBPalUpdate]
|
||||
and a
|
||||
ret z
|
||||
; fallthrough
|
||||
|
||||
ForceUpdateCGBPals::
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wBGPals2)
|
||||
ldh [rSVBK], a
|
||||
|
||||
ld hl, wBGPals2
|
||||
|
||||
; copy 8 pals to bgpd
|
||||
ld a, 1 << rBGPI_AUTO_INCREMENT
|
||||
ldh [rBGPI], a
|
||||
ld c, LOW(rBGPD)
|
||||
ld b, 8 / 2
|
||||
.bgp
|
||||
rept (1 palettes) * 2
|
||||
ld a, [hli]
|
||||
ldh [c], a
|
||||
endr
|
||||
|
||||
dec b
|
||||
jr nz, .bgp
|
||||
|
||||
; hl is now wOBPals2
|
||||
|
||||
; copy 8 pals to obpd
|
||||
ld a, 1 << rOBPI_AUTO_INCREMENT
|
||||
ldh [rOBPI], a
|
||||
ld c, LOW(rOBPD)
|
||||
ld b, 8 / 2
|
||||
.obp
|
||||
rept (1 palettes) * 2
|
||||
ld a, [hli]
|
||||
ldh [c], a
|
||||
endr
|
||||
|
||||
dec b
|
||||
jr nz, .obp
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
|
||||
; clear pal update queue
|
||||
xor a
|
||||
ldh [hCGBPalUpdate], a
|
||||
|
||||
scf
|
||||
ret
|
||||
|
||||
DmgToCgbBGPals::
|
||||
; exists to forego reinserting cgb-converted image data
|
||||
|
||||
; input: a -> bgp
|
||||
|
||||
ldh [rBGP], a
|
||||
push af
|
||||
|
||||
; Don't need to be here if DMG
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .end
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
|
||||
ld a, BANK(wBGPals2)
|
||||
ldh [rSVBK], a
|
||||
|
||||
; copy & reorder bg pal buffer
|
||||
ld hl, wBGPals2 ; to
|
||||
ld de, wBGPals1 ; from
|
||||
; order
|
||||
ldh a, [rBGP]
|
||||
ld b, a
|
||||
; all pals
|
||||
ld c, 8
|
||||
call CopyPals
|
||||
; request pal update
|
||||
ld a, TRUE
|
||||
ldh [hCGBPalUpdate], a
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
.end
|
||||
pop af
|
||||
ret
|
||||
|
||||
DmgToCgbObjPals::
|
||||
; exists to forego reinserting cgb-converted image data
|
||||
|
||||
; input: d -> obp1
|
||||
; e -> obp2
|
||||
|
||||
ld a, e
|
||||
ldh [rOBP0], a
|
||||
ld a, d
|
||||
ldh [rOBP1], a
|
||||
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
ret z
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
|
||||
ld a, BANK(wOBPals2)
|
||||
ldh [rSVBK], a
|
||||
|
||||
; copy & reorder obj pal buffer
|
||||
ld hl, wOBPals2 ; to
|
||||
ld de, wOBPals1 ; from
|
||||
; order
|
||||
ldh a, [rOBP0]
|
||||
ld b, a
|
||||
; all pals
|
||||
ld c, 8
|
||||
call CopyPals
|
||||
; request pal update
|
||||
ld a, TRUE
|
||||
ldh [hCGBPalUpdate], a
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
DmgToCgbObjPal0::
|
||||
ldh [rOBP0], a
|
||||
push af
|
||||
|
||||
; Don't need to be here if not CGB
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .dmg
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wOBPals2)
|
||||
ldh [rSVBK], a
|
||||
|
||||
ld hl, wOBPals2 palette 0
|
||||
ld de, wOBPals1 palette 0
|
||||
ldh a, [rOBP0]
|
||||
ld b, a
|
||||
ld c, 1
|
||||
call CopyPals
|
||||
ld a, TRUE
|
||||
ldh [hCGBPalUpdate], a
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
|
||||
.dmg
|
||||
pop af
|
||||
ret
|
||||
|
||||
DmgToCgbObjPal1::
|
||||
ldh [rOBP1], a
|
||||
push af
|
||||
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .dmg
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wOBPals2)
|
||||
ldh [rSVBK], a
|
||||
|
||||
ld hl, wOBPals2 palette 1
|
||||
ld de, wOBPals1 palette 1
|
||||
ldh a, [rOBP1]
|
||||
ld b, a
|
||||
ld c, 1
|
||||
call CopyPals
|
||||
ld a, TRUE
|
||||
ldh [hCGBPalUpdate], a
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
|
||||
.dmg
|
||||
pop af
|
||||
ret
|
||||
|
||||
CopyPals::
|
||||
; copy c palettes in order b from de to hl
|
||||
|
||||
push bc
|
||||
ld c, NUM_PAL_COLORS
|
||||
.loop
|
||||
push de
|
||||
push hl
|
||||
|
||||
; get pal color
|
||||
ld a, b
|
||||
maskbits 1 << PAL_COLOR_SIZE
|
||||
; 2 bytes per color
|
||||
add a
|
||||
ld l, a
|
||||
ld h, 0
|
||||
add hl, de
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
|
||||
; dest
|
||||
pop hl
|
||||
; write color
|
||||
ld [hl], e
|
||||
inc hl
|
||||
ld [hl], d
|
||||
inc hl
|
||||
; next pal color
|
||||
rept PAL_COLOR_SIZE
|
||||
srl b
|
||||
endr
|
||||
; source
|
||||
pop de
|
||||
; done pal?
|
||||
dec c
|
||||
jr nz, .loop
|
||||
|
||||
; de += 8 (next pal)
|
||||
ld a, PALETTE_SIZE
|
||||
add e
|
||||
jr nc, .ok
|
||||
inc d
|
||||
.ok
|
||||
ld e, a
|
||||
|
||||
; how many more pals?
|
||||
pop bc
|
||||
dec c
|
||||
jr nz, CopyPals
|
||||
ret
|
||||
|
||||
ClearVBank1::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ld a, 1
|
||||
ldh [rVBK], a
|
||||
|
||||
ld hl, VRAM_Begin
|
||||
ld bc, VRAM_End - VRAM_Begin
|
||||
xor a
|
||||
call ByteFill
|
||||
|
||||
xor a
|
||||
ldh [rVBK], a
|
||||
ret
|
||||
|
||||
ReloadSpritesNoPalettes::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
ret z
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wBGPals2)
|
||||
ldh [rSVBK], a
|
||||
ld hl, wBGPals2
|
||||
ld bc, (8 palettes) + (2 palettes)
|
||||
xor a
|
||||
call ByteFill
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
ld a, TRUE
|
||||
ldh [hCGBPalUpdate], a
|
||||
jp DelayFrame
|
||||
|
||||
SwapTextboxPalettes::
|
||||
homecall _SwapTextboxPalettes
|
||||
ret
|
||||
|
||||
ScrollBGMapPalettes::
|
||||
homecall _ScrollBGMapPalettes
|
||||
ret
|
||||
110
home/pokedex_flags.asm
Normal file
110
home/pokedex_flags.asm
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
CountSetBits::
|
||||
; Count the number of set bits in b bytes starting from hl.
|
||||
; Return in a, c and [wNumSetBits].
|
||||
ld c, 0
|
||||
.next
|
||||
ld a, [hli]
|
||||
ld e, a
|
||||
ld d, 8
|
||||
|
||||
.count
|
||||
srl e
|
||||
ld a, 0
|
||||
adc c
|
||||
ld c, a
|
||||
dec d
|
||||
jr nz, .count
|
||||
|
||||
dec b
|
||||
jr nz, .next
|
||||
|
||||
ld a, c
|
||||
ld [wNumSetBits], a
|
||||
ret
|
||||
|
||||
CountSetBits16::
|
||||
; Count the number of set bits in bc bytes starting from hl - assumes bc < $1000
|
||||
; Returns in bc; hl points to the end of the buffer; clobbers everything else
|
||||
; Assumes that CountSetBits will leave hl pointing to the end of the buffer
|
||||
swap b
|
||||
ld a, c
|
||||
swap a
|
||||
and $f
|
||||
or b
|
||||
ld d, a
|
||||
ld a, c
|
||||
jr z, .small_count
|
||||
ld bc, 0
|
||||
and $f
|
||||
jr z, .loop
|
||||
push de
|
||||
call .small_count
|
||||
pop de
|
||||
.loop
|
||||
push bc
|
||||
push de
|
||||
ld b, $10
|
||||
call CountSetBits
|
||||
pop de
|
||||
pop bc
|
||||
add a, c
|
||||
ld c, a
|
||||
jr nc, .handle_loop
|
||||
inc b
|
||||
.handle_loop
|
||||
dec d
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
.small_count
|
||||
ld b, a
|
||||
call CountSetBits
|
||||
ld b, 0
|
||||
ret
|
||||
|
||||
GetWeekday::
|
||||
ld a, [wCurDay]
|
||||
.mod
|
||||
sub 7
|
||||
jr nc, .mod
|
||||
add 7
|
||||
ret
|
||||
|
||||
SetSeenAndCaughtMon::
|
||||
call GetPokemonFlagIndex
|
||||
push de
|
||||
call SetSeenMonIndex
|
||||
pop de
|
||||
SetCaughtMonIndex::
|
||||
ld hl, wPokedexCaught
|
||||
jr SetPokedexStatusMonIndex
|
||||
|
||||
SetSeenMon::
|
||||
call GetPokemonFlagIndex
|
||||
SetSeenMonIndex::
|
||||
ld hl, wPokedexSeen
|
||||
SetPokedexStatusMonIndex:
|
||||
ld b, SET_FLAG
|
||||
jr FlagActionBaseOne
|
||||
|
||||
CheckCaughtMon::
|
||||
call GetPokemonFlagIndex
|
||||
CheckCaughtMonIndex::
|
||||
ld hl, wPokedexCaught
|
||||
jr CheckPokedexStatusMonIndex
|
||||
|
||||
CheckSeenMon::
|
||||
call GetPokemonFlagIndex
|
||||
CheckSeenMonIndex::
|
||||
ld hl, wPokedexSeen
|
||||
CheckPokedexStatusMonIndex:
|
||||
ld b, CHECK_FLAG
|
||||
FlagActionBaseOne:
|
||||
dec de
|
||||
jp FlagAction
|
||||
|
||||
GetPokemonFlagIndex:
|
||||
call GetPokemonIndexFromID
|
||||
ld d, h
|
||||
ld e, l
|
||||
ret
|
||||
318
home/pokemon.asm
Normal file
318
home/pokemon.asm
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
IsAPokemon::
|
||||
; Return carry if species a is not a Pokemon.
|
||||
and a
|
||||
jr z, .NotAPokemon
|
||||
cp EGG
|
||||
jr z, .Pokemon
|
||||
cp MON_TABLE_ENTRIES + 1
|
||||
jr c, .Pokemon
|
||||
|
||||
.NotAPokemon:
|
||||
scf
|
||||
ret
|
||||
|
||||
.Pokemon:
|
||||
and a
|
||||
ret
|
||||
|
||||
DrawBattleHPBar::
|
||||
; Draw an HP bar d tiles long at hl
|
||||
; Fill it up to e pixels
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
; Place 'HP:'
|
||||
ld a, $60
|
||||
ld [hli], a
|
||||
ld a, $61
|
||||
ld [hli], a
|
||||
|
||||
; Draw a template
|
||||
push hl
|
||||
ld a, $62 ; empty bar
|
||||
.template
|
||||
ld [hli], a
|
||||
dec d
|
||||
jr nz, .template
|
||||
ld a, $6b ; bar end
|
||||
add b
|
||||
ld [hl], a
|
||||
pop hl
|
||||
|
||||
; Safety check # pixels
|
||||
ld a, e
|
||||
and a
|
||||
jr nz, .fill
|
||||
ld a, c
|
||||
and a
|
||||
jr z, .done
|
||||
ld e, 1
|
||||
|
||||
.fill
|
||||
; Keep drawing tiles until pixel length is reached
|
||||
ld a, e
|
||||
sub TILE_WIDTH
|
||||
jr c, .lastbar
|
||||
|
||||
ld e, a
|
||||
ld a, $6a ; full bar
|
||||
ld [hli], a
|
||||
ld a, e
|
||||
and a
|
||||
jr z, .done
|
||||
jr .fill
|
||||
|
||||
.lastbar
|
||||
ld a, $62 ; empty bar
|
||||
add e ; + e
|
||||
ld [hl], a
|
||||
|
||||
.done
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
PrepMonFrontpic::
|
||||
ld a, $1
|
||||
ld [wBoxAlignment], a
|
||||
|
||||
_PrepMonFrontpic::
|
||||
ld a, [wCurPartySpecies]
|
||||
call IsAPokemon
|
||||
jr c, .not_pokemon
|
||||
|
||||
push hl
|
||||
ld de, vTiles2
|
||||
predef GetMonFrontpic
|
||||
pop hl
|
||||
xor a
|
||||
ldh [hGraphicStartTile], a
|
||||
lb bc, 7, 7
|
||||
predef PlaceGraphic
|
||||
xor a
|
||||
ld [wBoxAlignment], a
|
||||
ret
|
||||
|
||||
.not_pokemon
|
||||
xor a
|
||||
ld [wBoxAlignment], a
|
||||
inc a
|
||||
ld [wCurPartySpecies], a
|
||||
ret
|
||||
|
||||
PlayStereoCry::
|
||||
push af
|
||||
ld a, 1
|
||||
ld [wStereoPanningMask], a
|
||||
pop af
|
||||
call _PlayMonCry
|
||||
call WaitSFX
|
||||
ret
|
||||
|
||||
PlayStereoCry2::
|
||||
; Don't wait for the cry to end.
|
||||
; Used during pic animations.
|
||||
push af
|
||||
ld a, 1
|
||||
ld [wStereoPanningMask], a
|
||||
pop af
|
||||
jp _PlayMonCry
|
||||
|
||||
PlayMonCry::
|
||||
call PlayMonCry2
|
||||
call WaitSFX
|
||||
ret
|
||||
|
||||
PlayMonCry2::
|
||||
; Don't wait for the cry to end.
|
||||
push af
|
||||
xor a
|
||||
ld [wStereoPanningMask], a
|
||||
ld [wCryTracks], a
|
||||
pop af
|
||||
call _PlayMonCry
|
||||
ret
|
||||
|
||||
_PlayMonCry::
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
call GetCryIndex
|
||||
jr c, .done
|
||||
|
||||
ld e, c
|
||||
ld d, b
|
||||
call PlayCry
|
||||
|
||||
.done
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
LoadCry::
|
||||
call GetCryIndex
|
||||
ret c
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(PokemonCries)
|
||||
rst Bankswitch
|
||||
|
||||
ld hl, PokemonCries
|
||||
rept MON_CRY_LENGTH
|
||||
add hl, bc
|
||||
endr
|
||||
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
inc hl
|
||||
|
||||
ld a, [hli]
|
||||
ld [wCryPitch], a
|
||||
ld a, [hli]
|
||||
ld [wCryPitch + 1], a
|
||||
ld a, [hli]
|
||||
ld [wCryLength], a
|
||||
ld a, [hl]
|
||||
ld [wCryLength + 1], a
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
and a
|
||||
ret
|
||||
|
||||
GetCryIndex::
|
||||
and a
|
||||
jr z, .no
|
||||
cp MON_TABLE_ENTRIES + 1
|
||||
jr nc, .no
|
||||
|
||||
push hl
|
||||
call GetPokemonIndexFromID
|
||||
dec hl
|
||||
ld b, h
|
||||
ld c, l
|
||||
pop hl
|
||||
and a
|
||||
ret
|
||||
|
||||
.no
|
||||
scf
|
||||
ret
|
||||
|
||||
PrintLevel::
|
||||
; Print wTempMonLevel at hl
|
||||
|
||||
ld a, [wTempMonLevel]
|
||||
ld [hl], "<LV>"
|
||||
inc hl
|
||||
|
||||
; How many digits?
|
||||
ld c, 2
|
||||
cp 100 ; This is distinct from MAX_LEVEL.
|
||||
jr c, Print8BitNumLeftAlign
|
||||
|
||||
; 3-digit numbers overwrite the :L.
|
||||
dec hl
|
||||
inc c
|
||||
jr Print8BitNumLeftAlign
|
||||
|
||||
PrintLevel_Force3Digits::
|
||||
; Print :L and all 3 digits
|
||||
ld [hl], "<LV>"
|
||||
inc hl
|
||||
ld c, 3
|
||||
|
||||
Print8BitNumLeftAlign::
|
||||
ld [wTextDecimalByte], a
|
||||
ld de, wTextDecimalByte
|
||||
ld b, PRINTNUM_LEFTALIGN | 1
|
||||
jp PrintNum
|
||||
|
||||
GetBaseData::
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
; Egg doesn't have BaseData
|
||||
ld a, [wCurSpecies]
|
||||
cp EGG
|
||||
jr z, .egg
|
||||
|
||||
; Get BaseData
|
||||
call GetPokemonIndexFromID
|
||||
ld b, h
|
||||
ld c, l
|
||||
ld a, BANK(BaseData)
|
||||
ld hl, BaseData
|
||||
call LoadIndirectPointer
|
||||
; jr z, <some error handler>
|
||||
rst Bankswitch
|
||||
ld de, wCurBaseData
|
||||
ld bc, BASE_DATA_SIZE
|
||||
call CopyBytes
|
||||
jr .end
|
||||
|
||||
.egg
|
||||
ld de, UnusedEggPic
|
||||
|
||||
; Sprite dimensions
|
||||
ld b, $55 ; 5x5
|
||||
ld hl, wBasePicSize
|
||||
ld [hl], b
|
||||
|
||||
; Beta front and back sprites
|
||||
; (see pokegold-spaceworld's data/pokemon/base_stats/*)
|
||||
ld hl, wBaseUnusedFrontpic
|
||||
ld [hl], e
|
||||
inc hl
|
||||
ld [hl], d
|
||||
inc hl
|
||||
ld [hl], e
|
||||
inc hl
|
||||
ld [hl], d
|
||||
jr .end ; useless
|
||||
|
||||
.end
|
||||
; Replace Pokedex # with species
|
||||
ld a, [wCurSpecies]
|
||||
ld [wBaseSpecies], a
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
ret
|
||||
|
||||
GetCurNickname::
|
||||
ld a, [wCurPartyMon]
|
||||
ld hl, wPartyMonNicknames
|
||||
|
||||
GetNickname::
|
||||
; Get nickname a from list hl.
|
||||
|
||||
push hl
|
||||
push bc
|
||||
|
||||
call SkipNames
|
||||
ld de, wStringBuffer1
|
||||
|
||||
push de
|
||||
ld bc, MON_NAME_LENGTH
|
||||
call CopyBytes
|
||||
pop de
|
||||
|
||||
callfar CorrectNickErrors
|
||||
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
52
home/predef.asm
Normal file
52
home/predef.asm
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
Predef::
|
||||
; Call predefined function a.
|
||||
; Preserves bc, de, hl and f.
|
||||
|
||||
ld [wPredefID], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
ld a, BANK(GetPredefPointer)
|
||||
rst Bankswitch
|
||||
call GetPredefPointer ; stores hl in wPredefHL
|
||||
|
||||
; Switch to the new function's bank
|
||||
rst Bankswitch
|
||||
|
||||
; Instead of directly calling stuff,
|
||||
; push it to the stack in reverse.
|
||||
|
||||
ld hl, .Return
|
||||
push hl
|
||||
|
||||
; Call the Predef function
|
||||
ld a, [wPredefAddress]
|
||||
ld h, a
|
||||
ld a, [wPredefAddress + 1]
|
||||
ld l, a
|
||||
push hl
|
||||
|
||||
; Get hl back
|
||||
ld a, [wPredefHL]
|
||||
ld h, a
|
||||
ld a, [wPredefHL + 1]
|
||||
ld l, a
|
||||
ret
|
||||
|
||||
.Return:
|
||||
; Clean up after the Predef call
|
||||
|
||||
ld a, h
|
||||
ld [wPredefHL], a
|
||||
ld a, l
|
||||
ld [wPredefHL + 1], a
|
||||
|
||||
pop hl
|
||||
ld a, h
|
||||
rst Bankswitch
|
||||
|
||||
ld a, [wPredefHL]
|
||||
ld h, a
|
||||
ld a, [wPredefHL + 1]
|
||||
ld l, a
|
||||
ret
|
||||
79
home/print_bcd.asm
Normal file
79
home/print_bcd.asm
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
PrintBCDNumber::
|
||||
; function to print a BCD (Binary-coded decimal) number
|
||||
; de = address of BCD number
|
||||
; hl = destination address
|
||||
; c = flags and length
|
||||
; bit 7: if set, do not print leading zeroes
|
||||
; if unset, print leading zeroes
|
||||
; bit 6: if set, left-align the string (do not pad empty digits with spaces)
|
||||
; if unset, right-align the string
|
||||
; bit 5: if set, print currency symbol at the beginning of the string
|
||||
; if unset, do not print the currency symbol
|
||||
; bits 0-4: length of BCD number in bytes
|
||||
; Note that bits 5 and 7 are modified during execution. The above reflects
|
||||
; their meaning at the beginning of the functions's execution.
|
||||
ld b, c ; save flags in b
|
||||
res PRINTNUM_LEADINGZEROS_F, c
|
||||
res PRINTNUM_LEFTALIGN_F, c
|
||||
res PRINTNUM_MONEY_F, c ; c now holds the length
|
||||
bit PRINTNUM_MONEY_F, b
|
||||
jr z, .loop
|
||||
bit PRINTNUM_LEADINGZEROS_F, b
|
||||
jr nz, .loop ; skip currency symbol
|
||||
ld [hl], "¥"
|
||||
inc hl
|
||||
.loop
|
||||
ld a, [de]
|
||||
swap a
|
||||
call PrintBCDDigit ; print upper digit
|
||||
ld a, [de]
|
||||
call PrintBCDDigit ; print lower digit
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .loop
|
||||
bit PRINTNUM_LEADINGZEROS_F, b
|
||||
ret z ; if so, we are done
|
||||
; every digit of the BCD number is zero
|
||||
bit PRINTNUM_LEFTALIGN_F, b
|
||||
jr nz, .skipLeftAlignmentAdjustment
|
||||
; the string is left-aligned; it needs to be moved back one space
|
||||
dec hl
|
||||
.skipLeftAlignmentAdjustment
|
||||
bit PRINTNUM_MONEY_F, b
|
||||
jr z, .skipCurrencySymbol
|
||||
ld [hl], "¥" ; currency symbol
|
||||
inc hl
|
||||
.skipCurrencySymbol
|
||||
ld [hl], "0"
|
||||
call PrintLetterDelay
|
||||
inc hl
|
||||
ret
|
||||
|
||||
PrintBCDDigit::
|
||||
and %00001111
|
||||
and a
|
||||
jr z, .zeroDigit
|
||||
; nonzero digit
|
||||
bit PRINTNUM_LEADINGZEROS_F, b ; have any non-space characters been printed?
|
||||
jr z, .outputDigit
|
||||
; if bit 7 is set, then no numbers have been printed yet
|
||||
bit PRINTNUM_MONEY_F, b
|
||||
jr z, .skipCurrencySymbol
|
||||
ld [hl], "¥"
|
||||
inc hl
|
||||
res PRINTNUM_MONEY_F, b
|
||||
.skipCurrencySymbol
|
||||
res PRINTNUM_LEADINGZEROS_F, b ; unset 7 to indicate that a nonzero digit has been reached
|
||||
.outputDigit
|
||||
add "0"
|
||||
ld [hli], a
|
||||
jp PrintLetterDelay
|
||||
|
||||
.zeroDigit
|
||||
bit PRINTNUM_LEADINGZEROS_F, b ; either printing leading zeroes or already reached a nonzero digit?
|
||||
jr z, .outputDigit ; if so, print a zero digit
|
||||
bit PRINTNUM_LEFTALIGN_F, b
|
||||
ret nz
|
||||
ld a, " "
|
||||
ld [hli], a ; if right-aligned, "print" a space by advancing the pointer
|
||||
ret
|
||||
127
home/print_text.asm
Normal file
127
home/print_text.asm
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
PrintLetterDelay::
|
||||
; Wait before printing the next letter.
|
||||
|
||||
; The text speed setting in wOptions is actually a frame count:
|
||||
; fast: 1 frame
|
||||
; mid: 3 frames
|
||||
; slow: 5 frames
|
||||
|
||||
; wTextboxFlags[!0] and A or B override text speed with a one-frame delay.
|
||||
; wOptions[4] and wTextboxFlags[!1] disable the delay.
|
||||
|
||||
ld a, [wOptions]
|
||||
bit NO_TEXT_SCROLL, a
|
||||
ret nz
|
||||
|
||||
; non-scrolling text?
|
||||
ld a, [wTextboxFlags]
|
||||
bit NO_TEXT_DELAY_F, a
|
||||
ret z
|
||||
|
||||
push hl
|
||||
push de
|
||||
push bc
|
||||
|
||||
; force fast scroll?
|
||||
ld a, [wTextboxFlags]
|
||||
bit FAST_TEXT_DELAY_F, a
|
||||
jr z, .fast
|
||||
|
||||
; text speed
|
||||
ld a, [wOptions]
|
||||
and %111
|
||||
jr .updatedelay
|
||||
|
||||
.fast
|
||||
ld a, TEXT_DELAY_FAST
|
||||
|
||||
.updatedelay
|
||||
ld [wTextDelayFrames], a
|
||||
|
||||
.checkjoypad
|
||||
call GetJoypad
|
||||
|
||||
; input override
|
||||
ld a, [wDisableTextAcceleration]
|
||||
and a
|
||||
jr nz, .wait
|
||||
|
||||
; Wait one frame if holding A or B.
|
||||
ldh a, [hJoyDown]
|
||||
bit A_BUTTON_F, a
|
||||
jr z, .checkb
|
||||
jr .delay
|
||||
.checkb
|
||||
bit B_BUTTON_F, a
|
||||
jr z, .wait
|
||||
|
||||
.delay
|
||||
call DelayFrame
|
||||
jr .end
|
||||
|
||||
.wait
|
||||
ld a, [wTextDelayFrames]
|
||||
and a
|
||||
jr nz, .checkjoypad
|
||||
|
||||
.end
|
||||
pop bc
|
||||
pop de
|
||||
pop hl
|
||||
ret
|
||||
|
||||
CopyDataUntil::
|
||||
; Copy [hl .. bc) to de.
|
||||
|
||||
; In other words, the source data is
|
||||
; from hl up to but not including bc,
|
||||
; and the destination is de.
|
||||
|
||||
ld a, [hli]
|
||||
ld [de], a
|
||||
inc de
|
||||
ld a, h
|
||||
cp b
|
||||
jr nz, CopyDataUntil
|
||||
ld a, l
|
||||
cp c
|
||||
jr nz, CopyDataUntil
|
||||
ret
|
||||
|
||||
PrintNum::
|
||||
homecall _PrintNum
|
||||
ret
|
||||
|
||||
MobilePrintNum::
|
||||
homecall _MobilePrintNum
|
||||
ret
|
||||
|
||||
FarPrintText::
|
||||
ldh [hTempBank], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ldh a, [hTempBank]
|
||||
rst Bankswitch
|
||||
|
||||
call PrintText
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
CallPointerAt::
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, [hli]
|
||||
rst Bankswitch
|
||||
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
call _hl_
|
||||
|
||||
pop hl
|
||||
ld a, h
|
||||
rst Bankswitch
|
||||
ret
|
||||
41
home/printer.asm
Normal file
41
home/printer.asm
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
PrinterReceive::
|
||||
homecall _PrinterReceive
|
||||
ret
|
||||
|
||||
AskSerial::
|
||||
; send out a handshake while serial int is off
|
||||
ld a, [wPrinterConnectionOpen]
|
||||
bit 0, a
|
||||
ret z
|
||||
|
||||
; if we're still interpreting data, don't try to receive
|
||||
ld a, [wPrinterOpcode]
|
||||
and a
|
||||
ret nz
|
||||
|
||||
; once every 6 frames
|
||||
ld hl, wHandshakeFrameDelay
|
||||
inc [hl]
|
||||
ld a, [hl]
|
||||
cp 6
|
||||
ret c
|
||||
|
||||
xor a
|
||||
ld [hl], a
|
||||
|
||||
ld a, $0c
|
||||
ld [wPrinterOpcode], a
|
||||
|
||||
; handshake
|
||||
ld a, $88
|
||||
ldh [rSB], a
|
||||
|
||||
; switch to internal clock
|
||||
ld a, (0 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
|
||||
; start transfer
|
||||
ld a, (1 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
|
||||
ret
|
||||
12
home/queue_script.asm
Normal file
12
home/queue_script.asm
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
QueueScript::
|
||||
; Push pointer hl in the current bank to wQueuedScriptBank.
|
||||
ldh a, [hROMBank]
|
||||
|
||||
FarQueueScript::
|
||||
; Push pointer a:hl to wQueuedScriptBank.
|
||||
ld [wQueuedScriptBank], a
|
||||
ld a, l
|
||||
ld [wQueuedScriptAddr], a
|
||||
ld a, h
|
||||
ld [wQueuedScriptAddr + 1], a
|
||||
ret
|
||||
80
home/random.asm
Normal file
80
home/random.asm
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
Random::
|
||||
; A simple hardware-based random number generator (RNG).
|
||||
|
||||
; Two random numbers are generated by adding and subtracting
|
||||
; the divider to the respective values every time it's called.
|
||||
|
||||
; The divider is a register that increments at a rate of 16384Hz.
|
||||
; For comparison, the Game Boy operates at a clock speed of 4.2MHz.
|
||||
|
||||
; Additionally, an equivalent function is executed in VBlank.
|
||||
|
||||
; This leaves a with the value in hRandomSub.
|
||||
|
||||
push bc
|
||||
|
||||
ldh a, [rDIV]
|
||||
ld b, a
|
||||
ldh a, [hRandomAdd]
|
||||
adc b
|
||||
ldh [hRandomAdd], a
|
||||
|
||||
ldh a, [rDIV]
|
||||
ld b, a
|
||||
ldh a, [hRandomSub]
|
||||
sbc b
|
||||
ldh [hRandomSub], a
|
||||
|
||||
pop bc
|
||||
ret
|
||||
|
||||
BattleRandom::
|
||||
; _BattleRandom lives in another bank.
|
||||
|
||||
; It handles all RNG calls in the battle engine, allowing
|
||||
; link battles to remain in sync using a shared PRNG.
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_BattleRandom)
|
||||
rst Bankswitch
|
||||
|
||||
call _BattleRandom
|
||||
|
||||
ld [wPredefHL + 1], a
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ld a, [wPredefHL + 1]
|
||||
ret
|
||||
|
||||
RandomRange::
|
||||
; Return a random number between 0 and a (non-inclusive).
|
||||
|
||||
push bc
|
||||
ld c, a
|
||||
|
||||
; b = $100 % c
|
||||
xor a
|
||||
sub c
|
||||
.mod
|
||||
sub c
|
||||
jr nc, .mod
|
||||
add c
|
||||
ld b, a
|
||||
|
||||
; Get a random number
|
||||
; from 0 to $ff - b.
|
||||
push bc
|
||||
.loop
|
||||
call Random
|
||||
ldh a, [hRandomAdd]
|
||||
ld c, a
|
||||
add b
|
||||
jr c, .loop
|
||||
ld a, c
|
||||
pop bc
|
||||
|
||||
call SimpleDivide
|
||||
|
||||
pop bc
|
||||
ret
|
||||
32
home/region.asm
Normal file
32
home/region.asm
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
IsInJohto::
|
||||
; Return 0 if the player is in Johto, and 1 in Kanto.
|
||||
|
||||
ld a, [wMapGroup]
|
||||
ld b, a
|
||||
ld a, [wMapNumber]
|
||||
ld c, a
|
||||
call GetWorldMapLocation
|
||||
|
||||
cp LANDMARK_FAST_SHIP
|
||||
jr z, .Johto
|
||||
|
||||
cp LANDMARK_SPECIAL
|
||||
jr nz, .CheckRegion
|
||||
|
||||
ld a, [wBackupMapGroup]
|
||||
ld b, a
|
||||
ld a, [wBackupMapNumber]
|
||||
ld c, a
|
||||
call GetWorldMapLocation
|
||||
|
||||
.CheckRegion:
|
||||
cp KANTO_LANDMARK
|
||||
jr nc, .Kanto
|
||||
|
||||
.Johto:
|
||||
xor a ; JOHTO_REGION
|
||||
ret
|
||||
|
||||
.Kanto:
|
||||
ld a, KANTO_REGION
|
||||
ret
|
||||
61
home/scrolling_menu.asm
Normal file
61
home/scrolling_menu.asm
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
ScrollingMenu::
|
||||
call CopyMenuData
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
ld a, BANK(_ScrollingMenu) ; aka BANK(_InitScrollingMenu)
|
||||
rst Bankswitch
|
||||
|
||||
call _InitScrollingMenu
|
||||
call .UpdatePalettes
|
||||
call _ScrollingMenu
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ld a, [wMenuJoypad]
|
||||
ret
|
||||
|
||||
.UpdatePalettes:
|
||||
ld hl, wVramState
|
||||
bit 0, [hl]
|
||||
jp nz, UpdateTimePals
|
||||
jp SetPalettes
|
||||
|
||||
InitScrollingMenu::
|
||||
ld a, [wMenuBorderTopCoord]
|
||||
dec a
|
||||
ld b, a
|
||||
ld a, [wMenuBorderBottomCoord]
|
||||
sub b
|
||||
ld d, a
|
||||
ld a, [wMenuBorderLeftCoord]
|
||||
dec a
|
||||
ld c, a
|
||||
ld a, [wMenuBorderRightCoord]
|
||||
sub c
|
||||
ld e, a
|
||||
push de
|
||||
call Coord2Tile
|
||||
pop bc
|
||||
jp Textbox
|
||||
|
||||
JoyTextDelay_ForcehJoyDown::
|
||||
call DelayFrame
|
||||
|
||||
ldh a, [hInMenu]
|
||||
push af
|
||||
ld a, $1
|
||||
ldh [hInMenu], a
|
||||
call JoyTextDelay
|
||||
pop af
|
||||
ldh [hInMenu], a
|
||||
|
||||
ldh a, [hJoyLast]
|
||||
and D_RIGHT + D_LEFT + D_UP + D_DOWN
|
||||
ld c, a
|
||||
ldh a, [hJoyPressed]
|
||||
and A_BUTTON + B_BUTTON + SELECT + START
|
||||
or c
|
||||
ld c, a
|
||||
ret
|
||||
407
home/serial.asm
Normal file
407
home/serial.asm
Normal file
|
|
@ -0,0 +1,407 @@
|
|||
Serial::
|
||||
; The serial interrupt.
|
||||
|
||||
push af
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
|
||||
ldh a, [hMobileReceive]
|
||||
and a
|
||||
jr nz, .mobile
|
||||
|
||||
ld a, [wPrinterConnectionOpen]
|
||||
bit 0, a
|
||||
jr nz, .printer
|
||||
|
||||
ldh a, [hSerialConnectionStatus]
|
||||
inc a ; is it equal to CONNECTION_NOT_ESTABLISHED?
|
||||
jr z, .establish_connection
|
||||
|
||||
ldh a, [rSB]
|
||||
ldh [hSerialReceive], a
|
||||
|
||||
ldh a, [hSerialSend]
|
||||
ldh [rSB], a
|
||||
|
||||
ldh a, [hSerialConnectionStatus]
|
||||
cp USING_INTERNAL_CLOCK
|
||||
jr z, .player2
|
||||
|
||||
ld a, (0 << rSC_ON) | (0 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
ld a, (1 << rSC_ON) | (0 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
jr .player2
|
||||
|
||||
.mobile
|
||||
call MobileReceive
|
||||
jr .end
|
||||
|
||||
.printer
|
||||
call PrinterReceive
|
||||
jr .end
|
||||
|
||||
.establish_connection
|
||||
ldh a, [rSB]
|
||||
cp USING_EXTERNAL_CLOCK
|
||||
jr z, .player1
|
||||
cp USING_INTERNAL_CLOCK
|
||||
jr nz, .player2
|
||||
|
||||
.player1
|
||||
ldh [hSerialReceive], a
|
||||
ldh [hSerialConnectionStatus], a
|
||||
cp USING_INTERNAL_CLOCK
|
||||
jr z, ._player2
|
||||
|
||||
xor a
|
||||
ldh [rSB], a
|
||||
|
||||
ld a, 3
|
||||
ldh [rDIV], a
|
||||
.delay_loop
|
||||
ldh a, [rDIV]
|
||||
bit 7, a
|
||||
jr nz, .delay_loop
|
||||
|
||||
ld a, (0 << rSC_ON) | (0 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
ld a, (1 << rSC_ON) | (0 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
jr .player2
|
||||
|
||||
._player2
|
||||
xor a
|
||||
ldh [rSB], a
|
||||
|
||||
.player2
|
||||
ld a, TRUE
|
||||
ldh [hSerialReceivedNewData], a
|
||||
ld a, SERIAL_NO_DATA_BYTE
|
||||
ldh [hSerialSend], a
|
||||
|
||||
.end
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
pop af
|
||||
reti
|
||||
|
||||
Serial_ExchangeBytes::
|
||||
; send bc bytes from hl, receive bc bytes to de
|
||||
ld a, TRUE
|
||||
ldh [hSerialIgnoringInitialData], a
|
||||
|
||||
.loop
|
||||
ld a, [hl]
|
||||
ldh [hSerialSend], a
|
||||
call Serial_ExchangeByte
|
||||
push bc
|
||||
ld b, a
|
||||
inc hl
|
||||
|
||||
ld a, 48
|
||||
.wait
|
||||
dec a
|
||||
jr nz, .wait
|
||||
|
||||
ldh a, [hSerialIgnoringInitialData]
|
||||
and a
|
||||
ld a, b
|
||||
pop bc
|
||||
jr z, .load
|
||||
dec hl
|
||||
cp SERIAL_PREAMBLE_BYTE
|
||||
jr nz, .loop
|
||||
xor a ; FALSE
|
||||
ldh [hSerialIgnoringInitialData], a
|
||||
jr .loop
|
||||
|
||||
.load
|
||||
ld [de], a
|
||||
inc de
|
||||
dec bc
|
||||
ld a, b
|
||||
or c
|
||||
jr nz, .loop
|
||||
ret
|
||||
|
||||
Serial_ExchangeByte::
|
||||
.timeout_loop
|
||||
xor a
|
||||
ldh [hSerialReceivedNewData], a
|
||||
ldh a, [hSerialConnectionStatus]
|
||||
cp USING_INTERNAL_CLOCK
|
||||
jr nz, .not_player_2
|
||||
ld a, (0 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
ld a, (1 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
.not_player_2
|
||||
.loop
|
||||
ldh a, [hSerialReceivedNewData]
|
||||
and a
|
||||
jr nz, .await_new_data
|
||||
ldh a, [hSerialConnectionStatus]
|
||||
cp USING_EXTERNAL_CLOCK
|
||||
jr nz, .not_player_1_or_timed_out
|
||||
call CheckLinkTimeoutFramesNonzero
|
||||
jr z, .not_player_1_or_timed_out
|
||||
call .ShortDelay
|
||||
push hl
|
||||
ld hl, wLinkTimeoutFrames + 1
|
||||
inc [hl]
|
||||
jr nz, .no_rollover_up
|
||||
dec hl
|
||||
inc [hl]
|
||||
|
||||
.no_rollover_up
|
||||
pop hl
|
||||
call CheckLinkTimeoutFramesNonzero
|
||||
jr nz, .loop
|
||||
jp SerialDisconnected
|
||||
|
||||
.not_player_1_or_timed_out
|
||||
ldh a, [rIE]
|
||||
and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
|
||||
cp 1 << SERIAL
|
||||
jr nz, .loop
|
||||
ld a, [wLinkByteTimeout]
|
||||
dec a
|
||||
ld [wLinkByteTimeout], a
|
||||
jr nz, .loop
|
||||
ld a, [wLinkByteTimeout + 1]
|
||||
dec a
|
||||
ld [wLinkByteTimeout + 1], a
|
||||
jr nz, .loop
|
||||
ldh a, [hSerialConnectionStatus]
|
||||
cp USING_EXTERNAL_CLOCK
|
||||
jr z, .await_new_data
|
||||
|
||||
ld a, 255
|
||||
.long_delay_loop
|
||||
dec a
|
||||
jr nz, .long_delay_loop
|
||||
|
||||
.await_new_data
|
||||
xor a
|
||||
ldh [hSerialReceivedNewData], a
|
||||
ldh a, [rIE]
|
||||
and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
|
||||
sub 1 << SERIAL
|
||||
jr nz, .non_serial_interrupts_enabled
|
||||
|
||||
; a == 0
|
||||
assert LOW(SERIAL_LINK_BYTE_TIMEOUT) == 0
|
||||
ld [wLinkByteTimeout], a
|
||||
ld a, HIGH(SERIAL_LINK_BYTE_TIMEOUT)
|
||||
ld [wLinkByteTimeout + 1], a
|
||||
|
||||
.non_serial_interrupts_enabled
|
||||
ldh a, [hSerialReceive]
|
||||
cp SERIAL_NO_DATA_BYTE
|
||||
ret nz
|
||||
call CheckLinkTimeoutFramesNonzero
|
||||
jr z, .timed_out
|
||||
push hl
|
||||
ld hl, wLinkTimeoutFrames + 1
|
||||
ld a, [hl]
|
||||
dec a
|
||||
ld [hld], a
|
||||
inc a
|
||||
jr nz, .no_rollover
|
||||
dec [hl]
|
||||
|
||||
.no_rollover
|
||||
pop hl
|
||||
call CheckLinkTimeoutFramesNonzero
|
||||
jr z, SerialDisconnected
|
||||
|
||||
.timed_out
|
||||
ldh a, [rIE]
|
||||
and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK)
|
||||
cp 1 << SERIAL
|
||||
ld a, SERIAL_NO_DATA_BYTE
|
||||
ret z
|
||||
ld a, [hl]
|
||||
ldh [hSerialSend], a
|
||||
call DelayFrame
|
||||
jp .timeout_loop
|
||||
|
||||
.ShortDelay:
|
||||
ld a, 15
|
||||
.short_delay_loop
|
||||
dec a
|
||||
jr nz, .short_delay_loop
|
||||
ret
|
||||
|
||||
CheckLinkTimeoutFramesNonzero::
|
||||
push hl
|
||||
ld hl, wLinkTimeoutFrames
|
||||
ld a, [hli]
|
||||
or [hl]
|
||||
pop hl
|
||||
ret
|
||||
|
||||
; This sets wLinkTimeoutFrames to $ffff, since
|
||||
; a is always 0 when it is called.
|
||||
SerialDisconnected::
|
||||
dec a
|
||||
ld [wLinkTimeoutFrames], a
|
||||
ld [wLinkTimeoutFrames + 1], a
|
||||
ret
|
||||
|
||||
; This is used to check that both players entered the same Cable Club room.
|
||||
Serial_ExchangeSyncBytes::
|
||||
ld hl, wLinkPlayerSyncBuffer
|
||||
ld de, wLinkReceivedSyncBuffer
|
||||
ld c, 2
|
||||
ld a, TRUE
|
||||
ldh [hSerialIgnoringInitialData], a
|
||||
.exchange
|
||||
call DelayFrame
|
||||
ld a, [hl]
|
||||
ldh [hSerialSend], a
|
||||
call Serial_ExchangeByte
|
||||
ld b, a
|
||||
inc hl
|
||||
ldh a, [hSerialIgnoringInitialData]
|
||||
and a
|
||||
ld a, FALSE
|
||||
ldh [hSerialIgnoringInitialData], a
|
||||
jr nz, .exchange
|
||||
ld a, b
|
||||
ld [de], a
|
||||
inc de
|
||||
dec c
|
||||
jr nz, .exchange
|
||||
ret
|
||||
|
||||
Serial_PrintWaitingTextAndSyncAndExchangeNybble::
|
||||
call LoadTilemapToTempTilemap
|
||||
callfar PlaceWaitingText
|
||||
call WaitLinkTransfer
|
||||
jp SafeLoadTempTilemapToTilemap
|
||||
|
||||
Serial_SyncAndExchangeNybble:: ; unreferenced
|
||||
call LoadTilemapToTempTilemap
|
||||
callfar PlaceWaitingText
|
||||
jp WaitLinkTransfer ; pointless
|
||||
|
||||
WaitLinkTransfer::
|
||||
vc_hook Wireless_WaitLinkTransfer
|
||||
ld a, $ff
|
||||
ld [wOtherPlayerLinkAction], a
|
||||
.loop
|
||||
call LinkTransfer
|
||||
call DelayFrame
|
||||
call CheckLinkTimeoutFramesNonzero
|
||||
jr z, .check
|
||||
push hl
|
||||
ld hl, wLinkTimeoutFrames + 1
|
||||
dec [hl]
|
||||
jr nz, .skip
|
||||
dec hl
|
||||
dec [hl]
|
||||
jr nz, .skip
|
||||
; We might be disconnected
|
||||
pop hl
|
||||
xor a
|
||||
jp SerialDisconnected
|
||||
|
||||
.skip
|
||||
pop hl
|
||||
|
||||
.check
|
||||
ld a, [wOtherPlayerLinkAction]
|
||||
inc a
|
||||
jr z, .loop
|
||||
|
||||
vc_patch Wireless_net_delay_1
|
||||
if DEF(_CRYSTAL_VC)
|
||||
ld b, 26
|
||||
else
|
||||
ld b, 10
|
||||
endc
|
||||
vc_patch_end
|
||||
.receive
|
||||
call DelayFrame
|
||||
call LinkTransfer
|
||||
dec b
|
||||
jr nz, .receive
|
||||
|
||||
vc_patch Wireless_net_delay_2
|
||||
if DEF(_CRYSTAL_VC)
|
||||
ld b, 26
|
||||
else
|
||||
ld b, 10
|
||||
endc
|
||||
vc_patch_end
|
||||
.acknowledge
|
||||
call DelayFrame
|
||||
call LinkDataReceived
|
||||
dec b
|
||||
jr nz, .acknowledge
|
||||
|
||||
ld a, [wOtherPlayerLinkAction]
|
||||
ld [wOtherPlayerLinkMode], a
|
||||
vc_hook Wireless_WaitLinkTransfer_ret
|
||||
ret
|
||||
|
||||
LinkTransfer::
|
||||
push bc
|
||||
ld b, SERIAL_TIMECAPSULE
|
||||
ld a, [wLinkMode]
|
||||
cp LINK_TIMECAPSULE
|
||||
jr z, .got_high_nybble
|
||||
ld b, SERIAL_TIMECAPSULE
|
||||
jr c, .got_high_nybble
|
||||
cp LINK_TRADECENTER
|
||||
ld b, SERIAL_TRADECENTER
|
||||
jr z, .got_high_nybble
|
||||
ld b, SERIAL_BATTLE
|
||||
|
||||
.got_high_nybble
|
||||
call .Receive
|
||||
ld a, [wPlayerLinkAction]
|
||||
add b
|
||||
ldh [hSerialSend], a
|
||||
ldh a, [hSerialConnectionStatus]
|
||||
cp USING_INTERNAL_CLOCK
|
||||
jr nz, .player_1
|
||||
ld a, (0 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
ld a, (1 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
|
||||
.player_1
|
||||
call .Receive
|
||||
pop bc
|
||||
ret
|
||||
|
||||
.Receive:
|
||||
ldh a, [hSerialReceive]
|
||||
ld [wOtherPlayerLinkMode], a
|
||||
and $f0
|
||||
cp b
|
||||
ret nz
|
||||
xor a
|
||||
ldh [hSerialReceive], a
|
||||
ld a, [wOtherPlayerLinkMode]
|
||||
and $f
|
||||
ld [wOtherPlayerLinkAction], a
|
||||
ret
|
||||
|
||||
LinkDataReceived::
|
||||
; Let the other system know that the data has been received.
|
||||
xor a
|
||||
ldh [hSerialSend], a
|
||||
ldh a, [hSerialConnectionStatus]
|
||||
cp USING_INTERNAL_CLOCK
|
||||
ret nz
|
||||
ld a, (0 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
ld a, (1 << rSC_ON) | (1 << rSC_CLOCK)
|
||||
ldh [rSC], a
|
||||
ret
|
||||
9
home/sine.asm
Normal file
9
home/sine.asm
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Cosine:: ; unreferenced
|
||||
; a = d * cos(a * pi/32)
|
||||
add %010000 ; cos(x) = sin(x + pi/2)
|
||||
; fallthrough
|
||||
Sine::
|
||||
; a = d * sin(a * pi/32)
|
||||
ld e, a
|
||||
homecall _Sine
|
||||
ret
|
||||
31
home/sprite_anims.asm
Normal file
31
home/sprite_anims.asm
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
InitSpriteAnimStruct::
|
||||
ld [wSpriteAnimID], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
ld a, BANK(_InitSpriteAnimStruct)
|
||||
rst Bankswitch
|
||||
ld a, [wSpriteAnimID]
|
||||
|
||||
call _InitSpriteAnimStruct
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ret
|
||||
|
||||
ReinitSpriteAnimFrame::
|
||||
ld [wSpriteAnimID], a
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
ld a, BANK(_ReinitSpriteAnimFrame)
|
||||
rst Bankswitch
|
||||
ld a, [wSpriteAnimID]
|
||||
|
||||
call _ReinitSpriteAnimFrame
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ret
|
||||
19
home/sprite_updates.asm
Normal file
19
home/sprite_updates.asm
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
DisableSpriteUpdates::
|
||||
xor a
|
||||
ldh [hMapAnims], a
|
||||
ld a, [wVramState]
|
||||
res 0, a
|
||||
ld [wVramState], a
|
||||
xor a
|
||||
ld [wSpriteUpdatesEnabled], a
|
||||
ret
|
||||
|
||||
EnableSpriteUpdates::
|
||||
ld a, $1
|
||||
ld [wSpriteUpdatesEnabled], a
|
||||
ld a, [wVramState]
|
||||
set 0, a
|
||||
ld [wVramState], a
|
||||
ld a, $1
|
||||
ldh [hMapAnims], a
|
||||
ret
|
||||
30
home/sram.asm
Normal file
30
home/sram.asm
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
OpenSRAM::
|
||||
; if invalid bank, sram is disabled
|
||||
cp NUM_SRAM_BANKS
|
||||
jr nc, CloseSRAM
|
||||
|
||||
; switch to sram bank a
|
||||
push af
|
||||
; latch clock data
|
||||
ld a, 1
|
||||
ld [MBC3LatchClock], a
|
||||
; enable sram/clock write
|
||||
ld a, SRAM_ENABLE
|
||||
ld [MBC3SRamEnable], a
|
||||
; select sram bank
|
||||
pop af
|
||||
ldh [hSRAMBank], a
|
||||
ld [MBC3SRamBank], a
|
||||
ret
|
||||
|
||||
CloseSRAM::
|
||||
push af
|
||||
ld a, -1
|
||||
ldh [hSRAMBank], a
|
||||
ld a, SRAM_DISABLE
|
||||
; reset clock latch for next time
|
||||
ld [MBC3LatchClock], a
|
||||
; disable sram/clock write
|
||||
ld [MBC3SRamEnable], a
|
||||
pop af
|
||||
ret
|
||||
124
home/stone_queue.asm
Normal file
124
home/stone_queue.asm
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
HandleStoneQueue::
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
call SwitchToMapScriptsBank
|
||||
call .WarpAction
|
||||
|
||||
pop bc
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
.WarpAction:
|
||||
ld hl, OBJECT_MAP_OBJECT_INDEX
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
cp $ff
|
||||
ret nc
|
||||
|
||||
ld l, a
|
||||
push hl
|
||||
call .IsObjectOnWarp
|
||||
pop hl
|
||||
ret nc
|
||||
ld d, a
|
||||
ld e, l
|
||||
call .IsObjectInStoneTable
|
||||
ret nc
|
||||
call CallMapScript
|
||||
farcall EnableScriptMode
|
||||
scf
|
||||
ret
|
||||
|
||||
.IsObjectOnWarp:
|
||||
push de
|
||||
|
||||
ld hl, OBJECT_MAP_X
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
ld hl, OBJECT_MAP_Y
|
||||
add hl, de
|
||||
ld e, [hl]
|
||||
|
||||
sub 4
|
||||
ld d, a
|
||||
ld a, e
|
||||
sub 4
|
||||
ld e, a
|
||||
call .check_on_warp
|
||||
|
||||
pop de
|
||||
ret
|
||||
|
||||
.check_on_warp
|
||||
ld hl, wCurMapWarpsPointer
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld a, [wCurMapWarpCount]
|
||||
and a
|
||||
ret z
|
||||
|
||||
.loop
|
||||
push af
|
||||
ld a, [hl]
|
||||
cp e
|
||||
jr nz, .not_on_warp
|
||||
inc hl
|
||||
ld a, [hld]
|
||||
cp d
|
||||
jr z, .found_warp
|
||||
|
||||
.not_on_warp
|
||||
ld a, WARP_EVENT_SIZE
|
||||
add l
|
||||
ld l, a
|
||||
jr nc, .no_carry
|
||||
inc h
|
||||
.no_carry
|
||||
|
||||
pop af
|
||||
dec a
|
||||
jr nz, .loop
|
||||
and a
|
||||
ret
|
||||
|
||||
.found_warp
|
||||
pop af
|
||||
ld d, a
|
||||
ld a, [wCurMapWarpCount]
|
||||
sub d
|
||||
inc a
|
||||
scf
|
||||
ret
|
||||
|
||||
.IsObjectInStoneTable:
|
||||
inc e
|
||||
ld hl, CMDQUEUE_ADDR
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
.loop2
|
||||
ld a, [hli]
|
||||
cp $ff
|
||||
ret z
|
||||
cp d
|
||||
jr nz, .next_inc3
|
||||
ld a, [hli]
|
||||
cp e
|
||||
jr nz, .next_inc2
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
scf
|
||||
ret
|
||||
|
||||
.next_inc3
|
||||
inc hl
|
||||
|
||||
.next_inc2
|
||||
inc hl
|
||||
inc hl
|
||||
jr .loop2
|
||||
35
home/string.asm
Normal file
35
home/string.asm
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
InitString::
|
||||
; Init a string of length c.
|
||||
push hl
|
||||
jr _InitString
|
||||
|
||||
InitName::
|
||||
; Intended for names, so this function is limited to ten characters.
|
||||
push hl
|
||||
ld c, NAME_LENGTH - 1
|
||||
_InitString::
|
||||
; if the string pointed to by hl is empty (defined as "zero or more spaces
|
||||
; followed by a null"), then initialize it to the string pointed to by de.
|
||||
push bc
|
||||
.loop
|
||||
ld a, [hli]
|
||||
cp "@"
|
||||
jr z, .blank
|
||||
cp " "
|
||||
jr nz, .notblank
|
||||
dec c
|
||||
jr nz, .loop
|
||||
.blank
|
||||
pop bc
|
||||
ld l, e
|
||||
ld h, d
|
||||
pop de
|
||||
ld b, 0
|
||||
inc c
|
||||
call CopyBytes
|
||||
ret
|
||||
|
||||
.notblank
|
||||
pop bc
|
||||
pop hl
|
||||
ret
|
||||
1044
home/text.asm
Normal file
1044
home/text.asm
Normal file
File diff suppressed because it is too large
Load diff
226
home/tilemap.asm
Normal file
226
home/tilemap.asm
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
ClearBGPalettes::
|
||||
call ClearPalettes
|
||||
WaitBGMap::
|
||||
; Tell VBlank to update BG Map
|
||||
ld a, 1 ; BG Map 0 tiles
|
||||
ldh [hBGMapMode], a
|
||||
; Wait for it to do its magic
|
||||
ld c, 4
|
||||
jp DelayFrames
|
||||
|
||||
WaitBGMap2::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .bg0
|
||||
|
||||
ld a, 2
|
||||
ldh [hBGMapMode], a
|
||||
ld c, 4
|
||||
call DelayFrames
|
||||
|
||||
.bg0
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
ld c, 4
|
||||
jp DelayFrames
|
||||
|
||||
IsCGB::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
ret
|
||||
|
||||
ApplyTilemap::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, .dmg
|
||||
|
||||
ld a, [wSpriteUpdatesEnabled]
|
||||
and a
|
||||
jr z, .dmg
|
||||
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
jr CopyTilemapAtOnce
|
||||
|
||||
.dmg
|
||||
; WaitBGMap
|
||||
ld a, 1
|
||||
ldh [hBGMapMode], a
|
||||
ld c, 4
|
||||
jp DelayFrames
|
||||
|
||||
CGBOnly_CopyTilemapAtOnce::
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr z, WaitBGMap
|
||||
|
||||
CopyTilemapAtOnce::
|
||||
ldh a, [hBGMapMode]
|
||||
push af
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
|
||||
ldh a, [hMapAnims]
|
||||
push af
|
||||
xor a
|
||||
ldh [hMapAnims], a
|
||||
|
||||
.wait
|
||||
ldh a, [rLY]
|
||||
cp $80 - 1
|
||||
jr c, .wait
|
||||
|
||||
di
|
||||
ld a, BANK(vBGMap2)
|
||||
ldh [rVBK], a
|
||||
hlcoord 0, 0, wAttrmap
|
||||
call .CopyBGMapViaStack
|
||||
ld a, BANK(vBGMap0)
|
||||
ldh [rVBK], a
|
||||
hlcoord 0, 0
|
||||
call .CopyBGMapViaStack
|
||||
|
||||
.wait2
|
||||
ldh a, [rLY]
|
||||
cp $80 - 1
|
||||
jr c, .wait2
|
||||
ei
|
||||
|
||||
pop af
|
||||
ldh [hMapAnims], a
|
||||
pop af
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
.CopyBGMapViaStack:
|
||||
; Copy all tiles to vBGMap
|
||||
ld [hSPBuffer], sp
|
||||
ld sp, hl
|
||||
ldh a, [hBGMapAddress + 1]
|
||||
ld h, a
|
||||
ld l, 0
|
||||
ld a, SCREEN_HEIGHT
|
||||
ldh [hTilesPerCycle], a
|
||||
ld b, 1 << 1 ; not in v/hblank
|
||||
ld c, LOW(rSTAT)
|
||||
|
||||
.loop
|
||||
rept SCREEN_WIDTH / 2
|
||||
pop de
|
||||
; if in v/hblank, wait until not in v/hblank
|
||||
.loop\@
|
||||
ldh a, [c]
|
||||
and b
|
||||
jr nz, .loop\@
|
||||
; load vBGMap
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], d
|
||||
inc l
|
||||
endr
|
||||
|
||||
ld de, BG_MAP_WIDTH - SCREEN_WIDTH
|
||||
add hl, de
|
||||
ldh a, [hTilesPerCycle]
|
||||
dec a
|
||||
ldh [hTilesPerCycle], a
|
||||
jr nz, .loop
|
||||
|
||||
ldh a, [hSPBuffer]
|
||||
ld l, a
|
||||
ldh a, [hSPBuffer + 1]
|
||||
ld h, a
|
||||
ld sp, hl
|
||||
ret
|
||||
|
||||
SetPalettes::
|
||||
; Inits the Palettes
|
||||
; depending on the system the monochromes palettes or color palettes
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr nz, .SetPalettesForGameBoyColor
|
||||
ld a, %11100100
|
||||
ldh [rBGP], a
|
||||
ld a, %11010000
|
||||
ldh [rOBP0], a
|
||||
ldh [rOBP1], a
|
||||
ret
|
||||
|
||||
.SetPalettesForGameBoyColor:
|
||||
push de
|
||||
ld a, %11100100
|
||||
call DmgToCgbBGPals
|
||||
lb de, %11100100, %11100100
|
||||
call DmgToCgbObjPals
|
||||
pop de
|
||||
ret
|
||||
|
||||
ClearPalettes::
|
||||
; Make all palettes white
|
||||
|
||||
; CGB: make all the palette colors white
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr nz, .cgb
|
||||
|
||||
; DMG: just change palettes to 0 (white)
|
||||
xor a
|
||||
ldh [rBGP], a
|
||||
ldh [rOBP0], a
|
||||
ldh [rOBP1], a
|
||||
ret
|
||||
|
||||
.cgb
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
|
||||
ld a, BANK(wBGPals2)
|
||||
ldh [rSVBK], a
|
||||
|
||||
; Fill wBGPals2 and wOBPals2 with $ffff (white)
|
||||
ld hl, wBGPals2
|
||||
ld bc, 16 palettes
|
||||
ld a, $ff
|
||||
call ByteFill
|
||||
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
|
||||
; Request palette update
|
||||
ld a, TRUE
|
||||
ldh [hCGBPalUpdate], a
|
||||
ret
|
||||
|
||||
GetMemSGBLayout::
|
||||
ld b, SCGB_DEFAULT
|
||||
GetSGBLayout::
|
||||
; load sgb packets unless dmg
|
||||
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jr nz, .sgb
|
||||
|
||||
ldh a, [hSGB]
|
||||
and a
|
||||
ret z
|
||||
|
||||
.sgb
|
||||
predef_jump LoadSGBLayout
|
||||
|
||||
SetHPPal::
|
||||
; Set palette for hp bar pixel length e at hl.
|
||||
call GetHPPal
|
||||
ld [hl], d
|
||||
ret
|
||||
|
||||
GetHPPal::
|
||||
; Get palette for hp bar pixel length e in d.
|
||||
ld d, HP_GREEN
|
||||
ld a, e
|
||||
cp (HP_BAR_LENGTH_PX * 50 / 100) ; 24
|
||||
ret nc
|
||||
inc d ; HP_YELLOW
|
||||
cp (HP_BAR_LENGTH_PX * 21 / 100) ; 10
|
||||
ret nc
|
||||
inc d ; HP_RED
|
||||
ret
|
||||
271
home/time.asm
Normal file
271
home/time.asm
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
; Functions relating to the timer interrupt and the real-time-clock.
|
||||
|
||||
Timer:: ; unreferenced
|
||||
push af
|
||||
ldh a, [hMobile]
|
||||
and a
|
||||
jr z, .not_mobile
|
||||
call MobileTimer
|
||||
|
||||
.not_mobile
|
||||
pop af
|
||||
reti
|
||||
|
||||
LatchClock::
|
||||
; latch clock counter data
|
||||
ld a, 0
|
||||
ld [MBC3LatchClock], a
|
||||
ld a, 1
|
||||
ld [MBC3LatchClock], a
|
||||
ret
|
||||
|
||||
UpdateTime::
|
||||
call GetClock
|
||||
call FixDays
|
||||
call FixTime
|
||||
farcall GetTimeOfDay
|
||||
ret
|
||||
|
||||
GetClock::
|
||||
; store clock data in hRTCDayHi-hRTCSeconds
|
||||
|
||||
; enable clock r/w
|
||||
ld a, SRAM_ENABLE
|
||||
ld [MBC3SRamEnable], a
|
||||
|
||||
; clock data is 'backwards' in hram
|
||||
|
||||
call LatchClock
|
||||
ld hl, MBC3SRamBank
|
||||
ld de, MBC3RTC
|
||||
|
||||
ld [hl], RTC_S
|
||||
ld a, [de]
|
||||
maskbits 60
|
||||
ldh [hRTCSeconds], a
|
||||
|
||||
ld [hl], RTC_M
|
||||
ld a, [de]
|
||||
maskbits 60
|
||||
ldh [hRTCMinutes], a
|
||||
|
||||
ld [hl], RTC_H
|
||||
ld a, [de]
|
||||
maskbits 24
|
||||
ldh [hRTCHours], a
|
||||
|
||||
ld [hl], RTC_DL
|
||||
ld a, [de]
|
||||
ldh [hRTCDayLo], a
|
||||
|
||||
ld [hl], RTC_DH
|
||||
ld a, [de]
|
||||
ldh [hRTCDayHi], a
|
||||
|
||||
; unlatch clock / disable clock r/w
|
||||
jp CloseSRAM
|
||||
|
||||
FixDays::
|
||||
; fix day count
|
||||
; mod by 140
|
||||
|
||||
; check if day count > 255 (bit 8 set)
|
||||
ldh a, [hRTCDayHi] ; DH
|
||||
bit 0, a
|
||||
jr z, .daylo
|
||||
; reset dh (bit 8)
|
||||
res 0, a
|
||||
ldh [hRTCDayHi], a
|
||||
|
||||
; mod 140
|
||||
; mod twice since bit 8 (DH) was set
|
||||
ldh a, [hRTCDayLo]
|
||||
.modh
|
||||
sub 140
|
||||
jr nc, .modh
|
||||
.modl
|
||||
sub 140
|
||||
jr nc, .modl
|
||||
add 140
|
||||
|
||||
; update dl
|
||||
ldh [hRTCDayLo], a
|
||||
|
||||
; flag for sRTCStatusFlags
|
||||
ld a, %01000000
|
||||
jr .set
|
||||
|
||||
.daylo
|
||||
; quit if fewer than 140 days have passed
|
||||
ldh a, [hRTCDayLo]
|
||||
cp 140
|
||||
jr c, .quit
|
||||
|
||||
; mod 140
|
||||
.mod
|
||||
sub 140
|
||||
jr nc, .mod
|
||||
add 140
|
||||
|
||||
; update dl
|
||||
ldh [hRTCDayLo], a
|
||||
|
||||
; flag for sRTCStatusFlags
|
||||
ld a, %00100000
|
||||
|
||||
.set
|
||||
; update clock with modded day value
|
||||
push af
|
||||
call SetClock
|
||||
pop af
|
||||
scf
|
||||
ret
|
||||
|
||||
.quit
|
||||
xor a
|
||||
ret
|
||||
|
||||
FixTime::
|
||||
; add ingame time (set at newgame) to current time
|
||||
; store time in wCurDay, hHours, hMinutes, hSeconds
|
||||
|
||||
; second
|
||||
ldh a, [hRTCSeconds]
|
||||
ld c, a
|
||||
ld a, [wStartSecond]
|
||||
add c
|
||||
sub 60
|
||||
jr nc, .updatesec
|
||||
add 60
|
||||
.updatesec
|
||||
ldh [hSeconds], a
|
||||
|
||||
; minute
|
||||
ccf ; carry is set, so turn it off
|
||||
ldh a, [hRTCMinutes]
|
||||
ld c, a
|
||||
ld a, [wStartMinute]
|
||||
adc c
|
||||
sub 60
|
||||
jr nc, .updatemin
|
||||
add 60
|
||||
.updatemin
|
||||
ldh [hMinutes], a
|
||||
|
||||
; hour
|
||||
ccf ; carry is set, so turn it off
|
||||
ldh a, [hRTCHours]
|
||||
ld c, a
|
||||
ld a, [wStartHour]
|
||||
adc c
|
||||
sub 24
|
||||
jr nc, .updatehr
|
||||
add 24
|
||||
.updatehr
|
||||
ldh [hHours], a
|
||||
|
||||
; day
|
||||
ccf ; carry is set, so turn it off
|
||||
ldh a, [hRTCDayLo]
|
||||
ld c, a
|
||||
ld a, [wStartDay]
|
||||
adc c
|
||||
ld [wCurDay], a
|
||||
ret
|
||||
|
||||
InitTimeOfDay::
|
||||
xor a
|
||||
ld [wStringBuffer2], a
|
||||
ld a, 0 ; useless
|
||||
ld [wStringBuffer2 + 3], a
|
||||
jr InitTime
|
||||
|
||||
InitDayOfWeek::
|
||||
call UpdateTime
|
||||
ldh a, [hHours]
|
||||
ld [wStringBuffer2 + 1], a
|
||||
ldh a, [hMinutes]
|
||||
ld [wStringBuffer2 + 2], a
|
||||
ldh a, [hSeconds]
|
||||
ld [wStringBuffer2 + 3], a
|
||||
jr InitTime ; useless
|
||||
|
||||
InitTime::
|
||||
farcall _InitTime
|
||||
ret
|
||||
|
||||
ClearClock::
|
||||
xor a
|
||||
ldh [hRTCSeconds], a
|
||||
ldh [hRTCMinutes], a
|
||||
ldh [hRTCHours], a
|
||||
ldh [hRTCDayLo], a
|
||||
ldh [hRTCDayHi], a
|
||||
; fallthrough
|
||||
|
||||
SetClock::
|
||||
; set clock data from hram
|
||||
|
||||
; enable clock r/w
|
||||
ld a, SRAM_ENABLE
|
||||
ld [MBC3SRamEnable], a
|
||||
|
||||
; set clock data
|
||||
; stored 'backwards' in hram
|
||||
|
||||
call LatchClock
|
||||
ld hl, MBC3SRamBank
|
||||
ld de, MBC3RTC
|
||||
|
||||
; seconds
|
||||
ld [hl], RTC_S
|
||||
ldh a, [hRTCSeconds]
|
||||
ld [de], a
|
||||
; minutes
|
||||
ld [hl], RTC_M
|
||||
ldh a, [hRTCMinutes]
|
||||
ld [de], a
|
||||
; hours
|
||||
ld [hl], RTC_H
|
||||
ldh a, [hRTCHours]
|
||||
ld [de], a
|
||||
; day lo
|
||||
ld [hl], RTC_DL
|
||||
ldh a, [hRTCDayLo]
|
||||
ld [de], a
|
||||
; day hi
|
||||
ld [hl], RTC_DH
|
||||
ldh a, [hRTCDayHi]
|
||||
res 6, a ; make sure timer is active
|
||||
ld [de], a
|
||||
|
||||
; cleanup
|
||||
jp CloseSRAM ; unlatch clock, disable clock r/w
|
||||
|
||||
ClearRTCStatus:: ; unreferenced
|
||||
; clear sRTCStatusFlags
|
||||
xor a
|
||||
push af
|
||||
ld a, BANK(sRTCStatusFlags)
|
||||
call OpenSRAM
|
||||
pop af
|
||||
ld [sRTCStatusFlags], a
|
||||
jp CloseSRAM
|
||||
|
||||
RecordRTCStatus::
|
||||
; append flags to sRTCStatusFlags
|
||||
ld hl, sRTCStatusFlags
|
||||
push af
|
||||
ld a, BANK(sRTCStatusFlags)
|
||||
call OpenSRAM
|
||||
pop af
|
||||
or [hl]
|
||||
ld [hl], a
|
||||
jp CloseSRAM
|
||||
|
||||
CheckRTCStatus::
|
||||
; check sRTCStatusFlags
|
||||
ld a, BANK(sRTCStatusFlags)
|
||||
call OpenSRAM
|
||||
ld a, [sRTCStatusFlags]
|
||||
jp CloseSRAM
|
||||
22
home/time_palettes.asm
Normal file
22
home/time_palettes.asm
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
UpdateTimeAndPals::
|
||||
; update time and time-sensitive palettes
|
||||
|
||||
; rtc enabled?
|
||||
ld a, [wSpriteUpdatesEnabled]
|
||||
cp 0
|
||||
ret z
|
||||
|
||||
call UpdateTime
|
||||
|
||||
; obj update on?
|
||||
ld a, [wVramState]
|
||||
bit 0, a ; obj update
|
||||
ret z
|
||||
|
||||
TimeOfDayPals::
|
||||
callfar _TimeOfDayPals
|
||||
ret
|
||||
|
||||
UpdateTimePals::
|
||||
callfar _UpdateTimePals
|
||||
ret
|
||||
244
home/trainers.asm
Normal file
244
home/trainers.asm
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
CheckTrainerBattle::
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
|
||||
call SwitchToMapScriptsBank
|
||||
call _CheckTrainerBattle
|
||||
|
||||
pop bc
|
||||
ld a, b
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
_CheckTrainerBattle::
|
||||
; Check if any trainer on the map sees the player and wants to battle.
|
||||
|
||||
; Skip the player object.
|
||||
ld a, 1
|
||||
ld de, wMap1Object
|
||||
|
||||
.loop
|
||||
|
||||
; Start a battle if the object:
|
||||
push af
|
||||
push de
|
||||
|
||||
; Has a sprite
|
||||
ld hl, MAPOBJECT_SPRITE
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
and a
|
||||
jr z, .next
|
||||
|
||||
; Is a trainer
|
||||
ld hl, MAPOBJECT_TYPE
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
and MAPOBJECT_TYPE_MASK
|
||||
cp OBJECTTYPE_TRAINER
|
||||
jr nz, .next
|
||||
|
||||
; Is visible on the map
|
||||
ld hl, MAPOBJECT_OBJECT_STRUCT_ID
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
cp -1
|
||||
jr z, .next
|
||||
|
||||
; Is facing the player...
|
||||
call GetObjectStruct
|
||||
call FacingPlayerDistance_bc
|
||||
jr nc, .next
|
||||
|
||||
; ...within their sight range
|
||||
ld hl, MAPOBJECT_SIGHT_RANGE
|
||||
add hl, de
|
||||
ld a, [hl]
|
||||
cp b
|
||||
jr c, .next
|
||||
|
||||
; And hasn't already been beaten
|
||||
push bc
|
||||
push de
|
||||
ld hl, MAPOBJECT_SCRIPT_POINTER
|
||||
add hl, de
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld e, [hl]
|
||||
inc hl
|
||||
ld d, [hl]
|
||||
ld b, CHECK_FLAG
|
||||
call EventFlagAction
|
||||
ld a, c
|
||||
pop de
|
||||
pop bc
|
||||
and a
|
||||
jr z, .startbattle
|
||||
|
||||
.next
|
||||
pop de
|
||||
ld hl, MAPOBJECT_LENGTH
|
||||
add hl, de
|
||||
ld d, h
|
||||
ld e, l
|
||||
|
||||
pop af
|
||||
inc a
|
||||
cp NUM_OBJECTS
|
||||
jr nz, .loop
|
||||
xor a
|
||||
ret
|
||||
|
||||
.startbattle
|
||||
pop de
|
||||
pop af
|
||||
ldh [hLastTalked], a
|
||||
ld a, b
|
||||
ld [wSeenTrainerDistance], a
|
||||
ld a, c
|
||||
ld [wSeenTrainerDirection], a
|
||||
jr LoadTrainer_continue
|
||||
|
||||
TalkToTrainer::
|
||||
ld a, 1
|
||||
ld [wSeenTrainerDistance], a
|
||||
ld a, -1
|
||||
ld [wSeenTrainerDirection], a
|
||||
|
||||
LoadTrainer_continue::
|
||||
call GetMapScriptsBank
|
||||
ld [wSeenTrainerBank], a
|
||||
|
||||
ldh a, [hLastTalked]
|
||||
call GetMapObject
|
||||
|
||||
ld hl, MAPOBJECT_SCRIPT_POINTER
|
||||
add hl, bc
|
||||
ld a, [wSeenTrainerBank]
|
||||
call GetFarWord
|
||||
ld de, wTempTrainer
|
||||
ld bc, wTempTrainerEnd - wTempTrainer
|
||||
ld a, [wSeenTrainerBank]
|
||||
call FarCopyBytes
|
||||
xor a
|
||||
ld [wRunningTrainerBattleScript], a
|
||||
scf
|
||||
ret
|
||||
|
||||
FacingPlayerDistance_bc::
|
||||
push de
|
||||
call FacingPlayerDistance
|
||||
ld b, d
|
||||
ld c, e
|
||||
pop de
|
||||
ret
|
||||
|
||||
FacingPlayerDistance::
|
||||
; Return carry if the sprite at bc is facing the player,
|
||||
; its distance in d, and its direction in e.
|
||||
|
||||
ld hl, OBJECT_MAP_X ; x
|
||||
add hl, bc
|
||||
ld d, [hl]
|
||||
|
||||
ld hl, OBJECT_MAP_Y ; y
|
||||
add hl, bc
|
||||
ld e, [hl]
|
||||
|
||||
ld a, [wPlayerMapX]
|
||||
cp d
|
||||
jr z, .CheckY
|
||||
|
||||
ld a, [wPlayerMapY]
|
||||
cp e
|
||||
jr z, .CheckX
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
.CheckY:
|
||||
ld a, [wPlayerMapY]
|
||||
sub e
|
||||
jr z, .NotFacing
|
||||
jr nc, .Above
|
||||
|
||||
; Below
|
||||
cpl
|
||||
inc a
|
||||
ld d, a
|
||||
ld e, OW_UP
|
||||
jr .CheckFacing
|
||||
|
||||
.Above:
|
||||
ld d, a
|
||||
ld e, OW_DOWN
|
||||
jr .CheckFacing
|
||||
|
||||
.CheckX:
|
||||
ld a, [wPlayerMapX]
|
||||
sub d
|
||||
jr z, .NotFacing
|
||||
jr nc, .Left
|
||||
|
||||
; Right
|
||||
cpl
|
||||
inc a
|
||||
ld d, a
|
||||
ld e, OW_LEFT
|
||||
jr .CheckFacing
|
||||
|
||||
.Left:
|
||||
ld d, a
|
||||
ld e, OW_RIGHT
|
||||
|
||||
.CheckFacing:
|
||||
call GetSpriteDirection
|
||||
cp e
|
||||
jr nz, .NotFacing
|
||||
scf
|
||||
ret
|
||||
|
||||
.NotFacing:
|
||||
and a
|
||||
ret
|
||||
|
||||
CheckTrainerFlag:: ; unreferenced
|
||||
push bc
|
||||
ld hl, OBJECT_MAP_OBJECT_INDEX
|
||||
add hl, bc
|
||||
ld a, [hl]
|
||||
call GetMapObject
|
||||
ld hl, MAPOBJECT_SCRIPT_POINTER
|
||||
add hl, bc
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
call GetMapScriptsBank
|
||||
call GetFarWord
|
||||
ld d, h
|
||||
ld e, l
|
||||
push de
|
||||
ld b, CHECK_FLAG
|
||||
call EventFlagAction
|
||||
pop de
|
||||
ld a, c
|
||||
and a
|
||||
pop bc
|
||||
ret
|
||||
|
||||
PrintWinLossText::
|
||||
ld a, [wBattleResult]
|
||||
ld hl, wWinTextPointer
|
||||
and $f ; WIN?
|
||||
jr z, .ok
|
||||
ld hl, wLossTextPointer
|
||||
|
||||
.ok
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
call GetMapScriptsBank
|
||||
call FarPrintText
|
||||
call WaitBGMap
|
||||
jp WaitPressAorB_BlinkCursor
|
||||
421
home/vblank.asm
Normal file
421
home/vblank.asm
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
; VBlank is the interrupt responsible for updating VRAM.
|
||||
|
||||
; In Pokemon Crystal, VBlank has been hijacked to act as the
|
||||
; main loop. After time-sensitive graphics operations have been
|
||||
; performed, joypad input and sound functions are executed.
|
||||
|
||||
; This prevents the display and audio output from lagging.
|
||||
|
||||
VBlank::
|
||||
push af
|
||||
push bc
|
||||
push de
|
||||
push hl
|
||||
|
||||
ldh a, [hVBlank]
|
||||
and 7
|
||||
|
||||
ld e, a
|
||||
ld d, 0
|
||||
ld hl, .VBlanks
|
||||
add hl, de
|
||||
add hl, de
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
call _hl_
|
||||
|
||||
call GameTimer
|
||||
|
||||
pop hl
|
||||
pop de
|
||||
pop bc
|
||||
pop af
|
||||
reti
|
||||
|
||||
.VBlanks:
|
||||
dw VBlank0
|
||||
dw VBlank1
|
||||
dw VBlank2
|
||||
dw VBlank3
|
||||
dw VBlank4
|
||||
dw VBlank5
|
||||
dw VBlank6
|
||||
dw VBlank0 ; just in case
|
||||
|
||||
VBlank0::
|
||||
; normal operation
|
||||
|
||||
; rng
|
||||
; scx, scy, wy, wx
|
||||
; bg map buffer
|
||||
; palettes
|
||||
; dma transfer
|
||||
; bg map
|
||||
; tiles
|
||||
; oam
|
||||
; joypad
|
||||
; sound
|
||||
|
||||
; inc frame counter
|
||||
ld hl, hVBlankCounter
|
||||
inc [hl]
|
||||
|
||||
; advance random variables
|
||||
ldh a, [rDIV]
|
||||
ld b, a
|
||||
ldh a, [hRandomAdd]
|
||||
adc b
|
||||
ldh [hRandomAdd], a
|
||||
|
||||
ldh a, [rDIV]
|
||||
ld b, a
|
||||
ldh a, [hRandomSub]
|
||||
sbc b
|
||||
ldh [hRandomSub], a
|
||||
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
ldh a, [hSCX]
|
||||
ldh [rSCX], a
|
||||
ldh a, [hSCY]
|
||||
ldh [rSCY], a
|
||||
ldh a, [hWY]
|
||||
ldh [rWY], a
|
||||
ldh a, [hWX]
|
||||
ldh [rWX], a
|
||||
|
||||
; There's only time to call one of these in one vblank.
|
||||
; Calls are in order of priority.
|
||||
|
||||
call UpdateBGMapBuffer
|
||||
jr c, .done
|
||||
call UpdatePalsIfCGB
|
||||
jr c, .done
|
||||
call DMATransfer
|
||||
jr c, .done
|
||||
call UpdateBGMap
|
||||
|
||||
; These have their own timing checks.
|
||||
|
||||
call Serve2bppRequest
|
||||
call Serve1bppRequest
|
||||
call AnimateTileset
|
||||
|
||||
.done
|
||||
|
||||
ldh a, [hOAMUpdate]
|
||||
and a
|
||||
jr nz, .done_oam
|
||||
call hTransferShadowOAM
|
||||
.done_oam
|
||||
|
||||
; vblank-sensitive operations are done
|
||||
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
ld a, [wOverworldDelay]
|
||||
and a
|
||||
jr z, .ok
|
||||
dec a
|
||||
ld [wOverworldDelay], a
|
||||
.ok
|
||||
|
||||
ld a, [wTextDelayFrames]
|
||||
and a
|
||||
jr z, .ok2
|
||||
dec a
|
||||
ld [wTextDelayFrames], a
|
||||
.ok2
|
||||
|
||||
call UpdateJoypad
|
||||
|
||||
ld a, BANK(_UpdateSound)
|
||||
rst Bankswitch
|
||||
call _UpdateSound
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
|
||||
ldh a, [hSeconds]
|
||||
ldh [hUnusedBackup], a
|
||||
|
||||
ret
|
||||
|
||||
VBlank2::
|
||||
; sound only
|
||||
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
ld a, BANK(_UpdateSound)
|
||||
rst Bankswitch
|
||||
call _UpdateSound
|
||||
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
ret
|
||||
|
||||
VBlank1::
|
||||
; scx, scy
|
||||
; palettes
|
||||
; bg map
|
||||
; tiles
|
||||
; oam
|
||||
; sound / lcd stat
|
||||
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
ldh a, [hSCX]
|
||||
ldh [rSCX], a
|
||||
ldh a, [hSCY]
|
||||
ldh [rSCY], a
|
||||
|
||||
call UpdatePals
|
||||
jr c, .done
|
||||
|
||||
call UpdateBGMap
|
||||
call Serve2bppRequest_VBlank
|
||||
|
||||
call hTransferShadowOAM
|
||||
|
||||
.done
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
; get requested ints
|
||||
ldh a, [rIF]
|
||||
ld b, a
|
||||
; discard requested ints
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
; enable lcd stat
|
||||
ld a, 1 << LCD_STAT
|
||||
ldh [rIE], a
|
||||
; rerequest serial int if applicable (still disabled)
|
||||
; request lcd stat
|
||||
ld a, b
|
||||
and 1 << SERIAL
|
||||
or 1 << LCD_STAT
|
||||
ldh [rIF], a
|
||||
|
||||
ei
|
||||
ld a, BANK(_UpdateSound)
|
||||
rst Bankswitch
|
||||
call _UpdateSound
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
di
|
||||
|
||||
; get requested ints
|
||||
ldh a, [rIF]
|
||||
ld b, a
|
||||
; discard requested ints
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
; enable ints besides joypad
|
||||
ld a, IE_DEFAULT
|
||||
ldh [rIE], a
|
||||
; rerequest ints
|
||||
ld a, b
|
||||
ldh [rIF], a
|
||||
ret
|
||||
|
||||
UpdatePals::
|
||||
; update pals for either dmg or cgb
|
||||
|
||||
ldh a, [hCGB]
|
||||
and a
|
||||
jp nz, UpdateCGBPals
|
||||
|
||||
; update gb pals
|
||||
ld a, [wBGP]
|
||||
ldh [rBGP], a
|
||||
ld a, [wOBP0]
|
||||
ldh [rOBP0], a
|
||||
ld a, [wOBP1]
|
||||
ldh [rOBP1], a
|
||||
|
||||
and a
|
||||
ret
|
||||
|
||||
VBlank3::
|
||||
; scx, scy
|
||||
; palettes
|
||||
; bg map
|
||||
; tiles
|
||||
; oam
|
||||
; sound / lcd stat
|
||||
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
ldh a, [hSCX]
|
||||
ldh [rSCX], a
|
||||
ldh a, [hSCY]
|
||||
ldh [rSCY], a
|
||||
|
||||
ldh a, [hCGBPalUpdate]
|
||||
and a
|
||||
call nz, ForceUpdateCGBPals
|
||||
jr c, .done
|
||||
|
||||
call UpdateBGMap
|
||||
call Serve2bppRequest_VBlank
|
||||
|
||||
call hTransferShadowOAM
|
||||
.done
|
||||
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
ldh a, [rIF]
|
||||
push af
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ld a, 1 << LCD_STAT
|
||||
ldh [rIE], a
|
||||
ldh [rIF], a
|
||||
|
||||
ei
|
||||
ld a, BANK(_UpdateSound)
|
||||
rst Bankswitch
|
||||
call _UpdateSound
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
di
|
||||
|
||||
; request lcdstat
|
||||
ldh a, [rIF]
|
||||
ld b, a
|
||||
; and any other ints
|
||||
pop af
|
||||
or b
|
||||
ld b, a
|
||||
; reset ints
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
; enable ints besides joypad
|
||||
ld a, IE_DEFAULT
|
||||
ldh [rIE], a
|
||||
; request ints
|
||||
ld a, b
|
||||
ldh [rIF], a
|
||||
ret
|
||||
|
||||
VBlank4::
|
||||
; bg map
|
||||
; tiles
|
||||
; oam
|
||||
; joypad
|
||||
; serial
|
||||
; sound
|
||||
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
call UpdateBGMap
|
||||
call Serve2bppRequest
|
||||
|
||||
call hTransferShadowOAM
|
||||
|
||||
call UpdateJoypad
|
||||
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
call AskSerial
|
||||
|
||||
ld a, BANK(_UpdateSound)
|
||||
rst Bankswitch
|
||||
call _UpdateSound
|
||||
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
VBlank5::
|
||||
; scx
|
||||
; palettes
|
||||
; bg map
|
||||
; tiles
|
||||
; joypad
|
||||
;
|
||||
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
ldh a, [hSCX]
|
||||
ldh [rSCX], a
|
||||
|
||||
call UpdatePalsIfCGB
|
||||
jr c, .done
|
||||
|
||||
call UpdateBGMap
|
||||
call Serve2bppRequest
|
||||
.done
|
||||
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
call UpdateJoypad
|
||||
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
ld a, 1 << LCD_STAT
|
||||
ldh [rIE], a
|
||||
; request lcd stat
|
||||
ldh [rIF], a
|
||||
|
||||
ei
|
||||
ld a, BANK(_UpdateSound)
|
||||
rst Bankswitch
|
||||
call _UpdateSound
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
di
|
||||
|
||||
xor a
|
||||
ldh [rIF], a
|
||||
; enable ints besides joypad
|
||||
ld a, IE_DEFAULT
|
||||
ldh [rIE], a
|
||||
ret
|
||||
|
||||
VBlank6::
|
||||
; palettes
|
||||
; tiles
|
||||
; dma transfer
|
||||
; sound
|
||||
|
||||
ldh a, [hROMBank]
|
||||
ldh [hROMBankBackup], a
|
||||
|
||||
; inc frame counter
|
||||
ld hl, hVBlankCounter
|
||||
inc [hl]
|
||||
|
||||
call UpdateCGBPals
|
||||
jr c, .done
|
||||
|
||||
call Serve2bppRequest
|
||||
call Serve1bppRequest
|
||||
call DMATransfer
|
||||
.done
|
||||
|
||||
xor a
|
||||
ld [wVBlankOccurred], a
|
||||
|
||||
ld a, BANK(_UpdateSound)
|
||||
rst Bankswitch
|
||||
call _UpdateSound
|
||||
|
||||
ldh a, [hROMBankBackup]
|
||||
rst Bankswitch
|
||||
ret
|
||||
459
home/video.asm
Normal file
459
home/video.asm
Normal file
|
|
@ -0,0 +1,459 @@
|
|||
; Functions dealing with VRAM.
|
||||
|
||||
DMATransfer::
|
||||
; Return carry if the transfer is completed.
|
||||
|
||||
ldh a, [hDMATransfer]
|
||||
and a
|
||||
ret z
|
||||
|
||||
; Start transfer
|
||||
ldh [rHDMA5], a
|
||||
|
||||
; Execution is halted until the transfer is complete.
|
||||
|
||||
xor a
|
||||
ldh [hDMATransfer], a
|
||||
scf
|
||||
ret
|
||||
|
||||
UpdateBGMapBuffer::
|
||||
; Copy [hBGMapTileCount] 16x8 tiles from wBGMapBuffer
|
||||
; to bg map addresses in wBGMapBufferPointers.
|
||||
|
||||
; [hBGMapTileCount] must be even since this is done in pairs.
|
||||
|
||||
; Return carry on success.
|
||||
|
||||
ldh a, [hBGMapUpdate]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ldh a, [rVBK]
|
||||
push af
|
||||
|
||||
; Relocate the stack pointer to wBGMapBufferPointers
|
||||
ld [hSPBuffer], sp
|
||||
ld hl, wBGMapBufferPointers
|
||||
ld sp, hl
|
||||
|
||||
; We can now pop the addresses of affected spots on the BG Map
|
||||
|
||||
ld hl, wBGMapPalBuffer
|
||||
ld de, wBGMapBuffer
|
||||
|
||||
.next
|
||||
; Copy a pair of 16x8 blocks (one 16x16 block)
|
||||
|
||||
rept 2
|
||||
; Get our BG Map address
|
||||
pop bc
|
||||
|
||||
; Palettes
|
||||
ld a, 1
|
||||
ldh [rVBK], a
|
||||
|
||||
ld a, [hli]
|
||||
ld [bc], a
|
||||
inc c
|
||||
ld a, [hli]
|
||||
ld [bc], a
|
||||
dec c
|
||||
|
||||
; Tiles
|
||||
xor a
|
||||
ldh [rVBK], a
|
||||
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld [bc], a
|
||||
inc c
|
||||
ld a, [de]
|
||||
inc de
|
||||
ld [bc], a
|
||||
endr
|
||||
|
||||
; We've done 2 16x8 blocks
|
||||
ldh a, [hBGMapTileCount]
|
||||
dec a
|
||||
dec a
|
||||
ldh [hBGMapTileCount], a
|
||||
|
||||
jr nz, .next
|
||||
|
||||
; Restore the stack pointer
|
||||
ldh a, [hSPBuffer]
|
||||
ld l, a
|
||||
ldh a, [hSPBuffer + 1]
|
||||
ld h, a
|
||||
ld sp, hl
|
||||
|
||||
pop af
|
||||
ldh [rVBK], a
|
||||
|
||||
xor a
|
||||
ldh [hBGMapUpdate], a
|
||||
scf
|
||||
ret
|
||||
|
||||
WaitTop::
|
||||
; Wait until the top third of the BG Map is being updated.
|
||||
|
||||
ldh a, [hBGMapMode]
|
||||
and a
|
||||
ret z
|
||||
|
||||
ldh a, [hBGMapThird]
|
||||
and a
|
||||
jr z, .done
|
||||
|
||||
call DelayFrame
|
||||
jr WaitTop
|
||||
|
||||
.done
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ret
|
||||
|
||||
UpdateBGMap::
|
||||
; Update the BG Map, in thirds, from wTilemap and wAttrmap.
|
||||
|
||||
ldh a, [hBGMapMode]
|
||||
and a ; 0
|
||||
ret z
|
||||
|
||||
; BG Map 0
|
||||
dec a ; 1
|
||||
jr z, .Tiles
|
||||
dec a ; 2
|
||||
jr z, .Attr
|
||||
|
||||
; BG Map 1
|
||||
dec a ; useless
|
||||
|
||||
ldh a, [hBGMapAddress]
|
||||
ld l, a
|
||||
ldh a, [hBGMapAddress + 1]
|
||||
ld h, a
|
||||
push hl
|
||||
|
||||
xor a ; LOW(vBGMap1)
|
||||
ldh [hBGMapAddress], a
|
||||
ld a, HIGH(vBGMap1)
|
||||
ldh [hBGMapAddress + 1], a
|
||||
|
||||
ldh a, [hBGMapMode]
|
||||
push af
|
||||
cp 3
|
||||
call z, .Tiles
|
||||
pop af
|
||||
cp 4
|
||||
call z, .Attr
|
||||
|
||||
pop hl
|
||||
ld a, l
|
||||
ldh [hBGMapAddress], a
|
||||
ld a, h
|
||||
ldh [hBGMapAddress + 1], a
|
||||
ret
|
||||
|
||||
.Attr:
|
||||
ld a, 1
|
||||
ldh [rVBK], a
|
||||
|
||||
hlcoord 0, 0, wAttrmap
|
||||
call .update
|
||||
|
||||
xor a
|
||||
ldh [rVBK], a
|
||||
ret
|
||||
|
||||
.Tiles:
|
||||
hlcoord 0, 0
|
||||
|
||||
.update
|
||||
ld [hSPBuffer], sp
|
||||
|
||||
; Which third?
|
||||
ldh a, [hBGMapThird]
|
||||
and a ; 0
|
||||
jr z, .top
|
||||
dec a ; 1
|
||||
jr z, .middle
|
||||
; 2
|
||||
|
||||
DEF THIRD_HEIGHT EQU SCREEN_HEIGHT / 3
|
||||
|
||||
; bottom
|
||||
ld de, 2 * THIRD_HEIGHT * SCREEN_WIDTH
|
||||
add hl, de
|
||||
ld sp, hl
|
||||
|
||||
ldh a, [hBGMapAddress + 1]
|
||||
ld h, a
|
||||
ldh a, [hBGMapAddress]
|
||||
ld l, a
|
||||
|
||||
ld de, 2 * THIRD_HEIGHT * BG_MAP_WIDTH
|
||||
add hl, de
|
||||
|
||||
; Next time: top third
|
||||
xor a
|
||||
jr .start
|
||||
|
||||
.middle
|
||||
ld de, THIRD_HEIGHT * SCREEN_WIDTH
|
||||
add hl, de
|
||||
ld sp, hl
|
||||
|
||||
ldh a, [hBGMapAddress + 1]
|
||||
ld h, a
|
||||
ldh a, [hBGMapAddress]
|
||||
ld l, a
|
||||
|
||||
ld de, THIRD_HEIGHT * BG_MAP_WIDTH
|
||||
add hl, de
|
||||
|
||||
; Next time: bottom third
|
||||
ld a, 2
|
||||
jr .start
|
||||
|
||||
.top
|
||||
ld sp, hl
|
||||
|
||||
ldh a, [hBGMapAddress + 1]
|
||||
ld h, a
|
||||
ldh a, [hBGMapAddress]
|
||||
ld l, a
|
||||
|
||||
; Next time: middle third
|
||||
ld a, 1
|
||||
|
||||
.start
|
||||
; Which third to update next time
|
||||
ldh [hBGMapThird], a
|
||||
|
||||
; Rows of tiles in a third
|
||||
ld a, THIRD_HEIGHT
|
||||
|
||||
; Discrepancy between wTilemap and BGMap
|
||||
ld bc, BG_MAP_WIDTH - (SCREEN_WIDTH - 1)
|
||||
|
||||
.row
|
||||
; Copy a row of 20 tiles
|
||||
rept SCREEN_WIDTH / 2 - 1
|
||||
pop de
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], d
|
||||
inc l
|
||||
endr
|
||||
pop de
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], d
|
||||
|
||||
add hl, bc
|
||||
dec a
|
||||
jr nz, .row
|
||||
|
||||
ldh a, [hSPBuffer]
|
||||
ld l, a
|
||||
ldh a, [hSPBuffer + 1]
|
||||
ld h, a
|
||||
ld sp, hl
|
||||
ret
|
||||
|
||||
Serve1bppRequest::
|
||||
; Only call during the first fifth of VBlank
|
||||
|
||||
ld a, [wRequested1bppSize]
|
||||
and a
|
||||
ret z
|
||||
|
||||
; Back out if we're too far into VBlank
|
||||
ldh a, [rLY]
|
||||
cp LY_VBLANK
|
||||
ret c
|
||||
cp LY_VBLANK + 2
|
||||
ret nc
|
||||
|
||||
; Copy [wRequested1bppSize] 1bpp tiles from [wRequested1bppSource] to [wRequested1bppDest]
|
||||
|
||||
ld [hSPBuffer], sp
|
||||
|
||||
; Source
|
||||
ld hl, wRequested1bppSource
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld sp, hl
|
||||
|
||||
; Destination
|
||||
ld hl, wRequested1bppDest
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
; # tiles to copy
|
||||
ld a, [wRequested1bppSize]
|
||||
ld b, a
|
||||
|
||||
xor a
|
||||
ld [wRequested1bppSize], a
|
||||
|
||||
.next
|
||||
|
||||
rept 3
|
||||
pop de
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], d
|
||||
inc l
|
||||
ld [hl], d
|
||||
inc l
|
||||
endr
|
||||
pop de
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], d
|
||||
inc l
|
||||
ld [hl], d
|
||||
|
||||
inc hl
|
||||
dec b
|
||||
jr nz, .next
|
||||
|
||||
ld a, l
|
||||
ld [wRequested1bppDest], a
|
||||
ld a, h
|
||||
ld [wRequested1bppDest + 1], a
|
||||
|
||||
ld [wRequested1bppSource], sp
|
||||
|
||||
ldh a, [hSPBuffer]
|
||||
ld l, a
|
||||
ldh a, [hSPBuffer + 1]
|
||||
ld h, a
|
||||
ld sp, hl
|
||||
ret
|
||||
|
||||
Serve2bppRequest::
|
||||
; Only call during the first fifth of VBlank
|
||||
|
||||
ld a, [wRequested2bppSize]
|
||||
and a
|
||||
ret z
|
||||
|
||||
; Back out if we're too far into VBlank
|
||||
ldh a, [rLY]
|
||||
cp LY_VBLANK
|
||||
ret c
|
||||
cp LY_VBLANK + 2
|
||||
ret nc
|
||||
jr _Serve2bppRequest
|
||||
|
||||
Serve2bppRequest_VBlank::
|
||||
ld a, [wRequested2bppSize]
|
||||
and a
|
||||
ret z
|
||||
|
||||
_Serve2bppRequest::
|
||||
; Copy [wRequested2bppSize] 2bpp tiles from [wRequested2bppSource] to [wRequested2bppDest]
|
||||
|
||||
ld [hSPBuffer], sp
|
||||
|
||||
; Source
|
||||
ld hl, wRequested2bppSource
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
ld sp, hl
|
||||
|
||||
; Destination
|
||||
ld hl, wRequested2bppDest
|
||||
ld a, [hli]
|
||||
ld h, [hl]
|
||||
ld l, a
|
||||
|
||||
; # tiles to copy
|
||||
ld a, [wRequested2bppSize]
|
||||
ld b, a
|
||||
|
||||
xor a
|
||||
ld [wRequested2bppSize], a
|
||||
|
||||
.next
|
||||
|
||||
rept 7
|
||||
pop de
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], d
|
||||
inc l
|
||||
endr
|
||||
pop de
|
||||
ld [hl], e
|
||||
inc l
|
||||
ld [hl], d
|
||||
|
||||
inc hl
|
||||
dec b
|
||||
jr nz, .next
|
||||
|
||||
ld a, l
|
||||
ld [wRequested2bppDest], a
|
||||
ld a, h
|
||||
ld [wRequested2bppDest + 1], a
|
||||
|
||||
ld [wRequested2bppSource], sp
|
||||
|
||||
ldh a, [hSPBuffer]
|
||||
ld l, a
|
||||
ldh a, [hSPBuffer + 1]
|
||||
ld h, a
|
||||
ld sp, hl
|
||||
ret
|
||||
|
||||
AnimateTileset::
|
||||
; Only call during the first fifth of VBlank
|
||||
|
||||
ldh a, [hMapAnims]
|
||||
and a
|
||||
ret z
|
||||
|
||||
; Back out if we're too far into VBlank
|
||||
ldh a, [rLY]
|
||||
cp LY_VBLANK
|
||||
ret c
|
||||
cp LY_VBLANK + 7
|
||||
ret nc
|
||||
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(_AnimateTileset)
|
||||
rst Bankswitch
|
||||
|
||||
ldh a, [rSVBK]
|
||||
push af
|
||||
ld a, BANK(wTilesetAnim)
|
||||
ldh [rSVBK], a
|
||||
|
||||
ldh a, [rVBK]
|
||||
push af
|
||||
xor a
|
||||
ldh [rVBK], a
|
||||
|
||||
call _AnimateTileset
|
||||
|
||||
pop af
|
||||
ldh [rVBK], a
|
||||
pop af
|
||||
ldh [rSVBK], a
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
93
home/window.asm
Normal file
93
home/window.asm
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
RefreshScreen::
|
||||
call ClearWindowData
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(ReanchorBGMap_NoOAMUpdate) ; aka BANK(LoadFonts_NoOAMUpdate)
|
||||
rst Bankswitch
|
||||
|
||||
call ReanchorBGMap_NoOAMUpdate
|
||||
call _OpenAndCloseMenu_HDMATransferTilemapAndAttrmap
|
||||
call LoadFonts_NoOAMUpdate
|
||||
|
||||
pop af
|
||||
rst Bankswitch
|
||||
ret
|
||||
|
||||
CloseText::
|
||||
ldh a, [hOAMUpdate]
|
||||
push af
|
||||
ld a, $1
|
||||
ldh [hOAMUpdate], a
|
||||
|
||||
call .CloseText
|
||||
|
||||
pop af
|
||||
ldh [hOAMUpdate], a
|
||||
ld hl, wVramState
|
||||
res 6, [hl]
|
||||
ret
|
||||
|
||||
.CloseText:
|
||||
call ClearWindowData
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
call OverworldTextModeSwitch
|
||||
call _OpenAndCloseMenu_HDMATransferTilemapAndAttrmap
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
call SafeUpdateSprites
|
||||
ld a, $90
|
||||
ldh [hWY], a
|
||||
call UpdatePlayerSprite
|
||||
farcall InitMapNameSign
|
||||
farcall LoadOverworldFont
|
||||
ret
|
||||
|
||||
OpenText::
|
||||
call ClearWindowData
|
||||
ldh a, [hROMBank]
|
||||
push af
|
||||
ld a, BANK(ReanchorBGMap_NoOAMUpdate) ; aka BANK(LoadFonts_NoOAMUpdate)
|
||||
rst Bankswitch
|
||||
|
||||
call ReanchorBGMap_NoOAMUpdate ; clear bgmap
|
||||
call SpeechTextbox
|
||||
call _OpenAndCloseMenu_HDMATransferTilemapAndAttrmap ; anchor bgmap
|
||||
call LoadFonts_NoOAMUpdate ; load font
|
||||
pop af
|
||||
rst Bankswitch
|
||||
|
||||
ret
|
||||
|
||||
_OpenAndCloseMenu_HDMATransferTilemapAndAttrmap::
|
||||
ldh a, [hOAMUpdate]
|
||||
push af
|
||||
ld a, $1
|
||||
ldh [hOAMUpdate], a
|
||||
|
||||
farcall OpenAndCloseMenu_HDMATransferTilemapAndAttrmap
|
||||
|
||||
pop af
|
||||
ldh [hOAMUpdate], a
|
||||
ret
|
||||
|
||||
SafeUpdateSprites::
|
||||
ldh a, [hOAMUpdate]
|
||||
push af
|
||||
ldh a, [hBGMapMode]
|
||||
push af
|
||||
xor a
|
||||
ldh [hBGMapMode], a
|
||||
ld a, $1
|
||||
ldh [hOAMUpdate], a
|
||||
|
||||
call UpdateSprites
|
||||
|
||||
xor a
|
||||
ldh [hOAMUpdate], a
|
||||
call DelayFrame
|
||||
pop af
|
||||
ldh [hBGMapMode], a
|
||||
pop af
|
||||
ldh [hOAMUpdate], a
|
||||
ret
|
||||
Loading…
Add table
Add a link
Reference in a new issue