summaryrefslogtreecommitdiff
path: root/home.asm
diff options
context:
space:
mode:
authordannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
committerdannye <33dannye@gmail.com>2020-11-04 00:06:44 -0600
commit5647ca687b92954dcf37a6ea6bfbc9a341c32de4 (patch)
treedde1937a1bfdb3a835f4155e1c2eb8f1aaf86f63 /home.asm
parent53fcd05aa24693093d8af1dc8ec4fedd3957decc (diff)
Sync with pokered
Diffstat (limited to 'home.asm')
-rw-r--r--home.asm4801
1 files changed, 77 insertions, 4724 deletions
diff --git a/home.asm b/home.asm
index 9d9b5dd4..17701681 100644
--- a/home.asm
+++ b/home.asm
@@ -1,105 +1,23 @@
-; The rst vectors are unused.
-SECTION "rst 00", ROM0
- rst $38
-SECTION "rst 08", ROM0
- rst $38
-SECTION "rst 10", ROM0
- rst $38
-SECTION "rst 18", ROM0
- rst $38
-SECTION "rst 20", ROM0
- rst $38
-SECTION "rst 28", ROM0
- rst $38
-SECTION "rst 30", ROM0
- rst $38
-SECTION "rst 38", ROM0
- rst $38
+INCLUDE "constants.asm"
-; Hardware interrupts
-SECTION "vblank", ROM0
- jp VBlank
-SECTION "hblank", ROM0
- jp LCDC
-SECTION "timer", ROM0
- jp Timer
-SECTION "serial", ROM0
- jp Serial
-SECTION "joypad", ROM0
- reti
+SECTION "NULL", ROM0
+NULL::
-SECTION "Home", ROM0
-
-DisableLCD::
- xor a
- ld [rIF], a
- ld a, [rIE]
- ld b, a
- res 0, a
- ld [rIE], a
+INCLUDE "home/header.asm"
-.wait
- ld a, [rLY]
- cp LY_VBLANK
- jr nz, .wait
- ld a, [rLCDC]
- and $ff ^ rLCDC_ENABLE_MASK
- ld [rLCDC], a
- ld a, b
- ld [rIE], a
- ret
-
-EnableLCD::
- ld a, [rLCDC]
- set rLCDC_ENABLE, a
- ld [rLCDC], a
- ret
-
-ClearSprites::
- xor a
- ld hl, wOAMBuffer
- ld b, 40 * 4
-.loop
- ld [hli], a
- dec b
- jr nz, .loop
- ret
-
-HideSprites::
- ld a, 160
- ld hl, wOAMBuffer
- ld de, 4
- ld b, 40
-.loop
- ld [hl], a
- add hl, de
- dec b
- jr nz, .loop
- ret
+SECTION "High Home", ROM0
+INCLUDE "home/lcd.asm"
+INCLUDE "home/clear_sprites.asm"
INCLUDE "home/copy.asm"
-SECTION "Entry", ROM0
-
- nop
- jp Start
-
-
-SECTION "Header", ROM0
-
- ; The header is generated by rgbfix.
- ; The space here is allocated to prevent code from being overwritten.
-
- ds $150 - $104
-
-
-SECTION "Main", ROM0
+SECTION "Home", ROM0
PlayPikachuPCM::
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
push af
ld a, b
call BankswitchCommon
@@ -134,7 +52,7 @@ LoadNextSoundClipSample::
and $80
srl a
srl a
- ld [rNR32], a
+ ldh [rNR32], a
sla d
ret
@@ -145,830 +63,15 @@ PlaySoundClipSample::
jr nz, .loop
ret
-Start::
- cp GBC
- jr z, .gbc
- xor a
- jr .ok
-.gbc
- ld a, 1
-.ok
- ld [hGBC], a
- jp Init
-
-Joypad::
- homecall_jump _Joypad
-
-ReadJoypad::
- homecall_jump ReadJoypad_
+INCLUDE "home/start.asm"
+INCLUDE "home/joypad.asm"
INCLUDE "home/overworld.asm"
-
-CheckForUserInterruption::
-; Return carry if Up + Select + B, Start or A are pressed in c frames.
-; Used only in the intro and title screen.
- call DelayFrame
-
- push bc
- call JoypadLowSensitivity
- pop bc
-
- ld a, [hJoyHeld]
- cp D_UP + SELECT + B_BUTTON
- jr z, .input
-
- ld a, [hJoy5]
- and START | A_BUTTON
- jr nz, .input
-
- dec c
- jr nz, CheckForUserInterruption
-
- and a
- ret
-
-.input
- scf
- ret
-
-; function to load position data for destination warp when switching maps
-; INPUT:
-; a = ID of destination warp within destination map
-LoadDestinationWarpPosition::
- ld b, a
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wPredefParentBank]
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- ld a, b
- add a
- add a
- ld c, a
- ld b, 0
- add hl, bc
- ld bc, 4
- ld de, wCurrentTileBlockMapViewPointer
- call CopyData
- pop af
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- ret
-
-
-DrawHPBar::
-; Draw an HP bar d tiles long, and fill it to e pixels.
-; If c is nonzero, show at least a sliver regardless.
-; The right end of the bar changes with [wHPBarType].
-
- push hl
- push de
- ;push bc
-
- ; Left
- ld a, $71 ; "HP:"
- ld [hli], a
- ld a, $62
- ld [hli], a
-
- push hl
-
- ; Middle
- ld a, $63 ; empty
-.draw
- ld [hli], a
- dec d
- jr nz, .draw
-
- ; Right
- ld a, [wHPBarType]
- dec a
- ld a, $6d ; status screen and battle
- jr z, .ok
- dec a ; pokemon menu
-.ok
- ld [hl], a
-
- pop hl
-
- ld a, e
- and a
- jr nz, .fill
-
- ; If c is nonzero, draw a pixel anyway.
- ld a, c
- and a
- jr z, .done
- ld e, 1
-
-.fill
- ld a, e
- sub 8
- jr c, .partial
- ld e, a
- ld a, $6b ; full
- ld [hli], a
- ld a, e
- and a
- jr z, .done
- jr .fill
-
-.partial
- ; Fill remaining pixels at the end if necessary.
- ld a, $63 ; empty
- add e
- ld [hl], a
-.done
- ;pop bc
- pop de
- pop hl
- ret
-
-
-; loads pokemon data from one of multiple sources to wLoadedMon
-; loads base stats to wMonHeader
-; INPUT:
-; [wWhichPokemon] = index of pokemon within party/box
-; [wMonDataLocation] = source
-; 00: player's party
-; 01: enemy's party
-; 02: current box
-; 03: daycare
-; OUTPUT:
-; [wcf91] = pokemon ID
-; wLoadedMon = base address of pokemon data
-; wMonHeader = base address of base stats
-LoadMonData::
- jpab LoadMonData_
-
-OverwritewMoves::
-; Write c to [wMoves + b]. Unused.
- ld hl, wMoves
- ld e, b
- ld d, 0
- add hl, de
- ld a, c
- ld [hl], a
- ret
-
-LoadFlippedFrontSpriteByMonIndex::
- ld a, 1
- ld [wSpriteFlipped], a
-
-LoadFrontSpriteByMonIndex::
- push hl
- ld a, [wd11e]
- push af
- ld a, [wcf91]
- ld [wd11e], a
- predef IndexToPokedex
- ld hl, wd11e
- ld a, [hl]
- pop bc
- ld [hl], b
- and a
- pop hl
- jr z, .invalidDexNumber ; dex #0 invalid
- cp NUM_POKEMON + 1
- jr c, .validDexNumber ; dex >#151 invalid
-.invalidDexNumber
- ld a, RHYDON ; $1
- ld [wcf91], a
- ret
-.validDexNumber
- push hl
- ld de, vFrontPic
- call LoadMonFrontSprite
- pop hl
- ld a, [H_LOADEDROMBANK]
- push af
- switchbank CopyUncompressedPicToHL
- xor a
- ld [hStartTileID], a
- call CopyUncompressedPicToHL
- xor a
- ld [wSpriteFlipped], a
- pop af
- jp BankswitchCommon
-
-PlayCry::
-; Play monster a's cry.
- push bc
- ld b, a
- ld a, [wLowHealthAlarm]
- push af
- xor a
- ld [wLowHealthAlarm], a
- ld a, b
- call GetCryData
- call PlaySound
- call WaitForSoundToFinish
- pop af
- ld [wLowHealthAlarm], a
- pop bc
- ret
-
-GetCryData::
-; Load cry data for monster a.
- dec a
- ld c, a
- ld b, 0
- ld hl, CryData
- add hl, bc
- add hl, bc
- add hl, bc
-
- ld a, BANK(CryData)
- call BankswitchHome
- ld a, [hli]
- ld b, a ; cry id
- ld a, [hli]
- ld [wFrequencyModifier], a
- ld a, [hl]
- ld [wTempoModifier], a
- call BankswitchBack
-
- ; Cry headers have 3 channels,
- ; and start from index $14,
- ; so add 3 times the cry id.
- ld a, b
- ld c, $14
- rlca ; * 2
- add b
- add c
- ret
-
-DisplayPartyMenu::
- ld a, [hTilesetType]
- push af
- xor a
- ld [hTilesetType], a
- call GBPalWhiteOutWithDelay3
- call ClearSprites
- call PartyMenuInit
- call DrawPartyMenu
- jp HandlePartyMenuInput
-
-GoBackToPartyMenu::
- ld a, [hTilesetType]
- push af
- xor a
- ld [hTilesetType], a
- call PartyMenuInit
- call RedrawPartyMenu
- jp HandlePartyMenuInput
-
-PartyMenuInit::
- ld a, 1 ; hardcoded bank
- call BankswitchHome
- call LoadHpBarAndStatusTilePatterns
- ld hl, wd730
- set 6, [hl] ; turn off letter printing delay
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- ld [wMenuWatchMovingOutOfBounds], a
- ld hl, wTopMenuItemY
- inc a
- ld [hli], a ; top menu item Y
- xor a
- ld [hli], a ; top menu item X
- ld a, [wPartyAndBillsPCSavedMenuItem]
- push af
- ld [hli], a ; current menu item ID
- inc hl
- ld a, [wPartyCount]
- and a ; are there more than 0 pokemon in the party?
- jr z, .storeMaxMenuItemID
- dec a
-; if party is not empty, the max menu item ID is ([wPartyCount] - 1)
-; otherwise, it is 0
-.storeMaxMenuItemID
- ld [hli], a ; max menu item ID
- ld a, [wForcePlayerToChooseMon]
- and a
- ld a, A_BUTTON | B_BUTTON
- jr z, .next
- xor a
- ld [wForcePlayerToChooseMon], a
- inc a ; a = A_BUTTON
-.next
- ld [hli], a ; menu watched keys
- pop af
- ld [hl], a ; old menu item ID
- ret
-
-HandlePartyMenuInput::
- ld a, 1
- ld [wMenuWrappingEnabled], a
- ld a, $40
- ld [wPartyMenuAnimMonEnabled], a
- call HandleMenuInputPokemonSelection
- push af ; save hJoy5 OR wMenuWrapping enabled, if no inputs were selected within a certain period of time
- bit 1, a ; was B button pressed?
- ld a, $0
- ld [wPartyMenuAnimMonEnabled], a
- ld a, [wCurrentMenuItem]
- ld [wPartyAndBillsPCSavedMenuItem], a
- jr nz, .asm_1258
- ld a, [wCurrentMenuItem]
- ld [wWhichPokemon], a
- callab IsThisPartymonStarterPikachu_Party
- jr nc, .asm_1258
- call CheckPikachuFollowingPlayer
- jr nz, .asm_128f
-.asm_1258
- pop af
- call PlaceUnfilledArrowMenuCursor
- ld b, a
- ld hl, wd730
- res 6, [hl] ; turn on letter printing delay
- ld a, [wMenuItemToSwap]
- and a
- jp nz, .swappingPokemon
- pop af
- ld [hTilesetType], a
- bit 1, b
- jr nz, .noPokemonChosen
- ld a, [wPartyCount]
- and a
- jr z, .noPokemonChosen
- ld a, [wCurrentMenuItem]
- ld [wWhichPokemon], a
- ld hl, wPartySpecies
- ld b, 0
- ld c, a
- add hl, bc
- ld a, [hl]
- ld [wcf91], a
- ld [wBattleMonSpecies2], a
- call BankswitchBack
- and a
- ret
-.asm_128f
- pop af
- ld hl, PartyMenuText_12cc
- call PrintText
- xor a
- ld [wMenuItemToSwap], a
- pop af
- ld [hTilesetType], a
-.noPokemonChosen
- call BankswitchBack
- scf
- ret
-.swappingPokemon
- bit 1, b ; was the B button pressed?
- jr z, .handleSwap ; if not, handle swapping the pokemon
-.cancelSwap ; if the B button was pressed
- callba ErasePartyMenuCursors
- xor a
- ld [wMenuItemToSwap], a
- ld [wPartyMenuTypeOrMessageID], a
- call RedrawPartyMenu
- jp HandlePartyMenuInput
-.handleSwap
- ld a, [wCurrentMenuItem]
- ld [wWhichPokemon], a
- callba SwitchPartyMon
- jp HandlePartyMenuInput
-
-PartyMenuText_12cc::
- TX_FAR _SleepingPikachuText1
- db "@"
-
-DrawPartyMenu::
- ld hl, DrawPartyMenu_
- jr DrawPartyMenuCommon
-
-RedrawPartyMenu::
- ld hl, RedrawPartyMenu_
-
-DrawPartyMenuCommon::
- ld b, BANK(RedrawPartyMenu_)
- jp Bankswitch
-
-; prints a pokemon's status condition
-; INPUT:
-; de = address of status condition
-; hl = destination address
-PrintStatusCondition::
- push de
- dec de
- dec de ; de = address of current HP
- ld a, [de]
- ld b, a
- dec de
- ld a, [de]
- or b ; is the pokemon's HP zero?
- pop de
- jr nz, PrintStatusConditionNotFainted
-; if the pokemon's HP is 0, print "FNT"
- ld a, "F"
- ld [hli], a
- ld a, "N"
- ld [hli], a
- ld [hl], "T"
- and a
- ret
-
-PrintStatusConditionNotFainted:
- homecall_jump_sf PrintStatusAilment
-
-; function to print pokemon level, leaving off the ":L" if the level is at least 100
-; INPUT:
-; hl = destination address
-; [wLoadedMonLevel] = level
-PrintLevel::
- ld a, $6e ; ":L" tile ID
- ld [hli], a
- ld c, 2 ; number of digits
- ld a, [wLoadedMonLevel] ; level
- cp 100
- jr c, PrintLevelCommon
-; if level at least 100, write over the ":L" tile
- dec hl
- inc c ; increment number of digits to 3
- jr PrintLevelCommon
-
-; prints the level without leaving off ":L" regardless of level
-; INPUT:
-; hl = destination address
-; [wLoadedMonLevel] = level
-PrintLevelFull::
- ld a, $6e ; ":L" tile ID
- ld [hli], a
- ld c, 3 ; number of digits
- ld a, [wLoadedMonLevel] ; level
-
-PrintLevelCommon::
- ld [wd11e], a
- ld de, wd11e
- ld b, LEFT_ALIGN | 1 ; 1 byte
- jp PrintNumber
-
-GetwMoves::
-; Unused. Returns the move at index a from wMoves in a
- ld hl, wMoves
- ld c, a
- ld b, 0
- add hl, bc
- ld a, [hl]
- ret
-
-; copies the base stat data of a pokemon to wMonHeader
-; INPUT:
-; [wd0b5] = pokemon ID
-GetMonHeader::
- ld a, [H_LOADEDROMBANK]
- push af
- switchbank BaseStats
- push bc
- push de
- push hl
- ld a, [wd11e]
- push af
- ld a, [wd0b5]
- ld [wd11e], a
- ld de, FossilKabutopsPic
- ld b, $66 ; size of Kabutops fossil and Ghost sprites
- cp FOSSIL_KABUTOPS ; Kabutops fossil
- jr z, .specialID
- ld de, GhostPic
- cp MON_GHOST ; Ghost
- jr z, .specialID
- ld de, FossilAerodactylPic
- ld b, $77 ; size of Aerodactyl fossil sprite
- cp FOSSIL_AERODACTYL ; Aerodactyl fossil
- jr z, .specialID
- ;cp MEW
- ;jr z, .mew
- predef IndexToPokedex ; convert pokemon ID in [wd11e] to pokedex number
- ld a, [wd11e]
- dec a
- ld bc, MonBaseStatsEnd - MonBaseStats
- ld hl, BaseStats
- call AddNTimes
- ld de, wMonHeader
- ld bc, MonBaseStatsEnd - MonBaseStats
- call CopyData
- jr .done
-.specialID
- ld hl, wMonHSpriteDim
- ld [hl], b ; write sprite dimensions
- inc hl
- ld [hl], e ; write front sprite pointer
- inc hl
- ld [hl], d
-.done
- ld a, [wd0b5]
- ld [wMonHIndex], a
- pop af
- ld [wd11e], a
- pop hl
- pop de
- pop bc
- pop af
- call BankswitchCommon
- ret
-
-; copy party pokemon's name to wcd6d
-GetPartyMonName2::
- ld a, [wWhichPokemon] ; index within party
- ld hl, wPartyMonNicks
-
-; this is called more often
-GetPartyMonName::
- push hl
- push bc
- call SkipFixedLengthTextEntries ; add NAME_LENGTH to hl, a times
- ld de, wcd6d
- push de
- ld bc, NAME_LENGTH
- call CopyData
- pop de
- pop bc
- pop hl
- ret
-
-; 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.
-PrintBCDNumber::
- ld b, c ; save flags in b
- res 7, c
- res 6, c
- res 5, c ; c now holds the length
- bit 5, b
- jr z, .loop
- bit 7, b
- jr nz, .loop
- 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 7, b ; were any non-zero digits printed?
- jr z, .done ; if so, we are done
-.numberEqualsZero ; if every digit of the BCD number is zero
- bit 6, b ; left or right alignment?
- jr nz, .skipRightAlignmentAdjustment
- dec hl ; if the string is right-aligned, it needs to be moved back one space
-.skipRightAlignmentAdjustment
- bit 5, b
- jr z, .skipCurrencySymbol
- ld [hl], "¥"
- inc hl
-.skipCurrencySymbol
- ld [hl], "0"
- call PrintLetterDelay
- inc hl
-.done
- ret
-
-PrintBCDDigit::
- and $f
- and a
- jr z, .zeroDigit
-.nonzeroDigit
- bit 7, b ; have any non-space characters been printed?
- jr z, .outputDigit
-; if bit 7 is set, then no numbers have been printed yet
- bit 5, b ; print the currency symbol?
- jr z, .skipCurrencySymbol
- ld [hl], "¥"
- inc hl
- res 5, b
-.skipCurrencySymbol
- res 7, b ; unset 7 to indicate that a nonzero digit has been reached
-.outputDigit
- add "0"
- ld [hli], a
- jp PrintLetterDelay
-.zeroDigit
- bit 7, b ; either printing leading zeroes or already reached a nonzero digit?
- jr z, .outputDigit ; if so, print a zero digit
- bit 6, b ; left or right alignment?
- ret nz
- inc hl ; if right-aligned, "print" a space by advancing the pointer
- ret
-
-; uncompresses the front or back sprite of the specified mon
-; assumes the corresponding mon header is already loaded
-; hl contains offset to sprite pointer ($b for front or $d for back)
-UncompressMonSprite::
- ld bc, wMonHeader
- add hl, bc
- ld a, [hli]
- ld [wSpriteInputPtr], a ; fetch sprite input pointer
- ld a, [hl]
- ld [wSpriteInputPtr + 1], a
-; define (by index number) the bank that a pokemon's image is in
-; index = Mew, bank 1
-; index = Kabutops fossil, bank $B
-; index < $1F, bank 9
-; $1F ≤ index < $4A, bank $A
-; $4A ≤ index < $74, bank $B
-; $74 ≤ index < $99, bank $C
-; $99 ≤ index, bank $D
- ld a, [wcf91] ; XXX name for this ram location
- ld b, a
- ;cp MEW
- ;ld a, BANK(MewPicFront)
- ;jr z, .GotBank
- ;ld a, b
- cp FOSSIL_KABUTOPS
- ld a, BANK(FossilKabutopsPic)
- jr z, .GotBank
- ld a, b
- cp TANGELA + 1
- ld a, BANK(TangelaPicFront)
- jr c, .GotBank
- ld a, b
- cp MOLTRES + 1
- ld a, BANK(MoltresPicFront)
- jr c, .GotBank
- ld a, b
- cp BEEDRILL + 2
- ld a, BANK(BeedrillPicFront)
- jr c, .GotBank
- ld a, b
- cp STARMIE + 1
- ld a, BANK(StarmiePicFront)
- jr c, .GotBank
- ld a, BANK(VictreebelPicFront)
-.GotBank
- jp UncompressSpriteData
-
-; de: destination location
-LoadMonFrontSprite::
- push de
- ld hl, wMonHFrontSprite - wMonHeader
- call UncompressMonSprite
- ld hl, wMonHSpriteDim
- ld a, [hli]
- ld c, a
- pop de
- ; fall through
-
-; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram
-; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers
-; de: destination location
-; a, c: sprite dimensions (in tiles of 8x8 each)
-LoadUncompressedSpriteData::
- push de
- and $f
- ld [H_SPRITEWIDTH], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width
- ld b, a
- ld a, $7
- sub b ; 7-w
- inc a ; 8-w
- srl a ; (8-w)/2 ; horizontal center (in tiles, rounded up)
- ld b, a
- add a
- add a
- add a
- sub b ; 7*((8-w)/2) ; skip for horizontal center (in tiles)
- ld [H_SPRITEOFFSET], a
- ld a, c
- swap a
- and $f
- ld b, a
- add a
- add a
- add a ; 8*tiles is height in bytes
- ld [H_SPRITEHEIGHT], a
- ld a, $7
- sub b ; 7-h ; skip for vertical center (in tiles, relative to current column)
- ld b, a
- ld a, [H_SPRITEOFFSET]
- add b ; 7*((8-w)/2) + 7-h ; combined overall offset (in tiles)
- add a
- add a
- add a ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes)
- ld [H_SPRITEOFFSET], a
- ld a, $0
- call SwitchSRAMBankAndLatchClockData
- ld hl, sSpriteBuffer0
- call ZeroSpriteBuffer ; zero buffer 0
- ld de, sSpriteBuffer1
- ld hl, sSpriteBuffer0
- call AlignSpriteDataCentered ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite)
- ld hl, sSpriteBuffer1
- call ZeroSpriteBuffer ; zero buffer 1
- ld de, sSpriteBuffer2
- ld hl, sSpriteBuffer1
- call AlignSpriteDataCentered ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite)
- call PrepareRTCDataAndDisableSRAM
- pop de
- jp InterlaceMergeSpriteBuffers
-
-; copies and aligns the sprite data properly inside the sprite buffer
-; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area
-AlignSpriteDataCentered::
- ld a, [H_SPRITEOFFSET]
- ld b, $0
- ld c, a
- add hl, bc
- ld a, [H_SPRITEWIDTH]
-.columnLoop
- push af
- push hl
- ld a, [H_SPRITEHEIGHT]
- ld c, a
-.columnInnerLoop
- ld a, [de]
- inc de
- ld [hli], a
- dec c
- jr nz, .columnInnerLoop
- pop hl
- ld bc, 7*8 ; 7 tiles
- add hl, bc ; advance one full column
- pop af
- dec a
- jr nz, .columnLoop
- ret
-
-; fills the sprite buffer (pointed to in hl) with zeros
-ZeroSpriteBuffer::
- ld bc, SPRITEBUFFERSIZE
-.nextByteLoop
- xor a
- ld [hli], a
- dec bc
- ld a, b
- or c
- jr nz, .nextByteLoop
- ret
-
-; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2
-; in the resulting sprite, the rows of the two source sprites are interlaced
-; de: output address
-InterlaceMergeSpriteBuffers::
- ld a, $0
- call SwitchSRAMBankAndLatchClockData
- push de
- ld hl, sSpriteBuffer2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2
- ld de, sSpriteBuffer1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1
- ld bc, sSpriteBuffer0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0
- ld a, SPRITEBUFFERSIZE/2 ; $c4
- ld [H_SPRITEINTERLACECOUNTER], a
-.interlaceLoop
- ld a, [de]
- dec de
- ld [hld], a ; write byte of source 2
- ld a, [bc]
- dec bc
- ld [hld], a ; write byte of source 1
- ld a, [de]
- dec de
- ld [hld], a ; write byte of source 2
- ld a, [bc]
- dec bc
- ld [hld], a ; write byte of source 1
- ld a, [H_SPRITEINTERLACECOUNTER]
- dec a
- ld [H_SPRITEINTERLACECOUNTER], a
- jr nz, .interlaceLoop
- ld a, [wSpriteFlipped]
- and a
- jr z, .notFlipped
- ld bc, 2*SPRITEBUFFERSIZE
- ld hl, sSpriteBuffer1
-.swapLoop
- swap [hl] ; if flipped swap nybbles in all bytes
- inc hl
- dec bc
- ld a, b
- or c
- jr nz, .swapLoop
-.notFlipped
- pop hl
- ld de, sSpriteBuffer1
- ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied
- ld a, [H_LOADEDROMBANK]
- ld b, a
- call CopyVideoData
- jp PrepareRTCDataAndDisableSRAM
+INCLUDE "home/pokemon.asm"
+INCLUDE "home/print_bcd.asm"
+INCLUDE "home/pics.asm"
INCLUDE "home/pikachu.asm"
-;INCLUDE "data/collision.asm"
INCLUDE "home/lcdc.asm"
@@ -987,1240 +90,43 @@ INCLUDE "home/play_time.asm"
INCLUDE "home/serial.asm"
INCLUDE "home/timer.asm"
INCLUDE "home/audio.asm"
+INCLUDE "home/update_sprites.asm"
+INCLUDE "data/items/marts.asm"
-UpdateSprites::
- ld a, [wUpdateSpritesEnabled]
- dec a
- ret nz
- ld a, [H_LOADEDROMBANK]
- push af
- switchbank _UpdateSprites
- ld a, $ff
- ld [wUpdateSpritesEnabled], a
- call _UpdateSprites
- ld a, $1
- ld [wUpdateSpritesEnabled], a
- pop af
- call BankswitchCommon
- ret
-
-INCLUDE "data/mart_inventories.asm"
-
-TextScriptEndingChar::
- db "@"
-TextScriptEnd::
- ld hl, TextScriptEndingChar
- ret
-
-ExclamationText::
- TX_FAR _ExclamationText
- db "@"
-
-GroundRoseText::
- TX_FAR _GroundRoseText
- db "@"
-
-BoulderText::
- TX_FAR _BoulderText
- db "@"
-
-MartSignText::
- TX_FAR _MartSignText
- db "@"
-
-PokeCenterSignText::
- TX_FAR _PokeCenterSignText
- db "@"
-
-PickUpItemText::
- TX_ASM
- predef PickUpItem
- jp TextScriptEnd
-
-
-INCLUDE "home/pic.asm"
-
-
-ResetPlayerSpriteData::
- ld hl, wSpriteStateData1
- call ResetPlayerSpriteData_ClearSpriteData
- ld hl, wSpriteStateData2
- call ResetPlayerSpriteData_ClearSpriteData
- ld a, $1
- ld [wSpriteStateData1], a
- ld [wSpriteStateData2 + $0e], a
- ld hl, wSpriteStateData1 + 4
- ld [hl], $3c ; set Y screen pos
- inc hl
- inc hl
- ld [hl], $40 ; set X screen pos
- ret
-
-; overwrites sprite data with zeroes
-ResetPlayerSpriteData_ClearSpriteData::
- ld bc, $10
- xor a
- call FillMemory
- ret
-
-FadeOutAudio::
- ld a, [wAudioFadeOutControl]
- and a ; currently fading out audio?
- jr nz, .fadingOut
- ld a, [wd72c]
- bit 1, a
- ret nz
- ld a, $77
- ld [rNR50], a
- ret
-.fadingOut
- ld a, [wAudioFadeOutCounter]
- and a
- jr z, .counterReachedZero
- dec a
- ld [wAudioFadeOutCounter], a
- ret
-.counterReachedZero
- ld a, [wAudioFadeOutCounterReloadValue]
- ld [wAudioFadeOutCounter], a
- ld a, [rNR50]
- and a ; has the volume reached 0?
- jr z, .fadeOutComplete
- ld b, a
- and $f
- dec a
- ld c, a
- ld a, b
- and $f0
- swap a
- dec a
- swap a
- or c
- ld [rNR50], a
- ret
-.fadeOutComplete
- ld a, [wAudioFadeOutControl]
- ld b, a
- xor a
- ld [wAudioFadeOutControl], a
- call StopAllMusic
- ld a, [wAudioSavedROMBank]
- ld [wAudioROMBank], a
- ld a, b
- ld [wNewSoundID], a
- jp PlaySound
+INCLUDE "home/overworld_text.asm"
+INCLUDE "home/uncompress.asm"
+INCLUDE "home/reset_player_sprite.asm"
+INCLUDE "home/fade_audio.asm"
UnknownText_2812::
- TX_FAR _PokemonText
- db "@"
-
-; this function is used to display sign messages, sprite dialog, etc.
-; INPUT: [hSpriteIndexOrTextID] = sprite ID or text ID
-DisplayTextID::
- ld a, [H_LOADEDROMBANK]
- push af
- callba DisplayTextIDInit ; initialization
- ld hl, wTextPredefFlag
- bit 0, [hl]
- res 0, [hl]
- jr nz, .skipSwitchToMapBank
- ld a, [wCurMap]
- call SwitchToMapRomBank
-.skipSwitchToMapBank
- ld a, 30 ; half a second
- ld [H_FRAMECOUNTER], a ; used as joypad poll timer
- ld hl, wMapTextPtr
- ld a, [hli]
- ld h, [hl]
- ld l, a ; hl = map text pointer
- ld d, $00
- ld a, [hSpriteIndexOrTextID] ; text ID
- ld [wSpriteIndex], a
- and a
- jp z, DisplayStartMenu
- cp TEXT_PIKACHU_ANIM
- jp z, DisplayPikachuEmotion
- cp TEXT_SAFARI_GAME_OVER
- jp z, DisplaySafariGameOverText
- cp TEXT_MON_FAINTED
- jp z, DisplayPokemonFaintedText
- cp TEXT_BLACKED_OUT
- jp z, DisplayPlayerBlackedOutText
- cp TEXT_REPEL_WORE_OFF
- jp z, DisplayRepelWoreOffText
- ld a, [wNumSprites]
- ld e, a
- ld a, [hSpriteIndexOrTextID] ; sprite ID
- cp e
- jr z, .spriteHandling
- jr nc, .skipSpriteHandling
-.spriteHandling
-; get the text ID of the sprite
- push hl
- ;push de
- ;push bc
- ;callba UpdateSpriteFacingOffsetAndDelayMovement ; update the graphics of the sprite the player is talking to (to face the right direction)
- ;pop bc
- ;pop de
- ld hl, wMapSpriteData ; NPC text entries
- ld a, [hSpriteIndexOrTextID]
- dec a
- add a
- ld e, a
- ld d, $0
- add hl, de
- inc hl
- ld a, [hl] ; a = text ID of the sprite
- pop hl
-.skipSpriteHandling
-; look up the address of the text in the map's text entries
- dec a
- ld e, a
- ld d, $0
- add hl, de
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a ; hl = address of the text
- ld a, [hl] ; a = first byte of text
-; check first byte of text for special cases
- cp $fe ; Pokemart NPC
- jp z, DisplayPokemartDialogue
- cp $ff ; Pokemon Center NPC
- jp z, DisplayPokemonCenterDialogue
- cp $fc ; Item Storage PC
- jp z, FuncTX_ItemStoragePC
- cp $fd ; Bill's PC
- jp z, FuncTX_BillsPC
- cp $f9 ; Pokemon Center PC
- jp z, FuncTX_PokemonCenterPC
- cp $f5 ; Vending Machine
- jr nz, .notVendingMachine
- callba VendingMachineMenu ; jump banks to vending machine routine
- jr AfterDisplayingTextID
-.notVendingMachine
- cp $f7 ; prize menu
- jp z, FuncTX_GameCornerPrizeMenu
- cp $f6 ; cable connection NPC in Pokemon Center
- jr nz, .notSpecialCase
- callab CableClubNPC
- jr AfterDisplayingTextID
-.notSpecialCase
- call PrintText_NoCreatingTextBox ; display the text
- ld a, [wDoNotWaitForButtonPressAfterDisplayingText]
- and a
- jr nz, HoldTextDisplayOpen
-
-AfterDisplayingTextID::
- ld a, [wEnteringCableClub]
- and a
- jr nz, HoldTextDisplayOpen
- call WaitForTextScrollButtonPress ; wait for a button press after displaying all the text
-
-; loop to hold the dialogue box open as long as the player keeps holding down the A button
-HoldTextDisplayOpen::
- call Joypad
- ld a, [hJoyHeld]
- bit 0, a ; is the A button being pressed?
- jr nz, HoldTextDisplayOpen
-
-CloseTextDisplay::
- ld a, [wCurMap]
- call SwitchToMapRomBank
- ld a, $90
- ld [hWY], a ; move the window off the screen
- call DelayFrame
- call LoadGBPal
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; disable continuous WRAM to VRAM transfer each V-blank
-; loop to make sprites face the directions they originally faced before the dialogue
- ld hl, wSpriteStateData2 + $19
- ld c, $0f
- ld de, $0010
-.restoreSpriteFacingDirectionLoop
- ld a, [hl]
- dec h
- ld [hl], a
- inc h
- add hl, de
- dec c
- jr nz, .restoreSpriteFacingDirectionLoop
- call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns)
- ld hl, wFontLoaded
- res 0, [hl]
- ld a, [wd732]
- bit 3, a ; used fly warp
- call z, LoadPlayerSpriteGraphics
- call LoadCurrentMapView
- pop af
- call BankswitchCommon
- jp UpdateSprites
-
-DisplayPokemartDialogue::
- push hl
- ld hl, PokemartGreetingText
- call PrintText
- pop hl
- inc hl
- call LoadItemList
- ld a, PRICEDITEMLISTMENU
- ld [wListMenuID], a
- homecall DisplayPokemartDialogue_
- jp AfterDisplayingTextID
-
-PokemartGreetingText::
- TX_FAR _PokemartGreetingText
- db "@"
-
-LoadItemList::
- ld a, 1
- ld [wUpdateSpritesEnabled], a
- ld a, h
- ld [wItemListPointer], a
- ld a, l
- ld [wItemListPointer + 1], a
- ld de, wItemList
-.loop
- ld a, [hli]
- ld [de], a
- inc de
- cp $ff
- jr nz, .loop
- ret
-
-DisplayPokemonCenterDialogue::
-; zeroing these doesn't appear to serve any purpose
- xor a
- ld [$ff8b], a
- ld [$ff8c], a
- ld [$ff8d], a
-
- inc hl
- homecall DisplayPokemonCenterDialogue_
- jp AfterDisplayingTextID
-
-DisplaySafariGameOverText::
- callab PrintSafariGameOverText
- jp AfterDisplayingTextID
-
-DisplayPokemonFaintedText::
- ld hl, PokemonFaintedText
- call PrintText
- jp AfterDisplayingTextID
-
-PokemonFaintedText::
- TX_FAR _PokemonFaintedText
- db "@"
-
-DisplayPlayerBlackedOutText::
- ld hl, PlayerBlackedOutText
- call PrintText
- ld a, [wd732]
- res 5, a ; reset forced to use bike bit
- ld [wd732], a
- CheckEvent EVENT_IN_SAFARI_ZONE
- jr z, .didnotblackoutinsafari
- xor a
- ld [wNumSafariBalls], a
- ld [wSafariSteps], a
- ld [wSafariSteps + 1], a
- EventFlagAddressa EVENT_IN_SAFARI_ZONE
- ld [wcf0d], a
- ld [wSafariZoneGateCurScript], a
-.didnotblackoutinsafari
- jp HoldTextDisplayOpen
-
-PlayerBlackedOutText::
- TX_FAR _PlayerBlackedOutText
- db "@"
-
-DisplayRepelWoreOffText::
- ld hl, RepelWoreOffText
- call PrintText
- jp AfterDisplayingTextID
-
-RepelWoreOffText::
- TX_FAR _RepelWoreOffText
- db "@"
-
-DisplayPikachuEmotion::
- callab TalkToPikachu
- jp CloseTextDisplay
-
-INCLUDE "engine/menu/start_menu.asm"
-
-; function to count how many bits are set in a string of bytes
-; INPUT:
-; hl = address of string of bytes
-; b = length of string of bytes
-; OUTPUT:
-; [wNumSetBits] = number of set bits
-CountSetBits::
- ld c, 0
-.loop
- ld a, [hli]
- ld e, a
- ld d, 8
-.innerLoop ; count how many bits are set in the current byte
- srl e
- ld a, 0
- adc c
- ld c, a
- dec d
- jr nz, .innerLoop
- dec b
- jr nz, .loop
- ld a, c
- ld [wNumSetBits], a
- ret
-
-; subtracts the amount the player paid from their money
-; sets carry flag if there is enough money and unsets carry flag if not
-SubtractAmountPaidFromMoney::
- jpba SubtractAmountPaidFromMoney_
-
-; adds the amount the player sold to their money
-AddAmountSoldToMoney::
- ld de, wPlayerMoney + 2
- ld hl, hMoney + 2 ; total price of items
- ld c, 3 ; length of money in bytes
- predef AddBCDPredef ; add total price to money
- ld a, MONEY_BOX
- ld [wTextBoxID], a
- call DisplayTextBoxID ; redraw money text box
- ld a, SFX_PURCHASE
- call PlaySoundWaitForCurrent
- jp WaitForSoundToFinish
-
-; function to remove an item (in varying quantities) from the player's bag or PC box
-; INPUT:
-; HL = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wWhichPokemon] = index (within the inventory) of the item to remove
-; [wItemQuantity] = quantity to remove
-RemoveItemFromInventory::
- homecall RemoveItemFromInventory_
- ret
-
-; function to add an item (in varying quantities) to the player's bag or PC box
-; INPUT:
-; HL = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wcf91] = item ID
-; [wItemQuantity] = item quantity
-; sets carry flag if successful, unsets carry flag if unsuccessful
-AddItemToInventory::
- push bc
- homecall_sf AddItemToInventory_
- pop bc
- ret
-
-; INPUT:
-; [wListMenuID] = list menu ID
-; [wListPointer] = address of the list (2 bytes)
-DisplayListMenuID::
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; disable auto-transfer
- ld a, 1
- ld [hJoy7], a ; joypad state update flag
- ld a, [wBattleType]
- and a ; is it the Old Man battle?
- jr nz, .specialBattleType
- ld a, $01 ; hardcoded bank
- jr .bankswitch
-.specialBattleType ; Old Man battle
- ld a, BANK(DisplayBattleMenu)
-.bankswitch
- call BankswitchHome
- ld hl, wd730
- set 6, [hl] ; turn off letter printing delay
- xor a
- ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
- ld [wListCount], a
- ld a, [wListPointer]
- ld l, a
- ld a, [wListPointer + 1]
- ld h, a ; hl = address of the list
- ld a, [hl] ; the first byte is the number of entries in the list
- ld [wListCount], a
- ld a, LIST_MENU_BOX
- ld [wTextBoxID], a
- call DisplayTextBoxID ; draw the menu text box
- call UpdateSprites ; disable sprites behind the text box
-; the code up to .skipMovingSprites appears to be useless
- coord hl, 4, 2 ; coordinates of upper left corner of menu text box
- lb de, 9, 14 ; height and width of menu text box
- ld a, [wListMenuID]
- and a ; is it a PC pokemon list?
- jr nz, .skipMovingSprites
- call UpdateSprites
-.skipMovingSprites
- ld a, 1 ; max menu item ID is 1 if the list has less than 2 entries
- ld [wMenuWatchMovingOutOfBounds], a
- ld a, [wListCount]
- cp 2 ; does the list have less than 2 entries?
- jr c, .setMenuVariables
- ld a, 2 ; max menu item ID is 2 if the list has at least 2 entries
-.setMenuVariables
- ld [wMaxMenuItem], a
- ld a, 4
- ld [wTopMenuItemY], a
- ld a, 5
- ld [wTopMenuItemX], a
- ld a, A_BUTTON | B_BUTTON | SELECT
- ld [wMenuWatchedKeys], a
- ld c, 10
- call DelayFrames
-
-DisplayListMenuIDLoop::
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a ; disable transfer
- call PrintListMenuEntries
- ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a ; enable transfer
- call Delay3
- ld a, [wBattleType]
- and a ; is it the Old Man battle?
- jr z, .notOldManBattle
-.oldManBattle
- ld a, "▶"
- Coorda 5, 4 ; place menu cursor in front of first menu entry
- ld c, 20
- call DelayFrames
- xor a
- ld [wCurrentMenuItem], a
- coord hl, 5, 4
- ld a, l
- ld [wMenuCursorLocation], a
- ld a, h
- ld [wMenuCursorLocation + 1], a
- jr .buttonAPressed
-.notOldManBattle
- call LoadGBPal
- call HandleMenuInput
- push af
- call PlaceMenuCursor
- pop af
- bit 0, a ; was the A button pressed?
- jp z, .checkOtherKeys
-.buttonAPressed
- ld a, [wCurrentMenuItem]
- call PlaceUnfilledArrowMenuCursor
-
-; pointless because both values are overwritten before they are read
- ld a, $01
- ld [wMenuExitMethod], a
- ld [wChosenMenuItem], a
-
- xor a
- ld [wMenuWatchMovingOutOfBounds], a
- ld a, [wCurrentMenuItem]
- ld c, a
- ld a, [wListScrollOffset]
- add c
- ld c, a
- ld a, [wListCount]
- and a ; is the list empty?
- jp z, ExitListMenu ; if so, exit the menu
- dec a
- cp c ; did the player select Cancel?
- jp c, ExitListMenu ; if so, exit the menu
- ld a, c
- ld [wWhichPokemon], a
- ld a, [wListMenuID]
- cp ITEMLISTMENU
- jr nz, .skipMultiplying
-; if it's an item menu
- sla c ; item entries are 2 bytes long, so multiply by 2
-.skipMultiplying
- ld a, [wListPointer]
- ld l, a
- ld a, [wListPointer + 1]
- ld h, a
- inc hl ; hl = beginning of list entries
- ld b, 0
- add hl, bc
- ld a, [hl]
- ld [wcf91], a
- ld a, [wListMenuID]
- and a ; is it a PC pokemon list?
- jr z, .pokemonList
- push hl
- call GetItemPrice
- pop hl
- ld a, [wListMenuID]
- cp ITEMLISTMENU
- jr nz, .skipGettingQuantity
-; if it's an item menu
- inc hl
- ld a, [hl] ; a = item quantity
- ld [wMaxItemQuantity], a
-.skipGettingQuantity
- ld a, [wcf91]
- ld [wd0b5], a
- ld a, BANK(ItemNames)
- ld [wPredefBank], a
- call GetName
- jr .storeChosenEntry
-.pokemonList
- ld hl, wPartyCount
- ld a, [wListPointer]
- cp l ; is it a list of party pokemon or box pokemon?
- ld hl, wPartyMonNicks
- jr z, .getPokemonName
- ld hl, wBoxMonNicks ; box pokemon names
-.getPokemonName
- ld a, [wWhichPokemon]
- call GetPartyMonName
-.storeChosenEntry ; store the menu entry that the player chose and return
- ld de, wcd6d
- call CopyStringToCF4B ; copy name to wcf4b
- ld a, CHOSE_MENU_ITEM
- ld [wMenuExitMethod], a
- ld a, [wCurrentMenuItem]
- ld [wChosenMenuItem], a
- xor a
- ld [hJoy7], a ; joypad state update flag
- ld hl, wd730
- res 6, [hl] ; turn on letter printing delay
- jp BankswitchBack
-.checkOtherKeys ; check B, SELECT, Up, and Down keys
- bit 1, a ; was the B button pressed?
- jp nz, ExitListMenu ; if so, exit the menu
- bit 2, a ; was the select button pressed?
- jp nz, HandleItemListSwapping ; if so, allow the player to swap menu entries
- ld b, a
- bit 7, b ; was Down pressed?
- ld hl, wListScrollOffset
- jr z, .upPressed
-.downPressed
- ld a, [hl]
- add 3
- ld b, a
- ld a, [wListCount]
- cp b ; will going down scroll past the Cancel button?
- jp c, DisplayListMenuIDLoop
- inc [hl] ; if not, go down
- jp DisplayListMenuIDLoop
-.upPressed
- ld a, [hl]
- and a
- jp z, DisplayListMenuIDLoop
- dec [hl]
- jp DisplayListMenuIDLoop
-
-DisplayChooseQuantityMenu::
-; text box dimensions/coordinates for just quantity
- coord hl, 15, 9
- lb bc, 1, 3 ; height and width
- ld a, [wListMenuID]
- cp PRICEDITEMLISTMENU
- jr nz, .drawTextBox
-; text box dimensions/coordinates for quantity and price
- coord hl, 7, 9
- lb bc, 1, 11 ; height and width
-.drawTextBox
- call TextBoxBorder
- coord hl, 16, 10
- ld a, [wListMenuID]
- cp PRICEDITEMLISTMENU
- jr nz, .printInitialQuantity
- coord hl, 8, 10
-.printInitialQuantity
- ld de, InitialQuantityText
- call PlaceString
- xor a
- ld [wItemQuantity], a ; initialize current quantity to 0
- jp .incrementQuantity
-.waitForKeyPressLoop
- call JoypadLowSensitivity
- ld a, [hJoyPressed] ; newly pressed buttons
- bit 0, a ; was the A button pressed?
- jp nz, .buttonAPressed
- bit 1, a ; was the B button pressed?
- jp nz, .buttonBPressed
- bit 6, a ; was Up pressed?
- jr nz, .incrementQuantity
- bit 7, a ; was Down pressed?
- jr nz, .decrementQuantity
- jr .waitForKeyPressLoop
-.incrementQuantity
- ld a, [wMaxItemQuantity]
- inc a
- ld b, a
- ld hl, wItemQuantity ; current quantity
- inc [hl]
- ld a, [hl]
- cp b
- jr nz, .handleNewQuantity
-; wrap to 1 if the player goes above the max quantity
- ld a, 1
- ld [hl], a
- jr .handleNewQuantity
-.decrementQuantity
- ld hl, wItemQuantity ; current quantity
- dec [hl]
- jr nz, .handleNewQuantity
-; wrap to the max quantity if the player goes below 1
- ld a, [wMaxItemQuantity]
- ld [hl], a
-.handleNewQuantity
- coord hl, 17, 10
- ld a, [wListMenuID]
- cp PRICEDITEMLISTMENU
- jr nz, .printQuantity
-.printPrice
- ld c, $03
- ld a, [wItemQuantity]
- ld b, a
- ld hl, hMoney ; total price
-; initialize total price to 0
- xor a
- ld [hli], a
- ld [hli], a
- ld [hl], a
-.addLoop ; loop to multiply the individual price by the quantity to get the total price
- ld de, hMoney + 2
- ld hl, hItemPrice + 2
- push bc
- predef AddBCDPredef ; add the individual price to the current sum
- pop bc
- dec b
- jr nz, .addLoop
- ld a, [hHalveItemPrices]
- and a ; should the price be halved (for selling items)?
- jr z, .skipHalvingPrice
- xor a
- ld [hDivideBCDDivisor], a
- ld [hDivideBCDDivisor + 1], a
- ld a, $02
- ld [hDivideBCDDivisor + 2], a
- predef DivideBCDPredef3 ; halves the price
-; store the halved price
- ld a, [hDivideBCDQuotient]
- ld [hMoney], a
- ld a, [hDivideBCDQuotient + 1]
- ld [hMoney + 1], a
- ld a, [hDivideBCDQuotient + 2]
- ld [hMoney + 2], a
-.skipHalvingPrice
- coord hl, 12, 10
- ld de, SpacesBetweenQuantityAndPriceText
- call PlaceString
- ld de, hMoney ; total price
- ld c, $a3
- call PrintBCDNumber
- coord hl, 9, 10
-.printQuantity
- ld de, wItemQuantity ; current quantity
- lb bc, LEADING_ZEROES | 1, 2 ; 1 byte, 2 digits
- call PrintNumber
- jp .waitForKeyPressLoop
-.buttonAPressed ; the player chose to make the transaction
- xor a
- ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
- ret
-.buttonBPressed ; the player chose to cancel the transaction
- xor a
- ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
- ld a, $ff
- ret
-
-InitialQuantityText::
- db "×01@"
-
-SpacesBetweenQuantityAndPriceText::
- db " @"
-
-ExitListMenu::
- ld a, [wCurrentMenuItem]
- ld [wChosenMenuItem], a
- ld a, CANCELLED_MENU
- ld [wMenuExitMethod], a
- ld [wMenuWatchMovingOutOfBounds], a
- xor a
- ld [hJoy7], a
- ld hl, wd730
- res 6, [hl]
- call BankswitchBack
- xor a
- ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
- scf
- ret
-
-PrintListMenuEntries::
- coord hl, 5, 3
- lb bc, 9, 14
- call ClearScreenArea
- ld a, [wListPointer]
- ld e, a
- ld a, [wListPointer + 1]
- ld d, a
- inc de ; de = beginning of list entries
- ld a, [wListScrollOffset]
- ld c, a
- ld a, [wListMenuID]
- cp ITEMLISTMENU
- ld a, c
- jr nz, .skipMultiplying
-; if it's an item menu
-; item entries are 2 bytes long, so multiply by 2
- add a
- sla c
-.skipMultiplying
- add e
- ld e, a
- jr nc, .noCarry
- inc d
-.noCarry
- coord hl, 6, 4 ; coordinates of first list entry name
- ld b, 4 ; print 4 names
-.loop
- ld a, b
- ld [wWhichPokemon], a
- ld a, [de]
- ld [wd11e], a
- cp $ff
- jp z, .printCancelMenuItem
- push bc
- push de
- push hl
- push hl
- push de
- ld a, [wListMenuID]
- and a
- jr z, .pokemonPCMenu
- cp MOVESLISTMENU
- jr z, .movesMenu
-.itemMenu
- call GetItemName
- jr .placeNameString
-.pokemonPCMenu
- push hl
- ld hl, wPartyCount
- ld a, [wListPointer]
- cp l ; is it a list of party pokemon or box pokemon?
- ld hl, wPartyMonNicks
- jr z, .getPokemonName
- ld hl, wBoxMonNicks ; box pokemon names
-.getPokemonName
- ld a, [wWhichPokemon]
- ld b, a
- ld a, 4
- sub b
- ld b, a
- ld a, [wListScrollOffset]
- add b
- call GetPartyMonName
- pop hl
- jr .placeNameString
-.movesMenu
- call GetMoveName
-.placeNameString
- call PlaceString
- pop de
- pop hl
- ld a, [wPrintItemPrices]
- and a ; should prices be printed?
- jr z, .skipPrintingItemPrice
-.printItemPrice
- push hl
- ld a, [de]
- ld de, ItemPrices
- ld [wcf91], a
- call GetItemPrice ; get price
- pop hl
- ld bc, SCREEN_WIDTH + 5 ; 1 row down and 5 columns right
- add hl, bc
- ld c, $a3 ; no leading zeroes, right-aligned, print currency symbol, 3 bytes
- call PrintBCDNumber
-.skipPrintingItemPrice
- ld a, [wListMenuID]
- and a
- jr nz, .skipPrintingPokemonLevel
-.printPokemonLevel
- ld a, [wd11e]
- push af
- push hl
- ld hl, wPartyCount
- ld a, [wListPointer]
- cp l ; is it a list of party pokemon or box pokemon?
- ld a, PLAYER_PARTY_DATA
- jr z, .next
- ld a, BOX_DATA
-.next
- ld [wMonDataLocation], a
- ld hl, wWhichPokemon
- ld a, [hl]
- ld b, a
- ld a, $04
- sub b
- ld b, a
- ld a, [wListScrollOffset]
- add b
- ld [hl], a
- call LoadMonData
- ld a, [wMonDataLocation]
- and a ; is it a list of party pokemon or box pokemon?
- jr z, .skipCopyingLevel
-.copyLevel
- ld a, [wLoadedMonBoxLevel]
- ld [wLoadedMonLevel], a
-.skipCopyingLevel
- pop hl
- ld bc, $001c
- add hl, bc
- call PrintLevel
- pop af
- ld [wd11e], a
-.skipPrintingPokemonLevel
- pop hl
- pop de
- inc de
- ld a, [wListMenuID]
- cp ITEMLISTMENU
- jr nz, .nextListEntry
-.printItemQuantity
- ld a, [wd11e]
- ld [wcf91], a
- call IsKeyItem ; check if item is unsellable
- ld a, [wIsKeyItem]
- and a ; is the item unsellable?
- jr nz, .skipPrintingItemQuantity ; if so, don't print the quantity
- push hl
- ld bc, SCREEN_WIDTH + 8 ; 1 row down and 8 columns right
- add hl, bc
- ld a, "×"
- ld [hli], a
- ld a, [wd11e]
- push af
- ld a, [de]
- ld [wMaxItemQuantity], a
- push de
- ld de, wd11e
- ld [de], a
- lb bc, 1, 2
- call PrintNumber
- pop de
- pop af
- ld [wd11e], a
- pop hl
-.skipPrintingItemQuantity
- inc de
- pop bc
- inc c
- push bc
- inc c
- ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
- and a ; is an item being swapped?
- jr z, .nextListEntry
- add a
- cp c ; is it this item?
- jr nz, .nextListEntry
- dec hl
- ld a, $ec ; unfilled right arrow menu cursor to indicate an item being swapped
- ld [hli], a
-.nextListEntry
- ld bc, 2 * SCREEN_WIDTH ; 2 rows
- add hl, bc
- pop bc
- inc c
- dec b
- jp nz, .loop
- ld bc, -8
- add hl, bc
- ld a, "▼"
- ld [hl], a
- ret
-.printCancelMenuItem
- ld de, ListMenuCancelText
- jp PlaceString
-
-ListMenuCancelText::
- db "CANCEL@"
-
-GetMonName::
- push hl
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, BANK(MonsterNames)
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- ld a, [wd11e]
- dec a
- ld hl, MonsterNames
- ld c, 10
- ld b, 0
- call AddNTimes
- ld de, wcd6d
- push de
- ld bc, 10
- call CopyData
- ld hl, wcd6d + 10
- ld [hl], "@"
- pop de
- pop af
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- pop hl
- ret
-
-GetItemName::
-; given an item ID at [wd11e], store the name of the item into a string
-; starting at wcd6d
- push hl
- push bc
- ld a, [wd11e]
- cp HM_01 ; is this a TM/HM?
- jr nc, .Machine
-
- ld [wd0b5], a
- ld a, ITEM_NAME
- ld [wNameListType], a
- ld a, BANK(ItemNames)
- ld [wPredefBank], a
- call GetName
- jr .Finish
-
-.Machine
- call GetMachineName
-.Finish
- ld de, wcd6d ; pointer to where item name is stored in RAM
- pop bc
- pop hl
- ret
-
-GetMachineName::
-; copies the name of the TM/HM in [wd11e] to wcd6d
- push hl
- push de
- push bc
- ld a, [wd11e]
- push af
- cp TM_01 ; is this a TM? [not HM]
- jr nc, .WriteTM
-; if HM, then write "HM" and add 5 to the item ID, so we can reuse the
-; TM printing code
- add 5
- ld [wd11e], a
- ld hl, HiddenPrefix ; points to "HM"
- ld bc, 2
- jr .WriteMachinePrefix
-.WriteTM
- ld hl, TechnicalPrefix ; points to "TM"
- ld bc, 2
-.WriteMachinePrefix
- ld de, wcd6d
- call CopyData
-
-; now get the machine number and convert it to text
- ld a, [wd11e]
- sub TM_01 - 1
- ld b, "0"
-.FirstDigit
- sub 10
- jr c, .SecondDigit
- inc b
- jr .FirstDigit
-.SecondDigit
- add 10
- push af
- ld a, b
- ld [de], a
- inc de
- pop af
- ld b, "0"
- add b
- ld [de], a
- inc de
- ld a, "@"
- ld [de], a
- pop af
- ld [wd11e], a
- pop bc
- pop de
- pop hl
- ret
-
-TechnicalPrefix::
- db "TM"
-HiddenPrefix::
- db "HM"
-
-; sets carry if item is HM, clears carry if item is not HM
-; Input: a = item ID
-IsItemHM::
- cp HM_01
- jr c, .notHM
- cp TM_01
- ret
-.notHM
- and a
- ret
-
-; sets carry if move is an HM, clears carry if move is not an HM
-; Input: a = move ID
-IsMoveHM::
- ld hl, HMMoves
- ld de, 1
- jp IsInArray
-
-HMMoves::
- db CUT, FLY, SURF, STRENGTH, FLASH
- db $ff ; terminator
-
-GetMoveName::
- push hl
- ld a, MOVE_NAME
- ld [wNameListType], a
- ld a, [wd11e]
- ld [wd0b5], a
- ld a, BANK(MoveNames)
- ld [wPredefBank], a
- call GetName
- ld de, wcd6d ; pointer to where move name is stored in RAM
- pop hl
- ret
-
-; reloads text box tile patterns, current map view, and tileset tile patterns
-ReloadMapData::
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wCurMap]
- call SwitchToMapRomBank
- call DisableLCD
- call LoadTextBoxTilePatterns
- call LoadCurrentMapView
- call LoadTilesetTilePatternData
- call EnableLCD
- pop af
- call BankswitchCommon
- ret
-
-; reloads tileset tile patterns
-ReloadTilesetTilePatterns::
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wCurMap]
- call SwitchToMapRomBank
- call DisableLCD
- call LoadTilesetTilePatternData
- call EnableLCD
- pop af
- call BankswitchCommon
- ret
-
-; shows the town map and lets the player choose a destination to fly to
-ChooseFlyDestination::
- ld hl, wd72e
- res 4, [hl]
- jpba LoadTownMap_Fly
-
-PrinterSerial::
- homecall PrinterSerial_
- ret
-
-SerialFunction::
- ld a, [wPrinterConnectionOpen]
- bit 0, a
- ret z
- ld a, [wPrinterOpcode]
- and a
- ret nz
- ld hl, wOverworldMap + 650
- inc [hl]
- ld a, [hl]
- cp $6
- ret c
- xor a
- ld [hl], a
- ld a, $0c
- ld [wPrinterOpcode], a
- ld a, $88
- ld [rSB], a
- ld a, $1
- ld [rSC], a
- ld a, START_TRANSFER_INTERNAL_CLOCK
- ld [rSC], a
- ret
-
-; causes the text box to close without waiting for a button press after displaying text
-DisableWaitingAfterTextDisplay::
- ld a, $01
- ld [wDoNotWaitForButtonPressAfterDisplayingText], a
- ret
-
-; uses an item
-; UseItem is used with dummy items to perform certain other functions as well
-; INPUT:
-; [wcf91] = item ID
-; OUTPUT:
-; [wActionResultOrTookBattleTurn] = success
-; 00: unsuccessful
-; 01: successful
-; 02: not able to be used right now, no extra menu displayed (only certain items use this)
-UseItem::
- jpba UseItem_
-
-; confirms the item toss and then tosses the item
-; INPUT:
-; hl = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wcf91] = item ID
-; [wWhichPokemon] = index of item within inventory
-; [wItemQuantity] = quantity to toss
-; OUTPUT:
-; clears carry flag if the item is tossed, sets carry flag if not
-TossItem::
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, BANK(TossItem_)
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- call TossItem_
- pop de
- ld a, d
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- ret
-
-; checks if an item is a key item
-; INPUT:
-; [wcf91] = item ID
-; OUTPUT:
-; [wIsKeyItem] = result
-; 00: item is not key item
-; 01: item is key item
-IsKeyItem::
- push hl
- push de
- push bc
- callba IsKeyItem_
- pop bc
- pop de
- pop hl
- ret
-
-; function to draw various text boxes
-; INPUT:
-; [wTextBoxID] = text box ID
-; b, c = y, x cursor position (TWO_OPTION_MENU only)
-DisplayTextBoxID::
- homecall_sf DisplayTextBoxID_
- ret
+ text_far _PokemonText
+ text_end
+
+INCLUDE "home/text_script.asm"
+INCLUDE "home/start_menu.asm"
+INCLUDE "home/count_set_bits.asm"
+INCLUDE "home/inventory.asm"
+INCLUDE "home/list_menu.asm"
+INCLUDE "home/names.asm"
+INCLUDE "home/reload_tiles.asm"
+INCLUDE "home/item.asm"
+INCLUDE "home/textbox.asm"
UpdateGBCPal_BGP::
push af
- ld a, [hGBC]
+ ldh a, [hGBC]
and a
jr z, .notGBC
push bc
push de
push hl
- ld a, [rBGP]
+ ldh a, [rBGP]
ld b, a
ld a, [wLastBGP]
cp b
jr z, .noChangeInBGP
- callba _UpdateGBCPal_BGP
+ farcall _UpdateGBCPal_BGP
.noChangeInBGP
pop hl
pop de
@@ -2231,13 +137,13 @@ UpdateGBCPal_BGP::
UpdateGBCPal_OBP0::
push af
- ld a, [hGBC]
+ ldh a, [hGBC]
and a
jr z, .notGBC
push bc
push de
push hl
- ld a, [rOBP0]
+ ldh a, [rOBP0]
ld b, a
ld a, [wLastOBP0]
cp b
@@ -2256,13 +162,13 @@ UpdateGBCPal_OBP0::
UpdateGBCPal_OBP1::
push af
- ld a, [hGBC]
+ ldh a, [hGBC]
and a
jr z, .notGBC
push bc
push de
push hl
- ld a, [rOBP1]
+ ldh a, [rOBP1]
ld b, a
ld a, [wLastOBP1]
cp b
@@ -2280,7 +186,7 @@ UpdateGBCPal_OBP1::
ret
Func_3082::
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
push af
call FadeOutAudio
callbs Music_DoLowHealthAlarm
@@ -2289,2064 +195,32 @@ Func_3082::
call BankswitchCommon
ret
-; not zero if an NPC movement script is running, the player character is
-; automatically stepping down from a door, or joypad states are being simulated
-IsPlayerCharacterBeingControlledByGame::
- ld a, [wNPCMovementScriptPointerTableNum]
- and a
- ret nz
- ld a, [wd736]
- bit 1, a ; currently stepping down from door bit
- ret nz
- ld a, [wd730]
- and $80
- ret
-
-RunNPCMovementScript::
- ld hl, wd736
- bit 0, [hl]
- res 0, [hl]
- jr nz, .playerStepOutFromDoor
- ld a, [wNPCMovementScriptPointerTableNum]
- and a
- ret z
- dec a
- add a
- ld d, 0
- ld e, a
- ld hl, .NPCMovementScriptPointerTables
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wNPCMovementScriptBank]
- call BankswitchCommon
- ld a, [wNPCMovementScriptFunctionNum]
- call CallFunctionInTable
- pop af
- call BankswitchCommon
- ret
-
-.NPCMovementScriptPointerTables
- dw PalletMovementScriptPointerTable
- dw PewterMuseumGuyMovementScriptPointerTable
- dw PewterGymGuyMovementScriptPointerTable
-.playerStepOutFromDoor
- jpba PlayerStepOutFromDoor
-
-EndNPCMovementScript::
- jpba _EndNPCMovementScript
-
-EmptyFunc2::
- ret
-
-; stores hl in [wTrainerHeaderPtr]
-StoreTrainerHeaderPointer::
- ld a, h
- ld [wTrainerHeaderPtr], a
- ld a, l
- ld [wTrainerHeaderPtr + 1], a
- ret
-
-; executes the current map script from the function pointer array provided in hl.
-; a: map script index to execute (unless overridden by [wd733] bit 4)
-ExecuteCurMapScriptInTable::
- push af
- push de
- call StoreTrainerHeaderPointer
- pop hl
- pop af
- push hl
- ld hl, wFlags_D733
- bit 4, [hl]
- res 4, [hl]
- jr z, .useProvidedIndex ; test if map script index was overridden manually
- ld a, [wCurMapScript]
-.useProvidedIndex
- pop hl
- ld [wCurMapScript], a
- call CallFunctionInTable
- ld a, [wCurMapScript]
- ret
-
-LoadGymLeaderAndCityName::
- push de
- ld de, wGymCityName
- ld bc, $11
- call CopyData ; load city name
- pop hl
- ld de, wGymLeaderName
- ld bc, NAME_LENGTH
- jp CopyData ; load gym leader name
-
-; reads specific information from trainer header (pointed to at wTrainerHeaderPtr)
-; a: offset in header data
-; 0 -> flag's bit (into wTrainerHeaderFlagBit)
-; 2 -> flag's byte ptr (into hl)
-; 4 -> before battle text (into hl)
-; 6 -> after battle text (into hl)
-; 8 -> end battle text (into hl)
-ReadTrainerHeaderInfo::
- push de
- push af
- ld d, $0
- ld e, a
- ld hl, wTrainerHeaderPtr
- ld a, [hli]
- ld l, [hl]
- ld h, a
- add hl, de
- pop af
- and a
- jr nz, .nonZeroOffset
- ld a, [hl]
- ld [wTrainerHeaderFlagBit], a ; store flag's bit
- jr .done
-.nonZeroOffset
- cp $2
- jr z, .readPointer ; read flag's byte ptr
- cp $4
- jr z, .readPointer ; read before battle text
- cp $6
- jr z, .readPointer ; read after battle text
- cp $8
- jr z, .readPointer ; read end battle text
- cp $a
- jr nz, .done
- ld a, [hli] ; read end battle text (2) but override the result afterwards (XXX why, bug?)
- ld d, [hl]
- ld e, a
- jr .done
-.readPointer
- ld a, [hli]
- ld h, [hl]
- ld l, a
-.done
- pop de
- ret
-
-TrainerFlagAction::
- predef_jump FlagActionPredef
-
-TalkToTrainer::
- call StoreTrainerHeaderPointer
- xor a
- call ReadTrainerHeaderInfo ; read flag's bit
- ld a, $2
- call ReadTrainerHeaderInfo ; read flag's byte ptr
- ld a, [wTrainerHeaderFlagBit]
- ld c, a
- ld b, FLAG_TEST
- call TrainerFlagAction ; read trainer's flag
- ld a, c
- and a
- jr z, .trainerNotYetFought ; test trainer's flag
- ld a, $6
- call ReadTrainerHeaderInfo ; print after battle text
- jp PrintText
-.trainerNotYetFought
- ld a, $4
- call ReadTrainerHeaderInfo ; print before battle text
- call PrintText
- ld a, $a
- call ReadTrainerHeaderInfo ; (?) does nothing apparently (maybe bug in ReadTrainerHeaderInfo)
- push de
- ld a, $8
- call ReadTrainerHeaderInfo ; read end battle text
- pop de
- call SaveEndBattleTextPointers
- ld hl, wFlags_D733
- set 4, [hl] ; activate map script index override (index is set below)
- ld hl, wFlags_0xcd60
- bit 0, [hl] ; test if player is already engaging the trainer (because the trainer saw the player)
- ret nz
-; if the player talked to the trainer of his own volition
- call EngageMapTrainer
- ld hl, wCurMapScript
- inc [hl] ; increment map script index before StartTrainerBattle increments it again (next script function is usually EndTrainerBattle)
- jp StartTrainerBattle
-
-; checks if any trainers are seeing the player and wanting to fight
-CheckFightingMapTrainers::
- call CheckForEngagingTrainers
- ld a, [wSpriteIndex]
- cp $ff
- jr nz, .trainerEngaging
- xor a
- ld [wSpriteIndex], a
- ld [wTrainerHeaderFlagBit], a
- ret
-.trainerEngaging
- ld hl, wFlags_D733
- set 3, [hl]
- ld [wEmotionBubbleSpriteIndex], a
- xor a ; EXCLAMATION_BUBBLE
- ld [wWhichEmotionBubble], a
- predef EmotionBubble
- ld a, D_RIGHT | D_LEFT | D_UP | D_DOWN
- ld [wJoyIgnore], a
- xor a
- ld [hJoyHeld], a
- call TrainerWalkUpToPlayer_Bank0
- ld hl, wCurMapScript
- inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle)
- ret
-
-; display the before battle text after the enemy trainer has walked up to the player's sprite
-DisplayEnemyTrainerTextAndStartBattle::
- ld a, [wd730]
- and $1
- ret nz ; return if the enemy trainer hasn't finished walking to the player's sprite
- ld [wJoyIgnore], a
- ld a, [wSpriteIndex]
- ld [hSpriteIndexOrTextID], a
- call DisplayTextID
- ; fall through
-
-StartTrainerBattle::
- xor a
- ld [wJoyIgnore], a
- call InitBattleEnemyParameters
- ld hl, wd72d
- set 6, [hl]
- set 7, [hl]
- ld hl, wd72e
- set 1, [hl]
- ld hl, wCurMapScript
- inc [hl] ; increment map script index (next script function is usually EndTrainerBattle)
- ret
-
-EndTrainerBattle::
- ld hl, wCurrentMapScriptFlags
- set 5, [hl]
- set 6, [hl]
- ld hl, wd72d
- res 7, [hl]
- ld hl, wFlags_0xcd60
- res 0, [hl] ; player is no longer engaged by any trainer
- ld a, [wIsInBattle]
- cp $ff
- jp z, ResetButtonPressedAndMapScript
- ld a, $2
- call ReadTrainerHeaderInfo
- ld a, [wTrainerHeaderFlagBit]
- ld c, a
- ld b, FLAG_SET
- call TrainerFlagAction ; flag trainer as fought
- ld a, [wEnemyMonOrTrainerClass]
- cp OPP_ID_OFFSET
- jr nc, .skipRemoveSprite ; test if trainer was fought (in that case skip removing the corresponding sprite)
- ld hl, wMissableObjectList
- ld de, $2
- ld a, [wSpriteIndex]
- call IsInArray ; search for sprite ID
- inc hl
- ld a, [hl]
- ld [wMissableObjectIndex], a ; load corresponding missable object index and remove it
- predef HideObject
-.skipRemoveSprite
- ld hl, wd730
- bit 4, [hl]
- res 4, [hl]
- ret nz
-
-ResetButtonPressedAndMapScript::
- xor a
- ld [wJoyIgnore], a
- ld [hJoyHeld], a
- ld [hJoyPressed], a
- ld [hJoyReleased], a
- ld [wCurMapScript], a ; reset battle status
- ret
-
-; calls TrainerWalkUpToPlayer
-TrainerWalkUpToPlayer_Bank0::
- jpba TrainerWalkUpToPlayer
-
-; sets opponent type and mon set/lvl based on the engaging trainer data
-InitBattleEnemyParameters::
- ld a, [wEngagedTrainerClass]
- ld [wCurOpponent], a
- ld [wEnemyMonOrTrainerClass], a
- cp OPP_ID_OFFSET
- ld a, [wEngagedTrainerSet]
- jr c, .noTrainer
- ld [wTrainerNo], a
- ret
-.noTrainer
- ld [wCurEnemyLVL], a
- ret
-
-GetSpritePosition1::
- ld hl, _GetSpritePosition1
- jr SpritePositionBankswitch
-
-GetSpritePosition2::
- ld hl, _GetSpritePosition2
- jr SpritePositionBankswitch
-
-SetSpritePosition1::
- ld hl, _SetSpritePosition1
- jr SpritePositionBankswitch
-
-SetSpritePosition2::
- ld hl, _SetSpritePosition2
-SpritePositionBankswitch::
- ld b, BANK(_GetSpritePosition1) ; BANK(_GetSpritePosition2), BANK(_SetSpritePosition1), BANK(_SetSpritePosition2)
- jp Bankswitch ; indirect jump to one of the four functions
-
-CheckForEngagingTrainers::
- xor a
- call ReadTrainerHeaderInfo ; read trainer flag's bit (unused)
- ld d, h ; store trainer header address in de
- ld e, l
-.trainerLoop
- call StoreTrainerHeaderPointer ; set trainer header pointer to current trainer
- ld a, [de]
- ld [wSpriteIndex], a ; store trainer flag's bit
- ld [wTrainerHeaderFlagBit], a
- cp $ff
- ret z
- ld a, $2
- call ReadTrainerHeaderInfo ; read trainer flag's byte ptr
- ld b, FLAG_TEST
- ld a, [wTrainerHeaderFlagBit]
- ld c, a
- call TrainerFlagAction ; read trainer flag
- ld a, c
- and a ; has the trainer already been defeated?
- jr nz, .continue
- push hl
- push de
- push hl
- xor a
- call ReadTrainerHeaderInfo ; get trainer header pointer
- inc hl
- ld a, [hl] ; read trainer engage distance
- pop hl
- ld [wTrainerEngageDistance], a
- ld a, [wSpriteIndex]
- swap a
- ld [wTrainerSpriteOffset], a
- predef TrainerEngage
- pop de
- pop hl
- ld a, [wTrainerSpriteOffset]
- and a
- ret nz ; break if the trainer is engaging
-.continue
- ld hl, $c
- add hl, de
- ld d, h
- ld e, l
- jr .trainerLoop
-
-; hl = text if the player wins
-; de = text if the player loses
-SaveEndBattleTextPointers::
- ld a, [H_LOADEDROMBANK]
- ld [wEndBattleTextRomBank], a
- ld a, h
- ld [wEndBattleWinTextPointer], a
- ld a, l
- ld [wEndBattleWinTextPointer + 1], a
- ld a, d
- ld [wEndBattleLoseTextPointer], a
- ld a, e
- ld [wEndBattleLoseTextPointer + 1], a
- ret
-
-; loads data of some trainer on the current map and plays pre-battle music
-; [wSpriteIndex]: sprite ID of trainer who is engaged
-EngageMapTrainer::
- ld hl, wMapSpriteExtraData
- ld d, $0
- ld a, [wSpriteIndex]
- dec a
- add a
- ld e, a
- add hl, de ; seek to engaged trainer data
- ld a, [hli] ; load trainer class
- ld [wEngagedTrainerClass], a
- ld a, [hl] ; load trainer mon set
- ld [wEngagedTrainerSet], a
- jp PlayTrainerMusic
-
-PrintEndBattleText::
- push hl
- ld hl, wd72d
- bit 7, [hl]
- res 7, [hl]
- pop hl
- ret z
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wEndBattleTextRomBank]
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- push hl
- callba SaveTrainerName
- ld hl, TrainerEndBattleText
- call PrintText
- pop hl
- pop af
- ld [H_LOADEDROMBANK], a
- ld [MBC1RomBank], a
- callba FreezeEnemyTrainerSprite
- jp WaitForSoundToFinish
-
-GetSavedEndBattleTextPointer::
- ld a, [wBattleResult]
- and a
-; won battle
- jr nz, .lostBattle
- ld a, [wEndBattleWinTextPointer]
- ld h, a
- ld a, [wEndBattleWinTextPointer + 1]
- ld l, a
- ret
-.lostBattle
- ld a, [wEndBattleLoseTextPointer]
- ld h, a
- ld a, [wEndBattleLoseTextPointer + 1]
- ld l, a
- ret
-
-TrainerEndBattleText::
- TX_FAR _TrainerNameText
- TX_ASM
- call GetSavedEndBattleTextPointer
- call TextCommandProcessor
- jp TextScriptEnd
-
-PlayTrainerMusic::
- ld a, [wEngagedTrainerClass]
- cp OPP_SONY1
- ret z
- cp OPP_SONY2
- ret z
- cp OPP_SONY3
- ret z
- ld a, [wGymLeaderNo]
- and a
- ret nz
- xor a
- ld [wAudioFadeOutControl], a
- call StopAllMusic ; stop music
- ld a, BANK(Music_MeetEvilTrainer)
- ld [wAudioROMBank], a
- ld [wAudioSavedROMBank], a
- ld a, [wEngagedTrainerClass]
- ld b, a
- ld hl, EvilTrainerList
-.evilTrainerListLoop
- ld a, [hli]
- cp $ff
- jr z, .noEvilTrainer
- cp b
- jr nz, .evilTrainerListLoop
- ld a, MUSIC_MEET_EVIL_TRAINER
- jr .PlaySound
-.noEvilTrainer
- ld hl, FemaleTrainerList
-.femaleTrainerListLoop
- ld a, [hli]
- cp $ff
- jr z, .maleTrainer
- cp b
- jr nz, .femaleTrainerListLoop
- ld a, MUSIC_MEET_FEMALE_TRAINER
- jr .PlaySound
-.maleTrainer
- ld a, MUSIC_MEET_MALE_TRAINER
-.PlaySound
- ld [wNewSoundID], a
- jp PlaySound
-
-INCLUDE "data/trainer_types.asm"
-
-; checks if the player's coordinates match an arrow movement tile's coordinates
-; and if so, decodes the RLE movement data
-; b = player Y
-; c = player X
-DecodeArrowMovementRLE::
- ld a, [hli]
- cp $ff
- ret z ; no match in the list
- cp b
- jr nz, .nextArrowMovementTileEntry1
- ld a, [hli]
- cp c
- jr nz, .nextArrowMovementTileEntry2
- ld a, [hli]
- ld d, [hl]
- ld e, a
- ld hl, wSimulatedJoypadStatesEnd
- call DecodeRLEList
- dec a
- ld [wSimulatedJoypadStatesIndex], a
- ret
-.nextArrowMovementTileEntry1
- inc hl
-.nextArrowMovementTileEntry2
- inc hl
- inc hl
- jr DecodeArrowMovementRLE
-
-FuncTX_ItemStoragePC::
- call SaveScreenTilesToBuffer2
- ld b, BANK(PlayerPC)
- ld hl, PlayerPC
- jr bankswitchAndContinue
-
-FuncTX_BillsPC::
- call SaveScreenTilesToBuffer2
- ld b, BANK(BillsPC_)
- ld hl, BillsPC_
- jr bankswitchAndContinue
-
-FuncTX_GameCornerPrizeMenu::
-; XXX find a better name for this function
-; special_F7
- ld b, BANK(CeladonPrizeMenu)
- ld hl, CeladonPrizeMenu
-bankswitchAndContinue::
- call Bankswitch
- jp HoldTextDisplayOpen ; continue to main text-engine function
-
-FuncTX_PokemonCenterPC::
- ld b, BANK(ActivatePC)
- ld hl, ActivatePC
- jr bankswitchAndContinue
-
-StartSimulatingJoypadStates::
- xor a
- ld [wOverrideSimulatedJoypadStatesMask], a
- ld [wSpriteStateData2 + $06], a ; player's sprite movement byte 1
- ld hl, wd730
- set 7, [hl]
- ret
-
-IsItemInBag::
-; given an item_id in b
-; set zero flag if item isn't in player's bag
-; else reset zero flag
-; related to Pokémon Tower and ghosts
- predef GetQuantityOfItemInBag
- ld a, b
- and a
- ret
-
-IsSurfingPikachuInParty::
-; set bit 6 of wd472 if true
-; also calls Func_3467, which is a bankswitch to IsStarterPikachuInOurParty
- ld a, [wd472]
- and $3f
- ld [wd472], a
- ld hl, wPartyMon1
- ld c, PARTY_LENGTH
- ld b, SURF
-.loop
- ld a, [hl]
- cp PIKACHU
- jr nz, .notPikachu
- push hl
- ld de, $8
- add hl, de
- ld a, [hli]
- cp b ; does pikachu have surf as one of its moves
- jr z, .hasSurf
- ld a, [hli]
- cp b
- jr z, .hasSurf
- ld a, [hli]
- cp b
- jr z, .hasSurf
- ld a, [hli]
- cp b
- jr nz, .noSurf
-.hasSurf
- ld a, [wd472]
- set 6, a
- ld [wd472], a
-.noSurf
- pop hl
-.notPikachu
- ld de, wPartyMon2 - wPartyMon1
- add hl, de
- dec c
- jr nz, .loop
- call Func_3467
- ret
-
-Func_3467::
- push hl
- push bc
- callab IsStarterPikachuInOurParty
- pop bc
- pop hl
- ret nc
- ld a, [wd472]
- set 7, a
- ld [wd472], a
- ret
-
-DisplayPokedex::
- ld [wd11e], a
- jpba _DisplayPokedex
-
-SetSpriteFacingDirectionAndDelay::
- call SetSpriteFacingDirection
- ld c, 6
- jp DelayFrames
-
-SetSpriteFacingDirection::
- ld a, $9
- ld [H_SPRITEDATAOFFSET], a
- call GetPointerWithinSpriteStateData1
- ld a, [hSpriteFacingDirection]
- ld [hl], a
- ret
-
-SetSpriteImageIndexAfterSettingFacingDirection::
- ld de, -7
- add hl, de
- ld [hl], a
- ret
-
-SpriteFunc_34a1::
- ld a, [H_SPRITEINDEX]
- swap a
- add $e
- ld l, a
- ld h, $c2
- ld c, [hl]
- dec c
- swap c
- ld a, [$ff8d]
- add c
- ld c, a
- ld a, [$ff8c]
- swap a
- add $2
- ld l, a
- dec h
- ld [hl], c
- ret
-
-; tests if the player's coordinates are in a specified array
-; INPUT:
-; hl = address of array
-; OUTPUT:
-; [wCoordIndex] = if there is match, the matching array index
-; sets carry if the coordinates are in the array, clears carry if not
-ArePlayerCoordsInArray::
- ld a, [wYCoord]
- ld b, a
- ld a, [wXCoord]
- ld c, a
- ; fallthrough
-
-CheckCoords::
- xor a
- ld [wCoordIndex], a
-.loop
- ld a, [hli]
- cp $ff ; reached terminator?
- jr z, .notInArray
- push hl
- ld hl, wCoordIndex
- inc [hl]
- pop hl
-.compareYCoord
- cp b
- jr z, .compareXCoord
- inc hl
- jr .loop
-.compareXCoord
- ld a, [hli]
- cp c
- jr nz, .loop
-.inArray
- scf
- ret
-.notInArray
- and a
- ret
-
-; tests if a boulder's coordinates are in a specified array
-; INPUT:
-; hl = address of array
-; [H_SPRITEINDEX] = index of boulder sprite
-; OUTPUT:
-; [wCoordIndex] = if there is match, the matching array index
-; sets carry if the coordinates are in the array, clears carry if not
-CheckBoulderCoords::
- push hl
- ld hl, wSpriteStateData2 + $04
- ld a, [H_SPRITEINDEX]
- swap a
- ld d, $0
- ld e, a
- add hl, de
- ld a, [hli]
- sub $4 ; because sprite coordinates are offset by 4
- ld b, a
- ld a, [hl]
- sub $4 ; because sprite coordinates are offset by 4
- ld c, a
- pop hl
- jp CheckCoords
-
-GetPointerWithinSpriteStateData1::
- ld h, $c1
- jr _GetPointerWithinSpriteStateData
-
-GetPointerWithinSpriteStateData2::
- ld h, $c2
-
-_GetPointerWithinSpriteStateData:
- ld a, [H_SPRITEDATAOFFSET]
- ld b, a
- ld a, [H_SPRITEINDEX]
- swap a
- add b
- ld l, a
- ret
-
-; decodes a $ff-terminated RLEncoded list
-; each entry is a pair of bytes <byte value> <repetitions>
-; the final $ff will be replicated in the output list and a contains the number of bytes written
-; de: input list
-; hl: output list
-DecodeRLEList::
- xor a
- ld [wRLEByteCount], a ; count written bytes here
-.listLoop
- ld a, [de]
- cp $ff
- jr z, .endOfList
- ld [hRLEByteValue], a ; store byte value to be written
- inc de
- ld a, [de]
- ld b, $0
- ld c, a ; number of bytes to be written
- ld a, [wRLEByteCount]
- add c
- ld [wRLEByteCount], a ; update total number of written bytes
- ld a, [hRLEByteValue]
- call FillMemory ; write a c-times to output
- inc de
- jr .listLoop
-.endOfList
- ld a, $ff
- ld [hl], a ; write final $ff
- ld a, [wRLEByteCount]
- inc a ; include sentinel in counting
- ret
-
-; sets movement byte 1 for sprite [H_SPRITEINDEX] to $FE and byte 2 to [hSpriteMovementByte2]
-SetSpriteMovementBytesToFE::
- push hl
- call GetSpriteMovementByte1Pointer
- ld [hl], $fe
- call GetSpriteMovementByte2Pointer
- ld a, [hSpriteMovementByte2]
- ld [hl], a
- pop hl
- ret
-
-; sets both movement bytes for sprite [H_SPRITEINDEX] to $FF
-SetSpriteMovementBytesToFF::
- push hl
- call GetSpriteMovementByte1Pointer
- ld [hl], $FF
- call GetSpriteMovementByte2Pointer
- ld [hl], $FF ; prevent person from walking?
- pop hl
- ret
-
-; returns the sprite movement byte 1 pointer for sprite [H_SPRITEINDEX] in hl
-GetSpriteMovementByte1Pointer::
- ld h, $C2
- ld a, [H_SPRITEINDEX]
- swap a
- add 6
- ld l, a
- ret
-
-; returns the sprite movement byte 2 pointer for sprite [H_SPRITEINDEX] in hl
-GetSpriteMovementByte2Pointer::
- push de
- ld hl, wMapSpriteData
- ld a, [H_SPRITEINDEX]
- dec a
- add a
- ld e, a
- ld d, 0
- add hl, de
- pop de
- ret
-
-GetTrainerInformation::
- call GetTrainerName
- ld a, [wLinkState]
- and a
- jr nz, .linkBattle
- ld a, BANK(TrainerPicAndMoneyPointers)
- call BankswitchHome
- ld a, [wTrainerClass]
- dec a
- ld hl, TrainerPicAndMoneyPointers
- ld bc, $5
- call AddNTimes
- ld de, wTrainerPicPointer
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- ld de, wTrainerBaseMoney
- ld a, [hli]
- ld [de], a
- inc de
- ld a, [hli]
- ld [de], a
- call IsFightingJessieJames
- jp BankswitchBack
-.linkBattle
- ld hl, wTrainerPicPointer
- ld de, RedPicFront
- ld [hl], e
- inc hl
- ld [hl], d
- ret
-
-IsFightingJessieJames::
- ld a, [wTrainerClass]
- cp ROCKET
- ret nz
- ld a, [wTrainerNo]
- cp $2a
- ret c
- ld de, JessieJamesPic
- cp $2e
- jr c, .dummy
- ld de, JessieJamesPic ; possibly meant to add another pic
-.dummy
- ld hl, wTrainerPicPointer
- ld a, e
- ld [hli], a
- ld [hl], d
- ret
-
-GetTrainerName::
- jpba GetTrainerName_
-
-HasEnoughMoney::
-; Check if the player has at least as much
-; money as the 3-byte BCD value at hMoney.
- ld de, wPlayerMoney
- ld hl, hMoney
- ld c, 3
- jp StringCmp
-
-HasEnoughCoins::
-; Check if the player has at least as many
-; coins as the 2-byte BCD value at hCoins.
- ld de, wPlayerCoins
- ld hl, hCoins
- ld c, 2
- jp StringCmp
-
-
-BankswitchHome::
-; switches to bank # in a
-; Only use this when in the home bank!
- ld [wBankswitchHomeTemp], a
- ld a, [H_LOADEDROMBANK]
- ld [wBankswitchHomeSavedROMBank], a
- ld a, [wBankswitchHomeTemp]
- call BankswitchCommon
- ret
-
-BankswitchBack::
-; returns from BankswitchHome
- ld a, [wBankswitchHomeSavedROMBank]
- call BankswitchCommon
- ret
-
-; displays yes/no choice
-; yes -> set carry
-YesNoChoice::
- call SaveScreenTilesToBuffer1
- call InitYesNoTextBoxParameters
- jr DisplayYesNoChoice
-
-Func_35f7::
- ld a, TWO_OPTION_MENU
- ld [wTextBoxID], a
- call InitYesNoTextBoxParameters
- jp DisplayTextBoxID
-
-InitYesNoTextBoxParameters::
- xor a ; YES_NO_MENU
- ld [wTwoOptionMenuID], a
- coord hl, 14, 7
- ld bc, $80f
- ret
-
-YesNoChoicePokeCenter::
- call SaveScreenTilesToBuffer1
- ld a, HEAL_CANCEL_MENU
- ld [wTwoOptionMenuID], a
- coord hl, 11, 6
- lb bc, 8, 12
- jr DisplayYesNoChoice
-
-WideYesNoChoice:: ; unused
- call SaveScreenTilesToBuffer1
- ld a, WIDE_YES_NO_MENU
- ld [wTwoOptionMenuID], a
- coord hl, 12, 7
- lb bc, 8, 13
-
-DisplayYesNoChoice::
- ld a, TWO_OPTION_MENU
- ld [wTextBoxID], a
- call DisplayTextBoxID
- jp LoadScreenTilesFromBuffer1
-
-; calculates the difference |a-b|, setting carry flag if a<b
-CalcDifference::
- sub b
- ret nc
- cpl
- add $1
- scf
- ret
-
-MoveSprite::
-; move the sprite [H_SPRITEINDEX] with the movement pointed to by de
-; actually only copies the movement data to wNPCMovementDirections for later
- call SetSpriteMovementBytesToFF
-MoveSprite_::
- push hl
- push bc
- call GetSpriteMovementByte1Pointer
- xor a
- ld [hl], a
- ld hl, wNPCMovementDirections
- ld c, 0
-
-.loop
- ld a, [de]
- ld [hli], a
- inc de
- inc c
- cp $FF ; have we reached the end of the movement data?
- jr nz, .loop
-
- ld a, c
- ld [wNPCNumScriptedSteps], a ; number of steps taken
-
- pop bc
- ld hl, wd730
- set 0, [hl]
- pop hl
- xor a
- ld [wOverrideSimulatedJoypadStatesMask], a
- ld [wSimulatedJoypadStatesEnd], a
- dec a
- ld [wJoyIgnore], a
- ld [wWastedByteCD3A], a
- ret
-
-; divides [hDividend2] by [hDivisor2] and stores the quotient in [hQuotient2]
-DivideBytes::
- push hl
- ld hl, hQuotient2
- xor a
- ld [hld], a
- ld a, [hld]
- and a
- jr z, .done
- ld a, [hli]
-.loop
- sub [hl]
- jr c, .done
- inc hl
- inc [hl]
- dec hl
- jr .loop
-.done
- pop hl
- ret
-
-
-LoadFontTilePatterns::
- ld a, [rLCDC]
- bit 7, a ; is the LCD enabled?
- jr nz, .on
-.off
- ld hl, FontGraphics
- ld de, vFont
- ld bc, FontGraphicsEnd - FontGraphics
- ld a, BANK(FontGraphics)
- jp FarCopyDataDouble ; if LCD is off, transfer all at once
-.on
- ld de, FontGraphics
- ld hl, vFont
- lb bc, BANK(FontGraphics), (FontGraphicsEnd - FontGraphics) / $8
- jp CopyVideoDataDouble ; if LCD is on, transfer during V-blank
-
-LoadTextBoxTilePatterns::
- ld a, [rLCDC]
- bit 7, a ; is the LCD enabled?
- jr nz, .on
-.off
- ld hl, TextBoxGraphics
- ld de, vChars2 + $600
- ld bc, TextBoxGraphicsEnd - TextBoxGraphics
- ld a, BANK(TextBoxGraphics)
- jp FarCopyData ; if LCD is off, transfer all at once
-.on
- ld de, TextBoxGraphics
- ld hl, vChars2 + $600
- lb bc, BANK(TextBoxGraphics), (TextBoxGraphicsEnd - TextBoxGraphics) / $10
- jp CopyVideoData ; if LCD is on, transfer during V-blank
-
-LoadHpBarAndStatusTilePatterns::
- ld a, [rLCDC]
- bit 7, a ; is the LCD enabled?
- jr nz, .on
-.off
- ld hl, HpBarAndStatusGraphics
- ld de, vChars2 + $620
- ld bc, HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics
- ld a, BANK(HpBarAndStatusGraphics)
- jp FarCopyData ; if LCD is off, transfer all at once
-.on
- ld de, HpBarAndStatusGraphics
- ld hl, vChars2 + $620
- lb bc, BANK(HpBarAndStatusGraphics), (HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics) / $10
- jp CopyVideoData ; if LCD is on, transfer during V-blank
-
-UncompressSpriteFromDE::
-; Decompress pic at a:de.
- ld hl, wSpriteInputPtr
- ld [hl], e
- inc hl
- ld [hl], d
- jp UncompressSpriteData
-
-SaveScreenTilesToBuffer2::
- coord hl, 0, 0
- ld de, wTileMapBackup2
- ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
- jp CopyData
-
-LoadScreenTilesFromBuffer2::
- call LoadScreenTilesFromBuffer2DisableBGTransfer
- ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
- ret
-
-; loads screen tiles stored in wTileMapBackup2 but leaves H_AUTOBGTRANSFERENABLED disabled
-LoadScreenTilesFromBuffer2DisableBGTransfer::
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld hl, wTileMapBackup2
- coord de, 0, 0
- ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
- jp CopyData
-
-SaveScreenTilesToBuffer1::
- coord hl, 0, 0
- ld de, wTileMapBackup
- ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
- jp CopyData
-
-LoadScreenTilesFromBuffer1::
- xor a
- ld [H_AUTOBGTRANSFERENABLED], a
- ld hl, wTileMapBackup
- coord de, 0, 0
- ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
- call CopyData
- ld a, 1
- ld [H_AUTOBGTRANSFERENABLED], a
- ret
-
-DelayFrames::
-; wait c frames
- call DelayFrame
- dec c
- jr nz, DelayFrames
- ret
-
-PlaySoundWaitForCurrent::
- push af
- call WaitForSoundToFinish
- pop af
- jp PlaySound
-
-; Wait for sound to finish playing
-WaitForSoundToFinish::
- ld a, [wLowHealthAlarm]
- and $80
- ret nz
- push hl
-.waitLoop
- ld hl, wChannelSoundIDs + Ch5
- xor a
- or [hl]
- inc hl
- or [hl]
- inc hl
- inc hl
- or [hl]
- and a
- jr nz, .waitLoop
- pop hl
- ret
-
-NamePointers::
- dw MonsterNames
- dw MoveNames
- dw UnusedNames
- dw ItemNames
- dw wPartyMonOT ; player's OT names list
- dw wEnemyMonOT ; enemy's OT names list
- dw TrainerNames
-
-GetName::
-; arguments:
-; [wd0b5] = which name
-; [wNameListType] = which list
-; [wPredefBank] = bank of list
-;
-; returns pointer to name in de
- ld a, [wd0b5]
- ld [wd11e], a
-
- ; TM names are separate from item names.
- ; BUG: This applies to all names instead of just items.
- cp HM_01
- jp nc, GetMachineName
-
- ld a, [H_LOADEDROMBANK]
- push af
- push hl
- push bc
- push de
- ld a, [wNameListType] ;List3759_entrySelector
- dec a
- jr nz, .otherEntries
- ;1 = MON_NAMES
- call GetMonName
- ld hl, NAME_LENGTH
- add hl, de
- ld e, l
- ld d, h
- jr .gotPtr
-.otherEntries
- ;2-7 = OTHER ENTRIES
- ld a, [wPredefBank]
- call BankswitchCommon
- ld a, [wNameListType] ;VariousNames' entryID
- dec a
- add a
- ld d, 0
- ld e, a
- jr nc, .skip
- inc d
-.skip
- ld hl, NamePointers
- add hl, de
- ld a, [hli]
- ld [$ff96], a
- ld a, [hl]
- ld [$ff95], a
- ld a, [$ff95]
- ld h, a
- ld a, [$ff96]
- ld l, a
- ld a, [wd0b5]
- ld b, a
- ld c, 0
-.nextName
- ld d, h
- ld e, l
-.nextChar
- ld a, [hli]
- cp "@"
- jr nz, .nextChar
- inc c ;entry counter
- ld a, b ;wanted entry
- cp c
- jr nz, .nextName
- ld h, d
- ld l, e
- ld de, wcd6d
- ld bc, $0014
- call CopyData
-.gotPtr
- ld a, e
- ld [wUnusedCF8D], a
- ld a, d
- ld [wUnusedCF8D + 1], a
- pop de
- pop bc
- pop hl
- pop af
- call BankswitchCommon
- ret
-
-GetItemPrice::
-; Stores item's price as BCD at hItemPrice (3 bytes)
-; Input: [wcf91] = item id
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [wListMenuID]
- cp MOVESLISTMENU
- ld a, BANK(ItemPrices)
- jr nz, .ok
- ld a, $f ; hardcoded Bank
-.ok
- call BankswitchCommon
- ld hl, wItemPrices
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld a, [wcf91] ; a contains item id
- cp HM_01
- jr nc, .getTMPrice
- ld bc, $3
-.loop
- add hl, bc
- dec a
- jr nz, .loop
- dec hl
- ld a, [hld]
- ld [hItemPrice + 2], a
- ld a, [hld]
- ld [hItemPrice + 1], a
- ld a, [hl]
- ld [hItemPrice], a
- jr .done
-.getTMPrice
- callbs GetMachinePrice
-.done
- ld de, hItemPrice
- pop af
- call BankswitchCommon
- ret
-
-; copies a string from [de] to [wcf4b]
-CopyStringToCF4B::
- ld hl, wcf4b
- ; fall through
-
-; copies a string from [de] to [hl]
-CopyString::
- ld a, [de]
- inc de
- ld [hli], a
- cp "@"
- jr nz, CopyString
- ret
-
-; this function is used when lower button sensitivity is wanted (e.g. menus)
-; OUTPUT: [hJoy5] = pressed buttons in usual format
-; there are two flags that control its functionality, [hJoy6] and [hJoy7]
-; there are essentially three modes of operation
-; 1. Get newly pressed buttons only
-; ([hJoy7] == 0, [hJoy6] == any)
-; Just copies [hJoyPressed] to [hJoy5].
-; 2. Get currently pressed buttons at low sample rate with delay
-; ([hJoy7] == 1, [hJoy6] != 0)
-; If the user holds down buttons for more than half a second,
-; report buttons as being pressed up to 12 times per second thereafter.
-; If the user holds down buttons for less than half a second,
-; report only one button press.
-; 3. Same as 2, but report no buttons as pressed if A or B is held down.
-; ([hJoy7] == 1, [hJoy6] == 0)
-JoypadLowSensitivity::
- call Joypad
- ld a, [hJoy7] ; flag
- and a ; get all currently pressed buttons or only newly pressed buttons?
- ld a, [hJoyPressed] ; newly pressed buttons
- jr z, .storeButtonState
- ld a, [hJoyHeld] ; all currently pressed buttons
-.storeButtonState
- ld [hJoy5], a
- ld a, [hJoyPressed] ; newly pressed buttons
- and a ; have any buttons been newly pressed since last check?
- jr z, .noNewlyPressedButtons
-.newlyPressedButtons
- ld a, 30 ; half a second delay
- ld [H_FRAMECOUNTER], a
- ret
-.noNewlyPressedButtons
- ld a, [H_FRAMECOUNTER]
- and a ; is the delay over?
- jr z, .delayOver
-.delayNotOver
- xor a
- ld [hJoy5], a ; report no buttons as pressed
- ret
-.delayOver
-; if [hJoy6] = 0 and A or B is pressed, report no buttons as pressed
- ld a, [hJoyHeld]
- and A_BUTTON | B_BUTTON
- jr z, .setShortDelay
- ld a, [hJoy6] ; flag
- and a
- jr nz, .setShortDelay
- xor a
- ld [hJoy5], a
-.setShortDelay
- ld a, 5 ; 1/12 of a second delay
- ld [H_FRAMECOUNTER], a
- ret
-
-WaitForTextScrollButtonPress::
- ld a, [H_DOWNARROWBLINKCNT1]
- push af
- ld a, [H_DOWNARROWBLINKCNT2]
- push af
- xor a
- ld [H_DOWNARROWBLINKCNT1], a
- ld a, $6
- ld [H_DOWNARROWBLINKCNT2], a
-.loop
- push hl
- ld a, [wTownMapSpriteBlinkingEnabled]
- and a
- jr z, .skipAnimation
- push de
- push bc
- callab TownMapSpriteBlinkingAnimation
- pop bc
- pop de
-.skipAnimation
- coord hl, 18, 16
- call HandleDownArrowBlinkTiming
- pop hl
- call JoypadLowSensitivity
- predef CableClub_Run
- ld a, [hJoy5]
- and A_BUTTON | B_BUTTON
- jr z, .loop
- pop af
- ld [H_DOWNARROWBLINKCNT2], a
- pop af
- ld [H_DOWNARROWBLINKCNT1], a
- ret
-
-; (unless in link battle) waits for A or B being pressed and outputs the scrolling sound effect
-ManualTextScroll::
- ld a, [wLinkState]
- cp LINK_STATE_BATTLING
- jr z, .inLinkBattle
- call WaitForTextScrollButtonPress
- call WaitForSoundToFinish
- ld a, SFX_PRESS_AB
- jp PlaySound
-.inLinkBattle
- ld c, 65
- jp DelayFrames
-
-; function to do multiplication
-; all values are big endian
-; INPUT
-; FF96-FF98 = multiplicand
-; FF99 = multiplier
-; OUTPUT
-; FF95-FF98 = product
-Multiply::
- push hl
- push bc
- callab _Multiply
- pop bc
- pop hl
- ret
-
-; function to do division
-; all values are big endian
-; INPUT
-; FF95-FF98 = dividend
-; FF99 = divisor
-; b = number of bytes in the dividend (starting from FF95)
-; OUTPUT
-; FF95-FF98 = quotient
-; FF99 = remainder
-Divide::
- push hl
- push de
- push bc
- homecall _Divide
- pop bc
- pop de
- pop hl
- ret
-
-; This function is used to wait a short period after printing a letter to the
-; screen unless the player presses the A/B button or the delay is turned off
-; through the [wd730] or [wLetterPrintingDelayFlags] flags.
-PrintLetterDelay::
- ld a, [wd730]
- bit 6, a
- ret nz
- ld a, [wLetterPrintingDelayFlags]
- bit 1, a
- ret z
- push hl
- push de
- push bc
- ld a, [wLetterPrintingDelayFlags]
- bit 0, a
- jr z, .waitOneFrame
- ld a, [wOptions]
- and $f
- ld [H_FRAMECOUNTER], a
- jr .checkButtons
-.waitOneFrame
- ld a, 1
- ld [H_FRAMECOUNTER], a
-.checkButtons
- call Joypad
- ld a, [hJoyHeld]
-.checkAButton
- bit 0, a ; is the A button pressed?
- jr z, .checkBButton
- jr .endWait
-.checkBButton
- bit 1, a ; is the B button pressed?
- jr z, .buttonsNotPressed
-.endWait
- call DelayFrame
- jr .done
-.buttonsNotPressed ; if neither A nor B is pressed
- ld a, [H_FRAMECOUNTER]
- and a
- jr nz, .checkButtons
-.done
- pop bc
- pop de
- pop hl
- ret
-
-; Copies [hl, bc) to [de, bc - hl).
-; In other words, the source data is from hl up to but not including bc,
-; and the destination is de.
-CopyDataUntil::
- 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
-
-; Function to remove a pokemon from the party or the current box.
-; wWhichPokemon determines the pokemon.
-; [wRemoveMonFromBox] == 0 specifies the party.
-; [wRemoveMonFromBox] != 0 specifies the current box.
-RemovePokemon::
- jpab _RemovePokemon
-
-AddPartyMon::
- push hl
- push de
- push bc
- callba _AddPartyMon
- pop bc
- pop de
- pop hl
- ret
-
-; calculates all 5 stats of current mon and writes them to [de]
-CalcStats::
- ld c, $0
-.statsLoop
- inc c
- call CalcStat
- ld a, [H_MULTIPLICAND + 1]
- ld [de], a
- inc de
- ld a, [H_MULTIPLICAND + 2]
- ld [de], a
- inc de
- ld a, c
- cp NUM_STATS
- jr nz, .statsLoop
- ret
-
-; calculates stat c of current mon
-; c: stat to calc (HP=1, Atk=2, Def=3, Spd=4, Spc=5)
-; b: consider stat exp?
-; hl: base ptr to stat exp values ([hl + 2*c - 1] and [hl + 2*c])
-CalcStat::
- push hl
- push de
- push bc
- ld a, b
- ld d, a
- push hl
- ld hl, wMonHeader
- ld b, $0
- add hl, bc
- ld a, [hl] ; read base value of stat
- ld e, a
- pop hl
- push hl
- sla c
- ld a, d
- and a
- jr z, .statExpDone ; consider stat exp?
- add hl, bc ; skip to corresponding stat exp value
-.statExpLoop ; calculates ceil(Sqrt(stat exp)) in b
- xor a
- ld [H_MULTIPLICAND], a
- ld [H_MULTIPLICAND + 1], a
- inc b ; increment current stat exp bonus
- ld a, b
- cp $ff
- jr z, .statExpDone
- ld [H_MULTIPLICAND + 2], a
- ld [H_MULTIPLIER], a
- call Multiply
- ld a, [hld]
- ld d, a
- ld a, [$ff98]
- sub d
- ld a, [hli]
- ld d, a
- ld a, [$ff97]
- sbc d ; test if (current stat exp bonus)^2 < stat exp
- jr c, .statExpLoop
-.statExpDone
- srl c
- pop hl
- push bc
- ld bc, wPartyMon1DVs - (wPartyMon1HPExp - 1) ; also wEnemyMonDVs - wEnemyMonHP
- add hl, bc
- pop bc
- ld a, c
- cp $2
- jr z, .getAttackIV
- cp $3
- jr z, .getDefenseIV
- cp $4
- jr z, .getSpeedIV
- cp $5
- jr z, .getSpecialIV
-.getHpIV
- push bc
- ld a, [hl] ; Atk IV
- swap a
- and $1
- sla a
- sla a
- sla a
- ld b, a
- ld a, [hli] ; Def IV
- and $1
- sla a
- sla a
- add b
- ld b, a
- ld a, [hl] ; Spd IV
- swap a
- and $1
- sla a
- add b
- ld b, a
- ld a, [hl] ; Spc IV
- and $1
- add b ; HP IV: LSB of the other 4 IVs
- pop bc
- jr .calcStatFromIV
-.getAttackIV
- ld a, [hl]
- swap a
- and $f
- jr .calcStatFromIV
-.getDefenseIV
- ld a, [hl]
- and $f
- jr .calcStatFromIV
-.getSpeedIV
- inc hl
- ld a, [hl]
- swap a
- and $f
- jr .calcStatFromIV
-.getSpecialIV
- inc hl
- ld a, [hl]
- and $f
-.calcStatFromIV
- ld d, $0
- add e
- ld e, a
- jr nc, .noCarry
- inc d ; de = Base + IV
-.noCarry
- sla e
- rl d ; de = (Base + IV) * 2
- srl b
- srl b ; b = ceil(Sqrt(stat exp)) / 4
- ld a, b
- add e
- jr nc, .noCarry2
- inc d ; de = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4
-.noCarry2
- ld [H_MULTIPLICAND + 2], a
- ld a, d
- ld [H_MULTIPLICAND + 1], a
- xor a
- ld [H_MULTIPLICAND], a
- ld a, [wCurEnemyLVL]
- ld [H_MULTIPLIER], a
- call Multiply ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level
- ld a, [H_MULTIPLICAND]
- ld [H_DIVIDEND], a
- ld a, [H_MULTIPLICAND + 1]
- ld [H_DIVIDEND + 1], a
- ld a, [H_MULTIPLICAND + 2]
- ld [H_DIVIDEND + 2], a
- ld a, $64
- ld [H_DIVISOR], a
- ld a, $3
- ld b, a
- call Divide ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100
- ld a, c
- cp $1
- ld a, 5 ; + 5 for non-HP stat
- jr nz, .notHPStat
- ld a, [wCurEnemyLVL]
- ld b, a
- ld a, [H_MULTIPLICAND + 2]
- add b
- ld [H_MULTIPLICAND + 2], a
- jr nc, .noCarry3
- ld a, [H_MULTIPLICAND + 1]
- inc a
- ld [H_MULTIPLICAND + 1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level
-.noCarry3
- ld a, 10 ; + 10 for HP stat
-.notHPStat
- ld b, a
- ld a, [H_MULTIPLICAND + 2]
- add b
- ld [H_MULTIPLICAND + 2], a
- jr nc, .noCarry4
- ld a, [H_MULTIPLICAND + 1]
- inc a ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5
- ld [H_MULTIPLICAND + 1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10
-.noCarry4
- ld a, [H_MULTIPLICAND + 1] ; check for overflow (>999)
- cp 999 / $100 + 1
- jr nc, .overflow
- cp 999 / $100
- jr c, .noOverflow
- ld a, [H_MULTIPLICAND + 2]
- cp 999 % $100 + 1
- jr c, .noOverflow
-.overflow
- ld a, 999 / $100 ; overflow: cap at 999
- ld [H_MULTIPLICAND + 1], a
- ld a, 999 % $100
- ld [H_MULTIPLICAND + 2], a
-.noOverflow
- pop bc
- pop de
- pop hl
- ret
-
-AddEnemyMonToPlayerParty::
- homecall_sf _AddEnemyMonToPlayerParty
- ret
-
-MoveMon::
- homecall_sf _MoveMon
- ret
-
-; skips a text entries, each of size NAME_LENGTH (like trainer name, OT name, rival name, ...)
-; hl: base pointer, will be incremented by NAME_LENGTH * a
-SkipFixedLengthTextEntries::
- and a
- ret z
- ld bc, NAME_LENGTH
-.skipLoop
- add hl, bc
- dec a
- jr nz, .skipLoop
- ret
-
-AddNTimes::
-; add bc to hl a times
- and a
- ret z
-.loop
- add hl, bc
- dec a
- jr nz, .loop
- ret
-
-; Compare strings, c bytes in length, at de and hl.
-; Often used to compare big endian numbers in battle calculations.
-StringCmp::
- ld a, [de]
- cp [hl]
- ret nz
- inc de
- inc hl
- dec c
- jr nz, StringCmp
- ret
-
-; INPUT:
-; a = oam block index (each block is 4 oam entries)
-; b = Y coordinate of upper left corner of sprite
-; c = X coordinate of upper left corner of sprite
-; de = base address of 4 tile number and attribute pairs
-WriteOAMBlock::
- ld h, wOAMBuffer / $100
- swap a ; multiply by 16
- ld l, a
- call .writeOneEntry ; upper left
- push bc
- ld a, 8
- add c
- ld c, a
- call .writeOneEntry ; upper right
- pop bc
- ld a, 8
- add b
- ld b, a
- call .writeOneEntry ; lower left
- ld a, 8
- add c
- ld c, a
- ; lower right
-.writeOneEntry
- ld [hl], b ; Y coordinate
- inc hl
- ld [hl], c ; X coordinate
- inc hl
- ld a, [de] ; tile number
- inc de
- ld [hli], a
- ld a, [de] ; attribute
- inc de
- ld [hli], a
- ret
-
-HandleMenuInput::
- xor a
- ld [wPartyMenuAnimMonEnabled], a
-
-HandleMenuInputPokemonSelection::
- ld a, [H_DOWNARROWBLINKCNT1]
- push af
- ld a, [H_DOWNARROWBLINKCNT2]
- push af ; save existing values on stack
- xor a
- ld [H_DOWNARROWBLINKCNT1], a ; blinking down arrow timing value 1
- ld a, 6
- ld [H_DOWNARROWBLINKCNT2], a ; blinking down arrow timing value 2
-.loop1
- xor a
- ld [wAnimCounter], a ; counter for pokemon shaking animation
- call PlaceMenuCursor
- call Delay3
-.loop2
- push hl
- ld a, [wPartyMenuAnimMonEnabled]
- and a ; is it a pokemon selection menu?
- jr z, .getJoypadState
- callba AnimatePartyMon ; shake mini sprite of selected pokemon
-.getJoypadState
- pop hl
- call JoypadLowSensitivity
- ld a, [hJoy5]
- and a ; was a key pressed?
- jr nz, .keyPressed
- push hl
- coord hl, 18, 11 ; coordinates of blinking down arrow in some menus
- call HandleDownArrowBlinkTiming ; blink down arrow (if any)
- pop hl
- ld a, [wMenuJoypadPollCount]
- dec a
- jr z, .giveUpWaiting
- jr .loop2
-.giveUpWaiting
-; if a key wasn't pressed within the specified number of checks
- pop af
- ld [H_DOWNARROWBLINKCNT2], a
- pop af
- ld [H_DOWNARROWBLINKCNT1], a ; restore previous values
- xor a
- ld [wMenuWrappingEnabled], a ; disable menu wrapping
- ret
-.keyPressed
- xor a
- ld [wCheckFor180DegreeTurn], a
- ld a, [hJoy5]
- ld b, a
- bit 0, a ; pressed A key?
- jr nz, .checkOtherKeys
- bit 6, a ; pressed Up key?
- jr z, .checkIfDownPressed
-.upPressed
- ld a, [wCurrentMenuItem] ; selected menu item
- and a ; already at the top of the menu?
- jr z, .alreadyAtTop
-.notAtTop
- dec a
- ld [wCurrentMenuItem], a ; move selected menu item up one space
- jr .checkOtherKeys
-.alreadyAtTop
- ld a, [wMenuWrappingEnabled]
- and a ; is wrapping around enabled?
- jr z, .noWrappingAround
- ld a, [wMaxMenuItem]
- ld [wCurrentMenuItem], a ; wrap to the bottom of the menu
- jr .checkOtherKeys
-.checkIfDownPressed
- bit 7, a
- jr z, .checkOtherKeys
-.downPressed
- ld a, [wCurrentMenuItem]
- inc a
- ld c, a
- ld a, [wMaxMenuItem]
- cp c
- jr nc, .notAtBottom
-.alreadyAtBottom
- ld a, [wMenuWrappingEnabled]
- and a ; is wrapping around enabled?
- jr z, .noWrappingAround
- ld c, $00 ; wrap from bottom to top
-.notAtBottom
- ld a, c
- ld [wCurrentMenuItem], a
-.checkOtherKeys
- ld a, [wMenuWatchedKeys]
- and b ; does the menu care about any of the pressed keys?
- jp z, .loop1
-.checkIfAButtonOrBButtonPressed
- ld a, [hJoy5]
- and A_BUTTON | B_BUTTON
- jr z, .skipPlayingSound
-.AButtonOrBButtonPressed
- push hl
- ld hl, wFlags_0xcd60
- bit 5, [hl]
- pop hl
- jr nz, .skipPlayingSound
- ld a, SFX_PRESS_AB
- call PlaySound
-.skipPlayingSound
- pop af
- ld [H_DOWNARROWBLINKCNT2], a
- pop af
- ld [H_DOWNARROWBLINKCNT1], a ; restore previous values
- xor a
- ld [wMenuWrappingEnabled], a ; disable menu wrapping
- ld a, [hJoy5]
- ret
-.noWrappingAround
- ld a, [wMenuWatchMovingOutOfBounds]
- and a ; should we return if the user tried to go past the top or bottom?
- jr z, .checkOtherKeys
- jr .checkIfAButtonOrBButtonPressed
-
-PlaceMenuCursor::
- ld a, [wTopMenuItemY]
- and a ; is the y coordinate 0?
- jr z, .adjustForXCoord
- coord hl, 0, 0
- ld bc, SCREEN_WIDTH
-.topMenuItemLoop
- add hl, bc
- dec a
- jr nz, .topMenuItemLoop
-.adjustForXCoord
- ld a, [wTopMenuItemX]
- ld b, 0
- ld c, a
- add hl, bc
- push hl
- ld a, [wLastMenuItem]
- and a ; was the previous menu id 0?
- jr z, .checkForArrow1
- ld bc, 40
- push af
- ld a, [hFlags_0xFFFA]
- bit 1, a ; is the menu double spaced?
- jr z, .doubleSpaced1
- ld bc, 20
-.doubleSpaced1
- pop af
-.oldMenuItemLoop
- add hl, bc
- dec a
- jr nz, .oldMenuItemLoop
-.checkForArrow1
- ld a, [hl]
- cp "▶" ; was an arrow next to the previously selected menu item?
- jr nz, .skipClearingArrow
-.clearArrow
- ld a, [wTileBehindCursor]
- ld [hl], a
-.skipClearingArrow
- pop hl
- ld a, [wCurrentMenuItem]
- and a
- jr z, .checkForArrow2
- ld bc, 40
- push af
- ld a, [hFlags_0xFFFA]
- bit 1, a ; is the menu double spaced?
- jr z, .doubleSpaced2
- ld bc, 20
-.doubleSpaced2
- pop af
-.currentMenuItemLoop
- add hl, bc
- dec a
- jr nz, .currentMenuItemLoop
-.checkForArrow2
- ld a, [hl]
- cp "▶" ; has the right arrow already been placed?
- jr z, .skipSavingTile ; if so, don't lose the saved tile
- ld [wTileBehindCursor], a ; save tile before overwriting with right arrow
-.skipSavingTile
- ld a, "▶" ; place right arrow
- ld [hl], a
- ld a, l
- ld [wMenuCursorLocation], a
- ld a, h
- ld [wMenuCursorLocation + 1], a
- ld a, [wCurrentMenuItem]
- ld [wLastMenuItem], a
- ret
-
-; This is used to mark a menu cursor other than the one currently being
-; manipulated. In the case of submenus, this is used to show the location of
-; the menu cursor in the parent menu. In the case of swapping items in list,
-; this is used to mark the item that was first chosen to be swapped.
-PlaceUnfilledArrowMenuCursor::
- ld b, a
- ld a, [wMenuCursorLocation]
- ld l, a
- ld a, [wMenuCursorLocation + 1]
- ld h, a
- ld [hl], $ec ; outline of right arrow
- ld a, b
- ret
-
-; Replaces the menu cursor with a blank space.
-EraseMenuCursor::
- ld a, [wMenuCursorLocation]
- ld l, a
- ld a, [wMenuCursorLocation + 1]
- ld h, a
- ld [hl], " "
- ret
-
-; This toggles a blinking down arrow at hl on and off after a delay has passed.
-; This is often called even when no blinking is occurring.
-; The reason is that most functions that call this initialize H_DOWNARROWBLINKCNT1 to 0.
-; The effect is that if the tile at hl is initialized with a down arrow,
-; this function will toggle that down arrow on and off, but if the tile isn't
-; initialized with a down arrow, this function does nothing.
-; That allows this to be called without worrying about if a down arrow should
-; be blinking.
-HandleDownArrowBlinkTiming::
- ld a, [hl]
- ld b, a
- ld a, "▼"
- cp b
- jr nz, .downArrowOff
-.downArrowOn
- ld a, [H_DOWNARROWBLINKCNT1]
- dec a
- ld [H_DOWNARROWBLINKCNT1], a
- ret nz
- ld a, [H_DOWNARROWBLINKCNT2]
- dec a
- ld [H_DOWNARROWBLINKCNT2], a
- ret nz
- ld a, " "
- ld [hl], a
- ld a, $ff
- ld [H_DOWNARROWBLINKCNT1], a
- ld a, $06
- ld [H_DOWNARROWBLINKCNT2], a
- ret
-.downArrowOff
- ld a, [H_DOWNARROWBLINKCNT1]
- and a
- ret z
- dec a
- ld [H_DOWNARROWBLINKCNT1], a
- ret nz
- dec a
- ld [H_DOWNARROWBLINKCNT1], a
- ld a, [H_DOWNARROWBLINKCNT2]
- dec a
- ld [H_DOWNARROWBLINKCNT2], a
- ret nz
- ld a, $06
- ld [H_DOWNARROWBLINKCNT2], a
- ld a, "▼"
- ld [hl], a
- ret
-
-; The following code either enables or disables the automatic drawing of
-; text boxes by DisplayTextID. Both functions cause DisplayTextID to wait
-; for a button press after displaying text (unless [wEnteringCableClub] is set).
-
-EnableAutoTextBoxDrawing::
- xor a
- jr AutoTextBoxDrawingCommon
-
-DisableAutoTextBoxDrawing::
- ld a, $01
-
-AutoTextBoxDrawingCommon::
- ld [wAutoTextBoxDrawingControl], a
- xor a
- ld [wDoNotWaitForButtonPressAfterDisplayingText], a ; make DisplayTextID wait for button press
- ret
-
-PrintText::
-; Print text hl at (1, 14).
- push hl
- ld a, MESSAGE_BOX
- ld [wTextBoxID], a
- call DisplayTextBoxID
- call UpdateSprites
- call Delay3
- pop hl
-PrintText_NoCreatingTextBox::
- coord bc, 1, 14
- jp TextCommandProcessor
+INCLUDE "home/npc_movement.asm"
+INCLUDE "home/trainers.asm"
+INCLUDE "home/map_objects.asm"
+INCLUDE "home/trainers2.asm"
+INCLUDE "home/money.asm"
+INCLUDE "home/bankswitch.asm"
+INCLUDE "home/yes_no.asm"
+INCLUDE "home/pathfinding.asm"
+INCLUDE "home/load_font.asm"
+INCLUDE "home/tilemap.asm"
+INCLUDE "home/delay.asm"
+INCLUDE "home/names2.asm"
+INCLUDE "home/item_price.asm"
+INCLUDE "home/copy_string.asm"
+INCLUDE "home/joypad2.asm"
+INCLUDE "home/math.asm"
+INCLUDE "home/print_text.asm"
+INCLUDE "home/move_mon.asm"
+INCLUDE "home/array.asm"
+INCLUDE "home/compare.asm"
+INCLUDE "home/oam.asm"
+INCLUDE "home/window.asm"
FarPrintText::
; print text b:hl at (1, 14)
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
push af
ld a, b
call BankswitchCommon
@@ -4355,421 +229,34 @@ FarPrintText::
call BankswitchCommon
ret
-PrintNumber::
-; Print the c-digit, b-byte value at de.
-; Allows 2 to 7 digits. For 1-digit numbers, add
-; the value to char "0" instead of calling PrintNumber.
-; Flags LEADING_ZEROES and LEFT_ALIGN can be given
-; in bits 7 and 6 of b respectively.
- push bc
- xor a
- ld [H_PASTLEADINGZEROES], a
- ld [H_NUMTOPRINT], a
- ld [H_NUMTOPRINT + 1], a
- ld a, b
- and $f
- cp 1
- jr z, .byte
- cp 2
- jr z, .word
-.long
- ld a, [de]
- ld [H_NUMTOPRINT], a
- inc de
- ld a, [de]
- ld [H_NUMTOPRINT + 1], a
- inc de
- ld a, [de]
- ld [H_NUMTOPRINT + 2], a
- jr .start
-
-.word
- ld a, [de]
- ld [H_NUMTOPRINT + 1], a
- inc de
- ld a, [de]
- ld [H_NUMTOPRINT + 2], a
- jr .start
-
-.byte
- ld a, [de]
- ld [H_NUMTOPRINT + 2], a
-
-.start
- push de
-
- ld d, b
- ld a, c
- ld b, a
- xor a
- ld c, a
- ld a, b
-
- cp 2
- jr z, .tens
- cp 3
- jr z, .hundreds
- cp 4
- jr z, .thousands
- cp 5
- jr z, .ten_thousands
- cp 6
- jr z, .hundred_thousands
-
-print_digit: macro
-
-if (\1) / $10000
- ld a, \1 / $10000 % $100
-else xor a
-endc
- ld [H_POWEROFTEN + 0], a
-
-if (\1) / $100
- ld a, \1 / $100 % $100
-else xor a
-endc
- ld [H_POWEROFTEN + 1], a
-
- ld a, \1 / $1 % $100
- ld [H_POWEROFTEN + 2], a
-
- call .PrintDigit
- call .NextDigit
-endm
-
-.millions print_digit 1000000
-.hundred_thousands print_digit 100000
-.ten_thousands print_digit 10000
-.thousands print_digit 1000
-.hundreds print_digit 100
-
-.tens
- ld c, 0
- ld a, [H_NUMTOPRINT + 2]
-.mod
- cp 10
- jr c, .ok
- sub 10
- inc c
- jr .mod
-.ok
-
- ld b, a
- ld a, [H_PASTLEADINGZEROES]
- or c
- ld [H_PASTLEADINGZEROES], a
- jr nz, .past
- call .PrintLeadingZero
- jr .next
-.past
- ld a, "0"
- add c
- ld [hl], a
-.next
-
- call .NextDigit
-.ones
- ld a, "0"
- add b
- ld [hli], a
- pop de
- dec de
- pop bc
- ret
-
-.PrintDigit:
-; Divide by the current decimal place.
-; Print the quotient, and keep the modulus.
- ld c, 0
-.loop
- ld a, [H_POWEROFTEN]
- ld b, a
- ld a, [H_NUMTOPRINT]
- ld [H_SAVEDNUMTOPRINT], a
- cp b
- jr c, .underflow0
- sub b
- ld [H_NUMTOPRINT], a
- ld a, [H_POWEROFTEN + 1]
- ld b, a
- ld a, [H_NUMTOPRINT + 1]
- ld [H_SAVEDNUMTOPRINT + 1], a
- cp b
- jr nc, .noborrow1
-
- ld a, [H_NUMTOPRINT]
- or 0
- jr z, .underflow1
- dec a
- ld [H_NUMTOPRINT], a
- ld a, [H_NUMTOPRINT + 1]
-.noborrow1
-
- sub b
- ld [H_NUMTOPRINT + 1], a
- ld a, [H_POWEROFTEN + 2]
- ld b, a
- ld a, [H_NUMTOPRINT + 2]
- ld [H_SAVEDNUMTOPRINT + 2], a
- cp b
- jr nc, .noborrow2
-
- ld a, [H_NUMTOPRINT + 1]
- and a
- jr nz, .borrowed
-
- ld a, [H_NUMTOPRINT]
- and a
- jr z, .underflow2
- dec a
- ld [H_NUMTOPRINT], a
- xor a
-.borrowed
-
- dec a
- ld [H_NUMTOPRINT + 1], a
- ld a, [H_NUMTOPRINT + 2]
-.noborrow2
- sub b
- ld [H_NUMTOPRINT + 2], a
- inc c
- jr .loop
-
-.underflow2
- ld a, [H_SAVEDNUMTOPRINT + 1]
- ld [H_NUMTOPRINT + 1], a
-.underflow1
- ld a, [H_SAVEDNUMTOPRINT]
- ld [H_NUMTOPRINT], a
-.underflow0
- ld a, [H_PASTLEADINGZEROES]
- or c
- jr z, .PrintLeadingZero
-
- ld a, "0"
- add c
- ld [hl], a
- ld [H_PASTLEADINGZEROES], a
- ret
-
-.PrintLeadingZero:
- bit BIT_LEADING_ZEROES, d
- ret z
- ld [hl], "0"
- ret
-
-.NextDigit:
-; Increment unless the number is left-aligned,
-; leading zeroes are not printed, and no digits
-; have been printed yet.
- bit BIT_LEADING_ZEROES, d
- jr nz, .inc
- bit BIT_LEFT_ALIGN, d
- jr z, .inc
- ld a, [H_PASTLEADINGZEROES]
- and a
- ret z
-.inc
- inc hl
- ret
-
-
-CallFunctionInTable::
-; Call function a in jumptable hl.
-; de is not preserved.
- push hl
- push de
- push bc
- add a
- ld d, 0
- ld e, a
- add hl, de
- ld a, [hli]
- ld h, [hl]
- ld l, a
- ld de, .returnAddress
- push de
- jp hl
-.returnAddress
- pop bc
- pop de
- pop hl
- ret
-
-
-IsInArray::
-; Search an array at hl for the value in a.
-; Entry size is de bytes.
-; Return count b and carry if found.
- ld b, 0
-
-IsInRestOfArray::
- ld c, a
-.loop
- ld a, [hl]
- cp -1
- jr z, .notfound
- cp c
- jr z, .found
- inc b
- add hl, de
- jr .loop
-
-.notfound
- and a
- ret
-
-.found
- scf
- ret
+INCLUDE "home/print_num.asm"
+INCLUDE "home/array2.asm"
InitMapSprites::
- jpab _InitMapSprites
-
-RestoreScreenTilesAndReloadTilePatterns::
- call ClearSprites
- ld a, $1
- ld [wUpdateSpritesEnabled], a
- call ReloadMapSpriteTilePatterns
- call LoadScreenTilesFromBuffer2
- call LoadTextBoxTilePatterns
- call RunDefaultPaletteCommand
- jr Delay3
-
-
-GBPalWhiteOutWithDelay3::
- call GBPalWhiteOut
-
-Delay3::
-; The bg map is updated each frame in thirds.
-; Wait three frames to let the bg map fully update.
- ld c, 3
- jp DelayFrames
-
-GBPalNormal::
-; Reset BGP and OBP0.
- ld a, %11100100 ; 3210
- ld [rBGP], a
- ld a, %11010000 ; 3100
- ld [rOBP0], a
- call UpdateGBCPal_BGP
- call UpdateGBCPal_OBP0
- call UpdateGBCPal_OBP1
- ret
-
-GBPalWhiteOut::
-; White out all palettes.
- xor a
- ld [rBGP], a
- ld [rOBP0], a
- ld [rOBP1], a
- call UpdateGBCPal_BGP
- call UpdateGBCPal_OBP0
- call UpdateGBCPal_OBP1
- ret
-
-
-RunDefaultPaletteCommand::
- ld b, $ff
-RunPaletteCommand::
- ld a, [wOnSGB]
- and a
- ret z
- predef_jump _RunPaletteCommand
-
-GetHealthBarColor::
-; Return at hl the palette of
-; an HP bar e pixels long.
- ld a, e
- cp 27
- ld d, 0 ; green
- jr nc, .gotColor
- cp 10
- inc d ; yellow
- jr nc, .gotColor
- inc d ; red
-.gotColor
- ld [hl], d
- ret
-
-; Copy the current map's sprites' tile patterns to VRAM again after they have
-; been overwritten by other tile patterns.
-ReloadMapSpriteTilePatterns::
- ld hl, wFontLoaded
- ld a, [hl]
- push af
- res 0, [hl]
- push hl
- xor a
- ld [wSpriteSetID], a
- call DisableLCD
- call InitMapSprites
- call EnableLCD
- pop hl
- pop af
- ld [hl], a
- call LoadPlayerSpriteGraphics
- call LoadFontTilePatterns
- jp UpdateSprites
+ jpfar _InitMapSprites
-
-GiveItem::
-; Give player quantity c of item b,
-; and copy the item's name to wcf4b.
-; Return carry on success.
- ld a, b
- ld [wd11e], a
- ld [wcf91], a
- ld a, c
- ld [wItemQuantity], a
- ld hl, wNumBagItems
- call AddItemToInventory
- ret nc
- call GetItemName
- call CopyStringToCF4B
- scf
- ret
-
-GivePokemon::
-; Give the player monster b at level c.
- ld a, b
- ld [wcf91], a
- ld a, c
- ld [wCurEnemyLVL], a
- xor a ; PLAYER_PARTY_DATA
- ld [wMonDataLocation], a
- jpba _GivePokemon
-
-Random::
-; Return a random number in a.
-; For battles, use BattleRandom.
- push hl
- push de
- push bc
- callba Random_
- ld a, [hRandomAdd]
- pop bc
- pop de
- pop hl
- ret
+INCLUDE "home/palettes.asm"
+INCLUDE "home/reload_sprites.asm"
+INCLUDE "home/give.asm"
+INCLUDE "home/random.asm"
BankswitchCommon::
- ld [H_LOADEDROMBANK], a
+ ldh [hLoadedROMBank], a
ld [MBC1RomBank], a
ret
Bankswitch::
; self-contained bankswitch, use this when not in the home bank
; switches to the bank in b
- ld a, [H_LOADEDROMBANK]
+ ldh a, [hLoadedROMBank]
push af
ld a, b
- ld [H_LOADEDROMBANK], a
+ ldh [hLoadedROMBank], a
ld [MBC1RomBank], a
call JumpToAddress
pop bc
ld a, b
- ld [H_LOADEDROMBANK], a
+ ldh [hLoadedROMBank], a
ld [MBC1RomBank], a
ret
JumpToAddress::
@@ -4794,139 +281,5 @@ PrepareRTCDataAndDisableSRAM::
ret
INCLUDE "home/predef.asm"
-
-UpdateCinnabarGymGateTileBlocks::
- callba UpdateCinnabarGymGateTileBlocks_
- ret ; again?
- ;jp Bankswitch
-
-CheckForHiddenObjectOrBookshelfOrCardKeyDoor::
- ld a, [H_LOADEDROMBANK]
- push af
- ld a, [hJoyHeld]
- bit 0, a ; A button
- jr z, .nothingFound
-; A button is pressed
- callbs CheckForHiddenObject
- ld a, [$ffee]
- and a
- jr nz, .hiddenObjectNotFound
- xor a
- ld [$ffeb], a
- ld a, [wHiddenObjectFunctionRomBank]
- call BankswitchCommon
- call JumpToAddress
- ld a, [$ffeb]
- jr .done
-.hiddenObjectNotFound
- predef GetTileAndCoordsInFrontOfPlayer
- callba PrintBookshelfText
- ld a, [$ffdb]
- and a
- jr z, .done
-.nothingFound
- ld a, $ff
-.done
- ld [$ffeb], a
- pop af
- call BankswitchCommon
- ret
-
-PrintPredefTextID::
- ld [hSpriteIndexOrTextID], a
- ld hl, TextPredefs
- call SetMapTextPointer
- ld hl, wTextPredefFlag
- set 0, [hl]
- call DisplayTextID
-
-RestoreMapTextPointer::
- ld hl, wMapTextPtr
- ld a, [$ffec]
- ld [hli], a
- ld a, [$ffec + 1]
- ld [hl], a
- ret
-
-SetMapTextPointer::
- ld a, [wMapTextPtr]
- ld [$ffec], a
- ld a, [wMapTextPtr + 1]
- ld [$ffec + 1], a
- ld a, l
- ld [wMapTextPtr], a
- ld a, h
- ld [wMapTextPtr + 1], a
- ret
-
-TextPredefs::
-const_value = 1
-
- add_tx_pre CardKeySuccessText ; 01
- add_tx_pre CardKeyFailText ; 02
- add_tx_pre RedBedroomPCText ; 03
- add_tx_pre RedBedroomSNESText ; 04
- add_tx_pre PushStartText ; 05
- add_tx_pre SaveOptionText ; 06
- add_tx_pre StrengthsAndWeaknessesText ; 07
- add_tx_pre OakLabEmailText ; 08
- add_tx_pre AerodactylFossilText ; 09
- add_tx_pre Route15UpstairsBinocularsText ; 0A
- add_tx_pre KabutopsFossilText ; 0B
- add_tx_pre FanClubPicture1Text ; 0C
- add_tx_pre FanClubPicture2Text ; 0D
- add_tx_pre GymStatueText1 ; 0E
- add_tx_pre GymStatueText2 ; 0F
- add_tx_pre BookcaseText ; 10
- add_tx_pre ViridianCityPokecenterBenchGuyText ; 11
- add_tx_pre PewterCityPokecenterBenchGuyText ; 12
- add_tx_pre CeruleanCityPokecenterBenchGuyText ; 13
- add_tx_pre LavenderCityPokecenterBenchGuyText ; 14
- add_tx_pre VermilionCityPokecenterBenchGuyText ; 15
- add_tx_pre CeladonCityPokecenterBenchGuyText ; 16
- add_tx_pre CeladonCityHotelText ; 17
- add_tx_pre FuchsiaCityPokecenterBenchGuyText ; 18
- add_tx_pre CinnabarIslandPokecenterBenchGuyText ; 19
- add_tx_pre SaffronCityPokecenterBenchGuyText ; 1A
- add_tx_pre MtMoonPokecenterBenchGuyText ; 1B
- add_tx_pre RockTunnelPokecenterBenchGuyText ; 1C
- add_tx_pre UnusedBenchGuyText1 ; 1D
- add_tx_pre UnusedBenchGuyText2 ; 1E
- add_tx_pre UnusedBenchGuyText3 ; 1F
- add_tx_pre UnusedPredefText ; 20
- add_tx_pre PokemonCenterPCText ; 21
- add_tx_pre ViridianSchoolNotebook ; 22
- add_tx_pre ViridianSchoolBlackboard ; 23
- add_tx_pre JustAMomentText ; 24
- add_tx_pre OpenBillsPCText ; 25
- add_tx_pre FoundHiddenItemText ; 26
- add_tx_pre HiddenItemBagFullText ; 27
- add_tx_pre VermilionGymTrashText ; 28
- add_tx_pre IndigoPlateauHQText ; 29
- add_tx_pre GameCornerOutOfOrderText ; 2A
- add_tx_pre GameCornerOutToLunchText ; 2B
- add_tx_pre GameCornerSomeonesKeysText ; 2C
- add_tx_pre FoundHiddenCoinsText ; 2D
- add_tx_pre DroppedHiddenCoinsText ; 2E
- add_tx_pre BillsHouseMonitorText ; 2F
- add_tx_pre BillsHouseInitiatedText ; 30
- add_tx_pre BillsHousePokemonList ; 31
- add_tx_pre MagazinesText ; 32
- add_tx_pre CinnabarGymQuiz ; 33
- add_tx_pre GameCornerNoCoinsText ; 34
- add_tx_pre GameCornerCoinCaseText ; 35
- add_tx_pre LinkCableHelp ; 36
- add_tx_pre TMNotebook ; 37
- add_tx_pre FightingDojoText ; 38
- add_tx_pre EnemiesOnEverySideText ; 39
- add_tx_pre WhatGoesAroundComesAroundText ; 3A
- add_tx_pre NewBicycleText ; 3B
- add_tx_pre IndigoPlateauStatues ; 3C XXX unused
- add_tx_pre VermilionGymTrashSuccessText1 ; 3D
- add_tx_pre VermilionGymTrashSuccessText2 ; 3E
- add_tx_pre VermilionGymTrashSuccessText3 ; 3F
- add_tx_pre VermilionGymTrashFailText ; 40
- add_tx_pre TownMapText ; 41
- add_tx_pre BookOrSculptureText ; 42
- add_tx_pre ElevatorText ; 43
- add_tx_pre PokemonStuffText ; 44
+INCLUDE "home/hidden_objects.asm"
+INCLUDE "home/predef_text.asm"