Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweaks to autosaves and pause saves to always persist them #616

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions mm/2s2h/BenGui/BenMenuBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
50 changes: 43 additions & 7 deletions mm/2s2h/Enhancements/Saving/SavingEnhancements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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.
Expand Down Expand Up @@ -82,17 +119,15 @@ 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();
iconTimer = 100;

// 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);
Expand All @@ -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;
}
});
Expand Down
11 changes: 11 additions & 0 deletions mm/2s2h/Enhancements/Saving/SavingEnhancements.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 0 additions & 4 deletions mm/include/functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand Down