System: Improve screenshot naming

This commit is contained in:
Stenzek 2024-03-15 15:21:06 +10:00
parent 6aa491f863
commit 43eb6e20fa
No known key found for this signature in database
5 changed files with 50 additions and 10 deletions

View file

@ -243,6 +243,16 @@ TEST(Path, SanitizeFileName)
ASSERT_EQ(Path::SanitizeFileName("foo/bar", false), "foo/bar"); ASSERT_EQ(Path::SanitizeFileName("foo/bar", false), "foo/bar");
} }
TEST(Path, RemoveLengthLimits)
{
#ifdef _WIN32
ASSERT_EQ(Path::RemoveLengthLimits("C:\\foo"), "\\\\?\\C:\\foo");
ASSERT_EQ(Path::RemoveLengthLimits("\\\\foo\\bar\\baz"), "\\\\?\\\\\\foo\\bar\\baz");
#else
ASSERT_EQ(Path::RemoveLengthLimits("/foo/bar/baz"), "/foo/bar/baz");
#endif
}
#if 0 #if 0
// Relies on presence of files. // Relies on presence of files.

View file

@ -182,6 +182,25 @@ void Path::SanitizeFileName(std::string* str, bool strip_slashes /* = true */)
#endif #endif
} }
std::string Path::RemoveLengthLimits(std::string_view str)
{
std::string ret;
#ifdef _WIN32
ret.reserve(str.length() + 4);
#endif
ret.append(str);
RemoveLengthLimits(&ret);
return ret;
}
void Path::RemoveLengthLimits(std::string* path)
{
DebugAssert(IsAbsolute(*path));
#ifdef _WIN32
path->insert(0, "\\\\?\\");
#endif
}
bool Path::IsAbsolute(const std::string_view& path) bool Path::IsAbsolute(const std::string_view& path)
{ {
#ifdef _WIN32 #ifdef _WIN32

View file

@ -28,6 +28,10 @@ void Canonicalize(std::string* path);
std::string SanitizeFileName(const std::string_view& str, bool strip_slashes = true); std::string SanitizeFileName(const std::string_view& str, bool strip_slashes = true);
void SanitizeFileName(std::string* str, bool strip_slashes = true); void SanitizeFileName(std::string* str, bool strip_slashes = true);
/// Mutates the path to remove any MAX_PATH limits (for Windows).
std::string RemoveLengthLimits(std::string_view str);
void RemoveLengthLimits(std::string* path);
/// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix). /// Returns true if the specified path is an absolute path (C:\Path on Windows or /path on Unix).
bool IsAbsolute(const std::string_view& path); bool IsAbsolute(const std::string_view& path);

View file

@ -2209,7 +2209,8 @@ bool GPU::RenderScreenshotToFile(std::string filename, DisplayScreenshotMode mod
return false; return false;
} }
auto fp = FileSystem::OpenManagedCFile(filename.c_str(), "wb"); // These filenames tend to be fairly long, so remove any MAX_PATH limit.
auto fp = FileSystem::OpenManagedCFile(Path::RemoveLengthLimits(filename).c_str(), "wb");
if (!fp) if (!fp)
{ {
Log_ErrorPrintf("Can't open file '%s': errno %d", filename.c_str(), errno); Log_ErrorPrintf("Can't open file '%s': errno %d", filename.c_str(), errno);

View file

@ -239,7 +239,7 @@ static time_t s_discord_presence_time_epoch;
static TinyString GetTimestampStringForFileName() static TinyString GetTimestampStringForFileName()
{ {
return TinyString::from_format("{:%Y-%m-%d_%H-%M-%S}", fmt::localtime(std::time(nullptr))); return TinyString::from_format("{:%Y-%m-%d-%H-%M-%S}", fmt::localtime(std::time(nullptr)));
} }
bool System::Internal::ProcessStartup() bool System::Internal::ProcessStartup()
@ -4348,17 +4348,23 @@ bool System::SaveScreenshot(const char* filename, DisplayScreenshotMode mode, Di
std::string auto_filename; std::string auto_filename;
if (!filename) if (!filename)
{ {
const auto& code = System::GetGameSerial(); const std::string& name = System::GetGameTitle();
const char* extension = Settings::GetDisplayScreenshotFormatExtension(format); const char* extension = Settings::GetDisplayScreenshotFormatExtension(format);
if (code.empty()) std::string basename;
{ if (name.empty())
auto_filename = basename = fmt::format("{}", GetTimestampStringForFileName());
Path::Combine(EmuFolders::Screenshots, fmt::format("{}.{}", GetTimestampStringForFileName(), extension));
}
else else
basename = fmt::format("{} {}", name, GetTimestampStringForFileName());
auto_filename = fmt::format("{}" FS_OSPATH_SEPARATOR_STR "{}.{}", EmuFolders::Screenshots, basename, extension);
// handle quick screenshots to the same filename
u32 next_suffix = 1;
while (FileSystem::FileExists(Path::RemoveLengthLimits(auto_filename).c_str()))
{ {
auto_filename = Path::Combine(EmuFolders::Screenshots, auto_filename = fmt::format("{}" FS_OSPATH_SEPARATOR_STR "{} ({}).{}", EmuFolders::Screenshots, basename,
fmt::format("{}_{}.{}", code, GetTimestampStringForFileName(), extension)); next_suffix, extension);
next_suffix++;
} }
filename = auto_filename.c_str(); filename = auto_filename.c_str();