mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 21:39:52 +00:00
Merge pull request #18468 from hrydgard/more-retroachievements-tweaks
RetroAchievements: Show rich presence message on pause screen, restriction tweaks
This commit is contained in:
commit
1065e18521
@ -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
|
||||
|
@ -513,7 +513,7 @@ public:
|
||||
bool bAchievementsUnofficial;
|
||||
bool bAchievementsSoundEffects;
|
||||
bool bAchievementsLogBadMemReads;
|
||||
bool bAchievementsSaveStateInChallengeMode;
|
||||
bool bAchievementsSaveStateInHardcoreMode;
|
||||
|
||||
// Positioning of the various notifications
|
||||
int iAchievementsLeaderboardTrackerPos;
|
||||
|
@ -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.
|
||||
@ -1196,7 +1196,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat,
|
||||
}
|
||||
|
||||
void CWCheatEngine::Run() {
|
||||
if (Achievements::ChallengeModeActive()) {
|
||||
if (Achievements::HardcoreModeActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1214,7 +1214,7 @@ bool CWCheatEngine::HasCheats() {
|
||||
}
|
||||
|
||||
bool CheatsInEffect() {
|
||||
if (!cheatEngine || !cheatsEnabled || Achievements::ChallengeModeActive())
|
||||
if (!cheatEngine || !cheatsEnabled || Achievements::HardcoreModeActive())
|
||||
return false;
|
||||
return cheatEngine->HasCheats();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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"));
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
@ -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()) {
|
||||
@ -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 {
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
@ -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);
|
||||
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
@ -518,7 +518,7 @@ 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);
|
||||
@ -526,7 +526,7 @@ namespace MainWindow {
|
||||
}
|
||||
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);
|
||||
@ -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);
|
||||
}
|
||||
@ -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);
|
||||
@ -559,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(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);
|
||||
}
|
||||
@ -573,7 +573,7 @@ namespace MainWindow {
|
||||
|
||||
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);
|
||||
@ -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);
|
||||
}
|
||||
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user