From f716d781b6c575415df950753daaf5cfd7a755f8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 2 Nov 2013 17:40:23 -0700 Subject: [PATCH 1/4] Retain threadend waits in savestates. Oops, been broken since 3fb2c8f654cafe85e50586bb51d8a3c4c0e10674. --- Core/HLE/sceKernelThread.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 7c9ea34949..6e5f8d2d10 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -520,7 +520,7 @@ public: virtual void DoState(PointerWrap &p) { - auto s = p.Section("Thread", 1); + auto s = p.Section("Thread", 1, 2); if (!s) return; @@ -537,6 +537,12 @@ public: p.Do(pendingMipsCalls); p.Do(pushedStacks); p.Do(currentStack); + + if (s >= 2) + { + p.Do(waitingThreads); + p.Do(pausedWaits); + } } NativeThread nt; From 79254c7a527b0db86795bec8c74cad738c14f29a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 2 Nov 2013 18:32:34 -0700 Subject: [PATCH 2/4] Fix some rewinding issues, better accessors. --- Core/SaveState.cpp | 23 ++++++++++++++++++++--- Core/SaveState.h | 3 +++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 0f71933c16..673ecb2e81 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -75,7 +75,7 @@ namespace SaveState CChunkFileReader::Error Save() { int n = next_++ % size_; - if (n == first_) + if ((next_ % size_) == first_) ++first_; SaveStart state; @@ -89,7 +89,7 @@ namespace SaveState CChunkFileReader::Error Restore() { // No valid states left. - if (next_ == first_) + if (Empty()) return CChunkFileReader::ERROR_BAD_FILE; int n = (next_-- + size_) % size_; @@ -100,6 +100,17 @@ namespace SaveState return CChunkFileReader::LoadPtr(&states_[n][0], state); } + void Clear() + { + first_ = 0; + next_ = 0; + } + + bool Empty() + { + return next_ == first_; + } + typedef std::vector StateBuffer; int first_; int next_; @@ -179,6 +190,11 @@ namespace SaveState Enqueue(Operation(SAVESTATE_REWIND, std::string(""), callback, cbUserData)); } + bool CanRewind() + { + return !rewindStates.Empty(); + } + // Slot utilities @@ -317,7 +333,7 @@ namespace SaveState void Process() { - if (rewindStateFreq != 0) + if (rewindStateFreq != 0 && gpuStats.numFlips != 0) CheckRewindState(); if (!needsProcess) @@ -429,5 +445,6 @@ namespace SaveState pspFileSystem.MkDir("ms0:/PSP/PPSSPP_STATE"); std::lock_guard guard(mutex); + rewindStates.Clear(); } } diff --git a/Core/SaveState.h b/Core/SaveState.h index b2b9fda16d..65eccdb9ae 100644 --- a/Core/SaveState.h +++ b/Core/SaveState.h @@ -52,6 +52,9 @@ namespace SaveState // Warning: callback will be called on a different thread. void Rewind(Callback callback = 0, void *cbUserData = 0); + // Returns true if there are rewind snapshots available. + bool CanRewind(); + // Check if there's any save stating needing to be done. Normally called once per frame. void Process(); }; From 2f010773e1c1f8740d94df5cea1159885d194916 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 2 Nov 2013 18:33:23 -0700 Subject: [PATCH 3/4] Add rewind feature to the UI. May not be perfect yet. --- Core/Config.cpp | 2 ++ Core/Config.h | 1 + Core/SaveState.cpp | 6 ++---- UI/GameSettingsScreen.cpp | 1 + UI/MainScreen.cpp | 14 ++++++++++++++ UI/MainScreen.h | 1 + 6 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index c2162ddece..73ed515c97 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -75,6 +75,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) { general->Get("EnableCheats", &bEnableCheats, false); general->Get("ScreenshotsAsPNG", &bScreenshotsAsPNG, false); general->Get("StateSlot", &iCurrentStateSlot, 0); + general->Get("RewindFlipFrequency", &iRewindFlipFrequency, 0); general->Get("GridView1", &bGridView1, true); general->Get("GridView2", &bGridView2, true); general->Get("GridView3", &bGridView3, true); @@ -341,6 +342,7 @@ void Config::Save() { general->Set("EnableCheats", bEnableCheats); general->Set("ScreenshotsAsPNG", bScreenshotsAsPNG); general->Set("StateSlot", iCurrentStateSlot); + general->Set("RewindFlipFrequency", iRewindFlipFrequency); general->Set("GridView1", bGridView1); general->Set("GridView2", bGridView2); general->Set("GridView3", bGridView3); diff --git a/Core/Config.h b/Core/Config.h index 7358ee7076..d28168d366 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -92,6 +92,7 @@ public: int iForceMaxEmulatedFPS; int iMaxRecent; int iCurrentStateSlot; + int iRewindFlipFrequency; bool bEnableCheats; bool bReloadCheats; bool bDisableStencilTest; diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 673ecb2e81..4cb48e7d65 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -125,8 +125,6 @@ namespace SaveState // TODO: Should this be configurable? static const int REWIND_NUM_STATES = 5; static StateRingbuffer rewindStates(REWIND_NUM_STATES); - // TODO: g_Config setting or something instead. - static int rewindStateFreq = 0; // TODO: Any reason for this to be configurable? const static float rewindMaxWallFrequency = 1.0f; static float rewindLastTime = 0.0f; @@ -318,7 +316,7 @@ namespace SaveState static inline void CheckRewindState() { - if (gpuStats.numFlips % rewindStateFreq != 0) + if (gpuStats.numFlips % g_Config.iRewindFlipFrequency != 0) return; // For fast-forwarding, otherwise they may be useless and too close. @@ -333,7 +331,7 @@ namespace SaveState void Process() { - if (rewindStateFreq != 0 && gpuStats.numFlips != 0) + if (g_Config.iRewindFlipFrequency != 0 && gpuStats.numFlips != 0) CheckRewindState(); if (!needsProcess) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index dc2ec89e63..fa83aca318 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -254,6 +254,7 @@ void GameSettingsScreen::CreateViews() { systemSettings->Add(new CheckBox(&g_Config.bSeparateIOThread, s->T("I/O on thread (experimental)")))->SetEnabled(!PSP_IsInited()); #endif systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, s->T("Change CPU Clock", "Change CPU Clock (0 = default)"), screenManager())); + systemSettings->Add(new PopupSliderChoice(&g_Config.iRewindFlipFrequency, 0, 1800, s->T("Rewind Snapshot Frequency (0 = off)"), screenManager())); systemSettings->Add(new CheckBox(&g_Config.bAtomicAudioLocks, s->T("Atomic Audio locks (experimental)")))->SetEnabled(!PSP_IsInited()); diff --git a/UI/MainScreen.cpp b/UI/MainScreen.cpp index 4c11c98f4e..a13864e470 100644 --- a/UI/MainScreen.cpp +++ b/UI/MainScreen.cpp @@ -779,6 +779,12 @@ void GamePauseScreen::CreateViews() { loadStateButton_ = leftColumnItems->Add(new Choice(i->T("Load State"))); loadStateButton_->OnClick.Handle(this, &GamePauseScreen::OnLoadState); + if (g_Config.iRewindFlipFrequency > 0) { + UI::Choice *rewindButton = leftColumnItems->Add(new Choice(i->T("Rewind"))); + rewindButton->SetEnabled(SaveState::CanRewind()); + rewindButton->OnClick.Handle(this, &GamePauseScreen::OnRewind); + } + ViewGroup *rightColumn = new ScrollView(ORIENT_VERTICAL, new LinearLayoutParams(300, FILL_PARENT, actionMenuMargins)); root_->Add(rightColumn); @@ -833,6 +839,14 @@ UI::EventReturn GamePauseScreen::OnSaveState(UI::EventParams &e) { screenManager()->finishDialog(this, DR_CANCEL); return UI::EVENT_DONE; } + +UI::EventReturn GamePauseScreen::OnRewind(UI::EventParams &e) { + SaveState::Rewind(0, 0); + + screenManager()->finishDialog(this, DR_CANCEL); + return UI::EVENT_DONE; +} + UI::EventReturn GamePauseScreen::OnCwCheat(UI::EventParams &e) { screenManager()->push(new CwCheatScreen()); return UI::EVENT_DONE; diff --git a/UI/MainScreen.h b/UI/MainScreen.h index bdac77ca83..4bdcdb9065 100644 --- a/UI/MainScreen.h +++ b/UI/MainScreen.h @@ -72,6 +72,7 @@ private: UI::EventReturn OnSaveState(UI::EventParams &e); UI::EventReturn OnLoadState(UI::EventParams &e); + UI::EventReturn OnRewind(UI::EventParams &e); UI::EventReturn OnStateSelected(UI::EventParams &e); UI::EventReturn OnCwCheat(UI::EventParams &e); From 3591d9d33e9537ea2ccbf2040f43cc32b01bc099 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 2 Nov 2013 18:35:48 -0700 Subject: [PATCH 4/4] Add a warning for people with low mem devices. --- UI/GameSettingsScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index fa83aca318..b903fba78a 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -254,7 +254,7 @@ void GameSettingsScreen::CreateViews() { systemSettings->Add(new CheckBox(&g_Config.bSeparateIOThread, s->T("I/O on thread (experimental)")))->SetEnabled(!PSP_IsInited()); #endif systemSettings->Add(new PopupSliderChoice(&g_Config.iLockedCPUSpeed, 0, 1000, s->T("Change CPU Clock", "Change CPU Clock (0 = default)"), screenManager())); - systemSettings->Add(new PopupSliderChoice(&g_Config.iRewindFlipFrequency, 0, 1800, s->T("Rewind Snapshot Frequency (0 = off)"), screenManager())); + systemSettings->Add(new PopupSliderChoice(&g_Config.iRewindFlipFrequency, 0, 1800, s->T("Rewind Snapshot Frequency (0 = off, mem hog)"), screenManager())); systemSettings->Add(new CheckBox(&g_Config.bAtomicAudioLocks, s->T("Atomic Audio locks (experimental)")))->SetEnabled(!PSP_IsInited());