Skip to content

Instantly share code, notes, and snippets.

@dkosmari
Created March 14, 2025 00:18
Show Gist options
  • Select an option

  • Save dkosmari/40ad1db100d11292dc5be175c25d40a6 to your computer and use it in GitHub Desktop.

Select an option

Save dkosmari/40ad1db100d11292dc5be175c25d40a6 to your computer and use it in GitHub Desktop.
Using OSScreen with ProcUI/WHBProc.
#include <stdlib.h>
#include <coreinit/cache.h>
#include <coreinit/foreground.h>
#include <coreinit/memfrmheap.h>
#include <coreinit/memheap.h>
#include <coreinit/memory.h>
#include <coreinit/screen.h>
#include <coreinit/thread.h>
#include <coreinit/time.h>
#include <proc_ui/memory.h>
#include <proc_ui/procui.h>
#include <sndcore2/core.h>
#include <sysapp/launch.h>
#include <vpad/input.h>
#include <whb/log.h>
#include <whb/log_module.h>
#include <whb/proc.h>
//#include "image.h"
#define IMAGE_NAME "Test"
void* drc_framebuffer = NULL;
size_t drc_framebuffer_size = 0;
// Define this to let ProcUI preserve MEM1 and FG bucket
#define PROCUI_PRESERVE
void drawImageAndText()
{
if (!ProcUIInForeground())
return;
OSScreenClearBufferEx(SCREEN_DRC, 0);
// for (int x = 0; x < WIDTH; ++x)
// for (int y = 0; y < HEIGHT; ++y)
// if (x <= 1280 && y <= 720)
// OSScreenPutPixelEx(SCREEN_TV, x, y, image[x][y] *= 0x100);
OSScreenPutFontEx(SCREEN_DRC, 10, 7, IMAGE_NAME);
DCFlushRange(drc_framebuffer, drc_framebuffer_size);
OSScreenFlipBuffersEx(SCREEN_DRC);
}
uint32_t
create_mem1_objects(void*)
{
WHBLogPrintf("creating MEM1 objects");
MEMHeapHandle mem1_heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
if (drc_framebuffer_size)
drc_framebuffer = MEMAllocFromFrmHeapEx(mem1_heap, drc_framebuffer_size, 4);
OSScreenSetBufferEx(SCREEN_DRC, drc_framebuffer);
return 0;
}
uint32_t
destroy_mem1_objects(void*)
{
WHBLogPrintf("destroying MEM1 objects");
drc_framebuffer = NULL;
MEMHeapHandle mem1_heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
MEMFreeToFrmHeap(mem1_heap, MEM_FRM_HEAP_FREE_ALL);
return 0;
}
int main()
{
WHBLogModuleInit();
WHBProcInit();
AXInit();
OSScreenInit();
OSScreenEnableEx(SCREEN_DRC, true);
drc_framebuffer_size = OSScreenGetBufferSizeEx(SCREEN_DRC);
#ifdef PROCUI_PRESERVE
uint32_t mem1_start = 0;
uint32_t mem1_size = 0;
OSGetMemBound(OS_MEM1, &mem1_start, &mem1_size);
WHBLogPrintf("MEM1 size is %u, starting at %08x",
mem1_size,
mem1_start);
void* mem1_backup = malloc(mem1_size);
ProcUISetMEM1Storage(mem1_backup, mem1_size);
uint32_t fg_bucket_start = 0;
uint32_t fg_bucket_free_size = 0;
OSGetForegroundBucketFreeArea(&fg_bucket_start, &fg_bucket_free_size);
WHBLogPrintf("FG bucket free size is %u, starting at %08x",
fg_bucket_free_size,
fg_bucket_start);
void* fg_bucket_backup = malloc(fg_bucket_free_size);
ProcUISetBucketStorage(fg_bucket_backup, fg_bucket_free_size);
#else
ProcUIRegisterCallback(PROCUI_CALLBACK_ACQUIRE, create_mem1_objects, NULL, 100);
ProcUIRegisterCallback(PROCUI_CALLBACK_RELEASE, destroy_mem1_objects, NULL, 100);
#endif
create_mem1_objects(NULL);
while (WHBProcIsRunning()) {
VPADStatus status;
if (VPADRead(VPAD_CHAN_0, &status, 1, NULL) == 1) {
if (status.trigger & VPAD_BUTTON_PLUS)
SYSLaunchMenu();
}
drawImageAndText();
OSSleepTicks(OSMillisecondsToTicks(16));
}
if (ProcUIInForeground()) {
OSScreenShutdown();
destroy_mem1_objects(NULL);
}
#ifdef PROCUI_PRESERVE
free(fg_bucket_backup);
free(mem1_backup);
#endif
AXQuit();
WHBProcShutdown();
WHBLogModuleDeinit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment