diff --git a/libraries/libwhb/include/whb/log_console.h b/libraries/libwhb/include/whb/log_console.h new file mode 100644 index 0000000..d9af22a --- /dev/null +++ b/libraries/libwhb/include/whb/log_console.h @@ -0,0 +1,29 @@ +#pragma once +#include + +/** + * \defgroup whb_log_console On screen console log output + * \ingroup whb + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define WHB_SERVER_BUFFER_SIZE 1024 + +BOOL +WHBLogConsoleInit(); + +void +WHBLogConsoleFree(); + +void +WHBLogConsoleDraw(); + +#ifdef __cplusplus +} +#endif + +/** @} */ diff --git a/libraries/libwhb/src/console.c b/libraries/libwhb/src/console.c new file mode 100644 index 0000000..eec7b77 --- /dev/null +++ b/libraries/libwhb/src/console.c @@ -0,0 +1,100 @@ +#include +#include + +#include +#include +#include +#include + +#include + +#define NUM_LINES (16) +#define LINE_LENGTH (128) +#define FRAME_HEAP_TAG (0x000DECAF) + +static char sConsoleBuffer[NUM_LINES][LINE_LENGTH]; +static int sLineNum = 0; +static void *sBufferTV, *sBufferDRC; +static uint32_t sBufferSizeTV, sBufferSizeDRC; + +static void +consoleAddLine(const char *line); + +BOOL +WHBLogConsoleInit() +{ + MEMFrameHeap *heap = (MEMFrameHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1); + MEMRecordStateForFrmHeap(heap, FRAME_HEAP_TAG); + + OSScreenInit(); + sBufferSizeTV = OSScreenGetBufferSizeEx(SCREEN_TV); + sBufferSizeDRC = OSScreenGetBufferSizeEx(SCREEN_DRC); + + sBufferTV = MEMAllocFromFrmHeapEx(heap, sBufferSizeTV, 4); + if (!sBufferTV) { + WHBLogPrintf("sBufferTV = MEMAllocFromFrmHeapEx(heap, 0x%X, 4) returned NULL", sBufferSizeTV); + return FALSE; + } + + sBufferDRC = MEMAllocFromFrmHeapEx(heap, sBufferSizeDRC, 4); + if (!sBufferDRC) { + WHBLogPrintf("sBufferDRC = MEMAllocFromFrmHeapEx(heap, 0x%X, 4) returned NULL", sBufferSizeDRC); + return FALSE; + } + + OSScreenSetBufferEx(SCREEN_TV, sBufferTV); + OSScreenSetBufferEx(SCREEN_DRC, sBufferDRC); + + OSScreenEnableEx(SCREEN_TV, 1); + OSScreenEnableEx(SCREEN_DRC, 1); + WHBAddLogHandler(consoleAddLine); + return FALSE; +} + +void +WHBLogConsoleFree() +{ + MEMFrameHeap *heap = (MEMFrameHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1); + OSScreenShutdown(); + MEMFreeByStateToFrmHeap(heap, FRAME_HEAP_TAG); +} + +void +WHBLogConsoleDraw() +{ + OSScreenClearBufferEx(SCREEN_TV, 0x993333FF); + OSScreenClearBufferEx(SCREEN_DRC, 0x993333FF); + + for (int y = 0; y < NUM_LINES; ++y) { + OSScreenPutFontEx(SCREEN_TV, 0, y, sConsoleBuffer[y]); + OSScreenPutFontEx(SCREEN_DRC, 0, y, sConsoleBuffer[y]); + } + + DCFlushRange(sBufferTV, sBufferSizeTV); + DCFlushRange(sBufferDRC, sBufferSizeDRC); + OSScreenFlipBuffersEx(SCREEN_TV); + OSScreenFlipBuffersEx(SCREEN_DRC); +} + +static void +consoleAddLine(const char *line) +{ + int length = strlen(line); + + if (length > LINE_LENGTH) { + length = LINE_LENGTH - 1; + } + + if (sLineNum == NUM_LINES) { + for (int i = 0; i < NUM_LINES - 1; ++i) { + memcpy(sConsoleBuffer[i], sConsoleBuffer[i + 1], LINE_LENGTH); + } + + memcpy(sConsoleBuffer[sLineNum - 1], line, length); + sConsoleBuffer[sLineNum - 1][length] = 0; + } else { + memcpy(sConsoleBuffer[sLineNum], line, length); + sConsoleBuffer[sLineNum][length] = 0; + ++sLineNum; + } +}