summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Cox <garrettjcox@gmail.com>2024-05-30 22:20:29 -0500
committerGitHub <noreply@github.com>2024-05-30 23:20:29 -0400
commit464c55fcbb5191694b5f9b402c1a2bc74e85192c (patch)
treeb3061e69b35cf7e097fc49adedc95286de260a28
parent8ac7dc6b7d65a363b450d6799e9f135537a88303 (diff)
Tweaks to autosaves and pause saves to always persist them, along with preventing saves when it's too early or late in the game (#616)
-rw-r--r--mm/2s2h/BenGui/BenMenuBar.cpp12
-rw-r--r--mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp50
-rw-r--r--mm/2s2h/Enhancements/Saving/SavingEnhancements.h11
-rw-r--r--mm/include/functions.h4
-rw-r--r--mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c9
5 files changed, 65 insertions, 21 deletions
diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp
index d5a2efc96..036a5c778 100644
--- a/mm/2s2h/BenGui/BenMenuBar.cpp
+++ b/mm/2s2h/BenGui/BenMenuBar.cpp
@@ -437,14 +437,14 @@ void DrawEnhancementsMenu() {
UIWidgets::CVarCheckbox(
"Pause Menu Save", "gEnhancements.Saving.PauseSave",
{ .tooltip = "Re-introduce the pause menu save system. Pressing B in the pause menu will give you the "
- "option to create an Owl Save from your current location.\n\nWhen loading back into the "
- "game, you will be placed either at the entrance of the dungeon you saved in, or in South "
- "Clock Town." });
+ "option to create a persistent Owl Save from your current location.\n\nWhen loading back "
+ "into the game, you will be placed either at the entrance of the dungeon you saved in, or "
+ "in South Clock Town." });
if (UIWidgets::CVarCheckbox(
"Autosave", "gEnhancements.Saving.Autosave",
- { .tooltip = "Automatically create owl saves on the chosen interval.\n\nWhen loading back into the "
- "game, you will be placed either at the entrance of the dungeon you saved in, or in "
- "South Clock Town." })) {
+ { .tooltip = "Automatically create a persistent Owl Save on the chosen interval.\n\nWhen loading "
+ "back into the game, you will be placed either at the entrance of the dungeon you "
+ "saved in, or in South Clock Town." })) {
RegisterAutosave();
}
UIWidgets::CVarSliderInt("Autosave Interval (minutes): %d", "gEnhancements.Saving.AutosaveInterval", 1, 60,
diff --git a/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp b/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp
index ed8171cc9..d0e6d32b8 100644
--- a/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp
+++ b/mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp
@@ -16,8 +16,8 @@ static uint32_t autosaveGameStateUpdateHookId = 0;
static uint32_t autosaveGameStateDrawFinishHookId = 0;
// Used for saving through Autosaves and Pause Menu saves.
-extern "C" int32_t GetSaveEntrance(PlayState* play) {
- switch (play->sceneId) {
+extern "C" int SavingEnhancements_GetSaveEntrance() {
+ switch (gPlayState->sceneId) {
// Woodfall Temple + Odolwa
case SCENE_MITURIN:
case SCENE_MITURIN_BS:
@@ -40,6 +40,43 @@ extern "C" int32_t GetSaveEntrance(PlayState* play) {
}
}
+extern "C" bool SavingEnhancements_CanSave() {
+ // Game State
+ if (gPlayState == NULL || GET_PLAYER(gPlayState) == NULL) {
+ return false;
+ }
+
+ // Owl saving available
+ if (!gSaveContext.flashSaveAvailable || gSaveContext.fileNum == 255) {
+ return false;
+ }
+
+ // Not in a blocking cutscene
+ if (Player_InBlockingCsMode(gPlayState, GET_PLAYER(gPlayState))) {
+ return false;
+ }
+
+ // Not in the middle of dialog
+ if (gPlayState->msgCtx.msgMode != 0) {
+ return false;
+ }
+
+ // Hasn't gotten to clock town yet
+ if (gPlayState->sceneId == SCENE_SPOT00 || gPlayState->sceneId == SCENE_LOST_WOODS ||
+ gPlayState->sceneId == SCENE_OPENINGDAN) {
+ return false;
+ }
+
+ // Can't save once you've gone to the moon
+ if (gPlayState->sceneId == SCENE_SOUGEN || gPlayState->sceneId == SCENE_LAST_LINK ||
+ gPlayState->sceneId == SCENE_LAST_DEKU || gPlayState->sceneId == SCENE_LAST_GORON ||
+ gPlayState->sceneId == SCENE_LAST_ZORA || gPlayState->sceneId == SCENE_LAST_BS) {
+ return false;
+ }
+
+ return true;
+}
+
void DeleteOwlSave() {
// Remove Owl Save on time cycle reset, needed when persisting owl saves and/or when
// creating owl saves without the player being send back to the file select screen.
@@ -82,9 +119,7 @@ void HandleAutoSave() {
}
// If owl save available to create, do it and reset the interval.
- if (gSaveContext.flashSaveAvailable && gSaveContext.fileNum != 255 &&
- !Player_InBlockingCsMode(gPlayState, player) && gPlayState->pauseCtx.state == 0 &&
- gPlayState->msgCtx.msgMode == 0) {
+ if (SavingEnhancements_CanSave() && gPlayState->pauseCtx.state == 0) {
// Reset timestamp, set icon timer to show autosave icon for 5 seconds (100 frames)
lastSaveTimestamp = GetUnixTimestamp();
@@ -92,7 +127,7 @@ void HandleAutoSave() {
// Create owl save
gSaveContext.save.isOwlSave = true;
- gSaveContext.save.shipSaveInfo.pauseSaveEntrance = GetSaveEntrance(gPlayState);
+ gSaveContext.save.shipSaveInfo.pauseSaveEntrance = SavingEnhancements_GetSaveEntrance();
Play_SaveCycleSceneFlags(&gPlayState->state);
gSaveContext.save.saveInfo.playerData.savedSceneId = gPlayState->sceneId;
func_8014546C(&gPlayState->sramCtx);
@@ -106,7 +141,8 @@ void HandleAutoSave() {
void RegisterSavingEnhancements() {
REGISTER_VB_SHOULD(GI_VB_DELETE_OWL_SAVE, {
- if (CVarGetInteger("gEnhancements.Saving.PersistentOwlSaves", 0)) {
+ if (CVarGetInteger("gEnhancements.Saving.PersistentOwlSaves", 0) ||
+ gSaveContext.save.shipSaveInfo.pauseSaveEntrance != -1) {
*should = false;
}
});
diff --git a/mm/2s2h/Enhancements/Saving/SavingEnhancements.h b/mm/2s2h/Enhancements/Saving/SavingEnhancements.h
index 327817c1d..71018fe64 100644
--- a/mm/2s2h/Enhancements/Saving/SavingEnhancements.h
+++ b/mm/2s2h/Enhancements/Saving/SavingEnhancements.h
@@ -4,4 +4,15 @@
void RegisterSavingEnhancements();
void RegisterAutosave();
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int SavingEnhancements_GetSaveEntrance();
+bool SavingEnhancements_CanSave();
+
+#ifdef __cplusplus
+}
+#endif
+
#endif // SAVING_ENHANCEMENTS_H
diff --git a/mm/include/functions.h b/mm/include/functions.h
index ea5806f21..62ac3cb60 100644
--- a/mm/include/functions.h
+++ b/mm/include/functions.h
@@ -1365,10 +1365,6 @@ void osSpTaskYield(void);
void osViSetXScale(f32 value);
void osViSetYScale(f32 value);
// #endregion
-// #region 2S2H [Enhancements]
-// [Autosaves & Pause Menu Saves]
-int32_t GetSaveEntrance(PlayState* play);
-// #endregion
void Regs_InitData(PlayState* play);
diff --git a/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c b/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
index 172e06919..071f4d208 100644
--- a/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
+++ b/mm/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c
@@ -18,6 +18,7 @@
#include "archives/item_name_static/item_name_static.h"
#include "archives/map_name_static/map_name_static.h"
#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
+#include "2s2h/Enhancements/Saving/SavingEnhancements.h"
#include "2s2h_assets.h"
@@ -3377,7 +3378,7 @@ void KaleidoScope_Update(PlayState* play) {
if (!pauseCtx->itemDescriptionOn &&
(CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_B))) {
Interface_SetAButtonDoAction(play, DO_ACTION_NONE);
- if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0)) {
+ if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0) && SavingEnhancements_CanSave()) {
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
pauseCtx->state = PAUSE_STATE_SAVEPROMPT;
Audio_PlaySfx_MessageDecide();
@@ -3418,7 +3419,7 @@ void KaleidoScope_Update(PlayState* play) {
// Abort having the player play the song and close the pause menu
AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF);
Interface_SetAButtonDoAction(play, DO_ACTION_NONE);
- if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0)) {
+ if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0) && SavingEnhancements_CanSave()) {
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
pauseCtx->state = PAUSE_STATE_SAVEPROMPT;
Audio_PlaySfx_MessageDecide();
@@ -3461,7 +3462,7 @@ void KaleidoScope_Update(PlayState* play) {
if (CHECK_BTN_ALL(input->press.button, BTN_START) || CHECK_BTN_ALL(input->press.button, BTN_B)) {
AudioOcarina_SetInstrument(OCARINA_INSTRUMENT_OFF);
Interface_SetAButtonDoAction(play, DO_ACTION_NONE);
- if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0)) {
+ if (CVarGetInteger("gEnhancements.Saving.PauseSave", 0) && SavingEnhancements_CanSave()) {
if (CHECK_BTN_ALL(input->press.button, BTN_B)) {
pauseCtx->state = PAUSE_STATE_SAVEPROMPT;
Audio_PlaySfx_MessageDecide();
@@ -3518,7 +3519,7 @@ void KaleidoScope_Update(PlayState* play) {
// 2S2H [Enhancement] Eventually we might allow them to load from their last entrance,
// but we need to first identify and fix edge cases where that doesn't work properly
// like grottos and cutscenes
- gSaveContext.save.shipSaveInfo.pauseSaveEntrance = GetSaveEntrance(play);
+ gSaveContext.save.shipSaveInfo.pauseSaveEntrance = SavingEnhancements_GetSaveEntrance();
}
Play_SaveCycleSceneFlags(&play->state);
gSaveContext.save.saveInfo.playerData.savedSceneId = play->sceneId;