diff --git a/Core/RetroAchievements.cpp b/Core/RetroAchievements.cpp index 2c30cef1a4..c5737b5eef 100644 --- a/Core/RetroAchievements.cpp +++ b/Core/RetroAchievements.cpp @@ -125,8 +125,8 @@ bool ChallengeModeActive() { return IsLoggedIn() && rc_client_get_hardcore_enabled(g_rcClient); } -bool WarnUserIfChallengeModeActive(const char *message) { - if (!ChallengeModeActive()) { +bool WarnUserIfChallengeModeActive(bool isSaveStateAction, const char *message) { + if (!ChallengeModeActive() || (isSaveStateAction && g_Config.bAchievementsSaveStateInChallengeMode)) { return false; } diff --git a/Core/RetroAchievements.h b/Core/RetroAchievements.h index afd7833fed..ed92938b04 100644 --- a/Core/RetroAchievements.h +++ b/Core/RetroAchievements.h @@ -74,7 +74,8 @@ bool ChallengeModeActive(); // only for shortcut keys and commands. You should look up the message in I18NCat::ACHIEVEMENTS. // If no message is specified, a standard "This feature is not available in Challenge Mode" message will be shown. // Also returns true if challenge mode is active. -bool WarnUserIfChallengeModeActive(const char *message = nullptr); +// Specify isSaveAction so we can still permit saves (but not loads) in challenge mode if that option is enabled. +bool WarnUserIfChallengeModeActive(bool isSaveStateAction, const char *message = nullptr); // The new API is so much nicer that we can use it directly instead of wrapping it. So let's expose the client. // Will of course return nullptr if not active. diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index a0462d1731..8a6f02c397 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -655,7 +655,7 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) { break; case VIRTKEY_FRAME_ADVANCE: - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(false)) { if (down) { // If game is running, pause emulation immediately. Otherwise, advance a single frame. if (Core_IsStepping()) { @@ -713,7 +713,7 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) { #endif case VIRTKEY_REWIND: - if (down && !Achievements::WarnUserIfChallengeModeActive()) { + if (down && !Achievements::WarnUserIfChallengeModeActive(false)) { if (SaveState::CanRewind()) { SaveState::Rewind(&AfterSaveStateAction); } else { @@ -722,21 +722,23 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) { } break; case VIRTKEY_SAVE_STATE: - if (down && !Achievements::WarnUserIfChallengeModeActive()) + if (down && !Achievements::WarnUserIfChallengeModeActive(true)) { SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction); + } break; case VIRTKEY_LOAD_STATE: - if (down && !Achievements::WarnUserIfChallengeModeActive()) + if (down && !Achievements::WarnUserIfChallengeModeActive(false)) { SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction); + } break; case VIRTKEY_PREVIOUS_SLOT: - if (down && !Achievements::WarnUserIfChallengeModeActive()) { + if (down && !Achievements::WarnUserIfChallengeModeActive(true)) { SaveState::PrevSlot(); System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT); } break; case VIRTKEY_NEXT_SLOT: - if (down && !Achievements::WarnUserIfChallengeModeActive()) { + if (down && !Achievements::WarnUserIfChallengeModeActive(true)) { SaveState::NextSlot(); System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT); } diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 9f5b89253f..fa6c7a8bc7 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -72,21 +72,26 @@ namespace MainWindow { void SetIngameMenuItemStates(HMENU menu, const GlobalUIState state) { bool menuEnableBool = state == UISTATE_INGAME || state == UISTATE_EXCEPTION; + bool loadStateEnableBool = menuEnableBool; bool saveStateEnableBool = menuEnableBool; if (Achievements::ChallengeModeActive()) { - saveStateEnableBool = false; + loadStateEnableBool = false; + if (!g_Config.bAchievementsSaveStateInChallengeMode) { + saveStateEnableBool = false; + } } UINT menuEnable = menuEnableBool ? MF_ENABLED : MF_GRAYED; + UINT loadStateEnable = loadStateEnableBool ? MF_ENABLED : MF_GRAYED; UINT saveStateEnable = saveStateEnableBool ? MF_ENABLED : MF_GRAYED; UINT menuInGameEnable = state == UISTATE_INGAME ? MF_ENABLED : MF_GRAYED; UINT umdSwitchEnable = state == UISTATE_INGAME && getUMDReplacePermit() ? MF_ENABLED : MF_GRAYED; EnableMenuItem(menu, ID_FILE_SAVESTATE_SLOT_MENU, saveStateEnable); EnableMenuItem(menu, ID_FILE_SAVESTATEFILE, saveStateEnable); - EnableMenuItem(menu, ID_FILE_LOADSTATEFILE, saveStateEnable); + EnableMenuItem(menu, ID_FILE_LOADSTATEFILE, loadStateEnable); EnableMenuItem(menu, ID_FILE_QUICKSAVESTATE, saveStateEnable); - EnableMenuItem(menu, ID_FILE_QUICKLOADSTATE, saveStateEnable); + EnableMenuItem(menu, ID_FILE_QUICKLOADSTATE, loadStateEnable); EnableMenuItem(menu, ID_EMULATION_PAUSE, menuEnable); EnableMenuItem(menu, ID_EMULATION_STOP, menuEnable); EnableMenuItem(menu, ID_EMULATION_RESET, menuEnable); @@ -513,7 +518,7 @@ namespace MainWindow { } break; case ID_FILE_LOADSTATEFILE: - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(false)) { if (W32Util::BrowseForFileName(true, hWnd, L"Load state", 0, L"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0", L"ppst", fn)) { SetCursor(LoadCursor(0, IDC_WAIT)); SaveState::Load(Path(fn), -1, SaveStateActionFinished); @@ -521,7 +526,7 @@ namespace MainWindow { } break; case ID_FILE_SAVESTATEFILE: - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(true)) { if (W32Util::BrowseForFileName(false, hWnd, L"Save state", 0, L"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0", L"ppst", fn)) { SetCursor(LoadCursor(0, IDC_WAIT)); SaveState::Save(Path(fn), -1, SaveStateActionFinished); @@ -531,7 +536,7 @@ namespace MainWindow { case ID_FILE_SAVESTATE_NEXT_SLOT: { - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(true)) { SaveState::NextSlot(); System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT); } @@ -540,7 +545,7 @@ namespace MainWindow { case ID_FILE_SAVESTATE_NEXT_SLOT_HC: { - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(true)) { if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT)) { SaveState::NextSlot(); System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT); @@ -554,13 +559,13 @@ namespace MainWindow { case ID_FILE_SAVESTATE_SLOT_3: case ID_FILE_SAVESTATE_SLOT_4: case ID_FILE_SAVESTATE_SLOT_5: - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(true)) { g_Config.iCurrentStateSlot = wmId - ID_FILE_SAVESTATE_SLOT_1; } break; case ID_FILE_QUICKLOADSTATE: - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(false)) { SetCursor(LoadCursor(0, IDC_WAIT)); SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished); } @@ -568,7 +573,7 @@ namespace MainWindow { case ID_FILE_QUICKLOADSTATE_HC: { - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(false)) { if (!KeyMap::PspButtonHasMappings(VIRTKEY_LOAD_STATE)) { SetCursor(LoadCursor(0, IDC_WAIT)); SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished); @@ -578,7 +583,7 @@ namespace MainWindow { } case ID_FILE_QUICKSAVESTATE: { - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(true)) { SetCursor(LoadCursor(0, IDC_WAIT)); SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished); } @@ -587,7 +592,7 @@ namespace MainWindow { case ID_FILE_QUICKSAVESTATE_HC: { - if (!Achievements::WarnUserIfChallengeModeActive()) { + if (!Achievements::WarnUserIfChallengeModeActive(true)) { if (!KeyMap::PspButtonHasMappings(VIRTKEY_SAVE_STATE)) { SetCursor(LoadCursor(0, IDC_WAIT));