pokered/home.asm

4722 lines
94 KiB
NASM
Raw Normal View History

2014-05-25 17:26:42 +00:00
; The rst vectors are unused.
SECTION "rst 00", ROM0 [$00]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "rst 08", ROM0 [$08]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "rst 10", ROM0 [$10]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "rst 18", ROM0 [$18]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "rst 20", ROM0 [$20]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "rst 28", ROM0 [$28]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "rst 30", ROM0 [$30]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "rst 38", ROM0 [$38]
2014-05-25 17:26:42 +00:00
rst $38
; Hardware interrupts
SECTION "vblank", ROM0 [$40]
2014-05-25 17:26:42 +00:00
jp VBlank
SECTION "hblank", ROM0 [$48]
2014-05-25 17:26:42 +00:00
rst $38
SECTION "timer", ROM0 [$50]
2014-05-25 17:26:42 +00:00
jp Timer
SECTION "serial", ROM0 [$58]
2014-05-25 17:26:42 +00:00
jp Serial
SECTION "joypad", ROM0 [$60]
2014-05-25 17:26:42 +00:00
reti
SECTION "Home", ROM0
2014-05-25 17:26:42 +00:00
DisableLCD::
xor a
ld [rIF], a
ld a, [rIE]
ld b, a
res 0, a
ld [rIE], a
.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
INCLUDE "home/copy.asm"
2014-05-25 17:26:42 +00:00
SECTION "Entry", ROM0 [$100]
2014-05-25 17:26:42 +00:00
nop
jp Start
SECTION "Header", ROM0 [$104]
; The header is generated by rgbfix.
; The space here is allocated to prevent code from being overwritten.
ds $150 - $104
SECTION "Main", ROM0
2014-05-25 17:26:42 +00:00
Start::
cp GBC
jr z, .gbc
xor a
jr .ok
.gbc
ld a, 0
.ok
ld [wGBC], a
jp Init
INCLUDE "home/joypad.asm"
2014-05-25 17:26:42 +00:00
INCLUDE "data/map_header_pointers.asm"
INCLUDE "home/overworld.asm"
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
CheckForUserInterruption::
; Return carry if Up+Select+B, Start or A are pressed in c frames.
; Used only in the intro and title screen.
2014-05-25 17:26:42 +00:00
call DelayFrame
2014-05-25 17:26:42 +00:00
push bc
2014-05-25 18:21:48 +00:00
call JoypadLowSensitivity
2014-05-25 17:26:42 +00:00
pop bc
ld a, [hJoyHeld]
cp D_UP + SELECT + B_BUTTON
jr z, .input
ld a, [hJoy5]
and START | A_BUTTON
jr nz, .input
2014-05-25 17:26:42 +00:00
dec c
jr nz, CheckForUserInterruption
2014-05-25 17:26:42 +00:00
and a
ret
.input
2014-05-25 17:26:42 +00:00
scf
ret
; function to load position data for destination warp when switching maps
; INPUT:
; a = ID of destination warp within destination map
2016-06-12 00:24:04 +00:00
LoadDestinationWarpPosition::
2014-05-25 17:26:42 +00:00
ld b,a
ld a,[H_LOADEDROMBANK]
push af
ld a,[wPredefParentBank]
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ld a,b
add a
add a
ld c,a
ld b,0
add hl,bc
ld bc,4
2014-09-13 07:50:56 +00:00
ld de,wCurrentTileBlockMapViewPointer
2014-05-25 17:26:42 +00:00
call CopyData
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
2014-09-18 04:02:59 +00:00
2016-06-12 00:24:04 +00:00
DrawHPBar::
2014-09-18 04:02:59 +00:00
; Draw an HP bar d tiles long, and fill it to e pixels.
; If c is nonzero, show at least a sliver regardless.
2015-02-08 06:18:42 +00:00
; The right end of the bar changes with [wHPBarType].
2014-09-18 04:02:59 +00:00
2014-05-25 17:26:42 +00:00
push hl
push de
push bc
2014-09-18 04:02:59 +00:00
; Left
ld a, $71 ; "HP:"
ld [hli], a
ld a, $62
ld [hli], a
2014-05-25 17:26:42 +00:00
push hl
2014-09-18 04:02:59 +00:00
; Middle
ld a, $63 ; empty
.draw
2014-05-25 17:26:42 +00:00
ld [hli],a
dec d
2014-09-18 04:02:59 +00:00
jr nz, .draw
; Right
2015-02-08 06:18:42 +00:00
ld a,[wHPBarType]
2014-09-18 04:02:59 +00:00
dec a
ld a, $6d ; status screen and battle
jr z, .ok
dec a ; pokemon menu
.ok
2014-05-25 17:26:42 +00:00
ld [hl],a
2014-09-18 04:02:59 +00:00
2014-05-25 17:26:42 +00:00
pop hl
2014-09-18 04:02:59 +00:00
ld a, e
2014-05-25 17:26:42 +00:00
and a
2014-09-18 04:02:59 +00:00
jr nz, .fill
; If c iz 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
2014-05-25 17:26:42 +00:00
.done
pop bc
pop de
pop hl
ret
2014-09-18 04:02:59 +00:00
2015-02-08 02:37:40 +00:00
; loads pokemon data from one of multiple sources to wLoadedMon
2015-08-31 02:38:41 +00:00
; loads base stats to wMonHeader
2014-05-25 17:26:42 +00:00
; INPUT:
; [wWhichPokemon] = index of pokemon within party/box
2015-07-16 03:04:58 +00:00
; [wMonDataLocation] = source
2014-05-25 17:26:42 +00:00
; 00: player's party
; 01: enemy's party
; 02: current box
; 03: daycare
; OUTPUT:
; [wcf91] = pokemon ID
2015-02-08 02:37:40 +00:00
; wLoadedMon = base address of pokemon data
2015-08-31 02:38:41 +00:00
; wMonHeader = base address of base stats
2016-06-12 00:24:04 +00:00
LoadMonData::
2015-07-19 18:56:13 +00:00
jpab LoadMonData_
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
OverwritewMoves::
2015-02-08 08:17:03 +00:00
; Write c to [wMoves + b]. Unused.
ld hl, wMoves
2014-05-25 17:26:42 +00:00
ld e, b
2014-09-18 04:02:59 +00:00
ld d, 0
2014-05-25 17:26:42 +00:00
add hl, de
ld a, c
ld [hl], a
ret
2016-06-12 00:24:04 +00:00
LoadFlippedFrontSpriteByMonIndex::
2014-09-18 04:02:59 +00:00
ld a, 1
2015-08-31 02:38:41 +00:00
ld [wSpriteFlipped], a
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
LoadFrontSpriteByMonIndex::
2014-05-25 17:26:42 +00:00
push hl
ld a, [wd11e]
2014-05-25 17:26:42 +00:00
push af
ld a, [wcf91]
ld [wd11e], a
predef IndexToPokedex
ld hl, wd11e
2014-05-25 17:26:42 +00:00
ld a, [hl]
pop bc
ld [hl], b
and a
pop hl
2014-09-18 04:02:59 +00:00
jr z, .invalidDexNumber ; dex #0 invalid
cp NUM_POKEMON + 1
2014-09-18 04:02:59 +00:00
jr c, .validDexNumber ; dex >#151 invalid
2014-05-25 17:26:42 +00:00
.invalidDexNumber
ld a, RHYDON ; $1
ld [wcf91], a
2014-05-25 17:26:42 +00:00
ret
.validDexNumber
push hl
2014-05-29 08:31:46 +00:00
ld de, vFrontPic
2014-05-25 17:26:42 +00:00
call LoadMonFrontSprite
pop hl
ld a, [H_LOADEDROMBANK]
push af
ld a, Bank(CopyUncompressedPicToHL)
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
xor a
2015-07-24 03:48:35 +00:00
ld [hStartTileID], a
call CopyUncompressedPicToHL
2014-05-25 17:26:42 +00:00
xor a
2015-08-31 02:38:41 +00:00
ld [wSpriteFlipped], a
2014-05-25 17:26:42 +00:00
pop af
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
ret
2014-09-18 04:02:59 +00:00
2016-06-12 00:24:04 +00:00
PlayCry::
2014-09-18 04:02:59 +00:00
; Play monster a's cry.
2014-05-25 17:26:42 +00:00
call GetCryData
2014-09-18 04:02:59 +00:00
call PlaySound
jp WaitForSoundToFinish
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
GetCryData::
2014-09-18 04:02:59 +00:00
; Load cry data for monster a.
2014-05-25 17:26:42 +00:00
dec a
2014-09-18 04:02:59 +00:00
ld c, a
ld b, 0
ld hl, CryData
add hl, bc
add hl, bc
add hl, bc
2016-06-12 18:35:21 +00:00
ld a, BANK(CryData)
2014-05-25 17:26:42 +00:00
call BankswitchHome
2014-09-18 04:02:59 +00:00
ld a, [hli]
ld b, a ; cry id
ld a, [hli]
2015-08-09 05:32:44 +00:00
ld [wFrequencyModifier], a
2014-09-18 04:02:59 +00:00
ld a, [hl]
2015-08-09 05:32:44 +00:00
ld [wTempoModifier], a
2014-05-25 17:26:42 +00:00
call BankswitchBack
2014-09-18 04:02:59 +00:00
; 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
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
DisplayPartyMenu::
2014-09-14 18:29:18 +00:00
ld a,[hTilesetType]
2014-05-25 17:26:42 +00:00
push af
xor a
2014-09-14 18:29:18 +00:00
ld [hTilesetType],a
2014-05-25 17:26:42 +00:00
call GBPalWhiteOutWithDelay3
call ClearSprites
call PartyMenuInit
call DrawPartyMenu
jp HandlePartyMenuInput
2016-06-12 00:24:04 +00:00
GoBackToPartyMenu::
2014-09-14 18:29:18 +00:00
ld a,[hTilesetType]
2014-05-25 17:26:42 +00:00
push af
xor a
2014-09-14 18:29:18 +00:00
ld [hTilesetType],a
2014-05-25 17:26:42 +00:00
call PartyMenuInit
call RedrawPartyMenu
jp HandlePartyMenuInput
2016-06-12 00:24:04 +00:00
PartyMenuInit::
2014-09-18 04:02:59 +00:00
ld a, 1 ; hardcoded bank
2014-05-25 17:26:42 +00:00
call BankswitchHome
call LoadHpBarAndStatusTilePatterns
2014-09-18 04:02:59 +00:00
ld hl, wd730
set 6, [hl] ; turn off letter printing delay
2015-07-16 03:04:58 +00:00
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
2015-07-13 07:32:03 +00:00
ld [wMenuWatchMovingOutOfBounds], a
2014-09-18 04:02:59 +00:00
ld hl, wTopMenuItemY
2014-05-25 17:26:42 +00:00
inc a
2014-09-18 04:02:59 +00:00
ld [hli], a ; top menu item Y
2014-05-25 17:26:42 +00:00
xor a
2014-09-18 04:02:59 +00:00
ld [hli], a ; top menu item X
2015-07-16 03:04:58 +00:00
ld a, [wPartyAndBillsPCSavedMenuItem]
2014-05-25 17:26:42 +00:00
push af
2014-09-18 04:02:59 +00:00
ld [hli], a ; current menu item ID
2014-05-25 17:26:42 +00:00
inc hl
2014-09-18 04:02:59 +00:00
ld a, [wPartyCount]
2014-05-25 17:26:42 +00:00
and a ; are there more than 0 pokemon in the party?
2014-09-18 04:02:59 +00:00
jr z, .storeMaxMenuItemID
2014-05-25 17:26:42 +00:00
dec a
; if party is not empty, the max menu item ID is ([wPartyCount] - 1)
2014-05-25 17:26:42 +00:00
; otherwise, it is 0
.storeMaxMenuItemID
2014-09-18 04:02:59 +00:00
ld [hli], a ; max menu item ID
2015-07-25 03:27:59 +00:00
ld a, [wForcePlayerToChooseMon]
2014-05-25 17:26:42 +00:00
and a
2015-07-25 03:27:59 +00:00
ld a, A_BUTTON | B_BUTTON
2014-09-18 04:02:59 +00:00
jr z, .next
2014-05-25 17:26:42 +00:00
xor a
2015-07-25 03:27:59 +00:00
ld [wForcePlayerToChooseMon], a
inc a ; a = A_BUTTON
2014-05-25 17:26:42 +00:00
.next
2014-09-18 04:02:59 +00:00
ld [hli], a ; menu watched keys
2014-05-25 17:26:42 +00:00
pop af
2014-09-18 04:02:59 +00:00
ld [hl], a ; old menu item ID
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
HandlePartyMenuInput::
2014-05-25 17:26:42 +00:00
ld a,1
ld [wMenuWrappingEnabled],a
2014-05-25 17:26:42 +00:00
ld a,$40
2015-07-24 21:39:45 +00:00
ld [wPartyMenuAnimMonEnabled],a
call HandleMenuInput_
2014-05-25 17:26:42 +00:00
call PlaceUnfilledArrowMenuCursor
ld b,a
xor a
2015-07-24 21:39:45 +00:00
ld [wPartyMenuAnimMonEnabled],a
2014-05-25 17:26:42 +00:00
ld a,[wCurrentMenuItem]
2015-07-16 03:04:58 +00:00
ld [wPartyAndBillsPCSavedMenuItem],a
ld hl,wd730
2014-05-25 17:26:42 +00:00
res 6,[hl] ; turn on letter printing delay
2014-08-09 05:39:13 +00:00
ld a,[wMenuItemToSwap]
2014-05-25 17:26:42 +00:00
and a
jp nz,.swappingPokemon
pop af
2014-09-14 18:29:18 +00:00
ld [hTilesetType],a
2014-05-25 17:26:42 +00:00
bit 1,b
jr nz,.noPokemonChosen
ld a,[wPartyCount]
2014-05-25 17:26:42 +00:00
and a
jr z,.noPokemonChosen
ld a,[wCurrentMenuItem]
ld [wWhichPokemon],a
ld hl,wPartySpecies
2014-05-25 17:26:42 +00:00
ld b,0
ld c,a
add hl,bc
ld a,[hl]
ld [wcf91],a
ld [wBattleMonSpecies2],a
2014-05-25 17:26:42 +00:00
call BankswitchBack
and a
ret
.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
2014-08-09 05:39:13 +00:00
ld [wMenuItemToSwap],a
ld [wPartyMenuTypeOrMessageID],a
2014-05-25 17:26:42 +00:00
call RedrawPartyMenu
jr HandlePartyMenuInput
.handleSwap
ld a,[wCurrentMenuItem]
ld [wWhichPokemon],a
callba SwitchPartyMon
jr HandlePartyMenuInput
2016-06-12 00:24:04 +00:00
DrawPartyMenu::
2014-05-25 17:26:42 +00:00
ld hl, DrawPartyMenu_
jr DrawPartyMenuCommon
2016-06-12 00:24:04 +00:00
RedrawPartyMenu::
2014-05-25 17:26:42 +00:00
ld hl, RedrawPartyMenu_
2016-06-12 00:24:04 +00:00
DrawPartyMenuCommon::
2014-05-25 17:26:42 +00:00
ld b, BANK(RedrawPartyMenu_)
jp Bankswitch
; prints a pokemon's status condition
; INPUT:
; de = address of status condition
; hl = destination address
2016-06-12 00:24:04 +00:00
PrintStatusCondition::
2014-05-25 17:26:42 +00:00
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
2016-06-12 18:35:21 +00:00
PrintStatusConditionNotFainted:
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
ld a,BANK(PrintStatusAilment)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call PrintStatusAilment ; print status condition
pop bc
ld a,b
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
; function to print pokemon level, leaving off the ":L" if the level is at least 100
; INPUT:
; hl = destination address
2015-02-08 02:37:40 +00:00
; [wLoadedMonLevel] = level
2016-06-12 00:24:04 +00:00
PrintLevel::
2014-05-25 17:26:42 +00:00
ld a,$6e ; ":L" tile ID
ld [hli],a
ld c,2 ; number of digits
2015-02-08 02:37:40 +00:00
ld a,[wLoadedMonLevel] ; level
2016-06-12 18:35:21 +00:00
cp 100
2014-05-25 17:26:42 +00:00
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
2015-02-08 02:37:40 +00:00
; [wLoadedMonLevel] = level
2016-06-12 00:24:04 +00:00
PrintLevelFull::
2014-05-25 17:26:42 +00:00
ld a,$6e ; ":L" tile ID
ld [hli],a
ld c,3 ; number of digits
2015-02-08 02:37:40 +00:00
ld a,[wLoadedMonLevel] ; level
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
PrintLevelCommon::
ld [wd11e],a
ld de,wd11e
2015-07-28 01:48:44 +00:00
ld b,LEFT_ALIGN | 1 ; 1 byte
2014-05-25 17:26:42 +00:00
jp PrintNumber
2016-06-12 00:24:04 +00:00
GetwMoves::
; Unused. Returns the move at index a from wMoves in a
2015-02-08 08:17:03 +00:00
ld hl,wMoves
2014-05-25 17:26:42 +00:00
ld c,a
ld b,0
add hl,bc
ld a,[hl]
ret
2015-08-31 02:38:41 +00:00
; copies the base stat data of a pokemon to wMonHeader
2014-05-25 17:26:42 +00:00
; INPUT:
; [wd0b5] = pokemon ID
2016-06-12 00:24:04 +00:00
GetMonHeader::
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
ld a,BANK(BaseStats)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
push bc
push de
push hl
ld a,[wd11e]
2014-05-25 17:26:42 +00:00
push af
ld a,[wd0b5]
ld [wd11e],a
2014-05-25 17:26:42 +00:00
ld de,FossilKabutopsPic
ld b,$66 ; size of Kabutops fossil and Ghost sprites
2016-06-12 18:35:21 +00:00
cp FOSSIL_KABUTOPS ; Kabutops fossil
2014-05-25 17:26:42 +00:00
jr z,.specialID
ld de,GhostPic
2016-06-12 18:35:21 +00:00
cp MON_GHOST ; Ghost
2014-05-25 17:26:42 +00:00
jr z,.specialID
ld de,FossilAerodactylPic
ld b,$77 ; size of Aerodactyl fossil sprite
2016-06-12 18:35:21 +00:00
cp FOSSIL_AERODACTYL ; Aerodactyl fossil
2014-05-25 17:26:42 +00:00
jr z,.specialID
cp a,MEW
jr z,.mew
predef IndexToPokedex ; convert pokemon ID in [wd11e] to pokedex number
ld a,[wd11e]
2014-05-25 17:26:42 +00:00
dec a
2016-06-12 18:35:21 +00:00
ld bc, MonBaseStatsEnd - MonBaseStats
2014-05-25 17:26:42 +00:00
ld hl,BaseStats
call AddNTimes
2015-08-31 02:38:41 +00:00
ld de,wMonHeader
2016-06-12 18:35:21 +00:00
ld bc, MonBaseStatsEnd - MonBaseStats
2014-05-25 17:26:42 +00:00
call CopyData
jr .done
.specialID
2015-08-31 02:38:41 +00:00
ld hl,wMonHSpriteDim
2014-05-25 17:26:42 +00:00
ld [hl],b ; write sprite dimensions
inc hl
ld [hl],e ; write front sprite pointer
inc hl
ld [hl],d
jr .done
.mew
ld hl,MewBaseStats
2015-08-31 02:38:41 +00:00
ld de,wMonHeader
ld bc,MonBaseStatsEnd - MonBaseStats
2014-05-25 17:26:42 +00:00
ld a,BANK(MewBaseStats)
call FarCopyData
.done
ld a,[wd0b5]
2015-08-31 02:38:41 +00:00
ld [wMonHIndex],a
2014-05-25 17:26:42 +00:00
pop af
ld [wd11e],a
2014-05-25 17:26:42 +00:00
pop hl
pop de
pop bc
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
; copy party pokemon's name to wcd6d
2016-06-12 00:24:04 +00:00
GetPartyMonName2::
2014-05-25 17:26:42 +00:00
ld a,[wWhichPokemon] ; index within party
ld hl,wPartyMonNicks
2014-05-25 17:26:42 +00:00
; this is called more often
2016-06-12 00:24:04 +00:00
GetPartyMonName::
2014-05-25 17:26:42 +00:00
push hl
push bc
call SkipFixedLengthTextEntries ; add NAME_LENGTH to hl, a times
ld de,wcd6d
2014-05-25 17:26:42 +00:00
push de
ld bc,NAME_LENGTH
2014-05-25 17:26:42 +00:00
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.
2016-06-12 00:24:04 +00:00
PrintBCDNumber::
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
PrintBCDDigit::
2014-09-18 04:02:59 +00:00
and $f
2014-05-25 17:26:42 +00:00
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
2016-06-12 18:35:21 +00:00
add "0"
2014-05-25 17:26:42 +00:00
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)
2016-06-12 00:24:04 +00:00
UncompressMonSprite::
2015-08-31 02:38:41 +00:00
ld bc,wMonHeader
2014-05-25 17:26:42 +00:00
add hl,bc
ld a,[hli]
2015-08-31 02:38:41 +00:00
ld [wSpriteInputPtr],a ; fetch sprite input pointer
2014-05-25 17:26:42 +00:00
ld a,[hl]
2015-08-31 02:38:41 +00:00
ld [wSpriteInputPtr+1],a
2014-05-25 17:26:42 +00:00
; 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
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
LoadMonFrontSprite::
2014-05-25 17:26:42 +00:00
push de
2015-08-31 02:38:41 +00:00
ld hl, wMonHFrontSprite - wMonHeader
2014-05-25 17:26:42 +00:00
call UncompressMonSprite
2015-08-31 02:38:41 +00:00
ld hl, wMonHSpriteDim
2014-05-25 17:26:42 +00:00
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)
2016-06-12 00:24:04 +00:00
LoadUncompressedSpriteData::
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
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
xor a
ld [$4000], a
2015-08-31 03:15:32 +00:00
ld hl, sSpriteBuffer0
2014-05-25 17:26:42 +00:00
call ZeroSpriteBuffer ; zero buffer 0
2015-08-31 03:15:32 +00:00
ld de, sSpriteBuffer1
ld hl, sSpriteBuffer0
2014-05-25 17:26:42 +00:00
call AlignSpriteDataCentered ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite)
2015-08-31 03:15:32 +00:00
ld hl, sSpriteBuffer1
2014-05-25 17:26:42 +00:00
call ZeroSpriteBuffer ; zero buffer 1
2015-08-31 03:15:32 +00:00
ld de, sSpriteBuffer2
ld hl, sSpriteBuffer1
2014-05-25 17:26:42 +00:00
call AlignSpriteDataCentered ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite)
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
2016-06-12 00:24:04 +00:00
AlignSpriteDataCentered::
2014-05-25 17:26:42 +00:00
ld a, [H_SPRITEOFFSET]
ld b, $0
ld c, a
add hl, bc
ld a, [H_SPRITEWIDTH]
2014-05-25 17:26:42 +00:00
.columnLoop
push af
push hl
ld a, [H_SPRITEHEIGHT]
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
ZeroSpriteBuffer::
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
InterlaceMergeSpriteBuffers::
2014-05-25 17:26:42 +00:00
xor a
ld [$4000], a
push de
2015-08-31 03:15:32 +00:00
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
2014-05-25 17:26:42 +00:00
ld a, SPRITEBUFFERSIZE/2 ; $c4
ld [H_SPRITEINTERLACECOUNTER], a
2014-05-25 17:26:42 +00:00
.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]
2014-05-25 17:26:42 +00:00
dec a
ld [H_SPRITEINTERLACECOUNTER], a
2014-05-25 17:26:42 +00:00
jr nz, .interlaceLoop
2015-08-31 02:38:41 +00:00
ld a, [wSpriteFlipped]
2014-05-25 17:26:42 +00:00
and a
jr z, .notFlipped
ld bc, 2*SPRITEBUFFERSIZE
2015-08-31 03:15:32 +00:00
ld hl, sSpriteBuffer1
2014-05-25 17:26:42 +00:00
.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
2015-08-31 03:15:32 +00:00
ld de, sSpriteBuffer1
2014-05-25 17:26:42 +00:00
ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied
ld a, [H_LOADEDROMBANK]
ld b, a
jp CopyVideoData
2014-05-31 08:22:15 +00:00
INCLUDE "data/collision.asm"
INCLUDE "home/copy2.asm"
2014-05-31 02:52:24 +00:00
INCLUDE "home/text.asm"
2014-05-31 08:22:15 +00:00
INCLUDE "home/vcopy.asm"
INCLUDE "home/init.asm"
INCLUDE "home/vblank.asm"
INCLUDE "home/fade.asm"
INCLUDE "home/serial.asm"
INCLUDE "home/timer.asm"
2014-05-31 08:22:15 +00:00
INCLUDE "home/audio.asm"
2016-06-12 00:24:04 +00:00
UpdateSprites::
2014-09-13 07:50:56 +00:00
ld a, [wUpdateSpritesEnabled]
2014-05-31 08:22:15 +00:00
dec a
ret nz
ld a, [H_LOADEDROMBANK]
2014-05-25 17:26:42 +00:00
push af
2014-05-31 08:22:15 +00:00
ld a, Bank(_UpdateSprites)
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-31 08:22:15 +00:00
call _UpdateSprites
2014-05-25 17:26:42 +00:00
pop af
2014-05-31 08:22:15 +00:00
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-31 08:22:15 +00:00
ret
2014-05-25 17:26:42 +00:00
2014-05-31 08:22:15 +00:00
INCLUDE "data/mart_inventories.asm"
2016-06-12 00:24:04 +00:00
TextScriptEndingChar::
2014-05-31 08:22:15 +00:00
db "@"
2016-06-12 00:24:04 +00:00
TextScriptEnd::
2014-05-31 08:22:15 +00:00
ld hl,TextScriptEndingChar
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
ExclamationText::
2014-05-31 08:22:15 +00:00
TX_FAR _ExclamationText
db "@"
2016-06-12 00:24:04 +00:00
GroundRoseText::
2014-05-31 08:22:15 +00:00
TX_FAR _GroundRoseText
db "@"
2016-06-12 00:24:04 +00:00
BoulderText::
2014-05-31 08:22:15 +00:00
TX_FAR _BoulderText
db "@"
2016-06-12 00:24:04 +00:00
MartSignText::
2014-05-31 08:22:15 +00:00
TX_FAR _MartSignText
db "@"
2016-06-12 00:24:04 +00:00
PokeCenterSignText::
2014-05-31 08:22:15 +00:00
TX_FAR _PokeCenterSignText
db "@"
2016-06-12 00:24:04 +00:00
PickUpItemText::
2015-07-03 19:58:50 +00:00
TX_ASM
2015-07-18 15:17:29 +00:00
predef PickUpItem
2014-05-31 08:22:15 +00:00
jp TextScriptEnd
INCLUDE "home/pic.asm"
2016-06-12 00:24:04 +00:00
ResetPlayerSpriteData::
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
ld [hl], $3c ; set Y screen pos
inc hl
inc hl
ld [hl], $40 ; set X screen pos
ret
; overwrites sprite data with zeroes
2016-06-12 00:24:04 +00:00
ResetPlayerSpriteData_ClearSpriteData::
2014-05-25 17:26:42 +00:00
ld bc, $10
xor a
jp FillMemory
2016-06-12 00:24:04 +00:00
FadeOutAudio::
2015-08-09 05:32:44 +00:00
ld a, [wAudioFadeOutControl]
2016-06-12 18:35:21 +00:00
and a ; currently fading out audio?
jr nz, .fadingOut
ld a, [wd72c]
2014-05-25 17:26:42 +00:00
bit 1, a
ret nz
ld a, $77
2015-08-09 05:32:44 +00:00
ld [rNR50], a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 18:35:21 +00:00
.fadingOut
2015-08-09 05:32:44 +00:00
ld a, [wAudioFadeOutCounter]
2014-05-25 17:26:42 +00:00
and a
2015-08-09 05:32:44 +00:00
jr z, .counterReachedZero
2014-05-25 17:26:42 +00:00
dec a
2015-08-09 05:32:44 +00:00
ld [wAudioFadeOutCounter], a
2014-05-25 17:26:42 +00:00
ret
2015-08-09 05:32:44 +00:00
.counterReachedZero
ld a, [wAudioFadeOutCounterReloadValue]
ld [wAudioFadeOutCounter], a
ld a, [rNR50]
2016-06-12 18:35:21 +00:00
and a ; has the volume reached 0?
jr z, .fadeOutComplete
2014-05-25 17:26:42 +00:00
ld b, a
and $f
dec a
ld c, a
ld a, b
and $f0
swap a
dec a
swap a
or c
2015-08-09 05:32:44 +00:00
ld [rNR50], a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 18:35:21 +00:00
.fadeOutComplete
2015-08-09 05:32:44 +00:00
ld a, [wAudioFadeOutControl]
2014-05-25 17:26:42 +00:00
ld b, a
xor a
2015-08-09 05:32:44 +00:00
ld [wAudioFadeOutControl], a
2014-05-25 17:26:42 +00:00
ld a, $ff
2015-08-09 05:32:44 +00:00
ld [wNewSoundID], a
2014-05-25 17:26:42 +00:00
call PlaySound
2015-08-09 05:32:44 +00:00
ld a, [wAudioSavedROMBank]
ld [wAudioROMBank], a
2014-05-25 17:26:42 +00:00
ld a, b
2015-08-09 05:32:44 +00:00
ld [wNewSoundID], a
2014-05-25 17:26:42 +00:00
jp PlaySound
; this function is used to display sign messages, sprite dialog, etc.
2015-07-18 15:17:29 +00:00
; INPUT: [hSpriteIndexOrTextID] = sprite ID or text ID
2016-06-12 00:24:04 +00:00
DisplayTextID::
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
callba DisplayTextIDInit ; initialization
2015-07-15 06:16:06 +00:00
ld hl,wTextPredefFlag
2014-05-25 17:26:42 +00:00
bit 0,[hl]
res 0,[hl]
jr nz,.skipSwitchToMapBank
2015-08-31 02:38:41 +00:00
ld a,[wCurMap]
2014-05-25 17:26:42 +00:00
call SwitchToMapRomBank
.skipSwitchToMapBank
ld a,30 ; half a second
ld [H_FRAMECOUNTER],a ; used as joypad poll timer
2015-08-31 02:38:41 +00:00
ld hl,wMapTextPtr
2014-05-25 17:26:42 +00:00
ld a,[hli]
ld h,[hl]
ld l,a ; hl = map text pointer
ld d,$00
2015-07-18 15:17:29 +00:00
ld a,[hSpriteIndexOrTextID] ; text ID
2014-09-13 07:50:56 +00:00
ld [wSpriteIndex],a
2014-05-25 17:26:42 +00:00
and a
jp z,DisplayStartMenu
2016-06-12 18:35:21 +00:00
cp TEXT_SAFARI_GAME_OVER
2014-05-25 17:26:42 +00:00
jp z,DisplaySafariGameOverText
2016-06-12 18:35:21 +00:00
cp TEXT_MON_FAINTED
2014-05-25 17:26:42 +00:00
jp z,DisplayPokemonFaintedText
2016-06-12 18:35:21 +00:00
cp TEXT_BLACKED_OUT
2014-05-25 17:26:42 +00:00
jp z,DisplayPlayerBlackedOutText
2016-06-12 18:35:21 +00:00
cp TEXT_REPEL_WORE_OFF
2014-05-25 17:26:42 +00:00
jp z,DisplayRepelWoreOffText
2015-08-31 02:38:41 +00:00
ld a,[wNumSprites]
2014-05-25 17:26:42 +00:00
ld e,a
2015-07-18 15:17:29 +00:00
ld a,[hSpriteIndexOrTextID] ; sprite ID
2014-05-25 17:26:42 +00:00
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)
2014-05-25 17:26:42 +00:00
pop bc
pop de
2015-08-31 02:38:41 +00:00
ld hl,wMapSpriteData ; NPC text entries
2015-07-18 15:17:29 +00:00
ld a,[hSpriteIndexOrTextID]
2014-05-25 17:26:42 +00:00
dec a
add a
add l
ld l,a
jr nc,.noCarry
inc h
.noCarry
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
sla e
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
2016-06-12 18:35:21 +00:00
cp $fe ; Pokemart NPC
2014-05-25 17:26:42 +00:00
jp z,DisplayPokemartDialogue
2016-06-12 18:35:21 +00:00
cp $ff ; Pokemon Center NPC
2014-05-25 17:26:42 +00:00
jp z,DisplayPokemonCenterDialogue
2016-06-12 18:35:21 +00:00
cp $fc ; Item Storage PC
2014-05-25 17:26:42 +00:00
jp z,FuncTX_ItemStoragePC
2016-06-12 18:35:21 +00:00
cp $fd ; Bill's PC
2014-05-25 17:26:42 +00:00
jp z,FuncTX_BillsPC
2016-06-12 18:35:21 +00:00
cp $f9 ; Pokemon Center PC
2014-05-25 17:26:42 +00:00
jp z,FuncTX_PokemonCenterPC
2016-06-12 18:35:21 +00:00
cp $f5 ; Vending Machine
2014-05-25 17:26:42 +00:00
jr nz,.notVendingMachine
callba VendingMachineMenu ; jump banks to vending machine routine
2014-05-25 17:26:42 +00:00
jr AfterDisplayingTextID
.notVendingMachine
2016-06-12 18:35:21 +00:00
cp $f7 ; prize menu
jp z, FuncTX_GameCornerPrizeMenu
cp $f6 ; cable connection NPC in Pokemon Center
2014-05-25 17:26:42 +00:00
jr nz,.notSpecialCase
callab CableClubNPC
jr AfterDisplayingTextID
.notSpecialCase
2015-07-19 05:34:11 +00:00
call PrintText_NoCreatingTextBox ; display the text
2014-09-13 07:50:56 +00:00
ld a,[wDoNotWaitForButtonPressAfterDisplayingText]
2014-05-25 17:26:42 +00:00
and a
jr nz,HoldTextDisplayOpen
2016-06-12 00:24:04 +00:00
AfterDisplayingTextID::
2015-07-26 02:26:54 +00:00
ld a,[wEnteringCableClub]
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
HoldTextDisplayOpen::
2014-05-25 18:21:48 +00:00
call Joypad
2014-05-25 17:51:53 +00:00
ld a,[hJoyHeld]
2014-05-25 17:26:42 +00:00
bit 0,a ; is the A button being pressed?
jr nz,HoldTextDisplayOpen
2016-06-12 00:24:04 +00:00
CloseTextDisplay::
2015-08-31 02:38:41 +00:00
ld a,[wCurMap]
2014-05-25 17:26:42 +00:00
call SwitchToMapRomBank
ld a,$90
2014-09-23 22:02:03 +00:00
ld [hWY],a ; move the window off the screen
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
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
ld a,BANK(InitMapSprites)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns)
2015-02-09 02:40:08 +00:00
ld hl,wFontLoaded
2014-05-25 17:26:42 +00:00
res 0,[hl]
ld a,[wd732]
2014-09-13 07:50:56 +00:00
bit 3,a ; used fly warp
2014-05-25 17:26:42 +00:00
call z,LoadPlayerSpriteGraphics
call LoadCurrentMapView
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-09-13 07:50:56 +00:00
jp UpdateSprites
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
DisplayPokemartDialogue::
2014-05-25 17:26:42 +00:00
push hl
ld hl,PokemartGreetingText
call PrintText
pop hl
inc hl
call LoadItemList
2015-07-13 06:00:48 +00:00
ld a,PRICEDITEMLISTMENU
ld [wListMenuID],a
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
ld a,Bank(DisplayPokemartDialogue_)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call DisplayPokemartDialogue_
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
jp AfterDisplayingTextID
2016-06-12 00:24:04 +00:00
PokemartGreetingText::
2014-05-25 17:26:42 +00:00
TX_FAR _PokemartGreetingText
db "@"
2016-06-12 00:24:04 +00:00
LoadItemList::
2015-07-13 06:00:48 +00:00
ld a,1
2014-09-13 07:50:56 +00:00
ld [wUpdateSpritesEnabled],a
2014-05-25 17:26:42 +00:00
ld a,h
2015-07-13 06:00:48 +00:00
ld [wItemListPointer],a
2014-05-25 17:26:42 +00:00
ld a,l
2015-07-13 06:00:48 +00:00
ld [wItemListPointer + 1],a
2015-07-15 06:16:06 +00:00
ld de,wItemList
2014-05-25 17:26:42 +00:00
.loop
ld a,[hli]
ld [de],a
inc de
2016-06-12 18:35:21 +00:00
cp $ff
2014-05-25 17:26:42 +00:00
jr nz,.loop
ret
2016-06-12 00:24:04 +00:00
DisplayPokemonCenterDialogue::
2015-07-18 15:17:29 +00:00
; zeroing these doesn't appear to serve any purpose
2014-05-25 17:26:42 +00:00
xor a
ld [$ff8b],a
ld [$ff8c],a
ld [$ff8d],a
2015-07-18 15:17:29 +00:00
2014-05-25 17:26:42 +00:00
inc hl
ld a,[H_LOADEDROMBANK]
push af
ld a,Bank(DisplayPokemonCenterDialogue_)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call DisplayPokemonCenterDialogue_
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
jp AfterDisplayingTextID
2016-06-12 00:24:04 +00:00
DisplaySafariGameOverText::
2014-05-25 17:26:42 +00:00
callab PrintSafariGameOverText
jp AfterDisplayingTextID
2016-06-12 00:24:04 +00:00
DisplayPokemonFaintedText::
2014-05-25 17:26:42 +00:00
ld hl,PokemonFaintedText
call PrintText
jp AfterDisplayingTextID
2016-06-12 00:24:04 +00:00
PokemonFaintedText::
2014-05-25 17:26:42 +00:00
TX_FAR _PokemonFaintedText
db "@"
2016-06-12 00:24:04 +00:00
DisplayPlayerBlackedOutText::
2014-05-25 17:26:42 +00:00
ld hl,PlayerBlackedOutText
call PrintText
ld a,[wd732]
2014-09-13 07:50:56 +00:00
res 5,a ; reset forced to use bike bit
ld [wd732],a
2014-05-25 17:26:42 +00:00
jp HoldTextDisplayOpen
2016-06-12 00:24:04 +00:00
PlayerBlackedOutText::
2014-05-25 17:26:42 +00:00
TX_FAR _PlayerBlackedOutText
db "@"
2016-06-12 00:24:04 +00:00
DisplayRepelWoreOffText::
2014-05-25 17:26:42 +00:00
ld hl,RepelWoreOffText
call PrintText
jp AfterDisplayingTextID
2016-06-12 00:24:04 +00:00
RepelWoreOffText::
2014-05-25 17:26:42 +00:00
TX_FAR _RepelWoreOffText
db "@"
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:
2015-08-07 11:24:06 +00:00
; [wNumSetBits] = number of set bits
2016-06-12 00:24:04 +00:00
CountSetBits::
2014-05-25 17:26:42 +00:00
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
2015-08-07 11:24:06 +00:00
ld [wNumSetBits],a
2014-05-25 17:26:42 +00:00
ret
; subtracts the amount the player paid from their money
; sets carry flag if there is enough money and unsets carry flag if not
2016-06-12 00:24:04 +00:00
SubtractAmountPaidFromMoney::
2015-07-19 18:56:13 +00:00
jpba SubtractAmountPaidFromMoney_
2014-05-25 17:26:42 +00:00
; adds the amount the player sold to their money
2016-06-12 00:24:04 +00:00
AddAmountSoldToMoney::
2014-05-25 17:26:42 +00:00
ld de,wPlayerMoney + 2
ld hl,$ffa1 ; total price of items
ld c,3 ; length of money in bytes
predef AddBCDPredef ; add total price to money
2015-02-07 20:27:36 +00:00
ld a,MONEY_BOX
2015-02-07 10:43:08 +00:00
ld [wTextBoxID],a
2014-05-25 17:26:42 +00:00
call DisplayTextBoxID ; redraw money text box
2015-07-19 08:46:12 +00:00
ld a, SFX_PURCHASE
call PlaySoundWaitForCurrent
jp WaitForSoundToFinish
2014-05-25 17:26:42 +00:00
; 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
2015-07-13 06:00:48 +00:00
; [wItemQuantity] = quantity to remove
2016-06-12 00:24:04 +00:00
RemoveItemFromInventory::
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
ld a,BANK(RemoveItemFromInventory_)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call RemoveItemFromInventory_
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
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
2015-07-13 06:00:48 +00:00
; [wItemQuantity] = item quantity
2014-05-25 17:26:42 +00:00
; sets carry flag if successful, unsets carry flag if unsuccessful
2016-06-12 00:24:04 +00:00
AddItemToInventory::
2014-05-25 17:26:42 +00:00
push bc
ld a,[H_LOADEDROMBANK]
push af
ld a,BANK(AddItemToInventory_)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call AddItemToInventory_
pop bc
ld a,b
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
pop bc
ret
; INPUT:
; [wListMenuID] = list menu ID
2015-07-15 06:16:06 +00:00
; [wListPointer] = address of the list (2 bytes)
2016-06-12 00:24:04 +00:00
DisplayListMenuID::
2014-05-25 17:26:42 +00:00
xor a
ld [H_AUTOBGTRANSFERENABLED],a ; disable auto-transfer
ld a,1
ld [hJoy7],a ; joypad state update flag
2015-08-31 02:38:41 +00:00
ld a,[wBattleType]
2014-05-25 17:26:42 +00:00
and a ; is it the Old Man battle?
jr nz,.specialBattleType
ld a,$01 ; hardcoded bank
jr .bankswitch
.specialBattleType ; Old Man battle
2016-06-12 18:35:21 +00:00
ld a, BANK(DisplayBattleMenu)
2014-05-25 17:26:42 +00:00
.bankswitch
call BankswitchHome
ld hl,wd730
2014-05-25 17:26:42 +00:00
set 6,[hl] ; turn off letter printing delay
xor a
2014-08-09 05:39:13 +00:00
ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
2015-07-13 07:32:03 +00:00
ld [wListCount],a
2015-07-15 06:16:06 +00:00
ld a,[wListPointer]
2014-05-25 17:26:42 +00:00
ld l,a
2015-07-15 06:16:06 +00:00
ld a,[wListPointer + 1]
2014-05-25 17:26:42 +00:00
ld h,a ; hl = address of the list
2015-07-13 07:32:03 +00:00
ld a,[hl] ; the first byte is the number of entries in the list
ld [wListCount],a
2015-02-07 20:27:36 +00:00
ld a,LIST_MENU_BOX
2015-02-07 10:43:08 +00:00
ld [wTextBoxID],a
2014-05-25 17:26:42 +00:00
call DisplayTextBoxID ; draw the menu text box
call UpdateSprites ; disable sprites behind the text box
; the code up to .skipMovingSprites appears to be useless
2015-07-18 20:52:03 +00:00
coord hl, 4, 2 ; coordinates of upper left corner of menu text box
2015-08-05 21:20:29 +00:00
lb de, 9, 14 ; height and width of menu text box
2014-05-25 17:26:42 +00:00
ld a,[wListMenuID]
and a ; is it a PC pokemon list?
jr nz,.skipMovingSprites
call UpdateSprites
2014-05-25 17:26:42 +00:00
.skipMovingSprites
ld a,1 ; max menu item ID is 1 if the list has less than 2 entries
2015-07-13 07:32:03 +00:00
ld [wMenuWatchMovingOutOfBounds],a
ld a,[wListCount]
2016-06-12 18:35:21 +00:00
cp 2 ; does the list have less than 2 entries?
2014-05-25 17:26:42 +00:00
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
2014-09-18 04:02:59 +00:00
ld a,A_BUTTON | B_BUTTON | SELECT
2014-05-25 17:26:42 +00:00
ld [wMenuWatchedKeys],a
ld c,10
call DelayFrames
2016-06-12 00:24:04 +00:00
DisplayListMenuIDLoop::
2014-05-25 17:26:42 +00:00
xor a
ld [H_AUTOBGTRANSFERENABLED],a ; disable transfer
call PrintListMenuEntries
ld a,1
ld [H_AUTOBGTRANSFERENABLED],a ; enable transfer
call Delay3
2015-08-31 02:38:41 +00:00
ld a,[wBattleType]
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
ld c,80
call DelayFrames
xor a
ld [wCurrentMenuItem],a
2015-07-18 20:52:03 +00:00
coord hl, 5, 4
2014-05-25 17:26:42 +00:00
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
2015-07-13 06:00:48 +00:00
; pointless because both values are overwritten before they are read
2014-05-25 17:26:42 +00:00
ld a,$01
2015-07-13 06:00:48 +00:00
ld [wMenuExitMethod],a
2015-07-22 01:58:19 +00:00
ld [wChosenMenuItem],a
2015-07-13 06:00:48 +00:00
2014-05-25 17:26:42 +00:00
xor a
2015-07-13 07:32:03 +00:00
ld [wMenuWatchMovingOutOfBounds],a
2014-05-25 17:26:42 +00:00
ld a,[wCurrentMenuItem]
ld c,a
ld a,[wListScrollOffset]
add c
ld c,a
2015-07-13 07:32:03 +00:00
ld a,[wListCount]
2014-05-25 17:26:42 +00:00
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]
2016-06-12 18:35:21 +00:00
cp ITEMLISTMENU
2014-05-25 17:26:42 +00:00
jr nz,.skipMultiplying
; if it's an item menu
sla c ; item entries are 2 bytes long, so multiply by 2
.skipMultiplying
2015-07-15 06:16:06 +00:00
ld a,[wListPointer]
2014-05-25 17:26:42 +00:00
ld l,a
2015-07-15 06:16:06 +00:00
ld a,[wListPointer + 1]
2014-05-25 17:26:42 +00:00
ld h,a
inc hl ; hl = beginning of list entries
ld b,0
add hl,bc
ld a,[hl]
ld [wcf91],a
2014-05-25 17:26:42 +00:00
ld a,[wListMenuID]
and a ; is it a PC pokemon list?
jr z,.pokemonList
push hl
call GetItemPrice
pop hl
ld a,[wListMenuID]
2016-06-12 18:35:21 +00:00
cp ITEMLISTMENU
2014-05-25 17:26:42 +00:00
jr nz,.skipGettingQuantity
; if it's an item menu
inc hl
ld a,[hl] ; a = item quantity
2015-07-13 06:00:48 +00:00
ld [wMaxItemQuantity],a
2014-05-25 17:26:42 +00:00
.skipGettingQuantity
ld a,[wcf91]
ld [wd0b5],a
ld a,BANK(ItemNames)
ld [wPredefBank],a
2014-05-25 17:26:42 +00:00
call GetName
jr .storeChosenEntry
.pokemonList
ld hl,wPartyCount
2015-07-15 06:16:06 +00:00
ld a,[wListPointer]
2014-05-25 17:26:42 +00:00
cp l ; is it a list of party pokemon or box pokemon?
ld hl,wPartyMonNicks
2014-05-25 17:26:42 +00:00
jr z,.getPokemonName
ld hl, wBoxMonNicks ; box pokemon names
2014-05-25 17:26:42 +00:00
.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
2015-07-13 06:00:48 +00:00
ld a,CHOSE_MENU_ITEM
ld [wMenuExitMethod],a
2014-05-25 17:26:42 +00:00
ld a,[wCurrentMenuItem]
2015-07-13 06:00:48 +00:00
ld [wChosenMenuItem],a
2014-05-25 17:26:42 +00:00
xor a
ld [hJoy7],a ; joypad state update flag
ld hl,wd730
2014-05-25 17:26:42 +00:00
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]
2016-06-12 18:35:21 +00:00
add 3
2014-05-25 17:26:42 +00:00
ld b,a
2015-07-13 07:32:03 +00:00
ld a,[wListCount]
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
DisplayChooseQuantityMenu::
2014-05-25 17:26:42 +00:00
; text box dimensions/coordinates for just quantity
2015-07-18 20:52:03 +00:00
coord hl, 15, 9
2014-05-25 17:26:42 +00:00
ld b,1 ; height
ld c,3 ; width
ld a,[wListMenuID]
2016-06-12 18:35:21 +00:00
cp PRICEDITEMLISTMENU
2014-05-25 17:26:42 +00:00
jr nz,.drawTextBox
; text box dimensions/coordinates for quantity and price
2015-07-18 20:52:03 +00:00
coord hl, 7, 9
2014-05-25 17:26:42 +00:00
ld b,1 ; height
ld c,11 ; width
.drawTextBox
call TextBoxBorder
2015-07-18 20:52:03 +00:00
coord hl, 16, 10
2014-05-25 17:26:42 +00:00
ld a,[wListMenuID]
2016-06-12 18:35:21 +00:00
cp PRICEDITEMLISTMENU
2014-05-25 17:26:42 +00:00
jr nz,.printInitialQuantity
2015-07-18 20:52:03 +00:00
coord hl, 8, 10
2014-05-25 17:26:42 +00:00
.printInitialQuantity
ld de,InitialQuantityText
call PlaceString
xor a
2015-07-13 06:00:48 +00:00
ld [wItemQuantity],a ; initialize current quantity to 0
2014-05-25 17:26:42 +00:00
jp .incrementQuantity
.waitForKeyPressLoop
2014-05-25 18:21:48 +00:00
call JoypadLowSensitivity
2014-05-25 17:51:53 +00:00
ld a,[hJoyPressed] ; newly pressed buttons
2014-05-25 17:26:42 +00:00
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
2015-07-13 06:00:48 +00:00
ld a,[wMaxItemQuantity]
2014-05-25 17:26:42 +00:00
inc a
ld b,a
2015-07-13 06:00:48 +00:00
ld hl,wItemQuantity ; current quantity
2014-05-25 17:26:42 +00:00
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
2015-07-13 06:00:48 +00:00
ld hl,wItemQuantity ; current quantity
2014-05-25 17:26:42 +00:00
dec [hl]
jr nz,.handleNewQuantity
; wrap to the max quantity if the player goes below 1
2015-07-13 06:00:48 +00:00
ld a,[wMaxItemQuantity]
2014-05-25 17:26:42 +00:00
ld [hl],a
.handleNewQuantity
2015-07-18 20:52:03 +00:00
coord hl, 17, 10
2014-05-25 17:26:42 +00:00
ld a,[wListMenuID]
2016-06-12 18:35:21 +00:00
cp PRICEDITEMLISTMENU
2014-05-25 17:26:42 +00:00
jr nz,.printQuantity
.printPrice
ld c,$03
2015-07-13 06:00:48 +00:00
ld a,[wItemQuantity]
2014-05-25 17:26:42 +00:00
ld b,a
2015-07-17 08:21:40 +00:00
ld hl,hMoney ; total price
2014-05-25 17:26:42 +00:00
; 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
2015-07-17 08:21:40 +00:00
ld de,hMoney + 2
ld hl,hItemPrice + 2
2014-05-25 17:26:42 +00:00
push bc
predef AddBCDPredef ; add the individual price to the current sum
2014-05-25 17:26:42 +00:00
pop bc
dec b
jr nz,.addLoop
2015-07-13 06:00:48 +00:00
ld a,[hHalveItemPrices]
2014-05-25 17:26:42 +00:00
and a ; should the price be halved (for selling items)?
jr z,.skipHalvingPrice
xor a
2015-07-17 08:21:40 +00:00
ld [hDivideBCDDivisor],a
ld [hDivideBCDDivisor + 1],a
2014-05-25 17:26:42 +00:00
ld a,$02
2015-07-17 08:21:40 +00:00
ld [hDivideBCDDivisor + 2],a
predef DivideBCDPredef3 ; halves the price
2014-05-25 17:26:42 +00:00
; store the halved price
2015-07-17 08:21:40 +00:00
ld a,[hDivideBCDQuotient]
ld [hMoney],a
ld a,[hDivideBCDQuotient + 1]
ld [hMoney + 1],a
ld a,[hDivideBCDQuotient + 2]
ld [hMoney + 2],a
2014-05-25 17:26:42 +00:00
.skipHalvingPrice
2015-07-18 20:52:03 +00:00
coord hl, 12, 10
2014-05-25 17:26:42 +00:00
ld de,SpacesBetweenQuantityAndPriceText
call PlaceString
2015-07-17 08:21:40 +00:00
ld de,hMoney ; total price
2014-05-25 17:26:42 +00:00
ld c,$a3
call PrintBCDNumber
2015-07-18 20:52:03 +00:00
coord hl, 9, 10
2014-05-25 17:26:42 +00:00
.printQuantity
2015-07-13 06:00:48 +00:00
ld de,wItemQuantity ; current quantity
2015-08-05 21:20:29 +00:00
lb bc, LEADING_ZEROES | 1, 2 ; 1 byte, 2 digits
2014-05-25 17:26:42 +00:00
call PrintNumber
jp .waitForKeyPressLoop
.buttonAPressed ; the player chose to make the transaction
xor a
2014-08-09 05:39:13 +00:00
ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
2014-05-25 17:26:42 +00:00
ret
.buttonBPressed ; the player chose to cancel the transaction
xor a
2014-08-09 05:39:13 +00:00
ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
2014-05-25 17:26:42 +00:00
ld a,$ff
ret
2016-06-12 00:24:04 +00:00
InitialQuantityText::
2014-05-25 17:26:42 +00:00
db "×01@"
2016-06-12 00:24:04 +00:00
SpacesBetweenQuantityAndPriceText::
2014-05-25 17:26:42 +00:00
db " @"
2016-06-12 00:24:04 +00:00
ExitListMenu::
2014-05-25 17:26:42 +00:00
ld a,[wCurrentMenuItem]
2015-07-13 06:00:48 +00:00
ld [wChosenMenuItem],a
ld a,CANCELLED_MENU
ld [wMenuExitMethod],a
2015-07-13 07:32:03 +00:00
ld [wMenuWatchMovingOutOfBounds],a
2014-05-25 17:26:42 +00:00
xor a
ld [hJoy7],a
ld hl,wd730
2014-05-25 17:26:42 +00:00
res 6,[hl]
call BankswitchBack
xor a
2014-08-09 05:39:13 +00:00
ld [wMenuItemToSwap],a ; 0 means no item is currently being swapped
2014-05-25 17:26:42 +00:00
scf
ret
2016-06-12 00:24:04 +00:00
PrintListMenuEntries::
2015-07-18 20:52:03 +00:00
coord hl, 5, 3
2015-08-05 21:20:29 +00:00
ld b,9
ld c,14
2014-05-25 17:26:42 +00:00
call ClearScreenArea
2015-07-15 06:16:06 +00:00
ld a,[wListPointer]
2014-05-25 17:26:42 +00:00
ld e,a
2015-07-15 06:16:06 +00:00
ld a,[wListPointer + 1]
2014-05-25 17:26:42 +00:00
ld d,a
inc de ; de = beginning of list entries
ld a,[wListScrollOffset]
ld c,a
ld a,[wListMenuID]
2016-06-12 18:35:21 +00:00
cp ITEMLISTMENU
2014-05-25 17:26:42 +00:00
ld a,c
jr nz,.skipMultiplying
; if it's an item menu
; item entries are 2 bytes long, so multiply by 2
sla a
sla c
.skipMultiplying
add e
ld e,a
jr nc,.noCarry
inc d
.noCarry
2015-07-18 20:52:03 +00:00
coord hl, 6, 4 ; coordinates of first list entry name
2014-05-25 17:26:42 +00:00
ld b,4 ; print 4 names
.loop
ld a,b
ld [wWhichPokemon],a
ld a,[de]
ld [wd11e],a
2016-06-12 18:35:21 +00:00
cp $ff
2014-05-25 17:26:42 +00:00
jp z,.printCancelMenuItem
push bc
push de
push hl
push hl
push de
ld a,[wListMenuID]
and a
jr z,.pokemonPCMenu
2016-06-12 18:35:21 +00:00
cp MOVESLISTMENU
2014-05-25 17:26:42 +00:00
jr z,.movesMenu
.itemMenu
call GetItemName
jr .placeNameString
.pokemonPCMenu
push hl
ld hl,wPartyCount
2015-07-15 06:16:06 +00:00
ld a,[wListPointer]
2014-05-25 17:26:42 +00:00
cp l ; is it a list of party pokemon or box pokemon?
ld hl,wPartyMonNicks
2014-05-25 17:26:42 +00:00
jr z,.getPokemonName
ld hl, wBoxMonNicks ; box pokemon names
2014-05-25 17:26:42 +00:00
.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
2015-07-13 06:00:48 +00:00
ld a,[wPrintItemPrices]
2014-05-25 17:26:42 +00:00
and a ; should prices be printed?
jr z,.skipPrintingItemPrice
.printItemPrice
push hl
ld a,[de]
ld de,ItemPrices
ld [wcf91],a
2014-05-25 17:26:42 +00:00
call GetItemPrice ; get price
pop hl
2015-08-05 21:20:29 +00:00
ld bc, SCREEN_WIDTH + 5 ; 1 row down and 5 columns right
2014-05-25 17:26:42 +00:00
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]
2014-05-25 17:26:42 +00:00
push af
push hl
ld hl,wPartyCount
2015-07-15 06:16:06 +00:00
ld a,[wListPointer]
2014-05-25 17:26:42 +00:00
cp l ; is it a list of party pokemon or box pokemon?
2015-07-16 03:04:58 +00:00
ld a,PLAYER_PARTY_DATA
2014-05-25 17:26:42 +00:00
jr z,.next
2015-07-16 03:04:58 +00:00
ld a,BOX_DATA
2014-05-25 17:26:42 +00:00
.next
2015-07-16 03:04:58 +00:00
ld [wMonDataLocation],a
2014-05-25 17:26:42 +00:00
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
2015-08-05 21:20:29 +00:00
call LoadMonData
2015-07-16 03:04:58 +00:00
ld a,[wMonDataLocation]
2014-05-25 17:26:42 +00:00
and a ; is it a list of party pokemon or box pokemon?
jr z,.skipCopyingLevel
.copyLevel
2015-02-08 02:37:40 +00:00
ld a,[wLoadedMonBoxLevel]
ld [wLoadedMonLevel],a
2014-05-25 17:26:42 +00:00
.skipCopyingLevel
pop hl
ld bc,$001c
add hl,bc
2015-08-05 21:20:29 +00:00
call PrintLevel
2014-05-25 17:26:42 +00:00
pop af
ld [wd11e],a
2014-05-25 17:26:42 +00:00
.skipPrintingPokemonLevel
pop hl
pop de
inc de
ld a,[wListMenuID]
2016-06-12 18:35:21 +00:00
cp ITEMLISTMENU
2014-05-25 17:26:42 +00:00
jr nz,.nextListEntry
.printItemQuantity
ld a,[wd11e]
ld [wcf91],a
2014-05-25 17:26:42 +00:00
call IsKeyItem ; check if item is unsellable
2015-07-13 06:00:48 +00:00
ld a,[wIsKeyItem]
2014-05-25 17:26:42 +00:00
and a ; is the item unsellable?
jr nz,.skipPrintingItemQuantity ; if so, don't print the quantity
push hl
2015-08-05 21:20:29 +00:00
ld bc, SCREEN_WIDTH + 8 ; 1 row down and 8 columns right
2014-05-25 17:26:42 +00:00
add hl,bc
ld a,"×"
2014-09-18 04:02:59 +00:00
ld [hli],a
ld a,[wd11e]
2014-05-25 17:26:42 +00:00
push af
ld a,[de]
2015-07-13 06:00:48 +00:00
ld [wMaxItemQuantity],a
2014-05-25 17:26:42 +00:00
push de
ld de,wd11e
2014-05-25 17:26:42 +00:00
ld [de],a
2015-07-28 01:48:44 +00:00
lb bc, 1, 2
2014-05-25 17:26:42 +00:00
call PrintNumber
pop de
pop af
ld [wd11e],a
2014-05-25 17:26:42 +00:00
pop hl
.skipPrintingItemQuantity
inc de
pop bc
inc c
push bc
inc c
2014-08-09 05:39:13 +00:00
ld a,[wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
2014-05-25 17:26:42 +00:00
and a ; is an item being swapped?
jr z,.nextListEntry
sla 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
2015-08-05 21:20:29 +00:00
ld bc,2 * SCREEN_WIDTH ; 2 rows
2014-05-25 17:26:42 +00:00
add hl,bc
pop bc
inc c
dec b
jp nz,.loop
ld bc,-8
add hl,bc
2016-07-18 06:17:03 +00:00
ld a,"▼"
2014-05-25 17:26:42 +00:00
ld [hl],a
ret
.printCancelMenuItem
ld de,ListMenuCancelText
jp PlaceString
2016-06-12 00:24:04 +00:00
ListMenuCancelText::
2014-05-25 17:26:42 +00:00
db "CANCEL@"
2016-06-12 00:24:04 +00:00
GetMonName::
2014-05-25 17:26:42 +00:00
push hl
ld a,[H_LOADEDROMBANK]
push af
2015-08-05 21:20:29 +00:00
ld a,BANK(MonsterNames)
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
ld a,[wd11e]
2014-05-25 17:26:42 +00:00
dec a
2015-08-05 21:20:29 +00:00
ld hl,MonsterNames
2014-05-25 17:26:42 +00:00
ld c,10
ld b,0
call AddNTimes
ld de,wcd6d
2014-05-25 17:26:42 +00:00
push de
ld bc,10
call CopyData
2015-07-15 06:16:06 +00:00
ld hl,wcd6d + 10
2014-05-25 17:26:42 +00:00
ld [hl], "@"
pop de
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
pop hl
ret
2016-06-12 00:24:04 +00:00
GetItemName::
; given an item ID at [wd11e], store the name of the item into a string
; starting at wcd6d
2014-05-25 17:26:42 +00:00
push hl
push bc
ld a,[wd11e]
2014-05-25 17:26:42 +00:00
cp HM_01 ; is this a TM/HM?
jr nc,.Machine
ld [wd0b5],a
2014-05-25 17:26:42 +00:00
ld a,ITEM_NAME
2015-02-08 09:44:41 +00:00
ld [wNameListType],a
2014-05-25 17:26:42 +00:00
ld a,BANK(ItemNames)
ld [wPredefBank],a
2014-05-25 17:26:42 +00:00
call GetName
jr .Finish
.Machine
call GetMachineName
.Finish
ld de,wcd6d ; pointer to where item name is stored in RAM
2014-05-25 17:26:42 +00:00
pop bc
pop hl
ret
2016-06-12 00:24:04 +00:00
GetMachineName::
; copies the name of the TM/HM in [wd11e] to wcd6d
2014-05-25 17:26:42 +00:00
push hl
push de
push bc
ld a,[wd11e]
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
call CopyData
; now get the machine number and convert it to text
ld a,[wd11e]
2014-05-25 17:26:42 +00:00
sub TM_01 - 1
2015-08-05 21:20:29 +00:00
ld b, "0"
2014-05-25 17:26:42 +00:00
.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
2015-08-05 21:20:29 +00:00
ld b, "0"
2014-05-25 17:26:42 +00:00
add b
ld [de],a
inc de
ld a,"@"
ld [de],a
pop af
ld [wd11e],a
2014-05-25 17:26:42 +00:00
pop bc
pop de
pop hl
ret
2016-06-12 00:24:04 +00:00
TechnicalPrefix::
2014-05-25 17:26:42 +00:00
db "TM"
2016-06-12 00:24:04 +00:00
HiddenPrefix::
2014-05-25 17:26:42 +00:00
db "HM"
; sets carry if item is HM, clears carry if item is not HM
; Input: a = item ID
2016-06-12 00:24:04 +00:00
IsItemHM::
2016-06-12 18:35:21 +00:00
cp HM_01
2014-05-25 17:26:42 +00:00
jr c,.notHM
2016-06-12 18:35:21 +00:00
cp TM_01
2014-05-25 17:26:42 +00:00
ret
.notHM
and a
ret
; sets carry if move is an HM, clears carry if move is not an HM
; Input: a = move ID
2016-06-12 00:24:04 +00:00
IsMoveHM::
2014-05-25 17:26:42 +00:00
ld hl,HMMoves
ld de,1
jp IsInArray
2016-06-12 00:24:04 +00:00
HMMoves::
2014-05-25 17:26:42 +00:00
db CUT,FLY,SURF,STRENGTH,FLASH
db $ff ; terminator
2016-06-12 00:24:04 +00:00
GetMoveName::
2014-05-25 17:26:42 +00:00
push hl
ld a,MOVE_NAME
2015-02-08 09:44:41 +00:00
ld [wNameListType],a
ld a,[wd11e]
ld [wd0b5],a
2014-05-25 17:26:42 +00:00
ld a,BANK(MoveNames)
ld [wPredefBank],a
2014-05-25 17:26:42 +00:00
call GetName
ld de,wcd6d ; pointer to where move name is stored in RAM
2014-05-25 17:26:42 +00:00
pop hl
ret
; reloads text box tile patterns, current map view, and tileset tile patterns
2016-06-12 00:24:04 +00:00
ReloadMapData::
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
2015-08-31 02:38:41 +00:00
ld a,[wCurMap]
2014-05-25 17:26:42 +00:00
call SwitchToMapRomBank
call DisableLCD
call LoadTextBoxTilePatterns
call LoadCurrentMapView
call LoadTilesetTilePatternData
call EnableLCD
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
; reloads tileset tile patterns
2016-06-12 00:24:04 +00:00
ReloadTilesetTilePatterns::
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
2015-08-31 02:38:41 +00:00
ld a,[wCurMap]
2014-05-25 17:26:42 +00:00
call SwitchToMapRomBank
call DisableLCD
call LoadTilesetTilePatternData
call EnableLCD
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
; shows the town map and lets the player choose a destination to fly to
2016-06-12 00:24:04 +00:00
ChooseFlyDestination::
ld hl,wd72e
2014-05-25 17:26:42 +00:00
res 4,[hl]
2015-07-19 18:56:13 +00:00
jpba LoadTownMap_Fly
2014-05-25 17:26:42 +00:00
2014-08-09 05:39:13 +00:00
; causes the text box to close without waiting for a button press after displaying text
2016-06-12 00:24:04 +00:00
DisableWaitingAfterTextDisplay::
2014-05-25 17:26:42 +00:00
ld a,$01
2014-09-13 07:50:56 +00:00
ld [wDoNotWaitForButtonPressAfterDisplayingText],a
2014-05-25 17:26:42 +00:00
ret
; uses an item
; UseItem is used with dummy items to perform certain other functions as well
; INPUT:
; [wcf91] = item ID
2014-05-25 17:26:42 +00:00
; OUTPUT:
2015-07-15 06:16:06 +00:00
; [wActionResultOrTookBattleTurn] = success
2014-05-25 17:26:42 +00:00
; 00: unsucessful
; 01: successful
; 02: not able to be used right now, no extra menu displayed (only certain items use this)
2016-06-12 00:24:04 +00:00
UseItem::
2015-07-19 18:56:13 +00:00
jpba UseItem_
2014-05-25 17:26:42 +00:00
; 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
2015-07-13 06:00:48 +00:00
; [wItemQuantity] = quantity to toss
2014-05-25 17:26:42 +00:00
; OUTPUT:
; clears carry flag if the item is tossed, sets carry flag if not
2016-06-12 00:24:04 +00:00
TossItem::
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
ld a,BANK(TossItem_)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call TossItem_
pop de
ld a,d
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
; checks if an item is a key item
; INPUT:
; [wcf91] = item ID
2014-05-25 17:26:42 +00:00
; OUTPUT:
2015-07-13 06:00:48 +00:00
; [wIsKeyItem] = result
2014-05-25 17:26:42 +00:00
; 00: item is not key item
; 01: item is key item
2016-06-12 00:24:04 +00:00
IsKeyItem::
2014-05-25 17:26:42 +00:00
push hl
push de
push bc
callba IsKeyItem_
pop bc
pop de
pop hl
ret
; function to draw various text boxes
; INPUT:
2015-02-07 10:43:08 +00:00
; [wTextBoxID] = text box ID
2015-08-05 21:20:29 +00:00
; b, c = y, x cursor position (TWO_OPTION_MENU only)
2016-06-12 00:24:04 +00:00
DisplayTextBoxID::
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
ld a,BANK(DisplayTextBoxID_)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call DisplayTextBoxID_
pop bc
ld a,b
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
2014-09-14 18:29:18 +00:00
; 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
2016-06-12 00:24:04 +00:00
IsPlayerCharacterBeingControlledByGame::
ld a, [wNPCMovementScriptPointerTableNum]
2014-05-25 17:26:42 +00:00
and a
ret nz
ld a, [wd736]
2014-09-14 18:29:18 +00:00
bit 1, a ; currently stepping down from door bit
2014-05-25 17:26:42 +00:00
ret nz
ld a, [wd730]
2014-05-25 17:26:42 +00:00
and $80
ret
2016-06-12 00:24:04 +00:00
RunNPCMovementScript::
ld hl, wd736
2014-05-25 17:26:42 +00:00
bit 0, [hl]
res 0, [hl]
jr nz, .playerStepOutFromDoor
ld a, [wNPCMovementScriptPointerTableNum]
2014-05-25 17:26:42 +00:00
and a
ret z
dec a
add a
ld d, 0
2014-05-25 17:26:42 +00:00
ld e, a
ld hl, .NPCMovementScriptPointerTables
2014-05-25 17:26:42 +00:00
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [H_LOADEDROMBANK]
push af
ld a, [wNPCMovementScriptBank]
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
ld a, [wNPCMovementScriptFunctionNum]
2014-05-25 17:26:42 +00:00
call CallFunctionInTable
pop af
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 18:35:21 +00:00
.NPCMovementScriptPointerTables
2015-07-15 20:58:21 +00:00
dw PalletMovementScriptPointerTable
dw PewterMuseumGuyMovementScriptPointerTable
dw PewterGymGuyMovementScriptPointerTable
.playerStepOutFromDoor
2015-07-19 18:56:13 +00:00
jpba PlayerStepOutFromDoor
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
EndNPCMovementScript::
2015-07-19 18:56:13 +00:00
jpba _EndNPCMovementScript
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
EmptyFunc2::
2014-05-25 17:26:42 +00:00
ret
2015-08-31 02:38:41 +00:00
; stores hl in [wTrainerHeaderPtr]
2016-06-12 00:24:04 +00:00
StoreTrainerHeaderPointer::
2014-05-25 17:26:42 +00:00
ld a, h
2015-08-31 02:38:41 +00:00
ld [wTrainerHeaderPtr], a
2014-05-25 17:26:42 +00:00
ld a, l
2015-08-31 02:38:41 +00:00
ld [wTrainerHeaderPtr+1], a
2014-05-25 17:26:42 +00:00
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)
2016-06-12 00:24:04 +00:00
ExecuteCurMapScriptInTable::
2014-05-25 17:26:42 +00:00
push af
push de
call StoreTrainerHeaderPointer
pop hl
pop af
push hl
2015-08-31 02:38:41 +00:00
ld hl, wFlags_D733
2014-05-25 17:26:42 +00:00
bit 4, [hl]
res 4, [hl]
jr z, .useProvidedIndex ; test if map script index was overridden manually
2015-08-31 02:38:41 +00:00
ld a, [wCurMapScript]
2014-05-25 17:26:42 +00:00
.useProvidedIndex
pop hl
2015-08-31 02:38:41 +00:00
ld [wCurMapScript], a
2014-05-25 17:26:42 +00:00
call CallFunctionInTable
2015-08-31 02:38:41 +00:00
ld a, [wCurMapScript]
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
LoadGymLeaderAndCityName::
2014-05-25 17:26:42 +00:00
push de
ld de, wGymCityName
ld bc, $11
call CopyData ; load city name
pop hl
ld de, wGymLeaderName
ld bc, NAME_LENGTH
2014-05-25 17:26:42 +00:00
jp CopyData ; load gym leader name
2015-08-31 02:38:41 +00:00
; reads specific information from trainer header (pointed to at wTrainerHeaderPtr)
2014-05-25 17:26:42 +00:00
; 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)
2016-06-12 00:24:04 +00:00
ReadTrainerHeaderInfo::
2014-05-25 17:26:42 +00:00
push de
push af
ld d, $0
ld e, a
2015-08-31 02:38:41 +00:00
ld hl, wTrainerHeaderPtr
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
TalkToTrainer::
2014-05-25 17:26:42 +00:00
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
2015-07-20 03:45:34 +00:00
ld b, FLAG_TEST
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
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
2014-09-14 18:29:18 +00:00
call SaveEndBattleTextPointers
2015-08-31 02:38:41 +00:00
ld hl, wFlags_D733
2014-05-25 17:26:42 +00:00
set 4, [hl] ; activate map script index override (index is set below)
ld hl, wFlags_0xcd60
2014-09-14 18:29:18 +00:00
bit 0, [hl] ; test if player is already engaging the trainer (because the trainer saw the player)
2014-05-25 17:26:42 +00:00
ret nz
2014-09-14 18:29:18 +00:00
; if the player talked to the trainer of his own volition
2014-05-25 17:26:42 +00:00
call EngageMapTrainer
2015-08-31 02:38:41 +00:00
ld hl, wCurMapScript
2014-09-14 18:29:18 +00:00
inc [hl] ; increment map script index before StartTrainerBattle increments it again (next script function is usually EndTrainerBattle)
jp StartTrainerBattle
2014-05-25 17:26:42 +00:00
; checks if any trainers are seeing the player and wanting to fight
2016-06-12 00:24:04 +00:00
CheckFightingMapTrainers::
2014-05-25 17:26:42 +00:00
call CheckForEngagingTrainers
2014-09-13 07:50:56 +00:00
ld a, [wSpriteIndex]
2014-05-25 17:26:42 +00:00
cp $ff
jr nz, .trainerEngaging
xor a
2014-09-13 07:50:56 +00:00
ld [wSpriteIndex], a
2014-05-25 17:26:42 +00:00
ld [wTrainerHeaderFlagBit], a
ret
.trainerEngaging
2015-08-31 02:38:41 +00:00
ld hl, wFlags_D733
2014-05-25 17:26:42 +00:00
set 3, [hl]
ld [wEmotionBubbleSpriteIndex], a
xor a ; EXCLAMATION_BUBBLE
ld [wWhichEmotionBubble], a
predef EmotionBubble
2014-05-25 17:26:42 +00:00
ld a, D_RIGHT | D_LEFT | D_UP | D_DOWN
2014-05-25 17:51:53 +00:00
ld [wJoyIgnore], a
2014-05-25 17:26:42 +00:00
xor a
2015-07-03 20:13:35 +00:00
ld [hJoyHeld], a
2014-05-25 17:26:42 +00:00
call TrainerWalkUpToPlayer_Bank0
2015-08-31 02:38:41 +00:00
ld hl, wCurMapScript
2014-09-14 18:29:18 +00:00
inc [hl] ; increment map script index (next script function is usually DisplayEnemyTrainerTextAndStartBattle)
2014-05-25 17:26:42 +00:00
ret
2014-09-14 18:29:18 +00:00
; display the before battle text after the enemy trainer has walked up to the player's sprite
2016-06-12 00:24:04 +00:00
DisplayEnemyTrainerTextAndStartBattle::
ld a, [wd730]
2014-05-25 17:26:42 +00:00
and $1
2014-09-14 18:29:18 +00:00
ret nz ; return if the enemy trainer hasn't finished walking to the player's sprite
2014-05-25 17:51:53 +00:00
ld [wJoyIgnore], a
2014-09-13 07:50:56 +00:00
ld a, [wSpriteIndex]
2014-09-14 18:29:18 +00:00
ld [hSpriteIndexOrTextID], a
2014-05-25 17:26:42 +00:00
call DisplayTextID
2014-09-14 18:29:18 +00:00
; fall through
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
StartTrainerBattle::
2014-05-25 17:26:42 +00:00
xor a
2014-05-25 17:51:53 +00:00
ld [wJoyIgnore], a
2014-05-25 17:26:42 +00:00
call InitBattleEnemyParameters
ld hl, wd72d
2014-05-25 17:26:42 +00:00
set 6, [hl]
set 7, [hl]
ld hl, wd72e
2014-05-25 17:26:42 +00:00
set 1, [hl]
2015-08-31 02:38:41 +00:00
ld hl, wCurMapScript
2014-09-14 18:29:18 +00:00
inc [hl] ; increment map script index (next script function is usually EndTrainerBattle)
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
EndTrainerBattle::
2016-01-03 19:17:10 +00:00
ld hl, wCurrentMapScriptFlags
2014-05-25 17:26:42 +00:00
set 5, [hl]
set 6, [hl]
ld hl, wd72d
2014-05-25 17:26:42 +00:00
res 7, [hl]
ld hl, wFlags_0xcd60
res 0, [hl] ; player is no longer engaged by any trainer
2015-08-31 02:38:41 +00:00
ld a, [wIsInBattle]
2014-05-25 17:26:42 +00:00
cp $ff
jp z, ResetButtonPressedAndMapScript
ld a, $2
call ReadTrainerHeaderInfo
ld a, [wTrainerHeaderFlagBit]
ld c, a
2015-07-20 03:45:34 +00:00
ld b, FLAG_SET
2014-05-25 17:26:42 +00:00
call TrainerFlagAction ; flag trainer as fought
2015-08-31 02:38:41 +00:00
ld a, [wEnemyMonOrTrainerClass]
cp 200
2014-05-25 17:26:42 +00:00
jr nc, .skipRemoveSprite ; test if trainer was fought (in that case skip removing the corresponding sprite)
2015-08-31 02:38:41 +00:00
ld hl, wMissableObjectList
2014-05-25 17:26:42 +00:00
ld de, $2
2014-09-13 07:50:56 +00:00
ld a, [wSpriteIndex]
2014-05-25 17:26:42 +00:00
call IsInArray ; search for sprite ID
inc hl
ld a, [hl]
2015-07-25 03:27:59 +00:00
ld [wMissableObjectIndex], a ; load corresponding missable object index and remove it
predef HideObject
2014-05-25 17:26:42 +00:00
.skipRemoveSprite
ld hl, wd730
2014-05-25 17:26:42 +00:00
bit 4, [hl]
res 4, [hl]
ret nz
2016-06-12 00:24:04 +00:00
ResetButtonPressedAndMapScript::
2014-05-25 17:26:42 +00:00
xor a
2014-05-25 17:51:53 +00:00
ld [wJoyIgnore], a
ld [hJoyHeld], a
ld [hJoyPressed], a
ld [hJoyReleased], a
2015-08-31 02:38:41 +00:00
ld [wCurMapScript], a ; reset battle status
2014-05-25 17:26:42 +00:00
ret
; calls TrainerWalkUpToPlayer
2016-06-12 00:24:04 +00:00
TrainerWalkUpToPlayer_Bank0::
2015-07-19 18:56:13 +00:00
jpba TrainerWalkUpToPlayer
2014-05-25 17:26:42 +00:00
; sets opponent type and mon set/lvl based on the engaging trainer data
2016-06-12 00:24:04 +00:00
InitBattleEnemyParameters::
2014-05-25 17:26:42 +00:00
ld a, [wEngagedTrainerClass]
2015-08-31 02:38:41 +00:00
ld [wCurOpponent], a
ld [wEnemyMonOrTrainerClass], a
cp 200
ld a, [wEngagedTrainerSet]
2014-05-25 17:26:42 +00:00
jr c, .noTrainer
2015-08-31 02:38:41 +00:00
ld [wTrainerNo], a
2014-05-25 17:26:42 +00:00
ret
.noTrainer
2015-08-31 02:38:41 +00:00
ld [wCurEnemyLVL], a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
GetSpritePosition1::
ld hl, _GetSpritePosition1
jr SpritePositionBankswitch
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
GetSpritePosition2::
ld hl, _GetSpritePosition2
jr SpritePositionBankswitch
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
SetSpritePosition1::
ld hl, _SetSpritePosition1
jr SpritePositionBankswitch
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
SetSpritePosition2::
ld hl, _SetSpritePosition2
2016-06-12 00:24:04 +00:00
SpritePositionBankswitch::
ld b, BANK(_GetSpritePosition1) ; BANK(_GetSpritePosition2), BANK(_SetSpritePosition1), BANK(_SetSpritePosition2)
2014-05-25 17:26:42 +00:00
jp Bankswitch ; indirect jump to one of the four functions
2016-06-12 00:24:04 +00:00
CheckForEngagingTrainers::
2014-05-25 17:26:42 +00:00
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]
2014-09-13 07:50:56 +00:00
ld [wSpriteIndex], a ; store trainer flag's bit
2014-05-25 17:26:42 +00:00
ld [wTrainerHeaderFlagBit], a
cp $ff
ret z
ld a, $2
call ReadTrainerHeaderInfo ; read trainer flag's byte ptr
2015-07-20 03:45:34 +00:00
ld b, FLAG_TEST
2014-05-25 17:26:42 +00:00
ld a, [wTrainerHeaderFlagBit]
ld c, a
call TrainerFlagAction ; read trainer flag
ld a, c
2015-07-18 15:17:29 +00:00
and a ; has the trainer already been defeated?
jr nz, .continue
2014-05-25 17:26:42 +00:00
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
2014-09-13 07:50:56 +00:00
ld a, [wSpriteIndex]
2014-05-25 17:26:42 +00:00
swap a
ld [wTrainerSpriteOffset], a
predef TrainerEngage
2014-05-25 17:26:42 +00:00
pop de
pop hl
ld a, [wTrainerSpriteOffset]
2014-05-25 17:26:42 +00:00
and a
ret nz ; break if the trainer is engaging
2015-07-18 15:17:29 +00:00
.continue
2014-05-25 17:26:42 +00:00
ld hl, $c
add hl, de
ld d, h
ld e, l
jr .trainerLoop
2014-09-14 18:29:18 +00:00
; hl = text if the player wins
; de = text if the player loses
2016-06-12 00:24:04 +00:00
SaveEndBattleTextPointers::
2014-05-25 17:26:42 +00:00
ld a, [H_LOADEDROMBANK]
2014-09-14 18:29:18 +00:00
ld [wEndBattleTextRomBank], a
2014-05-25 17:26:42 +00:00
ld a, h
2014-09-14 18:29:18 +00:00
ld [wEndBattleWinTextPointer], a
2014-05-25 17:26:42 +00:00
ld a, l
2014-09-14 18:29:18 +00:00
ld [wEndBattleWinTextPointer + 1], a
2014-05-25 17:26:42 +00:00
ld a, d
2014-09-14 18:29:18 +00:00
ld [wEndBattleLoseTextPointer], a
2014-05-25 17:26:42 +00:00
ld a, e
2014-09-14 18:29:18 +00:00
ld [wEndBattleLoseTextPointer + 1], a
2014-05-25 17:26:42 +00:00
ret
; loads data of some trainer on the current map and plays pre-battle music
2014-09-13 07:50:56 +00:00
; [wSpriteIndex]: sprite ID of trainer who is engaged
2016-06-12 00:24:04 +00:00
EngageMapTrainer::
2015-08-31 02:38:41 +00:00
ld hl, wMapSpriteExtraData
2014-05-25 17:26:42 +00:00
ld d, $0
2014-09-13 07:50:56 +00:00
ld a, [wSpriteIndex]
2014-05-25 17:26:42 +00:00
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 [wEnemyMonAttackMod], a
2014-05-25 17:26:42 +00:00
jp PlayTrainerMusic
2016-06-12 00:24:04 +00:00
PrintEndBattleText::
2014-05-25 17:26:42 +00:00
push hl
ld hl, wd72d
2014-05-25 17:26:42 +00:00
bit 7, [hl]
res 7, [hl]
pop hl
ret z
ld a, [H_LOADEDROMBANK]
push af
2014-09-14 18:29:18 +00:00
ld a, [wEndBattleTextRomBank]
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
2014-09-14 18:29:18 +00:00
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
push hl
callba SaveTrainerName
2014-09-14 18:29:18 +00:00
ld hl, TrainerEndBattleText
2014-05-25 17:26:42 +00:00
call PrintText
pop hl
pop af
ld [H_LOADEDROMBANK], a
2014-09-14 18:29:18 +00:00
ld [MBC1RomBank], a
callba FreezeEnemyTrainerSprite
2014-05-25 17:26:42 +00:00
jp WaitForSoundToFinish
2016-06-12 00:24:04 +00:00
GetSavedEndBattleTextPointer::
2014-08-09 05:39:13 +00:00
ld a, [wBattleResult]
2014-05-25 17:26:42 +00:00
and a
2014-09-14 18:29:18 +00:00
; won battle
jr nz, .lostBattle
ld a, [wEndBattleWinTextPointer]
2014-05-25 17:26:42 +00:00
ld h, a
2014-09-14 18:29:18 +00:00
ld a, [wEndBattleWinTextPointer + 1]
2014-05-25 17:26:42 +00:00
ld l, a
ret
2014-09-14 18:29:18 +00:00
.lostBattle
ld a, [wEndBattleLoseTextPointer]
2014-05-25 17:26:42 +00:00
ld h, a
2014-09-14 18:29:18 +00:00
ld a, [wEndBattleLoseTextPointer + 1]
2014-05-25 17:26:42 +00:00
ld l, a
ret
2016-06-12 00:24:04 +00:00
TrainerEndBattleText::
2014-05-25 17:26:42 +00:00
TX_FAR _TrainerNameText
2015-07-03 19:58:50 +00:00
TX_ASM
2014-09-14 18:29:18 +00:00
call GetSavedEndBattleTextPointer
2014-05-25 17:26:42 +00:00
call TextCommandProcessor
jp TextScriptEnd
; only engage withe trainer if the player is not already
; engaged with another trainer
2014-09-14 18:29:18 +00:00
; XXX unused?
2016-06-12 00:24:04 +00:00
CheckIfAlreadyEngaged::
2014-05-25 17:26:42 +00:00
ld a, [wFlags_0xcd60]
bit 0, a
ret nz
call EngageMapTrainer
xor a
ret
2016-06-12 00:24:04 +00:00
PlayTrainerMusic::
2014-05-25 17:26:42 +00:00
ld a, [wEngagedTrainerClass]
cp OPP_SONY1
2014-05-25 17:26:42 +00:00
ret z
cp OPP_SONY2
2014-05-25 17:26:42 +00:00
ret z
cp OPP_SONY3
2014-05-25 17:26:42 +00:00
ret z
2015-08-31 02:38:41 +00:00
ld a, [wGymLeaderNo]
2014-05-25 17:26:42 +00:00
and a
ret nz
xor a
2015-08-09 05:32:44 +00:00
ld [wAudioFadeOutControl], a
2014-05-25 17:26:42 +00:00
ld a, $ff
call PlaySound
2014-05-25 17:26:42 +00:00
ld a, BANK(Music_MeetEvilTrainer)
2015-08-09 05:32:44 +00:00
ld [wAudioROMBank], a
ld [wAudioSavedROMBank], a
2014-05-25 17:26:42 +00:00
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
2015-08-09 05:32:44 +00:00
ld [wNewSoundID], a
2014-05-25 17:26:42 +00:00
jp PlaySound
INCLUDE "data/trainer_types.asm"
2014-09-14 18:29:18 +00:00
; 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
2016-06-12 00:24:04 +00:00
DecodeArrowMovementRLE::
2014-05-25 17:26:42 +00:00
ld a, [hli]
cp $ff
2014-09-14 18:29:18 +00:00
ret z ; no match in the list
2014-05-25 17:26:42 +00:00
cp b
2014-09-14 18:29:18 +00:00
jr nz, .nextArrowMovementTileEntry1
2014-05-25 17:26:42 +00:00
ld a, [hli]
cp c
2014-09-14 18:29:18 +00:00
jr nz, .nextArrowMovementTileEntry2
2014-05-25 17:26:42 +00:00
ld a, [hli]
ld d, [hl]
ld e, a
ld hl, wSimulatedJoypadStatesEnd
2014-05-25 17:26:42 +00:00
call DecodeRLEList
dec a
ld [wSimulatedJoypadStatesIndex], a
2014-05-25 17:26:42 +00:00
ret
2014-09-14 18:29:18 +00:00
.nextArrowMovementTileEntry1
2014-05-25 17:26:42 +00:00
inc hl
2014-09-14 18:29:18 +00:00
.nextArrowMovementTileEntry2
2014-05-25 17:26:42 +00:00
inc hl
inc hl
2014-09-14 18:29:18 +00:00
jr DecodeArrowMovementRLE
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
FuncTX_ItemStoragePC::
2014-05-25 17:26:42 +00:00
call SaveScreenTilesToBuffer2
ld b, BANK(PlayerPC)
ld hl, PlayerPC
jr bankswitchAndContinue
2016-06-12 00:24:04 +00:00
FuncTX_BillsPC::
2014-05-25 17:26:42 +00:00
call SaveScreenTilesToBuffer2
2014-09-18 04:02:59 +00:00
ld b, BANK(BillsPC_)
ld hl, BillsPC_
2014-05-25 17:26:42 +00:00
jr bankswitchAndContinue
2016-06-12 18:35:21 +00:00
FuncTX_GameCornerPrizeMenu::
2014-05-25 17:26:42 +00:00
; XXX find a better name for this function
; special_F7
ld b,BANK(CeladonPrizeMenu)
ld hl,CeladonPrizeMenu
2016-06-12 00:24:04 +00:00
bankswitchAndContinue::
2014-05-25 17:26:42 +00:00
call Bankswitch
jp HoldTextDisplayOpen ; continue to main text-engine function
2016-06-12 00:24:04 +00:00
FuncTX_PokemonCenterPC::
2014-05-25 17:26:42 +00:00
ld b, BANK(ActivatePC)
ld hl, ActivatePC
jr bankswitchAndContinue
2016-06-12 00:24:04 +00:00
StartSimulatingJoypadStates::
2014-05-25 17:26:42 +00:00
xor a
ld [wOverrideSimulatedJoypadStatesMask], a
ld [wSpriteStateData2 + $06], a ; player's sprite movement byte 1
ld hl, wd730
2014-05-25 17:26:42 +00:00
set 7, [hl]
ret
2016-06-12 00:24:04 +00:00
IsItemInBag::
2014-05-25 17:26:42 +00:00
; 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
2015-08-13 05:14:31 +00:00
predef GetQuantityOfItemInBag
2014-05-25 17:26:42 +00:00
ld a,b
and a
ret
2016-06-12 00:24:04 +00:00
DisplayPokedex::
ld [wd11e], a
2015-07-19 18:56:13 +00:00
jpba _DisplayPokedex
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
SetSpriteFacingDirectionAndDelay::
call SetSpriteFacingDirection
ld c, 6
2014-05-25 17:26:42 +00:00
jp DelayFrames
2016-06-12 00:24:04 +00:00
SetSpriteFacingDirection::
2014-05-25 17:26:42 +00:00
ld a, $9
ld [H_SPRITEDATAOFFSET], a
call GetPointerWithinSpriteStateData1
2015-07-18 15:17:29 +00:00
ld a, [hSpriteFacingDirection]
2014-05-25 17:26:42 +00:00
ld [hl], a
ret
2016-06-12 00:24:04 +00:00
SetSpriteImageIndexAfterSettingFacingDirection::
ld de, -7
2014-05-25 17:26:42 +00:00
add hl, de
ld [hl], a
ret
; tests if the player's coordinates are in a specified array
; INPUT:
; hl = address of array
; OUTPUT:
2015-07-16 03:04:58 +00:00
; [wCoordIndex] = if there is match, the matching array index
2014-05-25 17:26:42 +00:00
; sets carry if the coordinates are in the array, clears carry if not
2016-06-12 00:24:04 +00:00
ArePlayerCoordsInArray::
2015-08-31 02:38:41 +00:00
ld a,[wYCoord]
2014-05-25 17:26:42 +00:00
ld b,a
2015-08-31 02:38:41 +00:00
ld a,[wXCoord]
2014-05-25 17:26:42 +00:00
ld c,a
; fallthrough
2016-06-12 00:24:04 +00:00
CheckCoords::
2014-05-25 17:26:42 +00:00
xor a
2015-07-16 03:04:58 +00:00
ld [wCoordIndex],a
2014-05-25 17:26:42 +00:00
.loop
ld a,[hli]
2016-06-12 18:35:21 +00:00
cp $ff ; reached terminator?
2014-05-25 17:26:42 +00:00
jr z,.notInArray
push hl
2015-07-16 03:04:58 +00:00
ld hl,wCoordIndex
2014-05-25 17:26:42 +00:00
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
2014-09-14 18:29:18 +00:00
; [H_SPRITEINDEX] = index of boulder sprite
2014-05-25 17:26:42 +00:00
; OUTPUT:
2015-07-16 03:04:58 +00:00
; [wCoordIndex] = if there is match, the matching array index
2014-05-25 17:26:42 +00:00
; sets carry if the coordinates are in the array, clears carry if not
2016-06-12 00:24:04 +00:00
CheckBoulderCoords::
2014-05-25 17:26:42 +00:00
push hl
ld hl, wSpriteStateData2 + $04
2014-09-14 18:29:18 +00:00
ld a, [H_SPRITEINDEX]
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
GetPointerWithinSpriteStateData1::
2014-05-25 17:26:42 +00:00
ld h, $c1
jr _GetPointerWithinSpriteStateData
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
GetPointerWithinSpriteStateData2::
2014-05-25 17:26:42 +00:00
ld h, $c2
_GetPointerWithinSpriteStateData:
ld a, [H_SPRITEDATAOFFSET]
2014-05-25 17:26:42 +00:00
ld b, a
ld a, [H_SPRITEINDEX]
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
DecodeRLEList::
2014-05-25 17:26:42 +00:00
xor a
ld [wRLEByteCount], a ; count written bytes here
.listLoop
ld a, [de]
cp $ff
jr z, .endOfList
2015-07-24 03:48:35 +00:00
ld [hRLEByteValue], a ; store byte value to be written
2014-05-25 17:26:42 +00:00
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
2015-07-24 03:48:35 +00:00
ld a, [hRLEByteValue]
2014-05-25 17:26:42 +00:00
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
2015-07-18 15:17:29 +00:00
; sets movement byte 1 for sprite [H_SPRITEINDEX] to $FE and byte 2 to [hSpriteMovementByte2]
2016-06-12 00:24:04 +00:00
SetSpriteMovementBytesToFE::
2014-05-25 17:26:42 +00:00
push hl
call GetSpriteMovementByte1Pointer
ld [hl], $fe
call GetSpriteMovementByte2Pointer
2015-07-18 15:17:29 +00:00
ld a, [hSpriteMovementByte2]
2014-05-25 17:26:42 +00:00
ld [hl], a
pop hl
ret
2015-07-18 15:17:29 +00:00
; sets both movement bytes for sprite [H_SPRITEINDEX] to $FF
2016-06-12 00:24:04 +00:00
SetSpriteMovementBytesToFF::
2014-05-25 17:26:42 +00:00
push hl
call GetSpriteMovementByte1Pointer
ld [hl],$FF
call GetSpriteMovementByte2Pointer
ld [hl],$FF ; prevent person from walking?
pop hl
ret
2015-07-18 15:17:29 +00:00
; returns the sprite movement byte 1 pointer for sprite [H_SPRITEINDEX] in hl
2016-06-12 00:24:04 +00:00
GetSpriteMovementByte1Pointer::
2014-05-25 17:26:42 +00:00
ld h,$C2
2015-07-18 15:17:29 +00:00
ld a,[H_SPRITEINDEX]
2014-05-25 17:26:42 +00:00
swap a
2016-06-12 18:35:21 +00:00
add 6
2014-05-25 17:26:42 +00:00
ld l,a
ret
2015-07-18 15:17:29 +00:00
; returns the sprite movement byte 2 pointer for sprite [H_SPRITEINDEX] in hl
2016-06-12 00:24:04 +00:00
GetSpriteMovementByte2Pointer::
2014-05-25 17:26:42 +00:00
push de
2015-08-31 02:38:41 +00:00
ld hl,wMapSpriteData
2015-07-18 15:17:29 +00:00
ld a,[H_SPRITEINDEX]
2014-05-25 17:26:42 +00:00
dec a
add a
ld d,0
ld e,a
add hl,de
pop de
ret
2016-06-12 00:24:04 +00:00
GetTrainerInformation::
2014-05-25 17:26:42 +00:00
call GetTrainerName
2015-02-07 10:43:08 +00:00
ld a, [wLinkState]
2014-05-25 17:26:42 +00:00
and a
jr nz, .linkBattle
ld a, Bank(TrainerPicAndMoneyPointers)
call BankswitchHome
2015-08-31 02:38:41 +00:00
ld a, [wTrainerClass]
2014-05-25 17:26:42 +00:00
dec a
ld hl, TrainerPicAndMoneyPointers
ld bc, $5
call AddNTimes
2015-04-09 11:05:57 +00:00
ld de, wTrainerPicPointer
2014-05-25 17:26:42 +00:00
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
2015-07-25 03:27:59 +00:00
ld de, wTrainerBaseMoney
2014-05-25 17:26:42 +00:00
ld a, [hli]
ld [de], a
inc de
ld a, [hli]
ld [de], a
jp BankswitchBack
.linkBattle
2015-04-09 11:05:57 +00:00
ld hl, wTrainerPicPointer
2014-05-25 17:26:42 +00:00
ld de, RedPicFront
ld [hl], e
inc hl
ld [hl], d
ret
2016-06-12 00:24:04 +00:00
GetTrainerName::
2015-07-19 18:56:13 +00:00
jpba GetTrainerName_
2014-05-25 17:26:42 +00:00
2014-05-26 00:27:02 +00:00
HasEnoughMoney::
; Check if the player has at least as much
2015-07-17 08:21:40 +00:00
; money as the 3-byte BCD value at hMoney.
2014-05-26 00:27:02 +00:00
ld de, wPlayerMoney
2015-07-17 08:21:40 +00:00
ld hl, hMoney
2014-05-26 00:27:02 +00:00
ld c, 3
2014-05-25 17:26:42 +00:00
jp StringCmp
2014-05-26 00:27:02 +00:00
HasEnoughCoins::
; Check if the player has at least as many
2015-07-17 08:21:40 +00:00
; coins as the 2-byte BCD value at hCoins.
2014-05-25 17:26:42 +00:00
ld de, wPlayerCoins
2015-07-17 08:21:40 +00:00
ld hl, hCoins
2014-05-26 00:27:02 +00:00
ld c, 2
2014-05-25 17:26:42 +00:00
jp StringCmp
2014-05-26 00:27:02 +00:00
2016-06-12 00:24:04 +00:00
BankswitchHome::
2014-05-25 17:26:42 +00:00
; switches to bank # in a
; Only use this when in the home bank!
2015-07-15 06:16:06 +00:00
ld [wBankswitchHomeTemp],a
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
2015-07-15 06:16:06 +00:00
ld [wBankswitchHomeSavedROMBank],a
ld a,[wBankswitchHomeTemp]
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
BankswitchBack::
2014-05-25 17:26:42 +00:00
; returns from BankswitchHome
2015-07-15 06:16:06 +00:00
ld a,[wBankswitchHomeSavedROMBank]
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
Bankswitch::
2014-05-25 17:26:42 +00:00
; self-contained bankswitch, use this when not in the home bank
; switches to the bank in b
ld a,[H_LOADEDROMBANK]
push af
ld a,b
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ld bc,.Return
push bc
jp [hl]
.Return
pop bc
ld a,b
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
; displays yes/no choice
; yes -> set carry
2016-06-12 00:24:04 +00:00
YesNoChoice::
2014-05-25 17:26:42 +00:00
call SaveScreenTilesToBuffer1
call InitYesNoTextBoxParameters
jr DisplayYesNoChoice
2016-06-12 00:24:04 +00:00
Func_35f4::
2015-02-07 20:27:36 +00:00
ld a, TWO_OPTION_MENU
2015-02-07 10:43:08 +00:00
ld [wTextBoxID], a
2014-05-25 17:26:42 +00:00
call InitYesNoTextBoxParameters
jp DisplayTextBoxID
2016-06-12 00:24:04 +00:00
InitYesNoTextBoxParameters::
2015-02-07 10:43:08 +00:00
xor a ; YES_NO_MENU
ld [wTwoOptionMenuID], a
2015-07-18 20:52:03 +00:00
coord hl, 14, 7
2014-05-25 17:26:42 +00:00
ld bc, $80f
ret
2016-06-12 00:24:04 +00:00
YesNoChoicePokeCenter::
2014-05-25 17:26:42 +00:00
call SaveScreenTilesToBuffer1
2015-02-07 10:43:08 +00:00
ld a, HEAL_CANCEL_MENU
ld [wTwoOptionMenuID], a
2015-07-18 20:52:03 +00:00
coord hl, 11, 6
2015-08-05 21:20:29 +00:00
lb bc, 8, 12
2014-05-25 17:26:42 +00:00
jr DisplayYesNoChoice
2016-06-12 18:35:21 +00:00
WideYesNoChoice:: ; unused
2014-05-25 17:26:42 +00:00
call SaveScreenTilesToBuffer1
2015-02-07 10:43:08 +00:00
ld a, WIDE_YES_NO_MENU
ld [wTwoOptionMenuID], a
2015-07-18 20:52:03 +00:00
coord hl, 12, 7
2015-08-05 21:20:29 +00:00
lb bc, 8, 13
2016-06-12 18:35:21 +00:00
2016-06-12 00:24:04 +00:00
DisplayYesNoChoice::
2015-02-07 20:27:36 +00:00
ld a, TWO_OPTION_MENU
2015-02-07 10:43:08 +00:00
ld [wTextBoxID], a
2014-05-25 17:26:42 +00:00
call DisplayTextBoxID
jp LoadScreenTilesFromBuffer1
; calculates the difference |a-b|, setting carry flag if a<b
2016-06-12 00:24:04 +00:00
CalcDifference::
2014-05-25 17:26:42 +00:00
sub b
ret nc
cpl
add $1
scf
ret
2016-06-12 00:24:04 +00:00
MoveSprite::
2015-07-15 11:27:59 +00:00
; move the sprite [H_SPRITEINDEX] with the movement pointed to by de
; actually only copies the movement data to wNPCMovementDirections for later
2014-05-25 17:26:42 +00:00
call SetSpriteMovementBytesToFF
2016-06-12 00:24:04 +00:00
MoveSprite_::
2014-05-25 17:26:42 +00:00
push hl
push bc
call GetSpriteMovementByte1Pointer
xor a
ld [hl],a
2015-07-15 11:27:59 +00:00
ld hl,wNPCMovementDirections
2014-05-25 17:26:42 +00:00
ld c,0
.loop
ld a,[de]
ld [hli],a
inc de
inc c
2016-06-12 18:35:21 +00:00
cp $FF ; have we reached the end of the movement data?
2014-05-25 17:26:42 +00:00
jr nz,.loop
ld a,c
ld [wNPCNumScriptedSteps],a ; number of steps taken
2014-05-25 17:26:42 +00:00
pop bc
ld hl,wd730
2014-05-25 17:26:42 +00:00
set 0,[hl]
pop hl
xor a
ld [wOverrideSimulatedJoypadStatesMask],a
ld [wSimulatedJoypadStatesEnd],a
2014-05-25 17:26:42 +00:00
dec a
2014-05-25 17:51:53 +00:00
ld [wJoyIgnore],a
ld [wWastedByteCD3A],a
2014-05-25 17:26:42 +00:00
ret
2015-07-15 20:58:21 +00:00
; divides [hDividend2] by [hDivisor2] and stores the quotient in [hQuotient2]
2016-06-12 00:24:04 +00:00
DivideBytes::
2014-05-25 17:26:42 +00:00
push hl
2016-06-12 18:35:21 +00:00
ld hl, hQuotient2
2014-05-25 17:26:42 +00:00
xor a
ld [hld], a
ld a, [hld]
and a
jr z, .done
2014-05-25 17:26:42 +00:00
ld a, [hli]
.loop
2014-05-25 17:26:42 +00:00
sub [hl]
jr c, .done
2014-05-25 17:26:42 +00:00
inc hl
inc [hl]
dec hl
jr .loop
.done
2014-05-25 17:26:42 +00:00
pop hl
ret
2014-09-18 04:02:59 +00:00
LoadFontTilePatterns::
ld a, [rLCDC]
bit 7, a ; is the LCD enabled?
jr nz, .on
.off
ld hl, FontGraphics
ld de, vFont
2015-08-10 04:56:20 +00:00
ld bc, FontGraphicsEnd - FontGraphics
2014-09-18 04:02:59 +00:00
ld a, BANK(FontGraphics)
2014-05-25 17:26:42 +00:00
jp FarCopyDataDouble ; if LCD is off, transfer all at once
2014-09-18 04:02:59 +00:00
.on
ld de, FontGraphics
ld hl, vFont
2015-08-10 04:56:20 +00:00
lb bc, BANK(FontGraphics), (FontGraphicsEnd - FontGraphics) / $8
2014-05-25 17:26:42 +00:00
jp CopyVideoDataDouble ; if LCD is on, transfer during V-blank
2014-09-18 04:02:59 +00:00
LoadTextBoxTilePatterns::
ld a, [rLCDC]
bit 7, a ; is the LCD enabled?
jr nz, .on
.off
ld hl, TextBoxGraphics
ld de, vChars2 + $600
2015-08-10 04:56:20 +00:00
ld bc, TextBoxGraphicsEnd - TextBoxGraphics
2014-09-18 04:02:59 +00:00
ld a, BANK(TextBoxGraphics)
2014-05-25 17:26:42 +00:00
jp FarCopyData2 ; if LCD is off, transfer all at once
2014-09-18 04:02:59 +00:00
.on
ld de, TextBoxGraphics
ld hl, vChars2 + $600
2015-08-10 04:56:20 +00:00
lb bc, BANK(TextBoxGraphics), (TextBoxGraphicsEnd - TextBoxGraphics) / $10
2014-05-25 17:26:42 +00:00
jp CopyVideoData ; if LCD is on, transfer during V-blank
2014-09-18 04:02:59 +00:00
LoadHpBarAndStatusTilePatterns::
ld a, [rLCDC]
bit 7, a ; is the LCD enabled?
jr nz, .on
.off
ld hl, HpBarAndStatusGraphics
ld de, vChars2 + $620
2015-08-10 04:56:20 +00:00
ld bc, HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics
2014-09-18 04:02:59 +00:00
ld a, BANK(HpBarAndStatusGraphics)
2014-05-25 17:26:42 +00:00
jp FarCopyData2 ; if LCD is off, transfer all at once
2014-09-18 04:02:59 +00:00
.on
ld de, HpBarAndStatusGraphics
ld hl, vChars2 + $620
2015-08-10 04:56:20 +00:00
lb bc, BANK(HpBarAndStatusGraphics), (HpBarAndStatusGraphicsEnd - HpBarAndStatusGraphics) / $10
2014-05-25 17:26:42 +00:00
jp CopyVideoData ; if LCD is on, transfer during V-blank
2014-09-18 04:02:59 +00:00
FillMemory::
; Fill bc bytes at hl with a.
2014-05-25 17:26:42 +00:00
push de
ld d, a
.loop
ld a, d
2014-09-18 04:02:59 +00:00
ld [hli], a
2014-05-25 17:26:42 +00:00
dec bc
ld a, b
or c
jr nz, .loop
pop de
ret
2014-09-18 04:02:59 +00:00
2016-06-12 00:24:04 +00:00
UncompressSpriteFromDE::
2014-09-18 04:02:59 +00:00
; Decompress pic at a:de.
2015-08-31 02:38:41 +00:00
ld hl, wSpriteInputPtr
2014-05-25 17:26:42 +00:00
ld [hl], e
inc hl
ld [hl], d
jp UncompressSpriteData
2016-06-12 00:24:04 +00:00
SaveScreenTilesToBuffer2::
2015-07-18 20:52:03 +00:00
coord hl, 0, 0
2014-05-25 17:26:42 +00:00
ld de, wTileMapBackup2
2015-07-14 07:16:19 +00:00
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
2014-05-25 17:26:42 +00:00
call CopyData
ret
2016-06-12 00:24:04 +00:00
LoadScreenTilesFromBuffer2::
2014-05-25 17:26:42 +00:00
call LoadScreenTilesFromBuffer2DisableBGTransfer
2015-08-30 06:21:54 +00:00
ld a, 1
ld [H_AUTOBGTRANSFERENABLED], a
2014-05-25 17:26:42 +00:00
ret
; loads screen tiles stored in wTileMapBackup2 but leaves H_AUTOBGTRANSFERENABLED disabled
2016-06-12 00:24:04 +00:00
LoadScreenTilesFromBuffer2DisableBGTransfer::
2014-05-25 17:26:42 +00:00
xor a
ld [H_AUTOBGTRANSFERENABLED], a
2014-05-25 17:26:42 +00:00
ld hl, wTileMapBackup2
2015-07-18 20:52:03 +00:00
coord de, 0, 0
2015-08-30 06:21:54 +00:00
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
2014-05-25 17:26:42 +00:00
call CopyData
ret
2016-06-12 00:24:04 +00:00
SaveScreenTilesToBuffer1::
2015-07-18 20:52:03 +00:00
coord hl, 0, 0
2014-05-25 17:26:42 +00:00
ld de, wTileMapBackup
2015-07-14 07:16:19 +00:00
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
2014-05-25 17:26:42 +00:00
jp CopyData
2016-06-12 00:24:04 +00:00
LoadScreenTilesFromBuffer1::
2014-05-25 17:26:42 +00:00
xor a
ld [H_AUTOBGTRANSFERENABLED], a
2014-05-25 17:26:42 +00:00
ld hl, wTileMapBackup
2015-07-18 20:52:03 +00:00
coord de, 0, 0
2015-07-14 07:16:19 +00:00
ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
2014-05-25 17:26:42 +00:00
call CopyData
2015-08-30 06:21:54 +00:00
ld a, 1
ld [H_AUTOBGTRANSFERENABLED], a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
DelayFrames::
2016-06-12 18:35:21 +00:00
; wait c frames
2014-05-25 17:26:42 +00:00
call DelayFrame
dec c
jr nz,DelayFrames
ret
2016-06-12 00:24:04 +00:00
PlaySoundWaitForCurrent::
2014-05-25 17:26:42 +00:00
push af
call WaitForSoundToFinish
pop af
jp PlaySound
; Wait for sound to finish playing
2016-06-12 00:24:04 +00:00
WaitForSoundToFinish::
ld a, [wLowHealthAlarm]
2014-05-25 17:26:42 +00:00
and $80
ret nz
push hl
2015-08-09 05:32:44 +00:00
.waitLoop
ld hl, wChannelSoundIDs + CH4
2014-05-25 17:26:42 +00:00
xor a
or [hl]
inc hl
or [hl]
inc hl
inc hl
or [hl]
2015-08-09 05:32:44 +00:00
jr nz, .waitLoop
2014-05-25 17:26:42 +00:00
pop hl
ret
2016-06-12 00:24:04 +00:00
NamePointers::
2014-05-25 17:26:42 +00:00
dw MonsterNames
dw MoveNames
dw UnusedNames
dw ItemNames
dw wPartyMonOT ; player's OT names list
dw wEnemyMonOT ; enemy's OT names list
2014-05-25 17:26:42 +00:00
dw TrainerNames
2016-06-12 00:24:04 +00:00
GetName::
2014-05-25 17:26:42 +00:00
; arguments:
; [wd0b5] = which name
2015-02-08 09:44:41 +00:00
; [wNameListType] = which list
; [wPredefBank] = bank of list
2014-05-25 17:26:42 +00:00
;
; returns pointer to name in de
ld a,[wd0b5]
ld [wd11e],a
2014-09-18 04:02:59 +00:00
; TM names are separate from item names.
; BUG: This applies to all names instead of just items.
cp HM_01
2014-09-18 04:02:59 +00:00
jp nc, GetMachineName
2014-05-25 17:26:42 +00:00
ld a,[H_LOADEDROMBANK]
push af
push hl
push bc
push de
2015-02-08 09:44:41 +00:00
ld a,[wNameListType] ;List3759_entrySelector
2014-05-25 17:26:42 +00:00
dec a
jr nz,.otherEntries
;1 = MON_NAMES
call GetMonName
ld hl,NAME_LENGTH
2014-05-25 17:26:42 +00:00
add hl,de
ld e,l
ld d,h
jr .gotPtr
.otherEntries
2014-05-25 17:26:42 +00:00
;2-7 = OTHER ENTRIES
ld a,[wPredefBank]
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2015-02-08 09:44:41 +00:00
ld a,[wNameListType] ;VariousNames' entryID
2014-05-25 17:26:42 +00:00
dec a
add a
ld d,0
ld e,a
jr nc,.skip
inc d
.skip
2014-05-25 17:26:42 +00:00
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]
2014-05-25 17:26:42 +00:00
ld b,a
ld c,0
.nextName
ld d,h
ld e,l
.nextChar
ld a,[hli]
2016-06-12 18:35:21 +00:00
cp "@"
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
ld bc,$0014
call CopyData
.gotPtr
2014-05-25 17:26:42 +00:00
ld a,e
2015-08-07 19:39:29 +00:00
ld [wUnusedCF8D],a
2014-05-25 17:26:42 +00:00
ld a,d
2015-08-07 19:39:29 +00:00
ld [wUnusedCF8D + 1],a
2014-05-25 17:26:42 +00:00
pop de
pop bc
pop hl
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
GetItemPrice::
2015-02-08 02:37:40 +00:00
; Stores item's price as BCD at hItemPrice (3 bytes)
; Input: [wcf91] = item id
2014-05-25 17:26:42 +00:00
ld a, [H_LOADEDROMBANK]
push af
2015-02-08 02:37:40 +00:00
ld a, [wListMenuID]
cp MOVESLISTMENU
ld a, BANK(ItemPrices)
2016-06-12 18:35:21 +00:00
jr nz, .ok
2014-05-25 17:26:42 +00:00
ld a, $f ; hardcoded Bank
2016-06-12 18:35:21 +00:00
.ok
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2015-02-08 02:37:40 +00:00
ld hl, wItemPrices
2014-05-25 17:26:42 +00:00
ld a, [hli]
ld h, [hl]
ld l, a
ld a, [wcf91] ; a contains item id
2014-05-25 17:26:42 +00:00
cp HM_01
jr nc, .getTMPrice
2014-05-25 17:26:42 +00:00
ld bc, $3
2016-06-12 18:35:21 +00:00
.loop
2014-05-25 17:26:42 +00:00
add hl, bc
dec a
2016-06-12 18:35:21 +00:00
jr nz, .loop
2014-05-25 17:26:42 +00:00
dec hl
ld a, [hld]
2015-02-08 02:37:40 +00:00
ld [hItemPrice + 2], a
2014-05-25 17:26:42 +00:00
ld a, [hld]
2015-02-08 02:37:40 +00:00
ld [hItemPrice + 1], a
2014-05-25 17:26:42 +00:00
ld a, [hl]
2015-02-08 02:37:40 +00:00
ld [hItemPrice], a
2016-06-12 18:35:21 +00:00
jr .done
.getTMPrice
2014-05-25 17:26:42 +00:00
ld a, Bank(GetMachinePrice)
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
call GetMachinePrice
2016-06-12 18:35:21 +00:00
.done
2015-02-08 02:37:40 +00:00
ld de, hItemPrice
2014-05-25 17:26:42 +00:00
pop af
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
ret
; copies a string from [de] to [wcf4b]
2016-06-12 00:24:04 +00:00
CopyStringToCF4B::
ld hl, wcf4b
2014-05-25 17:26:42 +00:00
; fall through
; copies a string from [de] to [hl]
2016-06-12 00:24:04 +00:00
CopyString::
2014-05-25 17:26:42 +00:00
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]
2014-05-25 17:26:42 +00:00
; there are esentially three modes of operation
; 1. Get newly pressed buttons only
; ([hJoy7] == 0, [hJoy6] == any)
; Just copies [hJoyPressed] to [hJoy5].
2014-05-25 17:26:42 +00:00
; 2. Get currently pressed buttons at low sample rate with delay
; ([hJoy7] == 1, [hJoy6] != 0)
2014-05-25 17:26:42 +00:00
; 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)
2016-06-12 00:24:04 +00:00
JoypadLowSensitivity::
2014-05-25 18:21:48 +00:00
call Joypad
ld a,[hJoy7] ; flag
2014-05-25 17:26:42 +00:00
and a ; get all currently pressed buttons or only newly pressed buttons?
2014-05-25 17:51:53 +00:00
ld a,[hJoyPressed] ; newly pressed buttons
2014-05-25 17:26:42 +00:00
jr z,.storeButtonState
2014-05-25 17:51:53 +00:00
ld a,[hJoyHeld] ; all currently pressed buttons
2014-05-25 17:26:42 +00:00
.storeButtonState
ld [hJoy5],a
2014-05-25 17:51:53 +00:00
ld a,[hJoyPressed] ; newly pressed buttons
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
ret
.delayOver
; if [hJoy6] = 0 and A or B is pressed, report no buttons as pressed
2014-05-25 17:51:53 +00:00
ld a,[hJoyHeld]
2014-09-18 04:02:59 +00:00
and A_BUTTON | B_BUTTON
2014-05-25 17:26:42 +00:00
jr z,.setShortDelay
ld a,[hJoy6] ; flag
2014-05-25 17:26:42 +00:00
and a
jr nz,.setShortDelay
xor a
ld [hJoy5],a
2014-05-25 17:26:42 +00:00
.setShortDelay
ld a,5 ; 1/12 of a second delay
ld [H_FRAMECOUNTER],a
ret
2016-06-12 00:24:04 +00:00
WaitForTextScrollButtonPress::
2014-09-14 18:29:18 +00:00
ld a, [H_DOWNARROWBLINKCNT1]
2014-05-25 17:26:42 +00:00
push af
2014-09-14 18:29:18 +00:00
ld a, [H_DOWNARROWBLINKCNT2]
2014-05-25 17:26:42 +00:00
push af
xor a
2014-09-14 18:29:18 +00:00
ld [H_DOWNARROWBLINKCNT1], a
2014-05-25 17:26:42 +00:00
ld a, $6
2014-09-14 18:29:18 +00:00
ld [H_DOWNARROWBLINKCNT2], a
.loop
2014-05-25 17:26:42 +00:00
push hl
2014-09-14 18:29:18 +00:00
ld a, [wTownMapSpriteBlinkingEnabled]
2014-05-25 17:26:42 +00:00
and a
2014-09-14 18:29:18 +00:00
jr z, .skipAnimation
call TownMapSpriteBlinkingAnimation
.skipAnimation
2015-07-18 20:52:03 +00:00
coord hl, 18, 16
2014-05-25 17:26:42 +00:00
call HandleDownArrowBlinkTiming
pop hl
2014-05-25 18:21:48 +00:00
call JoypadLowSensitivity
2015-02-07 10:43:08 +00:00
predef CableClub_Run
ld a, [hJoy5]
2014-05-25 17:26:42 +00:00
and A_BUTTON | B_BUTTON
2014-09-14 18:29:18 +00:00
jr z, .loop
2014-05-25 17:26:42 +00:00
pop af
2014-09-14 18:29:18 +00:00
ld [H_DOWNARROWBLINKCNT2], a
2014-05-25 17:26:42 +00:00
pop af
2014-09-14 18:29:18 +00:00
ld [H_DOWNARROWBLINKCNT1], a
2014-05-25 17:26:42 +00:00
ret
2014-09-14 18:29:18 +00:00
; (unless in link battle) waits for A or B being pressed and outputs the scrolling sound effect
2016-06-12 00:24:04 +00:00
ManualTextScroll::
2015-02-07 10:43:08 +00:00
ld a, [wLinkState]
cp LINK_STATE_BATTLING
2014-05-25 17:26:42 +00:00
jr z, .inLinkBattle
call WaitForTextScrollButtonPress
2015-07-19 08:46:12 +00:00
ld a, SFX_PRESS_AB
2014-05-25 17:26:42 +00:00
jp PlaySound
.inLinkBattle
ld c, 65
2014-05-25 17:26:42 +00:00
jp DelayFrames
; function to do multiplication
; all values are big endian
; INPUT
; FF96-FF98 = multiplicand
; FF99 = multiplier
; OUTPUT
; FF95-FF98 = product
2016-06-12 00:24:04 +00:00
Multiply::
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
Divide::
2014-05-25 17:26:42 +00:00
push hl
push de
push bc
ld a,[H_LOADEDROMBANK]
push af
ld a,Bank(_Divide)
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
call _Divide
pop af
ld [H_LOADEDROMBANK],a
ld [MBC1RomBank],a
2014-05-25 17:26:42 +00:00
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
2015-07-15 02:46:52 +00:00
; through the [wd730] or [wLetterPrintingDelayFlags] flags.
2016-06-12 00:24:04 +00:00
PrintLetterDelay::
ld a,[wd730]
2014-05-25 17:26:42 +00:00
bit 6,a
ret nz
2015-07-15 02:46:52 +00:00
ld a,[wLetterPrintingDelayFlags]
2014-05-25 17:26:42 +00:00
bit 1,a
ret z
push hl
push de
push bc
2015-07-15 02:46:52 +00:00
ld a,[wLetterPrintingDelayFlags]
2014-05-25 17:26:42 +00:00
bit 0,a
jr z,.waitOneFrame
2015-08-31 02:38:41 +00:00
ld a,[wOptions]
2014-09-18 04:02:59 +00:00
and $f
2014-05-25 17:26:42 +00:00
ld [H_FRAMECOUNTER],a
jr .checkButtons
.waitOneFrame
ld a,1
ld [H_FRAMECOUNTER],a
.checkButtons
2014-05-25 18:21:48 +00:00
call Joypad
2014-05-25 17:51:53 +00:00
ld a,[hJoyHeld]
2014-05-25 17:26:42 +00:00
.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.
2016-06-12 00:24:04 +00:00
CopyDataUntil::
2014-05-25 17:26:42 +00:00
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.
2016-06-12 00:24:04 +00:00
RemovePokemon::
2015-07-19 18:56:13 +00:00
jpab _RemovePokemon
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
AddPartyMon::
2014-05-25 17:26:42 +00:00
push hl
push de
push bc
callba _AddPartyMon
2014-05-25 17:26:42 +00:00
pop bc
pop de
pop hl
ret
; calculates all 5 stats of current mon and writes them to [de]
2016-06-12 00:24:04 +00:00
CalcStats::
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
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])
2016-06-12 00:24:04 +00:00
CalcStat::
2014-05-25 17:26:42 +00:00
push hl
push de
push bc
ld a, b
ld d, a
push hl
2015-08-31 02:38:41 +00:00
ld hl, wMonHeader
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
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 ; da = (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
2015-08-31 02:38:41 +00:00
ld a, [wCurEnemyLVL]
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
jr nz, .notHPStat
2015-08-31 02:38:41 +00:00
ld a, [wCurEnemyLVL]
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
.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
2014-05-25 17:26:42 +00:00
jr nc, .overflow
cp 999 / $100
2014-05-25 17:26:42 +00:00
jr c, .noOverflow
ld a, [H_MULTIPLICAND+2]
cp 999 % $100 + 1
2014-05-25 17:26:42 +00:00
jr c, .noOverflow
.overflow
ld a, 999 / $100 ; overflow: cap at 999
2014-05-25 17:26:42 +00:00
ld [H_MULTIPLICAND+1], a
ld a, 999 % $100
2014-05-25 17:26:42 +00:00
ld [H_MULTIPLICAND+2], a
.noOverflow
pop bc
pop de
pop hl
ret
2016-06-12 00:24:04 +00:00
AddEnemyMonToPlayerParty::
2014-05-25 17:26:42 +00:00
ld a, [H_LOADEDROMBANK]
push af
ld a, BANK(_AddEnemyMonToPlayerParty)
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
call _AddEnemyMonToPlayerParty
pop bc
ld a, b
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
MoveMon::
2014-05-25 17:26:42 +00:00
ld a, [H_LOADEDROMBANK]
push af
2015-07-13 06:00:48 +00:00
ld a, BANK(_MoveMon)
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2015-07-13 06:00:48 +00:00
call _MoveMon
2014-05-25 17:26:42 +00:00
pop bc
ld a, b
ld [H_LOADEDROMBANK], a
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
SkipFixedLengthTextEntries::
2014-05-25 17:26:42 +00:00
and a
ret z
ld bc, NAME_LENGTH
2014-05-25 17:26:42 +00:00
.skipLoop
add hl, bc
dec a
jr nz, .skipLoop
ret
2016-06-12 00:24:04 +00:00
AddNTimes::
2014-05-25 17:26:42 +00:00
; 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.
2016-06-12 00:24:04 +00:00
StringCmp::
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
WriteOAMBlock::
2014-05-27 18:08:52 +00:00
ld h,wOAMBuffer / $100
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
HandleMenuInput::
2014-05-25 17:26:42 +00:00
xor a
2015-07-24 21:39:45 +00:00
ld [wPartyMenuAnimMonEnabled],a
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
HandleMenuInput_::
2014-05-25 17:26:42 +00:00
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
2015-07-24 03:48:35 +00:00
ld a,6
2014-05-25 17:26:42 +00:00
ld [H_DOWNARROWBLINKCNT2],a ; blinking down arrow timing value 2
.loop1
xor a
2015-07-13 20:35:35 +00:00
ld [wAnimCounter],a ; counter for pokemon shaking animation
2014-05-25 17:26:42 +00:00
call PlaceMenuCursor
call Delay3
.loop2
push hl
2015-07-24 21:39:45 +00:00
ld a,[wPartyMenuAnimMonEnabled]
2014-05-25 17:26:42 +00:00
and a ; is it a pokemon selection menu?
jr z,.getJoypadState
callba AnimatePartyMon ; shake mini sprite of selected pokemon
.getJoypadState
pop hl
2014-05-25 18:21:48 +00:00
call JoypadLowSensitivity
ld a,[hJoy5]
2014-05-25 17:26:42 +00:00
and a ; was a key pressed?
jr nz,.keyPressed
push hl
2015-07-18 20:52:03 +00:00
coord hl, 18, 11 ; coordinates of blinking down arrow in some menus
2014-05-25 17:26:42 +00:00
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
2015-07-25 03:27:59 +00:00
ld [wCheckFor180DegreeTurn],a
ld a,[hJoy5]
2014-05-25 17:26:42 +00:00
ld b,a
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]
2014-09-18 04:02:59 +00:00
and A_BUTTON | B_BUTTON
2014-05-25 17:26:42 +00:00
jr z,.skipPlayingSound
.AButtonOrBButtonPressed
push hl
ld hl,wFlags_0xcd60
bit 5,[hl]
pop hl
jr nz,.skipPlayingSound
2015-07-19 08:46:12 +00:00
ld a,SFX_PRESS_AB
call PlaySound
2014-05-25 17:26:42 +00:00
.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]
2014-05-25 17:26:42 +00:00
ret
.noWrappingAround
2015-07-13 07:32:03 +00:00
ld a,[wMenuWatchMovingOutOfBounds]
2014-05-25 17:26:42 +00:00
and a ; should we return if the user tried to go past the top or bottom?
jr z,.checkOtherKeys
jr .checkIfAButtonOrBButtonPressed
2016-06-12 00:24:04 +00:00
PlaceMenuCursor::
2014-05-25 17:26:42 +00:00
ld a,[wTopMenuItemY]
and a ; is the y coordinate 0?
jr z,.adjustForXCoord
2015-07-18 20:52:03 +00:00
coord hl, 0, 0
2014-09-18 04:02:59 +00:00
ld bc,SCREEN_WIDTH
2014-05-25 17:26:42 +00:00
.topMenuItemLoop
add hl,bc
dec a
jr nz,.topMenuItemLoop
.adjustForXCoord
ld a,[wTopMenuItemX]
2014-09-18 04:02:59 +00:00
ld b,0
2014-05-25 17:26:42 +00:00
ld c,a
add hl,bc
push hl
ld a,[wLastMenuItem]
and a ; was the previous menu id 0?
jr z,.checkForArrow1
push af
2015-02-08 00:24:16 +00:00
ld a,[hFlags_0xFFF6]
2014-05-25 17:26:42 +00:00
bit 1,a ; is the menu double spaced?
jr z,.doubleSpaced1
ld bc,20
jr .getOldMenuItemScreenPosition
.doubleSpaced1
ld bc,40
.getOldMenuItemScreenPosition
pop af
.oldMenuItemLoop
add hl,bc
dec a
jr nz,.oldMenuItemLoop
.checkForArrow1
ld a,[hl]
cp a,"▶" ; 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
push af
2015-02-08 00:24:16 +00:00
ld a,[hFlags_0xFFF6]
2014-05-25 17:26:42 +00:00
bit 1,a ; is the menu double spaced?
jr z,.doubleSpaced2
ld bc,20
jr .getCurrentMenuItemScreenPosition
.doubleSpaced2
ld bc,40
.getCurrentMenuItemScreenPosition
pop af
.currentMenuItemLoop
add hl,bc
dec a
jr nz,.currentMenuItemLoop
.checkForArrow2
ld a,[hl]
2016-06-12 18:35:21 +00:00
cp "▶" ; has the right arrow already been placed?
2014-05-25 17:26:42 +00:00
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.
2016-06-12 00:24:04 +00:00
PlaceUnfilledArrowMenuCursor::
2014-05-25 17:26:42 +00:00
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.
2016-06-12 00:24:04 +00:00
EraseMenuCursor::
2014-05-25 17:26:42 +00:00
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
; initliazed with a down arrow, this function does nothing.
; That allows this to be called without worrying about if a down arrow should
; be blinking.
2016-06-12 00:24:04 +00:00
HandleDownArrowBlinkTiming::
2014-05-25 17:26:42 +00:00
ld a,[hl]
ld b,a
2016-07-18 06:17:03 +00:00
ld a,"▼"
2014-05-25 17:26:42 +00:00
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
2016-07-18 06:17:03 +00:00
ld a,"▼"
2014-05-25 17:26:42 +00:00
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
2015-07-26 02:26:54 +00:00
; for a button press after displaying text (unless [wEnteringCableClub] is set).
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
EnableAutoTextBoxDrawing::
2014-05-25 17:26:42 +00:00
xor a
jr AutoTextBoxDrawingCommon
2016-06-12 00:24:04 +00:00
DisableAutoTextBoxDrawing::
2014-05-25 17:26:42 +00:00
ld a,$01
2016-06-12 00:24:04 +00:00
AutoTextBoxDrawingCommon::
2014-09-13 07:50:56 +00:00
ld [wAutoTextBoxDrawingControl],a
2014-05-25 17:26:42 +00:00
xor a
2014-09-13 07:50:56 +00:00
ld [wDoNotWaitForButtonPressAfterDisplayingText],a ; make DisplayTextID wait for button press
2014-05-25 17:26:42 +00:00
ret
2016-06-12 00:24:04 +00:00
PrintText::
2014-09-18 04:02:59 +00:00
; Print text hl at (1, 14).
2014-05-25 17:26:42 +00:00
push hl
2015-02-07 20:27:36 +00:00
ld a,MESSAGE_BOX
2015-02-07 10:43:08 +00:00
ld [wTextBoxID],a
2014-05-25 17:26:42 +00:00
call DisplayTextBoxID
call UpdateSprites
call Delay3
pop hl
2016-06-12 00:24:04 +00:00
PrintText_NoCreatingTextBox::
2015-07-18 20:52:03 +00:00
coord bc, 1, 14
2014-05-25 17:26:42 +00:00
jp TextCommandProcessor
2014-09-18 04:02:59 +00:00
PrintNumber::
2014-09-18 04:02:59 +00:00
; 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.
2014-05-25 17:26:42 +00:00
push bc
xor a
2014-09-18 04:02:59 +00:00
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
2014-05-25 17:26:42 +00:00
inc de
2014-09-18 04:02:59 +00:00
ld a, [de]
ld [H_NUMTOPRINT + 1], a
2014-05-25 17:26:42 +00:00
inc de
2014-09-18 04:02:59 +00:00
ld a, [de]
ld [H_NUMTOPRINT + 2], a
jr .start
.word
ld a, [de]
ld [H_NUMTOPRINT + 1], a
2014-05-25 17:26:42 +00:00
inc de
2014-09-18 04:02:59 +00:00
ld a, [de]
ld [H_NUMTOPRINT + 2], a
jr .start
.byte
ld a, [de]
ld [H_NUMTOPRINT + 2], a
.start
2014-05-25 17:26:42 +00:00
push de
2014-09-18 04:02:59 +00:00
ld d, b
ld a, c
ld b, a
2014-05-25 17:26:42 +00:00
xor a
2014-09-18 04:02:59 +00:00
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
2014-05-25 17:26:42 +00:00
inc c
2014-09-18 04:02:59 +00:00
jr .mod
.ok
ld b, a
ld a, [H_PASTLEADINGZEROES]
2014-05-25 17:26:42 +00:00
or c
2014-09-18 04:02:59 +00:00
ld [H_PASTLEADINGZEROES], a
jr nz, .past
call .PrintLeadingZero
jr .next
.past
ld a, "0"
2014-05-25 17:26:42 +00:00
add c
2014-09-18 04:02:59 +00:00
ld [hl], a
.next
call .NextDigit
.ones
ld a, "0"
2014-05-25 17:26:42 +00:00
add b
2014-09-18 04:02:59 +00:00
ld [hli], a
2014-05-25 17:26:42 +00:00
pop de
dec de
pop bc
ret
2014-09-18 04:02:59 +00:00
.PrintDigit:
; Divide by the current decimal place.
; Print the quotient, and keep the modulus.
ld c, 0
2014-05-25 17:26:42 +00:00
.loop
2014-09-18 04:02:59 +00:00
ld a, [H_POWEROFTEN]
ld b, a
ld a, [H_NUMTOPRINT]
ld [H_SAVEDNUMTOPRINT], a
2014-05-25 17:26:42 +00:00
cp b
2014-09-18 04:02:59 +00:00
jr c, .underflow0
2014-05-25 17:26:42 +00:00
sub b
2014-09-18 04:02:59 +00:00
ld [H_NUMTOPRINT], a
ld a, [H_POWEROFTEN + 1]
ld b, a
ld a, [H_NUMTOPRINT + 1]
ld [H_SAVEDNUMTOPRINT + 1], a
2014-05-25 17:26:42 +00:00
cp b
2014-09-18 04:02:59 +00:00
jr nc, .noborrow1
ld a, [H_NUMTOPRINT]
or 0
jr z, .underflow1
2014-05-25 17:26:42 +00:00
dec a
2014-09-18 04:02:59 +00:00
ld [H_NUMTOPRINT], a
ld a, [H_NUMTOPRINT + 1]
.noborrow1
2014-05-25 17:26:42 +00:00
sub b
2014-09-18 04:02:59 +00:00
ld [H_NUMTOPRINT + 1], a
ld a, [H_POWEROFTEN + 2]
ld b, a
ld a, [H_NUMTOPRINT + 2]
ld [H_SAVEDNUMTOPRINT + 2], a
2014-05-25 17:26:42 +00:00
cp b
2014-09-18 04:02:59 +00:00
jr nc, .noborrow2
ld a, [H_NUMTOPRINT + 1]
2014-05-25 17:26:42 +00:00
and a
2014-09-18 04:02:59 +00:00
jr nz, .borrowed
ld a, [H_NUMTOPRINT]
2014-05-25 17:26:42 +00:00
and a
2014-09-18 04:02:59 +00:00
jr z, .underflow2
2014-05-25 17:26:42 +00:00
dec a
2014-09-18 04:02:59 +00:00
ld [H_NUMTOPRINT], a
2014-05-25 17:26:42 +00:00
xor a
2014-09-18 04:02:59 +00:00
.borrowed
2014-05-25 17:26:42 +00:00
dec a
2014-09-18 04:02:59 +00:00
ld [H_NUMTOPRINT + 1], a
ld a, [H_NUMTOPRINT + 2]
.noborrow2
2014-05-25 17:26:42 +00:00
sub b
2014-09-18 04:02:59 +00:00
ld [H_NUMTOPRINT + 2], a
2014-05-25 17:26:42 +00:00
inc c
jr .loop
2014-09-18 04:02:59 +00:00
2014-05-25 17:26:42 +00:00
.underflow2
2014-09-18 04:02:59 +00:00
ld a, [H_SAVEDNUMTOPRINT + 1]
ld [H_NUMTOPRINT + 1], a
2014-05-25 17:26:42 +00:00
.underflow1
2014-09-18 04:02:59 +00:00
ld a, [H_SAVEDNUMTOPRINT]
ld [H_NUMTOPRINT], a
2014-05-25 17:26:42 +00:00
.underflow0
2014-09-18 04:02:59 +00:00
ld a, [H_PASTLEADINGZEROES]
2014-05-25 17:26:42 +00:00
or c
2014-09-18 04:02:59 +00:00
jr z, .PrintLeadingZero
ld a, "0"
2014-05-25 17:26:42 +00:00
add c
2014-09-18 04:02:59 +00:00
ld [hl], a
ld [H_PASTLEADINGZEROES], a
2014-05-25 17:26:42 +00:00
ret
2014-09-18 04:02:59 +00:00
.PrintLeadingZero:
2015-07-28 01:48:44 +00:00
bit BIT_LEADING_ZEROES, d
2014-05-25 17:26:42 +00:00
ret z
2014-09-18 04:02:59 +00:00
ld [hl], "0"
ret
.NextDigit:
; Increment unless the number is left-aligned,
; leading zeroes are not printed, and no digits
; have been printed yet.
2015-07-28 01:48:44 +00:00
bit BIT_LEADING_ZEROES, d
2014-09-18 04:02:59 +00:00
jr nz, .inc
2015-07-28 01:48:44 +00:00
bit BIT_LEFT_ALIGN, d
2014-09-18 04:02:59 +00:00
jr z, .inc
ld a, [H_PASTLEADINGZEROES]
2014-05-25 17:26:42 +00:00
and a
ret z
2014-09-18 04:02:59 +00:00
.inc
2014-05-25 17:26:42 +00:00
inc hl
ret
2014-09-18 04:02:59 +00:00
CallFunctionInTable::
; Call function a in jumptable hl.
; de is not preserved.
2014-05-25 17:26:42 +00:00
push hl
push de
push bc
add a
2014-09-18 04:02:59 +00:00
ld d, 0
ld e, a
add hl, de
ld a, [hli]
ld h, [hl]
ld l, a
ld de, .returnAddress
2014-05-25 17:26:42 +00:00
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
2016-06-12 00:24:04 +00:00
RestoreScreenTilesAndReloadTilePatterns::
2014-05-25 17:26:42 +00:00
call ClearSprites
ld a, $1
2014-09-13 07:50:56 +00:00
ld [wUpdateSpritesEnabled], a
call ReloadMapSpriteTilePatterns
2014-05-25 17:26:42 +00:00
call LoadScreenTilesFromBuffer2
call LoadTextBoxTilePatterns
2015-08-12 09:16:56 +00:00
call RunDefaultPaletteCommand
2014-05-25 17:26:42 +00:00
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
ret
GBPalWhiteOut::
; White out all palettes.
xor a
ld [rBGP],a
ld [rOBP0],a
ld [rOBP1],a
ret
2016-06-12 00:24:04 +00:00
RunDefaultPaletteCommand::
2014-05-25 17:26:42 +00:00
ld b,$ff
2016-06-12 00:24:04 +00:00
RunPaletteCommand::
2014-09-13 07:50:56 +00:00
ld a,[wOnSGB]
2014-05-25 17:26:42 +00:00
and a
ret z
2015-08-12 09:16:56 +00:00
predef_jump _RunPaletteCommand
2014-05-25 17:26:42 +00:00
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.
2016-06-12 00:24:04 +00:00
ReloadMapSpriteTilePatterns::
2015-02-09 02:40:08 +00:00
ld hl, wFontLoaded
2014-05-25 17:26:42 +00:00
ld a, [hl]
push af
res 0, [hl]
push hl
xor a
2015-08-31 02:38:41 +00:00
ld [wSpriteSetID], a
2014-05-25 17:26:42 +00:00
call DisableLCD
callba InitMapSprites
call EnableLCD
pop hl
pop af
ld [hl], a
call LoadPlayerSpriteGraphics
call LoadFontTilePatterns
jp UpdateSprites
GiveItem::
; Give player quantity c of item b,
; and copy the item's name to wcf4b.
2014-05-25 17:26:42 +00:00
; Return carry on success.
ld a, b
ld [wd11e], a
ld [wcf91], a
2014-05-25 17:26:42 +00:00
ld a, c
2015-07-13 06:00:48 +00:00
ld [wItemQuantity], a
2014-05-25 17:26:42 +00:00
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
2014-05-25 17:26:42 +00:00
ld a, c
2015-08-31 02:38:41 +00:00
ld [wCurEnemyLVL], a
2015-07-16 03:04:58 +00:00
xor a ; PLAYER_PARTY_DATA
ld [wMonDataLocation], a
2015-07-19 18:56:13 +00:00
jpba _GivePokemon
2014-05-25 17:26:42 +00:00
Random::
; Return a random number in a.
; For battles, use BattleRandom.
push hl
push de
push bc
callba Random_
2014-09-18 04:02:59 +00:00
ld a, [hRandomAdd]
2014-05-25 17:26:42 +00:00
pop bc
pop de
pop hl
ret
2014-05-31 08:22:15 +00:00
INCLUDE "home/predef.asm"
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
UpdateCinnabarGymGateTileBlocks::
2015-07-21 21:21:14 +00:00
jpba UpdateCinnabarGymGateTileBlocks_
2014-05-25 17:26:42 +00:00
2016-06-12 00:24:04 +00:00
CheckForHiddenObjectOrBookshelfOrCardKeyDoor::
2014-05-25 17:26:42 +00:00
ld a, [H_LOADEDROMBANK]
push af
2014-05-25 17:51:53 +00:00
ld a, [hJoyHeld]
2014-09-14 18:29:18 +00:00
bit 0, a ; A button
jr z, .nothingFound
; A button is pressed
ld a, Bank(CheckForHiddenObject)
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
2014-09-14 18:29:18 +00:00
call CheckForHiddenObject
2014-05-25 17:26:42 +00:00
ld a, [$ffee]
and a
2014-09-14 18:29:18 +00:00
jr nz, .hiddenObjectNotFound
ld a, [wHiddenObjectFunctionRomBank]
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
2014-09-14 18:29:18 +00:00
ld de, .returnAddress
2014-05-25 17:26:42 +00:00
push de
jp [hl]
2014-09-14 18:29:18 +00:00
.returnAddress
2014-05-25 17:26:42 +00:00
xor a
2014-09-14 18:29:18 +00:00
jr .done
.hiddenObjectNotFound
2014-05-25 17:26:42 +00:00
callba PrintBookshelfText
ld a, [$ffdb]
and a
2014-09-14 18:29:18 +00:00
jr z, .done
.nothingFound
2014-05-25 17:26:42 +00:00
ld a, $ff
2014-09-14 18:29:18 +00:00
.done
2014-05-25 17:26:42 +00:00
ld [$ffeb], a
pop af
2014-09-14 18:29:18 +00:00
ld [MBC1RomBank], a
2014-05-25 17:26:42 +00:00
ld [H_LOADEDROMBANK], a
ret
2016-06-12 00:24:04 +00:00
PrintPredefTextID::
2015-07-24 03:48:35 +00:00
ld [hSpriteIndexOrTextID], a
2014-09-18 04:02:59 +00:00
ld hl, TextPredefs
2014-09-14 18:29:18 +00:00
call SetMapTextPointer
2015-07-15 06:16:06 +00:00
ld hl, wTextPredefFlag
2014-05-25 17:26:42 +00:00
set 0, [hl]
call DisplayTextID
2016-06-12 00:24:04 +00:00
RestoreMapTextPointer::
2015-08-31 02:38:41 +00:00
ld hl, wMapTextPtr
2014-05-25 17:26:42 +00:00
ld a, [$ffec]
ld [hli], a
2014-09-18 04:02:59 +00:00
ld a, [$ffec + 1]
2014-05-25 17:26:42 +00:00
ld [hl], a
ret
2016-06-12 00:24:04 +00:00
SetMapTextPointer::
2015-08-31 02:38:41 +00:00
ld a, [wMapTextPtr]
2014-05-25 17:26:42 +00:00
ld [$ffec], a
2015-08-31 02:38:41 +00:00
ld a, [wMapTextPtr + 1]
2014-09-18 04:02:59 +00:00
ld [$ffec + 1], a
2014-05-25 17:26:42 +00:00
ld a, l
2015-08-31 02:38:41 +00:00
ld [wMapTextPtr], a
2014-05-25 17:26:42 +00:00
ld a, h
2015-08-31 02:38:41 +00:00
ld [wMapTextPtr + 1], a
2014-05-25 17:26:42 +00:00
ret
2014-09-18 04:02:59 +00:00
TextPredefs::
2016-06-12 18:35:21 +00:00
const_value = 1
2014-09-18 04:15:11 +00:00
add_tx_pre CardKeySuccessText ; 01
add_tx_pre CardKeyFailText ; 02
add_tx_pre RedBedroomPCText ; 03
2014-09-18 04:15:11 +00:00
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 GymStatueText1 ; 0C
add_tx_pre GymStatueText2 ; 0D
add_tx_pre BookcaseText ; 0E
add_tx_pre ViridianCityPokecenterBenchGuyText ; 0F
add_tx_pre PewterCityPokecenterBenchGuyText ; 10
add_tx_pre CeruleanCityPokecenterBenchGuyText ; 11
add_tx_pre LavenderCityPokecenterBenchGuyText ; 12
add_tx_pre VermilionCityPokecenterBenchGuyText ; 13
add_tx_pre CeladonCityPokecenterBenchGuyText ; 14
add_tx_pre CeladonCityHotelText ; 15
add_tx_pre FuchsiaCityPokecenterBenchGuyText ; 16
add_tx_pre CinnabarIslandPokecenterBenchGuyText ; 17
add_tx_pre SaffronCityPokecenterBenchGuyText ; 18
add_tx_pre MtMoonPokecenterBenchGuyText ; 19
add_tx_pre RockTunnelPokecenterBenchGuyText ; 1A
add_tx_pre UnusedBenchGuyText1 ; 1B XXX unused
add_tx_pre UnusedBenchGuyText2 ; 1C XXX unused
add_tx_pre UnusedBenchGuyText3 ; 1D XXX unused
add_tx_pre UnusedPredefText ; 1E XXX unused
add_tx_pre PokemonCenterPCText ; 1F
2014-09-18 04:15:11 +00:00
add_tx_pre ViridianSchoolNotebook ; 20
add_tx_pre ViridianSchoolBlackboard ; 21
add_tx_pre JustAMomentText ; 22
add_tx_pre OpenBillsPCText ; 23
2014-09-18 04:15:11 +00:00
add_tx_pre FoundHiddenItemText ; 24
add_tx_pre HiddenItemBagFullText ; 25 XXX unused
2014-09-18 04:15:11 +00:00
add_tx_pre VermilionGymTrashText ; 26
add_tx_pre IndigoPlateauHQText ; 27
add_tx_pre GameCornerOutOfOrderText ; 28
add_tx_pre GameCornerOutToLunchText ; 29
add_tx_pre GameCornerSomeonesKeysText ; 2A
add_tx_pre FoundHiddenCoinsText ; 2B
add_tx_pre DroppedHiddenCoinsText ; 2C
add_tx_pre BillsHouseMonitorText ; 2D
add_tx_pre BillsHouseInitiatedText ; 2E
add_tx_pre BillsHousePokemonList ; 2F
add_tx_pre MagazinesText ; 30
add_tx_pre CinnabarGymQuiz ; 31
add_tx_pre GameCornerNoCoinsText ; 32
add_tx_pre GameCornerCoinCaseText ; 33
add_tx_pre LinkCableHelp ; 34
add_tx_pre TMNotebook ; 35
add_tx_pre FightingDojoText ; 36
2016-06-12 04:30:05 +00:00
add_tx_pre EnemiesOnEverySideText ; 37
add_tx_pre WhatGoesAroundComesAroundText ; 38
2014-09-18 04:15:11 +00:00
add_tx_pre NewBicycleText ; 39
add_tx_pre IndigoPlateauStatues ; 3A
2016-01-09 11:03:55 +00:00
add_tx_pre VermilionGymTrashSuccessText1 ; 3B
add_tx_pre VermilionGymTrashSuccessText2 ; 3C XXX unused
add_tx_pre VermilionGymTrashSuccessText3 ; 3D
2014-09-18 04:15:11 +00:00
add_tx_pre VermilionGymTrashFailText ; 3E
add_tx_pre TownMapText ; 3F
add_tx_pre BookOrSculptureText ; 40
add_tx_pre ElevatorText ; 41
add_tx_pre PokemonStuffText ; 42