You've already forked hackerlibultra
mirror of
https://github.com/HackerN64/hackerlibultra.git
synced 2026-01-21 10:37:53 -08:00
Gamecube Controller Centering (#21)
* implement gc controller centering on boot * add clamp macros too * format --------- Co-authored-by: someone2639 <someone2639@gmail.com>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -21,4 +21,42 @@
|
||||
|
||||
#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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 = 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 = 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);
|
||||
data->l_trig = readformatgcn.l_trig;
|
||||
data->r_trig = readformatgcn.r_trig;
|
||||
} else {
|
||||
__osControllerCenters[i].initialized = FALSE;
|
||||
}
|
||||
|
||||
ptr += sizeof(__OSContGCNShortPollFormat);
|
||||
} else {
|
||||
readformat = *(__OSContReadFormat*)ptr;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user