From cb923e77a39869c52e771587db8742783406317d Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sun, 7 Sep 2025 17:46:21 -0400 Subject: [PATCH 1/3] implement gc controller centering on boot --- include/PR/os_cont.h | 8 ++++++++ src/io/contreaddata.c | 46 ++++++++++++++++++++++++++++++------------- src/io/controller.c | 2 +- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/include/PR/os_cont.h b/include/PR/os_cont.h index 860a7926..f512cc67 100644 --- a/include/PR/os_cont.h +++ b/include/PR/os_cont.h @@ -93,6 +93,14 @@ typedef struct { } cStickMap; } OSContButtonMap; +typedef struct { + s8 initialized; + u8 stick_x; + u8 stick_y; + u8 c_stick_x; + u8 c_stick_y; +} OSContCenterMapping; + typedef struct { void* address; /* Ram pad Address: 11 bits */ u8 databuffer[32]; /* address of the data buffer */ diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index 1c1ac8e7..4fbdac26 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -9,6 +9,8 @@ static void __osPackReadData(void); static u16 __osTranslateGCNButtons(u16, s32, s32); static u16 __osTranslateN64Buttons(u16); +static OSContCenterMapping __osControllerCenters[MAXCONTROLLERS] = { 0 }; + static OSContButtonMap __osDefaultControllerMap = { .buttonMap = { .l_jpad = L_JPAD, @@ -64,21 +66,37 @@ void osContGetReadData(OSContPad* data) { for (i = 0; i < __osMaxControllers; i++, data++) { if (__osControllerTypes[i] == CONT_TYPE_GCN) { s32 stick_x, stick_y, c_stick_x, c_stick_y; + readformatgcn = *(__OSContGCNShortPollFormat*)ptr; - // The analog stick data is encoded unsigned, with (0, 0) being the bottom left of the stick plane, - // compared to the N64 where (0, 0) is the center. We correct it here so that the end user does not - // have to account for this discrepancy. - stick_x = ((s32)readformatgcn.stick_x) - 128; - stick_y = ((s32)readformatgcn.stick_y) - 128; - data->stick_x = stick_x; - data->stick_y = stick_y; - c_stick_x = ((s32)readformatgcn.c_stick_x) - 128; - c_stick_y = ((s32)readformatgcn.c_stick_y) - 128; - data->c_stick_x = c_stick_x; - data->c_stick_y = c_stick_y; - data->button = __osTranslateGCNButtons(readformatgcn.button, c_stick_x, c_stick_y); - data->l_trig = readformatgcn.l_trig; - data->r_trig = readformatgcn.r_trig; + data->errno = CHNL_ERR(readformatgcn); + + if (data->errno == 0) { + // The analog stick data is encoded unsigned, with (0, 0) being the bottom left of the stick plane, + // compared to the N64 where (0, 0) is the center. We correct it here so that the end user does not + // have to account for this discrepancy. + if (!__osControllerCenters[i].initialized) { + __osControllerCenters[i].initialized = TRUE; + __osControllerCenters[i].stick_x = readformatgcn.stick_x; + __osControllerCenters[i].stick_y = readformatgcn.stick_y; + __osControllerCenters[i].c_stick_x = readformatgcn.c_stick_x; + __osControllerCenters[i].c_stick_y = readformatgcn.c_stick_y; + } + + stick_x = ((s32)readformatgcn.stick_x) - __osControllerCenters[i].stick_x; + stick_y = ((s32)readformatgcn.stick_y) - __osControllerCenters[i].stick_y; + data->stick_x = stick_x; + data->stick_y = stick_y; + c_stick_x = ((s32)readformatgcn.c_stick_x) - __osControllerCenters[i].c_stick_x; + c_stick_y = ((s32)readformatgcn.c_stick_y) - __osControllerCenters[i].c_stick_y; + data->c_stick_x = c_stick_x; + data->c_stick_y = c_stick_y; + data->button = __osTranslateGCNButtons(readformatgcn.button, c_stick_x, c_stick_y); + data->l_trig = readformatgcn.l_trig; + data->r_trig = readformatgcn.r_trig; + } else { + __osControllerCenters[i].initialized = FALSE; + } + ptr += sizeof(__OSContGCNShortPollFormat); } else { readformat = *(__OSContReadFormat*)ptr; diff --git a/src/io/controller.c b/src/io/controller.c index 2210f6df..1027a424 100644 --- a/src/io/controller.c +++ b/src/io/controller.c @@ -35,7 +35,7 @@ s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) { osRecvMesg(&timerMesgQueue, &dummy, OS_MESG_BLOCK); } - __osMaxControllers = 4; + __osMaxControllers = MAXCONTROLLERS; __osPackRequestData(CONT_CMD_REQUEST_STATUS); From b6c1e38f43219fa4c3c00a6dd04a21b44f042af6 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sun, 7 Sep 2025 17:52:02 -0400 Subject: [PATCH 2/3] add clamp macros too --- include/PRinternal/macros.h | 35 +++++++++++++++++++++++++++++++++++ src/host/writehost.c | 4 +--- src/io/contreaddata.c | 8 ++++---- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/PRinternal/macros.h b/include/PRinternal/macros.h index 1bdfc589..42588ca8 100644 --- a/include/PRinternal/macros.h +++ b/include/PRinternal/macros.h @@ -21,4 +21,39 @@ #define STACK_START(stack) ((u8*)(stack) + sizeof(stack)) +#ifndef MIN +#define MIN(a, b) ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a < _b ? _a : _b; }) +#endif // MIN + +#ifndef MAX +#define MAX(a, b) ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a > _b ? _a : _b; }) +#endif // MAX + +// Integer limits and clamping +#define S8_MAX 127 +#define S8_MIN -128 +#define U8_MAX 255 +#define S16_MAX 32767 +#define S16_MIN -32768 +#define U16_MAX 65535 +#define S32_MAX 2147483647 +#define S32_MIN -2147483648 +#define U32_MAX 4294967295 + +// Clamp a value inbetween a range +#define CLAMP(x, low, high) MIN(MAX((x), (low)), (high)) + +// Clamp a value to the range of a specific data type +#define CLAMP_U8( x) CLAMP((x), 0, U8_MAX) +#define CLAMP_S8( x) CLAMP((x), S8_MIN, S8_MAX) +#define CLAMP_U16(x) CLAMP((x), 0, U16_MAX) +#define CLAMP_S16(x) CLAMP((x), S16_MIN, S16_MAX) + + #endif diff --git a/src/host/writehost.c b/src/host/writehost.c index 1d1baf46..9643b174 100644 --- a/src/host/writehost.c +++ b/src/host/writehost.c @@ -10,8 +10,6 @@ static int writeHostInitialized = FALSE; static OSMesgQueue writeHostMesgQueue ALIGNED(0x8); static OSMesg writeHostMesgBuf[1]; -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - void osWriteHost(void* dramAddr, u32 nbytes) { u8* tPtr = dramAddr; u32 sent; @@ -32,7 +30,7 @@ void osWriteHost(void* dramAddr, u32 nbytes) { } while (nbytes != 0) { - count = MIN(nbytes, 0x8000); + count = MIN(nbytes, 0x8000U); dCount[0] = (count & 0xFF0000) >> 0x10; dCount[1] = (count & 0xFF00) >> 8; diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index 4fbdac26..0cd3b657 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -82,12 +82,12 @@ void osContGetReadData(OSContPad* data) { __osControllerCenters[i].c_stick_y = readformatgcn.c_stick_y; } - stick_x = ((s32)readformatgcn.stick_x) - __osControllerCenters[i].stick_x; - stick_y = ((s32)readformatgcn.stick_y) - __osControllerCenters[i].stick_y; + stick_x = CLAMP_S8(((s32)readformatgcn.stick_x) - __osControllerCenters[i].stick_x); + stick_y = CLAMP_S8(((s32)readformatgcn.stick_y) - __osControllerCenters[i].stick_y); data->stick_x = stick_x; data->stick_y = stick_y; - c_stick_x = ((s32)readformatgcn.c_stick_x) - __osControllerCenters[i].c_stick_x; - c_stick_y = ((s32)readformatgcn.c_stick_y) - __osControllerCenters[i].c_stick_y; + c_stick_x = CLAMP_S8(((s32)readformatgcn.c_stick_x) - __osControllerCenters[i].c_stick_x); + c_stick_y = CLAMP_S8(((s32)readformatgcn.c_stick_y) - __osControllerCenters[i].c_stick_y); data->c_stick_x = c_stick_x; data->c_stick_y = c_stick_y; data->button = __osTranslateGCNButtons(readformatgcn.button, c_stick_x, c_stick_y); From 59e266758215d8da78457174a345401d3a05c2a7 Mon Sep 17 00:00:00 2001 From: someone2639 Date: Sun, 7 Sep 2025 17:52:38 -0400 Subject: [PATCH 3/3] format --- include/PRinternal/macros.h | 43 ++++++++++++++++++++----------------- src/io/contreaddata.c | 4 ++-- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/include/PRinternal/macros.h b/include/PRinternal/macros.h index 42588ca8..0baeeeaa 100644 --- a/include/PRinternal/macros.h +++ b/include/PRinternal/macros.h @@ -22,38 +22,41 @@ #define STACK_START(stack) ((u8*)(stack) + sizeof(stack)) #ifndef MIN -#define MIN(a, b) ({ \ - __auto_type _a = (a); \ - __auto_type _b = (b); \ - _a < _b ? _a : _b; }) +#define MIN(a, b) \ + ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a < _b ? _a : _b; \ + }) #endif // MIN #ifndef MAX -#define MAX(a, b) ({ \ - __auto_type _a = (a); \ - __auto_type _b = (b); \ - _a > _b ? _a : _b; }) +#define MAX(a, b) \ + ({ \ + __auto_type _a = (a); \ + __auto_type _b = (b); \ + _a > _b ? _a : _b; \ + }) #endif // MAX // Integer limits and clamping -#define S8_MAX 127 +#define S8_MAX 127 #define S8_MIN -128 -#define U8_MAX 255 -#define S16_MAX 32767 +#define U8_MAX 255 +#define S16_MAX 32767 #define S16_MIN -32768 -#define U16_MAX 65535 -#define S32_MAX 2147483647 +#define U16_MAX 65535 +#define S32_MAX 2147483647 #define S32_MIN -2147483648 -#define U32_MAX 4294967295 +#define U32_MAX 4294967295 // Clamp a value inbetween a range -#define CLAMP(x, low, high) MIN(MAX((x), (low)), (high)) +#define CLAMP(x, low, high) MIN(MAX((x), (low)), (high)) // Clamp a value to the range of a specific data type -#define CLAMP_U8( x) CLAMP((x), 0, U8_MAX) -#define CLAMP_S8( x) CLAMP((x), S8_MIN, S8_MAX) -#define CLAMP_U16(x) CLAMP((x), 0, U16_MAX) -#define CLAMP_S16(x) CLAMP((x), S16_MIN, S16_MAX) - +#define CLAMP_U8(x) CLAMP((x), 0, U8_MAX) +#define CLAMP_S8(x) CLAMP((x), S8_MIN, S8_MAX) +#define CLAMP_U16(x) CLAMP((x), 0, U16_MAX) +#define CLAMP_S16(x) CLAMP((x), S16_MIN, S16_MAX) #endif diff --git a/src/io/contreaddata.c b/src/io/contreaddata.c index 0cd3b657..06a9a0c3 100644 --- a/src/io/contreaddata.c +++ b/src/io/contreaddata.c @@ -76,8 +76,8 @@ void osContGetReadData(OSContPad* data) { // have to account for this discrepancy. if (!__osControllerCenters[i].initialized) { __osControllerCenters[i].initialized = TRUE; - __osControllerCenters[i].stick_x = readformatgcn.stick_x; - __osControllerCenters[i].stick_y = readformatgcn.stick_y; + __osControllerCenters[i].stick_x = readformatgcn.stick_x; + __osControllerCenters[i].stick_y = readformatgcn.stick_y; __osControllerCenters[i].c_stick_x = readformatgcn.c_stick_x; __osControllerCenters[i].c_stick_y = readformatgcn.c_stick_y; }