Compare commits

...

17 Commits

Author SHA1 Message Date
Daniel K. O. (dkosmari)
c8dbca8fad Use steady/monotonic clock for the timers, so they can handle realtime clock jumps. 2024-06-01 10:18:09 +02:00
Maschell
36993e1630 make sure gOverlayFrame is valid 2024-05-06 17:35:14 +02:00
dependabot[bot]
5801f61ec7 Bump wiiu-env/devkitppc from 20240423 to 20240505
Bumps wiiu-env/devkitppc from 20240423 to 20240505.

---
updated-dependencies:
- dependency-name: wiiu-env/devkitppc
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-06 10:20:14 +02:00
Maschell
a2cf5293d8 Add support for notification that can survive application changes 2024-04-26 13:57:56 +02:00
Maschell
42727408df Update github actions 2024-04-25 21:19:13 +02:00
Maschell
4963c1b304 Update Dockerfile 2024-04-25 21:19:13 +02:00
Maschell
846fa5ed6a Bump version 2024-04-25 21:19:13 +02:00
Maschell
6954c0dc64 Fix some warnings in SchriftGX2 2024-04-25 21:19:13 +02:00
Maschell
8fb509ad9c Update .gitignore to ignore all files with .zip extension 2024-04-25 21:19:13 +02:00
dependabot[bot]
4b0f42e5fb Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-04-25 21:19:13 +02:00
Maschell
920258c265 Make sure to stop Drawing on the screen before destorying all shaders and other data 2024-04-25 21:19:13 +02:00
Maschell
209f2c1805 Improve font system init logic 2024-04-25 21:19:13 +02:00
Maschell
e19f9ba398 Implement WUMS_DEINITIALIZE 2024-04-25 21:19:13 +02:00
Maschell
b1e06017ac Add missing OSFatals and make existing OSFatals more verbose 2024-04-25 21:19:13 +02:00
Maschell
1bf259db4b Save Notifications in a queue until the overlay has been initialized 2024-04-25 21:19:13 +02:00
Maschell
d9da174f4b Create dependabot.yml 2023-07-23 10:21:40 +02:00
Maschell
ade4a272bb Bump version 2023-07-19 18:35:54 +02:00
14 changed files with 165 additions and 65 deletions

10
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View File

@ -9,7 +9,7 @@ jobs:
clang-format: clang-format:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: clang-format - name: clang-format
run: | run: |
docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src
@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
needs: clang-format needs: clang-format
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: create version.h - name: create version.h
run: | run: |
git_hash=$(git rev-parse --short "$GITHUB_SHA") git_hash=$(git rev-parse --short "$GITHUB_SHA")
@ -48,7 +48,7 @@ jobs:
- name: zip artifact - name: zip artifact
run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip *.wms run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip *.wms
- name: Create Release - name: Create Release
uses: "softprops/action-gh-release@v1" uses: "softprops/action-gh-release@v2"
with: with:
tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }} tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }}
draft: false draft: false

View File

@ -6,7 +6,7 @@ jobs:
clang-format: clang-format:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: clang-format - name: clang-format
run: | run: |
docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src
@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
needs: clang-format needs: clang-format
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: build binary with logging - name: build binary with logging
run: | run: |
docker build . -t builder docker build . -t builder
@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
needs: clang-format needs: clang-format
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: create version.h - name: create version.h
run: | run: |
git_hash=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}") git_hash=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ build/
cmake-build-debug/ cmake-build-debug/
CMakeLists.txt CMakeLists.txt
*.wms *.wms
*.zip

View File

@ -1,8 +1,8 @@
FROM ghcr.io/wiiu-env/devkitppc:20230621 FROM ghcr.io/wiiu-env/devkitppc:20240505
COPY --from=ghcr.io/wiiu-env/libnotifications:20230621 /artifacts $DEVKITPRO COPY --from=ghcr.io/wiiu-env/libnotifications:20240426 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libmappedmemory:20230621 /artifacts $DEVKITPRO COPY --from=ghcr.io/wiiu-env/libmappedmemory:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20230621 /artifacts $DEVKITPRO COPY --from=ghcr.io/wiiu-env/libfunctionpatcher:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20230719 /artifacts $DEVKITPRO COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20240424 /artifacts $DEVKITPRO
WORKDIR project WORKDIR project

View File

@ -8,19 +8,29 @@
void ExportCleanUp() { void ExportCleanUp() {
std::lock_guard<std::mutex> lock(gNotificationListMutex); std::lock_guard<std::mutex> lock(gNotificationListMutex);
gNotificationList.clear(); gNotificationList.clear();
std::lock_guard overlay_lock(gOverlayFrameMutex);
// Remove notification in queue that should not survive
std::vector<std::shared_ptr<Notification>> keepQueue;
for (const auto &notification : gOverlayQueueDuringStartup) {
if (notification->isKeepUntilShown()) {
keepQueue.push_back(notification);
} else {
}
}
gOverlayQueueDuringStartup.clear();
gOverlayQueueDuringStartup = keepQueue;
} }
NotificationModuleStatus NMAddStaticNotification(const char *text, NotificationModuleStatus NMAddStaticNotificationV2(const char *text,
NotificationModuleNotificationType type, NotificationModuleNotificationType type,
float durationBeforeFadeOutInSeconds, float durationBeforeFadeOutInSeconds,
float shakeDurationInSeconds, float shakeDurationInSeconds,
NMColor textColor, NMColor textColor,
NMColor backgroundColor, NMColor backgroundColor,
void (*finishFunc)(NotificationModuleHandle, void *context), void (*finishFunc)(NotificationModuleHandle, void *context),
void *context) { void *context,
if (!gOverlayFrame) { bool keepUntilShown) {
return NOTIFICATION_MODULE_RESULT_OVERLAY_NOT_READY;
}
NotificationStatus status; NotificationStatus status;
switch (type) { switch (type) {
@ -41,16 +51,37 @@ NotificationModuleStatus NMAddStaticNotification(const char *text,
(GX2Color){textColor.r, textColor.g, textColor.b, textColor.a}, (GX2Color){textColor.r, textColor.g, textColor.b, textColor.a},
(GX2Color){backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a}, (GX2Color){backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a},
finishFunc, finishFunc,
context); context,
nullptr,
keepUntilShown);
if (!notification) { if (!notification) {
return NOTIFICATION_MODULE_RESULT_ALLOCATION_FAILED; return NOTIFICATION_MODULE_RESULT_ALLOCATION_FAILED;
} }
gOverlayFrame->addNotification(notification); {
std::lock_guard lock(gOverlayFrameMutex);
if (gOverlayFrame && gDrawReady) {
gOverlayFrame->addNotification(std::move(notification));
} else {
gOverlayQueueDuringStartup.push_back(std::move(notification));
}
}
return NOTIFICATION_MODULE_RESULT_SUCCESS; return NOTIFICATION_MODULE_RESULT_SUCCESS;
} }
NotificationModuleStatus NMAddStaticNotification(const char *text,
NotificationModuleNotificationType type,
float durationBeforeFadeOutInSeconds,
float shakeDurationInSeconds,
NMColor textColor,
NMColor backgroundColor,
void (*finishFunc)(NotificationModuleHandle, void *context),
void *context) {
return NMAddStaticNotificationV2(text, type, durationBeforeFadeOutInSeconds, shakeDurationInSeconds, textColor, backgroundColor, finishFunc, context, false);
}
void NMNotificationRemovedFromOverlay(Notification *notification) { void NMNotificationRemovedFromOverlay(Notification *notification) {
if (notification) { if (notification) {
auto handle = notification->getHandle(); auto handle = notification->getHandle();
@ -60,19 +91,17 @@ void NMNotificationRemovedFromOverlay(Notification *notification) {
} }
} }
NotificationModuleStatus NMAddDynamicNotification(const char *text, NotificationModuleStatus NMAddDynamicNotificationV2(const char *text,
NMColor textColor, NMColor textColor,
NMColor backgroundColor, NMColor backgroundColor,
void (*finishFunc)(NotificationModuleHandle, void *context), void (*finishFunc)(NotificationModuleHandle, void *context),
void *context, void *context,
NotificationModuleHandle *outHandle) { bool keep_until_shown,
NotificationModuleHandle *outHandle) {
if (outHandle == nullptr) { if (outHandle == nullptr) {
return NOTIFICATION_MODULE_RESULT_INVALID_ARGUMENT; return NOTIFICATION_MODULE_RESULT_INVALID_ARGUMENT;
} }
*outHandle = 0; *outHandle = 0;
if (!gOverlayFrame) {
return NOTIFICATION_MODULE_RESULT_OVERLAY_NOT_READY;
}
auto notification = make_shared_nothrow<Notification>( auto notification = make_shared_nothrow<Notification>(
text, text,
@ -83,7 +112,8 @@ NotificationModuleStatus NMAddDynamicNotification(const char *text,
(GX2Color){backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a}, (GX2Color){backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a},
finishFunc, finishFunc,
context, context,
NMNotificationRemovedFromOverlay); NMNotificationRemovedFromOverlay,
keep_until_shown);
if (!notification) { if (!notification) {
return NOTIFICATION_MODULE_RESULT_ALLOCATION_FAILED; return NOTIFICATION_MODULE_RESULT_ALLOCATION_FAILED;
} }
@ -91,13 +121,29 @@ NotificationModuleStatus NMAddDynamicNotification(const char *text,
{ {
std::lock_guard<std::mutex> lock(gNotificationListMutex); std::lock_guard<std::mutex> lock(gNotificationListMutex);
*outHandle = notification->getHandle(); *outHandle = notification->getHandle();
gOverlayFrame->addNotification(notification); {
gNotificationList.push_front(notification); std::lock_guard overlay_lock(gOverlayFrameMutex);
if (gOverlayFrame) {
gOverlayFrame->addNotification(notification);
} else {
gOverlayQueueDuringStartup.push_back(notification);
}
}
gNotificationList.push_front(std::move(notification));
} }
return NOTIFICATION_MODULE_RESULT_SUCCESS; return NOTIFICATION_MODULE_RESULT_SUCCESS;
} }
NotificationModuleStatus NMAddDynamicNotification(const char *text,
NMColor textColor,
NMColor backgroundColor,
void (*finishFunc)(NotificationModuleHandle, void *context),
void *context,
NotificationModuleHandle *outHandle) {
return NMAddDynamicNotificationV2(text, textColor, backgroundColor, finishFunc, context, false, outHandle);
}
NotificationModuleStatus NMUpdateDynamicNotificationText(NotificationModuleHandle handle, NotificationModuleStatus NMUpdateDynamicNotificationText(NotificationModuleHandle handle,
const char *text) { const char *text) {
NotificationModuleStatus res = NOTIFICATION_MODULE_RESULT_INVALID_HANDLE; NotificationModuleStatus res = NOTIFICATION_MODULE_RESULT_INVALID_HANDLE;
@ -186,10 +232,12 @@ NotificationModuleStatus NMGetVersion(NotificationModuleAPIVersion *outVersion)
if (outVersion == nullptr) { if (outVersion == nullptr) {
return NOTIFICATION_MODULE_RESULT_INVALID_ARGUMENT; return NOTIFICATION_MODULE_RESULT_INVALID_ARGUMENT;
} }
*outVersion = 1; *outVersion = 2;
return NOTIFICATION_MODULE_RESULT_SUCCESS; return NOTIFICATION_MODULE_RESULT_SUCCESS;
} }
WUMS_EXPORT_FUNCTION(NMAddDynamicNotificationV2);
WUMS_EXPORT_FUNCTION(NMAddStaticNotificationV2);
WUMS_EXPORT_FUNCTION(NMAddDynamicNotification); WUMS_EXPORT_FUNCTION(NMAddDynamicNotification);
WUMS_EXPORT_FUNCTION(NMAddStaticNotification); WUMS_EXPORT_FUNCTION(NMAddStaticNotification);
WUMS_EXPORT_FUNCTION(NMUpdateDynamicNotificationText); WUMS_EXPORT_FUNCTION(NMUpdateDynamicNotificationText);

View File

@ -71,8 +71,21 @@ void drawScreenshotSavedTexture2(GX2ColorBuffer *colorBuffer, GX2ScanTarget scan
drawIntoColorBuffer(colorBuffer, gOverlayFrame, scan_target); drawIntoColorBuffer(colorBuffer, gOverlayFrame, scan_target);
} }
static void TryAddFromQueue() {
if (!gOverlayFrame) {
return;
}
std::lock_guard overlay_lock(gOverlayFrameMutex);
// Add notification that had been called before the overlay was ready
for (const auto &notification : gOverlayQueueDuringStartup) {
gOverlayFrame->addNotification(notification);
}
gOverlayQueueDuringStartup.clear();
}
DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) { DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, GX2ScanTarget scan_target) {
gDrawReady = true; gDrawReady = true;
TryAddFromQueue();
if (drawScreenshotSavedTexture(colorBuffer, scan_target)) { if (drawScreenshotSavedTexture(colorBuffer, scan_target)) {
// if it returns true we don't need to call GX2CopyColorBufferToScanBuffer // if it returns true we don't need to call GX2CopyColorBufferToScanBuffer
return; return;
@ -110,19 +123,24 @@ bool drawScreenshotSavedTexture(const GX2ColorBuffer *colorBuffer, GX2ScanTarget
DECL_FUNCTION(void, GX2Init, uint32_t attributes) { DECL_FUNCTION(void, GX2Init, uint32_t attributes) {
real_GX2Init(attributes); real_GX2Init(attributes);
if (!gOverlayInitDone) { if (!gOverlayInitDone) {
std::lock_guard overlay_lock(gOverlayFrameMutex);
DEBUG_FUNCTION_LINE_VERBOSE("Init Overlay"); DEBUG_FUNCTION_LINE_VERBOSE("Init Overlay");
gOverlayFrame = new (std::nothrow) OverlayFrame(1280.0f, 720.0f); gOverlayFrame = new (std::nothrow) OverlayFrame(1280.0f, 720.0f);
if (!gOverlayFrame) { if (!gOverlayFrame) {
OSFatal("Failed to alloc gOverlayFrame"); OSFatal("NotificationModule: Failed to alloc gOverlayFrame");
} }
// Allocate shader. // Allocate shader.
ColorShader::instance(); if (ColorShader::instance() == nullptr) {
Texture2DShader::instance(); OSFatal("NotificationModule: Failed to alloc ColorShader");
}
if (Texture2DShader::instance() == nullptr) {
OSFatal("NotificationModule: Failed to alloc Texture2DShader");
}
// has been allocated in WUMS INIT // has been allocated in WUMS INIT
if (!gContextState) { if (!gContextState) {
OSFatal("Failed to alloc gContextState"); OSFatal("NotificationModule: Failed to alloc gContextState");
} }
real_GX2SetupContextStateEx(gContextState, GX2_TRUE); real_GX2SetupContextStateEx(gContextState, GX2_TRUE);
DCInvalidateRange(gContextState, sizeof(GX2ContextState)); // Important! DCInvalidateRange(gContextState, sizeof(GX2ContextState)); // Important!
@ -132,6 +150,7 @@ DECL_FUNCTION(void, GX2Init, uint32_t attributes) {
DECL_FUNCTION(void, GX2MarkScanBufferCopied, GX2ScanTarget scan_target) { DECL_FUNCTION(void, GX2MarkScanBufferCopied, GX2ScanTarget scan_target) {
gDrawReady = true; gDrawReady = true;
TryAddFromQueue();
if (scan_target == GX2_SCAN_TARGET_TV) { if (scan_target == GX2_SCAN_TARGET_TV) {
drawScreenshotSavedTexture2(&lastTVColorBuffer, scan_target); drawScreenshotSavedTexture2(&lastTVColorBuffer, scan_target);
} else { } else {

View File

@ -8,7 +8,8 @@ Notification::Notification(const std::string &overlayText,
GX2Color backgroundColor, GX2Color backgroundColor,
void (*finishFunc)(NotificationModuleHandle, void *), void (*finishFunc)(NotificationModuleHandle, void *),
void *context, void *context,
void (*removedFromOverlayCallback)(Notification *)) : GuiFrame(0, 0), mBackground(0, 0, backgroundColor) { void (*removedFromOverlayCallback)(Notification *),
bool keepUntilShown) : GuiFrame(0, 0), mBackground(0, 0, backgroundColor) {
mFinishFunction = finishFunc; mFinishFunction = finishFunc;
mFinishFunctionContext = context; mFinishFunctionContext = context;
mRemovedFromOverlayCallback = removedFromOverlayCallback; mRemovedFromOverlayCallback = removedFromOverlayCallback;
@ -20,6 +21,7 @@ Notification::Notification(const std::string &overlayText,
mNotificationText.setPosition(0, 0); mNotificationText.setPosition(0, 0);
mNotificationText.setFontSize(20); mNotificationText.setFontSize(20);
mNotificationText.setAlignment(ALIGN_CENTERED); mNotificationText.setAlignment(ALIGN_CENTERED);
mKeepUntilShown = keepUntilShown;
updateStatus(status); updateStatus(status);

View File

@ -35,7 +35,8 @@ public:
GX2Color backgroundColor = {100, 100, 100, 255}, GX2Color backgroundColor = {100, 100, 100, 255},
void (*finishFunc)(NotificationModuleHandle, void *) = nullptr, void (*finishFunc)(NotificationModuleHandle, void *) = nullptr,
void *context = nullptr, void *context = nullptr,
void (*removedFromOverlayCallback)(Notification *) = nullptr); void (*removedFromOverlayCallback)(Notification *) = nullptr,
bool keepUntilShown = false);
~Notification() override; ~Notification() override;
@ -90,6 +91,10 @@ public:
mPositionSet = true; mPositionSet = true;
} }
[[nodiscard]] bool isKeepUntilShown() const {
return mKeepUntilShown;
}
private: private:
std::function<void(NotificationModuleHandle, void *)> mFinishFunction; std::function<void(NotificationModuleHandle, void *)> mFinishFunction;
std::function<void(Notification *)> mRemovedFromOverlayCallback; std::function<void(Notification *)> mRemovedFromOverlayCallback;
@ -106,6 +111,8 @@ private:
bool mTextDirty = false; bool mTextDirty = false;
bool mPositionSet = false; bool mPositionSet = false;
bool mKeepUntilShown = false;
NotificationStatus mStatus = NOTIFICATION_STATUS_INFO; NotificationStatus mStatus = NOTIFICATION_STATUS_INFO;
NotificationInternalStatus mInternalStatus = NOTIFICATION_STATUS_NOTHING; NotificationInternalStatus mInternalStatus = NOTIFICATION_STATUS_NOTHING;
}; };

View File

@ -217,6 +217,7 @@ ftgxCharData *SchriftGX2::cacheGlyphData(wchar_t charCode, int16_t pixelSize) {
textureHeight = mtx.minHeight; textureHeight = mtx.minHeight;
SFT_Image img = { SFT_Image img = {
.pixels = nullptr,
.width = textureWidth, .width = textureWidth,
.height = textureHeight, .height = textureHeight,
}; };
@ -307,7 +308,7 @@ bool SchriftGX2::loadGlyphData(SFT_Image *bmp, ftgxCharData *charData, ftGX2Data
auto *src = (uint8_t *) bmp->pixels; auto *src = (uint8_t *) bmp->pixels;
auto *dst = (uint32_t *) charData->texture->surface.image; auto *dst = (uint32_t *) charData->texture->surface.image;
uint32_t x, y; int32_t x, y;
for (y = 0; y < bmp->height; y++) { for (y = 0; y < bmp->height; y++) {
for (x = 0; x < bmp->width; x++) { for (x = 0; x < bmp->width; x++) {
@ -391,6 +392,7 @@ int16_t SchriftGX2::getStyleOffsetHeight(int16_t format, uint16_t pixelSize) {
*/ */
uint16_t SchriftGX2::drawText(int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, const glm::vec4 &color, uint16_t textStyle, uint16_t textWidth, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 &blurColor) { uint16_t SchriftGX2::drawText(int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, const glm::vec4 &color, uint16_t textStyle, uint16_t textWidth, const float &textBlur, const float &colorBlurIntensity, const glm::vec4 &blurColor) {
(void) textWidth;
if (!text) { if (!text) {
return 0; return 0;
} }

View File

@ -3,16 +3,16 @@
class Timer { class Timer {
public: public:
Timer() { clock_gettime(CLOCK_REALTIME, &beg_); } Timer() { clock_gettime(CLOCK_MONOTONIC, &beg_); }
double elapsed() { double elapsed() {
clock_gettime(CLOCK_REALTIME, &end_); clock_gettime(CLOCK_MONOTONIC, &end_);
return end_.tv_sec - beg_.tv_sec + return end_.tv_sec - beg_.tv_sec +
(end_.tv_nsec - beg_.tv_nsec) / 1000000000.; (end_.tv_nsec - beg_.tv_nsec) / 1000000000.;
} }
void reset() { clock_gettime(CLOCK_REALTIME, &beg_); } void reset() { clock_gettime(CLOCK_MONOTONIC, &beg_); }
private: private:
timespec beg_, end_; timespec beg_, end_;
}; };

View File

@ -11,7 +11,7 @@
WUMS_MODULE_EXPORT_NAME("homebrew_notifications"); WUMS_MODULE_EXPORT_NAME("homebrew_notifications");
#define VERSION "v0.1.0" #define VERSION "v0.1.2"
WUMS_DEPENDS_ON(homebrew_memorymapping); WUMS_DEPENDS_ON(homebrew_memorymapping);
WUMS_DEPENDS_ON(homebrew_functionpatcher); WUMS_DEPENDS_ON(homebrew_functionpatcher);
@ -20,7 +20,7 @@ WUMS_INITIALIZE() {
initLogging(); initLogging();
if (FunctionPatcher_InitLibrary() != FUNCTION_PATCHER_RESULT_SUCCESS) { if (FunctionPatcher_InitLibrary() != FUNCTION_PATCHER_RESULT_SUCCESS) {
OSFatal("homebrew_notifications: FunctionPatcher_InitLibrary failed"); OSFatal("NotificationModule: FunctionPatcher_InitLibrary failed");
} }
DEBUG_FUNCTION_LINE("Patch NotificationModule functions"); DEBUG_FUNCTION_LINE("Patch NotificationModule functions");
for (uint32_t i = 0; i < function_replacements_size; i++) { for (uint32_t i = 0; i < function_replacements_size; i++) {
@ -38,22 +38,22 @@ WUMS_INITIALIZE() {
sizeof(GX2ContextState), sizeof(GX2ContextState),
GX2_CONTEXT_STATE_ALIGNMENT); GX2_CONTEXT_STATE_ALIGNMENT);
if (gContextState == nullptr) { if (gContextState == nullptr) {
OSFatal("Failed to allocate gContextState"); OSFatal("NotificationModule: Failed to allocate gContextState");
} else { } else {
DEBUG_FUNCTION_LINE("Allocated %d bytes for gCont extState", sizeof(GX2ContextState)); DEBUG_FUNCTION_LINE_VERBOSE("Allocated %d bytes for gContextState", sizeof(GX2ContextState));
} }
void *font = nullptr; void *font = nullptr;
uint32_t size = 0; uint32_t size = 0;
OSGetSharedData(OS_SHAREDDATATYPE_FONT_STANDARD, 0, &font, &size); if (OSGetSharedData(OS_SHAREDDATATYPE_FONT_STANDARD, 0, &font, &size) && font && size > 0) {
if (font && size) {
gFontSystem = new (std::nothrow) SchriftGX2((uint8_t *) font, (int32_t) size); gFontSystem = new (std::nothrow) SchriftGX2((uint8_t *) font, (int32_t) size);
if (gFontSystem) {
GuiText::setPresetFont(gFontSystem);
} else {
DEBUG_FUNCTION_LINE_ERR("Failed to init font system");
}
} }
if (gFontSystem != nullptr) {
GuiText::setPresetFont(gFontSystem);
} else {
OSFatal("NotificationModule: Failed to init font system");
}
OSMemoryBarrier(); OSMemoryBarrier();
deinitLogging(); deinitLogging();
} }
@ -65,6 +65,7 @@ WUMS_APPLICATION_STARTS() {
} }
WUMS_APPLICATION_ENDS() { WUMS_APPLICATION_ENDS() {
gDrawReady = false;
if (gOverlayFrame) { if (gOverlayFrame) {
gOverlayFrame->clearElements(); gOverlayFrame->clearElements();
} }
@ -76,3 +77,9 @@ WUMS_APPLICATION_ENDS() {
Texture2DShader::destroyInstance(); Texture2DShader::destroyInstance();
deinitLogging(); deinitLogging();
} }
WUMS_DEINITIALIZE() {
delete gOverlayFrame;
delete gFontSystem;
MEMFreeToMappedMemory(gContextState);
}

View File

@ -1,10 +1,12 @@
#include "retain_vars.hpp" #include "retain_vars.hpp"
GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8; GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2ContextState *gContextState = nullptr; GX2ContextState *gContextState = nullptr;
GX2ContextState *gOriginalContextState = nullptr; GX2ContextState *gOriginalContextState = nullptr;
OverlayFrame *gOverlayFrame = nullptr; std::mutex gOverlayFrameMutex = {};
SchriftGX2 *gFontSystem = nullptr; std::vector<std::shared_ptr<Notification>> gOverlayQueueDuringStartup = {};
bool gOverlayInitDone = false; OverlayFrame *gOverlayFrame = nullptr;
bool gDrawReady = false; SchriftGX2 *gFontSystem = nullptr;
bool gOverlayInitDone = false;
bool gDrawReady = false;

View File

@ -7,6 +7,8 @@ extern GX2SurfaceFormat gTVSurfaceFormat;
extern GX2SurfaceFormat gDRCSurfaceFormat; extern GX2SurfaceFormat gDRCSurfaceFormat;
extern GX2ContextState *gContextState; extern GX2ContextState *gContextState;
extern GX2ContextState *gOriginalContextState; extern GX2ContextState *gOriginalContextState;
extern std::mutex gOverlayFrameMutex;
extern std::vector<std::shared_ptr<Notification>> gOverlayQueueDuringStartup;
extern OverlayFrame *gOverlayFrame; extern OverlayFrame *gOverlayFrame;
extern SchriftGX2 *gFontSystem; extern SchriftGX2 *gFontSystem;
extern bool gOverlayInitDone; extern bool gOverlayInitDone;