[Enhancement] Hide quests in File Select (#7093)

Migrate File Select CVars

Co-authored-by: Unreference <87878910+unreference@users.noreply.github.com>
This commit is contained in:
Jordan Longstaff
2026-08-31 10:03:04 -04:00
committed by GitHub
parent 2ba5c40da6
commit 2dd51f1288
8 changed files with 255 additions and 131 deletions
@@ -15,6 +15,9 @@
"DynamicWalletIcon": 1,
"EnemySpawnsOverWaterboxes": 1,
"FasterRupeeAccumulator": 1,
"FileSelect": {
"TimeFlow": 1
},
"FixBrokenGiantsKnife": 1,
"FixDaruniaDanceSpeed": 1,
"FixDampeGoingBackwards": 1,
@@ -45,7 +48,6 @@
"SkipSaveConfirmation": 1,
"SkipText": 1,
"TextSpeed": 5,
"TimeFlowFileSelect": 1,
"TwoHandedIdle": 1,
"VisualAgony": 1,
"WidescreenActorCulling": 1
@@ -42,7 +42,10 @@
"FasterBlockPush": 5,
"FasterHeavyBlockLift": 1,
"FasterRupeeAccumulator": 1,
"FileSelectMoreInfo": 1,
"FileSelect": {
"MoreInfo": 1,
"TimeFlow": 1
},
"FishNeverEscape": 1,
"FixBrokenGiantsKnife": 1,
"FixDaruniaDanceSpeed": 1,
@@ -105,7 +108,6 @@
"SlowTextSpeed": 5,
"SwordToggle": 1,
"TextSpeed": 5,
"TimeFlowFileSelect": 1,
"TimeSavers": {
"DisableTitleCard": 1,
"SkipChildStealth": 1,
@@ -15,6 +15,9 @@
"DynamicWalletIcon": 1,
"EnemySpawnsOverWaterboxes": 1,
"FasterRupeeAccumulator": 1,
"FileSelect": {
"TimeFlow": 1
},
"FixBrokenGiantsKnife": 1,
"FixDampeGoingBackwards": 1,
"FixDaruniaDanceSpeed": 1,
@@ -45,7 +48,6 @@
"SkipSaveConfirmation": 1,
"SkipText": 1,
"TextSpeed": 5,
"TimeFlowFileSelect": 1,
"TimeSavers": {
"SkipJabuJabuFish": 1
},
@@ -757,7 +757,7 @@ static void DrawMoreInfo(FileChooseContext* thisx, s16 fileIndex, u8 alpha) {
}
#define CVAR_FILE_SELECT_MORE_INFO_DEFAULT false
#define CVAR_FILE_SELECT_MORE_INFO_NAME CVAR_ENHANCEMENT("FileSelectMoreInfo")
#define CVAR_FILE_SELECT_MORE_INFO_NAME CVAR_ENHANCEMENT("FileSelect.MoreInfo")
#define CVAR_FILE_SELECT_MORE_INFO_VALUE \
CVarGetInteger(CVAR_FILE_SELECT_MORE_INFO_NAME, CVAR_FILE_SELECT_MORE_INFO_DEFAULT)
@@ -8,7 +8,7 @@ extern "C" {
extern "C" SaveContext gSaveContext;
static constexpr int32_t CVAR_TIMEFLOWFILESELECT_DEFAULT = 0;
#define CVAR_TIMEFLOWFILESELECT_NAME CVAR_ENHANCEMENT("TimeFlowFileSelect")
#define CVAR_TIMEFLOWFILESELECT_NAME CVAR_ENHANCEMENT("FileSelect.TimeFlow")
#define CVAR_TIMEFLOWFILESELECT_VALUE CVarGetInteger(CVAR_TIMEFLOWFILESELECT_NAME, CVAR_TIMEFLOWFILESELECT_DEFAULT)
void OnFileChooseMainTimeFlowFileSelect(void* gameState) {
+87 -7
View File
@@ -10,6 +10,7 @@
#include "soh/Enhancements/Restorations/GetItemManipulation.h"
#include "soh/Enhancements/randomizer/SeedContext.h"
#include <ship/Context.h>
#include <soh/ResourceManagerHelpers.h>
extern "C" {
#include "functions.h"
@@ -174,6 +175,28 @@ static const std::map<int32_t, const char*> mirroredWorldModes = {
{ MIRRORED_WORLD_DUNGEONS_RANDOM_SEEDED, "Dungeons Random (Seeded)" },
};
static uint8_t CountVisibleFileSelectQuests() {
uint8_t count = 0;
if (ResourceMgr_GameHasOriginal() && !CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideNormalQuest"), 0)) {
count++;
}
if (ResourceMgr_GameHasMasterQuest() && !CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideMasterQuest"), 0)) {
count++;
}
if (!CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideRandomizerQuest"), 0)) {
count++;
}
if (!CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideBossRushQuest"), 0)) {
count++;
}
return count;
}
void SohMenu::AddMenuEnhancements() {
// Add Enhancements Menu
AddMenuEntry("Enhancements", CVAR_SETTING("Menu.EnhancementsSidebarSection"));
@@ -758,22 +781,79 @@ void SohMenu::AddMenuEnhancements() {
.CVar(CVAR_ENHANCEMENT("AlwaysShowDungeonMinimapIcon"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("Always shows dungeon entrance icons on the Minimap."));
AddWidget(path, "More Info in File Select", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelectMoreInfo"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip(
"Shows what items you have collected in the File Select screen, like in N64 Randomizer."));
AddWidget(path, "Better Ammo Rendering in Pause Menu", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("BetterAmmoRendering"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip(
"Ammo counts in the pause menu will work correctly regardless of the position of items in the Inventory."));
AddWidget(path, "Enable Passage of Time on File Select", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("TimeFlowFileSelect"))
AddWidget(path, "File Select", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "More Info", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelect.MoreInfo"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip(
"Shows what items you have collected in the File Select screen, like in N64 Randomizer."));
AddWidget(path, "Enable Passage of Time", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelect.TimeFlow"))
.RaceDisable(false)
.Options(CheckboxOptions().Tooltip("The skybox in the background of the File Select screen will go through the "
"day and night cycle over time."));
AddWidget(path, "Hide Original", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelect.HideNormalQuest"))
.RaceDisable(false)
.PreFunc([](const WidgetInfo& info) {
if (!ResourceMgr_GameHasOriginal()) {
info.options->disabled = true;
info.options->disabledTooltip = "This option requires a loaded original O2R.";
} else if (CountVisibleFileSelectQuests() <= 1 &&
!CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideNormalQuest"), 0)) {
info.options->disabled = true;
info.options->disabledTooltip = "At least one quest type must remain visible.";
}
})
.Options(CheckboxOptions().Tooltip(
"Hides the original game when selecting a quest type on the File Select screen."));
AddWidget(path, "Hide Master Quest", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelect.HideMasterQuest"))
.RaceDisable(false)
.PreFunc([](const WidgetInfo& info) {
if (!ResourceMgr_GameHasMasterQuest()) {
info.options->disabled = true;
info.options->disabledTooltip = "This option requires a loaded Master Quest O2R.";
} else if (CountVisibleFileSelectQuests() <= 1 &&
!CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideMasterQuest"), 0)) {
info.options->disabled = true;
info.options->disabledTooltip = "At least one quest type must remain visible.";
}
})
.Options(CheckboxOptions().Tooltip(
"Hides the Master Quest option when selecting a quest type on the File Select screen."));
AddWidget(path, "Hide Randomizer", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelect.HideRandomizerQuest"))
.RaceDisable(false)
.PreFunc([](const WidgetInfo& info) {
if (CountVisibleFileSelectQuests() <= 1 &&
!CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideRandomizerQuest"), 0)) {
info.options->disabled = true;
info.options->disabledTooltip = "At least one quest type must remain visible.";
}
})
.Options(CheckboxOptions().Tooltip(
"Hides the Randomizer option when selecting a quest type on the File Select screen."));
AddWidget(path, "Hide Boss Rush", WIDGET_CVAR_CHECKBOX)
.CVar(CVAR_ENHANCEMENT("FileSelect.HideBossRushQuest"))
.RaceDisable(false)
.PreFunc([](const WidgetInfo& info) {
if (CountVisibleFileSelectQuests() <= 1 &&
!CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideBossRushQuest"), 0)) {
info.options->disabled = true;
info.options->disabledTooltip = "At least one quest type must remain visible.";
}
})
.Options(CheckboxOptions().Tooltip(
"Hides the Boss Rush option when selecting a quest type on the File Select screen."));
path.column = SECTION_COLUMN_3;
AddWidget(path, "Misc.", WIDGET_SEPARATOR_TEXT);
AddWidget(path, "N64 Mode", WIDGET_CVAR_CHECKBOX)
+2
View File
@@ -1449,6 +1449,8 @@ static const Migration version6Migrations[] = {
};
static const Migration version7Migrations[] = {
{ "gEnhancements.FileSelectMoreInfo", "gEnhancements.FileSelect.MoreInfo" },
{ "gEnhancements.TimeFlowFileSelect", "gEnhancements.FileSelect.TimeFlow" },
{ "gRandoSettings.LacsStoneCount", "gRandoSettings.GbkStoneCount" },
{ "gRandoSettings.LacsMedallionCount", "gRandoSettings.GbkMedallionCount" },
{ "gRandoSettings.LacsRewardCount", "gRandoSettings.GbkRewardCount" },
@@ -20,6 +20,7 @@
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#include <assert.h>
#include "z64save.h"
#include "variables.h"
#include "soh/SaveManager.h"
#include "soh/OTRGlobals.h"
#include "soh/ResourceManagerHelpers.h"
@@ -28,6 +29,35 @@
#define MIN_QUEST (ResourceMgr_GameHasOriginal() ? QUEST_NORMAL : QUEST_MASTER)
#define MAX_QUEST QUEST_BOSSRUSH
// #region SOH [Enhancement] - Hide Quest Modes
static bool IsQuestSkipped(uint8_t quest) {
switch (quest) {
case QUEST_NORMAL:
return !ResourceMgr_GameHasOriginal() || CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideNormalQuest"), 0);
case QUEST_MASTER:
return !ResourceMgr_GameHasMasterQuest() ||
CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideMasterQuest"), 0);
case QUEST_RANDOMIZER:
return CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideRandomizerQuest"), 0);
case QUEST_BOSSRUSH:
return CVarGetInteger(CVAR_ENHANCEMENT("FileSelect.HideBossRushQuest"), 0);
default:
return false;
}
}
static uint8_t CountVisibleQuests(void) {
uint8_t count = 0;
for (int32_t quest = MIN_QUEST; quest <= MAX_QUEST; ++quest) {
if (!IsQuestSkipped(quest)) {
count++;
}
}
return count;
}
// #endregion
void Sram_InitDebugSave(void);
void Sram_InitBossRushSave();
@@ -420,9 +450,17 @@ static s16 sLastFileChooseButtonIndex;
* Update function for `CM_MAIN_MENU`
*/
void FileChoose_UpdateMainMenu(GameState* thisx) {
static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E };
static u8 emptyNameNES[] = { 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF };
static u8 linkName[] = { 0x15, 0x2C, 0x31, 0x2E, 0x3E, 0x3E, 0x3E, 0x3E };
static u8 linkNameNES[] = { 0xB6, 0xCD, 0xD2, 0xCF, 0xDF, 0xDF, 0xDF, 0xDF };
static u8 linkNameJP[] = { 0x81, 0x87, 0x61, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF };
FileChooseContext* this = (FileChooseContext*)thisx;
Input* input = &this->state.input[0];
bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0);
u8* defaultName;
u8 isDefaultNameOptionSet;
FileChoose_UpdateRandomizer();
@@ -434,6 +472,32 @@ void FileChoose_UpdateMainMenu(GameState* thisx) {
this->prevConfigMode = this->configMode;
this->configMode = CM_ROTATE_TO_QUEST_MENU;
this->logoAlpha = 0;
this->kbdButton = FS_KBD_BTN_NONE;
this->charPage = FS_CHAR_PAGE_ENG;
this->kbdX = 0;
this->kbdY = 0;
this->charIndex = 0;
this->charBgAlpha = 0;
isDefaultNameOptionSet = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0);
this->newFileNameCharCount = isDefaultNameOptionSet ? 4 : 0;
this->nameEntryBoxPosX = 120;
this->nameEntryBoxAlpha = 0;
if (gSaveContext.language == LANGUAGE_JPN) { // Japanese
if (isDefaultNameOptionSet) {
// Set player name to "リンク" ("Link" in Katakana, 3 characters long) when playing in Japanese.
defaultName = &linkNameJP;
this->newFileNameCharCount = 3;
} else {
defaultName = &emptyNameNES;
}
this->charPage = FS_CHAR_PAGE_HIRA; // Default to Hiragana Keyboard
} else if (ResourceMgr_GetGameRegion(0) == GAME_REGION_PAL) {
defaultName = isDefaultNameOptionSet ? &linkName : &emptyName;
} else { // GAME_REGION_NTSC
defaultName = isDefaultNameOptionSet ? &linkNameNES : &emptyNameNES;
}
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, defaultName, 8);
} else if (!FileChoose_IsSaveCompatible(Save_GetSaveMetaInfo(this->buttonIndex))) {
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
@@ -626,11 +690,6 @@ void FileChoose_StartRandomizerMenu(GameState* thisx) {
}
void FileChoose_UpdateQuestMenu(GameState* thisx) {
static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E };
static u8 emptyNameNES[] = { 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF };
static u8 linkName[] = { 0x15, 0x2C, 0x31, 0x2E, 0x3E, 0x3E, 0x3E, 0x3E };
static u8 linkNameNES[] = { 0xB6, 0xCD, 0xD2, 0xCF, 0xDF, 0xDF, 0xDF, 0xDF };
static u8 linkNameJP[] = { 0x81, 0x87, 0x61, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF };
FileChoose_UpdateStickDirectionPromptAnim(thisx);
FileChooseContext* this = (FileChooseContext*)thisx;
Input* input = &this->state.input[0];
@@ -640,27 +699,40 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
FileChoose_UpdateRandomizer();
if (ABS(this->stickRelX) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) {
if (this->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) {
this->questType[this->buttonIndex] += 1;
while (this->questType[this->buttonIndex] == QUEST_MASTER && !ResourceMgr_GameHasMasterQuest()) {
// If Master Quest is selected without a Master Quest OTR present, skip past it.
this->questType[this->buttonIndex] += 1;
}
} else if (this->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) {
this->questType[this->buttonIndex] -= 1;
while (this->questType[this->buttonIndex] == QUEST_MASTER && !ResourceMgr_GameHasMasterQuest()) {
// If Master Quest is selected without a Master Quest OTR present, skip past it.
this->questType[this->buttonIndex] -= 1;
// #region SOH [Enhancement] - Hide Quest Modes
// If the current quest type was hidden after being selected (i.e., CVar changed while on the quest menu), advance
// to the next visible one.
if (CountVisibleQuests() > 0) {
while (IsQuestSkipped(this->questType[this->buttonIndex])) {
this->questType[this->buttonIndex]++;
if (this->questType[this->buttonIndex] > MAX_QUEST) {
this->questType[this->buttonIndex] = MIN_QUEST;
}
}
}
// #endregion
// If current buttonIndex is higher or lower than the min/max value, wrap around.
if (this->questType[this->buttonIndex] > MAX_QUEST) {
this->questType[this->buttonIndex] = MIN_QUEST;
} else if (this->questType[this->buttonIndex] < MIN_QUEST) {
this->questType[this->buttonIndex] = MAX_QUEST;
// #region SOH [Enhancement] - Hide Quest Modes
if (CountVisibleQuests() > 1 && ABS(this->stickRelX) > 30 ||
(dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT | BTN_DRIGHT))) {
// Cycle through quest types, skipping any that are hidden (i.e., Master Quest without O2R,
// Randomizer/Boss Rush when their CVars are set). Wraps around if past min/max.
if (this->stickRelX > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DRIGHT))) {
do {
this->questType[this->buttonIndex]++;
if (this->questType[this->buttonIndex] > MAX_QUEST) {
this->questType[this->buttonIndex] = MIN_QUEST;
}
} while (IsQuestSkipped(this->questType[this->buttonIndex]));
} else if (this->stickRelX < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DLEFT))) {
do {
this->questType[this->buttonIndex]--;
if (this->questType[this->buttonIndex] < MIN_QUEST) {
this->questType[this->buttonIndex] = MAX_QUEST;
}
} while (IsQuestSkipped(this->questType[this->buttonIndex]));
}
// #endregion
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
@@ -689,30 +761,6 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) {
this->prevConfigMode = this->configMode;
this->configMode = CM_ROTATE_TO_NAME_ENTRY;
this->logoAlpha = 0;
this->kbdButton = FS_KBD_BTN_NONE;
this->charPage = FS_CHAR_PAGE_ENG;
this->kbdX = 0;
this->kbdY = 0;
this->charIndex = 0;
this->charBgAlpha = 0;
this->newFileNameCharCount = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? 4 : 0;
this->nameEntryBoxPosX = 120;
this->nameEntryBoxAlpha = 0;
if (ResourceMgr_GetGameRegion(0) == GAME_REGION_PAL && gSaveContext.language != LANGUAGE_JPN) {
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkName : &emptyName;
} else if (gSaveContext.language == LANGUAGE_JPN) { // Japanese
if (CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) != 0) {
// Set player name to "リンク" ("Link" in Katakana, 3 characters long) when playing in Japanese.
defaultName = &linkNameJP;
this->newFileNameCharCount = 3;
} else {
defaultName = &emptyNameNES;
}
this->charPage = FS_CHAR_PAGE_HIRA; // Default to Hiragana Keyboard
} else { // GAME_REGION_NTSC
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
}
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, defaultName, 8);
return;
}
}
@@ -779,41 +827,10 @@ void FileChoose_UpdateRandomizerMenu(GameState* thisx) {
SohFileSelect_ShowPresetModal();
Audio_PlaySfxGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
static u8 emptyName[] = { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E };
static u8 emptyNameNES[] = { 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF };
static u8 linkName[] = { 0x15, 0x2C, 0x31, 0x2E, 0x3E, 0x3E, 0x3E, 0x3E };
static u8 linkNameNES[] = { 0xB6, 0xCD, 0xD2, 0xCF, 0xDF, 0xDF, 0xDF, 0xDF };
static u8 linkNameJP[] = { 0x81, 0x87, 0x61, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF };
u8* defaultName;
this->prevConfigMode = this->configMode;
this->configMode = CM_ROTATE_TO_NAME_ENTRY;
this->logoAlpha = 0;
CVarSetInteger(CVAR_GENERAL("OnFileSelectNameEntry"), 1);
this->kbdButton = FS_KBD_BTN_NONE;
this->charPage = FS_CHAR_PAGE_ENG;
this->kbdX = 0;
this->kbdY = 0;
this->charIndex = 0;
this->charBgAlpha = 0;
this->newFileNameCharCount = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? 4 : 0;
this->nameEntryBoxPosX = 120;
this->nameEntryBoxAlpha = 0;
if (ResourceMgr_GetGameRegion(0) == GAME_REGION_PAL && gSaveContext.language != LANGUAGE_JPN) {
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkName : &emptyName;
} else if (gSaveContext.language == LANGUAGE_JPN) { // Japanese
if (CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) != 0) {
// Set player name to "リンク" ("Link" in Katakana, 3 characters long) when playing in Japanese.
defaultName = &linkNameJP;
this->newFileNameCharCount = 3;
} else {
defaultName = &emptyNameNES;
}
this->charPage = FS_CHAR_PAGE_HIRA; // Default to Hiragana Keyboard
} else { // GAME_REGION_NTSC
defaultName = CVarGetInteger(CVAR_ENHANCEMENT("LinkDefaultName"), 0) ? &linkNameNES : &emptyNameNES;
}
memcpy(Save_GetSaveMetaInfo(this->buttonIndex)->playerName, defaultName, 8);
} else {
Sfx_PlaySfxCentered(NA_SE_SY_OCARINA_ERROR);
}
@@ -895,20 +912,13 @@ void FileChoose_RotateToMain(GameState* thisx) {
FileChooseContext* this = (FileChooseContext*)thisx;
if (this->configMode == CM_QUEST_TO_MAIN || this->configMode == CM_OPTIONS_TO_MAIN) {
this->windowRot -= VREG(16);
if (this->windowRot <= 0.0f) {
this->windowRot = 0.0f;
this->configMode = CM_MAIN_MENU;
}
} else if (this->configMode == CM_NAME_ENTRY_TO_MAIN) {
this->windowRot += VREG(16);
}
if (this->configMode == CM_NAME_ENTRY_TO_MAIN && this->prevConfigMode == CM_MAIN_MENU) {
this->windowRot += VREG(16);
if (this->windowRot >= 942.0f) {
this->windowRot = 0.0f;
this->configMode = CM_MAIN_MENU;
}
if (this->windowRot <= 0.0f || this->windowRot >= 942.0f) {
this->windowRot = 0.0f;
this->configMode = CM_MAIN_MENU;
}
}
@@ -920,15 +930,35 @@ void FileChoose_RotateToQuest(GameState* thisx) {
this->windowRot -= VREG(16);
if (this->windowRot <= 314.0f) {
this->windowRot = 314.0f;
this->configMode = CM_START_QUEST_MENU;
if (CountVisibleQuests() > 1) {
this->windowRot = 314.0f;
this->configMode = CM_START_QUEST_MENU;
} else {
this->windowRot = 0.0f;
this->configMode = CM_MAIN_MENU;
}
}
} else {
this->windowRot += VREG(16);
if (this->windowRot >= 314.0f) {
this->windowRot = 314.0f;
this->configMode = CM_START_QUEST_MENU;
if (CountVisibleQuests() > 1) {
this->windowRot = 314.0f;
this->configMode = CM_START_QUEST_MENU;
} else {
this->windowRot = 628.0f;
if (!IsQuestSkipped(QUEST_RANDOMIZER)) {
this->configMode = CM_START_RANDOMIZER_SETTINGS_MENU;
} else if (!IsQuestSkipped(QUEST_BOSSRUSH)) {
this->configMode = CM_START_BOSS_RUSH_MENU;
} else {
this->configMode = CM_START_NAME_ENTRY;
// Needed to come back to main menu
this->prevConfigMode = CM_MAIN_MENU;
}
}
}
}
}
@@ -1718,31 +1748,37 @@ void FileChoose_DrawWindowContents(GameState* thisx) {
if ((this->configMode == CM_QUEST_MENU) || (this->configMode == CM_START_QUEST_MENU) ||
this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU ||
this->configMode == CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) {
// draw control stick prompts.
Gfx_SetupDL_39Opa(this->state.gfxCtx);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.arrowColorR, this->stickLeftPrompt.arrowColorG,
this->stickLeftPrompt.arrowColorB, this->stickLeftPrompt.arrowColorA,
this->stickLeftPrompt.arrowTexX, this->stickLeftPrompt.arrowTexY,
this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR,
this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB,
this->stickRightPrompt.arrowColorA, this->stickRightPrompt.arrowTexX,
this->stickRightPrompt.arrowTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f);
gDPLoadTextureBlock(POLY_OPA_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.stickColorR, this->stickLeftPrompt.stickColorG,
this->stickLeftPrompt.stickColorB, this->stickLeftPrompt.stickColorA,
this->stickLeftPrompt.stickTexX, this->stickLeftPrompt.stickTexY,
this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.stickColorR,
this->stickRightPrompt.stickColorG, this->stickRightPrompt.stickColorB,
this->stickRightPrompt.stickColorA, this->stickRightPrompt.stickTexX,
this->stickRightPrompt.stickTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f);
// #region SOH [Enhancement] - Hide Quest Modes
// Only draw the control stick prompts and arrows when there's more than one quest to cycle through.
if (CountVisibleQuests() > 1) {
// #endregion
// draw control stick prompts.
Gfx_SetupDL_39Opa(this->state.gfxCtx);
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.arrowColorR,
this->stickLeftPrompt.arrowColorG, this->stickLeftPrompt.arrowColorB,
this->stickLeftPrompt.arrowColorA, this->stickLeftPrompt.arrowTexX,
this->stickLeftPrompt.arrowTexY, this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR,
this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB,
this->stickRightPrompt.arrowColorA, this->stickRightPrompt.arrowTexX,
this->stickRightPrompt.arrowTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f);
gDPLoadTextureBlock(POLY_OPA_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0,
G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD,
G_TX_NOLOD);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickLeftPrompt.stickColorR,
this->stickLeftPrompt.stickColorG, this->stickLeftPrompt.stickColorB,
this->stickLeftPrompt.stickColorA, this->stickLeftPrompt.stickTexX,
this->stickLeftPrompt.stickTexY, this->stickLeftPrompt.z, 0, 0, -1.0f, 1.0f);
FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.stickColorR,
this->stickRightPrompt.stickColorG, this->stickRightPrompt.stickColorB,
this->stickRightPrompt.stickColorA, this->stickRightPrompt.stickTexX,
this->stickRightPrompt.stickTexY, this->stickRightPrompt.z, 0, 0, 1.0f, 1.0f);
}
switch (this->questType[this->buttonIndex]) {
case QUEST_NORMAL:
default: