diff --git a/Core/SaveState.cpp b/Core/SaveState.cpp index 1dfa5a86ee..810b82f0db 100644 --- a/Core/SaveState.cpp +++ b/Core/SaveState.cpp @@ -735,6 +735,21 @@ int g_screenshotFailures; Rescan(gamePrefix); } + std::vector GetCompanionFilePaths(const Path &statePath) { + const std::string stateExtension = std::string(".") + STATE_EXTENSION; + // A path that isn't a savestate yields nothing, which WithReplacedExtension now tells us + // rather than handing back the path itself. An undo state does work, and correctly: + // "x.undo.ppst" maps onto "x.undo.jpg". + std::vector paths; + for (const char *extension : { SCREENSHOT_EXTENSION, NAME_EXTENSION }) { + Path companion; + if (statePath.WithReplacedExtension(stateExtension, std::string(".") + extension, &companion)) { + paths.push_back(companion); + } + } + return paths; + } + std::vector Flush() { std::lock_guard guard(mutex); std::vector copy = g_pendingOperations; diff --git a/Core/SaveState.h b/Core/SaveState.h index b20a689c53..746c4c3f11 100644 --- a/Core/SaveState.h +++ b/Core/SaveState.h @@ -79,6 +79,12 @@ namespace SaveState { Path GenerateSaveSlotPath(std::string_view gamePrefix, int slot, const char *extension); void SetSlotCustomName(std::string_view gamePrefix, int slot, std::string_view newName); + // The files that sit beside a savestate and mean nothing without it: its screenshot, and the + // slot's custom name if it was given one. Anything deleting a .ppst from outside DeleteSlot - + // the savestate browser does exactly that - has to take these along, or they stay in the + // savestate folder for good. Returns nothing for a path that isn't a savestate. + std::vector GetCompanionFilePaths(const Path &statePath); + std::string GetTitle(const Path &filename); // Load the specified file into the current state (async.) diff --git a/UI/GameInfoCache.cpp b/UI/GameInfoCache.cpp index 5d353f2eb2..20fa67ae97 100644 --- a/UI/GameInfoCache.cpp +++ b/UI/GameInfoCache.cpp @@ -170,9 +170,11 @@ bool GameInfo::Delete() { const Path &ppstPath = filePath_; INFO_LOG(Log::System, "Deleting file %s", ppstPath.c_str()); MoveFileToTrashOrDelete(ppstPath); - Path screenshotPath; - if (filePath_.WithReplacedExtension(".ppst", ".jpg", &screenshotPath) && File::Exists(screenshotPath)) { - MoveFileToTrashOrDelete(screenshotPath); + // The screenshot and the slot's custom name are no use without the state itself. + for (const Path &companion : SaveState::GetCompanionFilePaths(ppstPath)) { + if (File::Exists(companion)) { + MoveFileToTrashOrDelete(companion); + } } return true; }