Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement support for WUPS 0.8.0 #27

Merged
merged 6 commits into from
Apr 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
- name: zip artifact
run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip *.wps
- name: Create Release
uses: "softprops/action-gh-release@v1"
uses: "softprops/action-gh-release@v2"
with:
tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }}
draft: false
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM ghcr.io/wiiu-env/devkitppc:20231112
FROM ghcr.io/wiiu-env/devkitppc:20240423

COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20230719 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20240425 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libmappedmemory:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libnotifications:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libnotifications:20240426 /artifacts $DEVKITPRO

WORKDIR project
14 changes: 10 additions & 4 deletions src/common.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
#pragma once

#include <coreinit/time.h>
#define WIIU_SCREENSHOT_PATH "fs:/vol/external01/wiiu/screenshots/"

typedef enum {
enum ImageOutputFormatEnum {
IMAGE_OUTPUT_FORMAT_JPEG = 0,
IMAGE_OUTPUT_FORMAT_PNG = 1,
IMAGE_OUTPUT_FORMAT_BMP = 2,
} ImageOutputFormatEnum;
};

typedef enum {
enum ImageSourceEnum {
IMAGE_SOURCE_TV_AND_DRC = 0,
IMAGE_SOURCE_TV = 1,
IMAGE_SOURCE_DRC = 2,
} ImageSourceEnum;
};

enum ScreenshotState {
SCREENSHOT_STATE_READY,
SCREENSHOT_STATE_REQUESTED,
SCREENSHOT_STATE_SAVING,
};

struct ScreenshotStateInfo {
ScreenshotState state;
OSCalendarTime time;
};
278 changes: 124 additions & 154 deletions src/config.cpp

Large diffs are not rendered by default.

19 changes: 13 additions & 6 deletions src/config.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
#pragma once

#define ENABLED_CONFIG_STRING "enabled"
#define BUTTON_COMBO_CONFIG_STRING "buttonCombo"
#define FORMAT_CONFIG_STRING "format"
#define QUALITY_CONFIG_STRING "quality"
#define SCREEN_CONFIG_STRING "screen"
#define RESERVED_BIT_USAGE_CONFIG_STRING "reservedBitUsage"
#define ENABLED_CONFIG_DEFAULT true
#define FORMAT_CONFIG_DEFAULT IMAGE_OUTPUT_FORMAT_JPEG
#define QUALITY_CONFIG_DEFAULT 90
#define SCREEN_CONFIG_DEFAULT IMAGE_SOURCE_TV_AND_DRC
#define BUTTON_COMBO_CONFIG_DEFAULT 0
#define RESERVED_BIT_USAGE_CONFIG_DEFAULT true

#define ENABLED_CONFIG_STRING "enabled"
#define BUTTON_COMBO_CONFIG_STRING "buttonCombo"
#define FORMAT_CONFIG_STRING "format"
#define QUALITY_CONFIG_STRING "quality"
#define SCREEN_CONFIG_STRING "screen"
#define RESERVED_BIT_USAGE_CONFIG_STRING "reservedBitUsage"

void InitConfig();
59 changes: 32 additions & 27 deletions src/function_patcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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.",
Expand Down Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -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;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/main.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma once
#include "version.h"

#define VERSION "v0.1.2"
#define VERSION "v0.1.3"
#define VERSION_FULL VERSION VERSION_EXTRA
24 changes: 13 additions & 11 deletions src/retain_vars.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
#include "retain_vars.hpp"
#include "config.h"
#include <string>

GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
ImageSourceEnum gImageSource = IMAGE_SOURCE_TV_AND_DRC;
bool gEnabled = true;
uint32_t gButtonCombo = 0;
int32_t gQuality = 90;
ImageOutputFormatEnum gOutputFormat = IMAGE_OUTPUT_FORMAT_JPEG;
std::string gShortNameEn;
GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;

ImageSourceEnum gImageSource = SCREEN_CONFIG_DEFAULT;
bool gEnabled = ENABLED_CONFIG_DEFAULT;
uint32_t gButtonCombo = BUTTON_COMBO_CONFIG_DEFAULT;
int32_t gQuality = QUALITY_CONFIG_DEFAULT;
ImageOutputFormatEnum gOutputFormat = FORMAT_CONFIG_DEFAULT;
bool gReservedBitUsage = RESERVED_BIT_USAGE_CONFIG_DEFAULT;

ScreenshotState gTakeScreenshotTV = SCREENSHOT_STATE_READY;
ScreenshotState gTakeScreenshotDRC = SCREENSHOT_STATE_READY;
std::string gShortNameEn;

bool gReservedBitUsage = true;
ScreenshotStateInfo gTakeScreenshotTV = {SCREENSHOT_STATE_READY};
ScreenshotStateInfo gTakeScreenshotDRC = {SCREENSHOT_STATE_READY};

bool gInProgressNotificationDisplayedDRC = false;
bool gInProgressNotificationDisplayedTV = false;
Expand Down
12 changes: 7 additions & 5 deletions src/retain_vars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@
#include <notifications/notifications.h>
#include <string>

extern bool gEnabled;
extern ImageSourceEnum gImageSource;
extern GX2SurfaceFormat gTVSurfaceFormat;
extern GX2SurfaceFormat gDRCSurfaceFormat;

extern ImageSourceEnum gImageSource;
extern bool gEnabled;
extern uint32_t gButtonCombo;
extern int32_t gQuality;
extern ImageOutputFormatEnum gOutputFormat;
extern bool gReservedBitUsage;

extern std::string gShortNameEn;

extern ScreenshotState gTakeScreenshotTV;
extern ScreenshotState gTakeScreenshotDRC;
extern ScreenshotStateInfo gTakeScreenshotTV;
extern ScreenshotStateInfo gTakeScreenshotDRC;

extern bool gReservedBitUsage;

extern bool gInProgressNotificationDisplayedDRC;
extern bool gInProgressNotificationDisplayedTV;
Expand Down
7 changes: 4 additions & 3 deletions src/screenshot_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down
3 changes: 1 addition & 2 deletions src/screenshot_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
11 changes: 4 additions & 7 deletions src/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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());
Expand Down Expand Up @@ -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]);
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct SaveScreenshotMessage {
bool convertRGBtoSRGB;
int quality;
GX2ScanTarget scanTarget;
OSCalendarTime time;
};

extern FSIOThreadData gThreadData;
Expand Down
Loading