diff options
author | Rangi <35663410+Rangi42@users.noreply.github.com> | 2020-07-03 09:38:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-03 09:38:52 -0400 |
commit | c85050497c1bd062e9cd40bf5b32fa3beca366cc (patch) | |
tree | 9593ddd3ab820223ab580d5fc0ae133b485b8315 /engine/menus/pokedex.asm | |
parent | 5559d51c863b6fb529ea0494d857950a36fe85b7 (diff) | |
parent | 87ef75c173b5d5f227912860487600b6f53d1d1f (diff) |
Merge pull request #256 from Rangi42/master
Add subdirectories to engine/ similar to pokecrystal
Diffstat (limited to 'engine/menus/pokedex.asm')
-rwxr-xr-x | engine/menus/pokedex.asm | 665 |
1 files changed, 665 insertions, 0 deletions
diff --git a/engine/menus/pokedex.asm b/engine/menus/pokedex.asm new file mode 100755 index 00000000..8e1fd480 --- /dev/null +++ b/engine/menus/pokedex.asm @@ -0,0 +1,665 @@ +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 + ld [hJoy7], a +.setUpGraphics + ld b, SET_PAL_GENERIC + call RunPaletteCommand + callab 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 + ld [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 + coord hl, 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 + coord hl, 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 + ld [H_AUTOBGTRANSFERENABLED], a +; draw the horizontal line separating the seen and owned amounts from the menu + coord hl, 15, 8 + ld a, "─" + ld [hli], a + ld [hli], a + ld [hli], a + ld [hli], a + ld [hli], a + coord hl, 14, 0 + ld [hl], $71 ; vertical line tile + coord hl, 14, 1 + call DrawPokedexVerticalLine + coord hl, 14, 9 + call DrawPokedexVerticalLine + ld hl, wPokedexSeen + ld b, wPokedexSeenEnd - wPokedexSeen + call CountSetBits + ld de, wNumSetBits + coord hl, 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 + coord hl, 16, 6 + lb bc, 1, 3 + call PrintNumber ; print number of owned pokemon + coord hl, 16, 2 + ld de, PokedexSeenText + call PlaceString + coord hl, 16, 5 + ld de, PokedexOwnText + call PlaceString + coord hl, 1, 1 + ld de, PokedexContentsText + call PlaceString + coord hl, 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 + ld [H_AUTOBGTRANSFERENABLED], a + coord hl, 4, 2 + lb bc, 14, 10 + call ClearScreenArea + coord hl, 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 + ld [H_AUTOBGTRANSFERENABLED], 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 + callab 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 + ld [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 + ld a, [hTilesetType] + push af + xor a + ld [hTilesetType], a + + coord hl, 0, 0 + ld de, 1 + lb bc, $64, SCREEN_WIDTH + call DrawTileLine ; draw top border + + coord hl, 0, 17 + ld b, $6f + call DrawTileLine ; draw bottom border + + coord hl, 0, 1 + ld de, 20 + lb bc, $66, $10 + call DrawTileLine ; draw left border + + coord hl, 19, 1 + ld b, $67 + call DrawTileLine ; draw right border + + ld a, $63 ; upper left corner tile + Coorda 0, 0 + ld a, $65 ; upper right corner tile + Coorda 19, 0 + ld a, $6c ; lower left corner tile + Coorda 0, 17 + ld a, $6e ; lower right corner tile + Coorda 19, 17 + + coord hl, 0, 9 + ld de, PokedexDataDividerLine + call PlaceString ; draw horizontal divider line + + coord hl, 9, 6 + ld de, HeightWeightText + call PlaceString + + call GetMonName + coord hl, 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 + + coord hl, 9, 4 + call PlaceString ; print species name + + ld h, b + ld l, c + push de + ld a, [wd11e] + push af + call IndexToPokedex + + coord hl, 2, 8 + ld a, "№" + ld [hli], a + ld a, "⠄" + 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 + coord hl, 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 + coord hl, 12, 6 + lb bc, 1, 2 + call PrintNumber ; print feet (height) + ld a, $60 ; feet symbol tile (one tick) + ld [hl], a + inc de + inc de ; de = address of inches (height) + coord hl, 15, 6 + lb bc, LEADING_ZEROES | 1, 2 + call PrintNumber ; print inches (height) + ld a, $61 ; inches symbol tile (two ticks) + 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 + coord hl, 11, 8 + lb bc, 2, 5 ; 2 bytes, 5 digits + call PrintNumber ; print weight + coord hl, 14, 8 + ld a, [hDexWeight + 1] + sub 10 + ld 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], "⠄" ; decimal point tile + pop af + ld [hDexWeight + 1], a ; restore original value of [hDexWeight + 1] + pop af + ld [hDexWeight], a ; restore original value of [hDexWeight] + pop hl + inc hl ; hl = address of pokedex description text + coord bc, 1, 11 + ld a, 2 + ld [$fff4], a + call TextCommandProcessor ; print pokedex description text + xor a + ld [$fff4], a +.waitForButtonPress + call JoypadLowSensitivity + ld a, [hJoy5] + and A_BUTTON | B_BUTTON + jr z, .waitForButtonPress + pop af + ld [hTilesetType], a + call GBPalWhiteOut + call ClearScreen + call RunDefaultPaletteCommand + call LoadTextBoxTilePatterns + call GBPalNormal + ld hl, wd72c + res 1, [hl] + ld a, $77 ; max volume + ld [rNR50], a + ret + +HeightWeightText: + db "HT ?",$60,"??",$61 + 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 + db $69,$6B,$69,$6B,$6B + db $6B,$6B,$69,$6B,$69 + db $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/pokedex_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/pokedex_order.asm" |