From 862d4ea328ed30d79f4e28eb9119e21e275295d9 Mon Sep 17 00:00:00 2001 From: Craig Robbins Date: Tue, 31 Mar 2015 16:13:42 +1000 Subject: [PATCH] Change format of screenshot names Filename screenshot_ + ISO 8601 format + [-serial] i.e. screenshot_YYYY-MM-DDTHH::MM::SS[-serial].png Serial is added if the filename + timestamp already exists and is in the range 1 to 999 --- src/client.cpp | 52 +++++++++++++++++++++++++++++++++---------------- src/constants.h | 6 ++++++ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 6ee918ad0..611a73bb1 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -1704,26 +1704,43 @@ void Client::makeScreenshot(IrrlichtDevice *device) { irr::video::IVideoDriver *driver = device->getVideoDriver(); irr::video::IImage* const raw_image = driver->createScreenShot(); - if (raw_image) { - irr::video::IImage* const image = driver->createImage(video::ECF_R8G8B8, - raw_image->getDimension()); + + if (!raw_image) + return; + + time_t t = time(NULL); + struct tm *tm = localtime(&t); + + char timetstamp_c[64]; + strftime(timetstamp_c, sizeof(timetstamp_c), "%FT%T", tm); + + std::string filename_base = g_settings->get("screenshot_path") + + DIR_DELIM + + std::string("screenshot_") + + std::string(timetstamp_c); + std::string filename_ext = ".png"; + std::string filename; + + // Try to find a unique filename + unsigned serial = 0; + + while (serial < SCREENSHOT_MAX_SERIAL_TRIES) { + filename = filename_base + (serial > 0 ? ("-" + itos(serial)) : "") + filename_ext; + std::ifstream tmp(filename.c_str()); + if (!tmp.good()) + break; // File did not apparently exist, we'll go with it + serial++; + } + + if (serial == SCREENSHOT_MAX_SERIAL_TRIES) { + infostream << "Could not find suitable filename for screenshot" << std::endl; + } else { + irr::video::IImage* const image = + driver->createImage(video::ECF_R8G8B8, raw_image->getDimension()); if (image) { raw_image->copyTo(image); - std::string filename; - - time_t t = time(NULL); - struct tm *tm = localtime(&t); - char timetstamp_c[16]; // YYYYMMDD_HHMMSS + '\0' - strftime(timetstamp_c, sizeof(timetstamp_c), "%Y%m%d_%H%M%S", tm); - - filename = g_settings->get("screenshot_path") - + DIR_DELIM - + std::string("screenshot_") - + std::string(timetstamp_c) - + ".png"; - std::ostringstream sstr; if (driver->writeImageToFile(image, filename.c_str())) { sstr << "Saved screenshot to '" << filename << "'"; @@ -1734,8 +1751,9 @@ void Client::makeScreenshot(IrrlichtDevice *device) infostream << sstr.str() << std::endl; image->drop(); } - raw_image->drop(); } + + raw_image->drop(); } // IGameDef interface diff --git a/src/constants.h b/src/constants.h index d7163bf68..22cadc5a8 100644 --- a/src/constants.h +++ b/src/constants.h @@ -97,6 +97,12 @@ with this program; if not, write to the Free Software Foundation, Inc., // TODO: Use case-insensitive player names instead of this hack. #define PLAYER_FILE_ALTERNATE_TRIES 1000 +// For screenshots a serial number is appended to the filename + datetimestamp +// if filename + datetimestamp is not unique. +// This is the maximum number of attempts to try and add a serial to the end of +// the file attempting to ensure a unique filename +#define SCREENSHOT_MAX_SERIAL_TRIES 1000 + /* GUI related things */