From f46db37d508f0111ad44ad062ed3d83ba3282d1d Mon Sep 17 00:00:00 2001 From: SatoMew Date: Sat, 15 Jul 2023 23:36:59 +0100 Subject: Thoroughly document debug code (#410) --- engine/battle/core.asm | 25 +++++++++----- engine/battle/init_battle_variables.asm | 2 +- engine/debug/debug_menu.asm | 23 +++++++------ engine/debug/debug_party.asm | 24 ++++++------- engine/menus/main_menu.asm | 13 ++++--- engine/movie/oak_speech/oak_speech.asm | 17 ++++++--- engine/movie/title.asm | 8 ++--- engine/overworld/special_warps.asm | 61 ++++++++++++++++----------------- 8 files changed, 95 insertions(+), 78 deletions(-) (limited to 'engine') diff --git a/engine/battle/core.asm b/engine/battle/core.asm index 4a0263e2..f976674a 100644 --- a/engine/battle/core.asm +++ b/engine/battle/core.asm @@ -2493,9 +2493,9 @@ MoveSelectionMenu: ; so it is necessary to put the di ei block to not cause tearing call TextBoxBorder hlcoord 4, 12 - ld [hl], $7a + ld [hl], "─" hlcoord 10, 12 - ld [hl], $7e + ld [hl], "┘" ei hlcoord 6, 13 call .writemoves @@ -2557,11 +2557,12 @@ MoveSelectionMenu: ld a, [wLinkState] cp LINK_STATE_BATTLING jr z, .matchedkeyspicked + ; Disable left, right, and START buttons in regular battles. ld a, [wFlags_D733] bit BIT_TEST_BATTLE, a ld b, D_UP | D_DOWN | A_BUTTON | B_BUTTON | SELECT jr z, .matchedkeyspicked - ld b, $ff + ld b, D_UP | D_DOWN | D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON | SELECT | START .matchedkeyspicked ld a, b ld [hli], a ; wMenuWatchedKeys @@ -2585,8 +2586,12 @@ SelectMenuItem: call PlaceString jr .select .battleselect + ; Hide move swap cursor in TestBattle. ld a, [wFlags_D733] bit BIT_TEST_BATTLE, a + ; This causes PrintMenuItem to not run in TestBattle. + ; MoveSelectionMenu still draws part of its window, an issue + ; which did not seem to exist in the Japanese versions. jr nz, .select call PrintMenuItem ld a, [wMenuItemToSwap] @@ -2648,8 +2653,9 @@ SelectMenuItem: jr z, .disabled ld a, [wPlayerBattleStatus3] bit 3, a ; transformed - jr nz, .dummy ; game freak derp -.dummy + jr nz, .transformedMoveSelected +.transformedMoveSelected ; pointless + ; Allow moves copied by Transform to be used. ld a, [wCurrentMenuItem] ld hl, wBattleMonMoves ld c, a @@ -6085,6 +6091,7 @@ GetCurrentMove: jr .selected .player ld de, wPlayerMoveNum + ; Apply InitBattleVariables to TestBattle. ld a, [wFlags_D733] bit BIT_TEST_BATTLE, a ld a, [wTestBattlePlayerSelectedMove] @@ -6768,12 +6775,12 @@ InitOpponent: DetermineWildOpponent: ld a, [wd732] - bit 1, a - jr z, .notDebug + bit BIT_DEBUG_MODE, a + jr z, .notDebugMode ldh a, [hJoyHeld] - bit BIT_B_BUTTON, a + bit BIT_B_BUTTON, a ; disable wild encounters ret nz -.notDebug +.notDebugMode ld a, [wNumberOfNoRandomBattleStepsLeft] and a ret nz diff --git a/engine/battle/init_battle_variables.asm b/engine/battle/init_battle_variables.asm index dd9f9714..aa081296 100644 --- a/engine/battle/init_battle_variables.asm +++ b/engine/battle/init_battle_variables.asm @@ -20,7 +20,7 @@ InitBattleVariables: ld [hli], a ; wPlayerHPBarColor ld [hl], a ; wEnemyHPBarColor ld hl, wCanEvolveFlags - ld b, $3c + ld b, wMiscBattleDataEnd - wMiscBattleData .loop ld [hli], a dec b diff --git a/engine/debug/debug_menu.asm b/engine/debug/debug_menu.asm index 907acb8a..fbf136fe 100644 --- a/engine/debug/debug_menu.asm +++ b/engine/debug/debug_menu.asm @@ -56,7 +56,7 @@ IF DEF(_DEBUG) ; DEBUG ld hl, wd732 - set 1, [hl] + set BIT_DEBUG_MODE, [hl] jp StartNewGameDebug DebugBattlePlayerName: @@ -72,18 +72,23 @@ ELSE ret ENDC -TestBattle: +TestBattle: ; unreferenced except in _DEBUG .loop call GBPalNormal - ; Don't mess around - ; with obedience. + ; Don't mess around with obedience. ld a, 1 << BIT_EARTHBADGE ld [wObtainedBadges], a ld hl, wFlags_D733 set BIT_TEST_BATTLE, [hl] + ; wNumBagItems and wBagItems are not initialized here, + ; and their garbage values happen to act as if EXP_ALL + ; is in the bag at the end of the test battle. + ; pokeyellow fixes this by initializing them with a + ; list of items. + ; Reset the party. ld hl, wPartyCount xor a @@ -91,8 +96,7 @@ TestBattle: dec a ld [hl], a - ; Give the player a - ; level 20 Rhydon. + ; Give the player a level 20 Rhydon. ld a, RHYDON ld [wcf91], a ld a, 20 @@ -102,15 +106,14 @@ TestBattle: ld [wCurMap], a call AddPartyMon - ; Fight against a - ; level 20 Rhydon. + ; Fight against a level 20 Rhydon. ld a, RHYDON ld [wCurOpponent], a predef InitOpponent - ; When the battle ends, - ; do it all again. + ; When the battle ends, do it all again. + ; There are some graphical quirks in SGB mode. ld a, 1 ld [wUpdateSpritesEnabled], a ldh [hAutoBGTransferEnabled], a diff --git a/engine/debug/debug_party.asm b/engine/debug/debug_party.asm index 36eb8e6f..0c76bde1 100644 --- a/engine/debug/debug_party.asm +++ b/engine/debug/debug_party.asm @@ -1,13 +1,5 @@ -; This function is a debugging feature to give the player Tsunekazu Ishihara's -; favorite Pokemon. This is indicated by the overpowered Exeggutor, which -; Ishihara (president of Creatures Inc.) said was his favorite Pokemon in an ABC -; interview on February 8, 2000. -; "Exeggutor is my favorite. That's because I was always using this character -; while I was debugging the program." -; http://www.ign.com/articles/2000/02/09/abc-news-pokamon-chat-transcript - -SetIshiharaTeam: - ld de, IshiharaTeam +SetDebugNewGameParty: ; unreferenced except in _DEBUG + ld de, DebugNewGameParty .loop ld a, [de] cp -1 @@ -20,7 +12,11 @@ SetIshiharaTeam: call AddPartyMon jr .loop -IshiharaTeam: +DebugNewGameParty: ; unreferenced except in _DEBUG + ; Exeggutor is the only debug party member shared with Red, Green, and Japanese Blue. + ; "Tsunekazu Ishihara: Exeggutor is my favorite. That's because I was + ; always using this character while I was debugging the program." + ; From https://web.archive.org/web/20000607152840/http://pocket.ign.com/news/14973.html db EXEGGUTOR, 90 IF DEF(_DEBUG) db MEW, 5 @@ -35,13 +31,13 @@ IF DEF(_DEBUG) ENDC db -1 ; end -DebugStart: +PrepareNewGameDebug: ; dummy except in _DEBUG IF DEF(_DEBUG) xor a ; PLAYER_PARTY_DATA ld [wMonDataLocation], a ; Fly anywhere. - dec a ; $ff + dec a ; $ff (all bits) ld [wTownVisitedFlag], a ld [wTownVisitedFlag + 1], a @@ -49,7 +45,7 @@ IF DEF(_DEBUG) ld a, ~(1 << BIT_EARTHBADGE) ld [wObtainedBadges], a - call SetIshiharaTeam + call SetDebugNewGameParty ; Exeggutor gets four HM moves. ld hl, wPartyMon1Moves diff --git a/engine/menus/main_menu.asm b/engine/menus/main_menu.asm index 024def28..69b3b918 100644 --- a/engine/menus/main_menu.asm +++ b/engine/menus/main_menu.asm @@ -121,7 +121,7 @@ MainMenu: ld [wDestinationMap], a ld hl, wd732 set 2, [hl] ; fly warp or dungeon warp - call SpecialWarpIn + call PrepareForSpecialWarp jp SpecialEnterMap InitOptions: @@ -268,10 +268,10 @@ LinkMenu: ld c, 50 call DelayFrames ld hl, wd732 - res 1, [hl] + res BIT_DEBUG_MODE, [hl] ld a, [wDefaultMap] ld [wDestinationMap], a - call SpecialWarpIn + call PrepareForSpecialWarp ld c, 20 call DelayFrames xor a @@ -308,7 +308,12 @@ LinkCanceledText: StartNewGame: ld hl, wd732 - res 1, [hl] + ; Ensure debug mode is not used when + ; starting a regular new game. + ; Debug mode persists in saved games for + ; both debug and non-debug builds, and is + ; only reset here by the main menu. + res BIT_DEBUG_MODE, [hl] ; fallthrough StartNewGameDebug: call OakSpeech diff --git a/engine/movie/oak_speech/oak_speech.asm b/engine/movie/oak_speech/oak_speech.asm index 3a08372d..4ed4735e 100644 --- a/engine/movie/oak_speech/oak_speech.asm +++ b/engine/movie/oak_speech/oak_speech.asm @@ -3,6 +3,11 @@ PrepareOakSpeech: push af ld a, [wOptions] push af + ; Retrieve BIT_DEBUG_MODE set in DebugMenu for StartNewGameDebug. + ; BUG: StartNewGame carries over bit 5 from previous save files, + ; which causes CheckForceBikeOrSurf to not return. + ; To fix this in debug builds, reset bit 5 here or in StartNewGame. + ; In non-debug builds, the instructions can be removed. ld a, [wd732] push af ld hl, wPlayerName @@ -24,6 +29,7 @@ PrepareOakSpeech: call z, InitOptions ; These debug names are used for StartNewGameDebug. ; TestBattle uses the debug names from DebugMenu. + ; A variant of this process is performed in PrepareTitleScreen. ld hl, DebugNewGamePlayerName ld de, wPlayerName ld bc, NAME_LENGTH @@ -49,15 +55,15 @@ OakSpeech: ld [wcf91], a ld a, 1 ld [wItemQuantity], a - call AddItemToInventory ; give one potion + call AddItemToInventory ld a, [wDefaultMap] ld [wDestinationMap], a - call SpecialWarpIn + call PrepareForSpecialWarp xor a ldh [hTileAnimations], a ld a, [wd732] - bit 1, a ; possibly a debug mode bit - jp nz, .skipChoosingNames + bit BIT_DEBUG_MODE, a + jp nz, .skipSpeech ld de, ProfOakPic lb bc, BANK(ProfOakPic), $00 call IntroDisplayPicCenteredOrUpperRight @@ -93,7 +99,7 @@ OakSpeech: ld hl, IntroduceRivalText call PrintText call ChooseRivalName -.skipChoosingNames +.skipSpeech call GBFadeOutToWhite call ClearScreen ld de, RedPicFront @@ -159,6 +165,7 @@ OakSpeechText1: text_end OakSpeechText2: text_far _OakSpeechText2A + ; BUG: The cry played does not match the sprite displayed. sound_cry_nidorina text_far _OakSpeechText2B text_end diff --git a/engine/movie/title.asm b/engine/movie/title.asm index ad5f6ebf..36a28b0d 100644 --- a/engine/movie/title.asm +++ b/engine/movie/title.asm @@ -1,4 +1,4 @@ -CopyDebugName: +CopyDebugName: ; unused ld bc, NAME_LENGTH jp CopyData @@ -42,10 +42,10 @@ DisplayTitleScreen: ld bc, 5 tiles ld a, BANK(NintendoCopyrightLogoGraphics) call FarCopyData2 - ld hl, GamefreakLogoGraphics + ld hl, GameFreakLogoGraphics ld de, vTitleLogo2 tile (16 + 5) ld bc, 9 tiles - ld a, BANK(GamefreakLogoGraphics) + ld a, BANK(GameFreakLogoGraphics) call FarCopyData2 ld hl, PokemonLogoGraphics ld de, vTitleLogo @@ -378,7 +378,7 @@ LoadCopyrightAndTextBoxTiles: LoadCopyrightTiles: ld de, NintendoCopyrightLogoGraphics ld hl, vChars2 tile $60 - lb bc, BANK(NintendoCopyrightLogoGraphics), (GamefreakLogoGraphicsEnd - NintendoCopyrightLogoGraphics) / $10 + lb bc, BANK(NintendoCopyrightLogoGraphics), (GameFreakLogoGraphicsEnd - NintendoCopyrightLogoGraphics) / $10 call CopyVideoData hlcoord 2, 7 ld de, CopyrightTextString diff --git a/engine/overworld/special_warps.asm b/engine/overworld/special_warps.asm index 61356a03..c538938b 100644 --- a/engine/overworld/special_warps.asm +++ b/engine/overworld/special_warps.asm @@ -1,60 +1,60 @@ -SpecialWarpIn:: +PrepareForSpecialWarp:: call LoadSpecialWarpData predef LoadTilesetHeader ld hl, wd732 bit 2, [hl] ; dungeon warp or fly warp? res 2, [hl] - jr z, .next -; if dungeon warp or fly warp + jr z, .debugNewGameWarp ld a, [wDestinationMap] - jr .next2 + jr .next +.debugNewGameWarp + bit BIT_DEBUG_MODE, [hl] + jr z, .setNewGameMatWarp ; apply to StartNewGameDebug only + call PrepareNewGameDebug +.setNewGameMatWarp + ; This is called by OakSpeech during StartNewGame and + ; loads the first warp event for the specified map index. + ld a, PALLET_TOWN .next - bit 1, [hl] - jr z, .next3 - call DebugStart -.next3 - ld a, 0 -.next2 ld b, a ld a, [wd72d] and a - jr nz, .next4 + jr nz, .next2 ld a, b -.next4 +.next2 ld hl, wd732 - bit 4, [hl] ; dungeon warp? + bit 4, [hl] ; dungeon warp ret nz -; if not dungeon warp ld [wLastMap], a ret -; gets the map ID, tile block map view pointer, tileset, and coordinates LoadSpecialWarpData: ld a, [wd72d] cp TRADE_CENTER jr nz, .notTradeCenter - ld hl, TradeCenterSpec1 + ld hl, TradeCenterPlayerWarp ldh a, [hSerialConnectionStatus] - cp USING_INTERNAL_CLOCK ; which gameboy is clocking determines who is on the left and who is on the right + cp USING_INTERNAL_CLOCK jr z, .copyWarpData - ld hl, TradeCenterSpec2 + ld hl, TradeCenterFriendWarp jr .copyWarpData .notTradeCenter cp COLOSSEUM jr nz, .notColosseum - ld hl, ColosseumSpec1 + ld hl, ColosseumPlayerWarp ldh a, [hSerialConnectionStatus] cp USING_INTERNAL_CLOCK jr z, .copyWarpData - ld hl, ColosseumSpec2 + ld hl, ColosseumFriendWarp jr .copyWarpData .notColosseum ld a, [wd732] - bit 1, a - jr nz, .notFirstMap + bit BIT_DEBUG_MODE, a + ; warp to wLastMap (PALLET_TOWN) for StartNewGameDebug + jr nz, .notNewGameWarp bit 2, a - jr nz, .notFirstMap - ld hl, FirstMapSpec + jr nz, .notNewGameWarp + ld hl, NewGameWarp .copyWarpData ld de, wCurMap ld c, $7 @@ -68,18 +68,17 @@ LoadSpecialWarpData: ld [wCurMapTileset], a xor a jr .done -.notFirstMap +.notNewGameWarp ld a, [wLastMap] ; this value is overwritten before it's ever read ld hl, wd732 - bit 4, [hl] ; used dungeon warp (jumped down hole/waterfall)? - jr nz, .usedDunegonWarp - bit 6, [hl] ; return to last pokemon center (or player's house)? + bit 4, [hl] ; dungeon warp + jr nz, .usedDungeonWarp + bit 6, [hl] ; blacked out res 6, [hl] jr z, .otherDestination -; return to last pokemon center or player's house ld a, [wLastBlackoutMap] jr .usedFlyWarp -.usedDunegonWarp +.usedDungeonWarp ld hl, wd72d res 4, [hl] ld a, [wDungeonWarpDestinationMap] @@ -142,7 +141,7 @@ LoadSpecialWarpData: .done ld [wYOffsetSinceLastSpecialWarp], a ld [wXOffsetSinceLastSpecialWarp], a - ld a, $ff ; the player's coordinates have already been updated using a special warp, so don't use any of the normal warps + ld a, -1 ; exclude normal warps ld [wDestinationWarpID], a ret -- cgit v1.3.1-sl0p