Achievement savestate fixes
This commit is contained in:
parent
01667feccc
commit
9bd67df5b2
11 changed files with 81 additions and 13 deletions
|
@ -147,6 +147,11 @@ public:
|
||||||
|
|
||||||
void DoMarker(const char *prevName, u32 arbitraryNumber = 0x42);
|
void DoMarker(const char *prevName, u32 arbitraryNumber = 0x42);
|
||||||
|
|
||||||
|
void SkipBytes(size_t bytes) {
|
||||||
|
// Should work in all modes.
|
||||||
|
*ptr += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
size_t Offset() const { return *ptr - ptrStart_; }
|
size_t Offset() const { return *ptr - ptrStart_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -85,8 +85,7 @@
|
||||||
#include "sceDmac.h"
|
#include "sceDmac.h"
|
||||||
#include "sceMp4.h"
|
#include "sceMp4.h"
|
||||||
#include "sceOpenPSID.h"
|
#include "sceOpenPSID.h"
|
||||||
|
#include "Core/Util/PPGeDraw.h"
|
||||||
#include "../Util/PPGeDraw.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
17: [MIPS32 R4K 00000000 ]: Loader: Type: 1 Vaddr: 00000000 Filesz: 2856816 Memsz: 2856816
|
17: [MIPS32 R4K 00000000 ]: Loader: Type: 1 Vaddr: 00000000 Filesz: 2856816 Memsz: 2856816
|
||||||
|
|
|
@ -354,6 +354,11 @@ static void event_handler_callback(const rc_client_event_t *event, rc_client_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() {
|
void Initialize() {
|
||||||
|
if (!g_Config.bAchievementsEnable) {
|
||||||
|
_dbg_assert_(!g_rcClient);
|
||||||
|
INFO_LOG(ACHIEVEMENTS, "Achievements are disabled, not initializing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
_assert_msg_(g_Config.bAchievementsEnable, "Achievements are enabled");
|
_assert_msg_(g_Config.bAchievementsEnable, "Achievements are enabled");
|
||||||
|
|
||||||
g_challengeMode = true; // the default
|
g_challengeMode = true; // the default
|
||||||
|
@ -453,14 +458,27 @@ void Idle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoState(PointerWrap &p) {
|
void DoState(PointerWrap &p) {
|
||||||
auto sw = p.Section("Achievements", 1);
|
auto sw = p.Section("Achievements", 0, 1);
|
||||||
if (!sw) {
|
if (!sw) {
|
||||||
// Save state is missing the section.
|
// Save state is missing the section.
|
||||||
// Reset the runtime.
|
// Reset the runtime.
|
||||||
|
if (HasAchievementsOrLeaderboards()) {
|
||||||
|
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
|
||||||
|
g_OSD.Show(OSDType::MESSAGE_WARNING, ac->T("Save state loaded without achievement data"), 5.0f);
|
||||||
|
}
|
||||||
|
rc_client_reset(g_rcClient);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t data_size = 0;
|
uint32_t data_size = 0;
|
||||||
|
|
||||||
|
if (!g_activeGame) {
|
||||||
|
WARN_LOG(ACHIEVEMENTS, "Save state contained achievement data, but achievements are not active. Ignore.");
|
||||||
|
Do(p, data_size);
|
||||||
|
p.SkipBytes(data_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (p.mode == PointerWrap::MODE_MEASURE || p.mode == PointerWrap::MODE_WRITE || p.mode == PointerWrap::MODE_VERIFY || p.mode == PointerWrap::MODE_NOOP) {
|
if (p.mode == PointerWrap::MODE_MEASURE || p.mode == PointerWrap::MODE_WRITE || p.mode == PointerWrap::MODE_VERIFY || p.mode == PointerWrap::MODE_NOOP) {
|
||||||
data_size = (uint32_t)(g_rcClient ? rc_client_progress_size(g_rcClient) : 0);
|
data_size = (uint32_t)(g_rcClient ? rc_client_progress_size(g_rcClient) : 0);
|
||||||
}
|
}
|
||||||
|
@ -473,18 +491,35 @@ void DoState(PointerWrap &p) {
|
||||||
case PointerWrap::MODE_MEASURE:
|
case PointerWrap::MODE_MEASURE:
|
||||||
case PointerWrap::MODE_WRITE:
|
case PointerWrap::MODE_WRITE:
|
||||||
case PointerWrap::MODE_VERIFY:
|
case PointerWrap::MODE_VERIFY:
|
||||||
rc_client_serialize_progress(g_rcClient, buffer);
|
{
|
||||||
|
int retval = rc_client_serialize_progress(g_rcClient, buffer);
|
||||||
|
if (retval != RC_OK) {
|
||||||
|
ERROR_LOG(ACHIEVEMENTS, "Error %d serializing achievement data. Ignoring.", retval);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DoArray(p, buffer, data_size);
|
DoArray(p, buffer, data_size);
|
||||||
|
|
||||||
switch (p.mode) {
|
switch (p.mode) {
|
||||||
case PointerWrap::MODE_READ:
|
case PointerWrap::MODE_READ:
|
||||||
rc_client_deserialize_progress(g_rcClient, buffer);
|
{
|
||||||
|
int retval = rc_client_deserialize_progress(g_rcClient, buffer);
|
||||||
|
if (retval != RC_OK) {
|
||||||
|
// TODO: What should we really do here?
|
||||||
|
ERROR_LOG(ACHIEVEMENTS, "Error %d deserializing achievement data. Ignoring.", retval);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
} else {
|
||||||
|
if (HasAchievementsOrLeaderboards()) {
|
||||||
|
auto ac = GetI18NCategory(I18NCat::ACHIEVEMENTS);
|
||||||
|
g_OSD.Show(OSDType::MESSAGE_WARNING, ac->T("Save state loaded without achievement data"), 5.0f);
|
||||||
|
}
|
||||||
|
rc_client_reset(g_rcClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,6 +645,7 @@ void UnloadGame() {
|
||||||
if (g_rcClient) {
|
if (g_rcClient) {
|
||||||
rc_client_unload_game(g_rcClient);
|
rc_client_unload_game(g_rcClient);
|
||||||
}
|
}
|
||||||
|
g_activeGame = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void change_media_callback(int result, const char *error_message, rc_client_t *client, void *userdata) {
|
void change_media_callback(int result, const char *error_message, rc_client_t *client, void *userdata) {
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "Core/MemMap.h"
|
#include "Core/MemMap.h"
|
||||||
#include "Core/MIPS/MIPS.h"
|
#include "Core/MIPS/MIPS.h"
|
||||||
#include "Core/MIPS/JitCommon/JitBlockCache.h"
|
#include "Core/MIPS/JitCommon/JitBlockCache.h"
|
||||||
|
#include "Core/RetroAchievements.h"
|
||||||
#include "HW/MemoryStick.h"
|
#include "HW/MemoryStick.h"
|
||||||
#include "GPU/GPUState.h"
|
#include "GPU/GPUState.h"
|
||||||
|
|
||||||
|
@ -391,6 +392,7 @@ namespace SaveState
|
||||||
currentMIPS->DoState(p);
|
currentMIPS->DoState(p);
|
||||||
HLEDoState(p);
|
HLEDoState(p);
|
||||||
__KernelDoState(p);
|
__KernelDoState(p);
|
||||||
|
Achievements::DoState(p);
|
||||||
// Kernel object destructors might close open files, so do the filesystem last.
|
// Kernel object destructors might close open files, so do the filesystem last.
|
||||||
pspFileSystem.DoState(p);
|
pspFileSystem.DoState(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,9 @@ void RetroAchievementsSettingsScreen::CreateAccountTab(UI::ViewGroup *viewGroup)
|
||||||
|
|
||||||
using namespace UI;
|
using namespace UI;
|
||||||
|
|
||||||
if (Achievements::IsLoggedIn()) {
|
if (!g_Config.bAchievementsEnable) {
|
||||||
|
viewGroup->Add(new TextView(ac->T("Achievements are disabled")));
|
||||||
|
} else if (Achievements::IsLoggedIn()) {
|
||||||
const rc_client_user_t *info = rc_client_get_user_info(Achievements::GetClient());
|
const rc_client_user_t *info = rc_client_get_user_info(Achievements::GetClient());
|
||||||
|
|
||||||
// In the future, RetroAchievements will support display names. Prepare for that.
|
// In the future, RetroAchievements will support display names. Prepare for that.
|
||||||
|
@ -255,9 +257,14 @@ void RetroAchievementsSettingsScreen::CreateSettingsTab(UI::ViewGroup *viewGroup
|
||||||
|
|
||||||
using namespace UI;
|
using namespace UI;
|
||||||
viewGroup->Add(new ItemHeader(ac->T("Settings")));
|
viewGroup->Add(new ItemHeader(ac->T("Settings")));
|
||||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsRichPresence, ac->T("Rich Presence")));
|
viewGroup->Add(new CheckBox(&g_Config.bAchievementsEnable, ac->T("Achievements enabled")))->OnClick.Add([&](UI::EventParams &e) -> UI::EventReturn {
|
||||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsSoundEffects, ac->T("Sound Effects"))); // not yet implemented
|
Achievements::UpdateSettings();
|
||||||
viewGroup->Add(new CheckBox(&g_Config.bAchievementsLogBadMemReads, ac->T("Log bad memory accesses")));
|
RecreateViews();
|
||||||
|
return UI::EVENT_DONE;
|
||||||
|
});
|
||||||
|
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);
|
||||||
|
|
||||||
// Not yet fully implemented
|
// Not yet fully implemented
|
||||||
// viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode (no savestates)")));
|
// viewGroup->Add(new CheckBox(&g_Config.bAchievementsChallengeMode, ac->T("Challenge Mode (no savestates)")));
|
||||||
|
|
|
@ -106,6 +106,9 @@
|
||||||
<ClInclude Include="Theme.h" />
|
<ClInclude Include="Theme.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Core\Core.vcxproj">
|
||||||
|
<Project>{533f1d30-d04d-47cc-ad71-20f658907e36}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\ext\discord-rpc-build\discord-rpc.vcxproj">
|
<ProjectReference Include="..\ext\discord-rpc-build\discord-rpc.vcxproj">
|
||||||
<Project>{beb0a821-3c7f-410f-a525-63afbc69bf8f}</Project>
|
<Project>{beb0a821-3c7f-410f-a525-63afbc69bf8f}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
%d achievements, %d points = %d achievements, %d points
|
%d achievements, %d points = %d achievements, %d points
|
||||||
Account = Account
|
Account = Account
|
||||||
Achievements = Achievements
|
Achievements = Achievements
|
||||||
|
Achievements are disabled = Achievements are disabled
|
||||||
Challenge Mode = Challenge Mode
|
Challenge Mode = Challenge Mode
|
||||||
Challenge Mode (no savestates) = Challenge Mode (no savestates)
|
Challenge Mode (no savestates) = Challenge Mode (no savestates)
|
||||||
Earned = You have earned %d of %d achievements, and %d of %d points
|
Earned = You have earned %d of %d achievements, and %d of %d points
|
||||||
|
@ -33,7 +34,6 @@ How to use RetroAchievements = How to use RetroAchievements
|
||||||
Leaderboard submission is enabled = Leaderboard submission is enabled
|
Leaderboard submission is enabled = Leaderboard submission is enabled
|
||||||
Leaderboards = Leaderboards
|
Leaderboards = Leaderboards
|
||||||
Links = Links
|
Links = Links
|
||||||
Local = Local
|
|
||||||
Locked achievements = Locked achievements
|
Locked achievements = Locked achievements
|
||||||
Log bad memory accesses = Log bad memory accesses
|
Log bad memory accesses = Log bad memory accesses
|
||||||
Mastered %1 = Mastered %1
|
Mastered %1 = Mastered %1
|
||||||
|
@ -41,6 +41,7 @@ Register on www.retroachievements.org = Register on www.retroachievements.org
|
||||||
RetroAchievements are not available for this game = RetroAchievements are not available for this game
|
RetroAchievements are not available for this game = RetroAchievements are not available for this game
|
||||||
RetroAchievements website = RetroAchievements website
|
RetroAchievements website = RetroAchievements website
|
||||||
Rich Presence = Rich Presence
|
Rich Presence = Rich Presence
|
||||||
|
Save state loaded without achievement data = Save state loaded without achievement data
|
||||||
Sound Effects = Sound Effects
|
Sound Effects = Sound Effects
|
||||||
Statistics = Statistics
|
Statistics = Statistics
|
||||||
Submitted Score = Submitted Score
|
Submitted Score = Submitted Score
|
||||||
|
|
|
@ -143,6 +143,12 @@ void System_AudioGetDebugStats(char *buf, size_t bufSize) { if (buf) buf[0] = '\
|
||||||
void System_AudioClear() {}
|
void System_AudioClear() {}
|
||||||
void System_AudioPushSamples(const s32 *audio, int numSamples) {}
|
void System_AudioPushSamples(const s32 *audio, int numSamples) {}
|
||||||
|
|
||||||
|
// TODO: To avoid having to define these here, these should probably be turned into system "requests".
|
||||||
|
void NativeSaveSecret(const char *nameOfSecret, const std::string &data) {}
|
||||||
|
std::string NativeLoadSecret(const char *nameOfSecret) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
int printUsage(const char *progname, const char *reason)
|
int printUsage(const char *progname, const char *reason)
|
||||||
{
|
{
|
||||||
if (reason != NULL)
|
if (reason != NULL)
|
||||||
|
|
|
@ -508,6 +508,9 @@
|
||||||
<ProjectReference Include="..\ext\libzstd.vcxproj">
|
<ProjectReference Include="..\ext\libzstd.vcxproj">
|
||||||
<Project>{8bfd8150-94d5-4bf9-8a50-7bd9929a0850}</Project>
|
<Project>{8bfd8150-94d5-4bf9-8a50-7bd9929a0850}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\ext\rcheevos-build\rcheevos.vcxproj">
|
||||||
|
<Project>{31694510-a8c0-40f6-b09b-e8df825adefa}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\GPU\GPU.vcxproj">
|
<ProjectReference Include="..\GPU\GPU.vcxproj">
|
||||||
<Project>{457f45d2-556f-47bc-a31d-aff0d15beaed}</Project>
|
<Project>{457f45d2-556f-47bc-a31d-aff0d15beaed}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -103,6 +103,12 @@ void System_AudioGetDebugStats(char *buf, size_t bufSize) { if (buf) buf[0] = '\
|
||||||
void System_AudioClear() {}
|
void System_AudioClear() {}
|
||||||
void System_AudioPushSamples(const s32 *audio, int numSamples) {}
|
void System_AudioPushSamples(const s32 *audio, int numSamples) {}
|
||||||
|
|
||||||
|
// TODO: To avoid having to define these here, these should probably be turned into system "requests".
|
||||||
|
void NativeSaveSecret(const char *nameOfSecret, const std::string &data) {}
|
||||||
|
std::string NativeLoadSecret(const char *nameOfSecret) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
#if PPSSPP_PLATFORM(ANDROID)
|
#if PPSSPP_PLATFORM(ANDROID)
|
||||||
JNIEnv *getEnv() {
|
JNIEnv *getEnv() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -426,15 +426,15 @@
|
||||||
<ProjectReference Include="..\ext\libzstd.vcxproj">
|
<ProjectReference Include="..\ext\libzstd.vcxproj">
|
||||||
<Project>{8bfd8150-94d5-4bf9-8a50-7bd9929a0850}</Project>
|
<Project>{8bfd8150-94d5-4bf9-8a50-7bd9929a0850}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\ext\rcheevos-build\rcheevos.vcxproj">
|
||||||
|
<Project>{31694510-a8c0-40f6-b09b-e8df825adefa}</Project>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\ext\zlib\zlib.vcxproj">
|
<ProjectReference Include="..\ext\zlib\zlib.vcxproj">
|
||||||
<Project>{f761046e-6c38-4428-a5f1-38391a37bb34}</Project>
|
<Project>{f761046e-6c38-4428-a5f1-38391a37bb34}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\GPU\GPU.vcxproj">
|
<ProjectReference Include="..\GPU\GPU.vcxproj">
|
||||||
<Project>{457f45d2-556f-47bc-a31d-aff0d15beaed}</Project>
|
<Project>{457f45d2-556f-47bc-a31d-aff0d15beaed}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\UI\UI.vcxproj">
|
|
||||||
<Project>{004b8d11-2be3-4bd9-ab40-2be04cf2096f}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="JitHarness.h" />
|
<ClInclude Include="JitHarness.h" />
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue