ShowPokedexMenu:
call GBPalWhiteOut
call ClearScreen
call UpdateSprites
ld a, [wListScrollOffset]
push af
xor a
ld [wCurrentMenuItem], a
ld [wListScrollOffset], a
ld [wLastMenuItem], a
inc a
ld [wPokedexNum], a
ldh [hJoy7], a
.setUpGraphics
ld b, SET_PAL_GENERIC
call RunPaletteCommand
callfar LoadPokedexTilePatterns
.doPokemonListMenu
ld hl, wTopMenuItemY
ld a, 3
ld [hli], a ; top menu item Y
xor a
ld [hli], a ; top menu item X
inc a
ld [wMenuWatchMovingOutOfBounds], a
inc hl
inc hl
ld a, 6
ld [hli], a ; max menu item ID
ld [hl], PAD_LEFT | PAD_RIGHT | PAD_B | PAD_A
call HandlePokedexListMenu
jr c, .goToSideMenu ; if the player chose a pokemon from the list
.exitPokedex
xor a
ld [wMenuWatchMovingOutOfBounds], a
ld [wCurrentMenuItem], a
ld [wLastMenuItem], a
ldh [hJoy7], a
ld [wUnusedOverrideSimulatedJoypadStatesIndex], a
ld [wOverrideSimulatedJoypadStatesMask], a
pop af
ld [wListScrollOffset], a
call GBPalWhiteOutWithDelay3
call RunDefaultPaletteCommand
jp ReloadMapData
.goToSideMenu
call HandlePokedexSideMenu
dec b
jr z, .exitPokedex ; if the player chose Quit
dec b
jr z, .doPokemonListMenu ; if pokemon not seen or player pressed B button
jp .setUpGraphics ; if pokemon data or area was shown
; handles the menu on the lower right in the pokedex screen
; OUTPUT:
; b = reason for exiting menu
; 00: showed pokemon data or area
; 01: the player chose Quit
; 02: the pokemon has not been seen yet or the player pressed the B button
HandlePokedexSideMenu:
call PlaceUnfilledArrowMenuCursor
ld a, [wCurrentMenuItem]
push af
ld b, a
ld a, [wLastMenuItem]
push af
ld a, [wListScrollOffset]
push af
add b
inc a
ld [wPokedexNum], a
ld a, [wPokedexNum]
push af
ld a, [wDexMaxSeenMon]
push af ; this doesn't need to be preserved
ld hl, wPokedexSeen
call IsPokemonBitSet
ld b, 2
jr z, .exitSideMenu
call PokedexToIndex
ld hl, wTopMenuItemY
ld a, 10
ld [hli], a ; top menu item Y
ld a, 15
ld [hli], a ; top menu item X
xor a
ld [hli], a ; current menu item ID
inc hl
ld a, 3
ld [hli], a ; max menu item ID
;ld a, PAD_A | PAD_B
ld [hli], a ; menu watched keys (A button and B button)
xor a
ld [hli], a ; old menu item ID
ld [wMenuWatchMovingOutOfBounds], a
.handleMenuInput
call HandleMenuInput
bit B_PAD_B, a
ld b, 2
jr nz, .buttonBPressed
ld a, [wCurrentMenuItem]
and a
jr z, .choseData
dec a
jr z, .choseCry
dec a
jr z, .choseArea
.choseQuit
ld b, 1
.exitSideMenu
pop af
ld [wDexMaxSeenMon], a
pop af
ld [wPokedexNum], a
pop af
ld [wListScrollOffset], a
pop af
ld [wLastMenuItem], a
pop af
ld [wCurrentMenuItem], a
push bc
hlcoord 0, 3
ld de, 20
lb bc, " ", 13
call DrawTileLine ; cover up the menu cursor in the pokemon list
pop bc
ret
.buttonBPressed
push bc
hlcoord 15, 10
ld de, 20
lb bc, " ", 7
call DrawTileLine ; cover up the menu cursor in the side menu
pop bc
jr .exitSideMenu
.choseData
call ShowPokedexDataInternal
ld b, 0
jr .exitSideMenu
; play pokemon cry
.choseCry
ld a, [wPokedexNum]
call GetCryData
call PlaySound
jr .handleMenuInput
.choseArea
predef LoadTownMap_Nest ; display pokemon areas
ld b, 0
jr .exitSideMenu
; handles the list of pokemon on the left of the pokedex screen
; sets carry flag if player presses A, unsets carry flag if player presses B
HandlePokedexListMenu:
xor a
ldh [hAutoBGTransferEnabled], a
; draw the horizontal line separating the seen and owned amounts from the menu
hlcoord 15, 8
ld a, "─"
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
ld [hli], a
hlcoord 14, 0
ld [hl], $71 ; vertical line tile
hlcoord 14, 1
call DrawPokedexVerticalLine
hlcoord 14, 9
call DrawPokedexVerticalLine
ld hl, wPokedexSeen
ld b, wPokedexSeenEnd - wPokedexSeen
call CountSetBits
ld de, wNumSetBits
hlcoord 16, 3
lb bc, 1, 3
call PrintNumber ; print number of seen pokemon
ld hl, wPokedexOwned
ld b, wPokedexOwnedEnd - wPokedexOwned
call CountSetBits
ld de, wNumSetBits
hlcoord 16, 6
lb bc, 1, 3
call PrintNumber ; print number of owned pokemon
hlcoord 16, 2
ld de, PokedexSeenText
call PlaceString
hlcoord 16, 5
ld de, PokedexOwnText
call PlaceString
hlcoord 1, 1
ld de, PokedexContentsText
call PlaceString
hlcoord 16, 10
ld de, PokedexMenuItemsText
call PlaceString
; find the highest pokedex number among the pokemon the player has seen
ld hl, wPokedexSeenEnd - 1
ld b, (wPokedexSeenEnd - wPokedexSeen) * 8 + 1
.maxSeenPokemonLoop
ld a, [hld]
ld c, 8
.maxSeenPokemonInnerLoop
dec b
sla a
jr c, .storeMaxSeenPokemon
dec c
jr nz, .maxSeenPokemonInnerLoop
jr .maxSeenPokemonLoop
.storeMaxSeenPokemon
ld a, b
ld [wDexMaxSeenMon], a
.loop
xor a
ldh [hAutoBGTransferEnabled], a
hlcoord 4, 2
lb bc, 14, 10
call ClearScreenArea
hlcoord 1, 3
ld a, [wListScrollOffset]
ld [wPokedexNum], a
ld d, 7
ld a, [wDexMaxSeenMon]
cp 7
jr nc, .printPokemonLoop
ld d, a
dec a
ld [wMaxMenuItem], a
; loop to print pokemon pokedex numbers and names
; if the player has owned the pokemon, it puts a pokeball beside the name
.printPokemonLoop
ld a, [wPokedexNum]
inc a
ld [wPokedexNum], a
push af
push de
push hl
ld de, -SCREEN_WIDTH
add hl, de
ld de, wPokedexNum
lb bc, LEADING_ZEROES | 1, 3
call PrintNumber
ld de, SCREEN_WIDTH
add hl, de
dec hl
push hl
ld hl, wPokedexOwned
call IsPokemonBitSet
pop hl
ld a, " "
jr z, .writeTile
ld a, $72 ; pokeball tile
.writeTile
ld [hl], a ; put a pokeball next to pokemon that the player has owned
push hl
ld hl, wPokedexSeen
call IsPokemonBitSet
jr nz, .getPokemonName ; if the player has seen the pokemon
ld de, .dashedLine ; print a dashed line in place of the name if the player hasn't seen the pokemon
jr .skipGettingName
.dashedLine ; for unseen pokemon in the list
db "----------@"
.getPokemonName
call PokedexToIndex
call GetMonName
.skipGettingName
pop hl
inc hl
call PlaceString
pop hl
ld bc, 2 * SCREEN_WIDTH
add hl, bc
pop de
pop af
ld [wPokedexNum], a
dec d
jr nz, .printPokemonLoop
ld a, 01
ldh [hAutoBGTransferEnabled], a
call Delay3
call GBPalNormal
call HandleMenuInput
bit B_PAD_B, a
jp nz, .buttonBPressed
.checkIfUpPressed
bit B_PAD_UP, a
jr z, .checkIfDownPressed
.upPressed ; scroll up one row
ld a, [wListScrollOffset]
and a
jp z, .loop
dec a
ld [wListScrollOffset], a
jp .loop
.checkIfDownPressed
bit B_PAD_DOWN, a
jr z, .checkIfRightPressed
.downPressed ; scroll down one row
ld a, [wDexMaxSeenMon]
cp 7
jp c, .loop ; can't if the list is shorter than 7
sub 7
ld b, a
ld a, [wListScrollOffset]
cp b
jp z, .loop
inc a
ld [wListScrollOffset], a
jp .loop
.checkIfRightPressed
bit B_PAD_RIGHT, a
jr z, .checkIfLeftPressed
.rightPressed ; scroll down 7 rows
ld a, [wDexMaxSeenMon]
cp 7
jp c, .loop ; can't if the list is shorter than 7
sub 6
ld b, a
ld a, [wListScrollOffset]
add 7
ld [wListScrollOffset], a
cp b
jp c, .loop
dec b
ld a, b
ld [wListScrollOffset], a
jp .loop
.checkIfLeftPressed ; scroll up 7 rows
bit B_PAD_LEFT, a
jr z, .buttonAPressed
.leftPressed
ld a, [wListScrollOffset]
sub 7
ld [wListScrollOffset], a
jp nc, .loop
xor a
ld [wListScrollOffset], a
jp .loop
.buttonAPressed
scf
ret
.buttonBPressed
and a
ret
DrawPokedexVerticalLine:
ld c, 9 ; height of line
ld de, SCREEN_WIDTH
ld a, $71 ; vertical line tile
.loop
ld [hl], a
add hl, de
xor 1 ; toggle between vertical line tile and box tile
dec c
jr nz, .loop
ret
PokedexSeenText:
db "SEEN@"
PokedexOwnText:
db "OWN@"
PokedexContentsText:
db "CONTENTS@"
PokedexMenuItemsText:
db "DATA"
next "CRY"
next "AREA"
next "QUIT@"
; tests if a pokemon's bit is set in the seen or owned pokemon bit fields
; INPUT:
; [wPokedexNum] = pokedex number
; hl = address of bit field
IsPokemonBitSet:
ld a, [wPokedexNum]
dec a
ld c, a
ld b, FLAG_TEST
predef FlagActionPredef
ld a, c
and a
ret
; function to display pokedex data from outside the pokedex
ShowPokedexData:
call GBPalWhiteOutWithDelay3
call ClearScreen
call UpdateSprites
callfar LoadPokedexTilePatterns ; load pokedex tiles
; function to display pokedex data from inside the pokedex
ShowPokedexDataInternal:
ld hl, wStatusFlags2
set BIT_NO_AUDIO_FADE_OUT, [hl]
ld a, $33 ; 3/7 volume
ldh [rAUDVOL], a
call GBPalWhiteOut ; zero all palettes
call ClearScreen
ld a, [wPokedexNum]
ld [wCurPartySpecies], a
push af
ld b, SET_PAL_POKEDEX
call RunPaletteCommand
pop af
ld [wPokedexNum], a
ldh a, [hTileAnimations]
push af
xor a
ldh [hTileAnimations], a
hlcoord 0, 0
ld de, 1
lb bc, $64, SCREEN_WIDTH
call DrawTileLine ; draw top border
hlcoord 0, 17
ld b, $6f
call DrawTileLine ; draw bottom border
hlcoord 0, 1
ld de, 20
lb bc, $66, $10
call DrawTileLine ; draw left border
hlcoord 19, 1
ld b, $67
call DrawTileLine ; draw right border
ld a, $63 ; upper left corner tile
ldcoord_a 0, 0
ld a, $65 ; upper right corner tile
ldcoord_a 19, 0
ld a, $6c ; lower left corner tile
ldcoord_a 0, 17
ld a, $6e ; lower right corner tile
ldcoord_a 19, 17
hlcoord 0, 9
ld de, PokedexDataDividerLine
call PlaceString ; draw horizontal divider line
hlcoord 9, 6
ld de, HeightWeightText
call PlaceString
call GetMonName
hlcoord 9, 2
call PlaceString
ld hl, PokedexEntryPointers
ld a, [wPokedexNum]
dec a
ld e, a
ld d, 0
add hl, de
add hl, de
ld a, [hli]
ld e, a
ld d, [hl] ; de = address of pokedex entry
hlcoord 9, 4
call PlaceString ; print species name
ld h, b
ld l, c
push de
ld a, [wPokedexNum]
push af
call IndexToPokedex
hlcoord 2, 8
ld a, "№"
ld [hli], a
ld a, "<DOT>"
ld [hli], a
ld de, wPokedexNum
lb bc, LEADING_ZEROES | 1, 3
call PrintNumber ; print pokedex number
ld hl, wPokedexOwned
call IsPokemonBitSet
pop af
ld [wPokedexNum], a
ld a, [wCurPartySpecies]
ld [wCurSpecies], a
pop de
push af
push bc
push de
push hl
call Delay3
call GBPalNormal
call GetMonHeader ; load pokemon picture location
hlcoord 1, 1
call LoadFlippedFrontSpriteByMonIndex ; draw pokemon picture
ld a, [wCurPartySpecies]
call PlayCry
pop hl
pop de
pop bc
pop af
ld a, c
and a
jp z, .waitForButtonPress ; if the pokemon has not been owned, don't print the height, weight, or description
inc de ; de = address of feet (height)
ld a, [de] ; reads feet, but a is overwritten without being used
hlcoord 12, 6
lb bc, 1, 2
call PrintNumber ; print feet (height)
ld a, "′"
ld [hl], a
inc de
inc de ; de = address of inches (height)
hlcoord 15, 6
lb bc, LEADING_ZEROES | 1, 2
call PrintNumber ; print inches (height)
ld a, "″"
ld [hl], a
; now print the weight (note that weight is stored in tenths of pounds internally)
inc de
inc de
inc de ; de = address of upper byte of weight
push de
; put weight in big-endian order at hDexWeight
ld hl, hDexWeight
ld a, [hl] ; save existing value of [hDexWeight]
push af
ld a, [de] ; a = upper byte of weight
ld [hli], a ; store upper byte of weight in [hDexWeight]
ld a, [hl] ; save existing value of [hDexWeight + 1]
push af
dec de
ld a, [de] ; a = lower byte of weight
ld [hl], a ; store lower byte of weight in [hDexWeight + 1]
ld de, hDexWeight
hlcoord 11, 8
lb bc, 2, 5 ; 2 bytes, 5 digits
call PrintNumber ; print weight
hlcoord 14, 8
ldh a, [hDexWeight + 1]
sub 10
ldh a, [hDexWeight]
sbc 0
jr nc, .next
ld [hl], "0" ; if the weight is less than 10, put a 0 before the decimal point
.next
inc hl
ld a, [hli]
ld [hld], a ; make space for the decimal point by moving the last digit forward one tile
ld [hl], "<DOT>" ; decimal point tile
pop af
ldh [hDexWeight + 1], a ; restore original value of [hDexWeight + 1]
pop af
ldh [hDexWeight], a ; restore original value of [hDexWeight]
pop hl
inc hl ; hl = address of pokedex description text
bccoord 1, 11
ld a, %10
ldh [hClearLetterPrintingDelayFlags], a
call TextCommandProcessor ; print pokedex description text
xor a
ldh [hClearLetterPrintingDelayFlags], a
.waitForButtonPress
call JoypadLowSensitivity
ldh a, [hJoy5]
and PAD_A | PAD_B
jr z, .waitForButtonPress
pop af
ldh [hTileAnimations], a
call GBPalWhiteOut
call ClearScreen
call RunDefaultPaletteCommand
call LoadTextBoxTilePatterns
call GBPalNormal
ld hl, wStatusFlags2
res BIT_NO_AUDIO_FADE_OUT, [hl]
ld a, $77 ; max volume
ldh [rAUDVOL], a
ret
HeightWeightText:
db "HT ?′??″"
next "WT ???lb@"
; XXX does anything point to this?
PokeText:
db "#@"
; horizontal line that divides the pokedex text description from the rest of the data
PokedexDataDividerLine:
db $68, $69, $6B, $69, $6B, $69, $6B, $69, $6B, $6B
db $6B, $6B, $69, $6B, $69, $6B, $69, $6B, $69, $6A
db "@"
; draws a line of tiles
; INPUT:
; b = tile ID
; c = number of tile ID's to write
; de = amount to destination address after each tile (1 for horizontal, 20 for vertical)
; hl = destination address
DrawTileLine:
push bc
push de
.loop
ld [hl], b
add hl, de
dec c
jr nz, .loop
pop de
pop bc
ret
INCLUDE "data/pokemon/dex_entries.asm"
PokedexToIndex:
; converts the Pokédex number at [wPokedexNum] to an index
push bc
push hl
ld a, [wPokedexNum]
ld b, a
ld c, 0
ld hl, PokedexOrder
.loop ; go through the list until we find an entry with a matching dex number
inc c
ld a, [hli]
cp b
jr nz, .loop
ld a, c
ld [wPokedexNum], a
pop hl
pop bc
ret
IndexToPokedex:
; converts the index number at [wPokedexNum] to a Pokédex number
push bc
push hl
ld a, [wPokedexNum]
dec a
ld hl, PokedexOrder
ld b, 0
ld c, a
add hl, bc
ld a, [hl]
ld [wPokedexNum], a
pop hl
pop bc
ret
INCLUDE "data/pokemon/dex_order.asm"