mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-21 18:29:05 +02:00
Implement RetroAchievements challenge mode restrictions, and fix related bugs
This commit is contained in:
1 parent
9e4387c529
commit
c17b84b3d4
13 files changed
+192
-112
No files matched your search
@@ -5,6 +5,7 @@
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/Data/Collections/FastVec.h"
|
||||
#include "Common/GPU/Vulkan/VulkanContext.h"
|
||||
#include "Common/GPU/GPUBackendCommon.h"
|
||||
|
||||
@@ -205,4 +206,3 @@ private:
|
||||
uint32_t usage_ = 0;
|
||||
bool grow_;
|
||||
};
|
||||
|
||||
+14
-1
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Common/System/OSD.h"
|
||||
#include "Common/TimeUtil.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
OnScreenDisplay g_OSD;
|
||||
|
||||
@@ -146,6 +147,11 @@ void OnScreenDisplay::ShowChallengeIndicator(int achievementID, bool show) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!show) {
|
||||
// Sanity check
|
||||
return;
|
||||
}
|
||||
|
||||
// OK, let's make a new side-entry.
|
||||
Entry entry;
|
||||
entry.numericID = achievementID;
|
||||
@@ -172,13 +178,20 @@ void OnScreenDisplay::ShowLeaderboardTracker(int leaderboardTrackerID, const cha
|
||||
}
|
||||
}
|
||||
|
||||
if (!show) {
|
||||
// Sanity check
|
||||
return;
|
||||
}
|
||||
|
||||
// OK, let's make a new side-entry.
|
||||
Entry entry;
|
||||
entry.numericID = leaderboardTrackerID;
|
||||
entry.type = OSDType::LEADERBOARD_TRACKER;
|
||||
entry.startTime = now;
|
||||
entry.endTime = now + 10000000.0; // Don't auto-fadeout
|
||||
entry.text = trackerText;
|
||||
if (trackerText) {
|
||||
entry.text = trackerText;
|
||||
}
|
||||
sideEntries_.insert(sideEntries_.begin(), entry);
|
||||
}
|
||||
|
||||
|
||||
@@ -266,7 +266,6 @@ static bool DefaultSasThread() {
|
||||
|
||||
static const ConfigSetting achievementSettings[] = {
|
||||
ConfigSetting("AchievementsEnable", &g_Config.bAchievementsEnable, true, CfgFlag::DEFAULT),
|
||||
ConfigSetting("AchievementsRichPresence", &g_Config.bAchievementsRichPresence, true, CfgFlag::DEFAULT),
|
||||
ConfigSetting("AchievementsChallengeMode", &g_Config.bAchievementsChallengeMode, false, CfgFlag::DEFAULT),
|
||||
ConfigSetting("AchievementsEncoreMode", &g_Config.bAchievementsEncoreMode, false, CfgFlag::DEFAULT),
|
||||
ConfigSetting("AchievementsUnofficial", &g_Config.bAchievementsUnofficial, false, CfgFlag::DEFAULT),
|
||||
|
||||
@@ -488,7 +488,6 @@ public:
|
||||
// Retro Achievement settings
|
||||
// Copied from Duckstation, we might want to remove some.
|
||||
bool bAchievementsEnable;
|
||||
bool bAchievementsRichPresence;
|
||||
bool bAchievementsChallengeMode;
|
||||
bool bAchievementsEncoreMode;
|
||||
bool bAchievementsUnofficial;
|
||||
|
||||
+10
-4
@@ -19,6 +19,7 @@
|
||||
#include "Core/System.h"
|
||||
#include "Core/HLE/sceCtrl.h"
|
||||
#include "Core/MIPS/JitCommon/JitCommon.h"
|
||||
#include "Core/RetroAchievements.h"
|
||||
#include "GPU/Common/PostShader.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -319,9 +320,11 @@ void __CheatDoState(PointerWrap &p) {
|
||||
}
|
||||
|
||||
void hleCheat(u64 userdata, int cyclesLate) {
|
||||
if (cheatsEnabled != g_Config.bEnableCheats) {
|
||||
bool shouldBeEnabled = !Achievements::ChallengeModeActive() && g_Config.bEnableCheats;
|
||||
|
||||
if (cheatsEnabled != shouldBeEnabled) {
|
||||
// Okay, let's move to the desired state, then.
|
||||
if (g_Config.bEnableCheats) {
|
||||
if (shouldBeEnabled) {
|
||||
__CheatStart();
|
||||
} else {
|
||||
__CheatStop();
|
||||
@@ -1193,6 +1196,10 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat,
|
||||
}
|
||||
|
||||
void CWCheatEngine::Run() {
|
||||
if (Achievements::ChallengeModeActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (CheatCode cheat : cheats_) {
|
||||
// InterpretNextOp and ExecuteOp move i.
|
||||
for (size_t i = 0; i < cheat.lines.size(); ) {
|
||||
@@ -1207,8 +1214,7 @@ bool CWCheatEngine::HasCheats() {
|
||||
}
|
||||
|
||||
bool CheatsInEffect() {
|
||||
if (!cheatEngine || !cheatsEnabled)
|
||||
if (!cheatEngine || !cheatsEnabled || Achievements::ChallengeModeActive())
|
||||
return false;
|
||||
return cheatEngine->HasCheats();
|
||||
}
|
||||
|
||||
+10
-6
@@ -49,6 +49,7 @@
|
||||
#include "Core/HLE/sceKernelInterrupt.h"
|
||||
#include "Core/HW/Display.h"
|
||||
#include "Core/Util/PPGeDraw.h"
|
||||
#include "Core/RetroAchievements.h"
|
||||
|
||||
#include "GPU/GPU.h"
|
||||
#include "GPU/GPUState.h"
|
||||
@@ -348,12 +349,15 @@ void __DisplaySetWasPaused() {
|
||||
}
|
||||
|
||||
static int FrameTimingLimit() {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1)
|
||||
return g_Config.iFpsLimit1;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2)
|
||||
return g_Config.iFpsLimit2;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::ANALOG)
|
||||
return PSP_CoreParameter().analogFpsLimit;
|
||||
if (!Achievements::ChallengeModeActive()) {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1)
|
||||
return g_Config.iFpsLimit1;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2)
|
||||
return g_Config.iFpsLimit2;
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::ANALOG)
|
||||
return PSP_CoreParameter().analogFpsLimit;
|
||||
}
|
||||
// Note: Fast-forward is OK in challenge mode.
|
||||
if (PSP_CoreParameter().fastForward)
|
||||
return 0;
|
||||
return framerate;
|
||||
|
||||
+32
-23
@@ -74,8 +74,6 @@ namespace Achievements {
|
||||
// It's the name of the secret, not a secret name - the value is not secret :)
|
||||
static const char *RA_TOKEN_SECRET_NAME = "retroachievements";
|
||||
|
||||
static u32 GetGameID();
|
||||
|
||||
static Achievements::Statistics g_stats;
|
||||
|
||||
const std::string g_gameIconCachePrefix = "game:";
|
||||
@@ -84,8 +82,6 @@ const std::string g_iconCachePrefix = "badge:";
|
||||
Path s_game_path;
|
||||
std::string s_game_hash;
|
||||
|
||||
bool g_challengeMode = true;
|
||||
|
||||
bool g_isIdentifying = false;
|
||||
|
||||
// rc_client implementation
|
||||
@@ -101,10 +97,6 @@ bool IsLoggedIn() {
|
||||
return rc_client_get_user_info(g_rcClient) != nullptr;
|
||||
}
|
||||
|
||||
bool ChallengeModeActive() {
|
||||
return g_challengeMode;
|
||||
}
|
||||
|
||||
bool EncoreModeActive() {
|
||||
if (!g_rcClient) {
|
||||
return false;
|
||||
@@ -119,15 +111,33 @@ bool UnofficialEnabled() {
|
||||
return rc_client_get_unofficial_enabled(g_rcClient);
|
||||
}
|
||||
|
||||
bool IsActive() {
|
||||
return GetGameID() != 0;
|
||||
bool ChallengeModeActive() {
|
||||
if (!g_rcClient) {
|
||||
return false;
|
||||
}
|
||||
return rc_client_get_hardcore_enabled(g_rcClient);
|
||||
}
|
||||
|
||||
bool WarnUserIfChallengeModeActive(const char *message) {
|
||||
if (!ChallengeModeActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *showMessage = message;
|
||||
if (!message) {
|
||||
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
|
||||
showMessage = ac->T("This feature is not available in Challenge Mode");
|
||||
}
|
||||
|
||||
g_OSD.Show(OSDType::MESSAGE_WARNING, showMessage, 3.0f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsBlockingExecution() {
|
||||
return g_isIdentifying;
|
||||
}
|
||||
|
||||
u32 GetGameID() {
|
||||
static u32 GetGameID() {
|
||||
if (!g_rcClient) {
|
||||
return 0;
|
||||
}
|
||||
@@ -139,6 +149,10 @@ u32 GetGameID() {
|
||||
return info->id; // 0 if not identified
|
||||
}
|
||||
|
||||
bool IsActive() {
|
||||
return GetGameID() != 0;
|
||||
}
|
||||
|
||||
// This is the function the rc_client will use to read memory for the emulator. we don't need it yet,
|
||||
// so just provide a dummy function that returns "no memory read".
|
||||
static uint32_t read_memory_callback(uint32_t address, uint8_t *buffer, uint32_t num_bytes, rc_client_t *client) {
|
||||
@@ -260,12 +274,12 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t *
|
||||
break;
|
||||
case RC_CLIENT_EVENT_LEADERBOARD_FAILED:
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard attempt failed: %s", event->leaderboard->title);
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, ReplaceAll(ac->T("%1: Failed"), "%1", event->leaderboard->title), 3.0f);
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, ReplaceAll(ac->T("%1: Leaderboard attempt failed"), "%1", event->leaderboard->title), 3.0f);
|
||||
// A leaderboard attempt has failed.
|
||||
break;
|
||||
case RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED:
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard result submitted: %s", event->leaderboard->title);
|
||||
g_OSD.Show(OSDType::MESSAGE_SUCCESS, ReplaceAll(ac->T("%1: Submitting successful score!"), "%1", event->leaderboard->title), event->leaderboard->description, 3.0f);
|
||||
g_OSD.Show(OSDType::MESSAGE_SUCCESS, ReplaceAll(ReplaceAll(ac->T("%1: Submitting leaderboard score: %2!"), "%1", event->leaderboard->title), "%2", event->leaderboard->tracker_value), event->leaderboard->description, 3.0f);
|
||||
// A leaderboard attempt was completed.The handler may show a message with the leaderboard title and /or description indicating the final value being submitted to the server.
|
||||
break;
|
||||
case RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW:
|
||||
@@ -288,7 +302,7 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t *
|
||||
g_OSD.ShowAchievementProgress(event->achievement->id, 2.0f);
|
||||
break;
|
||||
case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW:
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard tracker show: %s", event->leaderboard_tracker->display);
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard tracker show: '%s' (id %d)", event->leaderboard_tracker->display, event->leaderboard_tracker->id);
|
||||
// A leaderboard_tracker has become active. The handler should show the tracker text on screen.
|
||||
// Multiple active leaderboards may share a single tracker if they have the same definition and value.
|
||||
// As such, the leaderboard tracker IDs are unique amongst the leaderboard trackers, and have no correlation to the active leaderboard(s).
|
||||
@@ -297,13 +311,13 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t *
|
||||
break;
|
||||
case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE:
|
||||
// A leaderboard_tracker has become inactive. The handler should hide the tracker text from the screen.
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard tracker hide: %s", event->leaderboard_tracker->display);
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard tracker hide: '%s' (id %d)", event->leaderboard_tracker->display, event->leaderboard_tracker->id);
|
||||
g_OSD.ShowLeaderboardTracker(event->leaderboard_tracker->id, nullptr, false);
|
||||
break;
|
||||
case RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE:
|
||||
// A leaderboard_tracker value has been updated. The handler should update the tracker text on the screen.
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard tracker update: %s", event->leaderboard_tracker->display);
|
||||
g_OSD.ShowLeaderboardTracker(event->leaderboard_tracker->id, event->leaderboard_tracker->display, false);
|
||||
NOTICE_LOG(ACHIEVEMENTS, "Leaderboard tracker update: '%s' (id %d)", event->leaderboard_tracker->display, event->leaderboard_tracker->id);
|
||||
g_OSD.ShowLeaderboardTracker(event->leaderboard_tracker->id, event->leaderboard_tracker->display, true);
|
||||
break;
|
||||
case RC_CLIENT_EVENT_RESET:
|
||||
WARN_LOG(ACHIEVEMENTS, "Resetting game due to achievement setting change!");
|
||||
@@ -328,16 +342,10 @@ void Initialize() {
|
||||
}
|
||||
_assert_msg_(g_Config.bAchievementsEnable, "Achievements are enabled");
|
||||
|
||||
g_challengeMode = true; // the default
|
||||
g_rcClient = rc_client_create(read_memory_callback, server_call_callback);
|
||||
// Provide a logging function to simplify debugging
|
||||
rc_client_enable_logging(g_rcClient, RC_CLIENT_LOG_LEVEL_VERBOSE, log_message_callback);
|
||||
|
||||
// FOR NOW: Disable hardcore - if we goof something up in the implementation, we don't want our
|
||||
// account disabled for cheating.
|
||||
rc_client_set_hardcore_enabled(g_rcClient, 0);
|
||||
g_challengeMode = false;
|
||||
|
||||
// Disable SSL for now.
|
||||
rc_client_set_host(g_rcClient, "http://retroachievements.org");
|
||||
|
||||
@@ -590,6 +598,7 @@ void SetGame(const Path &path) {
|
||||
g_isIdentifying = true;
|
||||
|
||||
// Apply pre-load settings.
|
||||
rc_client_set_hardcore_enabled(g_rcClient, g_Config.bAchievementsChallengeMode ? 1 : 0);
|
||||
rc_client_set_encore_mode_enabled(g_rcClient, g_Config.bAchievementsEncoreMode ? 1 : 0);
|
||||
rc_client_set_unofficial_enabled(g_rcClient, g_Config.bAchievementsUnofficial ? 1 : 0);
|
||||
|
||||
|
||||
@@ -51,14 +51,24 @@ bool IsLoggedIn();
|
||||
// Returns true if in a game, and achievements are active in the current game.
|
||||
bool IsActive();
|
||||
|
||||
// Returns true if unofficial achievements are enabled.
|
||||
bool UnofficialEnabled();
|
||||
|
||||
// Returns true if the emulator should hold off on executing game code, such as during game identification.
|
||||
bool IsBlockingExecution();
|
||||
|
||||
/// Returns true if features such as save states should be disabled.
|
||||
// Returns true if features such as save states should be disabled.
|
||||
// This should only be used for controlling functionality of the following things, which are banned in Challenge/Hardcore mode:
|
||||
//
|
||||
// * Savestates
|
||||
// * Slowdown time (though hard to fully prevent, could use crazy post shaders or software rendering...)
|
||||
bool ChallengeModeActive();
|
||||
|
||||
// Returns true if unofficial achievements are enabled.
|
||||
bool UnofficialEnabled();
|
||||
// Same as ChallengeModeActive but comes with a convenient user message. Don't use for every-frame checks or UI enablement,
|
||||
// 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);
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -399,6 +399,11 @@ namespace SaveState
|
||||
|
||||
void Enqueue(SaveState::Operation op)
|
||||
{
|
||||
if (Achievements::ChallengeModeActive()) {
|
||||
// No savestate operations are permitted, let's just ignore it.
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(mutex);
|
||||
pending.push_back(op);
|
||||
|
||||
|
||||
+37
-31
@@ -582,7 +582,7 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
|
||||
break;
|
||||
|
||||
case VIRTKEY_SPEED_TOGGLE:
|
||||
if (down) {
|
||||
if (down && !Achievements::WarnUserIfChallengeModeActive()) {
|
||||
// Cycle through enabled speeds.
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL && g_Config.iFpsLimit1 >= 0) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM1;
|
||||
@@ -598,28 +598,32 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
|
||||
break;
|
||||
|
||||
case VIRTKEY_SPEED_CUSTOM1:
|
||||
if (down) {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM1;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("fixed", "Speed: alternate"), 1.0);
|
||||
}
|
||||
} else {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("standard", "Speed: standard"), 1.0);
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
if (down) {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM1;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("fixed", "Speed: alternate"), 1.0);
|
||||
}
|
||||
} else {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("standard", "Speed: standard"), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VIRTKEY_SPEED_CUSTOM2:
|
||||
if (down) {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0);
|
||||
}
|
||||
} else {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("standard", "Speed: standard"), 1.0);
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
if (down) {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::NORMAL) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::CUSTOM2;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("SpeedCustom2", "Speed: alternate 2"), 1.0);
|
||||
}
|
||||
} else {
|
||||
if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) {
|
||||
PSP_CoreParameter().fpsLimit = FPSLimit::NORMAL;
|
||||
g_OSD.Show(OSDType::MESSAGE_INFO, sc->T("standard", "Speed: standard"), 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -635,13 +639,15 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
|
||||
break;
|
||||
|
||||
case VIRTKEY_FRAME_ADVANCE:
|
||||
if (down) {
|
||||
// If game is running, pause emulation immediately. Otherwise, advance a single frame.
|
||||
if (Core_IsStepping()) {
|
||||
frameStep_ = true;
|
||||
Core_EnableStepping(false);
|
||||
} else if (!frameStep_) {
|
||||
Core_EnableStepping(true, "ui.frameAdvance", 0);
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
if (down) {
|
||||
// If game is running, pause emulation immediately. Otherwise, advance a single frame.
|
||||
if (Core_IsStepping()) {
|
||||
frameStep_ = true;
|
||||
Core_EnableStepping(false);
|
||||
} else if (!frameStep_) {
|
||||
Core_EnableStepping(true, "ui.frameAdvance", 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -691,7 +697,7 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
|
||||
#endif
|
||||
|
||||
case VIRTKEY_REWIND:
|
||||
if (down) {
|
||||
if (down && !Achievements::WarnUserIfChallengeModeActive()) {
|
||||
if (SaveState::CanRewind()) {
|
||||
SaveState::Rewind(&AfterSaveStateAction);
|
||||
} else {
|
||||
@@ -700,21 +706,21 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
|
||||
}
|
||||
break;
|
||||
case VIRTKEY_SAVE_STATE:
|
||||
if (down)
|
||||
if (down && !Achievements::WarnUserIfChallengeModeActive())
|
||||
SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
|
||||
break;
|
||||
case VIRTKEY_LOAD_STATE:
|
||||
if (down)
|
||||
if (down && !Achievements::WarnUserIfChallengeModeActive())
|
||||
SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
|
||||
break;
|
||||
case VIRTKEY_PREVIOUS_SLOT:
|
||||
if (down) {
|
||||
if (down && !Achievements::WarnUserIfChallengeModeActive()) {
|
||||
SaveState::PrevSlot();
|
||||
System_PostUIMessage("savestate_displayslot", "");
|
||||
}
|
||||
break;
|
||||
case VIRTKEY_NEXT_SLOT:
|
||||
if (down) {
|
||||
if (down && !Achievements::WarnUserIfChallengeModeActive()) {
|
||||
SaveState::NextSlot();
|
||||
System_PostUIMessage("savestate_displayslot", "");
|
||||
}
|
||||
|
||||
@@ -275,7 +275,6 @@ void RetroAchievementsSettingsScreen::CreateSettingsTab(UI::ViewGroup *viewGroup
|
||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode (no savestates)")));
|
||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsEncoreMode, ac->T("Encore Mode")));
|
||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsUnofficial, ac->T("Unofficial achievements")));
|
||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsRichPresence, ac->T("Rich Presence")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
|
||||
// viewGroup->Add(new CheckBox(&g_Config.bAchievementsSoundEffects, ac->T("Sound Effects")))->SetEnabledPtr(&g_Config.bAchievementsEnable); // not yet implemented
|
||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsLogBadMemReads, ac->T("Log bad memory accesses")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
|
||||
|
||||
|
||||
+66
-39
@@ -51,6 +51,7 @@
|
||||
#include "Core/HLE/sceUmd.h"
|
||||
#include "Core/SaveState.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/RetroAchievements.h"
|
||||
|
||||
extern bool g_TakeScreenshot;
|
||||
|
||||
@@ -69,14 +70,23 @@ namespace MainWindow {
|
||||
LRESULT CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
void SetIngameMenuItemStates(HMENU menu, const GlobalUIState state) {
|
||||
UINT menuEnable = state == UISTATE_INGAME || state == UISTATE_EXCEPTION ? MF_ENABLED : MF_GRAYED;
|
||||
bool menuEnableBool = state == UISTATE_INGAME || state == UISTATE_EXCEPTION;
|
||||
|
||||
bool saveStateEnableBool = menuEnableBool;
|
||||
if (Achievements::ChallengeModeActive()) {
|
||||
saveStateEnableBool = false;
|
||||
}
|
||||
|
||||
UINT menuEnable = menuEnableBool ? 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_SAVESTATEFILE, menuEnable);
|
||||
EnableMenuItem(menu, ID_FILE_LOADSTATEFILE, menuEnable);
|
||||
EnableMenuItem(menu, ID_FILE_QUICKSAVESTATE, menuEnable);
|
||||
EnableMenuItem(menu, ID_FILE_QUICKLOADSTATE, menuEnable);
|
||||
EnableMenuItem(menu, ID_FILE_SAVESTATE_SLOT_MENU, saveStateEnable);
|
||||
EnableMenuItem(menu, ID_FILE_SAVESTATEFILE, saveStateEnable);
|
||||
EnableMenuItem(menu, ID_FILE_LOADSTATEFILE, saveStateEnable);
|
||||
EnableMenuItem(menu, ID_FILE_QUICKSAVESTATE, saveStateEnable);
|
||||
EnableMenuItem(menu, ID_FILE_QUICKLOADSTATE, saveStateEnable);
|
||||
EnableMenuItem(menu, ID_EMULATION_PAUSE, menuEnable);
|
||||
EnableMenuItem(menu, ID_EMULATION_STOP, menuEnable);
|
||||
EnableMenuItem(menu, ID_EMULATION_RESET, menuEnable);
|
||||
@@ -517,70 +527,87 @@ namespace MainWindow {
|
||||
}
|
||||
break;
|
||||
case ID_FILE_LOADSTATEFILE:
|
||||
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);
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ID_FILE_SAVESTATEFILE:
|
||||
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);
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_FILE_SAVESTATE_NEXT_SLOT:
|
||||
{
|
||||
SaveState::NextSlot();
|
||||
System_PostUIMessage("savestate_displayslot", "");
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_FILE_SAVESTATE_NEXT_SLOT_HC:
|
||||
{
|
||||
if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT)) {
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
SaveState::NextSlot();
|
||||
System_PostUIMessage("savestate_displayslot", "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_FILE_SAVESTATE_SLOT_1: g_Config.iCurrentStateSlot = 0; break;
|
||||
case ID_FILE_SAVESTATE_SLOT_2: g_Config.iCurrentStateSlot = 1; break;
|
||||
case ID_FILE_SAVESTATE_SLOT_3: g_Config.iCurrentStateSlot = 2; break;
|
||||
case ID_FILE_SAVESTATE_SLOT_4: g_Config.iCurrentStateSlot = 3; break;
|
||||
case ID_FILE_SAVESTATE_SLOT_5: g_Config.iCurrentStateSlot = 4; break;
|
||||
|
||||
case ID_FILE_QUICKLOADSTATE:
|
||||
case ID_FILE_SAVESTATE_NEXT_SLOT_HC:
|
||||
{
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT)) {
|
||||
SaveState::NextSlot();
|
||||
System_PostUIMessage("savestate_displayslot", "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_FILE_QUICKLOADSTATE_HC:
|
||||
{
|
||||
if (!KeyMap::PspButtonHasMappings(VIRTKEY_LOAD_STATE))
|
||||
{
|
||||
case ID_FILE_SAVESTATE_SLOT_1:
|
||||
case ID_FILE_SAVESTATE_SLOT_2:
|
||||
case ID_FILE_SAVESTATE_SLOT_3:
|
||||
case ID_FILE_SAVESTATE_SLOT_4:
|
||||
case ID_FILE_SAVESTATE_SLOT_5:
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
g_Config.iCurrentStateSlot = wmId - ID_FILE_SAVESTATE_SLOT_1;
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_FILE_QUICKLOADSTATE:
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_FILE_QUICKLOADSTATE_HC:
|
||||
{
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
if (!KeyMap::PspButtonHasMappings(VIRTKEY_LOAD_STATE)) {
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ID_FILE_QUICKSAVESTATE:
|
||||
{
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_FILE_QUICKSAVESTATE_HC:
|
||||
{
|
||||
if (!KeyMap::PspButtonHasMappings(VIRTKEY_SAVE_STATE))
|
||||
{
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
|
||||
break;
|
||||
if (!Achievements::WarnUserIfChallengeModeActive()) {
|
||||
if (!KeyMap::PspButtonHasMappings(VIRTKEY_SAVE_STATE))
|
||||
{
|
||||
SetCursor(LoadCursor(0, IDC_WAIT));
|
||||
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
[Achievements]
|
||||
%d achievements, %d points = %d achievements, %d points
|
||||
%1: Leaderboard attempt started = %1: Leaderboard attempt started
|
||||
%1: Leaderboard attempt failed = %1: Leaderboard attempt failed
|
||||
%1: Submitting leaderboard score: %2! = %1: Submitting leaderboard score: %2!
|
||||
Account = Account
|
||||
Achievements = Achievements
|
||||
Achievements are disabled = Achievements are disabled
|
||||
@@ -38,7 +41,7 @@ Links = Links
|
||||
Locked achievements = Locked achievements
|
||||
Log bad memory accesses = Log bad memory accesses
|
||||
Mastered %1 = Mastered %1
|
||||
Not available in Challenge Mode = Not available in Challenge Mode
|
||||
This feature is not available in Challenge Mode = This feature is not available in Challenge Mode
|
||||
Save states not available in Challenge Mode = Save states not available in Challenge Mode
|
||||
Register on www.retroachievements.org = Register on www.retroachievements.org
|
||||
RetroAchievements are not available for this game = RetroAchievements are not available for this game
|
||||
|
||||
Reference in new issue
Block a user