diff --git a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipLogoTitle.cpp b/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipLogoTitle.cpp deleted file mode 100644 index 7a7beeeb6..000000000 --- a/soh/soh/Enhancements/TimeSavers/SkipCutscene/SkipLogoTitle.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" -#include "soh/ShipInit.hpp" - -extern "C" { -#include "macros.h" -#include "z64.h" -} - -// Allows pressing A to skip the boot logo and go to the next state (opening or file select) -void OnZTitleUpdateSkipLogoTitle(void* gameState) { - TitleContext* titleContext = (TitleContext*)gameState; - - if (CHECK_BTN_ANY(titleContext->state.input->press.button, BTN_A | BTN_B | BTN_START)) { - // Force the title state to start fading to black and to last roughly 5 frames based on current fade in/out - titleContext->visibleDuration = 0; - titleContext->addAlpha = (255 - titleContext->coverAlpha) / 5; - } -} - -void RegisterSkipLogoTitle() { - COND_HOOK(OnZTitleUpdate, true, OnZTitleUpdateSkipLogoTitle); -} - -static RegisterShipInitFunc initFunc(RegisterSkipLogoTitle); diff --git a/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp new file mode 100644 index 000000000..df1216856 --- /dev/null +++ b/soh/soh/Enhancements/cosmetics/CustomLogoTitle.cpp @@ -0,0 +1,66 @@ +#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h" +#include "soh/ShipInit.hpp" + +extern "C" { +#include "macros.h" +#include "z64.h" +#include "functions.h" +#include "variables.h" +} + +extern "C" { +extern void Title_Calc(TitleContext*); +extern void Title_Draw(TitleContext*); +} + +extern "C" void CustomLogoTitle_Main(void* gameState) { + TitleContext* titleContext = (TitleContext*)gameState; + + OPEN_DISPS(titleContext->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0, (uintptr_t)NULL); + gSPSegment(POLY_OPA_DISP++, 1, (uintptr_t)titleContext->staticSegment); + Gfx_SetupFrame(titleContext->state.gfxCtx, 0, 0, 0); + Title_Calc(titleContext); + Title_Draw(titleContext); + + if (titleContext->exit || CVarGetInteger(CVAR_DEVELOPER_TOOLS("SkipLogoTitle"), 0)) { + gSaveContext.seqId = (u8)NA_BGM_DISABLED; + gSaveContext.natureAmbienceId = 0xFF; + gSaveContext.gameMode = 1; + titleContext->state.running = false; + + if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("SkipLogoTitle"), 0)) + SET_NEXT_GAMESTATE(&titleContext->state, FileChoose_Init, FileChooseContext); + else + SET_NEXT_GAMESTATE(&titleContext->state, Opening_Init, OpeningContext); + } + + GameInteractor_ExecuteOnZTitleUpdate(titleContext); + + CLOSE_DISPS(titleContext->state.gfxCtx); +} + +// Allows pressing A to skip the boot logo and go to the next state (opening or file select) +void OnZTitleUpdateSkipLogoTitle(void* gameState) { + TitleContext* titleContext = (TitleContext*)gameState; + + if (CHECK_BTN_ANY(titleContext->state.input->press.button, BTN_A | BTN_B | BTN_START)) { + // Force the title state to start fading to black and to last roughly 5 frames based on current fade in/out + titleContext->visibleDuration = 0; + titleContext->addAlpha = (255 - titleContext->coverAlpha) / 5; + } +} + +void OnZTitleInitReplaceTitleMainWithCustom(void* gameState) { + TitleContext* titleContext = (TitleContext*)gameState; + + titleContext->state.main = (GameStateFunc)CustomLogoTitle_Main; +} + +void RegisterCustomLogoTitle() { + COND_HOOK(OnZTitleInit, true, OnZTitleInitReplaceTitleMainWithCustom); + COND_HOOK(OnZTitleUpdate, true, OnZTitleUpdateSkipLogoTitle); +} + +static RegisterShipInitFunc initFunc(RegisterCustomLogoTitle); diff --git a/soh/soh/Enhancements/enhancementTypes.h b/soh/soh/Enhancements/enhancementTypes.h index d57a94991..225794d14 100644 --- a/soh/soh/Enhancements/enhancementTypes.h +++ b/soh/soh/Enhancements/enhancementTypes.h @@ -69,6 +69,12 @@ typedef enum { AUTOSAVE_ALL_ITEMS } AutosaveType; +typedef enum { + BOOTSEQUENCE_DEFAULT, + BOOTSEQUENCE_AUTHENTIC, + BOOTSEQUENCE_FILESELECT +} BootSequenceType; + typedef enum { ZFIGHT_FIX_DISABLED, ZFIGHT_FIX_CONSISTENT_VANISH, diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h index 0ed761716..8a4d803de 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_HookTable.h @@ -5,6 +5,7 @@ * - Argument 1: Name of the hook * - Argument 2: Function type that the hook uses */ +DEFINE_HOOK(OnZTitleInit, (void* gameState)); DEFINE_HOOK(OnZTitleUpdate, (void* gameState)); DEFINE_HOOK(OnLoadGame, (int32_t fileNum)); DEFINE_HOOK(OnExitGame, (int32_t fileNum)); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index bd2baef98..f77b88e20 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -2,6 +2,10 @@ // MARK: - Gameplay +void GameInteractor_ExecuteOnZTitleInit(void* gameState) { + GameInteractor::Instance->ExecuteHooks(gameState); +} + void GameInteractor_ExecuteOnZTitleUpdate(void* gameState) { GameInteractor::Instance->ExecuteHooks(gameState); } diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 0808bd844..099575b16 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -7,6 +7,7 @@ extern "C" { #endif // MARK: - Gameplay +void GameInteractor_ExecuteOnZTitleInit(void* gameState); void GameInteractor_ExecuteOnZTitleUpdate(void* gameState); void GameInteractor_ExecuteOnLoadGame(int32_t fileNum); void GameInteractor_ExecuteOnExitGame(int32_t fileNum); diff --git a/soh/soh/SohMenuBar.cpp b/soh/soh/SohMenuBar.cpp index 1edb7e461..8fd299f85 100644 --- a/soh/soh/SohMenuBar.cpp +++ b/soh/soh/SohMenuBar.cpp @@ -104,6 +104,7 @@ static const char* imguiScaleOptions[4] = { "Small", "Normal", "Large", "X-Large static const char* subSubPowers[7] = { allPowers[0], allPowers[1], allPowers[2], allPowers[3], allPowers[4], allPowers[5], allPowers[6] }; static const char* zFightingOptions[3] = { "Disabled", "Consistent Vanish", "No Vanish" }; static const char* autosaveLabels[6] = { "Off", "New Location + Major Item", "New Location + Any Item", "New Location", "Major Item", "Any Item" }; + static const char* bootSequenceLabels[3] = { "Default", "Authentic", "File Select" }; static const char* DebugSaveFileModes[3] = { "Off", "Vanilla", "Maxed" }; static const char* FastFileSelect[5] = { "File N.1", "File N.2", "File N.3", "Zelda Map Select (require OoT Debug Mode)", "File select" }; static const char* DekuStickCheat[3] = { "Normal", "Unbreakable", "Unbreakable + Always on Fire" }; @@ -1709,6 +1710,16 @@ void DrawEnhancementsMenu() { UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f); + UIWidgets::PaddedText("Boot Sequence", false, true); + UIWidgets::EnhancementCombobox(CVAR_ENHANCEMENT("BootSequence"), bootSequenceLabels, BOOTSEQUENCE_DEFAULT); + UIWidgets::Tooltip("Configure what happens when starting or resetting the game\n\n" + "Default: LUS logo -> N64 logo\n" + "Authentic: N64 logo only\n" + "File Select: Skip to file select menu" + ); + + UIWidgets::PaddedSeparator(true, true, 2.0f, 2.0f); + ImGui::EndDisabled(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(12.0f, 6.0f)); diff --git a/soh/src/overlays/gamestates/ovl_title/z_title.c b/soh/src/overlays/gamestates/ovl_title/z_title.c index 24de4fcd2..544fb6884 100644 --- a/soh/src/overlays/gamestates/ovl_title/z_title.c +++ b/soh/src/overlays/gamestates/ovl_title/z_title.c @@ -142,8 +142,6 @@ void Title_Main(GameState* thisx) { SET_NEXT_GAMESTATE(&this->state, Opening_Init, OpeningContext); } - GameInteractor_ExecuteOnZTitleUpdate(this); - CLOSE_DISPS(this->state.gfxCtx); } @@ -171,4 +169,6 @@ void Title_Init(GameState* thisx) { this->coverAlpha = 255; this->addAlpha = -3; this->visibleDuration = 0x3C; + + GameInteractor_ExecuteOnZTitleInit(this); }