diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp index 764d2ea65..37089aa7f 100644 --- a/mm/2s2h/BenGui/BenMenuBar.cpp +++ b/mm/2s2h/BenGui/BenMenuBar.cpp @@ -12,7 +12,6 @@ #include "2s2h/Enhancements/Graphics/PlayAsKafei.h" #include "2s2h/Enhancements/Modes/TimeMovesWhenYouMove.h" #include "2s2h/DeveloperTools/DeveloperTools.h" -#include "2s2h/DeveloperTools/WarpPoint.h" #include "2s2h/Enhancements/Cheats/Cheats.h" #include "2s2h/Enhancements/Player/Player.h" #include "HudEditor.h" diff --git a/mm/2s2h/DeveloperTools/DeveloperTools.cpp b/mm/2s2h/DeveloperTools/DeveloperTools.cpp index fe0d9606d..316d851e5 100644 --- a/mm/2s2h/DeveloperTools/DeveloperTools.cpp +++ b/mm/2s2h/DeveloperTools/DeveloperTools.cpp @@ -155,4 +155,5 @@ void InitDeveloperTools() { RegisterPreventActorUpdateHooks(); RegisterPreventActorDrawHooks(); RegisterPreventActorInitHooks(); + RegisterWarpPoint(); } diff --git a/mm/2s2h/DeveloperTools/DeveloperTools.h b/mm/2s2h/DeveloperTools/DeveloperTools.h index 3723d75d6..93c361b99 100644 --- a/mm/2s2h/DeveloperTools/DeveloperTools.h +++ b/mm/2s2h/DeveloperTools/DeveloperTools.h @@ -11,6 +11,8 @@ void RegisterDebugSaveCreate(); void RegisterPreventActorUpdateHooks(); void RegisterPreventActorDrawHooks(); void RegisterPreventActorInitHooks(); +void RegisterWarpPoint(); +void RenderWarpPointSection(); void InitDeveloperTools(); #endif // DEVELOPER_TOOLS_H diff --git a/mm/2s2h/DeveloperTools/WarpPoint.cpp b/mm/2s2h/DeveloperTools/WarpPoint.cpp index cde2fb3e6..619d2ccfd 100644 --- a/mm/2s2h/DeveloperTools/WarpPoint.cpp +++ b/mm/2s2h/DeveloperTools/WarpPoint.cpp @@ -1,15 +1,16 @@ -#include "WarpPoint.h" - #include #include "2s2h/BenGui/UIWidgets.hpp" #include "window/gui/IconsFontAwesome4.h" +#include "2s2h/Enhancements/GameInteractor/GameInteractor.h" extern "C" { #include "z64.h" #include "macros.h" #include "functions.h" +#include "overlays/gamestates/ovl_select/z_select.h" extern PlayState* gPlayState; extern SaveContext gSaveContext; +extern GameState* gGameState; } #define CV "gDeveloperTools.WarpPoint." @@ -27,6 +28,56 @@ std::unordered_map warpPointSceneList = { #undef DEFINE_SCENE #undef DEFINE_SCENE_UNSET +void Warp() { + Vec3f pos = { CVarGetFloat(CV "X", 0.0f), CVarGetFloat(CV "Y", 0.0f), CVarGetFloat(CV "Z", 0.0f) }; + s32 entrance = CVarGetInteger(CV "Entrance", ENTRANCE(SOUTH_CLOCK_TOWN, 0)); + + if (gPlayState == NULL) { + // If gPlayState is NULL, it means the the user opted into BootToWarpPoint and the game is starting up. This is + // a hidden cvar for developers, while it is extremely useful for quick testing and debugging, I am not 100% + // confident in it's stability and ability to initialize the game properly in all cases. So for now, I'm going + // to leave it as a hidden cvar. This is incompatible with the SkipToFileSelect enhancement. To enable it open + // the Console and type: `set gDeveloperTools.WarpPoint.BootToWarpPoint 1` + gSaveContext.gameMode = GAMEMODE_NORMAL; + Sram_InitNewSave(); + gSaveContext.sceneLayer = 0; + gSaveContext.save.time = CLOCK_TIME(8, 0); + gSaveContext.save.day = 1; + gSaveContext.save.cutsceneIndex = 0; + gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.save.linkAge = 0; + gSaveContext.fileNum = 0xFF; + MapSelect_LoadGame((MapSelectState*)gGameState, CVarGetInteger(CV "Entrance", 0), 0); + } else { + // The else case, and the rest of this function is primarly relevant code copied from Play_SetRespawnData and + // func_80169EFC, minus the parts that copy scene flags to scene we are warping to (this is obviously + // undesireable) + gPlayState->nextEntrance = Entrance_Create(entrance >> 9, 0, entrance & 0xF); + gPlayState->transitionTrigger = TRANS_TRIGGER_START; + gPlayState->transitionType = TRANS_TYPE_INSTANT; + } + gSaveContext.respawn[RESPAWN_MODE_DOWN].entrance = Entrance_Create(entrance >> 9, 0, entrance & 0xF); + gSaveContext.respawn[RESPAWN_MODE_DOWN].roomIndex = CVarGetInteger(CV "Room", 0); + gSaveContext.respawn[RESPAWN_MODE_DOWN].pos = pos; + gSaveContext.respawn[RESPAWN_MODE_DOWN].yaw = CVarGetFloat(CV "Rotation", 0.0f); + gSaveContext.respawn[RESPAWN_MODE_DOWN].playerParams = PLAYER_PARAMS(0xFF, PLAYER_INITMODE_D); + gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK_FAST; + gSaveContext.respawnFlag = -8; +} + +void RegisterWarpPoint() { + GameInteractor::Instance->RegisterGameHook([]() { + if (!CVarGetInteger("gEnhancements.Cutscenes.SkipToFileSelect", 0) && CVarGetInteger(CV "BootToWarpPoint", 0) && + CVarGetInteger(CV "Saved", 0)) { + // Normally called on console logo screen + gSaveContext.seqId = (u8)NA_BGM_DISABLED; + gSaveContext.ambienceId = AMBIENCE_ID_DISABLED; + gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; + Warp(); + } + }); +} + void RenderWarpPointSection() { if (gPlayState == NULL) return; @@ -60,14 +111,7 @@ void RenderWarpPointSection() { } ImGui::SameLine(); if (UIWidgets::Button("Warp", { .size = UIWidgets::Sizes::Inline })) { - Vec3f pos = { CVarGetFloat(CV "X", 0.0f), CVarGetFloat(CV "Y", 0.0f), CVarGetFloat(CV "Z", 0.0f) }; - - Play_SetRespawnData(&gPlayState->state, RESPAWN_MODE_DOWN, - CVarGetInteger(CV "Entrance", ENTRANCE(SOUTH_CLOCK_TOWN, 0)), - CVarGetInteger(CV "Room", 0), PLAYER_PARAMS(0xFF, PLAYER_INITMODE_D), &pos, - CVarGetFloat(CV "Rotation", 0.0f)); - func_80169EFC(&gPlayState->state); - gSaveContext.respawnFlag = -8; + Warp(); } } } diff --git a/mm/2s2h/DeveloperTools/WarpPoint.h b/mm/2s2h/DeveloperTools/WarpPoint.h deleted file mode 100644 index 5a6a10883..000000000 --- a/mm/2s2h/DeveloperTools/WarpPoint.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef DEVELOPER_TOOLS_WARP_POINT_H -#define DEVELOPER_TOOLS_WARP_POINT_H - -void RenderWarpPointSection(); - -#endif // DEVELOPER_TOOLS_WARP_POINT_H diff --git a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp index fe480a3f5..ecfc074bf 100644 --- a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp +++ b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.cpp @@ -12,4 +12,5 @@ void RegisterCutscenes() { RegisterHideTitleCards(); RegisterSkipEntranceCutscenes(); RegisterSkipIntroSequence(); + RegisterSkipToFileSelect(); } diff --git a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h index fcd955512..cca8e49af 100644 --- a/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h +++ b/mm/2s2h/Enhancements/Cutscenes/Cutscenes.h @@ -14,5 +14,6 @@ void RegisterSkipClockTowerOpen(); void RegisterHideTitleCards(); void RegisterSkipEntranceCutscenes(); void RegisterSkipIntroSequence(); +void RegisterSkipToFileSelect(); #endif // CUTSCENES_H diff --git a/mm/2s2h/Enhancements/Cutscenes/SkipToFileSelect.cpp b/mm/2s2h/Enhancements/Cutscenes/SkipToFileSelect.cpp new file mode 100644 index 000000000..1b1e4e029 --- /dev/null +++ b/mm/2s2h/Enhancements/Cutscenes/SkipToFileSelect.cpp @@ -0,0 +1,33 @@ +#include +#include "Enhancements/GameInteractor/GameInteractor.h" + +extern "C" { +#include "z64.h" +#include "z64game.h" +#include "overlays/gamestates/ovl_file_choose/z_file_select.h" +#include "overlays/gamestates/ovl_title/z_title.h" +extern SaveContext gSaveContext; +extern GameState* gGameState; +} + +void RegisterSkipToFileSelect() { + GameInteractor::Instance->RegisterGameHook([]() { + if (CVarGetInteger("gEnhancements.Cutscenes.SkipToFileSelect", 0)) { + ConsoleLogoState* consoleLogoState = (ConsoleLogoState*)gGameState; + + // Wait for the console logo to fade out + if (consoleLogoState->exit) { + // Normally the PRNG seed is set at least once from the title opening running Play_Init + // We need to call it manually before file select creates RNG values for new saves + Rand_Seed(osGetTime()); + // Normally called on console logo screen + gSaveContext.seqId = (u8)NA_BGM_DISABLED; + gSaveContext.ambienceId = AMBIENCE_ID_DISABLED; + gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; + + STOP_GAMESTATE(gGameState); + SET_NEXT_GAMESTATE(gGameState, FileSelect_Init, sizeof(FileSelectState)); + } + } + }); +} diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp index ae7eda45d..d0d9e4218 100644 --- a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp +++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.cpp @@ -19,6 +19,10 @@ void GameInteractor_ExecuteOnGameStateUpdate() { GameInteractor::Instance->ExecuteHooks(); } +void GameInteractor_ExecuteOnConsoleLogoUpdate() { + GameInteractor::Instance->ExecuteHooks(); +} + void GameInteractor_ExecuteOnKaleidoUpdate(PauseContext* pauseCtx) { GameInteractor::Instance->ExecuteHooks(pauseCtx); } diff --git a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h index 8da2e5ea6..1b2fdb2e9 100644 --- a/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h +++ b/mm/2s2h/Enhancements/GameInteractor/GameInteractor.h @@ -257,6 +257,7 @@ class GameInteractor { DEFINE_HOOK(OnGameStateMainFinish, ()); DEFINE_HOOK(OnGameStateDrawFinish, ()); DEFINE_HOOK(OnGameStateUpdate, ()); + DEFINE_HOOK(OnConsoleLogoUpdate, ()); DEFINE_HOOK(OnKaleidoUpdate, (PauseContext * pauseCtx)); DEFINE_HOOK(OnSaveInit, (s16 fileNum)); DEFINE_HOOK(BeforeEndOfCycleSave, ()); @@ -300,6 +301,7 @@ extern "C" { void GameInteractor_ExecuteOnGameStateMainFinish(); void GameInteractor_ExecuteOnGameStateDrawFinish(); void GameInteractor_ExecuteOnGameStateUpdate(); +void GameInteractor_ExecuteOnConsoleLogoUpdate(); void GameInteractor_ExecuteOnKaleidoUpdate(PauseContext* pauseCtx); void GameInteractor_ExecuteOnSaveInit(s16 fileNum); void GameInteractor_ExecuteBeforeEndOfCycleSave(); diff --git a/mm/include/variables.h b/mm/include/variables.h index 43d20b140..57fe03b94 100644 --- a/mm/include/variables.h +++ b/mm/include/variables.h @@ -1765,6 +1765,7 @@ extern u16 D_0F000000[]; // #region 2S2H [General] extern PlayState* gPlayState; +extern GameState* gGameState; // #endregion #ifdef __cplusplus diff --git a/mm/src/code/game.c b/mm/src/code/game.c index 1b349289c..7fb04a125 100644 --- a/mm/src/code/game.c +++ b/mm/src/code/game.c @@ -26,6 +26,10 @@ VisZbuf sGameVisZbuf; VisMono sGameVisMono; ViMode sGameViMode; +// #region 2S2H [General] Making gGameState available +GameState* gGameState; +// #endregion + void GameState_UpdateFramerateDivisors(s32 divisor) { gFramerateDivisor = divisor; gFramerateDivisorF = divisor; @@ -205,6 +209,7 @@ void GameState_Realloc(GameState* gameState, size_t size) { } void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* gfxCtx) { + gGameState = gameState; gameState->gfxCtx = gfxCtx; gameState->frames = 0; gameState->main = NULL; @@ -256,6 +261,7 @@ void GameState_Destroy(GameState* gameState) { ViMode_Destroy(&sGameViMode); THA_Destroy(&gameState->tha); GameAlloc_Cleanup(&gameState->alloc); + gGameState = NULL; } GameStateFunc GameState_GetInit(GameState* gameState) { diff --git a/mm/src/overlays/gamestates/ovl_title/z_title.c b/mm/src/overlays/gamestates/ovl_title/z_title.c index ed622dee7..dfc1c3160 100644 --- a/mm/src/overlays/gamestates/ovl_title/z_title.c +++ b/mm/src/overlays/gamestates/ovl_title/z_title.c @@ -11,9 +11,9 @@ #include "overlays/gamestates/ovl_opening/z_opening.h" #include "misc/nintendo_rogo_static/nintendo_rogo_static.h" -#include "overlays/gamestates/ovl_file_choose/z_file_select.h" #include "build.h" #include "BenPort.h" +#include "2s2h/Enhancements/GameInteractor/GameInteractor.h" #include #define dgShipLogoDL "__OTR__misc/nintendo_rogo_static/gShipLogoDL" @@ -200,16 +200,11 @@ void ConsoleLogo_Main(GameState* thisx) { gSaveContext.gameMode = GAMEMODE_TITLE_SCREEN; STOP_GAMESTATE(&this->state); - if (CVarGetInteger("gEnhancements.Cutscenes.SkipToFileSelect", 0)) { - // Normally the PRNG seed is set at least once from the title opening running Play_Init - // We need to call it manually before file select creates RNG values for new saves - Rand_Seed(osGetTime()); - SET_NEXT_GAMESTATE(&this->state, FileSelect_Init, sizeof(FileSelectState)); - } else { - SET_NEXT_GAMESTATE(&this->state, TitleSetup_Init, sizeof(TitleSetupState)); - } + SET_NEXT_GAMESTATE(&this->state, TitleSetup_Init, sizeof(TitleSetupState)); } + GameInteractor_ExecuteOnConsoleLogoUpdate(); + CLOSE_DISPS(this->state.gfxCtx); }