diff --git a/include/n64/PR/os_cont.h b/include/n64/PR/os_cont.h index 442994645..7af3072a2 100644 --- a/include/n64/PR/os_cont.h +++ b/include/n64/PR/os_cont.h @@ -112,6 +112,11 @@ typedef struct { /* Controller type */ +// Console ID: +#define CONT_CONSOLE_MASK (0x3 << 3) // 0x0018 | 0: N64, 1: Dolphin +#define CONT_CONSOLE_N64 ( 0 << 3) // 0x0000 +#define CONT_CONSOLE_GCN ( 1 << 3) // 0x0008 + #define CONT_ABSOLUTE 0x0001 #define CONT_RELATIVE 0x0002 #define CONT_JOYPORT 0x0004 @@ -194,9 +199,6 @@ typedef struct { #define CONT_ERR_VOICE_WORD 14 #define CONT_ERR_VOICE_NO_RESPONSE 15 -#define CONT_TYPE_N64 0 -#define CONT_TYPE_GCN 1 - #if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) @@ -213,7 +215,6 @@ typedef struct { * */ -extern u8 __osControllerTypes[MAXCONTROLLERS]; /************************************************************************** * diff --git a/sm64.ld b/sm64.ld index dc6a72a32..5c3e50da9 100755 --- a/sm64.ld +++ b/sm64.ld @@ -182,8 +182,6 @@ SECTIONS lib/PR/audio/n_aspMain.o(.text*); lib/PR/hvqm/hvqm2sp1.o(.text*); _mainSegmentTextEnd = .; - /* Overwrite a libultra function with its modified counterpart for GCN controller support */ - __osContGetInitData = __osContGetInitDataEx; /* data */ BUILD_DIR/asm/n64_assert.o(.*data*); diff --git a/src/game/game_init.c b/src/game/game_init.c index fce976991..9819e7900 100644 --- a/src/game/game_init.c +++ b/src/game/game_init.c @@ -598,7 +598,7 @@ void read_controller_inputs(s32 threadID) { // if we're receiving inputs, update the controller struct with the new button info. if (controller->controllerData != NULL) { // HackerSM64: Swaps Z and L, only on console, and only when playing with a GameCube controller. - if (__osControllerTypes[controller->port] == CONT_TYPE_GCN) { + if (controller->statusData->type & CONT_CONSOLE_GCN) { u32 oldButton = controllerData->button; u32 newButton = oldButton & ~(Z_TRIG | L_TRIG); if (oldButton & Z_TRIG) { @@ -687,15 +687,15 @@ void init_controllers(void) { #if (MAX_NUM_PLAYERS >= 2) //! Some flashcarts (eg. ED64p) don't let you start a ROM with a GameCube controller in port 1, // so if port 1 is an N64 controller and port 2 is a GC controller, swap them. - if (gEmulator & EMU_CONSOLE) { - if ( - (__osControllerTypes[0] == CONT_TYPE_N64) && - (__osControllerTypes[1] == CONT_TYPE_GCN) - ) { - struct Controller temp = gControllers[0]; - gControllers[0] = gControllers[1]; - gControllers[1] = temp; - } + if ( + (gEmulator & EMU_CONSOLE) && + ((gControllerBits & 0b11) == 0b11) && // Only swap if the first two ports both have controllers plugged in. + ((gControllerStatuses[0].type & CONT_CONSOLE_MASK) == CONT_CONSOLE_N64) && // If the first port's controller is N64. + ((gControllerStatuses[1].type & CONT_CONSOLE_MASK) == CONT_CONSOLE_GCN) // If the second port's controller is GCN. + ) { + struct Controller temp = gControllers[0]; + gControllers[0] = gControllers[1]; + gControllers[1] = temp; } #endif diff --git a/src/game/gamecube_controller.c b/src/game/gamecube_controller.c index 32295e61c..05ca0f571 100644 --- a/src/game/gamecube_controller.c +++ b/src/game/gamecube_controller.c @@ -1,5 +1,7 @@ #include "PR/os_internal.h" +#include "game_init.h" + ///////////////////////////////////////////////// // Libultra structs and macros (from ultralib) // ///////////////////////////////////////////////// @@ -168,7 +170,6 @@ typedef struct /* 0xD */ u8 r_trig; } __OSContGCNShortPollFormat; extern u8 __osContLastCmd; -u8 __osControllerTypes[MAXCONTROLLERS]; u8 __osGamecubeRumbleEnabled[MAXCONTROLLERS]; typedef struct @@ -216,7 +217,7 @@ void osContGetReadDataEx(OSContPadEx* data) { int i; for (i = 0; i < __osMaxControllers; i++, data++) { - if (__osControllerTypes[i] == CONT_TYPE_GCN) { + if (gControllerStatuses[i].type & CONT_CONSOLE_GCN) { s32 stick_x, stick_y, c_stick_x, c_stick_y; readformatgcn = *(__OSContGCNShortPollFormat*)ptr; data->errno = CHNL_ERR(readformatgcn); @@ -292,7 +293,7 @@ static void __osPackReadData(void) { readformatgcn.stick_y = -1; for (i = 0; i < __osMaxControllers; i++) { - if (__osControllerTypes[i] == CONT_TYPE_GCN) { + if (gControllerStatuses[i].type & CONT_CONSOLE_GCN) { readformatgcn.rumble = __osGamecubeRumbleEnabled[i]; *(__OSContGCNShortPollFormat*)ptr = readformatgcn; ptr += sizeof(__OSContGCNShortPollFormat); @@ -376,44 +377,12 @@ extern s32 __osContinitialized; extern OSPifRam __osContPifRam; extern u8 __osContLastCmd; extern u8 __osMaxControllers; -extern u8 __osControllerTypes[MAXCONTROLLERS]; extern u8 __osGamecubeRumbleEnabled[MAXCONTROLLERS]; extern OSTimer __osEepromTimer; extern OSMesgQueue __osEepromTimerQ; extern OSMesg __osEepromTimerMsg; -// Linker script will resolve references to the original function with this one instead -void __osContGetInitDataEx(u8* pattern, OSContStatus* data) { - u8* ptr; - __OSContRequesFormat requestHeader; - s32 i; - u8 bits; - - bits = 0; - ptr = (u8*)__osContPifRam.ramarray; - for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(requestHeader), data++) { - requestHeader = *(__OSContRequesFormat*)ptr; - data->error = CHNL_ERR(requestHeader); - if (data->error == 0) { - data->type = requestHeader.typel << 8 | requestHeader.typeh; - - // Check if the input type is a gamecube controller - // Some mupen cores seem to send back a controller type of 0xFFFF if the core doesn't initialize the input plugin quickly enough, - // so check for that and set the input type as N64 controller if so. - if ((data->type & CONT_GCN) && (s16)data->type != -1) { - __osControllerTypes[i] = CONT_TYPE_GCN; - } else { - __osControllerTypes[i] = CONT_TYPE_N64; - } - - data->status = requestHeader.status; - - bits |= 1 << i; - } - } - *pattern = bits; -} ///////////// // motor.c // @@ -432,7 +401,7 @@ s32 __osMotorAccessEx(OSPfs* pfs, s32 flag) { return 5; } - if (__osControllerTypes[pfs->channel] == CONT_TYPE_GCN) { + if (gControllerStatuses[pfs->channel].type & CONT_CONSOLE_GCN) { __osGamecubeRumbleEnabled[pfs->channel] = flag; __osContLastCmd = CONT_CMD_END; } else { @@ -503,7 +472,7 @@ s32 osMotorInitEx(OSMesgQueue *mq, OSPfs *pfs, int channel) pfs->activebank = 0xFF; pfs->status = 0; - if (__osControllerTypes[pfs->channel] != CONT_TYPE_GCN) { + if (gControllerStatuses[pfs->channel].type & CONT_CONSOLE_GCN) { ret = __osPfsSelectBank(pfs, 0xFE); if (ret == PFS_ERR_NEW_PACK) {