Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/PR/os_cont.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
38 changes: 38 additions & 0 deletions include/PRinternal/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 1 addition & 3 deletions src/host/writehost.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
46 changes: 32 additions & 14 deletions src/io/contreaddata.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/io/controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down