ref: a30bbae4b5b6433941b7011b82e4aee1ae6916e1
dir: /engine/menu/start_sub_menus.asm/
StartMenu_Pokedex: predef ShowPokedexMenu call LoadScreenTilesFromBuffer2 ; restore saved screen call Delay3 call LoadGBPal call UpdateSprites jp RedisplayStartMenu StartMenu_Pokemon: ld a,[wPartyCount] and a jp z,RedisplayStartMenu xor a ld [wMenuItemToSwap],a ld [wPartyMenuTypeOrMessageID],a ld [wUpdateSpritesEnabled],a call DisplayPartyMenu jr .checkIfPokemonChosen .loop xor a ld [wMenuItemToSwap],a ld [wPartyMenuTypeOrMessageID],a call GoBackToPartyMenu .checkIfPokemonChosen jr nc,.chosePokemon .exitMenu call GBPalWhiteOutWithDelay3 call RestoreScreenTilesAndReloadTilePatterns call LoadGBPal jp RedisplayStartMenu .chosePokemon call SaveScreenTilesToBuffer1 ld a,FIELD_MOVE_MON_MENU ld [wTextBoxID],a call DisplayTextBoxID ; display pokemon menu options ld hl,wFieldMoves lb bc, 2, 12 ; max menu item ID, top menu item Y ld e,5 .adjustMenuVariablesLoop dec e jr z,.storeMenuVariables ld a,[hli] and a ; end of field moves? jr z,.storeMenuVariables inc b dec c dec c jr .adjustMenuVariablesLoop .storeMenuVariables ld hl,wTopMenuItemY ld a,c ld [hli],a ; top menu item Y ld a,[hFieldMoveMonMenuTopMenuItemX] ld [hli],a ; top menu item X xor a ld [hli],a ; current menu item ID inc hl ld a,b ld [hli],a ; max menu item ID ld a,A_BUTTON | B_BUTTON ld [hli],a ; menu watched keys xor a ld [hl],a call HandleMenuInput push af call LoadScreenTilesFromBuffer1 ; restore saved screen pop af bit 1,a ; was the B button pressed? jp nz,.loop ; if the B button wasn't pressed ld a,[wMaxMenuItem] ld b,a ld a,[wCurrentMenuItem] ; menu selection cp b jp z,.exitMenu ; if the player chose Cancel dec b cp b jr z,.choseSwitch dec b cp b jp z,.choseStats ld c,a ld b,0 ld hl,wFieldMoves add hl,bc jp .choseOutOfBattleMove .choseSwitch ld a,[wPartyCount] cp a,2 ; is there more than one pokemon in the party? jp c,StartMenu_Pokemon ; if not, no switching call SwitchPartyMon_InitVarOrSwapData ; init [wMenuItemToSwap] ld a,SWAP_MONS_PARTY_MENU ld [wPartyMenuTypeOrMessageID],a call GoBackToPartyMenu jp .checkIfPokemonChosen .choseStats call ClearSprites xor a ; PLAYER_PARTY_DATA ld [wMonDataLocation],a predef StatusScreen predef StatusScreen2 call ReloadMapData jp StartMenu_Pokemon .choseOutOfBattleMove push hl ld a,[wWhichPokemon] ld hl,wPartyMonNicks call GetPartyMonName pop hl ld a,[hl] dec a add a ld b,0 ld c,a ld hl,.outOfBattleMovePointers add hl,bc ld a,[hli] ld h,[hl] ld l,a ld a,[wObtainedBadges] ; badges obtained jp [hl] .outOfBattleMovePointers dw .cut dw .fly dw .surf dw .surf dw .strength dw .flash dw .dig dw .teleport dw .softboiled .fly bit 2,a ; does the player have the Thunder Badge? jp z,.newBadgeRequired call CheckIfInOutsideMap jr z,.canFly ld a,[wWhichPokemon] ld hl,wPartyMonNicks call GetPartyMonName ld hl,.cannotFlyHereText call PrintText jp .loop .canFly call ChooseFlyDestination ld a,[wd732] bit 3,a ; did the player decide to fly? jp nz,.goBackToMap call LoadFontTilePatterns ld hl,wd72e set 1,[hl] jp StartMenu_Pokemon .cut bit 1,a ; does the player have the Cascade Badge? jp z,.newBadgeRequired predef UsedCut ld a,[wActionResultOrTookBattleTurn] and a jp z,.loop jp CloseTextDisplay .surf bit 4,a ; does the player have the Soul Badge? jp z,.newBadgeRequired callba IsSurfingAllowed ld hl,wd728 bit 1,[hl] res 1,[hl] jp z,.loop ld a,SURFBOARD ld [wcf91],a ld [wPseudoItemID],a call UseItem ld a,[wActionResultOrTookBattleTurn] and a jp z,.loop call GBPalWhiteOutWithDelay3 jp .goBackToMap .strength bit 3,a ; does the player have the Rainbow Badge? jp z,.newBadgeRequired predef PrintStrengthTxt call GBPalWhiteOutWithDelay3 jp .goBackToMap .flash bit 0,a ; does the player have the Boulder Badge? jp z,.newBadgeRequired xor a ld [wMapPalOffset],a ld hl,.flashLightsAreaText call PrintText call GBPalWhiteOutWithDelay3 jp .goBackToMap .flashLightsAreaText TX_FAR _FlashLightsAreaText db "@" .dig ld a,ESCAPE_ROPE ld [wcf91],a ld [wPseudoItemID],a call UseItem ld a,[wActionResultOrTookBattleTurn] and a jp z,.loop call GBPalWhiteOutWithDelay3 jp .goBackToMap .teleport call CheckIfInOutsideMap jr z,.canTeleport ld a,[wWhichPokemon] ld hl,wPartyMonNicks call GetPartyMonName ld hl,.cannotUseTeleportNowText call PrintText jp .loop .canTeleport ld hl,.warpToLastPokemonCenterText call PrintText ld hl,wd732 set 3,[hl] set 6,[hl] ld hl,wd72e set 1,[hl] res 4,[hl] ld c,60 call DelayFrames call GBPalWhiteOutWithDelay3 jp .goBackToMap .warpToLastPokemonCenterText TX_FAR _WarpToLastPokemonCenterText db "@" .cannotUseTeleportNowText TX_FAR _CannotUseTeleportNowText db "@" .cannotFlyHereText TX_FAR _CannotFlyHereText db "@" .softboiled ld hl,wPartyMon1MaxHP ld a,[wWhichPokemon] ld bc,wPartyMon2 - wPartyMon1 call AddNTimes ld a,[hli] ld [H_DIVIDEND],a ld a,[hl] ld [H_DIVIDEND + 1],a ld a,5 ld [H_DIVISOR],a ld b,2 ; number of bytes call Divide ld bc,wPartyMon1HP - wPartyMon1MaxHP add hl,bc ld a,[hld] ld b,a ld a,[H_QUOTIENT + 3] sub b ld b,[hl] ld a,[H_QUOTIENT + 2] sbc b jp nc,.notHealthyEnough ld a,[wPartyAndBillsPCSavedMenuItem] push af ld a,POTION ld [wcf91],a ld [wPseudoItemID],a call UseItem pop af ld [wPartyAndBillsPCSavedMenuItem],a jp .loop .notHealthyEnough ; if current HP is less than 1/5 of max HP ld hl,.notHealthyEnoughText call PrintText jp .loop .notHealthyEnoughText TX_FAR _NotHealthyEnoughText db "@" .goBackToMap call RestoreScreenTilesAndReloadTilePatterns jp CloseTextDisplay .newBadgeRequired ld hl,.newBadgeRequiredText call PrintText jp .loop .newBadgeRequiredText TX_FAR _NewBadgeRequiredText db "@" ; writes a blank tile to all possible menu cursor positions on the party menu ErasePartyMenuCursors: coord hl, 0, 1 ld bc,2 * 20 ; menu cursor positions are 2 rows apart ld a,6 ; 6 menu cursor positions .loop ld [hl]," " add hl,bc dec a jr nz,.loop ret ItemMenuLoop: call LoadScreenTilesFromBuffer2DisableBGTransfer ; restore saved screen call RunDefaultPaletteCommand StartMenu_Item: ld a,[wLinkState] dec a ; is the player in the Colosseum or Trade Centre? jr nz,.notInCableClubRoom ld hl,CannotUseItemsHereText call PrintText jr .exitMenu .notInCableClubRoom ld bc,wNumBagItems ld hl,wListPointer ld a,c ld [hli],a ld [hl],b ; store item bag pointer in wListPointer (for DisplayListMenuID) xor a ld [wPrintItemPrices],a ld a,ITEMLISTMENU ld [wListMenuID],a ld a,[wBagSavedMenuItem] ld [wCurrentMenuItem],a call DisplayListMenuID ld a,[wCurrentMenuItem] ld [wBagSavedMenuItem],a jr nc,.choseItem .exitMenu call LoadScreenTilesFromBuffer2 ; restore saved screen call LoadTextBoxTilePatterns call UpdateSprites jp RedisplayStartMenu .choseItem ; erase menu cursor (blank each tile in front of an item name) ld a," " Coorda 5, 4 Coorda 5, 6 Coorda 5, 8 Coorda 5, 10 call PlaceUnfilledArrowMenuCursor xor a ld [wMenuItemToSwap],a ld a,[wcf91] cp a,BICYCLE jp z,.useOrTossItem .notBicycle1 ld a,USE_TOSS_MENU_TEMPLATE ld [wTextBoxID],a call DisplayTextBoxID ld hl,wTopMenuItemY ld a,11 ld [hli],a ; top menu item Y ld a,14 ld [hli],a ; top menu item X xor a ld [hli],a ; current menu item ID inc hl inc a ; a = 1 ld [hli],a ; max menu item ID ld a,A_BUTTON | B_BUTTON ld [hli],a ; menu watched keys xor a ld [hl],a ; old menu item id call HandleMenuInput call PlaceUnfilledArrowMenuCursor bit 1,a ; was the B button pressed? jr z,.useOrTossItem jp ItemMenuLoop .useOrTossItem ; if the player made the choice to use or toss the item ld a,[wcf91] ld [wd11e],a call GetItemName call CopyStringToCF4B ; copy name to wcf4b ld a,[wcf91] cp a,BICYCLE jr nz,.notBicycle2 ld a,[wd732] bit 5,a jr z,.useItem_closeMenu ld hl,CannotGetOffHereText call PrintText jp ItemMenuLoop .notBicycle2 ld a,[wCurrentMenuItem] and a jr nz,.tossItem ; use item ld [wPseudoItemID],a ; a must be 0 due to above conditional jump ld a,[wcf91] cp a,HM_01 jr nc,.useItem_partyMenu ld hl,UsableItems_CloseMenu ld de,1 call IsInArray jr c,.useItem_closeMenu ld a,[wcf91] ld hl,UsableItems_PartyMenu ld de,1 call IsInArray jr c,.useItem_partyMenu call UseItem jp ItemMenuLoop .useItem_closeMenu xor a ld [wPseudoItemID],a call UseItem ld a,[wActionResultOrTookBattleTurn] and a jp z,ItemMenuLoop jp CloseStartMenu .useItem_partyMenu ld a,[wUpdateSpritesEnabled] push af call UseItem ld a,[wActionResultOrTookBattleTurn] cp a,$02 jp z,.partyMenuNotDisplayed call GBPalWhiteOutWithDelay3 call RestoreScreenTilesAndReloadTilePatterns pop af ld [wUpdateSpritesEnabled],a jp StartMenu_Item .partyMenuNotDisplayed pop af ld [wUpdateSpritesEnabled],a jp ItemMenuLoop .tossItem call IsKeyItem ld a,[wIsKeyItem] and a jr nz,.skipAskingQuantity ld a,[wcf91] call IsItemHM jr c,.skipAskingQuantity call DisplayChooseQuantityMenu inc a jr z,.tossZeroItems .skipAskingQuantity ld hl,wNumBagItems call TossItem .tossZeroItems jp ItemMenuLoop CannotUseItemsHereText: TX_FAR _CannotUseItemsHereText db "@" CannotGetOffHereText: TX_FAR _CannotGetOffHereText db "@" ; items which bring up the party menu when used UsableItems_PartyMenu: db MOON_STONE db ANTIDOTE db BURN_HEAL db ICE_HEAL db AWAKENING db PARLYZ_HEAL db FULL_RESTORE db MAX_POTION db HYPER_POTION db SUPER_POTION db POTION db FIRE_STONE db THUNDER_STONE db WATER_STONE db HP_UP db PROTEIN db IRON db CARBOS db CALCIUM db RARE_CANDY db LEAF_STONE db FULL_HEAL db REVIVE db MAX_REVIVE db FRESH_WATER db SODA_POP db LEMONADE db X_ATTACK db X_DEFEND db X_SPEED db X_SPECIAL db PP_UP db ETHER db MAX_ETHER db ELIXER db MAX_ELIXER db $ff ; items which close the item menu when used UsableItems_CloseMenu: db ESCAPE_ROPE db ITEMFINDER db POKE_FLUTE db OLD_ROD db GOOD_ROD db SUPER_ROD db $ff StartMenu_TrainerInfo: call GBPalWhiteOut call ClearScreen call UpdateSprites ld a,[hTilesetType] push af xor a ld [hTilesetType],a call DrawTrainerInfo predef DrawBadges ; draw badges ld b, SET_PAL_TRAINER_CARD call RunPaletteCommand call GBPalNormal call WaitForTextScrollButtonPress ; wait for button press call GBPalWhiteOut call LoadFontTilePatterns call LoadScreenTilesFromBuffer2 ; restore saved screen call RunDefaultPaletteCommand call ReloadMapData call LoadGBPal pop af ld [hTilesetType],a jp RedisplayStartMenu ; loads tile patterns and draws everything except for gym leader faces / badges DrawTrainerInfo: ld de,RedPicFront lb bc, BANK(RedPicFront), $01 predef DisplayPicCenteredOrUpperRight call DisableLCD coord hl, 0, 2 ld a," " call TrainerInfo_DrawVerticalLine coord hl, 1, 2 call TrainerInfo_DrawVerticalLine ld hl,vChars2 + $70 ld de,vChars2 ld bc,$70 * 4 call CopyData ld hl,TrainerInfoTextBoxTileGraphics ; trainer info text box tile patterns ld de,vChars2 + $770 ld bc,$0080 push bc call TrainerInfo_FarCopyData ld hl,BlankLeaderNames ld de,vChars2 + $600 ld bc,$0170 call TrainerInfo_FarCopyData pop bc ld hl,BadgeNumbersTileGraphics ; badge number tile patterns ld de,vChars1 + $580 call TrainerInfo_FarCopyData ld hl,GymLeaderFaceAndBadgeTileGraphics ; gym leader face and badge tile patterns ld de,vChars2 + $200 ld bc,$0400 ld a,$03 call FarCopyData2 ld hl,TextBoxGraphics ld de,$00d0 add hl,de ; hl = colon tile pattern ld de,vChars1 + $560 ld bc,$0010 ld a,$04 push bc call FarCopyData2 pop bc ld hl,TrainerInfoTextBoxTileGraphics + $80 ; background tile pattern ld de,vChars1 + $570 call TrainerInfo_FarCopyData call EnableLCD ld hl,wTrainerInfoTextBoxWidthPlus1 ld a,18 + 1 ld [hli],a dec a ld [hli],a ld [hl],1 coord hl, 0, 0 call TrainerInfo_DrawTextBox ld hl,wTrainerInfoTextBoxWidthPlus1 ld a,16 + 1 ld [hli],a dec a ld [hli],a ld [hl],3 coord hl, 1, 10 call TrainerInfo_DrawTextBox coord hl, 0, 10 ld a,$d7 call TrainerInfo_DrawVerticalLine coord hl, 19, 10 call TrainerInfo_DrawVerticalLine coord hl, 6, 9 ld de,TrainerInfo_BadgesText call PlaceString coord hl, 2, 2 ld de,TrainerInfo_NameMoneyTimeText call PlaceString coord hl, 7, 2 ld de,wPlayerName call PlaceString coord hl, 8, 4 ld de,wPlayerMoney ld c,$e3 call PrintBCDNumber coord hl, 9, 6 ld de,wPlayTimeHours ; hours lb bc, LEFT_ALIGN | 1, 3 call PrintNumber ld [hl],$d6 ; colon tile ID inc hl ld de,wPlayTimeMinutes ; minutes lb bc, LEADING_ZEROES | 1, 2 jp PrintNumber TrainerInfo_FarCopyData: ld a,BANK(TrainerInfoTextBoxTileGraphics) jp FarCopyData2 TrainerInfo_NameMoneyTimeText: db "NAME/" next "MONEY/" next "TIME/@" ; $76 is a circle tile TrainerInfo_BadgesText: db $76,"BADGES",$76,"@" ; draws a text box on the trainer info screen ; height is always 6 ; INPUT: ; hl = destination address ; [wTrainerInfoTextBoxWidthPlus1] = width ; [wTrainerInfoTextBoxWidth] = width - 1 ; [wTrainerInfoTextBoxNextRowOffset] = distance from the end of a text box row to the start of the next TrainerInfo_DrawTextBox: ld a,$79 ; upper left corner tile ID lb de, $7a, $7b ; top edge and upper right corner tile ID's call TrainerInfo_DrawHorizontalEdge ; draw top edge call TrainerInfo_NextTextBoxRow ld a,[wTrainerInfoTextBoxWidthPlus1] ld e,a ld d,0 ld c,6 ; height of the text box .loop ld [hl],$7c ; left edge tile ID add hl,de ld [hl],$78 ; right edge tile ID call TrainerInfo_NextTextBoxRow dec c jr nz,.loop ld a,$7d ; lower left corner tile ID lb de,$77, $7e ; bottom edge and lower right corner tile ID's TrainerInfo_DrawHorizontalEdge: ld [hli],a ; place left corner tile ld a,[wTrainerInfoTextBoxWidth] ld c,a ld a,d .loop ld [hli],a ; place edge tile dec c jr nz,.loop ld a,e ld [hl],a ; place right corner tile ret TrainerInfo_NextTextBoxRow: ld a,[wTrainerInfoTextBoxNextRowOffset] ; distance to the start of the next row .loop inc hl dec a jr nz,.loop ret ; draws a vertical line ; INPUT: ; hl = address of top tile in the line ; a = tile ID TrainerInfo_DrawVerticalLine: ld de,SCREEN_WIDTH ld c,8 .loop ld [hl],a add hl,de dec c jr nz,.loop ret StartMenu_SaveReset: ld a,[wd72e] bit 6,a ; is the player using the link feature? jp nz,Init predef SaveSAV ; save the game call LoadScreenTilesFromBuffer2 ; restore saved screen jp HoldTextDisplayOpen StartMenu_Option: xor a ld [H_AUTOBGTRANSFERENABLED],a call ClearScreen call UpdateSprites callab DisplayOptionMenu call LoadScreenTilesFromBuffer2 ; restore saved screen call LoadTextBoxTilePatterns call UpdateSprites jp RedisplayStartMenu SwitchPartyMon: call SwitchPartyMon_InitVarOrSwapData ; swap data ld a, [wSwappedMenuItem] call SwitchPartyMon_ClearGfx ld a, [wCurrentMenuItem] call SwitchPartyMon_ClearGfx jp RedrawPartyMenu_ SwitchPartyMon_ClearGfx: push af coord hl, 0, 0 ld bc, SCREEN_WIDTH * 2 call AddNTimes ld c, SCREEN_WIDTH * 2 ld a, " " .clearMonBGLoop ; clear the mon's row in the party menu ld [hli], a dec c jr nz, .clearMonBGLoop pop af ld hl, wOAMBuffer ld bc, $10 call AddNTimes ld de, $4 ld c, e .clearMonOAMLoop ld [hl], $a0 add hl, de dec c jr nz, .clearMonOAMLoop call WaitForSoundToFinish ld a, SFX_SWAP jp PlaySound SwitchPartyMon_InitVarOrSwapData: ; This is used to initialise [wMenuItemToSwap] and to actually swap the data. ld a, [wMenuItemToSwap] and a ; has [wMenuItemToSwap] been initialised yet? jr nz, .pickedMonsToSwap ; If not, initialise [wMenuItemToSwap] so that it matches the current mon. ld a, [wWhichPokemon] inc a ; [wMenuItemToSwap] counts from 1 ld [wMenuItemToSwap], a ret .pickedMonsToSwap xor a ld [wPartyMenuTypeOrMessageID], a ld a, [wMenuItemToSwap] dec a ld b, a ld a, [wCurrentMenuItem] ld [wSwappedMenuItem], a cp b ; swapping a mon with itself? jr nz, .swappingDifferentMons ; can't swap a mon with itself xor a ld [wMenuItemToSwap], a ld [wPartyMenuTypeOrMessageID], a ret .swappingDifferentMons ld a, b ld [wMenuItemToSwap], a push hl push de ld hl, wPartySpecies ld d, h ld e, l ld a, [wCurrentMenuItem] add l ld l, a jr nc, .noCarry inc h .noCarry ld a, [wMenuItemToSwap] add e ld e, a jr nc, .noCarry2 inc d .noCarry2 ld a, [hl] ld [hSwapTemp], a ld a, [de] ld [hl], a ld a, [hSwapTemp] ld [de], a ld hl, wPartyMons ld bc, wPartyMon2 - wPartyMon1 ld a, [wCurrentMenuItem] call AddNTimes push hl ld de, wSwitchPartyMonTempBuffer ld bc, wPartyMon2 - wPartyMon1 call CopyData ld hl, wPartyMons ld bc, wPartyMon2 - wPartyMon1 ld a, [wMenuItemToSwap] call AddNTimes pop de push hl ld bc, wPartyMon2 - wPartyMon1 call CopyData pop de ld hl, wSwitchPartyMonTempBuffer ld bc, wPartyMon2 - wPartyMon1 call CopyData ld hl, wPartyMonOT ld a, [wCurrentMenuItem] call SkipFixedLengthTextEntries push hl ld de, wSwitchPartyMonTempBuffer ld bc, NAME_LENGTH call CopyData ld hl, wPartyMonOT ld a, [wMenuItemToSwap] call SkipFixedLengthTextEntries pop de push hl ld bc, NAME_LENGTH call CopyData pop de ld hl, wSwitchPartyMonTempBuffer ld bc, NAME_LENGTH call CopyData ld hl, wPartyMonNicks ld a, [wCurrentMenuItem] call SkipFixedLengthTextEntries push hl ld de, wSwitchPartyMonTempBuffer ld bc, NAME_LENGTH call CopyData ld hl, wPartyMonNicks ld a, [wMenuItemToSwap] call SkipFixedLengthTextEntries pop de push hl ld bc, NAME_LENGTH call CopyData pop de ld hl, wSwitchPartyMonTempBuffer ld bc, NAME_LENGTH call CopyData ld a, [wMenuItemToSwap] ld [wSwappedMenuItem], a xor a ld [wMenuItemToSwap], a ld [wPartyMenuTypeOrMessageID], a pop de pop hl ret