From 5b71ab152fa7001d27480239ce35e0c0015e2981 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 1 Mar 2024 20:58:41 +0100 Subject: [PATCH] Use the time of creating the screenshot, not the time of saving the screenshot --- src/common.h | 6 ++++ src/config.cpp | 2 +- src/function_patcher.cpp | 59 ++++++++++++++++++++++------------------ src/retain_vars.cpp | 4 +-- src/retain_vars.hpp | 4 +-- src/screenshot_utils.cpp | 7 +++-- src/screenshot_utils.h | 3 +- src/thread.cpp | 11 +++----- src/thread.h | 1 + 9 files changed, 53 insertions(+), 44 deletions(-) diff --git a/src/common.h b/src/common.h index d973a31..6f23d83 100644 --- a/src/common.h +++ b/src/common.h @@ -1,5 +1,6 @@ #pragma once +#include #define WIIU_SCREENSHOT_PATH "fs:/vol/external01/wiiu/screenshots/" enum ImageOutputFormatEnum { @@ -19,3 +20,8 @@ enum ScreenshotState { SCREENSHOT_STATE_REQUESTED, SCREENSHOT_STATE_SAVING, }; + +struct ScreenshotStateInfo { + ScreenshotState state; + OSCalendarTime time; +}; \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 33d0bd5..75656fc 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -217,7 +217,7 @@ WUPSConfigAPICallbackStatus ConfigMenuOpenedCallback(WUPSConfigCategoryHandle ro &boolItemCallback)); } catch (std::exception &e) { - OSReport("Exception T_T : %s\n", e.what()); + OSReport("Exception: %s\n", e.what()); return WUPSCONFIG_API_CALLBACK_RESULT_ERROR; } diff --git a/src/function_patcher.cpp b/src/function_patcher.cpp index 71880e2..2a0e8af 100644 --- a/src/function_patcher.cpp +++ b/src/function_patcher.cpp @@ -43,11 +43,14 @@ void RequestScreenshot() { gNotAvailableNotificationDisplayed = true; } } else { + OSCalendarTime time; + OSTicksToCalendarTime(OSGetTime(), &time); 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!"); - gTakeScreenshotTV = SCREENSHOT_STATE_REQUESTED; - gReadySinceFramesTV = 0; + gTakeScreenshotTV.state = SCREENSHOT_STATE_REQUESTED; + gTakeScreenshotTV.time = time; + gReadySinceFramesTV = 0; } else if (!gInProgressNotificationDisplayedTV) { if ((err = NotificationModule_AddErrorNotificationWithCallback("Screenshot of the TV already in progress.", AlreadyInProgressCallback, @@ -64,9 +67,11 @@ void RequestScreenshot() { DEBUG_FUNCTION_LINE("Screenshots are blocked for DRC because it's not connected"); return; } - if (gTakeScreenshotDRC == SCREENSHOT_STATE_READY) { + if (gTakeScreenshotDRC.state == SCREENSHOT_STATE_READY) { DEBUG_FUNCTION_LINE("Requested screenshot for DRC!"); - gTakeScreenshotDRC = SCREENSHOT_STATE_REQUESTED; + gTakeScreenshotDRC.state = SCREENSHOT_STATE_REQUESTED; + gTakeScreenshotDRC.time = time; + gReadySinceFramesDRC = 0; } else if (!gInProgressNotificationDisplayedDRC) { 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) { if (gEnabled) { if (gCheckIfScreenRendered) { - if (gTakeScreenshotTV == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesTV > 5) { - gTakeScreenshotTV = SCREENSHOT_STATE_READY; - gReadySinceFramesTV = 0; - } else if (gTakeScreenshotDRC == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesDRC > 5) { - gTakeScreenshotDRC = SCREENSHOT_STATE_READY; - gReadySinceFramesDRC = 0; + if (gTakeScreenshotTV.state == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesTV > 5) { + gTakeScreenshotTV.state = SCREENSHOT_STATE_READY; + gReadySinceFramesTV = 0; + } else if (gTakeScreenshotDRC.state == SCREENSHOT_STATE_REQUESTED && ++gReadySinceFramesDRC > 5) { + gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY; + 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; DEBUG_FUNCTION_LINE("Lets take a screenshot from TV."); - if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality)) { - gTakeScreenshotTV = SCREENSHOT_STATE_READY; + if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotTV.time)) { + gTakeScreenshotTV.state = SCREENSHOT_STATE_READY; } 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; DEBUG_FUNCTION_LINE("Lets take a screenshot from DRC."); - if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality)) { - gTakeScreenshotDRC = SCREENSHOT_STATE_READY; + if (!takeScreenshot((GX2ColorBuffer *) colorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotDRC.time)) { + gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY; } 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) { 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."); - if (!takeScreenshot((GX2ColorBuffer *) &lastTVColorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality)) { - gTakeScreenshotTV = SCREENSHOT_STATE_READY; + if (!takeScreenshot((GX2ColorBuffer *) &lastTVColorBuffer, scan_target, gTVSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotTV.time)) { + gTakeScreenshotTV.state = SCREENSHOT_STATE_READY; } 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."); - if (!takeScreenshot((GX2ColorBuffer *) &lastDRCColorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality)) { - gTakeScreenshotDRC = SCREENSHOT_STATE_READY; + if (!takeScreenshot((GX2ColorBuffer *) &lastDRCColorBuffer, scan_target, gDRCSurfaceFormat, gOutputFormat, gQuality, gTakeScreenshotDRC.time)) { + gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY; } else { - gTakeScreenshotDRC = SCREENSHOT_STATE_SAVING; + gTakeScreenshotDRC.state = SCREENSHOT_STATE_SAVING; } } } diff --git a/src/retain_vars.cpp b/src/retain_vars.cpp index 7c6a3aa..93a5e0e 100644 --- a/src/retain_vars.cpp +++ b/src/retain_vars.cpp @@ -14,8 +14,8 @@ bool gReservedBitUsage = RESERVED_BIT_USAGE_CONFIG_DEFAULT; std::string gShortNameEn; -ScreenshotState gTakeScreenshotTV = SCREENSHOT_STATE_READY; -ScreenshotState gTakeScreenshotDRC = SCREENSHOT_STATE_READY; +ScreenshotStateInfo gTakeScreenshotTV = {SCREENSHOT_STATE_READY}; +ScreenshotStateInfo gTakeScreenshotDRC = {SCREENSHOT_STATE_READY}; bool gInProgressNotificationDisplayedDRC = false; bool gInProgressNotificationDisplayedTV = false; diff --git a/src/retain_vars.hpp b/src/retain_vars.hpp index d31f360..d6203c7 100644 --- a/src/retain_vars.hpp +++ b/src/retain_vars.hpp @@ -16,8 +16,8 @@ extern bool gReservedBitUsage; extern std::string gShortNameEn; -extern ScreenshotState gTakeScreenshotTV; -extern ScreenshotState gTakeScreenshotDRC; +extern ScreenshotStateInfo gTakeScreenshotTV; +extern ScreenshotStateInfo gTakeScreenshotDRC; extern bool gInProgressNotificationDisplayedDRC; diff --git a/src/screenshot_utils.cpp b/src/screenshot_utils.cpp index 8506496..8d31853 100644 --- a/src/screenshot_utils.cpp +++ b/src/screenshot_utils.cpp @@ -180,14 +180,14 @@ static bool copyBuffer(GX2ColorBuffer *sourceBuffer, GX2ColorBuffer *targetBuffe void ScreenshotSavedCallback(NotificationModuleHandle handle, void *context) { auto scanTarget = (GX2ScanTarget) (uint32_t) context; if (scanTarget == GX2_SCAN_TARGET_TV) { - gTakeScreenshotTV = SCREENSHOT_STATE_READY; + gTakeScreenshotTV.state = SCREENSHOT_STATE_READY; } else { - gTakeScreenshotDRC = SCREENSHOT_STATE_READY; + gTakeScreenshotDRC.state = SCREENSHOT_STATE_READY; } 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) { DEBUG_FUNCTION_LINE_ERR("Source buffer was NULL"); return false; @@ -262,6 +262,7 @@ bool takeScreenshot(GX2ColorBuffer *srcBuffer, GX2ScanTarget scanTarget, GX2Surf param->quality = quality; param->format = colorBuffer.surface.format; param->scanTarget = scanTarget; + param->time = time; res = sendMessageToThread(param); if (!res) { diff --git a/src/screenshot_utils.h b/src/screenshot_utils.h index f1a12ec..7f3589f 100644 --- a/src/screenshot_utils.h +++ b/src/screenshot_utils.h @@ -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 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); diff --git a/src/thread.cpp b/src/thread.cpp index b60ec64..c41991a 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -4,7 +4,6 @@ #include "screenshot_utils.h" #include "utils/StringTools.h" #include "utils/logger.h" -#include "utils/utils.h" #include #include #include @@ -14,9 +13,7 @@ FSIOThreadData gThreadData; bool gThreadsRunning; -bool getPath(GX2ScanTarget scanTarget, ImageOutputFormatEnum outputFormat, std::string &path) { - OSCalendarTime output; - OSTicksToCalendarTime(OSGetTime(), &output); +static bool getPath(GX2ScanTarget scanTarget, ImageOutputFormatEnum outputFormat, std::string &path, OSCalendarTime &output) { std::string buffer = string_format("%s%016llX", WIIU_SCREENSHOT_PATH, OSGetTitleID()); if (!gShortNameEn.empty()) { buffer += string_format(" (%s)", gShortNameEn.c_str()); @@ -66,7 +63,7 @@ bool getPath(GX2ScanTarget scanTarget, ImageOutputFormatEnum outputFormat, std:: 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); 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; 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()); auto res = saveTextureAsPicture(path, message->sourceBuffer, message->width, message->height, message->pitch, message->format, message->outputFormat, message->convertRGBtoSRGB, message->quality); if (res) { @@ -155,7 +152,7 @@ void startFSIOThreads() { OSMemoryBarrier(); - if (!OSCreateThread(threadData->thread, &fsIOthreadCallback, 1, (char *) threadData, reinterpret_cast((uint32_t) threadData->stack + stackSize), stackSize, 31, OS_THREAD_ATTRIB_AFFINITY_ANY)) { + if (!OSCreateThread(threadData->thread, &fsIOThreadCallback, 1, (char *) threadData, reinterpret_cast((uint32_t) threadData->stack + stackSize), stackSize, 31, OS_THREAD_ATTRIB_AFFINITY_ANY)) { free(threadData->thread); free(threadData->stack); threadData->setup = false; diff --git a/src/thread.h b/src/thread.h index 1379e67..81e8997 100644 --- a/src/thread.h +++ b/src/thread.h @@ -27,6 +27,7 @@ struct SaveScreenshotMessage { bool convertRGBtoSRGB; int quality; GX2ScanTarget scanTarget; + OSCalendarTime time; }; extern FSIOThreadData gThreadData;