Skip to content

Commit 1065e18

Browse files
authored
Merge pull request #18468 from hrydgard/more-retroachievements-tweaks
RetroAchievements: Show rich presence message on pause screen, restriction tweaks
2 parents 0f262d5 + 17c779c commit 1065e18

11 files changed

+71
-53
lines changed

Core/Config.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ static const ConfigSetting achievementSettings[] = {
310310
ConfigSetting("AchievementsEncoreMode", &g_Config.bAchievementsEncoreMode, false, CfgFlag::DEFAULT),
311311
ConfigSetting("AchievementsUnofficial", &g_Config.bAchievementsUnofficial, false, CfgFlag::DEFAULT),
312312
ConfigSetting("AchievementsLogBadMemReads", &g_Config.bAchievementsLogBadMemReads, false, CfgFlag::DEFAULT),
313-
ConfigSetting("bAchievementsSaveStateInChallengeMode", &g_Config.bAchievementsSaveStateInChallengeMode, false, CfgFlag::DEFAULT),
313+
ConfigSetting("bAchievementsSaveStateInChallengeMode", &g_Config.bAchievementsSaveStateInHardcoreMode, false, CfgFlag::DEFAULT),
314314

315315
// Achievements login info. Note that password is NOT stored, only a login token.
316316
// And that login token is stored separately from the ini, see NativeSaveSecret, but it can also be loaded

Core/Config.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ struct Config {
513513
bool bAchievementsUnofficial;
514514
bool bAchievementsSoundEffects;
515515
bool bAchievementsLogBadMemReads;
516-
bool bAchievementsSaveStateInChallengeMode;
516+
bool bAchievementsSaveStateInHardcoreMode;
517517

518518
// Positioning of the various notifications
519519
int iAchievementsLeaderboardTrackerPos;

Core/CwCheat.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ void __CheatDoState(PointerWrap &p) {
320320
}
321321

322322
void hleCheat(u64 userdata, int cyclesLate) {
323-
bool shouldBeEnabled = !Achievements::ChallengeModeActive() && g_Config.bEnableCheats;
323+
bool shouldBeEnabled = !Achievements::HardcoreModeActive() && g_Config.bEnableCheats;
324324

325325
if (cheatsEnabled != shouldBeEnabled) {
326326
// Okay, let's move to the desired state, then.
@@ -1196,7 +1196,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat,
11961196
}
11971197

11981198
void CWCheatEngine::Run() {
1199-
if (Achievements::ChallengeModeActive()) {
1199+
if (Achievements::HardcoreModeActive()) {
12001200
return;
12011201
}
12021202

@@ -1214,7 +1214,7 @@ bool CWCheatEngine::HasCheats() {
12141214
}
12151215

12161216
bool CheatsInEffect() {
1217-
if (!cheatEngine || !cheatsEnabled || Achievements::ChallengeModeActive())
1217+
if (!cheatEngine || !cheatsEnabled || Achievements::HardcoreModeActive())
12181218
return false;
12191219
return cheatEngine->HasCheats();
12201220
}

Core/HLE/sceDisplay.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ void __DisplaySetWasPaused() {
351351

352352
// TOOD: Should return 59.997?
353353
static int FrameTimingLimit() {
354-
bool challenge = Achievements::ChallengeModeActive();
354+
bool challenge = Achievements::HardcoreModeActive();
355355

356356
auto fixRate = [=](int limit) {
357357
int minRate = challenge ? 60 : 1;

Core/RetroAchievements.cpp

+27-18
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ std::string s_game_hash;
7777
std::set<uint32_t> g_activeChallenges;
7878
bool g_isIdentifying = false;
7979
bool g_isLoggingIn = false;
80+
bool g_hasRichPresence = false;
8081
int g_loginResult;
8182

8283
double g_lastLoginAttemptTime;
@@ -104,6 +105,19 @@ bool IsLoggedIn() {
104105
return rc_client_get_user_info(g_rcClient) != nullptr && !g_isLoggingIn;
105106
}
106107

108+
// This is the RetroAchievements game ID, rather than the PSP game ID.
109+
static u32 GetGameID() {
110+
if (!g_rcClient) {
111+
return 0;
112+
}
113+
114+
const rc_client_game_t *info = rc_client_get_game_info(g_rcClient);
115+
if (!info) {
116+
return 0;
117+
}
118+
return info->id; // 0 if not identified
119+
}
120+
107121
bool EncoreModeActive() {
108122
if (!g_rcClient) {
109123
return false;
@@ -118,15 +132,23 @@ bool UnofficialEnabled() {
118132
return rc_client_get_unofficial_enabled(g_rcClient);
119133
}
120134

121-
bool ChallengeModeActive() {
135+
bool HardcoreModeActive() {
122136
if (!g_rcClient) {
123137
return false;
124138
}
125-
return IsLoggedIn() && rc_client_get_hardcore_enabled(g_rcClient);
139+
// See "Enabling Hardcore" under https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration.
140+
return IsLoggedIn() && rc_client_get_hardcore_enabled(g_rcClient) && rc_client_is_processing_required(g_rcClient);
126141
}
127142

128-
bool WarnUserIfChallengeModeActive(bool isSaveStateAction, const char *message) {
129-
if (!ChallengeModeActive() || (isSaveStateAction && g_Config.bAchievementsSaveStateInChallengeMode)) {
143+
size_t GetRichPresenceMessage(char *buffer, size_t bufSize) {
144+
if (!IsLoggedIn() || !rc_client_has_rich_presence(g_rcClient)) {
145+
return (size_t)-1;
146+
}
147+
return rc_client_get_rich_presence_message(g_rcClient, buffer, bufSize);
148+
}
149+
150+
bool WarnUserIfHardcoreModeActive(bool isSaveStateAction, const char *message) {
151+
if (!HardcoreModeActive() || (isSaveStateAction && g_Config.bAchievementsSaveStateInHardcoreMode)) {
130152
return false;
131153
}
132154

@@ -148,19 +170,6 @@ bool IsBlockingExecution() {
148170
return g_isLoggingIn || g_isIdentifying;
149171
}
150172

151-
// This is the RetroAchievements game ID, rather than the PSP game ID.
152-
static u32 GetGameID() {
153-
if (!g_rcClient) {
154-
return 0;
155-
}
156-
157-
const rc_client_game_t *info = rc_client_get_game_info(g_rcClient);
158-
if (!info) {
159-
return 0;
160-
}
161-
return info->id; // 0 if not identified
162-
}
163-
164173
bool IsActive() {
165174
return GetGameID() != 0;
166175
}
@@ -730,7 +739,7 @@ std::string GetGameAchievementSummary() {
730739
summaryString = ApplySafeSubstitutions(ac->T("Earned", "You have unlocked %1 of %2 achievements, earning %3 of %4 points"),
731740
summary.num_unlocked_achievements, summary.num_core_achievements + summary.num_unofficial_achievements,
732741
summary.points_unlocked, summary.points_core);
733-
if (ChallengeModeActive()) {
742+
if (HardcoreModeActive()) {
734743
summaryString.append("\n");
735744
summaryString.append(ac->T("Hardcore Mode"));
736745
}

Core/RetroAchievements.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,17 @@ bool IsBlockingExecution();
6868
//
6969
// * Savestates
7070
// * Slowdown time (though hard to fully prevent, could use crazy post shaders or software rendering...)
71-
bool ChallengeModeActive();
71+
bool HardcoreModeActive();
7272

7373
// Same as ChallengeModeActive but comes with a convenient user message. Don't use for every-frame checks or UI enablement,
7474
// only for shortcut keys and commands. You should look up the message in I18NCat::ACHIEVEMENTS.
7575
// If no message is specified, a standard "This feature is not available in Hardcore Mode" message will be shown.
7676
// Also returns true if hardcore mode is active.
7777
// Specify isSaveAction so we can still permit saves (but not loads) in hardcore mode if that option is enabled.
78-
bool WarnUserIfChallengeModeActive(bool isSaveStateAction, const char *message = nullptr);
78+
bool WarnUserIfHardcoreModeActive(bool isSaveStateAction, const char *message = nullptr);
79+
80+
// Returns the length of the string. If (size_t)-1, there's no message.
81+
size_t GetRichPresenceMessage(char *buffer, size_t bufSize);
7982

8083
// The new API is so much nicer that we can use it directly instead of wrapping it. So let's expose the client.
8184
// Will of course return nullptr if not active.

Core/SaveState.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,8 @@ namespace SaveState
399399

400400
void Enqueue(SaveState::Operation op)
401401
{
402-
if (Achievements::ChallengeModeActive()) {
403-
if (g_Config.bAchievementsSaveStateInChallengeMode && (op.type == SaveState::SAVESTATE_SAVE) || (op.type == SAVESTATE_SAVE_SCREENSHOT)) {
402+
if (Achievements::HardcoreModeActive()) {
403+
if (g_Config.bAchievementsSaveStateInHardcoreMode && (op.type == SaveState::SAVESTATE_SAVE) || (op.type == SAVESTATE_SAVE_SCREENSHOT)) {
404404
// We allow saving in hardcore mode if this setting is on.
405405
} else {
406406
// Operation not allowed

UI/EmuScreen.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ void EmuScreen::bootComplete() {
368368
System_Notify(SystemNotification::DISASSEMBLY);
369369

370370
NOTICE_LOG(BOOT, "Booted %s...", PSP_CoreParameter().fileToStart.c_str());
371-
if (!Achievements::ChallengeModeActive()) {
371+
if (!Achievements::HardcoreModeActive()) {
372372
// Don't auto-load savestates in hardcore mode.
373373
autoLoad();
374374
}
@@ -680,7 +680,7 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
680680
break;
681681

682682
case VIRTKEY_FRAME_ADVANCE:
683-
if (!Achievements::WarnUserIfChallengeModeActive(false)) {
683+
if (!Achievements::WarnUserIfHardcoreModeActive(false)) {
684684
if (down) {
685685
// If game is running, pause emulation immediately. Otherwise, advance a single frame.
686686
if (Core_IsStepping()) {
@@ -738,7 +738,7 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
738738
#endif
739739

740740
case VIRTKEY_REWIND:
741-
if (down && !Achievements::WarnUserIfChallengeModeActive(false)) {
741+
if (down && !Achievements::WarnUserIfHardcoreModeActive(false)) {
742742
if (SaveState::CanRewind()) {
743743
SaveState::Rewind(&AfterSaveStateAction);
744744
} else {
@@ -747,23 +747,23 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
747747
}
748748
break;
749749
case VIRTKEY_SAVE_STATE:
750-
if (down && !Achievements::WarnUserIfChallengeModeActive(true)) {
750+
if (down && !Achievements::WarnUserIfHardcoreModeActive(true)) {
751751
SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
752752
}
753753
break;
754754
case VIRTKEY_LOAD_STATE:
755-
if (down && !Achievements::WarnUserIfChallengeModeActive(false)) {
755+
if (down && !Achievements::WarnUserIfHardcoreModeActive(false)) {
756756
SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
757757
}
758758
break;
759759
case VIRTKEY_PREVIOUS_SLOT:
760-
if (down && !Achievements::WarnUserIfChallengeModeActive(true)) {
760+
if (down && !Achievements::WarnUserIfHardcoreModeActive(true)) {
761761
SaveState::PrevSlot();
762762
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
763763
}
764764
break;
765765
case VIRTKEY_NEXT_SLOT:
766-
if (down && !Achievements::WarnUserIfChallengeModeActive(true)) {
766+
if (down && !Achievements::WarnUserIfHardcoreModeActive(true)) {
767767
SaveState::NextSlot();
768768
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
769769
}

UI/PauseScreen.cpp

+12-6
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ SaveSlotView::SaveSlotView(const Path &gameFilename, int slot, bool vertical, UI
200200
fv->OnClick.Handle(this, &SaveSlotView::OnScreenshotClick);
201201

202202
if (SaveState::HasSaveInSlot(gamePath_, slot)) {
203-
if (!Achievements::ChallengeModeActive()) {
203+
if (!Achievements::HardcoreModeActive()) {
204204
loadStateButton_ = buttons->Add(new Button(pa->T("Load State"), new LinearLayoutParams(0.0, G_VCENTER)));
205205
loadStateButton_->OnClick.Handle(this, &SaveSlotView::OnLoadState);
206206
}
@@ -288,7 +288,7 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems,
288288
leftColumnItems->Add(new Spacer(0.0));
289289

290290
LinearLayout *buttonRow = leftColumnItems->Add(new LinearLayout(ORIENT_HORIZONTAL));
291-
if (g_Config.bEnableStateUndo && !Achievements::ChallengeModeActive()) {
291+
if (g_Config.bEnableStateUndo && !Achievements::HardcoreModeActive()) {
292292
UI::Choice *loadUndoButton = buttonRow->Add(new Choice(pa->T("Undo last load")));
293293
loadUndoButton->SetEnabled(SaveState::HasUndoLoad(gamePath_));
294294
loadUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLoadUndo);
@@ -298,7 +298,7 @@ void GamePauseScreen::CreateSavestateControls(UI::LinearLayout *leftColumnItems,
298298
saveUndoButton->OnClick.Handle(this, &GamePauseScreen::OnLastSaveUndo);
299299
}
300300

301-
if (g_Config.iRewindSnapshotInterval > 0 && !Achievements::ChallengeModeActive()) {
301+
if (g_Config.iRewindSnapshotInterval > 0 && !Achievements::HardcoreModeActive()) {
302302
UI::Choice *rewindButton = buttonRow->Add(new Choice(pa->T("Rewind")));
303303
rewindButton->SetEnabled(SaveState::CanRewind());
304304
rewindButton->OnClick.Handle(this, &GamePauseScreen::OnRewind);
@@ -324,13 +324,19 @@ void GamePauseScreen::CreateViews() {
324324
LinearLayout *leftColumnItems = new LinearLayoutList(ORIENT_VERTICAL, new LayoutParams(FILL_PARENT, WRAP_CONTENT));
325325
leftColumn->Add(leftColumnItems);
326326

327-
leftColumnItems->Add(new Spacer(0.0));
327+
leftColumnItems->SetSpacing(5.0f);
328+
leftColumnItems->Add(new Spacer(0.0f));
328329
if (Achievements::IsActive()) {
329330
leftColumnItems->Add(new GameAchievementSummaryView());
330-
leftColumnItems->Add(new Spacer(5.0));
331+
332+
char buf[512];
333+
size_t sz = Achievements::GetRichPresenceMessage(buf, sizeof(buf));
334+
if (sz != (size_t)-1) {
335+
leftColumnItems->Add(new TextView(std::string_view(buf, sz), new UI::LinearLayoutParams(Margins(5, 5))))->SetSmall(true);
336+
}
331337
}
332338

333-
if (!Achievements::ChallengeModeActive() || g_Config.bAchievementsSaveStateInChallengeMode) {
339+
if (!Achievements::HardcoreModeActive() || g_Config.bAchievementsSaveStateInHardcoreMode) {
334340
CreateSavestateControls(leftColumnItems, vertical);
335341
} else {
336342
// Let's show the active challenges.

UI/RetroAchievementScreens.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ void RetroAchievementsSettingsScreen::CreateDeveloperToolsTab(UI::ViewGroup *vie
380380
viewGroup->Add(new CheckBox(&g_Config.bAchievementsEncoreMode, ac->T("Encore Mode")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
381381
viewGroup->Add(new CheckBox(&g_Config.bAchievementsUnofficial, ac->T("Unofficial achievements")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
382382
viewGroup->Add(new CheckBox(&g_Config.bAchievementsLogBadMemReads, ac->T("Log bad memory accesses")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
383-
viewGroup->Add(new CheckBox(&g_Config.bAchievementsSaveStateInChallengeMode, ac->T("Allow Save State in Hardcore Mode (but not Load State)")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
383+
viewGroup->Add(new CheckBox(&g_Config.bAchievementsSaveStateInHardcoreMode, ac->T("Allow Save State in Hardcore Mode (but not Load State)")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
384384
}
385385

386386
void MeasureAchievement(const UIContext &dc, const rc_client_achievement_t *achievement, AchievementRenderStyle style, float *w, float *h) {

Windows/MainWindowMenu.cpp

+11-11
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ namespace MainWindow {
7474

7575
bool loadStateEnableBool = menuEnableBool;
7676
bool saveStateEnableBool = menuEnableBool;
77-
if (Achievements::ChallengeModeActive()) {
77+
if (Achievements::HardcoreModeActive()) {
7878
loadStateEnableBool = false;
79-
if (!g_Config.bAchievementsSaveStateInChallengeMode) {
79+
if (!g_Config.bAchievementsSaveStateInHardcoreMode) {
8080
saveStateEnableBool = false;
8181
}
8282
}
@@ -518,15 +518,15 @@ namespace MainWindow {
518518
}
519519
break;
520520
case ID_FILE_LOADSTATEFILE:
521-
if (!Achievements::WarnUserIfChallengeModeActive(false)) {
521+
if (!Achievements::WarnUserIfHardcoreModeActive(false)) {
522522
if (W32Util::BrowseForFileName(true, hWnd, L"Load state", 0, L"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0", L"ppst", fn)) {
523523
SetCursor(LoadCursor(0, IDC_WAIT));
524524
SaveState::Load(Path(fn), -1, SaveStateActionFinished);
525525
}
526526
}
527527
break;
528528
case ID_FILE_SAVESTATEFILE:
529-
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
529+
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
530530
if (W32Util::BrowseForFileName(false, hWnd, L"Save state", 0, L"Save States (*.ppst)\0*.ppst\0All files\0*.*\0\0", L"ppst", fn)) {
531531
SetCursor(LoadCursor(0, IDC_WAIT));
532532
SaveState::Save(Path(fn), -1, SaveStateActionFinished);
@@ -536,7 +536,7 @@ namespace MainWindow {
536536

537537
case ID_FILE_SAVESTATE_NEXT_SLOT:
538538
{
539-
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
539+
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
540540
SaveState::NextSlot();
541541
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
542542
}
@@ -545,7 +545,7 @@ namespace MainWindow {
545545

546546
case ID_FILE_SAVESTATE_NEXT_SLOT_HC:
547547
{
548-
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
548+
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
549549
if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT)) {
550550
SaveState::NextSlot();
551551
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
@@ -559,21 +559,21 @@ namespace MainWindow {
559559
case ID_FILE_SAVESTATE_SLOT_3:
560560
case ID_FILE_SAVESTATE_SLOT_4:
561561
case ID_FILE_SAVESTATE_SLOT_5:
562-
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
562+
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
563563
g_Config.iCurrentStateSlot = wmId - ID_FILE_SAVESTATE_SLOT_1;
564564
}
565565
break;
566566

567567
case ID_FILE_QUICKLOADSTATE:
568-
if (!Achievements::WarnUserIfChallengeModeActive(false)) {
568+
if (!Achievements::WarnUserIfHardcoreModeActive(false)) {
569569
SetCursor(LoadCursor(0, IDC_WAIT));
570570
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
571571
}
572572
break;
573573

574574
case ID_FILE_QUICKLOADSTATE_HC:
575575
{
576-
if (!Achievements::WarnUserIfChallengeModeActive(false)) {
576+
if (!Achievements::WarnUserIfHardcoreModeActive(false)) {
577577
if (!KeyMap::PspButtonHasMappings(VIRTKEY_LOAD_STATE)) {
578578
SetCursor(LoadCursor(0, IDC_WAIT));
579579
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
@@ -583,7 +583,7 @@ namespace MainWindow {
583583
}
584584
case ID_FILE_QUICKSAVESTATE:
585585
{
586-
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
586+
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
587587
SetCursor(LoadCursor(0, IDC_WAIT));
588588
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
589589
}
@@ -592,7 +592,7 @@ namespace MainWindow {
592592

593593
case ID_FILE_QUICKSAVESTATE_HC:
594594
{
595-
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
595+
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
596596
if (!KeyMap::PspButtonHasMappings(VIRTKEY_SAVE_STATE))
597597
{
598598
SetCursor(LoadCursor(0, IDC_WAIT));

0 commit comments

Comments
 (0)