ref: 174ef99e0e0caf5e8af2825d0034c9f7b72784f8
dir: /engine/menus/pokedex.asm/
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 [wd11e], 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], D_LEFT | D_RIGHT | B_BUTTON | A_BUTTON 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 [wWastedByteCD3A], 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 [wd11e], a ld a, [wd11e] 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, A_BUTTON | B_BUTTON 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 1, a ; was the B button pressed? 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 [wd11e], 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, [wd11e] 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 [wd11e], 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, [wd11e] inc a ld [wd11e], a push af push de push hl ld de, -SCREEN_WIDTH add hl, de ld de, wd11e lb bc, LEADING_ZEROES | 1, 3 call PrintNumber ; print the pokedex number 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 [wd11e], a dec d jr nz, .printPokemonLoop ld a, 01 ldh [hAutoBGTransferEnabled], a call Delay3 call GBPalNormal call HandleMenuInput bit 1, a ; was the B button pressed? jp nz, .buttonBPressed .checkIfUpPressed bit 6, a ; was Up pressed? 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 7, a ; was Down pressed? 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 4, a ; was Right pressed? 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 5, a ; was Left pressed? 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: ; [wd11e] = pokedex number ; hl = address of bit field IsPokemonBitSet: ld a, [wd11e] 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, wd72c set 1, [hl] ld a, $33 ; 3/7 volume ldh [rNR50], a call GBPalWhiteOut ; zero all palettes call ClearScreen ld a, [wd11e] ; pokemon ID ld [wcf91], a push af ld b, SET_PAL_POKEDEX call RunPaletteCommand pop af ld [wd11e], a ldh a, [hTilesetType] push af xor a ldh [hTilesetType], 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, [wd11e] 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, [wd11e] push af call IndexToPokedex hlcoord 2, 8 ld a, "№" ld [hli], a ld a, "<DOT>" ld [hli], a ld de, wd11e lb bc, LEADING_ZEROES | 1, 3 call PrintNumber ; print pokedex number ld hl, wPokedexOwned call IsPokemonBitSet pop af ld [wd11e], a ld a, [wcf91] ld [wd0b5], 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, [wcf91] call PlayCry ; play pokemon cry 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 A_BUTTON | B_BUTTON jr z, .waitForButtonPress pop af ldh [hTilesetType], a call GBPalWhiteOut call ClearScreen call RunDefaultPaletteCommand call LoadTextBoxTilePatterns call GBPalNormal ld hl, wd72c res 1, [hl] ld a, $77 ; max volume ldh [rNR50], 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 wd11e to an index push bc push hl ld a, [wd11e] 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 [wd11e], a pop hl pop bc ret IndexToPokedex: ; converts the index number at wd11e to a Pokédex number push bc push hl ld a, [wd11e] dec a ld hl, PokedexOrder ld b, 0 ld c, a add hl, bc ld a, [hl] ld [wd11e], a pop hl pop bc ret INCLUDE "data/pokemon/dex_order.asm"