mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-08-12 12:18:32 -04:00
Better Save Menu: Ability to Reset to Spawn from anywhere (#6937)
Adds an option for a Better Save Menu that, after saving, allows you to effectively soft-reset the current save (either return to spawn or reset to the dungeon entrance), and additionally lets you reset to spawn specifcally, even if you are in a dungeon. This allows for escaping from the rare entrance-rando related softlock that can happen.
This commit is contained in:
committed by
GitHub
parent
29d4ff4205
commit
8cb0c74592
@@ -0,0 +1,220 @@
|
||||
#include "soh/Enhancements/custom-message/CustomMessageManager.h"
|
||||
#include "soh/Enhancements/custom-message/CustomMessageTypes.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
#include "soh/Enhancements/randomizer/randomizer_entrance.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern PlayState* gPlayState;
|
||||
#include "functions.h"
|
||||
#include "macros.h"
|
||||
#include "variables.h"
|
||||
#include "z64scene.h"
|
||||
}
|
||||
|
||||
#define CVAR_BETTERSAVE CVAR_ENHANCEMENT("BetterSaveMenu")
|
||||
#define CVAR_BETTERSAVE_DEFAULT 0
|
||||
#define CVAR_BETTERSAVE_VALUE CVarGetInteger(CVAR_BETTERSAVE, CVAR_BETTERSAVE_DEFAULT)
|
||||
static CustomMessage saveMsg = CustomMessage(
|
||||
"\x08Would you like to save?&&" + CustomMessage::TWO_WAY_CHOICE() + "%gYes&No%w\x09", TEXTBOX_TYPE_BLUE);
|
||||
static CustomMessage continueOverworldMsg = CustomMessage(
|
||||
"\x08 Continue?&&" + CustomMessage::TWO_WAY_CHOICE() + "%gContinue&Return to Spawn%w\x09", TEXTBOX_TYPE_BLUE);
|
||||
static CustomMessage continueDungeonMsg =
|
||||
CustomMessage("\x08 Continue?&" + CustomMessage::THREE_WAY_CHOICE() + "%gContinue&Restart&Return to Spawn%w\x09",
|
||||
TEXTBOX_TYPE_BLUE);
|
||||
|
||||
extern "C" uint8_t Randomizer_GetSettingValue(RandomizerSettingKey randoSettingKey);
|
||||
|
||||
bool IsSceneDungeon(int16_t scene) {
|
||||
switch (scene) {
|
||||
case SCENE_DEKU_TREE:
|
||||
case SCENE_DEKU_TREE_BOSS:
|
||||
case SCENE_DODONGOS_CAVERN:
|
||||
case SCENE_DODONGOS_CAVERN_BOSS:
|
||||
case SCENE_JABU_JABU:
|
||||
case SCENE_JABU_JABU_BOSS:
|
||||
case SCENE_FOREST_TEMPLE:
|
||||
case SCENE_FOREST_TEMPLE_BOSS:
|
||||
case SCENE_FIRE_TEMPLE:
|
||||
case SCENE_FIRE_TEMPLE_BOSS:
|
||||
case SCENE_WATER_TEMPLE:
|
||||
case SCENE_WATER_TEMPLE_BOSS:
|
||||
case SCENE_SPIRIT_TEMPLE:
|
||||
case SCENE_SPIRIT_TEMPLE_BOSS:
|
||||
case SCENE_SHADOW_TEMPLE:
|
||||
case SCENE_SHADOW_TEMPLE_BOSS:
|
||||
case SCENE_BOTTOM_OF_THE_WELL:
|
||||
case SCENE_GERUDO_TRAINING_GROUND:
|
||||
case SCENE_ICE_CAVERN:
|
||||
case SCENE_INSIDE_GANONS_CASTLE:
|
||||
case SCENE_GANONS_TOWER:
|
||||
case SCENE_GANONS_TOWER_COLLAPSE_EXTERIOR:
|
||||
case SCENE_GANONS_TOWER_COLLAPSE_INTERIOR:
|
||||
case SCENE_GANONDORF_BOSS:
|
||||
case SCENE_GANON_BOSS:
|
||||
case SCENE_INSIDE_GANONS_CASTLE_COLLAPSE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSaveMenu(bool* should, PlayState* play) {
|
||||
PauseContext* pauseCtx = &play->pauseCtx;
|
||||
InterfaceContext* interfaceCtx = &play->interfaceCtx;
|
||||
switch (pauseCtx->unk_1EC) {
|
||||
case 0:
|
||||
*should = false;
|
||||
Message_StartTextbox(play, TEXT_SAVE_MSG, NULL);
|
||||
pauseCtx->unk_1EC = 1;
|
||||
break;
|
||||
case 1:
|
||||
*should = false;
|
||||
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(play)) {
|
||||
if (play->msgCtx.choiceIndex == 0) {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Play_PerformSave(play);
|
||||
pauseCtx->unk_1EC = 4;
|
||||
if (IsSceneDungeon(gSaveContext.savedSceneNum)) {
|
||||
Message_StartTextbox(play, TEXT_CONTINUE_DUNGEON_MSG, NULL);
|
||||
} else {
|
||||
Message_StartTextbox(play, TEXT_CONTINUE_OVERWORLD_MSG, NULL);
|
||||
}
|
||||
} else {
|
||||
Interface_SetDoAction(play, DO_ACTION_NONE);
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
|
||||
gSaveContext.buttonStatus[3] = BTN_ENABLED;
|
||||
gSaveContext.buttonStatus[5] = gSaveContext.buttonStatus[6] = gSaveContext.buttonStatus[7] =
|
||||
gSaveContext.buttonStatus[8] = BTN_ENABLED;
|
||||
gSaveContext.hudVisibilityMode = 0;
|
||||
Interface_ChangeHudVisibilityMode(50);
|
||||
pauseCtx->unk_1EC = 2;
|
||||
WREG(2) = -6240;
|
||||
YREG(8) = static_cast<int16_t>(pauseCtx->unk_204);
|
||||
func_800F64E0(0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
*should = false;
|
||||
if (Message_GetState(&play->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(play)) {
|
||||
switch (play->msgCtx.choiceIndex) {
|
||||
case 0:
|
||||
// Continue
|
||||
Interface_SetDoAction(play, DO_ACTION_NONE);
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
|
||||
gSaveContext.buttonStatus[3] = BTN_ENABLED;
|
||||
gSaveContext.buttonStatus[5] = gSaveContext.buttonStatus[6] = gSaveContext.buttonStatus[7] =
|
||||
gSaveContext.buttonStatus[8] = BTN_ENABLED;
|
||||
gSaveContext.hudVisibilityMode = 0;
|
||||
Interface_ChangeHudVisibilityMode(50);
|
||||
pauseCtx->unk_1EC = 5;
|
||||
WREG(2) = -6240;
|
||||
YREG(8) = static_cast<int16_t>(pauseCtx->unk_204);
|
||||
func_800F64E0(0);
|
||||
break;
|
||||
case 1:
|
||||
// Reset (Dungeon) / Return to Spawn (Overworld)
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Play_SaveSceneFlags(play);
|
||||
Sram_OpenSave();
|
||||
if (!IsSceneDungeon(gSaveContext.savedSceneNum)) {
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS)) {
|
||||
if (LINK_AGE_IN_YEARS == YEARS_ADULT) {
|
||||
gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_10;
|
||||
}
|
||||
gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex);
|
||||
}
|
||||
}
|
||||
pauseCtx->promptChoice = 0;
|
||||
pauseCtx->unk_1EC = 7;
|
||||
break;
|
||||
case 2:
|
||||
// Reset to Spawn (Dungeon)
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb);
|
||||
Play_SaveSceneFlags(play);
|
||||
Sram_OpenSave();
|
||||
gSaveContext.entranceIndex = (LINK_AGE_IN_YEARS == YEARS_CHILD) ? ENTR_LINKS_HOUSE_CHILD_SPAWN
|
||||
: ENTR_TEMPLE_OF_TIME_WARP_PAD;
|
||||
if (IS_RANDO && Randomizer_GetSettingValue(RSK_SHUFFLE_OVERWORLD_SPAWNS)) {
|
||||
if (LINK_AGE_IN_YEARS == YEARS_ADULT) {
|
||||
gSaveContext.entranceIndex = ENTR_HYRULE_FIELD_10;
|
||||
}
|
||||
gSaveContext.entranceIndex = Entrance_OverrideNextIndex(gSaveContext.entranceIndex);
|
||||
}
|
||||
pauseCtx->promptChoice = 0;
|
||||
pauseCtx->unk_1EC = 7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (interfaceCtx->unk_244 != 255) {
|
||||
interfaceCtx->unk_244 += 10;
|
||||
if (interfaceCtx->unk_244 >= 255) {
|
||||
interfaceCtx->unk_244 = 255;
|
||||
pauseCtx->state = 0;
|
||||
R_UPDATE_RATE = 3;
|
||||
R_PAUSE_MENU_MODE = 0;
|
||||
func_800981B8(&play->objectCtx);
|
||||
func_800418D0(&play->colCtx, play);
|
||||
// Reset frame counter to prevent autosave on respawn
|
||||
play->gameplayFrames = 0;
|
||||
gSaveContext.nextTransitionType = TRANS_TYPE_FADE_BLACK;
|
||||
gSaveContext.health = CVarGetInteger(CVAR_ENHANCEMENT("FullHealthSpawn"), 0)
|
||||
? gSaveContext.healthCapacity
|
||||
: STARTING_HEALTH;
|
||||
Audio_QueueSeqCmd(0xF << 28 | SEQ_PLAYER_BGM_MAIN << 24 | 0xA);
|
||||
gSaveContext.healthAccumulator = 0;
|
||||
gSaveContext.magicState = MAGIC_STATE_IDLE;
|
||||
gSaveContext.prevMagicState = MAGIC_STATE_IDLE;
|
||||
gSaveContext.magicCapacity = 0;
|
||||
gSaveContext.magicFillTarget = gSaveContext.magic;
|
||||
gSaveContext.magicLevel = gSaveContext.magic = 0;
|
||||
play->state.running = false;
|
||||
SET_NEXT_GAMESTATE(&play->state, Play_Init, PlayState);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
*should = true;
|
||||
}
|
||||
Message_Update(play);
|
||||
}
|
||||
|
||||
void RegisterBetterSave() {
|
||||
saveMsg.Format();
|
||||
continueOverworldMsg.Format();
|
||||
continueDungeonMsg.Format();
|
||||
|
||||
REGISTER_VB_SHOULD(VB_LOAD_SAVE_MENU, {
|
||||
PlayState* play = va_arg(args, PlayState*);
|
||||
HandleSaveMenu(should, play);
|
||||
});
|
||||
|
||||
REGISTER_VB_SHOULD(VB_DRAW_SAVE_MENU, { *should = false; });
|
||||
|
||||
COND_ID_HOOK(OnOpenText, TEXT_SAVE_MSG, true, [](uint16_t* textId, bool* loadFromMessageTable) {
|
||||
saveMsg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
});
|
||||
|
||||
COND_ID_HOOK(OnOpenText, TEXT_CONTINUE_DUNGEON_MSG, true, [](uint16_t* textId, bool* loadFromMessageTable) {
|
||||
continueDungeonMsg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
});
|
||||
|
||||
COND_ID_HOOK(OnOpenText, TEXT_CONTINUE_OVERWORLD_MSG, true, [](uint16_t* textId, bool* loadFromMessageTable) {
|
||||
continueOverworldMsg.LoadIntoFont();
|
||||
*loadFromMessageTable = false;
|
||||
return;
|
||||
});
|
||||
}
|
||||
|
||||
static RegisterShipInitFunc initFunc(RegisterBetterSave, { CVAR_BETTERSAVE });
|
||||
@@ -806,6 +806,10 @@ std::string CustomMessage::TWO_WAY_CHOICE() {
|
||||
return "\x1B"s;
|
||||
}
|
||||
|
||||
std::string CustomMessage::THREE_WAY_CHOICE() {
|
||||
return "\x1C"s;
|
||||
}
|
||||
|
||||
bool CustomMessageManager::InsertCustomMessage(const std::string& tableID, uint16_t textID, CustomMessage messages) {
|
||||
auto foundMessageTable = messageTables.find(tableID);
|
||||
if (foundMessageTable == messageTables.end()) {
|
||||
|
||||
@@ -62,6 +62,7 @@ class CustomMessage {
|
||||
static std::string WAIT_FOR_INPUT();
|
||||
static std::string PLAYER_NAME();
|
||||
static std::string TWO_WAY_CHOICE();
|
||||
static std::string THREE_WAY_CHOICE();
|
||||
|
||||
const std::string GetEnglish(MessageFormat format = MF_FORMATTED) const;
|
||||
const std::string GetFrench(MessageFormat format = MF_FORMATTED) const;
|
||||
|
||||
@@ -240,6 +240,9 @@ typedef enum {
|
||||
TEXT_SHOOTING_GALLERY_MAN_COME_BACK_WITH_BOW = 0x9210,
|
||||
TEXT_CARPET_SALESMAN_MYSTERIOUS = 0x9211,
|
||||
TEXT_CARPET_SALESMAN_ARMS_DEALER = 0x9212,
|
||||
TEXT_SAVE_MSG = 0x9213,
|
||||
TEXT_CONTINUE_OVERWORLD_MSG = 0x9214,
|
||||
TEXT_CONTINUE_DUNGEON_MSG = 0x9215,
|
||||
} TextIDs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -3387,6 +3387,26 @@ typedef enum {
|
||||
// #### `args`
|
||||
// - None
|
||||
VB_TEMP_B_RESTORE_SWORDLESS,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// true
|
||||
// // ```
|
||||
// Hook to override the save menu for a message box allowing you to
|
||||
// Continue, Reset, and Reset to Spawn after saving (only from the pause menu, not the
|
||||
// game over screen).
|
||||
// #### `args`
|
||||
// - `*PlayState`
|
||||
VB_LOAD_SAVE_MENU,
|
||||
|
||||
// #### `result`
|
||||
// ```c
|
||||
// pauseCtx->state == 7
|
||||
// ```
|
||||
// Hook to override the drawing/loading textures for the save menu so that
|
||||
// a textbox can be rendered instead. Pause screen only, Game Over version left
|
||||
// intact.
|
||||
VB_DRAW_SAVE_MENU,
|
||||
} GIVanillaBehavior;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -180,6 +180,12 @@ void SohMenu::AddMenuEnhancements() {
|
||||
"When loading a save, places Link at the last entrance he went through.\n"
|
||||
"This doesn't work if the save was made in grottos, fairy fountains, or dungeons."));
|
||||
|
||||
AddWidget(path, "Better Save Menu", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("BetterSaveMenu"))
|
||||
.Options(CheckboxOptions().Tooltip(
|
||||
"Replaces the authentic save menu with a textbox that asks Yes or No for saving,\n"
|
||||
"then asks if you want to Continue, Reset, or Reset to Spawn."));
|
||||
|
||||
AddWidget(path, "Containers Match Contents", WIDGET_SEPARATOR_TEXT);
|
||||
AddWidget(path, "Containers Match Contents", WIDGET_CVAR_CHECKBOX)
|
||||
.CVar(CVAR_ENHANCEMENT("ChestSizeAndTextureMatchContents"))
|
||||
|
||||
@@ -1764,7 +1764,8 @@ void KaleidoScope_DrawPages(PlayState* play, GraphicsContext* gfxCtx) {
|
||||
|
||||
Gfx_SetupDL_42Opa(gfxCtx);
|
||||
|
||||
if ((pauseCtx->state == 7) || ((pauseCtx->state >= 8) && (pauseCtx->state < 0x12))) {
|
||||
if ((GameInteractor_Should(VB_DRAW_SAVE_MENU, pauseCtx->state == 7, pauseCtx)) ||
|
||||
((pauseCtx->state >= 8) && (pauseCtx->state < 0x12))) {
|
||||
KaleidoScope_UpdatePrompt(play);
|
||||
|
||||
gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA, G_CC_MODULATEIA);
|
||||
@@ -4397,20 +4398,61 @@ void KaleidoScope_Update(PlayState* play) {
|
||||
break;
|
||||
|
||||
case 7:
|
||||
switch (pauseCtx->unk_1EC) {
|
||||
case 0:
|
||||
pauseCtx->unk_204 -= 314.0f / WREG(6);
|
||||
WREG(16) -= WREG(25) / WREG(6);
|
||||
WREG(17) -= WREG(26) / WREG(6);
|
||||
if (pauseCtx->unk_204 <= -628.0f) {
|
||||
pauseCtx->unk_204 = -628.0f;
|
||||
pauseCtx->unk_1EC = 1;
|
||||
}
|
||||
break;
|
||||
if (GameInteractor_Should(VB_LOAD_SAVE_MENU, 1, play)) {
|
||||
switch (pauseCtx->unk_1EC) {
|
||||
case 0:
|
||||
pauseCtx->unk_204 -= 314.0f / WREG(6);
|
||||
WREG(16) -= WREG(25) / WREG(6);
|
||||
WREG(17) -= WREG(26) / WREG(6);
|
||||
if (pauseCtx->unk_204 <= -628.0f) {
|
||||
pauseCtx->unk_204 = -628.0f;
|
||||
pauseCtx->unk_1EC = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
if (pauseCtx->promptChoice != 0) {
|
||||
case 1:
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
|
||||
if (pauseCtx->promptChoice != 0) {
|
||||
Interface_SetDoAction(play, DO_ACTION_NONE);
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] =
|
||||
gSaveContext.buttonStatus[2] = gSaveContext.buttonStatus[3] = BTN_ENABLED;
|
||||
gSaveContext.buttonStatus[5] = gSaveContext.buttonStatus[6] =
|
||||
gSaveContext.buttonStatus[7] = gSaveContext.buttonStatus[8] = BTN_ENABLED;
|
||||
gSaveContext.hudVisibilityMode = 0;
|
||||
Interface_ChangeHudVisibilityMode(50);
|
||||
pauseCtx->unk_1EC = 2;
|
||||
WREG(2) = -6240;
|
||||
YREG(8) = pauseCtx->unk_204;
|
||||
func_800F64E0(0);
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
Play_PerformSave(play);
|
||||
pauseCtx->unk_1EC = 4;
|
||||
D_8082B25C = CVarGetInteger(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 0)
|
||||
? 3 /* 0.1 sec */
|
||||
: 90 /* 3 secs */;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_START) ||
|
||||
CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||
Interface_SetDoAction(play, DO_ACTION_NONE);
|
||||
pauseCtx->unk_1EC = 2;
|
||||
WREG(2) = -6240;
|
||||
YREG(8) = pauseCtx->unk_204;
|
||||
func_800F64E0(0);
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
|
||||
gSaveContext.buttonStatus[3] = BTN_ENABLED;
|
||||
gSaveContext.buttonStatus[5] = gSaveContext.buttonStatus[6] = gSaveContext.buttonStatus[7] =
|
||||
gSaveContext.buttonStatus[8] = BTN_ENABLED;
|
||||
gSaveContext.hudVisibilityMode = 0;
|
||||
Interface_ChangeHudVisibilityMode(50);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_B) || CHECK_BTN_ALL(input->press.button, BTN_A) ||
|
||||
CHECK_BTN_ALL(input->press.button, BTN_START) || (--D_8082B25C == 0)) {
|
||||
Interface_SetDoAction(play, DO_ACTION_NONE);
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
|
||||
gSaveContext.buttonStatus[3] = BTN_ENABLED;
|
||||
@@ -4418,88 +4460,50 @@ void KaleidoScope_Update(PlayState* play) {
|
||||
gSaveContext.buttonStatus[8] = BTN_ENABLED;
|
||||
gSaveContext.hudVisibilityMode = 0;
|
||||
Interface_ChangeHudVisibilityMode(50);
|
||||
pauseCtx->unk_1EC = 2;
|
||||
pauseCtx->unk_1EC = 5;
|
||||
WREG(2) = -6240;
|
||||
YREG(8) = pauseCtx->unk_204;
|
||||
func_800F64E0(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 6:
|
||||
pauseCtx->unk_204 += 314.0f / WREG(6);
|
||||
WREG(16) += WREG(25) / WREG(6);
|
||||
WREG(17) += WREG(26) / WREG(6);
|
||||
if (pauseCtx->unk_204 >= -314.0f) {
|
||||
pauseCtx->state = 6;
|
||||
pauseCtx->unk_1EC = 0;
|
||||
pauseCtx->unk_1F4 = pauseCtx->unk_1F8 = pauseCtx->unk_1FC = pauseCtx->unk_200 = 0.0f;
|
||||
pauseCtx->unk_204 = -314.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 5:
|
||||
if (pauseCtx->unk_204 != (YREG(8) + 160.0f)) {
|
||||
pauseCtx->unk_1F4 = pauseCtx->unk_1F8 = pauseCtx->unk_1FC = pauseCtx->unk_200 +=
|
||||
160.0f / WREG(6);
|
||||
pauseCtx->unk_204 += 160.0f / WREG(6);
|
||||
pauseCtx->infoPanelOffsetY -= 40 / WREG(6);
|
||||
WREG(16) -= WREG(25) / WREG(6);
|
||||
WREG(17) -= WREG(26) / WREG(6);
|
||||
XREG(5) -= 150 / WREG(6);
|
||||
pauseCtx->alpha -= (u16)(255 / WREG(6));
|
||||
if (pauseCtx->unk_204 == (YREG(8) + 160.0f)) {
|
||||
pauseCtx->alpha = 0;
|
||||
}
|
||||
} else {
|
||||
Audio_PlaySoundGeneral(NA_SE_SY_PIECE_OF_HEART, &gSfxDefaultPos, 4,
|
||||
&gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale,
|
||||
&gSfxDefaultReverb);
|
||||
Play_PerformSave(play);
|
||||
pauseCtx->unk_1EC = 4;
|
||||
D_8082B25C = CVarGetInteger(CVAR_ENHANCEMENT("SkipSaveConfirmation"), 0) ? 3 /* 0.1 sec */
|
||||
: 90 /* 3 secs */;
|
||||
pauseCtx->debugState = 0;
|
||||
pauseCtx->state = 0x13;
|
||||
pauseCtx->unk_1F4 = pauseCtx->unk_1F8 = pauseCtx->unk_1FC = pauseCtx->unk_200 = 160.0f;
|
||||
pauseCtx->namedItem = PAUSE_ITEM_NONE;
|
||||
pauseCtx->unk_1E4 = 0;
|
||||
pauseCtx->unk_204 = -434.0f;
|
||||
}
|
||||
} else if (CHECK_BTN_ALL(input->press.button, BTN_START) ||
|
||||
CHECK_BTN_ALL(input->press.button, BTN_B)) {
|
||||
Interface_SetDoAction(play, DO_ACTION_NONE);
|
||||
pauseCtx->unk_1EC = 2;
|
||||
WREG(2) = -6240;
|
||||
YREG(8) = pauseCtx->unk_204;
|
||||
func_800F64E0(0);
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
|
||||
gSaveContext.buttonStatus[3] = BTN_ENABLED;
|
||||
gSaveContext.buttonStatus[5] = gSaveContext.buttonStatus[6] = gSaveContext.buttonStatus[7] =
|
||||
gSaveContext.buttonStatus[8] = BTN_ENABLED;
|
||||
gSaveContext.hudVisibilityMode = 0;
|
||||
Interface_ChangeHudVisibilityMode(50);
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (CHECK_BTN_ALL(input->press.button, BTN_B) || CHECK_BTN_ALL(input->press.button, BTN_A) ||
|
||||
CHECK_BTN_ALL(input->press.button, BTN_START) || (--D_8082B25C == 0)) {
|
||||
Interface_SetDoAction(play, DO_ACTION_NONE);
|
||||
gSaveContext.buttonStatus[0] = gSaveContext.buttonStatus[1] = gSaveContext.buttonStatus[2] =
|
||||
gSaveContext.buttonStatus[3] = BTN_ENABLED;
|
||||
gSaveContext.buttonStatus[5] = gSaveContext.buttonStatus[6] = gSaveContext.buttonStatus[7] =
|
||||
gSaveContext.buttonStatus[8] = BTN_ENABLED;
|
||||
gSaveContext.hudVisibilityMode = 0;
|
||||
Interface_ChangeHudVisibilityMode(50);
|
||||
pauseCtx->unk_1EC = 5;
|
||||
WREG(2) = -6240;
|
||||
YREG(8) = pauseCtx->unk_204;
|
||||
func_800F64E0(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 6:
|
||||
pauseCtx->unk_204 += 314.0f / WREG(6);
|
||||
WREG(16) += WREG(25) / WREG(6);
|
||||
WREG(17) += WREG(26) / WREG(6);
|
||||
if (pauseCtx->unk_204 >= -314.0f) {
|
||||
pauseCtx->state = 6;
|
||||
pauseCtx->unk_1EC = 0;
|
||||
pauseCtx->unk_1F4 = pauseCtx->unk_1F8 = pauseCtx->unk_1FC = pauseCtx->unk_200 = 0.0f;
|
||||
pauseCtx->unk_204 = -314.0f;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 5:
|
||||
if (pauseCtx->unk_204 != (YREG(8) + 160.0f)) {
|
||||
pauseCtx->unk_1F4 = pauseCtx->unk_1F8 = pauseCtx->unk_1FC = pauseCtx->unk_200 +=
|
||||
160.0f / WREG(6);
|
||||
pauseCtx->unk_204 += 160.0f / WREG(6);
|
||||
pauseCtx->infoPanelOffsetY -= 40 / WREG(6);
|
||||
WREG(16) -= WREG(25) / WREG(6);
|
||||
WREG(17) -= WREG(26) / WREG(6);
|
||||
XREG(5) -= 150 / WREG(6);
|
||||
pauseCtx->alpha -= (u16)(255 / WREG(6));
|
||||
if (pauseCtx->unk_204 == (YREG(8) + 160.0f)) {
|
||||
pauseCtx->alpha = 0;
|
||||
}
|
||||
} else {
|
||||
pauseCtx->debugState = 0;
|
||||
pauseCtx->state = 0x13;
|
||||
pauseCtx->unk_1F4 = pauseCtx->unk_1F8 = pauseCtx->unk_1FC = pauseCtx->unk_200 = 160.0f;
|
||||
pauseCtx->namedItem = PAUSE_ITEM_NONE;
|
||||
pauseCtx->unk_1E4 = 0;
|
||||
pauseCtx->unk_204 = -434.0f;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user