diff options
author | IIMarckus <iimarckus@gmail.com> | 2018-06-02 04:27:31 -0600 |
---|---|---|
committer | IIMarckus <iimarckus@gmail.com> | 2018-06-02 04:27:31 -0600 |
commit | 5d2473f767b431910da023a6e37ad3239dcdd575 (patch) | |
tree | 6200e65d9bd7e8fa8429c62d3907f21587ab74df /de/engine/menu | |
parent | f31a2ed69f7368d88a0a1aed5c35aa8cb34af6b3 (diff) |
Start of German translation. Needs work.multilang
Diffstat (limited to 'de/engine/menu')
-rw-r--r-- | de/engine/menu/bills_pc.asm | 554 | ||||
-rwxr-xr-x | de/engine/menu/diploma.asm | 112 | ||||
-rw-r--r-- | de/engine/menu/draw_start_menu.asm | 89 | ||||
-rwxr-xr-x | de/engine/menu/league_pc.asm | 120 | ||||
-rwxr-xr-x | de/engine/menu/main_menu.asm | 712 | ||||
-rwxr-xr-x | de/engine/menu/naming_screen.asm | 512 | ||||
-rwxr-xr-x | de/engine/menu/party_menu.asm | 325 | ||||
-rwxr-xr-x | de/engine/menu/players_pc.asm | 303 | ||||
-rwxr-xr-x | de/engine/menu/pokedex.asm | 666 | ||||
-rwxr-xr-x | de/engine/menu/prize_menu.asm | 306 | ||||
-rwxr-xr-x | de/engine/menu/start_sub_menus.asm | 854 | ||||
-rwxr-xr-x | de/engine/menu/status_screen.asm | 491 | ||||
-rw-r--r-- | de/engine/menu/text_box.asm | 740 | ||||
-rwxr-xr-x | de/engine/menu/vending_machine.asm | 139 |
14 files changed, 5923 insertions, 0 deletions
diff --git a/de/engine/menu/bills_pc.asm b/de/engine/menu/bills_pc.asm new file mode 100644 index 00000000..50db8d92 --- /dev/null +++ b/de/engine/menu/bills_pc.asm @@ -0,0 +1,554 @@ +DisplayPCMainMenu:: + xor a + ld [H_AUTOBGTRANSFERENABLED], a + call SaveScreenTilesToBuffer2 + ld a, [wNumHoFTeams] + and a + jr nz, .leaguePCAvailable + CheckEvent EVENT_GOT_POKEDEX + jr z, .noOaksPC + ld a, [wNumHoFTeams] + and a + jr nz, .leaguePCAvailable + coord hl, 0, 0 + ld b, 8 + ld c, 15 + jr .next +.noOaksPC + coord hl, 0, 0 + ld b, 6 + ld c, 15 + jr .next +.leaguePCAvailable + coord hl, 0, 0 + ld b, 10 + ld c, 15 +.next + call TextBoxBorder + call UpdateSprites + ld a, 3 + ld [wMaxMenuItem], a + CheckEvent EVENT_MET_BILL + jr nz, .metBill + coord hl, 2, 2 + ld de, SomeonesPCText + jr .next2 +.metBill + coord hl, 2, 2 + ld de, BillsPCText +.next2 + call PlaceString + coord hl, 2, 4 + ld de, PlayersPCText + call PlaceString + ld l, c + ld h, b + ld de, wPlayerName + call PlaceString + CheckEvent EVENT_GOT_POKEDEX + jr z, .noOaksPC2 + coord hl, 2, 6 + ld de, OaksPCText + call PlaceString + ld a, [wNumHoFTeams] + and a + jr z, .noLeaguePC + ld a, 4 + ld [wMaxMenuItem], a + coord hl, 2, 8 + ld de, PKMNLeaguePCText + call PlaceString + coord hl, 2, 10 + ld de, LogOffPCText + jr .next3 +.noLeaguePC + coord hl, 2, 8 + ld de, LogOffPCText + jr .next3 +.noOaksPC2 + ld a, $2 + ld [wMaxMenuItem], a + coord hl, 2, 6 + ld de, LogOffPCText +.next3 + call PlaceString + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, 2 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a + xor a + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld a, 1 + ld [H_AUTOBGTRANSFERENABLED], a + ret + +SomeonesPCText: db "JEMANDES PC@" +BillsPCText: db "BILLS PC@" +PlayersPCText: db "PC VON @" +OaksPCText: db "EICHS PC@" +PKMNLeaguePCText: db "<pkmn>-LIGA@" +LogOffPCText: db "AUSLOGGEN@" + +BillsPC_:: + ld hl, wd730 + set 6, [hl] + xor a + ld [wParentMenuItem], a + inc a ; MONSTER_NAME + ld [wNameListType], a + call LoadHpBarAndStatusTilePatterns + ld a, [wListScrollOffset] + push af + ld a, [wFlags_0xcd60] + bit 3, a ; accessing Bill's PC through another PC? + jr nz, BillsPCMenu +; accessing it directly + ld a, $99 + call PlaySound + ld hl, SwitchOnText + call PrintText + +BillsPCMenu: + ld a, [wParentMenuItem] + ld [wCurrentMenuItem], a + ld hl, vChars2 + $780 + ld de, PokeballTileGraphics + lb bc, BANK(PokeballTileGraphics), $01 + call CopyVideoData + call LoadScreenTilesFromBuffer2DisableBGTransfer + coord hl, 0, 0 + ld b, 10 + ld c, 14 + call TextBoxBorder + coord hl, 2, 2 + ld de, BillsPCMenuText + call PlaceString + ld hl, wTopMenuItemY + ld a, 2 + ld [hli], a ; wTopMenuItemY + dec a + ld [hli], a ; wTopMenuItemX + inc hl + inc hl + ld a, 4 + ld [hli], a ; wMaxMenuItem + ld a, A_BUTTON | B_BUTTON + ld [hli], a ; wMenuWatchedKeys + xor a + ld [hli], a ; wLastMenuItem + ld [hli], a ; wPartyAndBillsPCSavedMenuItem + ld hl, wListScrollOffset + ld [hli], a ; wListScrollOffset + ld [hl], a ; wMenuWatchMovingOutOfBounds + ld [wPlayerMonNumber], a + ld hl, WhatText + call PrintText + coord hl, 9, 14 + ld b, 2 + ld c, 9 + call TextBoxBorder + ld a, [wCurrentBoxNum] + and $7f + cp 9 + jr c, .singleDigitBoxNum +; two digit box num + sub 9 + coord hl, 17, 16 + ld [hl], "1" + add "0" + jr .next +.singleDigitBoxNum + add "1" +.next + Coorda 18, 16 + coord hl, 10, 16 + ld de, BoxNoPCText + call PlaceString + ld a, 1 + ld [H_AUTOBGTRANSFERENABLED], a + call Delay3 + call HandleMenuInput + bit 1, a + jp nz, ExitBillsPC ; b button + call PlaceUnfilledArrowMenuCursor + ld a, [wCurrentMenuItem] + ld [wParentMenuItem], a + and a + jp z, BillsPCWithdraw ; withdraw + cp $1 + jp z, BillsPCDeposit ; deposit + cp $2 + jp z, BillsPCRelease ; release + cp $3 + jp z, BillsPCChangeBox ; change box + +ExitBillsPC: + ld a, [wFlags_0xcd60] + bit 3, a ; accessing Bill's PC through another PC? + jr nz, .next +; accessing it directly + call LoadTextBoxTilePatterns + ld a, $9a + call PlaySound + call WaitForSoundToFinish +.next + ld hl, wFlags_0xcd60 + res 5, [hl] + call LoadScreenTilesFromBuffer2 + pop af + ld [wListScrollOffset], a + ld hl, wd730 + res 6, [hl] + ret + +BillsPCDeposit: + ld a, [wPartyCount] + dec a + jr nz, .partyLargeEnough + ld hl, CantDepositLastMonText + call PrintText + jp BillsPCMenu +.partyLargeEnough + ld a, [wNumInBox] + cp MONS_PER_BOX + jr nz, .boxNotFull + ld hl, BoxFullText + call PrintText + jp BillsPCMenu +.boxNotFull + ld hl, wPartyCount + call DisplayMonListMenu + jp c, BillsPCMenu + call DisplayDepositWithdrawMenu + jp nc, BillsPCMenu + ld a, [wcf91] + call GetCryData + call PlaySoundWaitForCurrent + ld a, PARTY_TO_BOX + ld [wMoveMonType], a + call MoveMon + xor a + ld [wRemoveMonFromBox], a + call RemovePokemon + call WaitForSoundToFinish + ld hl, wBoxNumString + ld a, [wCurrentBoxNum] + and $7f + cp 9 + jr c, .singleDigitBoxNum + sub 9 + ld [hl], "1" + inc hl + add "0" + jr .next +.singleDigitBoxNum + add "1" +.next + ld [hli], a + ld [hl], "@" + ld hl, MonWasStoredText + call PrintText + jp BillsPCMenu + +BillsPCWithdraw: + ld a, [wNumInBox] + and a + jr nz, .boxNotEmpty + ld hl, NoMonText + call PrintText + jp BillsPCMenu +.boxNotEmpty + ld a, [wPartyCount] + cp PARTY_LENGTH + jr nz, .partyNotFull + ld hl, CantTakeMonText + call PrintText + jp BillsPCMenu +.partyNotFull + ld hl, wNumInBox + call DisplayMonListMenu + jp c, BillsPCMenu + call DisplayDepositWithdrawMenu + jp nc, BillsPCMenu + ld a, [wWhichPokemon] + ld hl, wBoxMonNicks + call GetPartyMonName + ld a, [wcf91] + call GetCryData + call PlaySoundWaitForCurrent + xor a ; BOX_TO_PARTY + ld [wMoveMonType], a + call MoveMon + ld a, 1 + ld [wRemoveMonFromBox], a + call RemovePokemon + call WaitForSoundToFinish + ld hl, MonIsTakenOutText + call PrintText + jp BillsPCMenu + +BillsPCRelease: + ld a, [wNumInBox] + and a + jr nz, .loop + ld hl, NoMonText + call PrintText + jp BillsPCMenu +.loop + ld hl, wNumInBox + call DisplayMonListMenu + jp c, BillsPCMenu + ld hl, OnceReleasedText + call PrintText + call YesNoChoice + ld a, [wCurrentMenuItem] + and a + jr nz, .loop + inc a + ld [wRemoveMonFromBox], a + call RemovePokemon + call WaitForSoundToFinish + ld a, [wcf91] + call PlayCry + ld hl, MonWasReleasedText + call PrintText + jp BillsPCMenu + +BillsPCChangeBox: + callba ChangeBox + jp BillsPCMenu + +DisplayMonListMenu: + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + xor a + ld [wPrintItemPrices], a + ld [wListMenuID], a + inc a ; MONSTER_NAME + ld [wNameListType], a + ld a, [wPartyAndBillsPCSavedMenuItem] + ld [wCurrentMenuItem], a + call DisplayListMenuID + ld a, [wCurrentMenuItem] + ld [wPartyAndBillsPCSavedMenuItem], a + ret + +BillsPCMenuText: + db "<pkmn> MITNEHMEN" + next "<pkmn> ABLEGEN" + next "<pkmn> FREILASSEN" + next "BOX WECHSELN" + next "TSCHÜSS!" + db "@" + +BoxNoPCText: + db "BOX Nr.@" + +KnowsHMMove:: +; returns whether mon with party index [wWhichPokemon] knows an HM move + ld hl, wPartyMon1Moves + ld bc, wPartyMon2 - wPartyMon1 + jr .next +; unreachable + ld hl, wBoxMon1Moves + ld bc, wBoxMon2 - wBoxMon1 +.next + ld a, [wWhichPokemon] + call AddNTimes + ld b, NUM_MOVES +.loop + ld a, [hli] + push hl + push bc + ld hl, HMMoveArray + ld de, 1 + call IsInArray + pop bc + pop hl + ret c + dec b + jr nz, .loop + and a + ret + +HMMoveArray: + db CUT + db FLY + db SURF + db STRENGTH + db FLASH + db -1 + +DisplayDepositWithdrawMenu: + coord hl, 8, 10 + ld b, 6 + ld c, 10 + call TextBoxBorder + ld a, [wParentMenuItem] + and a ; was the Deposit or Withdraw item selected in the parent menu? + ld de, DepositPCText + jr nz, .next + ld de, WithdrawPCText +.next + coord hl, 10, 12 + call PlaceString + coord hl, 10, 14 + ld de, StatsCancelPCText + call PlaceString + ld hl, wTopMenuItemY + ld a, 12 + ld [hli], a ; wTopMenuItemY + ld a, 9 + ld [hli], a ; wTopMenuItemX + xor a + ld [hli], a ; wCurrentMenuItem + inc hl + ld a, 2 + ld [hli], a ; wMaxMenuItem + ld a, A_BUTTON | B_BUTTON + ld [hli], a ; wMenuWatchedKeys + xor a + ld [hl], a ; wLastMenuItem + ld hl, wListScrollOffset + ld [hli], a ; wListScrollOffset + ld [hl], a ; wMenuWatchMovingOutOfBounds + ld [wPlayerMonNumber], a + ld [wPartyAndBillsPCSavedMenuItem], a +.loop + call HandleMenuInput + bit 1, a ; pressed B? + jr nz, .exit + ld a, [wCurrentMenuItem] + and a + jr z, .choseDepositWithdraw + dec a + jr z, .viewStats +.exit + and a + ret +.choseDepositWithdraw + scf + ret +.viewStats + call SaveScreenTilesToBuffer1 + ld a, [wParentMenuItem] + and a + ld a, PLAYER_PARTY_DATA + jr nz, .next2 + ld a, BOX_DATA +.next2 + ld [wMonDataLocation], a + predef StatusScreen + predef StatusScreen2 + call LoadScreenTilesFromBuffer1 + call ReloadTilesetTilePatterns + call RunDefaultPaletteCommand + call LoadGBPal + jr .loop + +DepositPCText: db "ABLEGEN@" +WithdrawPCText: db "MITNEHMEN@" +StatsCancelPCText: + db "STATUS" + next "ZURÜCK@" + +SwitchOnText: + TX_FAR _SwitchOnText + db "@" + +WhatText: + TX_FAR _WhatText + db "@" + +DepositWhichMonText: + TX_FAR _DepositWhichMonText + db "@" + +MonWasStoredText: + TX_FAR _MonWasStoredText + db "@" + +CantDepositLastMonText: + TX_FAR _CantDepositLastMonText + db "@" + +BoxFullText: + TX_FAR _BoxFullText + db "@" + +MonIsTakenOutText: + TX_FAR _MonIsTakenOutText + db "@" + +NoMonText: + TX_FAR _NoMonText + db "@" + +CantTakeMonText: + TX_FAR _CantTakeMonText + db "@" + +ReleaseWhichMonText: + TX_FAR _ReleaseWhichMonText + db "@" + +OnceReleasedText: + TX_FAR _OnceReleasedText + db "@" + +MonWasReleasedText: + TX_FAR _MonWasReleasedText + db "@" + +CableClubLeftGameboy:: + ld a, [hSerialConnectionStatus] + cp USING_EXTERNAL_CLOCK + ret z + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + cp SPRITE_FACING_RIGHT + ret nz + ld a, [wCurMap] + cp TRADE_CENTER + ld a, LINK_STATE_START_TRADE + jr z, .next + inc a ; LINK_STATE_START_BATTLE +.next + ld [wLinkState], a + call EnableAutoTextBoxDrawing + tx_pre_jump JustAMomentText + +CableClubRightGameboy:: + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + ret z + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + cp SPRITE_FACING_LEFT + ret nz + ld a, [wCurMap] + cp TRADE_CENTER + ld a, LINK_STATE_START_TRADE + jr z, .next + inc a ; LINK_STATE_START_BATTLE +.next + ld [wLinkState], a + call EnableAutoTextBoxDrawing + tx_pre_jump JustAMomentText + +JustAMomentText:: + TX_FAR _JustAMomentText + db "@" + + ld a, [wSpriteStateData1 + 9] ; player's sprite facing direction + cp SPRITE_FACING_UP + ret nz + call EnableAutoTextBoxDrawing + tx_pre_jump OpenBillsPCText + +OpenBillsPCText:: + db $FD ; FuncTX_BillsPC + diff --git a/de/engine/menu/diploma.asm b/de/engine/menu/diploma.asm new file mode 100755 index 00000000..9f559b8a --- /dev/null +++ b/de/engine/menu/diploma.asm @@ -0,0 +1,112 @@ +DisplayDiploma: + call SaveScreenTilesToBuffer2 + call GBPalWhiteOutWithDelay3 + call ClearScreen + xor a + ld [wUpdateSpritesEnabled], a + ld hl, wd730 + set 6, [hl] + call DisableLCD + ld hl, CircleTile + ld de, vChars2 + $700 + ld bc, $0010 + ld a, BANK(CircleTile) + call FarCopyData2 + coord hl, 0, 0 + lb bc, 16, 18 + predef Diploma_TextBoxBorder + ld hl, DiplomaTextPointersAndCoords + ld c, $5 +.asm_56715 + push bc + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + push hl + ld h, [hl] + ld l, a + call PlaceString + pop hl + inc hl + pop bc + dec c + jr nz, .asm_56715 + coord hl, 9, 6 + ld de, wPlayerName + call PlaceString + callba DrawPlayerCharacter + +; Move the player 33 pixels right and set the priority bit so he appears +; behind the background layer. + ld hl, wOAMBuffer + $01 + lb bc, $80, $28 +.adjustPlayerGfxLoop + ld a, [hl] ; X + add 33 + ld [hli], a + inc hl + ld a, b + ld [hli], a ; attributes + inc hl + dec c + jr nz, .adjustPlayerGfxLoop + + call EnableLCD + callba LoadTrainerInfoTextBoxTiles + ld b, SET_PAL_GENERIC + call RunPaletteCommand + call Delay3 + call GBPalNormal + ld a, $90 + ld [rOBP0], a + call WaitForTextScrollButtonPress + ld hl, wd730 + res 6, [hl] + call GBPalWhiteOutWithDelay3 + call RestoreScreenTilesAndReloadTilePatterns + call Delay3 + jp GBPalNormal + +UnusedPlayerNameLengthFunc: +; Unused function that does a calculation involving the length of the player's +; name. + ld hl, wPlayerName + ld bc, $ff00 +.loop + ld a, [hli] + cp "@" + ret z + dec c + jr .loop + +DiplomaTextPointersAndCoords: + dw DiplomaText + dwCoord 6, 2 + dw DiplomaPlayer1 + dwCoord 2, 4 + dw DiplomaPlayer2 + dwCoord 2, 6 + dw DiplomaCongrats + dwCoord 2, 8 + dw DiplomaGameFreak + dwCoord 9, 16 + +DiplomaText: + db $70,"Diplom",$70,"@" + +DiplomaPlayer1: + db "Herzlichen Glück-@" + +DiplomaPlayer2: + db "wunsch !@" + +DiplomaCongrats: + db "Du hast es ge-" + next "schafft, den" + next "#DEX zu" + next "vervollständigen@" + +DiplomaGameFreak: + db "GAME FREAK@" diff --git a/de/engine/menu/draw_start_menu.asm b/de/engine/menu/draw_start_menu.asm new file mode 100644 index 00000000..5e10b972 --- /dev/null +++ b/de/engine/menu/draw_start_menu.asm @@ -0,0 +1,89 @@ +; function that displays the start menu +DrawStartMenu: + CheckEvent EVENT_GOT_POKEDEX +; menu with pokedex + coord hl, 10, 0 + ld b,$0e + ld c,$08 + jr nz,.drawTextBoxBorder +; shorter menu if the player doesn't have the pokedex + coord hl, 10, 0 + ld b,$0c + ld c,$08 +.drawTextBoxBorder + call TextBoxBorder + ld a,D_DOWN | D_UP | START | B_BUTTON | A_BUTTON + ld [wMenuWatchedKeys],a + ld a,$02 + ld [wTopMenuItemY],a ; Y position of first menu choice + ld a,$0b + ld [wTopMenuItemX],a ; X position of first menu choice + ld a,[wBattleAndStartSavedMenuItem] ; remembered menu selection from last time + ld [wCurrentMenuItem],a + ld [wLastMenuItem],a + xor a + ld [wMenuWatchMovingOutOfBounds],a + ld hl,wd730 + set 6,[hl] ; no pauses between printing each letter + coord hl, 12, 2 + CheckEvent EVENT_GOT_POKEDEX +; case for not having pokedex + ld a,$06 + jr z,.storeMenuItemCount +; case for having pokedex + ld de,StartMenuPokedexText + call PrintStartMenuItem + ld a,$07 +.storeMenuItemCount + ld [wMaxMenuItem],a ; number of menu items + ld de,StartMenuPokemonText + call PrintStartMenuItem + ld de,StartMenuItemText + call PrintStartMenuItem + ld de,wPlayerName ; player's name + call PrintStartMenuItem + ld a,[wd72e] + bit 6,a ; is the player using the link feature? +; case for not using link feature + ld de,StartMenuSaveText + jr z,.printSaveOrResetText +; case for using link feature + ld de,StartMenuResetText +.printSaveOrResetText + call PrintStartMenuItem + ld de,StartMenuOptionText + call PrintStartMenuItem + ld de,StartMenuExitText + call PlaceString + ld hl,wd730 + res 6,[hl] ; turn pauses between printing letters back on + ret + +StartMenuPokedexText: + db "#DEX@" + +StartMenuPokemonText: + db "#MON@" + +StartMenuItemText: + db "ITEM@" + +StartMenuSaveText: + db "SICHERN@" + +StartMenuResetText: + db "RESET@" + +StartMenuExitText: + db "ZURÜCK@" + +StartMenuOptionText: + db "OPTION@" + +PrintStartMenuItem: + push hl + call PlaceString + pop hl + ld de,SCREEN_WIDTH * 2 + add hl,de + ret diff --git a/de/engine/menu/league_pc.asm b/de/engine/menu/league_pc.asm new file mode 100755 index 00000000..8ca8e1e3 --- /dev/null +++ b/de/engine/menu/league_pc.asm @@ -0,0 +1,120 @@ +PKMNLeaguePC: + ld hl, AccessedHoFPCText + call PrintText + ld hl, wd730 + set 6, [hl] + push hl + ld a, [wUpdateSpritesEnabled] + push af + ld a, [hTilesetType] + push af + xor a + ld [hTilesetType], a + ld [wSpriteFlipped], a + ld [wUpdateSpritesEnabled], a + ld [wHoFTeamIndex2], a + ld [wHoFTeamNo], a + ld a, [wNumHoFTeams] + ld b, a + cp HOF_TEAM_CAPACITY + 1 + jr c, .loop +; If the total number of hall of fame teams is greater than the storage +; capacity, then calculate the number of the first team that is still recorded. + ld b, HOF_TEAM_CAPACITY + sub b + ld [wHoFTeamNo], a +.loop + ld hl, wHoFTeamNo + inc [hl] + push bc + ld a, [wHoFTeamIndex2] + ld [wHoFTeamIndex], a + callba LoadHallOfFameTeams + call LeaguePCShowTeam + pop bc + jr c, .doneShowingTeams + ld hl, wHoFTeamIndex2 + inc [hl] + ld a, [hl] + cp b + jr nz, .loop +.doneShowingTeams + pop af + ld [hTilesetType], a + pop af + ld [wUpdateSpritesEnabled], a + pop hl + res 6, [hl] + call GBPalWhiteOutWithDelay3 + call ClearScreen + call RunDefaultPaletteCommand + jp GBPalNormal + +LeaguePCShowTeam: + ld c, PARTY_LENGTH +.loop + push bc + call LeaguePCShowMon + call WaitForTextScrollButtonPress + ld a, [hJoyHeld] + bit 1, a + jr nz, .exit + ld hl, wHallOfFame + HOF_MON + ld de, wHallOfFame + ld bc, HOF_TEAM - HOF_MON + call CopyData + pop bc + ld a, [wHallOfFame + 0] + cp $ff + jr z, .done + dec c + jr nz, .loop +.done + and a + ret +.exit + pop bc + scf + ret + +LeaguePCShowMon: + call GBPalWhiteOutWithDelay3 + call ClearScreen + ld hl, wHallOfFame + ld a, [hli] + ld [wHoFMonSpecies], a + ld [wcf91], a + ld [wd0b5], a + ld [wBattleMonSpecies2], a + ld [wWholeScreenPaletteMonSpecies], a + ld a, [hli] + ld [wHoFMonLevel], a + ld de, wcd6d + ld bc, NAME_LENGTH + call CopyData + ld b, SET_PAL_POKEMON_WHOLE_SCREEN + ld c, 0 + call RunPaletteCommand + coord hl, 12, 5 + call GetMonHeader + call LoadFrontSpriteByMonIndex + call GBPalNormal + coord hl, 0, 13 + ld b, 2 + ld c, $12 + call TextBoxBorder + coord hl, 1, 15 + ld de, HallOfFameNoText + call PlaceString + coord hl, 16, 15 + ld de, wHoFTeamNo + lb bc, 1, 3 + call PrintNumber + jpba HoFDisplayMonInfo + +HallOfFameNoText: + db "RUHMESHALLE Nr.@" + +AccessedHoFPCText: + TX_FAR _AccessedHoFPCText + db "@" diff --git a/de/engine/menu/main_menu.asm b/de/engine/menu/main_menu.asm new file mode 100755 index 00000000..2da68a3b --- /dev/null +++ b/de/engine/menu/main_menu.asm @@ -0,0 +1,712 @@ +MainMenu: +; Check save file + call InitOptions + xor a + ld [wOptionsInitialized],a + inc a + ld [wSaveFileStatus],a + call CheckForPlayerNameInSRAM + jr nc,.mainMenuLoop + + predef LoadSAV + +.mainMenuLoop + ld c,20 + call DelayFrames + xor a ; LINK_STATE_NONE + ld [wLinkState],a + ld hl,wPartyAndBillsPCSavedMenuItem + ld [hli],a + ld [hli],a + ld [hli],a + ld [hl],a + ld [wDefaultMap],a + ld hl,wd72e + res 6,[hl] + call ClearScreen + call RunDefaultPaletteCommand + call LoadTextBoxTilePatterns + call LoadFontTilePatterns + ld hl,wd730 + set 6,[hl] + ld a,[wSaveFileStatus] + cp a,1 + jr z,.noSaveFile +; there's a save file + coord hl, 0, 0 + ld b,6 + ld c,13 + call TextBoxBorder + coord hl, 2, 2 + ld de,ContinueText + call PlaceString + jr .next2 +.noSaveFile + coord hl, 0, 0 + ld b,4 + ld c,13 + call TextBoxBorder + coord hl, 2, 2 + ld de,NewGameText + call PlaceString +.next2 + ld hl,wd730 + res 6,[hl] + call UpdateSprites + xor a + ld [wCurrentMenuItem],a + ld [wLastMenuItem],a + ld [wMenuJoypadPollCount],a + inc a + ld [wTopMenuItemX],a + inc a + ld [wTopMenuItemY],a + ld a,A_BUTTON | B_BUTTON | START + ld [wMenuWatchedKeys],a + ld a,[wSaveFileStatus] + ld [wMaxMenuItem],a + call HandleMenuInput + bit 1,a ; pressed B? + jp nz,DisplayTitleScreen ; if so, go back to the title screen + ld c,20 + call DelayFrames + ld a,[wCurrentMenuItem] + ld b,a + ld a,[wSaveFileStatus] + cp a,2 + jp z,.skipInc +; If there's no save file, increment the current menu item so that the numbers +; are the same whether or not there's a save file. + inc b +.skipInc + ld a,b + and a + jr z,.choseContinue + cp a,1 + jp z,StartNewGame + call DisplayOptionMenu + ld a,1 + ld [wOptionsInitialized],a + jp .mainMenuLoop +.choseContinue + call DisplayContinueGameInfo + ld hl,wCurrentMapScriptFlags + set 5,[hl] +.inputLoop + xor a + ld [hJoyPressed],a + ld [hJoyReleased],a + ld [hJoyHeld],a + call Joypad + ld a,[hJoyHeld] + bit 0,a + jr nz,.pressedA + bit 1,a + jp nz,.mainMenuLoop ; pressed B + jr .inputLoop +.pressedA + call GBPalWhiteOutWithDelay3 + call ClearScreen + ld a,PLAYER_DIR_DOWN + ld [wPlayerDirection],a + ld c,10 + call DelayFrames + ld a,[wNumHoFTeams] + and a + jp z,SpecialEnterMap + ld a,[wCurMap] ; map ID + cp a,HALL_OF_FAME + jp nz,SpecialEnterMap + xor a + ld [wDestinationMap],a + ld hl,wd732 + set 2,[hl] ; fly warp or dungeon warp + call SpecialWarpIn + jp SpecialEnterMap + +InitOptions: + ld a,1 ; no delay + ld [wLetterPrintingDelayFlags],a + ld a,3 ; medium speed + ld [wOptions],a + ret + +LinkMenu: + xor a + ld [wLetterPrintingDelayFlags], a + ld hl, wd72e + set 6, [hl] + ld hl, TextTerminator_6b20 + call PrintText + call SaveScreenTilesToBuffer1 + ld hl, WhereWouldYouLikeText + call PrintText + coord hl, 4, 5 + ld b, $6 + ld c, $e + call TextBoxBorder + call UpdateSprites + coord hl, 6, 7 + ld de, CableClubOptionsText + call PlaceString + xor a + ld [wUnusedCD37], a + ld [wd72d], a + ld hl, wTopMenuItemY + ld a, $7 + ld [hli], a + ld a, $5 + ld [hli], a + xor a + ld [hli], a + inc hl + ld a, $2 + ld [hli], a + inc a + ; ld a, A_BUTTON | B_BUTTON + ld [hli], a ; wMenuWatchedKeys + xor a + ld [hl], a +.waitForInputLoop + call HandleMenuInput + and A_BUTTON | B_BUTTON + add a + add a + ld b, a + ld a, [wCurrentMenuItem] + add b + add $d0 + ld [wLinkMenuSelectionSendBuffer], a + ld [wLinkMenuSelectionSendBuffer + 1], a +.exchangeMenuSelectionLoop + call Serial_ExchangeLinkMenuSelection + ld a, [wLinkMenuSelectionReceiveBuffer] + ld b, a + and $f0 + cp $d0 + jr z, .asm_5c7d + ld a, [wLinkMenuSelectionReceiveBuffer + 1] + ld b, a + and $f0 + cp $d0 + jr nz, .exchangeMenuSelectionLoop +.asm_5c7d + ld a, b + and $c ; did the enemy press A or B? + jr nz, .enemyPressedAOrB +; the enemy didn't press A or B + ld a, [wLinkMenuSelectionSendBuffer] + and $c ; did the player press A or B? + jr z, .waitForInputLoop ; if neither the player nor the enemy pressed A or B, try again + jr .doneChoosingMenuSelection ; if the player pressed A or B but the enemy didn't, use the player's selection +.enemyPressedAOrB + ld a, [wLinkMenuSelectionSendBuffer] + and $c ; did the player press A or B? + jr z, .useEnemyMenuSelection ; if the enemy pressed A or B but the player didn't, use the enemy's selection +; the enemy and the player both pressed A or B +; The gameboy that is clocking the connection wins. + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr z, .doneChoosingMenuSelection +.useEnemyMenuSelection + ld a, b + ld [wLinkMenuSelectionSendBuffer], a + and $3 + ld [wCurrentMenuItem], a +.doneChoosingMenuSelection + ld a, [hSerialConnectionStatus] + cp USING_INTERNAL_CLOCK + jr nz, .skipStartingTransfer + call DelayFrame + call DelayFrame + ld a, START_TRANSFER_INTERNAL_CLOCK + ld [rSC], a +.skipStartingTransfer + ld b, $7f + ld c, $7f + ld d, $ec + ld a, [wLinkMenuSelectionSendBuffer] + and (B_BUTTON << 2) ; was B button pressed? + jr nz, .updateCursorPosition +; A button was pressed + ld a, [wCurrentMenuItem] + cp $2 + jr z, .updateCursorPosition + ld c, d + ld d, b + dec a + jr z, .updateCursorPosition + ld b, c + ld c, d +.updateCursorPosition + ld a, b + Coorda 5, 7 + ld a, c + Coorda 5, 9 + ld a, d + Coorda 5, 11 + ld c, 40 + call DelayFrames + call LoadScreenTilesFromBuffer1 + ld a, [wLinkMenuSelectionSendBuffer] + and (B_BUTTON << 2) ; was B button pressed? + jr nz, .choseCancel ; cancel if B pressed + ld a, [wCurrentMenuItem] + cp $2 + jr z, .choseCancel + xor a + ld [wWalkBikeSurfState], a ; start walking + ld a, [wCurrentMenuItem] + and a + ld a, COLOSSEUM + jr nz, .next + ld a, TRADE_CENTER +.next + ld [wd72d], a + ld hl, PleaseWaitText + call PrintText + ld c, 50 + call DelayFrames + ld hl, wd732 + res 1, [hl] + ld a, [wDefaultMap] + ld [wDestinationMap], a + call SpecialWarpIn + ld c, 20 + call DelayFrames + xor a + ld [wMenuJoypadPollCount], a + ld [wSerialExchangeNybbleSendData], a + inc a ; LINK_STATE_IN_CABLE_CLUB + ld [wLinkState], a + ld [wEnteringCableClub], a + jr SpecialEnterMap +.choseCancel + xor a + ld [wMenuJoypadPollCount], a + call Delay3 + call CloseLinkConnection + ld hl, LinkCanceledText + call PrintText + ld hl, wd72e + res 6, [hl] + ret + +WhereWouldYouLikeText: + TX_FAR _WhereWouldYouLikeText + db "@" + +PleaseWaitText: + TX_FAR _PleaseWaitText + db "@" + +LinkCanceledText: + TX_FAR _LinkCanceledText + db "@" + +StartNewGame: + ld hl, wd732 + res 1, [hl] + call OakSpeech + ld c, 20 + call DelayFrames + +; enter map after using a special warp or loading the game from the main menu +SpecialEnterMap: + xor a + ld [hJoyPressed], a + ld [hJoyHeld], a + ld [hJoy5], a + ld [wd72d], a + ld hl, wd732 + set 0, [hl] ; count play time + call ResetPlayerSpriteData + ld c, 20 + call DelayFrames + ld a, [wEnteringCableClub] + and a + ret nz + jp EnterMap + +ContinueText: + db "WEITER", $4e + +NewGameText: + db "NEUES SPIEL" + next "OPTIONEN@" + +CableClubOptionsText: + db "HANDELSCENTER" + next "KOLOSSEUM" + next "ZURÜCK@" + +DisplayContinueGameInfo: + xor a + ld [H_AUTOBGTRANSFERENABLED], a + coord hl, 3, 7 + ld b, 8 + ld c, 15 + call TextBoxBorder + coord hl, 4, 9 + ld de, SaveScreenInfoText + call PlaceString + coord hl, 12, 9 + ld de, wPlayerName + call PlaceString + coord hl, 17, 11 + call PrintNumBadges + coord hl, 16, 13 + call PrintNumOwnedMons + coord hl, 13, 15 + call PrintPlayTime + ld a, 1 + ld [H_AUTOBGTRANSFERENABLED], a + ld c, 30 + jp DelayFrames + +PrintSaveScreenText: + xor a + ld [H_AUTOBGTRANSFERENABLED], a + coord hl, 3, 0 + ld b, $8 + ld c, $f + call TextBoxBorder + call LoadTextBoxTilePatterns + call UpdateSprites + coord hl, 4, 2 + ld de, SaveScreenInfoText + call PlaceString + coord hl, 12, 2 + ld de, wPlayerName + call PlaceString + coord hl, 17, 4 + call PrintNumBadges + coord hl, 16, 6 + call PrintNumOwnedMons + coord hl, 13, 8 + call PrintPlayTime + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a + ld c, 30 + jp DelayFrames + +PrintNumBadges: + push hl + ld hl, wObtainedBadges + ld b, $1 + call CountSetBits + pop hl + ld de, wNumSetBits + lb bc, 1, 2 + jp PrintNumber + +PrintNumOwnedMons: + push hl + ld hl, wPokedexOwned + ld b, wPokedexOwnedEnd - wPokedexOwned + call CountSetBits + pop hl + ld de, wNumSetBits + lb bc, 1, 3 + jp PrintNumber + +PrintPlayTime: + ld de, wPlayTimeHours + lb bc, 1, 3 + call PrintNumber + ld [hl], $6d + inc hl + ld de, wPlayTimeMinutes + lb bc, LEADING_ZEROES | 1, 2 + jp PrintNumber + +SaveScreenInfoText: + db "SPIELER" + next "ORDEN " + next "#DEX " + next "ZEIT@" + +DisplayOptionMenu: + coord hl, 0, 0 + ld b,3 + ld c,18 + call TextBoxBorder + coord hl, 0, 5 + ld b,3 + ld c,18 + call TextBoxBorder + coord hl, 0, 10 + ld b,3 + ld c,18 + call TextBoxBorder + coord hl, 1, 1 + ld de,TextSpeedOptionText + call PlaceString + coord hl, 1, 6 + ld de,BattleAnimationOptionText + call PlaceString + coord hl, 1, 11 + ld de,BattleStyleOptionText + call PlaceString + coord hl, 2, 16 + ld de,OptionMenuCancelText + call PlaceString + xor a + ld [wCurrentMenuItem],a + ld [wLastMenuItem],a + inc a + ld [wLetterPrintingDelayFlags],a + ld [wUnusedCD40],a + ld a,3 ; text speed cursor Y coordinate + ld [wTopMenuItemY],a + call SetCursorPositionsFromOptions + ld a,[wOptionsTextSpeedCursorX] ; text speed cursor X coordinate + ld [wTopMenuItemX],a + ld a,$01 + ld [H_AUTOBGTRANSFERENABLED],a ; enable auto background transfer + call Delay3 +.loop + call PlaceMenuCursor + call SetOptionsFromCursorPositions +.getJoypadStateLoop + call JoypadLowSensitivity + ld a,[hJoy5] + ld b,a + and a,A_BUTTON | B_BUTTON | START | D_RIGHT | D_LEFT | D_UP | D_DOWN ; any key besides select pressed? + jr z,.getJoypadStateLoop + bit 1,b ; B button pressed? + jr nz,.exitMenu + bit 3,b ; Start button pressed? + jr nz,.exitMenu + bit 0,b ; A button pressed? + jr z,.checkDirectionKeys + ld a,[wTopMenuItemY] + cp a,16 ; is the cursor on Cancel? + jr nz,.loop +.exitMenu + ld a,SFX_PRESS_AB + call PlaySound + ret +.eraseOldMenuCursor + ld [wTopMenuItemX],a + call EraseMenuCursor + jp .loop +.checkDirectionKeys + ld a,[wTopMenuItemY] + bit 7,b ; Down pressed? + jr nz,.downPressed + bit 6,b ; Up pressed? + jr nz,.upPressed + cp a,8 ; cursor in Battle Animation section? + jr z,.cursorInBattleAnimation + cp a,13 ; cursor in Battle Style section? + jr z,.cursorInBattleStyle + cp a,16 ; cursor on Cancel? + jr z,.loop +.cursorInTextSpeed + bit 5,b ; Left pressed? + jp nz,.pressedLeftInTextSpeed + jp .pressedRightInTextSpeed +.downPressed + cp a,16 + ld b,-13 + ld hl,wOptionsTextSpeedCursorX + jr z,.updateMenuVariables + ld b,5 + cp a,3 + inc hl + jr z,.updateMenuVariables + cp a,8 + inc hl + jr z,.updateMenuVariables + ld b,3 + inc hl + jr .updateMenuVariables +.upPressed + cp a,8 + ld b,-5 + ld hl,wOptionsTextSpeedCursorX + jr z,.updateMenuVariables + cp a,13 + inc hl + jr z,.updateMenuVariables + cp a,16 + ld b,-3 + inc hl + jr z,.updateMenuVariables + ld b,13 + inc hl +.updateMenuVariables + add b + ld [wTopMenuItemY],a + ld a,[hl] + ld [wTopMenuItemX],a + call PlaceUnfilledArrowMenuCursor + jp .loop +.cursorInBattleAnimation + ld a,[wOptionsBattleAnimCursorX] ; battle animation cursor X coordinate + xor a,$0b ; toggle between 1 and 10 + ld [wOptionsBattleAnimCursorX],a + jp .eraseOldMenuCursor +.cursorInBattleStyle + ld a,[wOptionsBattleStyleCursorX] ; battle style cursor X coordinate + xor a,$0b ; toggle between 1 and 10 + ld [wOptionsBattleStyleCursorX],a + jp .eraseOldMenuCursor +.pressedLeftInTextSpeed + ld a,[wOptionsTextSpeedCursorX] ; text speed cursor X coordinate + cp a,1 + jr z,.updateTextSpeedXCoord + cp a,7 + jr nz,.fromSlowToMedium + sub a,6 + jr .updateTextSpeedXCoord +.fromSlowToMedium + sub a,7 + jr .updateTextSpeedXCoord +.pressedRightInTextSpeed + ld a,[wOptionsTextSpeedCursorX] ; text speed cursor X coordinate + cp a,14 + jr z,.updateTextSpeedXCoord + cp a,7 + jr nz,.fromFastToMedium + add a,7 + jr .updateTextSpeedXCoord +.fromFastToMedium + add a,6 +.updateTextSpeedXCoord + ld [wOptionsTextSpeedCursorX],a ; text speed cursor X coordinate + jp .eraseOldMenuCursor + +TextSpeedOptionText: + db "TEXT-TEMPO" + next " 3 2 1 @" + +BattleAnimationOptionText: + db "KAMPFANIMATION" + next " AN AUS@" + +BattleStyleOptionText: + db "KAMPFSTIL" + next " WECHSEL FOLGEND@" + +OptionMenuCancelText: + db "ZURÜCK@" + +; sets the options variable according to the current placement of the menu cursors in the options menu +SetOptionsFromCursorPositions: + ld hl,TextSpeedOptionData + ld a,[wOptionsTextSpeedCursorX] ; text speed cursor X coordinate + ld c,a +.loop + ld a,[hli] + cp c + jr z,.textSpeedMatchFound + inc hl + jr .loop +.textSpeedMatchFound + ld a,[hl] + ld d,a + ld a,[wOptionsBattleAnimCursorX] ; battle animation cursor X coordinate + dec a + jr z,.battleAnimationOn +.battleAnimationOff + set 7,d + jr .checkBattleStyle +.battleAnimationOn + res 7,d +.checkBattleStyle + ld a,[wOptionsBattleStyleCursorX] ; battle style cursor X coordinate + dec a + jr z,.battleStyleShift +.battleStyleSet + set 6,d + jr .storeOptions +.battleStyleShift + res 6,d +.storeOptions + ld a,d + ld [wOptions],a + ret + +; reads the options variable and places menu cursors in the correct positions within the options menu +SetCursorPositionsFromOptions: + ld hl,TextSpeedOptionData + 1 + ld a,[wOptions] + ld c,a + and a,$3f + push bc + ld de,2 + call IsInArray + pop bc + dec hl + ld a,[hl] + ld [wOptionsTextSpeedCursorX],a ; text speed cursor X coordinate + coord hl, 0, 3 + call .placeUnfilledRightArrow + sla c + ld a,1 ; On + jr nc,.storeBattleAnimationCursorX + ld a,10 ; Off +.storeBattleAnimationCursorX + ld [wOptionsBattleAnimCursorX],a ; battle animation cursor X coordinate + coord hl, 0, 8 + call .placeUnfilledRightArrow + sla c + ld a,1 + jr nc,.storeBattleStyleCursorX + ld a,10 +.storeBattleStyleCursorX + ld [wOptionsBattleStyleCursorX],a ; battle style cursor X coordinate + coord hl, 0, 13 + call .placeUnfilledRightArrow +; cursor in front of Cancel + coord hl, 0, 16 + ld a,1 +.placeUnfilledRightArrow + ld e,a + ld d,0 + add hl,de + ld [hl],$ec ; unfilled right arrow menu cursor + ret + +; table that indicates how the 3 text speed options affect frame delays +; Format: +; 00: X coordinate of menu cursor +; 01: delay after printing a letter (in frames) +TextSpeedOptionData: + db 14,5 ; Slow + db 7,3 ; Medium + db 1,1 ; Fast + db 7 ; default X coordinate (Medium) + db $ff ; terminator + +CheckForPlayerNameInSRAM: +; Check if the player name data in SRAM has a string terminator character +; (indicating that a name may have been saved there) and return whether it does +; in carry. + ld a, SRAM_ENABLE + ld [MBC1SRamEnable], a + ld a, $1 + ld [MBC1SRamBankingMode], a + ld [MBC1SRamBank], a + ld b, NAME_LENGTH + ld hl, sPlayerName +.loop + ld a, [hli] + cp "@" + jr z, .found + dec b + jr nz, .loop +; not found + xor a + ld [MBC1SRamEnable], a + ld [MBC1SRamBankingMode], a + and a + ret +.found + xor a + ld [MBC1SRamEnable], a + ld [MBC1SRamBankingMode], a + scf + ret diff --git a/de/engine/menu/naming_screen.asm b/de/engine/menu/naming_screen.asm new file mode 100755 index 00000000..a3c2c72a --- /dev/null +++ b/de/engine/menu/naming_screen.asm @@ -0,0 +1,512 @@ +AskName: + call SaveScreenTilesToBuffer1 + call GetPredefRegisters + push hl + ld a, [wIsInBattle] + dec a + coord hl, 0, 0 + ld b, 4 + ld c, 11 + call z, ClearScreenArea ; only if in wild battle + ld a, [wcf91] + ld [wd11e], a + call GetMonName + ld hl, DoYouWantToNicknameText + call PrintText + coord hl, 13, 7 + lb bc, 8, 14 + ld a, TWO_OPTION_MENU + ld [wTextBoxID], a + call DisplayTextBoxID + pop hl + ld a, [wCurrentMenuItem] + and a + jr nz, .declinedNickname + ld a, [wUpdateSpritesEnabled] + push af + xor a + ld [wUpdateSpritesEnabled], a + push hl + ld a, NAME_MON_SCREEN + ld [wNamingScreenType], a + call DisplayNamingScreen + ld a, [wIsInBattle] + and a + jr nz, .inBattle + call ReloadMapSpriteTilePatterns +.inBattle + call LoadScreenTilesFromBuffer1 + pop hl + pop af + ld [wUpdateSpritesEnabled], a + ld a, [wcf50] + cp "@" + ret nz +.declinedNickname + ld d, h + ld e, l + ld hl, wcd6d + ld bc, NAME_LENGTH + jp CopyData + +DoYouWantToNicknameText: + TX_FAR _DoYouWantToNicknameText + db "@" + +DisplayNameRaterScreen: + ld hl, wBuffer + xor a + ld [wUpdateSpritesEnabled], a + ld a, NAME_MON_SCREEN + ld [wNamingScreenType], a + call DisplayNamingScreen + call GBPalWhiteOutWithDelay3 + call RestoreScreenTilesAndReloadTilePatterns + call LoadGBPal + ld a, [wcf50] + cp "@" + jr z, .playerCancelled + ld hl, wPartyMonNicks + ld bc, NAME_LENGTH + ld a, [wWhichPokemon] + call AddNTimes + ld e, l + ld d, h + ld hl, wBuffer + ld bc, NAME_LENGTH + call CopyData + and a + ret +.playerCancelled + scf + ret + +DisplayNamingScreen: + push hl + ld hl, wd730 + set 6, [hl] + call GBPalWhiteOutWithDelay3 + call ClearScreen + call UpdateSprites + ld b, SET_PAL_GENERIC + call RunPaletteCommand + call LoadHpBarAndStatusTilePatterns + call LoadEDTile + callba LoadMonPartySpriteGfx + coord hl, 0, 4 + ld b, 9 + ld c, 18 + call TextBoxBorder + call PrintNamingText + ld a, 3 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a + ld [wLastMenuItem], a + ld [wCurrentMenuItem], a + ld a, $ff + ld [wMenuWatchedKeys], a + ld a, 7 + ld [wMaxMenuItem], a + ld a, "@" + ld [wcf50], a + xor a + ld hl, wNamingScreenSubmitName + ld [hli], a + ld [hli], a + ld [wAnimCounter], a +.selectReturnPoint + call PrintAlphabet + call GBPalNormal +.ABStartReturnPoint + ld a, [wNamingScreenSubmitName] + and a + jr nz, .submitNickname + call PrintNicknameAndUnderscores +.dPadReturnPoint + call PlaceMenuCursor +.inputLoop + ld a, [wCurrentMenuItem] + push af + callba AnimatePartyMon_ForceSpeed1 + pop af + ld [wCurrentMenuItem], a + call JoypadLowSensitivity + ld a, [hJoyPressed] + and a + jr z, .inputLoop + ld hl, .namingScreenButtonFunctions +.checkForPressedButton + sla a + jr c, .foundPressedButton + inc hl + inc hl + inc hl + inc hl + jr .checkForPressedButton +.foundPressedButton + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + ld a, [hli] + ld h, [hl] + ld l, a + push de + jp hl + +.submitNickname + pop de + ld hl, wcf50 + ld bc, NAME_LENGTH + call CopyData + call GBPalWhiteOutWithDelay3 + call ClearScreen + call ClearSprites + call RunDefaultPaletteCommand + call GBPalNormal + xor a + ld [wAnimCounter], a + ld hl, wd730 + res 6, [hl] + ld a, [wIsInBattle] + and a + jp z, LoadTextBoxTilePatterns + jpab LoadHudTilePatterns + +.namingScreenButtonFunctions + dw .dPadReturnPoint + dw .pressedDown + dw .dPadReturnPoint + dw .pressedUp + dw .dPadReturnPoint + dw .pressedLeft + dw .dPadReturnPoint + dw .pressedRight + dw .ABStartReturnPoint + dw .pressedStart + dw .selectReturnPoint + dw .pressedSelect + dw .ABStartReturnPoint + dw .pressedB + dw .ABStartReturnPoint + dw .pressedA + +.pressedA_changedCase + pop de + ld de, .selectReturnPoint + push de +.pressedSelect + ld a, [wAlphabetCase] + xor $1 + ld [wAlphabetCase], a + ret + +.pressedStart + ld a, 1 + ld [wNamingScreenSubmitName], a + ret + +.pressedA + ld a, [wCurrentMenuItem] + cp $5 ; "ED" row + jr nz, .didNotPressED + ld a, [wTopMenuItemX] + cp $11 ; "ED" column + jr z, .pressedStart +.didNotPressED + ld a, [wCurrentMenuItem] + cp $6 ; case switch row + jr nz, .didNotPressCaseSwtich + ld a, [wTopMenuItemX] + cp $1 ; case switch column + jr z, .pressedA_changedCase +.didNotPressCaseSwtich + ld hl, wMenuCursorLocation + ld a, [hli] + ld h, [hl] + ld l, a + inc hl + ld a, [hl] + ld [wNamingScreenLetter], a + call CalcStringLength + ld a, [wNamingScreenLetter] + cp $e5 + ld de, Dakutens + jr z, .dakutensAndHandakutens + cp $e4 + ld de, Handakutens + jr z, .dakutensAndHandakutens + ld a, [wNamingScreenType] + cp NAME_MON_SCREEN + jr nc, .checkMonNameLength + ld a, [wNamingScreenNameLength] + cp $7 ; max length of player/rival names + jr .checkNameLength +.checkMonNameLength + ld a, [wNamingScreenNameLength] + cp $a ; max length of pokemon nicknames +.checkNameLength + jr c, .addLetter + ret + +.dakutensAndHandakutens + push hl + call DakutensAndHandakutens + pop hl + ret nc + dec hl +.addLetter + ld a, [wNamingScreenLetter] + ld [hli], a + ld [hl], "@" + ld a, SFX_PRESS_AB + call PlaySound + ret +.pressedB + ld a, [wNamingScreenNameLength] + and a + ret z + call CalcStringLength + dec hl + ld [hl], "@" + ret +.pressedRight + ld a, [wCurrentMenuItem] + cp $6 + ret z ; can't scroll right on bottom row + ld a, [wTopMenuItemX] + cp $11 ; max + jp z, .wrapToFirstColumn + inc a + inc a + jr .done +.wrapToFirstColumn + ld a, $1 + jr .done +.pressedLeft + ld a, [wCurrentMenuItem] + cp $6 + ret z ; can't scroll right on bottom row + ld a, [wTopMenuItemX] + dec a + jp z, .wrapToLastColumn + dec a + jr .done +.wrapToLastColumn + ld a, $11 ; max + jr .done +.pressedUp + ld a, [wCurrentMenuItem] + dec a + ld [wCurrentMenuItem], a + and a + ret nz + ld a, $6 ; wrap to bottom row + ld [wCurrentMenuItem], a + ld a, $1 ; force left column + jr .done +.pressedDown + ld a, [wCurrentMenuItem] + inc a + ld [wCurrentMenuItem], a + cp $7 + jr nz, .wrapToTopRow + ld a, $1 + ld [wCurrentMenuItem], a + jr .done +.wrapToTopRow + cp $6 + ret nz + ld a, $1 +.done + ld [wTopMenuItemX], a + jp EraseMenuCursor + +LoadEDTile: + call DisableLCD + ld de, vFont + $700 + ld hl, ED_Tile + ld bc, (ED_TileEnd - ED_Tile) + ; to fix the graphical bug on poor emulators + ;lb bc, BANK(ED_Tile), (ED_TileEnd - ED_Tile) + ld a,$01 + call FarCopyDataDouble + jp EnableLCD + +ED_Tile: + INCBIN "gfx/ED_tile.1bpp" +ED_TileEnd: + +PrintAlphabet: + xor a + ld [H_AUTOBGTRANSFERENABLED], a + ld a, [wAlphabetCase] + and a + ld de, LowerCaseAlphabet + jr nz, .lowercase + ld de, UpperCaseAlphabet +.lowercase + coord hl, 2, 5 + lb bc, 5, 9 ; 5 rows, 9 columns +.outerLoop + push bc +.innerLoop + ld a, [de] + ld [hli], a + inc hl + inc de + dec c + jr nz, .innerLoop + ld bc, SCREEN_WIDTH + 2 + add hl, bc + pop bc + dec b + jr nz, .outerLoop + call PlaceString + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a + jp Delay3 + +LowerCaseAlphabet: + db "abcdefghijklmnopqrstuvwxyz äöü:×()",$e1,$e2,"-?!♂♀/⠄,¥GROSSBUCHSTABEN@" + +UpperCaseAlphabet: + db "ABCDEFGHIJKLMNOPQRSTUVWXYZ ÄÖÜ:;[]",$e1,$e2,"-?!♂♀/⠄,¥kleinbuchstaben@" + +PrintNicknameAndUnderscores: + call CalcStringLength + ld a, c + ld [wNamingScreenNameLength], a + coord hl, 10, 2 + lb bc, 1, 10 + call ClearScreenArea + coord hl, 10, 2 + ld de, wcf50 + call PlaceString + coord hl, 10, 3 + ld a, [wNamingScreenType] + cp NAME_MON_SCREEN + jr nc, .pokemon1 + ld b, 7 ; player or rival max name length + jr .playerOrRival1 +.pokemon1 + ld b, 10 ; pokemon max name length +.playerOrRival1 + ld a, $76 ; underscore tile id +.placeUnderscoreLoop + ld [hli], a + dec b + jr nz, .placeUnderscoreLoop + ld a, [wNamingScreenType] + cp NAME_MON_SCREEN + ld a, [wNamingScreenNameLength] + jr nc, .pokemon2 + cp 7 ; player or rival max name length + jr .playerOrRival2 +.pokemon2 + cp 10 ; pokemon max name length +.playerOrRival2 + jr nz, .emptySpacesRemaining + ; when all spaces are filled, force the cursor onto the ED tile + call EraseMenuCursor + ld a, $11 ; "ED" x coord + ld [wTopMenuItemX], a + ld a, $5 ; "ED" y coord + ld [wCurrentMenuItem], a + ld a, [wNamingScreenType] + cp NAME_MON_SCREEN + ld a, 9 ; keep the last underscore raised + jr nc, .pokemon3 + ld a, 6 ; keep the last underscore raised +.pokemon3 +.emptySpacesRemaining + ld c, a + ld b, $0 + coord hl, 10, 3 + add hl, bc + ld [hl], $77 ; raised underscore tile id + ret + +DakutensAndHandakutens: + push de + call CalcStringLength + dec hl + ld a, [hl] + pop hl + ld de, $2 + call IsInArray + ret nc + inc hl + ld a, [hl] + ld [wNamingScreenLetter], a + ret + +Dakutens: + db "かが", "きぎ", "くぐ", "けげ", "こご" + db "さざ", "しじ", "すず", "せぜ", "そぞ" + db "ただ", "ちぢ", "つづ", "てで", "とど" + db "はば", "ひび", "ふぶ", "へべ", "ほぼ" + db "カガ", "キギ", "クグ", "ケゲ", "コゴ" + db "サザ", "シジ", "スズ", "セゼ", "ソゾ" + db "タダ", "チヂ", "ツヅ", "テデ", "トド" + db "ハバ", "ヒビ", "フブ", "へべ", "ホボ" + db $ff + +Handakutens: + db "はぱ", "ひぴ", "ふぷ", "へぺ", "ほぽ" + db "ハパ", "ヒピ", "フプ", "へぺ", "ホポ" + db $ff + +; calculates the length of the string at wcf50 and stores it in c +CalcStringLength: + ld hl, wcf50 + ld c, $0 +.loop + ld a, [hl] + cp "@" + ret z + inc hl + inc c + jr .loop + +PrintNamingText: + coord hl, 0, 1 + ld a, [wNamingScreenType] + ld de, YourTextString + and a + jr z, .notNickname + ld de, RivalsTextString + dec a + jr z, .notNickname + ld a, [wcf91] + ld [wMonPartySpriteSpecies], a + push af + callba WriteMonPartySpriteOAMBySpecies + pop af + ld [wd11e], a + call GetMonName + coord hl, 4, 1 + call PlaceString + coord hl, 1, 3 + ld de, NicknameTextString + jr .placeString +.notNickname + call PlaceString + ld l, c + ld h, b + ld de, NameTextString +.placeString + jp PlaceString + +YourTextString: + db "DEIN @" + +RivalsTextString: + db "GEGNER-@" + +NameTextString: + db "NAME?@" + +NicknameTextString: + db "ALIAS?@" diff --git a/de/engine/menu/party_menu.asm b/de/engine/menu/party_menu.asm new file mode 100755 index 00000000..ff302968 --- /dev/null +++ b/de/engine/menu/party_menu.asm @@ -0,0 +1,325 @@ +; [wPartyMenuTypeOrMessageID] = menu type / message ID +; if less than $F0, it is a menu type +; menu types: +; 00: normal pokemon menu (e.g. Start menu) +; 01: use healing item on pokemon menu +; 02: in-battle switch pokemon menu +; 03: learn TM/HM menu +; 04: swap pokemon positions menu +; 05: use evolution stone on pokemon menu +; otherwise, it is a message ID +; f0: poison healed +; f1: burn healed +; f2: freeze healed +; f3: sleep healed +; f4: paralysis healed +; f5: HP healed +; f6: health returned +; f7: revitalized +; f8: leveled up +DrawPartyMenu_: + xor a + ld [H_AUTOBGTRANSFERENABLED],a + call ClearScreen + call UpdateSprites + callba LoadMonPartySpriteGfxWithLCDDisabled ; load pokemon icon graphics + +RedrawPartyMenu_: + ld a,[wPartyMenuTypeOrMessageID] + cp a,SWAP_MONS_PARTY_MENU + jp z,.printMessage + call ErasePartyMenuCursors + callba InitPartyMenuBlkPacket + coord hl, 3, 0 + ld de,wPartySpecies + xor a + ld c,a + ld [hPartyMonIndex],a + ld [wWhichPartyMenuHPBar],a +.loop + ld a,[de] + cp a,$FF ; reached the terminator? + jp z,.afterDrawingMonEntries + push bc + push de + push hl + ld a,c + push hl + ld hl,wPartyMonNicks + call GetPartyMonName + pop hl + call PlaceString ; print the pokemon's name + callba WriteMonPartySpriteOAMByPartyIndex ; place the appropriate pokemon icon + ld a,[hPartyMonIndex] + ld [wWhichPokemon],a + inc a + ld [hPartyMonIndex],a + call LoadMonData + pop hl + push hl + ld a,[wMenuItemToSwap] + and a ; is the player swapping pokemon positions? + jr z,.skipUnfilledRightArrow +; if the player is swapping pokemon positions + dec a + ld b,a + ld a,[wWhichPokemon] + cp b ; is the player swapping the current pokemon in the list? + jr nz,.skipUnfilledRightArrow +; the player is swapping the current pokemon in the list + dec hl + dec hl + dec hl + ld a,"▷" ; unfilled right arrow menu cursor + ld [hli],a ; place the cursor + inc hl + inc hl +.skipUnfilledRightArrow + ld a,[wPartyMenuTypeOrMessageID] ; menu type + cp a,TMHM_PARTY_MENU + jr z,.teachMoveMenu + cp a,EVO_STONE_PARTY_MENU + jr z,.evolutionStoneMenu + push hl + ld bc,14 ; 14 columns to the right + add hl,bc + ld de,wLoadedMonStatus + call PrintStatusCondition + pop hl + push hl + ld bc,SCREEN_WIDTH + 1 ; down 1 row and right 1 column + ld a,[hFlags_0xFFF6] + set 0,a + ld [hFlags_0xFFF6],a + add hl,bc + predef DrawHP2 ; draw HP bar and prints current / max HP + ld a,[hFlags_0xFFF6] + res 0,a + ld [hFlags_0xFFF6],a + call SetPartyMenuHPBarColor ; color the HP bar (on SGB) + pop hl + jr .printLevel +.teachMoveMenu + push hl + predef CanLearnTM ; check if the pokemon can learn the move + pop hl + ld de,.ableToLearnMoveText + ld a,c + and a + jr nz,.placeMoveLearnabilityString + ld de,.notAbleToLearnMoveText +.placeMoveLearnabilityString + ld bc,20 + 9 ; down 1 row and right 9 columns + push hl + add hl,bc + call PlaceString + pop hl +.printLevel + ld bc,10 ; move 10 columns to the right + add hl,bc + call PrintLevel + pop hl + pop de + inc de + ld bc,2 * 20 + add hl,bc + pop bc + inc c + jp .loop +.ableToLearnMoveText + db "OK@" +.notAbleToLearnMoveText + db "NEIN@" +.evolutionStoneMenu + push hl + ld hl,EvosMovesPointerTable + ld b,0 + ld a,[wLoadedMonSpecies] + dec a + add a + rl b + ld c,a + add hl,bc + ld de,wcd6d + ld a,BANK(EvosMovesPointerTable) + ld bc,2 + call FarCopyData + ld hl,wcd6d + ld a,[hli] + ld h,[hl] + ld l,a + ld de,wcd6d + ld a,BANK(EvosMovesPointerTable) + ld bc,Mon133_EvosEnd - Mon133_EvosMoves + call FarCopyData + ld hl,wcd6d + ld de,.notAbleToEvolveText +; loop through the pokemon's evolution entries +.checkEvolutionsLoop + ld a,[hli] + and a ; reached terminator? + jr z,.placeEvolutionStoneString ; if so, place the "NOT ABLE" string + inc hl + inc hl + cp a,EV_ITEM + jr nz,.checkEvolutionsLoop +; if it's a stone evolution entry + dec hl + dec hl + ld b,[hl] + ld a,[wEvoStoneItemID] ; the stone the player used + inc hl + inc hl + inc hl + cp b ; does the player's stone match this evolution entry's stone? + jr nz,.checkEvolutionsLoop +; if it does match + ld de,.ableToEvolveText +.placeEvolutionStoneString + ld bc,20 + 9 ; down 1 row and right 9 columns + pop hl + push hl + add hl,bc + call PlaceString + pop hl + jr .printLevel +.ableToEvolveText + db "OK@" +.notAbleToEvolveText + db "NEIN@" +.afterDrawingMonEntries + ld b, SET_PAL_PARTY_MENU + call RunPaletteCommand +.printMessage + ld hl,wd730 + ld a,[hl] + push af + push hl + set 6,[hl] ; turn off letter printing delay + ld a,[wPartyMenuTypeOrMessageID] ; message ID + cp a,$F0 + jr nc,.printItemUseMessage + add a + ld hl,PartyMenuMessagePointers + ld b,0 + ld c,a + add hl,bc + ld a,[hli] + ld h,[hl] + ld l,a + call PrintText +.done + pop hl + pop af + ld [hl],a + ld a,1 + ld [H_AUTOBGTRANSFERENABLED],a + call Delay3 + jp GBPalNormal +.printItemUseMessage + and a,$0F + ld hl,PartyMenuItemUseMessagePointers + add a + ld c,a + ld b,0 + add hl,bc + ld a,[hli] + ld h,[hl] + ld l,a + push hl + ld a,[wUsedItemOnWhichPokemon] + ld hl,wPartyMonNicks + call GetPartyMonName + pop hl + call PrintText + jr .done + +PartyMenuItemUseMessagePointers: + dw AntidoteText + dw BurnHealText + dw IceHealText + dw AwakeningText + dw ParlyzHealText + dw PotionText + dw FullHealText + dw ReviveText + dw RareCandyText + +PartyMenuMessagePointers: + dw PartyMenuNormalText + dw PartyMenuItemUseText + dw PartyMenuBattleText + dw PartyMenuUseTMText + dw PartyMenuSwapMonText + dw PartyMenuItemUseText + +PartyMenuNormalText: + TX_FAR _PartyMenuNormalText + db "@" + +PartyMenuItemUseText: + TX_FAR _PartyMenuItemUseText + db "@" + +PartyMenuBattleText: + TX_FAR _PartyMenuBattleText + db "@" + +PartyMenuUseTMText: + TX_FAR _PartyMenuUseTMText + db "@" + +PartyMenuSwapMonText: + TX_FAR _PartyMenuSwapMonText + db "@" + +PotionText: + TX_FAR _PotionText + db "@" + +AntidoteText: + TX_FAR _AntidoteText + db "@" + +ParlyzHealText: + TX_FAR _ParlyzHealText + db "@" + +BurnHealText: + TX_FAR _BurnHealText + db "@" + +IceHealText: + TX_FAR _IceHealText + db "@" + +AwakeningText: + TX_FAR _AwakeningText + db "@" + +FullHealText: + TX_FAR _FullHealText + db "@" + +ReviveText: + TX_FAR _ReviveText + db "@" + +RareCandyText: + TX_FAR _RareCandyText + TX_SFX_ITEM_1 ; probably supposed to play SFX_LEVEL_UP but the wrong music bank is loaded + TX_BLINK + db "@" + +SetPartyMenuHPBarColor: + ld hl, wPartyMenuHPBarColors + ld a, [wWhichPartyMenuHPBar] + ld c, a + ld b, 0 + add hl, bc + call GetHealthBarColor + ld b, UPDATE_PARTY_MENU_BLK_PACKET + call RunPaletteCommand + ld hl, wWhichPartyMenuHPBar + inc [hl] + ret diff --git a/de/engine/menu/players_pc.asm b/de/engine/menu/players_pc.asm new file mode 100755 index 00000000..c5acfec7 --- /dev/null +++ b/de/engine/menu/players_pc.asm @@ -0,0 +1,303 @@ +PlayerPC: + ld a, ITEM_NAME + ld [wNameListType], a + call SaveScreenTilesToBuffer1 + xor a + ld [wBagSavedMenuItem], a + ld [wParentMenuItem], a + ld a, [wFlags_0xcd60] + bit 3, a ; accessing player's PC through another PC? + jr nz, PlayerPCMenu +; accessing it directly + ld a, SFX_TURN_ON_PC + call PlaySound + ld hl, TurnedOnPC2Text + call PrintText + +PlayerPCMenu: + ld hl, wd730 + set 6, [hl] + ld a, [wParentMenuItem] + ld [wCurrentMenuItem], a + ld hl, wFlags_0xcd60 + set 5, [hl] + call LoadScreenTilesFromBuffer2 + coord hl, 0, 0 + ld b, 8 + ld c, 15 + call TextBoxBorder + call UpdateSprites + coord hl, 2, 2 + ld de, PlayersPCMenuEntries + call PlaceString + ld hl, wTopMenuItemY + ld a, 2 + ld [hli], a ; wTopMenuItemY + dec a + ld [hli], a ; wTopMenuItemX + inc hl + inc hl + ld a, 3 + ld [hli], a ; wMaxMenuItem + ld a, A_BUTTON | B_BUTTON + ld [hli], a ; wMenuWatchedKeys + xor a + ld [hl], a + ld hl, wListScrollOffset + ld [hli], a ; wListScrollOffset + ld [hl], a ; wMenuWatchMovingOutOfBounds + ld [wPlayerMonNumber], a + ld hl, WhatDoYouWantText + call PrintText + call HandleMenuInput + bit 1, a + jp nz, ExitPlayerPC + call PlaceUnfilledArrowMenuCursor + ld a, [wCurrentMenuItem] + ld [wParentMenuItem], a + and a + jp z, PlayerPCWithdraw + dec a + jp z, PlayerPCDeposit + dec a + jp z, PlayerPCToss + +ExitPlayerPC: + ld a, [wFlags_0xcd60] + bit 3, a ; accessing player's PC through another PC? + jr nz, .next +; accessing it directly + ld a, SFX_TURN_OFF_PC + call PlaySound + call WaitForSoundToFinish +.next + ld hl, wFlags_0xcd60 + res 5, [hl] + call LoadScreenTilesFromBuffer2 + xor a + ld [wListScrollOffset], a + ld [wBagSavedMenuItem], a + ld hl, wd730 + res 6, [hl] + xor a + ld [wDoNotWaitForButtonPressAfterDisplayingText], a + ret + +PlayerPCDeposit: + xor a + ld [wCurrentMenuItem], a + ld [wListScrollOffset], a + ld a, [wNumBagItems] + and a + jr nz, .loop + ld hl, NothingToDepositText + call PrintText + jp PlayerPCMenu +.loop + ld hl, WhatToDepositText + call PrintText + ld hl, wNumBagItems + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + xor a + ld [wPrintItemPrices], a + ld a, ITEMLISTMENU + ld [wListMenuID], a + call DisplayListMenuID + jp c, PlayerPCMenu + call IsKeyItem + ld a, 1 + ld [wItemQuantity], a + ld a, [wIsKeyItem] + and a + jr nz, .next +; if it's not a key item, there can be more than one of the item + ld hl, DepositHowManyText + call PrintText + call DisplayChooseQuantityMenu + cp $ff + jp z, .loop +.next + ld hl, wNumBoxItems + call AddItemToInventory + jr c, .roomAvailable + ld hl, NoRoomToStoreText + call PrintText + jp .loop +.roomAvailable + ld hl, wNumBagItems + call RemoveItemFromInventory + call WaitForSoundToFinish + ld a, SFX_WITHDRAW_DEPOSIT + call PlaySound + call WaitForSoundToFinish + ld hl, ItemWasStoredText + call PrintText + jp .loop + +PlayerPCWithdraw: + xor a + ld [wCurrentMenuItem], a + ld [wListScrollOffset], a + ld a, [wNumBoxItems] + and a + jr nz, .loop + ld hl, NothingStoredText + call PrintText + jp PlayerPCMenu +.loop + ld hl, WhatToWithdrawText + call PrintText + ld hl, wNumBoxItems + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + xor a + ld [wPrintItemPrices], a + ld a, ITEMLISTMENU + ld [wListMenuID], a + call DisplayListMenuID + jp c, PlayerPCMenu + call IsKeyItem + ld a, 1 + ld [wItemQuantity], a + ld a, [wIsKeyItem] + and a + jr nz, .next +; if it's not a key item, there can be more than one of the item + ld hl, WithdrawHowManyText + call PrintText + call DisplayChooseQuantityMenu + cp $ff + jp z, .loop +.next + ld hl, wNumBagItems + call AddItemToInventory + jr c, .roomAvailable + ld hl, CantCarryMoreText + call PrintText + jp .loop +.roomAvailable + ld hl, wNumBoxItems + call RemoveItemFromInventory + call WaitForSoundToFinish + ld a, SFX_WITHDRAW_DEPOSIT + call PlaySound + call WaitForSoundToFinish + ld hl, WithdrewItemText + call PrintText + jp .loop + +PlayerPCToss: + xor a + ld [wCurrentMenuItem], a + ld [wListScrollOffset], a + ld a, [wNumBoxItems] + and a + jr nz, .loop + ld hl, NothingStoredText + call PrintText + jp PlayerPCMenu +.loop + ld hl, WhatToTossText + call PrintText + ld hl, wNumBoxItems + ld a, l + ld [wListPointer], a + ld a, h + ld [wListPointer + 1], a + xor a + ld [wPrintItemPrices], a + ld a, ITEMLISTMENU + ld [wListMenuID], a + push hl + call DisplayListMenuID + pop hl + jp c, PlayerPCMenu + push hl + call IsKeyItem + pop hl + ld a, 1 + ld [wItemQuantity], a + ld a, [wIsKeyItem] + and a + jr nz, .next + ld a, [wcf91] + call IsItemHM + jr c, .next +; if it's not a key item, there can be more than one of the item + push hl + ld hl, TossHowManyText + call PrintText + call DisplayChooseQuantityMenu + pop hl + cp $ff + jp z, .loop +.next + call TossItem ; disallows tossing key items + jp .loop + +PlayersPCMenuEntries: + db "ITEM AUFNEHMEN" + next "ITEM ABLEGEN" + next "ITEM WEGWERFEN" + next "AUSLOGGEN@" + +TurnedOnPC2Text: + TX_FAR _TurnedOnPC2Text + db "@" + +WhatDoYouWantText: + TX_FAR _WhatDoYouWantText + db "@" + +WhatToDepositText: + TX_FAR _WhatToDepositText + db "@" + +DepositHowManyText: + TX_FAR _DepositHowManyText + db "@" + +ItemWasStoredText: + TX_FAR _ItemWasStoredText + db "@" + +NothingToDepositText: + TX_FAR _NothingToDepositText + db "@" + +NoRoomToStoreText: + TX_FAR _NoRoomToStoreText + db "@" + +WhatToWithdrawText: + TX_FAR _WhatToWithdrawText + db "@" + +WithdrawHowManyText: + TX_FAR _WithdrawHowManyText + db "@" + +WithdrewItemText: + TX_FAR _WithdrewItemText + db "@" + +NothingStoredText: + TX_FAR _NothingStoredText + db "@" + +CantCarryMoreText: + TX_FAR _CantCarryMoreText + db "@" + +WhatToTossText: + TX_FAR _WhatToTossText + db "@" + +TossHowManyText: + TX_FAR _TossHowManyText + db "@" diff --git a/de/engine/menu/pokedex.asm b/de/engine/menu/pokedex.asm new file mode 100755 index 00000000..ea28c133 --- /dev/null +++ b/de/engine/menu/pokedex.asm @@ -0,0 +1,666 @@ +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 a,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 a,7 + jp c,.loop ; can't if the list is shorter than 7 + sub a,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 a,7 + jp c,.loop ; can't if the list is shorter than 7 + sub a,6 + ld b,a + ld a,[wListScrollOffset] + add a,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 a,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 a,1 ; toggle between vertical line tile and box tile + dec c + jr nz,.loop + ret + +PokedexSeenText: + db "GES@" + +PokedexOwnText: + db "BES@" + +PokedexContentsText: + db "INHALT@" + +PokedexMenuItemsText: + db "DATA" + next "RUF" + next "GEB." + next "ZUR.@" + +; 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 + push af + coord hl, 13, 6 + lb bc, 1, 3 + call PrintNumber ; print feet (height) + ld hl, $C426 + pop af + cp $a + jr nc, .func_43d7 + ld [hl], $F6 +.func_43d7 + inc hl + ld a, [hli] + ldd [hl], a + ld [hl], $F2 + inc de + inc de + inc de ; de = address of inches (height) + 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, 12, 8 + lb bc, 2, 4 ; 2 bytes, 4 digits + call PrintNumber ; print weight + coord hl, 14, 8 + ld a,[hDexWeight + 1] + sub a,10 + ld a,[hDexWeight] + sbc a,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,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 "GR. ???",$60 + next "GEW ???",$61,$62,"@" + +; 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" diff --git a/de/engine/menu/prize_menu.asm b/de/engine/menu/prize_menu.asm new file mode 100755 index 00000000..5cfdbc87 --- /dev/null +++ b/de/engine/menu/prize_menu.asm @@ -0,0 +1,306 @@ +CeladonPrizeMenu: + ld b,COIN_CASE + call IsItemInBag + jr nz,.havingCoinCase + ld hl,RequireCoinCaseTextPtr + jp PrintText +.havingCoinCase + ld hl,wd730 + set 6,[hl] ; disable letter-printing delay + ld hl,ExchangeCoinsForPrizesTextPtr + call PrintText +; the following are the menu settings + xor a + ld [wCurrentMenuItem],a + ld [wLastMenuItem],a + ld a,A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys],a + ld a,$03 + ld [wMaxMenuItem],a + ld a,$04 + ld [wTopMenuItemY],a + ld a,$01 + ld [wTopMenuItemX],a + call PrintPrizePrice + coord hl, 0, 2 + ld b, 8 + ld c, 16 + call TextBoxBorder + call GetPrizeMenuId + call UpdateSprites + ld hl,WhichPrizeTextPtr + call PrintText + call HandleMenuInput ; menu choice handler + bit 1,a ; keypress = B (Cancel) + jr nz, .noChoice + ld a,[wCurrentMenuItem] + cp 3 ; "NO,THANKS" choice + jr z, .noChoice + call HandlePrizeChoice +.noChoice + ld hl,wd730 + res 6,[hl] + ret + +RequireCoinCaseTextPtr: + TX_FAR _RequireCoinCaseText + TX_WAIT + db "@" + +ExchangeCoinsForPrizesTextPtr: + TX_FAR _ExchangeCoinsForPrizesText + db "@" + +WhichPrizeTextPtr: + TX_FAR _WhichPrizeText + db "@" + +GetPrizeMenuId: +; determine which one among the three +; prize-texts has been selected +; using the text ID (stored in [hSpriteIndexOrTextID]) +; load the three prizes at wd13d-wd13f +; load the three prices at wd141-wd146 +; display the three prizes' names +; (distinguishing between Pokemon names +; and Items (specifically TMs) names) + ld a,[hSpriteIndexOrTextID] + sub 3 ; prize-texts' id are 3, 4 and 5 + ld [wWhichPrizeWindow],a ; prize-texts' id (relative, i.e. 0, 1 or 2) + add a + add a + ld d,0 + ld e,a + ld hl,PrizeDifferentMenuPtrs + add hl,de + ld a,[hli] + ld d,[hl] + ld e,a + inc hl + push hl + ld hl,wPrize1 + call CopyString + pop hl + ld a,[hli] + ld h,[hl] + ld l,a + ld de,wPrize1Price + ld bc,6 + call CopyData + ld a,[wWhichPrizeWindow] + cp 2 ;is TM_menu? + jr nz,.putMonName + ld a,[wPrize1] + ld [wd11e],a + call GetItemName + coord hl, 2, 4 + call PlaceString + ld a,[wPrize2] + ld [wd11e],a + call GetItemName + coord hl, 2, 6 + call PlaceString + ld a,[wPrize3] + ld [wd11e],a + call GetItemName + coord hl, 2, 8 + call PlaceString + jr .putNoThanksText +.putMonName + ld a,[wPrize1] + ld [wd11e],a + call GetMonName + coord hl, 2, 4 + call PlaceString + ld a,[wPrize2] + ld [wd11e],a + call GetMonName + coord hl, 2, 6 + call PlaceString + ld a,[wPrize3] + ld [wd11e],a + call GetMonName + coord hl, 2, 8 + call PlaceString +.putNoThanksText + coord hl, 2, 10 + ld de,NoThanksText + call PlaceString +; put prices on the right side of the textbox + ld de,wPrize1Price + coord hl, 13, 5 +; reg. c: +; [low nybble] number of bytes +; [bit 765 = %100] space-padding (not zero-padding) + ld c,(1 << 7 | 2) +; Function $15CD displays BCD value (same routine +; used by text-command $02) + call PrintBCDNumber + ld de,wPrize2Price + coord hl, 13, 7 + ld c,(1 << 7 | 2) + call PrintBCDNumber + ld de,wPrize3Price + coord hl, 13, 9 + ld c,(1 << 7 | 2) + jp PrintBCDNumber + +INCLUDE "data/prizes.asm" + +PrintPrizePrice: + coord hl, 11, 0 + ld b, 1 + ld c, 7 + call TextBoxBorder + call UpdateSprites + coord hl, 13, 0 + ld de, .CoinString + call PlaceString + coord hl, 13, 1 + ld de, .SixSpacesString + call PlaceString + coord hl, 13, 1 + ld de,wPlayerCoins + ld c,%10000010 + call PrintBCDNumber + ret + +.CoinString: + db "MÜNZEN@" + +.SixSpacesString: + db " @" + +LoadCoinsToSubtract: + ld a,[wWhichPrize] + add a + ld d,0 + ld e,a + ld hl,wPrize1Price + add hl,de ; get selected prize's price + xor a + ld [hUnusedCoinsByte],a + ld a,[hli] + ld [hCoins],a + ld a,[hl] + ld [hCoins + 1],a + ret + +HandlePrizeChoice: + ld a,[wCurrentMenuItem] + ld [wWhichPrize],a + ld d,0 + ld e,a + ld hl,wPrize1 + add hl,de + ld a,[hl] + ld [wd11e],a + ld a,[wWhichPrizeWindow] + cp 2 ; is prize a TM? + jr nz, .getMonName + call GetItemName + jr .givePrize +.getMonName + call GetMonName +.givePrize + ld hl,SoYouWantPrizeTextPtr + call PrintText + call YesNoChoice + ld a,[wCurrentMenuItem] ; yes/no answer (Y=0, N=1) + and a + jr nz, .printOhFineThen + call LoadCoinsToSubtract + call HasEnoughCoins + jr c, .notEnoughCoins + ld a,[wWhichPrizeWindow] + cp $02 + jr nz, .giveMon + ld a,[wd11e] + ld b,a + ld a,1 + ld c,a + call GiveItem + jr nc, .bagFull + jr .subtractCoins +.giveMon + ld a,[wd11e] + ld [wcf91],a + push af + call GetPrizeMonLevel + ld c,a + pop af + ld b,a + call GivePokemon + +; If either the party or box was full, wait after displaying message. + push af + ld a,[wAddedToParty] + and a + call z,WaitForTextScrollButtonPress + pop af + +; If the mon couldn't be given to the player (because both the party and box +; were full), return without subtracting coins. + ret nc + +.subtractCoins + call LoadCoinsToSubtract + ld hl,hCoins + 1 + ld de,wPlayerCoins + 1 + ld c,$02 ; how many bytes + predef SubBCDPredef + jp PrintPrizePrice +.bagFull + ld hl,PrizeRoomBagIsFullTextPtr + jp PrintText +.notEnoughCoins + ld hl,SorryNeedMoreCoinsText + jp PrintText +.printOhFineThen + ld hl,OhFineThenTextPtr + jp PrintText + +UnknownPrizeData: +; XXX what's this? + db $00,$01,$00,$01,$00,$01,$00,$00,$01 + +HereYouGoTextPtr: + TX_FAR _HereYouGoText + TX_WAIT + db "@" + +SoYouWantPrizeTextPtr: + TX_FAR _SoYouWantPrizeText + db "@" + +SorryNeedMoreCoinsText: + TX_FAR _SorryNeedMoreCoinsText + TX_WAIT + db "@" + +PrizeRoomBagIsFullTextPtr: + TX_FAR _OopsYouDontHaveEnoughRoomText + TX_WAIT + db "@" + +OhFineThenTextPtr: + TX_FAR _OhFineThenText + TX_WAIT + db "@" + +GetPrizeMonLevel: + ld a,[wcf91] + ld b,a + ld hl,PrizeMonLevelDictionary +.loop + ld a,[hli] + cp b + jr z,.matchFound + inc hl + jr .loop +.matchFound + ld a,[hl] + ld [wCurEnemyLVL],a + ret + +INCLUDE "data/prize_mon_levels.asm" diff --git a/de/engine/menu/start_sub_menus.asm b/de/engine/menu/start_sub_menus.asm new file mode 100755 index 00000000..f31c5d65 --- /dev/null +++ b/de/engine/menu/start_sub_menus.asm @@ -0,0 +1,854 @@ +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 CopyStringToCF50 ; copy name to wcf50 + 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 "GELD/" + next "ZEIT/@" + +; $76 is a circle tile +TrainerInfo_BadgesText: + db $76,"ORDEN",$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 diff --git a/de/engine/menu/status_screen.asm b/de/engine/menu/status_screen.asm new file mode 100755 index 00000000..2db9a908 --- /dev/null +++ b/de/engine/menu/status_screen.asm @@ -0,0 +1,491 @@ +DrawHP: +; Draws the HP bar in the stats screen + call GetPredefRegisters + ld a, $1 + jr DrawHP_ + +DrawHP2: +; Draws the HP bar in the party screen + call GetPredefRegisters + ld a, $2 + +DrawHP_: + ld [wHPBarType], a + push hl + ld a, [wLoadedMonHP] + ld b, a + ld a, [wLoadedMonHP + 1] + ld c, a + or b + jr nz, .nonzeroHP + xor a + ld c, a + ld e, a + ld a, $6 + ld d, a + jp .drawHPBarAndPrintFraction +.nonzeroHP + ld a, [wLoadedMonMaxHP] + ld d, a + ld a, [wLoadedMonMaxHP + 1] + ld e, a + predef HPBarLength + ld a, $6 + ld d, a + ld c, a +.drawHPBarAndPrintFraction + pop hl + push de + push hl + push hl + call DrawHPBar + pop hl + ld a, [hFlags_0xFFF6] + bit 0, a + jr z, .printFractionBelowBar + ld bc, $9 ; right of bar + jr .printFraction +.printFractionBelowBar + ld bc, SCREEN_WIDTH + 1 ; below bar +.printFraction + add hl, bc + ld de, wLoadedMonHP + lb bc, 2, 3 + call PrintNumber + ld a, "/" + ld [hli], a + ld de, wLoadedMonMaxHP + lb bc, 2, 3 + call PrintNumber + pop hl + pop de + ret + + +; Predef 0x37 +StatusScreen: + call LoadMonData + ld a, [wMonDataLocation] + cp BOX_DATA + jr c, .DontRecalculate +; mon is in a box or daycare + ld a, [wLoadedMonBoxLevel] + ld [wLoadedMonLevel], a + ld [wCurEnemyLVL], a + ld hl, wLoadedMonHPExp - 1 + ld de, wLoadedMonStats + ld b, $1 + call CalcStats ; Recalculate stats +.DontRecalculate + ld hl, wd72c + set 1, [hl] + ld a, $33 + ld [rNR50], a ; Reduce the volume + call GBPalWhiteOutWithDelay3 + call ClearScreen + call UpdateSprites + call LoadHpBarAndStatusTilePatterns + ld de, BattleHudTiles1 ; source + ld hl, vChars2 + $6d0 ; dest + lb bc, BANK(BattleHudTiles1), $03 + call CopyVideoDataDouble ; ·│ :L and halfarrow line end + ld de, BattleHudTiles2 + ld hl, vChars2 + $780 + lb bc, BANK(BattleHudTiles2), $01 + call CopyVideoDataDouble ; │ + ld de, BattleHudTiles3 + ld hl, vChars2 + $760 + lb bc, BANK(BattleHudTiles3), $02 + call CopyVideoDataDouble ; ─┘ + ld de, PTile + ld hl, vChars2 + $720 + lb bc, BANK(PTile), (PTileEnd - PTile) / $8 + call CopyVideoDataDouble ; P (for PP), inline + ld a, [hTilesetType] + push af + xor a + ld [hTilesetType], a + coord hl, 19, 1 + lb bc, 6, 10 + call DrawLineBox ; Draws the box around name, HP and status + ld de, -6 + add hl, de + ld [hl], "⠄" ; . after No ("." is a different one) + dec hl + ld [hl], "№" + coord hl, 19, 9 + lb bc, 8, 6 + call DrawLineBox ; Draws the box around types, ID No. and OT + coord hl, 10, 9 + ld de, Type1Text + call PlaceString ; "TYPE1/" + coord hl, 11, 3 + predef DrawHP + ld hl, wStatusScreenHPBarColor + call GetHealthBarColor + ld b, SET_PAL_STATUS_SCREEN + call RunPaletteCommand + coord hl, 16, 6 + ld de, wLoadedMonStatus + call PrintStatusCondition + jr nz, .StatusWritten + coord hl, 16, 6 + ld de, OKText + call PlaceString ; "OK" +.StatusWritten + coord hl, 9, 6 + ld de, StatusText + call PlaceString ; "STATUS/" + coord hl, 14, 2 + call PrintLevel ; Pokémon level + ld a, [wMonHIndex] + ld [wd11e], a + ld [wd0b5], a + predef IndexToPokedex + coord hl, 3, 7 + ld de, wd11e + lb bc, LEADING_ZEROES | 1, 3 + call PrintNumber ; Pokémon no. + coord hl, 11, 10 + predef PrintMonType + ld hl, NamePointers2 + call .GetStringPointer + ld d, h + ld e, l + coord hl, 9, 1 + call PlaceString ; Pokémon name + ld hl, OTPointers + call .GetStringPointer + ld d, h + ld e, l + coord hl, 12, 16 + call PlaceString ; OT + coord hl, 12, 14 + ld de, wLoadedMonOTID + lb bc, LEADING_ZEROES | 2, 5 + call PrintNumber ; ID Number + ld d, $0 + call PrintStatsBox + call Delay3 + call GBPalNormal + coord hl, 1, 0 + call LoadFlippedFrontSpriteByMonIndex ; draw Pokémon picture + ld a, [wcf91] + call PlayCry ; play Pokémon cry + call WaitForTextScrollButtonPress ; wait for button + pop af + ld [hTilesetType], a + ret + +.GetStringPointer + ld a, [wMonDataLocation] + add a + ld c, a + ld b, 0 + add hl, bc + ld a, [hli] + ld h, [hl] + ld l, a + ld a, [wMonDataLocation] + cp DAYCARE_DATA + ret z + ld a, [wWhichPokemon] + jp SkipFixedLengthTextEntries + +OTPointers: + dw wPartyMonOT + dw wEnemyMonOT + dw wBoxMonOT + dw wDayCareMonOT + +NamePointers2: + dw wPartyMonNicks + dw wEnemyMonNicks + dw wBoxMonNicks + dw wDayCareMonName + +Type1Text: + db "TYP1/", $4e + +Type2Text: + db "TYP2/", $4e + +IDNoText: + db "″№/", $4e + +OTText: + db "OT/" + next "@" + +StatusText: + db "STATUS/@" + +OKText: + db "OK@" + +; Draws a line starting from hl high b and wide c +DrawLineBox: + ld de, SCREEN_WIDTH ; New line +.PrintVerticalLine + ld [hl], $78 ; │ + add hl, de + dec b + jr nz, .PrintVerticalLine + ld [hl], $77 ; ┘ + dec hl +.PrintHorizLine + ld [hl], $76 ; ─ + dec hl + dec c + jr nz, .PrintHorizLine + ld [hl], $6f ; ← (halfarrow ending) + ret + +PTile: ; This is a single 1bpp "P" tile + INCBIN "gfx/p_tile.1bpp" +PTileEnd: + +PrintStatsBox: + ld a, d + and a ; a is 0 from the status screen + jr nz, .DifferentBox + coord hl, 0, 8 + ld b, 8 + ld c, 8 + call TextBoxBorder ; Draws the box + coord hl, 1, 9 ; Start printing stats from here + ld bc, $0019 ; Number offset + jr .PrintStats +.DifferentBox + coord hl, 9, 2 + ld b, 8 + ld c, 9 + call TextBoxBorder + coord hl, 11, 3 + ld bc, $0018 +.PrintStats + push bc + push hl + ld de, StatsText + call PlaceString + pop hl + pop bc + add hl, bc + ld de, wLoadedMonAttack + lb bc, 2, 3 + call PrintStat + ld de, wLoadedMonDefense + call PrintStat + ld de, wLoadedMonSpeed + call PrintStat + ld de, wLoadedMonSpecial + jp PrintNumber +PrintStat: + push hl + call PrintNumber + pop hl + ld de, SCREEN_WIDTH * 2 + add hl, de + ret + +StatsText: + db "ANGR" + next "VERT" + next "INIT" + next "SPEZ@" + +StatusScreen2: + ld a, [hTilesetType] + push af + xor a + ld [hTilesetType], a + ld [H_AUTOBGTRANSFERENABLED], a + ld bc, NUM_MOVES + 1 + ld hl, wMoves + call FillMemory + ld hl, wLoadedMonMoves + ld de, wMoves + ld bc, NUM_MOVES + call CopyData + callab FormatMovesString + coord hl, 9, 2 + lb bc, 5, 10 + call ClearScreenArea ; Clear under name + coord hl, 19, 3 + ld [hl], $78 + coord hl, 0, 8 + ld b, 8 + ld c, 18 + call TextBoxBorder ; Draw move container + coord hl, 2, 9 + ld de, wMovesString + call PlaceString ; Print moves + ld a, [wNumMovesMinusOne] + inc a + ld c, a + ld a, $4 + sub c + ld b, a ; Number of moves ? + coord hl, 11, 10 + ld de, SCREEN_WIDTH * 2 + ld a, $80 ; special P tile id + call StatusScreen_PrintAP ; Print "AP" + ld a, b + and a + jr z, .InitPP + ld c, a + ld a, "-" + call StatusScreen_PrintPP ; Fill the rest with -- +.InitPP + ld hl, wLoadedMonMoves + coord de, 14, 10 + ld b, 0 +.PrintPP + ld a, [hli] + and a + jr z, .PPDone + push bc + push hl + push de + ld hl, wCurrentMenuItem + ld a, [hl] + push af + ld a, b + ld [hl], a + push hl + callab GetMaxPP + pop hl + pop af + ld [hl], a + pop de + pop hl + push hl + ld bc, wPartyMon1PP - wPartyMon1Moves - 1 + add hl, bc + ld a, [hl] + and $3f + ld [wStatusScreenCurrentPP], a + ld h, d + ld l, e + push hl + ld de, wStatusScreenCurrentPP + lb bc, 1, 2 + call PrintNumber + ld a, "/" + ld [hli], a + ld de, wMaxPP + lb bc, 1, 2 + call PrintNumber + pop hl + ld de, SCREEN_WIDTH * 2 + add hl, de + ld d, h + ld e, l + pop hl + pop bc + inc b + ld a, b + cp $4 + jr nz, .PrintPP +.PPDone + coord hl, 9, 3 + ld de, StatusScreenExpText + call PlaceString + ld a, [wLoadedMonLevel] + push af + cp MAX_LEVEL + jr z, .Level100 + inc a + ld [wLoadedMonLevel], a ; Increase temporarily if not 100 +.Level100 + coord hl, 14, 6 + ld [hl], $70 ; 1-tile "to" + inc hl + inc hl + call PrintLevel + pop af + ld [wLoadedMonLevel], a + ld de, wLoadedMonExp + coord hl, 12, 4 + lb bc, 3, 7 + call PrintNumber ; exp + call CalcExpToLevelUp + ld de, wLoadedMonExp + coord hl, 7, 6 + lb bc, 3, 7 + call PrintNumber ; exp needed to level up + coord hl, 9, 0 + call StatusScreen_ClearName + coord hl, 9, 1 + call StatusScreen_ClearName + ld a, [wMonHIndex] + ld [wd11e], a + call GetMonName + coord hl, 9, 1 + call PlaceString + ld a, $1 + ld [H_AUTOBGTRANSFERENABLED], a + call Delay3 + call WaitForTextScrollButtonPress ; wait for button + pop af + ld [hTilesetType], a + ld hl, wd72c + res 1, [hl] + ld a, $77 + ld [rNR50], a + call GBPalWhiteOut + jp ClearScreen + +CalcExpToLevelUp: + ld a, [wLoadedMonLevel] + cp MAX_LEVEL + jr z, .atMaxLevel + inc a + ld d, a + callab CalcExperience + ld hl, wLoadedMonExp + 2 + ld a, [hExperience + 2] + sub [hl] + ld [hld], a + ld a, [hExperience + 1] + sbc [hl] + ld [hld], a + ld a, [hExperience] + sbc [hl] + ld [hld], a + ret +.atMaxLevel + ld hl, wLoadedMonExp + xor a + ld [hli], a + ld [hli], a + ld [hl], a + ret + +StatusScreenExpText: + db "EP-PUNKTE" + next "LEVEL UP@" + +StatusScreen_ClearName: + ld bc, 10 + ld a, " " + jp FillMemory + +StatusScreen_PrintPP: +; print PP or -- c times, going down two rows each time + ld [hli], a + ld [hld], a + add hl, de + dec c + jr nz, StatusScreen_PrintPP + ret + +StatusScreen_PrintAP: ; 12cd5 (4:6cd5) + ld a, "A" + ld [hli],a + ld a, "P" + ldd [hl], a + add hl, de + dec c + jr nz, StatusScreen_PrintAP + ret
\ No newline at end of file diff --git a/de/engine/menu/text_box.asm b/de/engine/menu/text_box.asm new file mode 100644 index 00000000..57f0aa29 --- /dev/null +++ b/de/engine/menu/text_box.asm @@ -0,0 +1,740 @@ +; function to draw various text boxes +DisplayTextBoxID_: + ld a,[wTextBoxID] + cp a,TWO_OPTION_MENU + jp z,DisplayTwoOptionMenu + ld c,a + ld hl,TextBoxFunctionTable + ld de,3 + call SearchTextBoxTable + jr c,.functionTableMatch + ld hl,TextBoxCoordTable + ld de,5 + call SearchTextBoxTable + jr c,.coordTableMatch + ld hl,TextBoxTextAndCoordTable + ld de,9 + call SearchTextBoxTable + jr c,.textAndCoordTableMatch +.done + ret +.functionTableMatch + ld a,[hli] + ld h,[hl] + ld l,a ; hl = address of function + ld de,.done + push de + jp hl ; jump to the function +.coordTableMatch + call GetTextBoxIDCoords + call GetAddressOfScreenCoords + call TextBoxBorder + ret +.textAndCoordTableMatch + call GetTextBoxIDCoords + push hl + call GetAddressOfScreenCoords + call TextBoxBorder + pop hl + call GetTextBoxIDText + ld a,[wd730] + push af + ld a,[wd730] + set 6,a ; no pauses between printing each letter + ld [wd730],a + call PlaceString + pop af + ld [wd730],a + call UpdateSprites + ret + +; function to search a table terminated with $ff for a byte matching c in increments of de +; sets carry flag if a match is found and clears carry flag if not +SearchTextBoxTable: + dec de +.loop + ld a,[hli] + cp a,$ff + jr z,.notFound + cp c + jr z,.found + add hl,de + jr .loop +.found + scf +.notFound + ret + +; function to load coordinates from the TextBoxCoordTable or the TextBoxTextAndCoordTable +; INPUT: +; hl = address of coordinates +; OUTPUT: +; b = height +; c = width +; d = row of upper left corner +; e = column of upper left corner +GetTextBoxIDCoords: + ld a,[hli] ; column of upper left corner + ld e,a + ld a,[hli] ; row of upper left corner + ld d,a + ld a,[hli] ; column of lower right corner + sub e + dec a + ld c,a ; c = width + ld a,[hli] ; row of lower right corner + sub d + dec a + ld b,a ; b = height + ret + +; function to load a text address and text coordinates from the TextBoxTextAndCoordTable +GetTextBoxIDText: + ld a,[hli] + ld e,a + ld a,[hli] + ld d,a ; de = address of text + push de ; save text address + ld a,[hli] + ld e,a ; column of upper left corner of text + ld a,[hl] + ld d,a ; row of upper left corner of text + call GetAddressOfScreenCoords + pop de ; restore text address + ret + +; function to point hl to the screen coordinates +; INPUT: +; d = row +; e = column +; OUTPUT: +; hl = address of upper left corner of text box +GetAddressOfScreenCoords: + push bc + coord hl, 0, 0 + ld bc,20 +.loop ; loop to add d rows to the base address + ld a,d + and a + jr z,.addedRows + add hl,bc + dec d + jr .loop +.addedRows + pop bc + add hl,de + ret + +; Format: +; 00: text box ID +; 01-02: function address +TextBoxFunctionTable: + dbw MONEY_BOX, DisplayMoneyBox + dbw BUY_SELL_QUIT_MENU, DoBuySellQuitMenu + dbw FIELD_MOVE_MON_MENU, DisplayFieldMoveMonMenu + db $ff ; terminator + +; Format: +; 00: text box ID +; 01: column of upper left corner +; 02: row of upper left corner +; 03: column of lower right corner +; 04: row of lower right corner +TextBoxCoordTable: + db MESSAGE_BOX, 0, 12, 19, 17 + db $03, 0, 0, 19, 14 + db $07, 0, 0, 11, 6 + db LIST_MENU_BOX, 4, 2, 19, 12 + db $10, 7, 0, 19, 17 + db MON_SPRITE_POPUP, 6, 4, 14, 13 + db $ff ; terminator + +; Format: +; 00: text box ID +; 01: column of upper left corner +; 02: row of upper left corner +; 03: column of lower right corner +; 04: row of lower right corner +; 05-06: address of text +; 07: column of beginning of text +; 08: row of beginning of text +; table of window positions and corresponding text [key, start column, start row, end column, end row, text pointer [2 bytes], text column, text row] +TextBoxTextAndCoordTable: + db JP_MOCHIMONO_MENU_TEMPLATE + db 0,0,14,17 ; text box coordinates + dw BuySellQuitText ; JapaneseMochimonoText + db 3,0 ; text coordinates + + db USE_TOSS_MENU_TEMPLATE + db 13,10,19,14 ; text box coordinates + dw UseTossText + db 15,11 ; text coordinates + + db JP_SAVE_MESSAGE_MENU_TEMPLATE + db 0,0,7,5 ; text box coordinates + dw BuySellQuitText ; JapaneseSaveMessageText + db 2,2 ; text coordinates + + db JP_SPEED_OPTIONS_MENU_TEMPLATE + db 0,6,5,10 ; text box coordinates + dw BuySellQuitText ; JapaneseSpeedOptionsText + db 2,7 ; text coordinates + + db BATTLE_MENU_TEMPLATE + db 6,12,19,17 ; text box coordinates + dw BattleMenuText + db 8,14 ; text coordinates + + db SAFARI_BATTLE_MENU_TEMPLATE + db 0,12,19,17 ; text box coordinates + dw SafariZoneBattleMenuText + db 2,14 ; text coordinates + + db SWITCH_STATS_CANCEL_MENU_TEMPLATE + db 11,11,19,17 ; text box coordinates + dw SwitchStatsCancelText + db 13,12 ; text coordinates + + db BUY_SELL_QUIT_MENU_TEMPLATE + db 0,0,10,6 ; text box coordinates + dw BuySellQuitText + 1 + db 2,1 ; text coordinates + + db MONEY_BOX_TEMPLATE + db 11,0,19,2 ; text box coordinates + dw MoneyText + db 13,0 ; text coordinates + + db JP_AH_MENU_TEMPLATE + db 7,6,11,10 ; text box coordinates + dw BuySellQuitText ; JapaneseAhText + db 8,8 ; text coordinates + + db JP_POKEDEX_MENU_TEMPLATE + db 11,8,19,17 ; text box coordinates + dw BuySellQuitText ; JapanesePokedexMenu + db 12,10 ; text coordinates + +; note that there is no terminator + +BuySellQuitText: + db "@KAUF" + next "VERKAUF" + next "TSCHÜSS!@" + +UseTossText: + db "OK" + next "MÜLL@" + +MoneyText: + db "GELD@" + +BattleMenuText: + db "KMPF ",$E1,$E2 + next "ITEM FLUCHT@" + +SafariZoneBattleMenuText: + db "BALL× KÖDER" + next "STEIN FLUCHT@" + +SwitchStatsCancelText: + db "TAUSCH" + next "STATUS" + next "ZURÜCK@" + +DisplayMoneyBox: + ld hl, wd730 + set 6, [hl] + ld a, MONEY_BOX_TEMPLATE + ld [wTextBoxID], a + call DisplayTextBoxID + coord hl, 13, 1 + ld b, 1 + ld c, 6 + call ClearScreenArea + coord hl, 12, 1 + ld de, wPlayerMoney + ld c, "d" + call PrintBCDNumber + ld hl, wd730 + res 6, [hl] + ret + +DoBuySellQuitMenu: + ld a, [wd730] + set 6, a ; no printing delay + ld [wd730], a + xor a + ld [wChosenMenuItem], a + ld a, BUY_SELL_QUIT_MENU_TEMPLATE + ld [wTextBoxID], a + call DisplayTextBoxID + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, $2 + ld [wMaxMenuItem], a + ld a, $1 + ld [wTopMenuItemY], a + ld a, $1 + ld [wTopMenuItemX], a + xor a + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld [wMenuWatchMovingOutOfBounds], a + ld a, [wd730] + res 6, a ; turn on the printing delay + ld [wd730], a + call HandleMenuInput + call PlaceUnfilledArrowMenuCursor + bit 0, a ; was A pressed? + jr nz, .pressedA + bit 1, a ; was B pressed? (always true since only A/B are watched) + jr z, .pressedA + ld a, CANCELLED_MENU + ld [wMenuExitMethod], a + jr .quit +.pressedA + ld a, CHOSE_MENU_ITEM + ld [wMenuExitMethod], a + ld a, [wCurrentMenuItem] + ld [wChosenMenuItem], a + ld b, a + ld a, [wMaxMenuItem] + cp b + jr z, .quit + ret +.quit + ld a, CANCELLED_MENU + ld [wMenuExitMethod], a + ld a, [wCurrentMenuItem] + ld [wChosenMenuItem], a + scf + ret + +; displays a menu with two options to choose from +; b = Y of upper left corner of text region +; c = X of upper left corner of text region +; hl = address where the text box border should be drawn +DisplayTwoOptionMenu: + push hl + ld a, [wd730] + set 6, a ; no printing delay + ld [wd730], a + +; pointless because both values are overwritten before they are read + xor a + ld [wChosenMenuItem], a + ld [wMenuExitMethod], a + + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, $1 + ld [wMaxMenuItem], a + ld a, b + ld [wTopMenuItemY], a + ld a, c + ld [wTopMenuItemX], a + xor a + ld [wLastMenuItem], a + ld [wMenuWatchMovingOutOfBounds], a + push hl + ld hl, wTwoOptionMenuID + bit 7, [hl] ; select second menu item by default? + res 7, [hl] + jr z, .storeCurrentMenuItem + inc a +.storeCurrentMenuItem + ld [wCurrentMenuItem], a + pop hl + push hl + push hl + call TwoOptionMenu_SaveScreenTiles + ld a, [wTwoOptionMenuID] + ld hl, TwoOptionMenuStrings + ld e, a + ld d, $0 + ld a, $5 +.menuStringLoop + add hl, de + dec a + jr nz, .menuStringLoop + ld a, [hli] + ld c, a + ld a, [hli] + ld b, a + ld e, l + ld d, h + pop hl + push de + ld a, [wTwoOptionMenuID] + cp TRADE_CANCEL_MENU + jr nz, .notTradeCancelMenu + call CableClub_TextBoxBorder + jr .afterTextBoxBorder +.notTradeCancelMenu + call TextBoxBorder +.afterTextBoxBorder + call UpdateSprites + pop hl + ld a, [hli] + and a ; put blank line before first menu item? + ld bc, 20 + 2 + jr z, .noBlankLine + ld bc, 2 * 20 + 2 +.noBlankLine + ld a, [hli] + ld e, a + ld a, [hli] + ld d, a + pop hl + add hl, bc + call PlaceString + ld hl, wd730 + res 6, [hl] ; turn on the printing delay + ld a, [wTwoOptionMenuID] + cp NO_YES_MENU + jr nz, .notNoYesMenu +; No/Yes menu +; this menu type ignores the B button +; it only seems to be used when confirming the deletion of a save file + xor a + ld [wTwoOptionMenuID], a + ld a, [wFlags_0xcd60] + push af + push hl + ld hl, wFlags_0xcd60 + bit 5, [hl] + set 5, [hl] ; don't play sound when A or B is pressed in menu + pop hl +.noYesMenuInputLoop + call HandleMenuInput + bit 1, a ; A button pressed? + jr nz, .noYesMenuInputLoop ; try again if A was not pressed + pop af + pop hl + ld [wFlags_0xcd60], a + ld a, SFX_PRESS_AB + call PlaySound + jr .pressedAButton +.notNoYesMenu + xor a + ld [wTwoOptionMenuID], a + call HandleMenuInput + pop hl + bit 1, a ; A button pressed? + jr nz, .choseSecondMenuItem ; automatically choose the second option if B is pressed +.pressedAButton + ld a, [wCurrentMenuItem] + ld [wChosenMenuItem], a + and a + jr nz, .choseSecondMenuItem +; chose first menu item + ld a, CHOSE_FIRST_ITEM + ld [wMenuExitMethod], a + ld c, 15 + call DelayFrames + call TwoOptionMenu_RestoreScreenTiles + and a + ret +.choseSecondMenuItem + ld a, 1 + ld [wCurrentMenuItem], a + ld [wChosenMenuItem], a + ld a, CHOSE_SECOND_ITEM + ld [wMenuExitMethod], a + ld c, 15 + call DelayFrames + call TwoOptionMenu_RestoreScreenTiles + scf + ret + +; Some of the wider/taller two option menus will not have the screen areas +; they cover be fully saved/restored by the two functions below. +; The bottom and right edges of the menu may remain after the function returns. + +TwoOptionMenu_SaveScreenTiles: + ld de, wBuffer + lb bc, 5, 7 +.loop + ld a, [hli] + ld [de], a + inc de + dec c + jr nz, .loop + push bc + ld bc, SCREEN_WIDTH - 7 + add hl, bc + pop bc + ld c, $7 + dec b + jr nz, .loop + ret + +TwoOptionMenu_RestoreScreenTiles: + ld de, wBuffer + lb bc, 5, 7 +.loop + ld a, [de] + inc de + ld [hli], a + dec c + jr nz, .loop + push bc + ld bc, SCREEN_WIDTH - 7 + add hl, bc + pop bc + ld c, 7 + dec b + jr nz, .loop + call UpdateSprites + ret + +; Format: +; 00: byte width +; 01: byte height +; 02: byte put blank line before first menu item +; 03: word text pointer +TwoOptionMenuStrings: + db 5,3,0 + dw .YesNoMenu + db 6,3,0 + dw .NorthWestMenu + db 6,3,0 + dw .SouthEastMenu + db 6,3,0 + dw .YesNoMenu + db 6,3,0 + dw .NorthEastMenu + db 7,3,0 + dw .TradeCancelMenu + db 7,4,1 + dw .HealCancelMenu + db 5,3,0 + dw .NoYesMenu + +.NorthWestMenu + db "NORTH" + next "WEST@" +.SouthEastMenu + db "SOUTH" + next "EAST@" +.NorthEastMenu + db "NORTH" + next "EAST@" +.NoYesMenu + db "NEIN" + next "JA@" +.YesNoMenu + db "JA" + next "NEIN@" +.TradeCancelMenu + db "TAUSCH" + next "ZURÜCK@" +.HealCancelMenu + db "HEILEN" + next "ZURÜCK@" + +DisplayFieldMoveMonMenu: + xor a + ld hl, wFieldMoves + ld [hli], a ; wFieldMoves + ld [hli], a ; wFieldMoves + 1 + ld [hli], a ; wFieldMoves + 2 + ld [hli], a ; wFieldMoves + 3 + ld [hli], a ; wNumFieldMoves + ld [hl], 12 ; wFieldMovesLeftmostXCoord + call GetMonFieldMoves + ld a, [wNumFieldMoves] + and a + jr nz, .fieldMovesExist + +; no field moves + coord hl, 11, 11 + ld b, 5 + ld c, 7 + call TextBoxBorder + call UpdateSprites + ld a, 12 + ld [hFieldMoveMonMenuTopMenuItemX], a + coord hl, 13, 12 + ld de, PokemonMenuEntries + jp PlaceString + +.fieldMovesExist + push af + +; Calculate the text box position and dimensions based on the leftmost X coord +; of the field move names before adjusting for the number of field moves. + coord hl, 0, 11 + ld a, [wFieldMovesLeftmostXCoord] + dec a + ld e, a + ld d, 0 + add hl, de + ld b, 5 + ld a, 18 + sub e + ld c, a + pop af + +; For each field move, move the top of the text box up 2 rows while the leaving +; the bottom of the text box at the bottom of the screen. + ld de, -SCREEN_WIDTH * 2 +.textBoxHeightLoop + add hl, de + inc b + inc b + dec a + jr nz, .textBoxHeightLoop + +; Make space for an extra blank row above the top field move. + ld de, -SCREEN_WIDTH + add hl, de + inc b + + call TextBoxBorder + call UpdateSprites + +; Calculate the position of the first field move name to print. + coord hl, 0, 12 + ld a, [wFieldMovesLeftmostXCoord] + inc a + ld e, a + ld d, 0 + add hl, de + ld de, -SCREEN_WIDTH * 2 + ld a, [wNumFieldMoves] +.calcFirstFieldMoveYLoop + add hl, de + dec a + jr nz, .calcFirstFieldMoveYLoop + + xor a + ld [wNumFieldMoves], a + ld de, wFieldMoves +.printNamesLoop + push hl + ld hl, FieldMoveNames + ld a, [de] + and a + jr z, .donePrintingNames + inc de + ld b, a ; index of name +.skipNamesLoop ; skip past names before the name we want + dec b + jr z, .reachedName +.skipNameLoop ; skip past current name + ld a, [hli] + cp "@" + jr nz, .skipNameLoop + jr .skipNamesLoop +.reachedName + ld b, h + ld c, l + pop hl + push de + ld d, b + ld e, c + call PlaceString + ld bc, SCREEN_WIDTH * 2 + add hl, bc + pop de + jr .printNamesLoop + +.donePrintingNames + pop hl + ld a, [wFieldMovesLeftmostXCoord] + ld [hFieldMoveMonMenuTopMenuItemX], a + coord hl, 0, 12 + ld a, [wFieldMovesLeftmostXCoord] + inc a + ld e, a + ld d, 0 + add hl, de + ld de, PokemonMenuEntries + jp PlaceString + +FieldMoveNames: + db "ZERSCHNEIDER@" + db "FLIEGEN@" + db "@" + db "SURFER@" + db "STÄRKE@" + db "BLITZ@" + db "SCHAUFLER@" + db "TELEPORT@" + db "WEICHEI@" + +PokemonMenuEntries: + db "STATUS" + next "TAUSCH" + next "ZURÜCK@" + +GetMonFieldMoves: + ld a, [wWhichPokemon] + ld hl, wPartyMon1Moves + ld bc, wPartyMon2 - wPartyMon1 + call AddNTimes + ld d, h + ld e, l + ld c, NUM_MOVES + 1 + ld hl, wFieldMoves +.loop + push hl +.nextMove + dec c + jr z, .done + ld a, [de] ; move ID + and a + jr z, .done + ld b, a + inc de + ld hl, FieldMoveDisplayData +.fieldMoveLoop + ld a, [hli] + cp $ff + jr z, .nextMove ; if the move is not a field move + cp b + jr z, .foundFieldMove + inc hl + inc hl + jr .fieldMoveLoop +.foundFieldMove + ld a, b + ld [wLastFieldMoveID], a + ld a, [hli] ; field move name index + ld b, [hl] ; field move leftmost X coordinate + pop hl + ld [hli], a ; store name index in wFieldMoves + ld a, [wNumFieldMoves] + inc a + ld [wNumFieldMoves], a + ld a, [wFieldMovesLeftmostXCoord] + cp b + jr c, .skipUpdatingLeftmostXCoord + ld a, b + ld [wFieldMovesLeftmostXCoord], a +.skipUpdatingLeftmostXCoord + ld a, [wLastFieldMoveID] + ld b, a + jr .loop +.done + pop hl + ret + +; Format: [Move id], [name index], [leftmost tile] +; Move id = id of move +; Name index = index of name in FieldMoveNames +; Leftmost tile = -1 + tile column in which the first letter of the move's name should be displayed +; "SOFTBOILED" is $08 because it has 4 more letters than "SURF", for example, whose value is $0C +FieldMoveDisplayData: + db CUT, $01, $06 + db FLY, $02, $0B + db $B4, $03, $0C ; unused field move + db SURF, $04, $0C + db STRENGTH, $05, $0C + db FLASH, $06, $0C + db DIG, $07, $09 + db TELEPORT, $08, $0A + db SOFTBOILED, $09, $0B + db $ff ; list terminator diff --git a/de/engine/menu/vending_machine.asm b/de/engine/menu/vending_machine.asm new file mode 100755 index 00000000..08f44694 --- /dev/null +++ b/de/engine/menu/vending_machine.asm @@ -0,0 +1,139 @@ +VendingMachineMenu: + ld hl, VendingMachineText1 + call PrintText + ld a, MONEY_BOX + ld [wTextBoxID], a + call DisplayTextBoxID + xor a + ld [wCurrentMenuItem], a + ld [wLastMenuItem], a + ld a, A_BUTTON | B_BUTTON + ld [wMenuWatchedKeys], a + ld a, 3 + ld [wMaxMenuItem], a + ld a, 5 + ld [wTopMenuItemY], a + ld a, 1 + ld [wTopMenuItemX], a + ld hl, wd730 + set 6, [hl] + coord hl, 0, 3 + ld b, 8 + ld c, 12 + call TextBoxBorder + call UpdateSprites + coord hl, 2, 5 + ld de, DrinkText + call PlaceString + coord hl, 9, 6 + ld de, DrinkPriceText + call PlaceString + ld hl, wd730 + res 6, [hl] + call HandleMenuInput + bit 1, a ; pressed B? + jr nz, .notThirsty + ld a, [wCurrentMenuItem] + cp 3 ; chose Cancel? + jr z, .notThirsty + xor a + ld [hMoney], a + ld [hMoney + 2], a + ld a, $2 + ld [hMoney + 1], a + call HasEnoughMoney + jr nc, .enoughMoney + ld hl, VendingMachineText4 + jp PrintText +.enoughMoney + call LoadVendingMachineItem + ld a, [hVendingMachineItem] + ld b, a + ld c, 1 + call GiveItem + jr nc, .BagFull + + ld b, 60 ; number of times to play the "brrrrr" sound +.playDeliverySound + ld c, 2 + call DelayFrames + push bc + ld a, SFX_PUSH_BOULDER + call PlaySound + pop bc + dec b + jr nz, .playDeliverySound + + ld hl, VendingMachineText5 + call PrintText + ld hl, hVendingMachinePrice + 2 + ld de, wPlayerMoney + 2 + ld c, $3 + predef SubBCDPredef + ld a, MONEY_BOX + ld [wTextBoxID], a + jp DisplayTextBoxID +.BagFull + ld hl, VendingMachineText6 + jp PrintText +.notThirsty + ld hl, VendingMachineText7 + jp PrintText + +VendingMachineText1: + TX_FAR _VendingMachineText1 + db "@" + +DrinkText: + db "TAFELWASSER" + next "SPRUDEL" + next "LIMONADE" + next "ZURÜCK@" + +DrinkPriceText: + db "¥200" + next "¥300" + next "¥350" + next "@" + +VendingMachineText4: + TX_FAR _VendingMachineText4 + db "@" + +VendingMachineText5: + TX_FAR _VendingMachineText5 + db "@" + +VendingMachineText6: + TX_FAR _VendingMachineText6 + db "@" + +VendingMachineText7: + TX_FAR _VendingMachineText7 + db "@" + +LoadVendingMachineItem: + ld hl, VendingPrices + ld a, [wCurrentMenuItem] + add a + add a + ld d, 0 + ld e, a + add hl, de + ld a, [hli] + ld [hVendingMachineItem], a + ld a, [hli] + ld [hVendingMachinePrice], a + ld a, [hli] + ld [hVendingMachinePrice + 1], a + ld a, [hl] + ld [hVendingMachinePrice + 2], a + ret + +VendingPrices: + db FRESH_WATER + money 200 + db SODA_POP + money 300 + db LEMONADE + money 350 |