Skip to content

Commit

Permalink
Merge pull request #18468 from hrydgard/more-retroachievements-tweaks
Browse files Browse the repository at this point in the history
RetroAchievements: Show rich presence message on pause screen, restriction tweaks
  • Loading branch information
hrydgard committed Dec 3, 2023
2 parents 0f262d5 + 17c779c commit 1065e18
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ static const ConfigSetting achievementSettings[] = {
ConfigSetting("AchievementsEncoreMode", &g_Config.bAchievementsEncoreMode, false, CfgFlag::DEFAULT),
ConfigSetting("AchievementsUnofficial", &g_Config.bAchievementsUnofficial, false, CfgFlag::DEFAULT),
ConfigSetting("AchievementsLogBadMemReads", &g_Config.bAchievementsLogBadMemReads, false, CfgFlag::DEFAULT),
ConfigSetting("bAchievementsSaveStateInChallengeMode", &g_Config.bAchievementsSaveStateInChallengeMode, false, CfgFlag::DEFAULT),
ConfigSetting("bAchievementsSaveStateInChallengeMode", &g_Config.bAchievementsSaveStateInHardcoreMode, false, CfgFlag::DEFAULT),

// Achievements login info. Note that password is NOT stored, only a login token.
// And that login token is stored separately from the ini, see NativeSaveSecret, but it can also be loaded
Expand Down
2 changes: 1 addition & 1 deletion Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ struct Config {
bool bAchievementsUnofficial;
bool bAchievementsSoundEffects;
bool bAchievementsLogBadMemReads;
bool bAchievementsSaveStateInChallengeMode;
bool bAchievementsSaveStateInHardcoreMode;

// Positioning of the various notifications
int iAchievementsLeaderboardTrackerPos;
Expand Down
6 changes: 3 additions & 3 deletions Core/CwCheat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ void __CheatDoState(PointerWrap &p) {
}

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

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

void CWCheatEngine::Run() {
if (Achievements::ChallengeModeActive()) {
if (Achievements::HardcoreModeActive()) {
return;
}

Expand All @@ -1214,7 +1214,7 @@ bool CWCheatEngine::HasCheats() {
}

bool CheatsInEffect() {
if (!cheatEngine || !cheatsEnabled || Achievements::ChallengeModeActive())
if (!cheatEngine || !cheatsEnabled || Achievements::HardcoreModeActive())
return false;
return cheatEngine->HasCheats();
}
2 changes: 1 addition & 1 deletion Core/HLE/sceDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ void __DisplaySetWasPaused() {

// TOOD: Should return 59.997?
static int FrameTimingLimit() {
bool challenge = Achievements::ChallengeModeActive();
bool challenge = Achievements::HardcoreModeActive();

auto fixRate = [=](int limit) {
int minRate = challenge ? 60 : 1;
Expand Down
45 changes: 27 additions & 18 deletions Core/RetroAchievements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ std::string s_game_hash;
std::set<uint32_t> g_activeChallenges;
bool g_isIdentifying = false;
bool g_isLoggingIn = false;
bool g_hasRichPresence = false;
int g_loginResult;

double g_lastLoginAttemptTime;
Expand Down Expand Up @@ -104,6 +105,19 @@ bool IsLoggedIn() {
return rc_client_get_user_info(g_rcClient) != nullptr && !g_isLoggingIn;
}

// This is the RetroAchievements game ID, rather than the PSP game ID.
static u32 GetGameID() {
if (!g_rcClient) {
return 0;
}

const rc_client_game_t *info = rc_client_get_game_info(g_rcClient);
if (!info) {
return 0;
}
return info->id; // 0 if not identified
}

bool EncoreModeActive() {
if (!g_rcClient) {
return false;
Expand All @@ -118,15 +132,23 @@ bool UnofficialEnabled() {
return rc_client_get_unofficial_enabled(g_rcClient);
}

bool ChallengeModeActive() {
bool HardcoreModeActive() {
if (!g_rcClient) {
return false;
}
return IsLoggedIn() && rc_client_get_hardcore_enabled(g_rcClient);
// See "Enabling Hardcore" under https://github.com/RetroAchievements/rcheevos/wiki/rc_client-integration.
return IsLoggedIn() && rc_client_get_hardcore_enabled(g_rcClient) && rc_client_is_processing_required(g_rcClient);
}

bool WarnUserIfChallengeModeActive(bool isSaveStateAction, const char *message) {
if (!ChallengeModeActive() || (isSaveStateAction && g_Config.bAchievementsSaveStateInChallengeMode)) {
size_t GetRichPresenceMessage(char *buffer, size_t bufSize) {
if (!IsLoggedIn() || !rc_client_has_rich_presence(g_rcClient)) {
return (size_t)-1;
}
return rc_client_get_rich_presence_message(g_rcClient, buffer, bufSize);
}

bool WarnUserIfHardcoreModeActive(bool isSaveStateAction, const char *message) {
if (!HardcoreModeActive() || (isSaveStateAction && g_Config.bAchievementsSaveStateInHardcoreMode)) {
return false;
}

Expand All @@ -148,19 +170,6 @@ bool IsBlockingExecution() {
return g_isLoggingIn || g_isIdentifying;
}

// This is the RetroAchievements game ID, rather than the PSP game ID.
static u32 GetGameID() {
if (!g_rcClient) {
return 0;
}

const rc_client_game_t *info = rc_client_get_game_info(g_rcClient);
if (!info) {
return 0;
}
return info->id; // 0 if not identified
}

bool IsActive() {
return GetGameID() != 0;
}
Expand Down Expand Up @@ -730,7 +739,7 @@ std::string GetGameAchievementSummary() {
summaryString = ApplySafeSubstitutions(ac->T("Earned", "You have unlocked %1 of %2 achievements, earning %3 of %4 points"),
summary.num_unlocked_achievements, summary.num_core_achievements + summary.num_unofficial_achievements,
summary.points_unlocked, summary.points_core);
if (ChallengeModeActive()) {
if (HardcoreModeActive()) {
summaryString.append("\n");
summaryString.append(ac->T("Hardcore Mode"));
}
Expand Down
7 changes: 5 additions & 2 deletions Core/RetroAchievements.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@ bool IsBlockingExecution();
//
// * Savestates
// * Slowdown time (though hard to fully prevent, could use crazy post shaders or software rendering...)
bool ChallengeModeActive();
bool HardcoreModeActive();

// 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 Hardcore Mode" message will be shown.
// Also returns true if hardcore mode is active.
// Specify isSaveAction so we can still permit saves (but not loads) in hardcore mode if that option is enabled.
bool WarnUserIfChallengeModeActive(bool isSaveStateAction, const char *message = nullptr);
bool WarnUserIfHardcoreModeActive(bool isSaveStateAction, const char *message = nullptr);

// Returns the length of the string. If (size_t)-1, there's no message.
size_t GetRichPresenceMessage(char *buffer, size_t bufSize);

// 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.
Expand Down
4 changes: 2 additions & 2 deletions Core/SaveState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,8 @@ namespace SaveState

void Enqueue(SaveState::Operation op)
{
if (Achievements::ChallengeModeActive()) {
if (g_Config.bAchievementsSaveStateInChallengeMode && (op.type == SaveState::SAVESTATE_SAVE) || (op.type == SAVESTATE_SAVE_SCREENSHOT)) {
if (Achievements::HardcoreModeActive()) {
if (g_Config.bAchievementsSaveStateInHardcoreMode && (op.type == SaveState::SAVESTATE_SAVE) || (op.type == SAVESTATE_SAVE_SCREENSHOT)) {
// We allow saving in hardcore mode if this setting is on.
} else {
// Operation not allowed
Expand Down
14 changes: 7 additions & 7 deletions UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ void EmuScreen::bootComplete() {
System_Notify(SystemNotification::DISASSEMBLY);

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

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

case VIRTKEY_REWIND:
if (down && !Achievements::WarnUserIfChallengeModeActive(false)) {
if (down && !Achievements::WarnUserIfHardcoreModeActive(false)) {
if (SaveState::CanRewind()) {
SaveState::Rewind(&AfterSaveStateAction);
} else {
Expand All @@ -747,23 +747,23 @@ void EmuScreen::onVKey(int virtualKeyCode, bool down) {
}
break;
case VIRTKEY_SAVE_STATE:
if (down && !Achievements::WarnUserIfChallengeModeActive(true)) {
if (down && !Achievements::WarnUserIfHardcoreModeActive(true)) {
SaveState::SaveSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
}
break;
case VIRTKEY_LOAD_STATE:
if (down && !Achievements::WarnUserIfChallengeModeActive(false)) {
if (down && !Achievements::WarnUserIfHardcoreModeActive(false)) {
SaveState::LoadSlot(gamePath_, g_Config.iCurrentStateSlot, &AfterSaveStateAction);
}
break;
case VIRTKEY_PREVIOUS_SLOT:
if (down && !Achievements::WarnUserIfChallengeModeActive(true)) {
if (down && !Achievements::WarnUserIfHardcoreModeActive(true)) {
SaveState::PrevSlot();
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
}
break;
case VIRTKEY_NEXT_SLOT:
if (down && !Achievements::WarnUserIfChallengeModeActive(true)) {
if (down && !Achievements::WarnUserIfHardcoreModeActive(true)) {
SaveState::NextSlot();
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
}
Expand Down
18 changes: 12 additions & 6 deletions UI/PauseScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ SaveSlotView::SaveSlotView(const Path &gameFilename, int slot, bool vertical, UI
fv->OnClick.Handle(this, &SaveSlotView::OnScreenshotClick);

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

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

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

leftColumnItems->Add(new Spacer(0.0));
leftColumnItems->SetSpacing(5.0f);
leftColumnItems->Add(new Spacer(0.0f));
if (Achievements::IsActive()) {
leftColumnItems->Add(new GameAchievementSummaryView());
leftColumnItems->Add(new Spacer(5.0));

char buf[512];
size_t sz = Achievements::GetRichPresenceMessage(buf, sizeof(buf));
if (sz != (size_t)-1) {
leftColumnItems->Add(new TextView(std::string_view(buf, sz), new UI::LinearLayoutParams(Margins(5, 5))))->SetSmall(true);
}
}

if (!Achievements::ChallengeModeActive() || g_Config.bAchievementsSaveStateInChallengeMode) {
if (!Achievements::HardcoreModeActive() || g_Config.bAchievementsSaveStateInHardcoreMode) {
CreateSavestateControls(leftColumnItems, vertical);
} else {
// Let's show the active challenges.
Expand Down
2 changes: 1 addition & 1 deletion UI/RetroAchievementScreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ void RetroAchievementsSettingsScreen::CreateDeveloperToolsTab(UI::ViewGroup *vie
viewGroup->Add(new CheckBox(&g_Config.bAchievementsEncoreMode, ac->T("Encore Mode")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
viewGroup->Add(new CheckBox(&g_Config.bAchievementsUnofficial, ac->T("Unofficial achievements")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
viewGroup->Add(new CheckBox(&g_Config.bAchievementsLogBadMemReads, ac->T("Log bad memory accesses")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
viewGroup->Add(new CheckBox(&g_Config.bAchievementsSaveStateInChallengeMode, ac->T("Allow Save State in Hardcore Mode (but not Load State)")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
viewGroup->Add(new CheckBox(&g_Config.bAchievementsSaveStateInHardcoreMode, ac->T("Allow Save State in Hardcore Mode (but not Load State)")))->SetEnabledPtr(&g_Config.bAchievementsEnable);
}

void MeasureAchievement(const UIContext &dc, const rc_client_achievement_t *achievement, AchievementRenderStyle style, float *w, float *h) {
Expand Down
22 changes: 11 additions & 11 deletions Windows/MainWindowMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ namespace MainWindow {

bool loadStateEnableBool = menuEnableBool;
bool saveStateEnableBool = menuEnableBool;
if (Achievements::ChallengeModeActive()) {
if (Achievements::HardcoreModeActive()) {
loadStateEnableBool = false;
if (!g_Config.bAchievementsSaveStateInChallengeMode) {
if (!g_Config.bAchievementsSaveStateInHardcoreMode) {
saveStateEnableBool = false;
}
}
Expand Down Expand Up @@ -518,15 +518,15 @@ namespace MainWindow {
}
break;
case ID_FILE_LOADSTATEFILE:
if (!Achievements::WarnUserIfChallengeModeActive(false)) {
if (!Achievements::WarnUserIfHardcoreModeActive(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);
}
}
break;
case ID_FILE_SAVESTATEFILE:
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
if (!Achievements::WarnUserIfHardcoreModeActive(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);
Expand All @@ -536,7 +536,7 @@ namespace MainWindow {

case ID_FILE_SAVESTATE_NEXT_SLOT:
{
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
SaveState::NextSlot();
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
}
Expand All @@ -545,7 +545,7 @@ namespace MainWindow {

case ID_FILE_SAVESTATE_NEXT_SLOT_HC:
{
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
if (!KeyMap::PspButtonHasMappings(VIRTKEY_NEXT_SLOT)) {
SaveState::NextSlot();
System_PostUIMessage(UIMessage::SAVESTATE_DISPLAY_SLOT);
Expand All @@ -559,21 +559,21 @@ namespace MainWindow {
case ID_FILE_SAVESTATE_SLOT_3:
case ID_FILE_SAVESTATE_SLOT_4:
case ID_FILE_SAVESTATE_SLOT_5:
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
g_Config.iCurrentStateSlot = wmId - ID_FILE_SAVESTATE_SLOT_1;
}
break;

case ID_FILE_QUICKLOADSTATE:
if (!Achievements::WarnUserIfChallengeModeActive(false)) {
if (!Achievements::WarnUserIfHardcoreModeActive(false)) {
SetCursor(LoadCursor(0, IDC_WAIT));
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
}
break;

case ID_FILE_QUICKLOADSTATE_HC:
{
if (!Achievements::WarnUserIfChallengeModeActive(false)) {
if (!Achievements::WarnUserIfHardcoreModeActive(false)) {
if (!KeyMap::PspButtonHasMappings(VIRTKEY_LOAD_STATE)) {
SetCursor(LoadCursor(0, IDC_WAIT));
SaveState::LoadSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
Expand All @@ -583,7 +583,7 @@ namespace MainWindow {
}
case ID_FILE_QUICKSAVESTATE:
{
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
SetCursor(LoadCursor(0, IDC_WAIT));
SaveState::SaveSlot(PSP_CoreParameter().fileToStart, g_Config.iCurrentStateSlot, SaveStateActionFinished);
}
Expand All @@ -592,7 +592,7 @@ namespace MainWindow {

case ID_FILE_QUICKSAVESTATE_HC:
{
if (!Achievements::WarnUserIfChallengeModeActive(true)) {
if (!Achievements::WarnUserIfHardcoreModeActive(true)) {
if (!KeyMap::PspButtonHasMappings(VIRTKEY_SAVE_STATE))
{
SetCursor(LoadCursor(0, IDC_WAIT));
Expand Down

0 comments on commit 1065e18

Please sign in to comment.