mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #4420 from unknownbrackets/savestates
Enable rewind feature in UI, fix a savestate bug
This commit is contained in:
commit
b2298a9e86
8 changed files with 50 additions and 7 deletions
|
@ -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);
|
||||
|
|
|
@ -92,6 +92,7 @@ public:
|
|||
int iForceMaxEmulatedFPS;
|
||||
int iMaxRecent;
|
||||
int iCurrentStateSlot;
|
||||
int iRewindFlipFrequency;
|
||||
bool bEnableCheats;
|
||||
bool bReloadCheats;
|
||||
bool bDisableStencilTest;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<u8> StateBuffer;
|
||||
int first_;
|
||||
int next_;
|
||||
|
@ -114,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;
|
||||
|
@ -179,6 +188,11 @@ namespace SaveState
|
|||
Enqueue(Operation(SAVESTATE_REWIND, std::string(""), callback, cbUserData));
|
||||
}
|
||||
|
||||
bool CanRewind()
|
||||
{
|
||||
return !rewindStates.Empty();
|
||||
}
|
||||
|
||||
|
||||
// Slot utilities
|
||||
|
||||
|
@ -302,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.
|
||||
|
@ -317,7 +331,7 @@ namespace SaveState
|
|||
|
||||
void Process()
|
||||
{
|
||||
if (rewindStateFreq != 0)
|
||||
if (g_Config.iRewindFlipFrequency != 0 && gpuStats.numFlips != 0)
|
||||
CheckRewindState();
|
||||
|
||||
if (!needsProcess)
|
||||
|
@ -429,5 +443,6 @@ namespace SaveState
|
|||
pspFileSystem.MkDir("ms0:/PSP/PPSSPP_STATE");
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(mutex);
|
||||
rewindStates.Clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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, mem hog)"), screenManager()));
|
||||
|
||||
systemSettings->Add(new CheckBox(&g_Config.bAtomicAudioLocks, s->T("Atomic Audio locks (experimental)")))->SetEnabled(!PSP_IsInited());
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue