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 6795e12f37
commit 5b71ab152f
9 changed files with 53 additions and 44 deletions

View File

@ -1,5 +1,6 @@
#pragma once
#include <coreinit/time.h>
#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;
};

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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) {

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 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);

View File

@ -4,7 +4,6 @@
#include "screenshot_utils.h"
#include "utils/StringTools.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include <coreinit/cache.h>
#include <coreinit/title.h>
#include <dirent.h>
@ -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<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->stack);
threadData->setup = false;

View File

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