whb: Add UDP logging support.

This commit is contained in:
James Benton 2017-06-02 11:46:15 +01:00
parent fb38792da9
commit fb325ec894
9 changed files with 278 additions and 20 deletions

View File

@ -0,0 +1,29 @@
#pragma once
#include <wut.h>
/**
* \defgroup whb_log Logger
* \ingroup whb
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*LogHandlerFn)(const char *msg);
BOOL
WHBAddLogHandler(LogHandlerFn fn);
BOOL
WHBLogPrint(const char *str);
BOOL
WHBLogPrintf(const char *fmt, ...);
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -0,0 +1,21 @@
#pragma once
#include <wut.h>
/**
* \defgroup whb_log_udp UDP Log Output
* \ingroup whb
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
BOOL
WHBLogUdpInit();
#ifdef __cplusplus
}
#endif
/** @} */

View File

@ -2,6 +2,7 @@
#include <defaultheap.h>
#include <string.h>
#include <whb/file.h>
#include <whb/log.h>
static BOOL
sInitialised = FALSE;
@ -49,6 +50,7 @@ WHBOpenFile(const char *path,
FSInitCmdBlock(&cmd);
result = FSOpenFile(&sClient, &cmd, tmp, mode, &handle, -1);
if (result < 0) {
WHBLogPrintf("%s: FSOpenFile error %d", __FUNCTION__, result);
return WHB_FILE_FATAL_ERROR;
}
@ -64,6 +66,7 @@ WHBGetFileSize(int32_t handle)
FSInitCmdBlock(&cmd);
result = FSGetStatFile(&sClient, &cmd, (FSFileHandle)handle, &stat, -1);
if (result < 0) {
WHBLogPrintf("%s: FSGetStatFile error %d", __FUNCTION__, result);
return 0;
}
@ -81,6 +84,7 @@ WHBReadFile(int32_t handle,
FSInitCmdBlock(&cmd);
result = FSReadFile(&sClient, &cmd, buf, size, count, (FSFileHandle)handle, 0, -1);
if (result < 0) {
WHBLogPrintf("%s: FSReadFile error %d", __FUNCTION__, result);
return 0;
}
@ -95,6 +99,7 @@ WHBCloseFile(int32_t handle)
FSInitCmdBlock(&cmd);
result = FSCloseFile(&sClient, &cmd, (FSFileHandle)handle, -1);
if (result != FS_STATUS_OK) {
WHBLogPrintf("%s: FSCloseFile error %d", __FUNCTION__, result);
return WHB_FILE_FATAL_ERROR;
}
@ -110,6 +115,7 @@ WHBReadWholeFile(const char *path,
char *buf = NULL;
handle = WHBOpenFile(path, "r");
if (handle == WHB_FILE_FATAL_ERROR) {
WHBLogPrintf("%s: WHBOpenFile failed", __FUNCTION__);
return NULL;
}
@ -120,6 +126,7 @@ WHBReadWholeFile(const char *path,
buf = MEMAllocFromDefaultHeapEx(size, 64);
if (!buf) {
WHBLogPrintf("%s: MEMAllocFromDefaultHeapEx(0x%X, 64) failed", __FUNCTION__, size);
goto error;
}

View File

@ -15,6 +15,7 @@
#include <proc_ui/procui.h>
#include <string.h>
#include <whb/gfx.h>
#include <whb/log.h>
#define WHB_GFX_COMMAND_BUFFER_POOL_SIZE (0x400000)
@ -148,12 +149,23 @@ GfxInitDepthBuffer(GX2DepthBuffer *db,
static uint32_t
GfxProcCallbackAcquired(void *context)
{
GfxHeapInitMEM1();
GfxHeapInitForeground();
if (!GfxHeapInitMEM1()) {
WHBLogPrintf("%s: GfxHeapInitMEM1 failed", __FUNCTION__);
goto error;
}
if (!GfxHeapInitForeground()) {
WHBLogPrintf("%s: GfxHeapInitForeground failed", __FUNCTION__);
goto error;
}
// Allocate TV scan buffer.
sTvScanBuffer = GfxHeapAllocForeground(sTvScanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT);
if (!sTvScanBuffer) {
WHBLogPrintf("%s: sTvScanBuffer = GfxHeapAllocForeground(0x%X, 0x%X) failed",
__FUNCTION__,
sTvScanBufferSize,
GX2_SCAN_BUFFER_ALIGNMENT);
goto error;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sTvScanBuffer, sTvScanBufferSize);
@ -162,6 +174,10 @@ GfxProcCallbackAcquired(void *context)
// Allocate TV colour buffer.
sTvColourBuffer.surface.image = GfxHeapAllocMEM1(sTvColourBuffer.surface.imageSize, sTvColourBuffer.surface.alignment);
if (!sTvColourBuffer.surface.image) {
WHBLogPrintf("%s: sTvColourBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed",
__FUNCTION__,
sTvColourBuffer.surface.imageSize,
sTvColourBuffer.surface.alignment);
goto error;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sTvColourBuffer.surface.image, sTvColourBuffer.surface.imageSize);
@ -169,6 +185,10 @@ GfxProcCallbackAcquired(void *context)
// Allocate TV depth buffer.
sTvDepthBuffer.surface.image = GfxHeapAllocMEM1(sTvDepthBuffer.surface.imageSize, sTvDepthBuffer.surface.alignment);
if (!sTvDepthBuffer.surface.image) {
WHBLogPrintf("%s: sTvDepthBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed",
__FUNCTION__,
sTvDepthBuffer.surface.imageSize,
sTvDepthBuffer.surface.alignment);
goto error;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sTvDepthBuffer.surface.image, sTvDepthBuffer.surface.imageSize);
@ -176,6 +196,10 @@ GfxProcCallbackAcquired(void *context)
// Allocate DRC scan buffer.
sDrcScanBuffer = GfxHeapAllocForeground(sDrcScanBufferSize, GX2_SCAN_BUFFER_ALIGNMENT);
if (!sDrcScanBuffer) {
WHBLogPrintf("%s: sDrcScanBuffer = GfxHeapAllocForeground(0x%X, 0x%X) failed",
__FUNCTION__,
sDrcScanBufferSize,
GX2_SCAN_BUFFER_ALIGNMENT);
goto error;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sDrcScanBuffer, sDrcScanBufferSize);
@ -184,6 +208,10 @@ GfxProcCallbackAcquired(void *context)
// Allocate DRC colour buffer.
sDrcColourBuffer.surface.image = GfxHeapAllocMEM1(sDrcColourBuffer.surface.imageSize, sDrcColourBuffer.surface.alignment);
if (!sDrcColourBuffer.surface.image) {
WHBLogPrintf("%s: sDrcColourBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed",
__FUNCTION__,
sDrcColourBuffer.surface.imageSize,
sDrcColourBuffer.surface.alignment);
goto error;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sDrcColourBuffer.surface.image, sDrcColourBuffer.surface.imageSize);
@ -191,13 +219,17 @@ GfxProcCallbackAcquired(void *context)
// Allocate DRC depth buffer.
sDrcDepthBuffer.surface.image = GfxHeapAllocMEM1(sDrcDepthBuffer.surface.imageSize, sDrcDepthBuffer.surface.alignment);
if (!sDrcDepthBuffer.surface.image) {
WHBLogPrintf("%s: sDrcDepthBuffer = GfxHeapAllocMEM1(0x%X, 0x%X) failed",
__FUNCTION__,
sDrcDepthBuffer.surface.imageSize,
sDrcDepthBuffer.surface.alignment);
goto error;
}
GX2Invalidate(GX2_INVALIDATE_MODE_CPU, sDrcDepthBuffer.surface.image, sDrcDepthBuffer.surface.imageSize);
return 0;
error:
return 1;
return -1;
}
static uint32_t
@ -250,6 +282,7 @@ WHBGfxInit()
sCommandBufferPool = GfxHeapAllocMEM2(WHB_GFX_COMMAND_BUFFER_POOL_SIZE,
GX2_COMMAND_BUFFER_ALIGNMENT);
if (!sCommandBufferPool) {
WHBLogPrintf("%s: failed to allocate command buffer pool", __FUNCTION__);
goto error;
}
@ -299,8 +332,8 @@ WHBGfxInit()
GX2CalcDRCSize(sDrcRenderMode, sDrcSurfaceFormat, GX2_BUFFERING_MODE_DOUBLE, &sDrcScanBufferSize, &unk);
GfxInitTvColourBuffer(&sDrcColourBuffer, drcWidth, drcHeight, sDrcSurfaceFormat, GX2_AA_MODE1X);
GfxInitDepthBuffer(&sDrcDepthBuffer, sDrcColourBuffer.surface.width, sDrcColourBuffer.surface.height, GX2_SURFACE_FORMAT_FLOAT_R32, sDrcColourBuffer.surface.aa);
if (GfxProcCallbackAcquired(NULL) != 0) {
WHBLogPrintf("%s: GfxProcCallbackAcquired failed", __FUNCTION__);
goto error;
}
@ -311,6 +344,7 @@ WHBGfxInit()
// Initialise TV context state.
sTvContextState = GfxHeapAllocMEM2(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT);
if (!sTvContextState) {
WHBLogPrintf("%s: failed to allocate sTvContextState", __FUNCTION__);
goto error;
}
GX2SetupContextStateEx(sTvContextState, TRUE);
@ -324,6 +358,7 @@ WHBGfxInit()
// Initialise DRC context state.
sDrcContextState = GfxHeapAllocMEM2(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT);
if (!sDrcContextState) {
WHBLogPrintf("%s: failed to allocate sDrcContextState", __FUNCTION__);
goto error;
}
GX2SetupContextStateEx(sDrcContextState, TRUE);
@ -336,8 +371,6 @@ WHBGfxInit()
// Set 60fps VSync
GX2SetSwapInterval(1);
GX2SetTVEnable(TRUE);
GX2SetDRCEnable(TRUE);
return TRUE;
@ -433,9 +466,11 @@ WHBGfxBeginRender()
void
WHBGfxFinishRender()
{
GX2Flush();
GX2SwapScanBuffers();
GX2Flush();
GX2DrawDone();
GX2SetTVEnable(TRUE);
GX2SetDRCEnable(TRUE);
}
void

View File

@ -3,6 +3,7 @@
#include <coreinit/expandedheap.h>
#include <coreinit/frameheap.h>
#include <defaultheap.h>
#include <whb/log.h>
static void *
sGfxHeapMEM1 = NULL;
@ -10,22 +11,35 @@ sGfxHeapMEM1 = NULL;
static void *
sGfxHeapForeground = NULL;
#define GFX_FRAME_HEAP_TAG (0x123DECAF)
BOOL
GfxHeapInitMEM1()
{
MEMHeapHandle mem1 = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
uint32_t size = MEMGetAllocatableSizeForFrmHeapEx(mem1, 4);
if (!size) {
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
uint32_t size;
void *base;
if (!MEMRecordStateForFrmHeap(heap, GFX_FRAME_HEAP_TAG)) {
WHBLogPrintf("%s: MEMRecordStateForFrmHeap failed", __FUNCTION__);
return FALSE;
}
void *base = MEMAllocFromFrmHeapEx(mem1, size, 4);
size = MEMGetAllocatableSizeForFrmHeapEx(heap, 4);
if (!size) {
WHBLogPrintf("%s: MEMGetAllocatableSizeForFrmHeapEx == 0", __FUNCTION__);
return FALSE;
}
base = MEMAllocFromFrmHeapEx(heap, size, 4);
if (!base) {
WHBLogPrintf("%s: MEMAllocFromFrmHeapEx(heap, 0x%X, 4) failed", __FUNCTION__, size);
return FALSE;
}
sGfxHeapMEM1 = MEMCreateExpHeapEx(base, size, 0);
if (!sGfxHeapMEM1) {
WHBLogPrintf("%s: MEMCreateExpHeapEx(0x%08X, 0x%X, 0) failed", __FUNCTION__, base, size);
return FALSE;
}
@ -35,33 +49,39 @@ GfxHeapInitMEM1()
BOOL
GfxHeapDestroyMEM1()
{
MEMHeapHandle mem1 = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM1);
if (sGfxHeapMEM1) {
MEMDestroyExpHeap(sGfxHeapMEM1);
sGfxHeapMEM1 = NULL;
}
MEMFreeToFrmHeap(mem1, MEM_FRAME_HEAP_FREE_ALL);
MEMFreeByStateToFrmHeap(heap, GFX_FRAME_HEAP_TAG);
return TRUE;
}
BOOL
GfxHeapInitForeground()
{
MEMHeapHandle mem1 = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG);
uint32_t size = MEMGetAllocatableSizeForFrmHeapEx(mem1, 4);
MEMHeapHandle heap = MEMGetBaseHeapHandle(MEM_BASE_HEAP_FG);
uint32_t size;
void *base;
size = MEMGetAllocatableSizeForFrmHeapEx(heap, 4);
if (!size) {
WHBLogPrintf("%s: MEMAllocFromFrmHeapEx(heap, 0x%X, 4)", __FUNCTION__, size);
return FALSE;
}
void *base = MEMAllocFromFrmHeapEx(mem1, size, 4);
base = MEMAllocFromFrmHeapEx(heap, size, 4);
if (!base) {
WHBLogPrintf("%s: MEMGetAllocatableSizeForFrmHeapEx == 0", __FUNCTION__);
return FALSE;
}
sGfxHeapForeground = MEMCreateExpHeapEx(base, size, 0);
if (!sGfxHeapForeground) {
WHBLogPrintf("%s: MEMCreateExpHeapEx(0x%08X, 0x%X, 0)", __FUNCTION__, base, size);
return FALSE;
}

View File

@ -6,6 +6,7 @@
#include <latte/latte_enum_sq.h>
#include <string.h>
#include <whb/gfx.h>
#include <whb/log.h>
GX2PixelShader *
WHBGfxLoadGFDPixelShader(uint32_t index,
@ -16,18 +17,28 @@ WHBGfxLoadGFDPixelShader(uint32_t index,
void *program = NULL;
if (index >= GFDGetPixelShaderCount(file)) {
WHBLogPrintf("%s: index %u >= %u GFDGetPixelShaderCount(file)",
__FUNCTION__,
index,
GFDGetPixelShaderCount(file));
goto error;
}
headerSize = GFDGetPixelShaderHeaderSize(index, file);
programSize = GFDGetPixelShaderProgramSize(index, file);
if (!headerSize) {
WHBLogPrintf("%s: headerSize == 0", __FUNCTION__);
goto error;
}
if (!headerSize || !programSize) {
programSize = GFDGetPixelShaderProgramSize(index, file);
if (!programSize) {
WHBLogPrintf("%s: programSize == 0", __FUNCTION__);
goto error;
}
shader = (GX2PixelShader *)GfxHeapAllocMEM2(headerSize, 64);
if (!shader) {
WHBLogPrintf("%s: GfxHeapAllocMEM2(%u, 64) failed", __FUNCTION__, headerSize);
goto error;
}
@ -36,11 +47,18 @@ WHBGfxLoadGFDPixelShader(uint32_t index,
shader->gx2rBuffer.elemCount = 1;
shader->gx2rBuffer.buffer = NULL;
if (!GX2RCreateBuffer(&shader->gx2rBuffer)) {
WHBLogPrintf("%s: GX2RCreateBuffer failed with programSize = %u", __FUNCTION__, programSize);
goto error;
}
program = GX2RLockBufferEx(&shader->gx2rBuffer, 0);
if (!program) {
WHBLogPrintf("%s: GX2RLockBufferEx failed", __FUNCTION__);
goto error;
}
if (!GFDGetPixelShader(shader, program, index, file)) {
WHBLogPrintf("%s: GFDGetPixelShader failed", __FUNCTION__);
GX2RUnlockBufferEx(&shader->gx2rBuffer, GX2R_RESOURCE_DISABLE_CPU_INVALIDATE | GX2R_RESOURCE_DISABLE_GPU_INVALIDATE);
goto error;
}
@ -79,18 +97,28 @@ WHBGfxLoadGFDVertexShader(uint32_t index,
void *program = NULL;
if (index >= GFDGetVertexShaderCount(file)) {
WHBLogPrintf("%s: index %u >= %u GFDGetVertexShaderCount(file)",
__FUNCTION__,
index,
GFDGetVertexShaderCount(file));
goto error;
}
headerSize = GFDGetVertexShaderHeaderSize(index, file);
programSize = GFDGetVertexShaderProgramSize(index, file);
if (!headerSize) {
WHBLogPrintf("%s: headerSize == 0", __FUNCTION__);
goto error;
}
if (!headerSize || !programSize) {
programSize = GFDGetVertexShaderProgramSize(index, file);
if (!programSize) {
WHBLogPrintf("%s: programSize == 0", __FUNCTION__);
goto error;
}
shader = (GX2VertexShader *)GfxHeapAllocMEM2(headerSize, 64);
if (!shader) {
WHBLogPrintf("%s: GfxHeapAllocMEM2(%u, 64) failed", __FUNCTION__, headerSize);
goto error;
}
@ -99,11 +127,18 @@ WHBGfxLoadGFDVertexShader(uint32_t index,
shader->gx2rBuffer.elemCount = 1;
shader->gx2rBuffer.buffer = NULL;
if (!GX2RCreateBuffer(&shader->gx2rBuffer)) {
WHBLogPrintf("%s: GX2RCreateBuffer failed with programSize = %u", __FUNCTION__, programSize);
goto error;
}
program = GX2RLockBufferEx(&shader->gx2rBuffer, 0);
if (!program) {
WHBLogPrintf("%s: GX2RLockBufferEx failed", __FUNCTION__);
goto error;
}
if (!GFDGetVertexShader(shader, program, index, file)) {
WHBLogPrintf("%s: GFDGetVertexShader failed", __FUNCTION__);
GX2RUnlockBufferEx(&shader->gx2rBuffer, GX2R_RESOURCE_DISABLE_CPU_INVALIDATE | GX2R_RESOURCE_DISABLE_GPU_INVALIDATE);
goto error;
}

View File

@ -2,6 +2,7 @@
#include <gfd.h>
#include <gx2r/surface.h>
#include <gx2/texture.h>
#include <whb/log.h>
#include <whb/gfx.h>
GX2Texture *
@ -13,6 +14,7 @@ WHBGfxLoadGFDTexture(uint32_t index,
void *image = NULL;
if (index >= GFDGetTextureCount(file)) {
WHBLogPrintf("%s: invalid GFD texture index %u", __FUNCTION__, index);
goto error;
}
@ -25,6 +27,7 @@ WHBGfxLoadGFDTexture(uint32_t index,
texture = (GX2Texture *)GfxHeapAllocMEM2(headerSize, 64);
if (!texture) {
WHBLogPrintf("%s: GfxHeapAllocMEM2(0x%X, 64) failed", __FUNCTION__, headerSize);
goto error;
}

61
src/libwhb/src/log.c Normal file
View File

@ -0,0 +1,61 @@
#include <defaultheap.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <whb/log.h>
#define MAX_HANDLERS 16
#define PRINTF_BUFFER_LENGTH 2048
static LogHandlerFn
sHandlers[MAX_HANDLERS] = { 0 };
BOOL
WHBAddLogHandler(LogHandlerFn fn)
{
int i;
for (i = 0; i < MAX_HANDLERS; ++i) {
if (!sHandlers[i]) {
sHandlers[i] = fn;
return TRUE;
}
}
return FALSE;
}
BOOL
WHBLogPrint(const char *str)
{
int i;
for (i = 0; i < MAX_HANDLERS; ++i) {
if (sHandlers[i]) {
sHandlers[i](str);
}
}
return TRUE;
}
BOOL
WHBLogPrintf(const char *fmt, ...)
{
char *buf = MEMAllocFromDefaultHeapEx(PRINTF_BUFFER_LENGTH, 4);
va_list va;
BOOL result;
if (!buf) {
return FALSE;
}
va_start(va, fmt);
vsnprintf(buf, PRINTF_BUFFER_LENGTH, fmt, va);
result = WHBLogPrint(buf);
MEMFreeToDefaultHeap(buf);
va_end(va);
return result;
}

47
src/libwhb/src/log_udp.c Normal file
View File

@ -0,0 +1,47 @@
#include <coreinit/mutex.h>
#include <defaultheap.h>
#include <nsysnet/socket.h>
#include <string.h>
#include <whb/log.h>
#include <whb/log_udp.h>
static int
sSocket = -1;
static struct sockaddr_in
sSendAddr;
#define SERVER_PORT 4405
static void
udpLogHandler(const char *msg)
{
sendto(sSocket,
msg,
strlen(msg),
0,
(struct sockaddr *)&sSendAddr,
sizeof(struct sockaddr_in));
}
BOOL
WHBLogUdpInit()
{
int broadcastEnable = 1;
socket_lib_init();
sSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sSocket < 0) {
return FALSE;
}
setsockopt(sSocket, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
memset(&sSendAddr, 0, sizeof(struct sockaddr_in));
sSendAddr.sin_family = AF_INET;
sSendAddr.sin_port = htons(SERVER_PORT);
sSendAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
WHBAddLogHandler(udpLogHandler);
return TRUE;
}