diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 687ab0983c45..94595f432c89 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -240,6 +240,7 @@ namespace SaveState static bool needsProcess = false; static std::vector pending; static std::mutex mutex; + static int screenshotFailures = 0; static bool hasLoadedState = false; static const int STALE_STATE_USES = 2; // 4 hours of total gameplay since the virtual PSP started the game. @@ -249,6 +250,7 @@ namespace SaveState // TODO: Should this be configurable? static const int REWIND_NUM_STATES = 20; + static const int SCREENSHOT_FAILURE_RETRIES = 15; static StateRingbuffer rewindStates(REWIND_NUM_STATES); // TODO: Any reason for this to be configurable? const static float rewindMaxWallFrequency = 1.0f; @@ -852,6 +854,12 @@ namespace SaveState callbackResult = tempResult ? Status::SUCCESS : Status::FAILURE; if (!tempResult) { ERROR_LOG(SAVESTATE, "Failed to take a screenshot for the savestate! %s", op.filename.c_str()); + if (screenshotFailures++ < SCREENSHOT_FAILURE_RETRIES) { + // Requeue for next frame. + SaveScreenshot(op.filename, op.callback, op.cbUserData); + } + } else { + screenshotFailures = 0; } break; } diff --git a/UI/SavedataScreen.cpp b/UI/SavedataScreen.cpp index f8e49d8a2d8b..a017aa540d78 100644 --- a/UI/SavedataScreen.cpp +++ b/UI/SavedataScreen.cpp @@ -323,6 +323,8 @@ void SavedataBrowser::SetSortOption(SavedataSortOption opt) { gl->SetCompare(&ByFilename, &SortDone); } else if (sortOption_ == SavedataSortOption::SIZE) { gl->SetCompare(&BySize, &SortDone); + } else if (sortOption_ == SavedataSortOption::DATE) { + gl->SetCompare(&ByDate, &SortDone); } } } @@ -345,6 +347,29 @@ bool SavedataBrowser::BySize(const UI::View *v1, const UI::View *v2) { return g1info->gameSize > g2info->gameSize; } +bool SavedataBrowser::ByDate(const UI::View *v1, const UI::View *v2) { + const SavedataButton *b1 = static_cast(v1); + const SavedataButton *b2 = static_cast(v2); + + auto getDateSeconds = [&](const SavedataButton *b) { + std::shared_ptr ginfo = g_gameInfoCache->GetInfo(nullptr, b->GamePath(), 0); + tm datetm; + bool success; + if (ginfo && ginfo->fileType == IdentifiedFileType::PSP_SAVEDATA_DIRECTORY) { + success = File::GetModifTime(b->GamePath() + "/PARAM.SFO", datetm); + } else { + success = File::GetModifTime(b->GamePath(), datetm); + } + + if (success) { + return mktime(&datetm); + } + return (time_t)0; + }; + + return getDateSeconds(b1) > getDateSeconds(b2); +} + bool SavedataBrowser::SortDone() { PrioritizedWorkQueue *wq = g_gameInfoCache->WorkQueue(); return wq->Done(); @@ -454,6 +479,7 @@ void SavedataScreen::CreateViews() { ChoiceStrip *sortStrip = new ChoiceStrip(ORIENT_HORIZONTAL, new AnchorLayoutParams(NONE, 0, 0, NONE)); sortStrip->AddChoice(sa->T("Filename")); sortStrip->AddChoice(sa->T("Size")); + sortStrip->AddChoice(sa->T("Date")); sortStrip->SetSelection((int)sortOption_); sortStrip->OnChoice.Handle(this, &SavedataScreen::OnSortClick); diff --git a/UI/SavedataScreen.h b/UI/SavedataScreen.h index 0ab3e6ed56bc..49da3704838b 100644 --- a/UI/SavedataScreen.h +++ b/UI/SavedataScreen.h @@ -29,6 +29,7 @@ enum class SavedataSortOption { FILENAME, SIZE, + DATE, }; class SavedataBrowser : public UI::LinearLayout { @@ -42,6 +43,7 @@ class SavedataBrowser : public UI::LinearLayout { private: static bool ByFilename(const UI::View *, const UI::View *); static bool BySize(const UI::View *, const UI::View *); + static bool ByDate(const UI::View *, const UI::View *); static bool SortDone(); void Refresh();