Simplify controller type checking + fix controller swapping

This commit is contained in:
Arceveti
2023-09-22 14:47:07 -07:00
parent c890838b24
commit 4397811b92
4 changed files with 21 additions and 53 deletions

View File

@@ -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];
/**************************************************************************
*

View File

@@ -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*);

View File

@@ -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

View File

@@ -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) {