Skip to content
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
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ jobs:
clang-format:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src
build-binary:
runs-on: ubuntu-22.04
needs: clang-format
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: create version.h
run: |
git_hash=$(git rev-parse --short "$GITHUB_SHA")
Expand Down Expand Up @@ -48,7 +48,7 @@ jobs:
- name: zip artifact
run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip *.wms
- 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 .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ jobs:
clang-format:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: clang-format
run: |
docker run --rm -v ${PWD}:/src ghcr.io/wiiu-env/clang-format:13.0.0-2 -r ./src
check-build-with-logging:
runs-on: ubuntu-22.04
needs: clang-format
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: build binary with logging
run: |
docker build . -t builder
Expand All @@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-22.04
needs: clang-format
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: create version.h
run: |
git_hash=$(git rev-parse --short "${{ github.event.pull_request.head.sha }}")
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ build/
cmake-build-debug/
CMakeLists.txt
*.wms
*.zip
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM ghcr.io/wiiu-env/devkitppc:20230621
FROM ghcr.io/wiiu-env/devkitppc:20240423

COPY --from=ghcr.io/wiiu-env/libnotifications: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/wiiumodulesystem:20230719 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/wiiumodulesystem:20240424 /artifacts $DEVKITPRO

WORKDIR project
28 changes: 19 additions & 9 deletions src/export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
void ExportCleanUp() {
std::lock_guard<std::mutex> lock(gNotificationListMutex);
gNotificationList.clear();
std::lock_guard overlay_lock(gOverlayFrameMutex);
gOverlayQueueDuringStartup.clear();
}

NotificationModuleStatus NMAddStaticNotification(const char *text,
Expand All @@ -18,9 +20,6 @@ NotificationModuleStatus NMAddStaticNotification(const char *text,
NMColor backgroundColor,
void (*finishFunc)(NotificationModuleHandle, void *context),
void *context) {
if (!gOverlayFrame) {
return NOTIFICATION_MODULE_RESULT_OVERLAY_NOT_READY;
}

NotificationStatus status;
switch (type) {
Expand All @@ -46,7 +45,14 @@ NotificationModuleStatus NMAddStaticNotification(const char *text,
return NOTIFICATION_MODULE_RESULT_ALLOCATION_FAILED;
}

gOverlayFrame->addNotification(notification);
{
std::lock_guard lock(gOverlayFrameMutex);
if (gOverlayFrame) {
gOverlayFrame->addNotification(std::move(notification));
} else {
gOverlayQueueDuringStartup.push_back(std::move(notification));
}
}

return NOTIFICATION_MODULE_RESULT_SUCCESS;
}
Expand All @@ -70,9 +76,6 @@ NotificationModuleStatus NMAddDynamicNotification(const char *text,
return NOTIFICATION_MODULE_RESULT_INVALID_ARGUMENT;
}
*outHandle = 0;
if (!gOverlayFrame) {
return NOTIFICATION_MODULE_RESULT_OVERLAY_NOT_READY;
}

auto notification = make_shared_nothrow<Notification>(
text,
Expand All @@ -91,8 +94,15 @@ NotificationModuleStatus NMAddDynamicNotification(const char *text,
{
std::lock_guard<std::mutex> lock(gNotificationListMutex);
*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;
Expand Down
19 changes: 15 additions & 4 deletions src/function_patches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,19 +110,30 @@ bool drawScreenshotSavedTexture(const GX2ColorBuffer *colorBuffer, GX2ScanTarget
DECL_FUNCTION(void, GX2Init, uint32_t attributes) {
real_GX2Init(attributes);
if (!gOverlayInitDone) {
std::lock_guard overlay_lock(gOverlayFrameMutex);
DEBUG_FUNCTION_LINE_VERBOSE("Init Overlay");
gOverlayFrame = new (std::nothrow) OverlayFrame(1280.0f, 720.0f);
if (!gOverlayFrame) {
OSFatal("Failed to alloc gOverlayFrame");
OSFatal("NotificationModule: Failed to alloc gOverlayFrame");
}

// Add notification that had been called before the overlay was ready
for (const auto &notification : gOverlayQueueDuringStartup) {
gOverlayFrame->addNotification(notification);
}
gOverlayQueueDuringStartup.clear();

// Allocate shader.
ColorShader::instance();
Texture2DShader::instance();
if (ColorShader::instance() == nullptr) {
OSFatal("NotificationModule: Failed to alloc ColorShader");
}
if (Texture2DShader::instance() == nullptr) {
OSFatal("NotificationModule: Failed to alloc Texture2DShader");
}

// has been allocated in WUMS INIT
if (!gContextState) {
OSFatal("Failed to alloc gContextState");
OSFatal("NotificationModule: Failed to alloc gContextState");
}
real_GX2SetupContextStateEx(gContextState, GX2_TRUE);
DCInvalidateRange(gContextState, sizeof(GX2ContextState)); // Important!
Expand Down
4 changes: 3 additions & 1 deletion src/gui/SchriftGX2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ ftgxCharData *SchriftGX2::cacheGlyphData(wchar_t charCode, int16_t pixelSize) {
textureHeight = mtx.minHeight;

SFT_Image img = {
.pixels = nullptr,
.width = textureWidth,
.height = textureHeight,
};
Expand Down Expand Up @@ -307,7 +308,7 @@ bool SchriftGX2::loadGlyphData(SFT_Image *bmp, ftgxCharData *charData, ftGX2Data

auto *src = (uint8_t *) bmp->pixels;
auto *dst = (uint32_t *) charData->texture->surface.image;
uint32_t x, y;
int32_t x, y;

for (y = 0; y < bmp->height; y++) {
for (x = 0; x < bmp->width; x++) {
Expand Down Expand Up @@ -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) {
(void) textWidth;
if (!text) {
return 0;
}
Expand Down
29 changes: 18 additions & 11 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

WUMS_MODULE_EXPORT_NAME("homebrew_notifications");

#define VERSION "v0.1.1"
#define VERSION "v0.1.2"

WUMS_DEPENDS_ON(homebrew_memorymapping);
WUMS_DEPENDS_ON(homebrew_functionpatcher);
Expand All @@ -20,7 +20,7 @@ WUMS_INITIALIZE() {
initLogging();

if (FunctionPatcher_InitLibrary() != FUNCTION_PATCHER_RESULT_SUCCESS) {
OSFatal("homebrew_notifications: FunctionPatcher_InitLibrary failed");
OSFatal("NotificationModule: FunctionPatcher_InitLibrary failed");
}
DEBUG_FUNCTION_LINE("Patch NotificationModule functions");
for (uint32_t i = 0; i < function_replacements_size; i++) {
Expand All @@ -38,22 +38,22 @@ WUMS_INITIALIZE() {
sizeof(GX2ContextState),
GX2_CONTEXT_STATE_ALIGNMENT);
if (gContextState == nullptr) {
OSFatal("Failed to allocate gContextState");
OSFatal("NotificationModule: Failed to allocate gContextState");
} 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;
uint32_t size = 0;
OSGetSharedData(OS_SHAREDDATATYPE_FONT_STANDARD, 0, &font, &size);
if (font && size) {
if (OSGetSharedData(OS_SHAREDDATATYPE_FONT_STANDARD, 0, &font, &size) && font && size > 0) {
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();
deinitLogging();
}
Expand All @@ -65,6 +65,7 @@ WUMS_APPLICATION_STARTS() {
}

WUMS_APPLICATION_ENDS() {
gDrawReady = false;
if (gOverlayFrame) {
gOverlayFrame->clearElements();
}
Expand All @@ -76,3 +77,9 @@ WUMS_APPLICATION_ENDS() {
Texture2DShader::destroyInstance();
deinitLogging();
}

WUMS_DEINITIALIZE() {
delete gOverlayFrame;
delete gFontSystem;
MEMFreeToMappedMemory(gContextState);
}
18 changes: 10 additions & 8 deletions src/retain_vars.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#include "retain_vars.hpp"

GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2ContextState *gContextState = nullptr;
GX2ContextState *gOriginalContextState = nullptr;
OverlayFrame *gOverlayFrame = nullptr;
SchriftGX2 *gFontSystem = nullptr;
bool gOverlayInitDone = false;
bool gDrawReady = false;
GX2SurfaceFormat gTVSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2SurfaceFormat gDRCSurfaceFormat = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
GX2ContextState *gContextState = nullptr;
GX2ContextState *gOriginalContextState = nullptr;
std::mutex gOverlayFrameMutex = {};
std::vector<std::shared_ptr<Notification>> gOverlayQueueDuringStartup = {};
OverlayFrame *gOverlayFrame = nullptr;
SchriftGX2 *gFontSystem = nullptr;
bool gOverlayInitDone = false;
bool gDrawReady = false;
2 changes: 2 additions & 0 deletions src/retain_vars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ extern GX2SurfaceFormat gTVSurfaceFormat;
extern GX2SurfaceFormat gDRCSurfaceFormat;
extern GX2ContextState *gContextState;
extern GX2ContextState *gOriginalContextState;
extern std::mutex gOverlayFrameMutex;
extern std::vector<std::shared_ptr<Notification>> gOverlayQueueDuringStartup;
extern OverlayFrame *gOverlayFrame;
extern SchriftGX2 *gFontSystem;
extern bool gOverlayInitDone;
Expand Down