Use the time of creating the screenshot, not the time of saving the screenshot

This commit is contained in:
Maschell 2024-03-01 20:58:41 +01:00
parent f447e0333f
commit c6e247c5cb
9 changed files with 53 additions and 44 deletions

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <coreinit/time.h>
#define WIIU_SCREENSHOT_PATH "fs:/vol/external01/wiiu/screenshots/" #define WIIU_SCREENSHOT_PATH "fs:/vol/external01/wiiu/screenshots/"
enum ImageOutputFormatEnum { enum ImageOutputFormatEnum {
@ -19,3 +20,8 @@ enum ScreenshotState {
SCREENSHOT_STATE_REQUESTED, SCREENSHOT_STATE_REQUESTED,
SCREENSHOT_STATE_SAVING, SCREENSHOT_STATE_SAVING,
}; };
struct ScreenshotStateInfo {
ScreenshotState state;
OSCalendarTime time;
};

View File

@ -217,7 +217,7 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro
&boolItemCallback)); &boolItemCallback));
} catch (std::exception &e) { } catch (std::exception &e) {
OSReport("Exception T_T : %s\n", e.what()); OSReport("Exception: %s\n", e.what());
return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; return WUPSCONFIG_API_CALLBACK_RESULT_ERROR;
} }

View File

@ -43,10 +43,13 @@ void RequestScreenshot() {
gNotAvailableNotificationDisplayed = true; gNotAvailableNotificationDisplayed = true;
} }
} else { } else {
OSCalendarTime time;
OSTicksToCalendarTime(OSGetTime(), &time);
if (gImageSource == IMAGE_SOURCE_TV_AND_DRC || gImageSource == IMAGE_SOURCE_TV) { if (gImageSource == IMAGE_SOURCE_TV_AND_DRC || gImageSource == IMAGE_SOURCE_TV) {
if (gTakeScreenshotTV == SCREENSHOT_STATE_READY) { if (gTakeScreenshotTV.state == SCREENSHOT_STATE_READY) {
DEBUG_FUNCTION_LINE("Requested screenshot for TV!"); DEBUG_FUNCTION_LINE("Requested screenshot for TV!");
gTakeScreenshotTV = SCREENSHOT_STATE_REQUESTED; gTakeScreenshotTV.state = SCREENSHOT_STATE_REQUESTED;
gTakeScreenshotTV.time = time;
gReadySinceFramesTV = 0; gReadySinceFramesTV = 0;
} else if (!gInProgressNotificationDisplayedTV) { } else if (!gInProgressNotificationDisplayedTV) {
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the TV already in progress.", if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the TV already in progress.",
@ -64,9 +67,11 @@ void RequestScreenshot() {
DEBUG_FUNCTION_LINE("Screenshots are blocked for DRC because it's not connected"); DEBUG_FUNCTION_LINE("Screenshots are blocked for DRC because it's not connected");
return; return;
} }
if (gTakeScreenshotDRC == SCREENSHOT_STATE_READY) { if (gTakeScreenshotDRC.state == SCREENSHOT_STATE_READY) {
DEBUG_FUNCTION_LINE("Requested screenshot for DRC!"); DEBUG_FUNCTION_LINE("Requested screenshot for DRC!");
gTakeScreenshotDRC = SCREENSHOT_STATE_REQUESTED; gTakeScreenshotDRC.state = SCREENSHOT_STATE_REQUESTED;
gTakeScreenshotDRC.time = time;
gReadySinceFramesDRC = 0; gReadySinceFramesDRC = 0;
} else if (!gInProgressNotificationDisplayedDRC) { } else if (!gInProgressNotificationDisplayedDRC) {
if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the GamePad already in progress.", if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the GamePad already in progress.",
@ -169,29 +174,29 @@ DECL_FUNCTION(void, WPADRead, WPADChan chan, WPADStatusProController *data) {
DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) { DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) {
if (gEnabled) { if (gEnabled) {
if (gCheckIfScreenRendered) { if (gCheckIfScreenRendered) {
if (gTakeScreenshotTV == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesTV > 5) { if (gTakeScreenshotTV.state == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesTV > 5) {
gTakeScreenshotTV = SCREENSHOT_STATE_READY; gTakeScreenshotTV.state = SCREENSHOT_STATE_READY;
gReadySinceFramesTV = 0; gReadySinceFramesTV = 0;
} else if (gTakeScreenshotDRC == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesDRC > 5) { } else if (gTakeScreenshotDRC.state == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesDRC > 5) {
gTakeScreenshotDRC = SCREENSHOT_STATE_READY; gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY;
gReadySinceFramesDRC = 0; gReadySinceFramesDRC = 0;
} }
} }
if (scan_target == GX2_SCAN_TARGET_TV && colorBuffer != nullptr && gTakeScreenshotTV == SCREENSHOT_STATE_REQUESTED) { if (scan_target == GX2_SCAN_TARGET_TV && colorBuffer != nullptr && gTakeScreenshotTV.state == SCREENSHOT_STATE_REQUESTED) {
gReadySinceFramesTV = 0; gReadySinceFramesTV = 0;
DEBUG_FUNCTION_LINE("Lets take a screenshot from TV."); DEBUG_FUNCTION_LINE("Lets take a screenshot from TV.");
if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality)) { if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotTV.time)) {
gTakeScreenshotTV = SCREENSHOT_STATE_READY; gTakeScreenshotTV.state = SCREENSHOT_STATE_READY;
} else { } else {
gTakeScreenshotTV = SCREENSHOT_STATE_SAVING; gTakeScreenshotTV.state = SCREENSHOT_STATE_SAVING;
} }
} else if (scan_target == GX2_SCAN_TARGET_DRC0 && colorBuffer != nullptr && gTakeScreenshotDRC == SCREENSHOT_STATE_REQUESTED) { } else if (scan_target == GX2_SCAN_TARGET_DRC0 && colorBuffer != nullptr && gTakeScreenshotDRC.state == SCREENSHOT_STATE_REQUESTED) {
gReadySinceFramesDRC = 0; gReadySinceFramesDRC = 0;
DEBUG_FUNCTION_LINE("Lets take a screenshot from DRC."); DEBUG_FUNCTION_LINE("Lets take a screenshot from DRC.");
if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality)) { if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotDRC.time)) {
gTakeScreenshotDRC = SCREENSHOT_STATE_READY; gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY;
} else { } else {
gTakeScreenshotDRC = SCREENSHOT_STATE_SAVING; gTakeScreenshotDRC.state = SCREENSHOT_STATE_SAVING;
} }
} }
} }
@ -226,19 +231,19 @@ DECL_FUNCTION(void, GX2GetCurrentScanBuffer, GX2ScanTarget scanTarget, GX2ColorB
DECL_FUNCTION(void, GX2MarkScanBufferCopied, GX2ScanTarget scan_target) { DECL_FUNCTION(void, GX2MarkScanBufferCopied, GX2ScanTarget scan_target) {
if (gEnabled) { if (gEnabled) {
if (scan_target == GX2_SCAN_TARGET_TV && gTakeScreenshotTV == SCREENSHOT_STATE_REQUESTED) { if (scan_target == GX2_SCAN_TARGET_TV && gTakeScreenshotTV.state == SCREENSHOT_STATE_REQUESTED) {
DEBUG_FUNCTION_LINE("Lets take a screenshot from TV."); DEBUG_FUNCTION_LINE("Lets take a screenshot from TV.");
if (!takeScreenshot((GX2ColorBuffer *) &lastTVColorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality)) { if (!takeScreenshot((GX2ColorBuffer *) &lastTVColorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotTV.time)) {
gTakeScreenshotTV = SCREENSHOT_STATE_READY; gTakeScreenshotTV.state = SCREENSHOT_STATE_READY;
} else { } else {
gTakeScreenshotTV = SCREENSHOT_STATE_SAVING; gTakeScreenshotTV.state = SCREENSHOT_STATE_SAVING;
} }
} else if (scan_target == GX2_SCAN_TARGET_DRC0 && gTakeScreenshotDRC == SCREENSHOT_STATE_REQUESTED) { } else if (scan_target == GX2_SCAN_TARGET_DRC0 && gTakeScreenshotDRC.state == SCREENSHOT_STATE_REQUESTED) {
DEBUG_FUNCTION_LINE("Lets take a screenshot from DRC."); DEBUG_FUNCTION_LINE("Lets take a screenshot from DRC.");
if (!takeScreenshot((GX2ColorBuffer *) &lastDRCColorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality)) { if (!takeScreenshot((GX2ColorBuffer *) &lastDRCColorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotDRC.time)) {
gTakeScreenshotDRC = SCREENSHOT_STATE_READY; gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY;
} else { } else {
gTakeScreenshotDRC = SCREENSHOT_STATE_SAVING; gTakeScreenshotDRC.state = SCREENSHOT_STATE_SAVING;
} }
} }
} }

View File

@ -14,8 +14,8 @@ bool gReservedBitUsage = RESERVED_BIT_USAGE_CONFIG_DEFAULT;
std::string gShortNameEn; std::string gShortNameEn;
ScreenshotState gTakeScreenshotTV = SCREENSHOT_STATE_READY; ScreenshotStateInfo gTakeScreenshotTV = {SCREENSHOT_STATE_READY};
ScreenshotState gTakeScreenshotDRC = SCREENSHOT_STATE_READY; ScreenshotStateInfo gTakeScreenshotDRC = {SCREENSHOT_STATE_READY};
bool gInProgressNotificationDisplayedDRC = false; bool gInProgressNotificationDisplayedDRC = false;
bool gInProgressNotificationDisplayedTV = false; bool gInProgressNotificationDisplayedTV = false;

View File

@ -16,8 +16,8 @@ extern bool gReservedBitUsage;
extern std::string gShortNameEn; extern std::string gShortNameEn;
extern ScreenshotState gTakeScreenshotTV; extern ScreenshotStateInfo gTakeScreenshotTV;
extern ScreenshotState gTakeScreenshotDRC; extern ScreenshotStateInfo gTakeScreenshotDRC;
extern bool gInProgressNotificationDisplayedDRC; extern bool gInProgressNotificationDisplayedDRC;

View File

@ -180,14 +180,14 @@ static bool copyBuffer(GX2ColorBuffer *sourceBuffer, GX2ColorBuffer *targetBuffe
void ScreenshotSavedCallback(NotificationModuleHandle handle, void *context) { void ScreenshotSavedCallback(NotificationModuleHandle handle, void *context) {
auto scanTarget = (GX2ScanTarget) (uint32_t) context; auto scanTarget = (GX2ScanTarget) (uint32_t) context;
if (scanTarget == GX2_SCAN_TARGET_TV) { if (scanTarget == GX2_SCAN_TARGET_TV) {
gTakeScreenshotTV = SCREENSHOT_STATE_READY; gTakeScreenshotTV.state = SCREENSHOT_STATE_READY;
} else { } else {
gTakeScreenshotDRC = SCREENSHOT_STATE_READY; gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY;
} }
OSMemoryBarrier(); OSMemoryBarrier();
} }
bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2SurfaceFormat outputBufferSurfaceFormat, ImageOutputFormatEnum outputFormat, int quality) { bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2SurfaceFormat outputBufferSurfaceFormat, ImageOutputFormatEnum outputFormat, int quality, const OSCalendarTime &time) {
if (srcBuffer == nullptr) { if (srcBuffer == nullptr) {
DEBUG_FUNCTION_LINE_ERR("Source buffer was NULL"); DEBUG_FUNCTION_LINE_ERR("Source buffer was NULL");
return false; return false;
@ -262,6 +262,7 @@ bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2Surf
param->quality = quality; param->quality = quality;
param->format = colorBuffer.surface.format; param->format = colorBuffer.surface.format;
param->scanTarget = scanTarget; param->scanTarget = scanTarget;
param->time = time;
res = sendMessageToThread(param); res = sendMessageToThread(param);
if (!res) { if (!res) {

View File

@ -9,5 +9,4 @@
bool saveTextureAsPicture(const std::string &path, uint8_t *sourceBuffer, uint32_t width, uint32_t height, uint32_t pitch, GX2SurfaceFormat format, ImageOutputFormatEnum outputFormat, bool convertRGBtoSRGB, int quality); bool saveTextureAsPicture(const std::string &path, uint8_t *sourceBuffer, uint32_t width, uint32_t height, uint32_t pitch, GX2SurfaceFormat format, ImageOutputFormatEnum outputFormat, bool convertRGBtoSRGB, int quality);
bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2SurfaceFormat outputBufferSurfaceFormat, ImageOutputFormatEnum outputFormat, int quality, const OSCalendarTime &time);
bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2SurfaceFormat outputBufferSurfaceFormat, ImageOutputFormatEnum outputFormat, int quality);

View File

@ -4,7 +4,6 @@
#include "screenshot_utils.h" #include "screenshot_utils.h"
#include "utils/StringTools.h" #include "utils/StringTools.h"
#include "utils/logger.h" #include "utils/logger.h"
#include "utils/utils.h"
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/title.h> #include <coreinit/title.h>
#include <dirent.h> #include <dirent.h>
@ -14,9 +13,7 @@
FSIOThreadData gThreadData; FSIOThreadData gThreadData;
bool gThreadsRunning; bool gThreadsRunning;
bool getPath(GX2ScanTarget scanTarget, ImageOutputFormatEnum outputFormat, std::string &path) { static bool getPath(GX2ScanTarget scanTarget, ImageOutputFormatEnum outputFormat, std::string &path, OSCalendarTime &output) {
OSCalendarTime output;
OSTicksToCalendarTime(OSGetTime(), &output);
std::string buffer = string_format("%s%016llX", WIIU_SCREENSHOT_PATH, OSGetTitleID()); std::string buffer = string_format("%s%016llX", WIIU_SCREENSHOT_PATH, OSGetTitleID());
if (!gShortNameEn.empty()) { if (!gShortNameEn.empty()) {
buffer += string_format(" (%s)", gShortNameEn.c_str()); buffer += string_format(" (%s)", gShortNameEn.c_str());
@ -66,7 +63,7 @@ bool getPath(GX2ScanTarget scanTarget, ImageOutputFormatEnum outputFormat, std::
return true; return true;
} }
static int32_t fsIOthreadCallback([[maybe_unused]] int argc, const char **argv) { static int32_t fsIOThreadCallback([[maybe_unused]] int argc, const char **argv) {
auto *magic = ((FSIOThreadData *) argv); auto *magic = ((FSIOThreadData *) argv);
constexpr int32_t messageSize = sizeof(magic->messages) / sizeof(magic->messages[0]); constexpr int32_t messageSize = sizeof(magic->messages) / sizeof(magic->messages[0]);
@ -81,7 +78,7 @@ static int32_t fsIOthreadCallback([[maybe_unused]] int argc, const char **argv)
std::string path; std::string path;
bool success = false; bool success = false;
if (getPath(message->scanTarget, message->outputFormat, path)) { if (getPath(message->scanTarget, message->outputFormat, path, message->time)) {
DEBUG_FUNCTION_LINE("Saving to %s", path.c_str()); DEBUG_FUNCTION_LINE("Saving to %s", path.c_str());
auto res = saveTextureAsPicture(path, message->sourceBuffer, message->width, message->height, message->pitch, message->format, message->outputFormat, message->convertRGBtoSRGB, message->quality); auto res = saveTextureAsPicture(path, message->sourceBuffer, message->width, message->height, message->pitch, message->format, message->outputFormat, message->convertRGBtoSRGB, message->quality);
if (res) { if (res) {
@ -155,7 +152,7 @@ void startFSIOThreads() {
OSMemoryBarrier(); OSMemoryBarrier();
if (!OSCreateThread(threadData->thread, &fsIOthreadCallback, 1, (char *) threadData, reinterpret_cast<void *>((uint32_t) threadData->stack + stackSize), stackSize, 31, OS_THREAD_ATTRIB_AFFINITY_ANY)) { if (!OSCreateThread(threadData->thread, &fsIOThreadCallback, 1, (char *) threadData, reinterpret_cast<void *>((uint32_t) threadData->stack + stackSize), stackSize, 31, OS_THREAD_ATTRIB_AFFINITY_ANY)) {
free(threadData->thread); free(threadData->thread);
free(threadData->stack); free(threadData->stack);
threadData->setup = false; threadData->setup = false;

View File

@ -27,6 +27,7 @@ struct SaveScreenshotMessage {
bool convertRGBtoSRGB; bool convertRGBtoSRGB;
int quality; int quality;
GX2ScanTarget scanTarget; GX2ScanTarget scanTarget;
OSCalendarTime time;
}; };
extern FSIOThreadData gThreadData; extern FSIOThreadData gThreadData;