From 6b77ddba5ae0941c10c58260c44270dfcb88e182 Mon Sep 17 00:00:00 2001 From: Tharo <17233964+Thar0@users.noreply.github.com> Date: Sat, 3 Sep 2022 01:52:13 +0100 Subject: [PATCH] More documentation for padmgr.c (#1336) * More documentation for padmgr.c * Update comments * Further suggested changes * Suggested changes * LOG_SEVERITY_INFO -> LOG_SEVERITY_CRITICAL * Adjust PadMgr_RequestPadData comment * Avoid array notation for args, adjust comment, rename the FaultMgr padInput field to inputs to better reflect it's an array --- include/fault.h | 10 +- include/functions.h | 15 -- include/irqmgr.h | 3 + include/padmgr.h | 63 ++++-- include/variables.h | 3 - include/z64.h | 2 +- src/code/code_800EC960.c | 11 +- src/code/db_camera.c | 208 +++++++++--------- src/code/fault.c | 21 +- src/code/game.c | 4 +- src/code/mempak.c | 28 +-- src/code/padmgr.c | 447 ++++++++++++++++++++++++--------------- src/code/padsetup.c | 4 +- 13 files changed, 481 insertions(+), 338 deletions(-) diff --git a/include/fault.h b/include/fault.h index 642d581d80..511d3516fe 100644 --- a/include/fault.h +++ b/include/fault.h @@ -1,6 +1,7 @@ #ifndef FAULT_H #define FAULT_H +#include "ultra64.h" #include "padmgr.h" // These are the same as the 3-bit ansi color codes @@ -69,7 +70,7 @@ void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...); typedef struct FaultMgr { /* 0x000 */ OSThread thread; - /* 0x1B0 */ u8 unk_1B0[0x600]; + /* 0x1B0 */ char unk_1B0[0x600]; // probably an unused internal thread stack for `Fault_ClientRunTask`/`clientThreadSp` /* 0x7B0 */ OSMesgQueue queue; /* 0x7C8 */ OSMesg msg; /* 0x7CC */ u8 exit; @@ -77,12 +78,11 @@ typedef struct FaultMgr { /* 0x7CE */ u8 faultHandlerEnabled; /* 0x7CF */ u8 autoScroll; /* 0x7D0 */ OSThread* faultedThread; - /* 0x7D4 */ void (*padCallback)(Input*); + /* 0x7D4 */ void (*padCallback)(Input* inputs); /* 0x7D8 */ FaultClient* clients; /* 0x7DC */ FaultAddrConvClient* addrConvClients; - /* 0x7E0 */ u8 unk_7E0[4]; - /* 0x7E4 */ Input padInput; - /* 0x7FC */ u16 colors[36]; + /* 0x7E0 */ char unk_7E0[0x4]; + /* 0x7E4 */ Input inputs[MAXCONTROLLERS]; /* 0x844 */ void* fb; /* 0x848 */ void* clientThreadSp; } FaultMgr; // size = 0x850 diff --git a/include/functions.h b/include/functions.h index e7ba5818c2..8df78a215a 100644 --- a/include/functions.h +++ b/include/functions.h @@ -1574,21 +1574,6 @@ void ListAlloc_Free(ListAlloc* this, void* data); void ListAlloc_FreeAll(ListAlloc* this); void Main_LogSystemHeap(void); void Main(void* arg); -OSMesgQueue* PadMgr_LockSerialMesgQueue(PadMgr* padMgr); -void PadMgr_UnlockSerialMesgQueue(PadMgr* padMgr, OSMesgQueue* serialEventQueue); -void PadMgr_LockPadData(PadMgr* padMgr); -void PadMgr_UnlockPadData(PadMgr* padMgr); -void PadMgr_RumbleControl(PadMgr* padMgr); -void PadMgr_RumbleStop(PadMgr* padMgr); -void PadMgr_RumbleReset(PadMgr* padMgr); -void PadMgr_RumbleSet(PadMgr* padMgr, u8* ctrlrRumbles); -void PadMgr_ProcessInputs(PadMgr* padMgr); -void PadMgr_HandleRetraceMsg(PadMgr* padMgr); -void PadMgr_HandlePreNMI(PadMgr* padMgr); -// This function must remain commented out, because it is called incorrectly in -// fault.c (actual bug in game), and the compiler notices and won't compile it -// void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 mode); -void PadMgr_Init(PadMgr* padMgr, OSMesgQueue* serialEventQueue, IrqMgr* irqMgr, OSId id, OSPri priority, void* stack); void SpeedMeter_InitImpl(SpeedMeter* this, u32 arg1, u32 y); void SpeedMeter_Init(SpeedMeter* this); void SpeedMeter_Destroy(SpeedMeter* this); diff --git a/include/irqmgr.h b/include/irqmgr.h index e1b3befbca..69a749a494 100644 --- a/include/irqmgr.h +++ b/include/irqmgr.h @@ -43,4 +43,7 @@ void IrqMgr_Init(IrqMgr* irqMgr, void* stack, OSPri pri, u8 retraceCount); void IrqMgr_AddClient(IrqMgr* irqMgr, IrqMgrClient* client, OSMesgQueue* msgQueue); void IrqMgr_RemoveClient(IrqMgr* irqMgr, IrqMgrClient* client); +extern vu32 gIrqMgrResetStatus; +extern volatile OSTime gIrqMgrRetraceTime; + #endif diff --git a/include/padmgr.h b/include/padmgr.h index 52f6f08ee7..bddb136eb9 100644 --- a/include/padmgr.h +++ b/include/padmgr.h @@ -1,8 +1,15 @@ #ifndef PADMGR_H #define PADMGR_H +#include "ultra64.h" #include "irqmgr.h" +typedef enum { + CONT_PAK_NONE, + CONT_PAK_RUMBLE, + CONT_PAK_OTHER +} ControllerPakType; + typedef struct { /* 0x00 */ OSContPad cur; /* 0x06 */ OSContPad prev; @@ -11,9 +18,9 @@ typedef struct { } Input; // size = 0x18 typedef struct PadMgr { - /* 0x0000 */ OSContStatus padStatus[4]; - /* 0x0010 */ OSMesg serialLockMsgBuf[1]; - /* 0x0014 */ OSMesg lockMsgBuf[1]; + /* 0x0000 */ OSContStatus padStatus[MAXCONTROLLERS]; + /* 0x0010 */ OSMesg serialMsg; + /* 0x0014 */ OSMesg lockMsg; /* 0x0018 */ OSMesg interruptMsgBuf[4]; /* 0x0028 */ OSMesgQueue serialLockQueue; /* 0x0040 */ OSMesgQueue lockQueue; @@ -21,20 +28,46 @@ typedef struct PadMgr { /* 0x0070 */ IrqMgrClient irqClient; /* 0x0078 */ IrqMgr* irqMgr; /* 0x0080 */ OSThread thread; - /* 0x0230 */ Input inputs[4]; - /* 0x0290 */ OSContPad pads[4]; + /* 0x0230 */ Input inputs[MAXCONTROLLERS]; + /* 0x0290 */ OSContPad pads[MAXCONTROLLERS]; /* 0x02A8 */ vu8 validCtrlrsMask; /* 0x02A9 */ u8 nControllers; - /* 0x02AA */ u8 ctrlrIsConnected[4]; // "Key_switch" originally - /* 0x02AE */ u8 pakType[4]; // 1 if rumble pack, 2 if mempak? - /* 0x02B2 */ vu8 rumbleEnable[4]; - /* 0x02B6 */ u8 rumbleCounter[4]; // not clear exact meaning - /* 0x02BC */ OSPfs pfs[4]; - /* 0x045C */ vu8 rumbleOffFrames; - /* 0x045D */ vu8 rumbleOnFrames; - /* 0x045E */ u8 preNMIShutdown; - /* 0x0460 */ void (*retraceCallback)(struct PadMgr* padmgr, s32 unk464); - /* 0x0464 */ u32 retraceCallbackValue; + /* 0x02AA */ u8 ctrlrIsConnected[MAXCONTROLLERS]; + /* 0x02AE */ u8 pakType[MAXCONTROLLERS]; + /* 0x02B2 */ vu8 rumbleEnable[MAXCONTROLLERS]; + /* 0x02B6 */ u8 rumbleTimer[MAXCONTROLLERS]; + /* 0x02BC */ OSPfs rumblePfs[MAXCONTROLLERS]; + /* 0x045C */ vu8 rumbleOffTimer; // amount of VI retraces to not rumble for, takes priority over rumbleOnTimer + /* 0x045D */ vu8 rumbleOnTimer; // amount of VI retraces to rumble for + /* 0x045E */ u8 isResetting; + /* 0x0460 */ void (*retraceCallback)(struct PadMgr* padMgr, s32 arg); + /* 0x0464 */ s32 retraceCallbackValue; } PadMgr; // size = 0x468 +extern PadMgr gPadMgr; + +// Initialization + +void PadMgr_Init(PadMgr* padMgr, OSMesgQueue* serialEventQueue, IrqMgr* irqMgr, OSId id, OSPri priority, void* stack); + +// Fetching inputs + +// This function cannot be prototyped here without AVOID_UB because it is called incorrectly in fault.c (see bug in +// `Fault_PadCallback`) +#ifdef AVOID_UB +void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 gameRequest); +#endif + +// For internal use by Controller Pak systems + +OSMesgQueue* PadMgr_AcquireSerialEventQueue(PadMgr* padMgr); +void PadMgr_ReleaseSerialEventQueue(PadMgr* padMgr, OSMesgQueue* serialEventQueue); + +// Rumble + +void PadMgr_RumbleStop(PadMgr* padMgr); +void PadMgr_RumbleReset(PadMgr* padMgr); +void PadMgr_RumbleSetSingle(PadMgr* padMgr, u32 port, u32 rumble); +void PadMgr_RumbleSet(PadMgr* padMgr, u8* enable); + #endif diff --git a/include/variables.h b/include/variables.h index 79b17f5ce6..a5808eb50c 100644 --- a/include/variables.h +++ b/include/variables.h @@ -110,8 +110,6 @@ extern s32 gScreenHeight; extern Mtx gMtxClear; extern MtxF gMtxFClear; extern u32 gIsCtrlr2Valid; -extern vu32 gIrqMgrResetStatus; -extern volatile OSTime gIrqMgrRetraceTime; extern s16* gWaveSamples[9]; extern f32 gBendPitchOneOctaveFrequencies[256]; extern f32 gBendPitchTwoSemitonesFrequencies[256]; @@ -193,7 +191,6 @@ extern s32 gTrnsnUnkState; extern Color_RGBA8_u32 D_801614B0; extern PreNmiBuff* gAppNmiBufferPtr; extern Scheduler gScheduler; -extern PadMgr gPadMgr; extern u32 gSegments[NUM_SEGMENTS]; extern volatile OSTime D_8016A520; extern volatile OSTime D_8016A528; diff --git a/include/z64.h b/include/z64.h index 6fb89528a9..7128cd1b2a 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1060,7 +1060,7 @@ typedef struct GameState { /* 0x08 */ GameStateFunc destroy; // "cleanup" /* 0x0C */ GameStateFunc init; /* 0x10 */ u32 size; - /* 0x14 */ Input input[4]; + /* 0x14 */ Input input[MAXCONTROLLERS]; /* 0x74 */ TwoHeadArena tha; /* 0x84 */ GameAlloc alloc; /* 0x98 */ u32 running; diff --git a/src/code/code_800EC960.c b/src/code/code_800EC960.c index fc05e71ad6..98e3a03560 100644 --- a/src/code/code_800EC960.c +++ b/src/code/code_800EC960.c @@ -1267,7 +1267,8 @@ OcarinaNote sScarecrowsLongSongSecondNote; u8 sAudioHasMalonBgm; f32 sAudioMalonBgmDist; -void PadMgr_RequestPadData(PadMgr* padmgr, Input* inputs, s32 mode); +void PadMgr_RequestPadData(PadMgr* padMgr, Input* inputs, s32 gameRequest); + void Audio_StepFreqLerp(FreqLerp* lerp); void func_800F56A8(void); void Audio_PlayNatureAmbienceSequence(u8 natureAmbienceId); @@ -1292,11 +1293,11 @@ void AudioOcarina_SetCustomButtonMapping(u8 useCustom) { } void AudioOcarina_ReadControllerInput(void) { - Input inputs[4]; + Input inputs[MAXCONTROLLERS]; Input* input = &inputs[0]; u32 ocarinaInputButtonPrev = sOcarinaInputButtonCur; - PadMgr_RequestPadData(&gPadMgr, inputs, 0); + PadMgr_RequestPadData(&gPadMgr, inputs, false); sOcarinaInputButtonCur = input->cur.button; sOcarinaInputButtonPrev = ocarinaInputButtonPrev; sOcarinaInputStickAdj.x = input->rel.stick_x; @@ -2371,10 +2372,10 @@ u8 sAudioNatureFailed = false; u8 sPeakNumNotes = 0; void AudioDebug_SetInput(void) { - Input inputs[4]; + Input inputs[MAXCONTROLLERS]; u32 btn; - PadMgr_RequestPadData(&gPadMgr, inputs, 0); + PadMgr_RequestPadData(&gPadMgr, inputs, false); btn = inputs[3].cur.button; sDebugPadHold = btn & 0xFFFF; sDebugPadPress = (btn ^ sDebugPadBtnLast) & btn; diff --git a/src/code/db_camera.c b/src/code/db_camera.c index 3cb5ffa12e..a514f92dea 100644 --- a/src/code/db_camera.c +++ b/src/code/db_camera.c @@ -1,6 +1,8 @@ #include "ultra64.h" #include "global.h" +#define DBCAM_CONTROLLER_PORT 2 + static PlayState* sPlay; // TODO: cleanup these arrays and UB access @@ -346,7 +348,7 @@ s32 func_800B4370(DbCamera* dbCamera, s16 idx, Camera* cam) { void func_800B44E0(DbCamera* dbCamera, Camera* cam) { s32 i; - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CRIGHT)) { sDbCamAnim.keyframe = 0; sDbCamAnim.unk_0A = 1; sDbCamAnim.curFrame = 0.0f; @@ -597,7 +599,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { sp80 = &dbCamera->eye; sp7C = &dbCamera->at; - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_Z)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_Z)) { dbCamera->unk_00++; dbCamera->unk_00 %= 3; dbCamera->unk_38 = 1; @@ -688,7 +690,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } dbCamera->unk_3C = D_80161140; - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_B | BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_B | BTN_L)) { sp104.r += temp_f2; if (sp104.r > 30000.0f) { @@ -702,7 +704,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } dbCamera->unk_40 = 7; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_B)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_B)) { spFC = sp104; spFC.r = temp_f2; if (!D_80161144) { @@ -719,7 +721,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 0xB; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_A | BTN_L)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_A | BTN_L)) { sp104.r -= temp_f2; if (sp104.r < 10.0f) { sp104.r = 10.0f; @@ -730,7 +732,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 8; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_A)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_A)) { spFC = sp104; spFC.r = -temp_f2; if (!D_80161144) { @@ -752,7 +754,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_40 = -1; } - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DDOWN | BTN_L)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DDOWN | BTN_L)) { spFC = sp104; spFC.r = temp_f2; spFC.pitch = 0; @@ -770,7 +772,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 1; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DUP | BTN_L)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DUP | BTN_L)) { spFC = sp104; spFC.r = -temp_f2; spFC.pitch = 0; @@ -787,7 +789,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 2; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DUP)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DUP)) { spFC = sp104; spFC.r = temp_f2; spFC.pitch = 0x3FFF; @@ -803,7 +805,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 3; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DDOWN)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DDOWN)) { spFC = sp104; spFC.r = temp_f2; spFC.pitch = -0x3FFF; @@ -819,8 +821,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 4; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, (BTN_DRIGHT | BTN_L)) || - CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DRIGHT)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, (BTN_DRIGHT | BTN_L)) || + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DRIGHT)) { spFC = sp104; spFC.r = temp_f2; spFC.pitch = 0; @@ -837,8 +839,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 5; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, (BTN_DLEFT | BTN_L)) || - CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DLEFT)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, (BTN_DLEFT | BTN_L)) || + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DLEFT)) { spFC = sp104; spFC.r = temp_f2; spFC.pitch = 0; @@ -855,7 +857,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 6; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_B | BTN_L)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_B | BTN_L)) { sp104.r = sp104.r + temp_f2; if (sp104.r > 30000.0f) { sp104.r = 30000.0f; @@ -866,7 +868,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 7; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_B)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_B)) { spFC = sp104; spFC.r = temp_f2; if (!D_80161144) { @@ -883,7 +885,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 0xB; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_A | BTN_L)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_A | BTN_L)) { sp104.r -= temp_f2; if (sp104.r < 10.0f) { @@ -895,7 +897,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_44 = 0; } dbCamera->unk_40 = 8; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_A)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_A)) { spFC = sp104; spFC.r = -temp_f2; if (!D_80161144) { @@ -917,7 +919,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->unk_40 = -1; } - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_R)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_R)) { if (dbCamera->unk_00 == 0) { dbCamera->sub.unk_104A = cam->inputDir; *sp7C = cam->at; @@ -932,13 +934,13 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { func_800B41DC(dbCamera, dbCamera->sub.unkIdx, cam); } else { - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_R) && - CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_R) && + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { Audio_PlaySfxGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.nPoints = dbCamera->sub.unkIdx + 1; func_800B4088(dbCamera, cam); - } else if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_R)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_R)) { if (dbCamera->sub.unkIdx == 0x80) { Audio_PlaySfxGeneral(NA_SE_SY_ERROR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -955,8 +957,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } } else { - temp_f0_5 = sPlay->state.input[2].rel.stick_y; - temp_f2_2 = sPlay->state.input[2].rel.stick_x; + temp_f0_5 = sPlay->state.input[DBCAM_CONTROLLER_PORT].rel.stick_y; + temp_f2_2 = sPlay->state.input[DBCAM_CONTROLLER_PORT].rel.stick_x; pitch = CAM_DEG_TO_BINANG((SQ(temp_f0_5) / 600.0f) * 0.8f); yaw = CAM_DEG_TO_BINANG((SQ(temp_f2_2) / 600.0f) * 0.8f); if (!D_80161144) { @@ -977,7 +979,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { DbCamera_CalcUpFromPitchYawRoll(&dbCamera->unk_1C, spF4.pitch, spF4.yaw, CAM_DEG_TO_BINANG(dbCamera->rollDegrees)); if (dbCamera->unk_00 == 1) { - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_CRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_CRIGHT)) { cam->inputDir = dbCamera->sub.unk_104A; new_var2 = OLib_Vec3fDist(&cam->at, &cam->eye); cam->at = *sp7C; @@ -991,12 +993,12 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { if (dbCamera->unk_00 == 1) { OREG(0) = 8; func_8006376C(0xC, 5, 0, D_8012CEF4); - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_CRIGHT) && - !CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_CRIGHT) && + !CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { func_800B44E0(dbCamera, cam); } else { - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CRIGHT) && - CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CRIGHT) && + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { Audio_PlaySfxGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); osSyncPrintf("@@@\n@@@\n@@@/* *** spline point data ** start here *** */\n@@@\n"); @@ -1006,14 +1008,14 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { osSyncPrintf("@@@static short nFrames = %d;\n@@@\n", dbCamera->sub.nFrames); osSyncPrintf("@@@static short Mode = %d;\n@@@\n", dbCamera->sub.mode); osSyncPrintf("@@@\n@@@\n@@@/* *** spline point data ** finish! *** */\n@@@\n"); - } else if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CLEFT)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CLEFT)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.unk_08 = (dbCamera->sub.unk_08 + 1) % 3; } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CUP) && - CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CUP) && + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { Audio_PlaySfxGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unkIdx > 0) { @@ -1022,7 +1024,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->sub.unkIdx = dbCamera->sub.nPoints - 1; } } else { - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CUP)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CUP)) { Audio_PlaySfxGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unkIdx > 0) { @@ -1043,8 +1045,8 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } } - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L) && - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CDOWN)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L) && + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CDOWN)) { Audio_PlaySfxGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unkIdx < (dbCamera->sub.nPoints - 1)) { @@ -1053,7 +1055,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->sub.unkIdx = 0; } } else { - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CDOWN)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CDOWN)) { Audio_PlaySfxGeneral(NA_SE_IT_SWORD_IMPACT, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unkIdx < (dbCamera->sub.nPoints - 1)) { @@ -1123,7 +1125,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { break; case 1: dbCamera->unk_3C = true; - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DUP)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DUP)) { Audio_PlaySfxGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unk_0A == 0) { @@ -1132,7 +1134,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->sub.unk_0A--; } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DDOWN)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DDOWN)) { Audio_PlaySfxGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.unk_0A == 5) { @@ -1141,12 +1143,12 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->sub.unk_0A++; } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DLEFT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DLEFT)) { Audio_PlaySfxGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); switch (dbCamera->sub.unk_0A) { case 1: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].nextPointFrame -= 5; } else { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].nextPointFrame--; @@ -1178,7 +1180,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->sub.unk_0C = false; break; case 2: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].cameraRoll -= 5; dbCamera->roll = dbCamera->sub.lookAt[dbCamera->sub.unkIdx].cameraRoll; } else { @@ -1190,7 +1192,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DLEFT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DLEFT)) { if ((D_8012D10C++ % 5) == 0) { Audio_PlaySfxGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -1198,7 +1200,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { switch (dbCamera->sub.unk_0A) { case 0: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].viewAngle -= 1.0f; dbCamera->fov = dbCamera->sub.lookAt[dbCamera->sub.unkIdx].viewAngle; } else { @@ -1207,7 +1209,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } break; case 5: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.nFrames -= 10; } else { dbCamera->sub.nFrames--; @@ -1229,13 +1231,13 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DRIGHT)) { Audio_PlaySfxGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); switch (dbCamera->sub.unk_0A) { case 1: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].nextPointFrame += 5; } else { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].nextPointFrame++; @@ -1267,7 +1269,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->sub.unk_0C = true; break; case 2: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].cameraRoll += 5; dbCamera->roll = dbCamera->sub.lookAt[dbCamera->sub.unkIdx].cameraRoll; } else { @@ -1278,7 +1280,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { break; } } - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_DRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_DRIGHT)) { if ((D_8012D10C++ % 5) == 0) { Audio_PlaySfxGeneral(NA_SE_SY_ATTENTION_ON, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -1286,7 +1288,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { switch (dbCamera->sub.unk_0A) { case 0: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.lookAt[dbCamera->sub.unkIdx].viewAngle += 1.0f; dbCamera->fov = dbCamera->sub.lookAt[dbCamera->sub.unkIdx].viewAngle; } else { @@ -1295,7 +1297,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { } break; case 5: - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { dbCamera->sub.nFrames += 10; } else { dbCamera->sub.nFrames++; @@ -1432,7 +1434,7 @@ void DbCamera_Update(DbCamera* dbCamera, Camera* cam) { dbCamera->roll = 0; dbCamera->fov = 60.0f; dbCamera->rollDegrees = dbCamera->roll * 1.40625f; - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CLEFT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CLEFT)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->unk_78 = (dbCamera->unk_78 + 1) % 3; @@ -1603,7 +1605,7 @@ s32 DbCamera_LoadCallback(char* c) { } } - if (!Mempak_Read(2, *c, sDbCameraCuts, 0, sizeof(sDbCameraCuts))) { + if (!Mempak_Read(DBCAM_CONTROLLER_PORT, *c, sDbCameraCuts, 0, sizeof(sDbCameraCuts))) { return false; } @@ -1618,7 +1620,7 @@ s32 DbCamera_LoadCallback(char* c) { osSyncPrintf("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2847); return false; } - if (!Mempak_Read(2, *c, sDbCameraCuts[i].lookAt, off, ALIGN32(size))) { + if (!Mempak_Read(DBCAM_CONTROLLER_PORT, *c, sDbCameraCuts[i].lookAt, off, ALIGN32(size))) { return false; } off += ALIGN32(size); @@ -1629,7 +1631,7 @@ s32 DbCamera_LoadCallback(char* c) { osSyncPrintf("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2858); return false; } - if (!Mempak_Read(2, *c, sDbCameraCuts[i].position, off, ALIGN32(size))) { + if (!Mempak_Read(DBCAM_CONTROLLER_PORT, *c, sDbCameraCuts[i].position, off, ALIGN32(size))) { return false; } off += ALIGN32(size); @@ -1649,16 +1651,16 @@ s32 DbCamera_SaveCallback(char* c) { s32 size; s32 i; - ret = Mempak_GetFileSize(2, *c); - freeSize = Mempak_GetFreeBytes(2); + ret = Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, *c); + freeSize = Mempak_GetFreeBytes(DBCAM_CONTROLLER_PORT); if ((u32)sAllocSize < (freeSize + ret)) { - if (!Mempak_Alloc(2, c, sAllocSize)) { + if (!Mempak_Alloc(DBCAM_CONTROLLER_PORT, c, sAllocSize)) { return false; } - if (!Mempak_Write(2, *c, sDbCameraCuts, 0, sizeof(sDbCameraCuts))) { - Mempak_DeleteFile(2, *c); + if (!Mempak_Write(DBCAM_CONTROLLER_PORT, *c, sDbCameraCuts, 0, sizeof(sDbCameraCuts))) { + Mempak_DeleteFile(DBCAM_CONTROLLER_PORT, *c); return false; } @@ -1667,13 +1669,13 @@ s32 DbCamera_SaveCallback(char* c) { if (sDbCameraCuts[i].letter != '?') { size = sDbCameraCuts[i].nPoints * sizeof(CutsceneCameraPoint); - ret = Mempak_Write(2, *c, sDbCameraCuts[i].lookAt, off, ALIGN32(size)); + ret = Mempak_Write(DBCAM_CONTROLLER_PORT, *c, sDbCameraCuts[i].lookAt, off, ALIGN32(size)); if (!ret) { break; } off += ALIGN32(size); - ret = Mempak_Write(2, *c, sDbCameraCuts[i].position, off, ALIGN32(size)); + ret = Mempak_Write(DBCAM_CONTROLLER_PORT, *c, sDbCameraCuts[i].position, off, ALIGN32(size)); if (!ret) { break; } @@ -1686,7 +1688,7 @@ s32 DbCamera_SaveCallback(char* c) { if (ret) { return *c; } else { - Mempak_DeleteFile(2, *c); + Mempak_DeleteFile(DBCAM_CONTROLLER_PORT, *c); return false; } } @@ -1695,7 +1697,7 @@ s32 DbCamera_SaveCallback(char* c) { } s32 DbCamera_ClearCallback(char* c) { - return Mempak_DeleteFile(2, *c); + return Mempak_DeleteFile(DBCAM_CONTROLLER_PORT, *c); } void DbCamera_DrawSlotLetters(char* str, s16 y, s16 x, s32 colorIndex) { @@ -1861,8 +1863,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { case DEMO_CTRL_MENU(ACTION_LOAD, MENU_INFO): case DEMO_CTRL_MENU(ACTION_CLEAR, MENU_INFO): { if ((1 << sCurFileIdx) & sMempakFiles) { - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DLEFT) || - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DLEFT) || + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DRIGHT)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlToggleSwitch ^= 1; @@ -1875,7 +1877,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { func_8006376C(0x11, 8, dbCamera->sub.demoCtrlToggleSwitch ? 4 : 7, D_8012CF94); func_8006376C(0x15, 8, dbCamera->sub.demoCtrlToggleSwitch ? 7 : 4, D_8012CF98); - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_A)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_A)) { if (dbCamera->sub.demoCtrlToggleSwitch == 0) { Audio_PlaySfxGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -1897,7 +1899,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { func_8006376C(0xD, 9, dbCamera->sub.demoCtrlToggleSwitch ? 1 : 6, "PRESS B BUTTON"); } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_B)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_B)) { Audio_PlaySfxGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu = 0; @@ -1933,8 +1935,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { func_8006376C(0x17, 7, 5, D_8012CFA4); func_8006376C(0xD, 9, (dbCamera->sub.demoCtrlToggleSwitch != 0) ? 1 : 6, "PRESS B BUTTON"); - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_A) || - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_B)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_A) || + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_B)) { Audio_PlaySfxGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (dbCamera->sub.demoCtrlMenu == DEMO_CTRL_MENU(ACTION_LOAD, MENU_SUCCESS)) { @@ -1956,8 +1958,8 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { func_8006376C(0x17, 7, 5, D_8012CFA4); func_8006376C(0xD, 9, (dbCamera->sub.demoCtrlToggleSwitch != 0) ? 1 : 6, "PRESS B BUTTON"); - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_A) || - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_B)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_A) || + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_B)) { Audio_PlaySfxGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu -= 9; @@ -1970,12 +1972,12 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { goto block_1; default: { - if (Mempak_Init(2)) { - sMempakFiles = Mempak_FindFile(2, 'A', 'E'); + if (Mempak_Init(DBCAM_CONTROLLER_PORT)) { + sMempakFiles = Mempak_FindFile(DBCAM_CONTROLLER_PORT, 'A', 'E'); dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_CALLBACK); DbCamera_CalcMempakAllocSize(); if ((1 << sCurFileIdx) & sMempakFiles) { - sMempakFilesize = Mempak_GetFileSize(2, sCurFileIdx + 'A'); + sMempakFilesize = Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, sCurFileIdx + 'A'); dbCamera->sub.demoCtrlActionIdx = ACTION_LOAD; } else { sMempakFilesize = 0; @@ -1992,7 +1994,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { sp74[i * 2 + 0] = '-'; sp74[i * 2 + 1] = '\0'; - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DRIGHT)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (sCurFileIdx >= 4) { @@ -2002,14 +2004,14 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } if ((1 << sCurFileIdx) & sMempakFiles) { - sMempakFilesize = Mempak_GetFileSize(2, sCurFileIdx + 'A'); + sMempakFilesize = Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, sCurFileIdx + 'A'); dbCamera->sub.demoCtrlActionIdx = ACTION_LOAD; } else { sMempakFilesize = 0; dbCamera->sub.demoCtrlActionIdx = ACTION_SAVE; } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DLEFT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DLEFT)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (sCurFileIdx <= 0) { @@ -2019,7 +2021,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } if ((1 << sCurFileIdx) & sMempakFiles) { - sMempakFilesize = Mempak_GetFileSize(2, sCurFileIdx + 'A'); + sMempakFilesize = Mempak_GetFileSize(DBCAM_CONTROLLER_PORT, sCurFileIdx + 'A'); dbCamera->sub.demoCtrlActionIdx = ACTION_LOAD; } else { sMempakFilesize = 0; @@ -2034,7 +2036,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { DbCamera_SetTextValue(DbCamera_GetMempakAllocSize(), sp74, 6); func_8006376C(0xD, 9, 6, D_8012CF78); // NEED BYTE func_8006376C(0x11, 9, 4, sp74); - DbCamera_SetTextValue(Mempak_GetFreeBytes(2), sp74, 6); + DbCamera_SetTextValue(Mempak_GetFreeBytes(DBCAM_CONTROLLER_PORT), sp74, 6); func_8006376C(0xD, 0xA, 6, D_8012CF74); // FREE BYTE func_8006376C(0x11, 0xA, 4, sp74); if (sMempakFilesize != 0) { @@ -2052,24 +2054,24 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { func_8006376C(0xD, 0x1A, 5, D_8012CF60[0]); func_8006376C(0x14, 0x1A, 5, D_8012CF70); - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DUP)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DUP)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx - 1) % 4u; } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DDOWN)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DDOWN)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx + 1) % 4u; } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_A)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_A)) { Audio_PlaySfxGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlToggleSwitch = 0; dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(dbCamera->sub.demoCtrlActionIdx, MENU_INFO); } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_B)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_B)) { Audio_PlaySfxGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlActionIdx = ACTION_E; @@ -2079,9 +2081,9 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } else { func_8006376C(0xC, 0x1A, 4, D_8012CF60[0]); func_8006376C(0x13, 0x1A, 4, D_8012CF80); - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_B) || - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DUP) || - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DDOWN)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_B) || + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DUP) || + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DDOWN)) { Audio_PlaySfxGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -2095,14 +2097,14 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { break; default: { - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DUP)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DUP)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_INFO); dbCamera->sub.demoCtrlActionIdx = (dbCamera->sub.demoCtrlActionIdx - 1) % 4u; sCurFileIdx = 0; } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DDOWN)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DDOWN)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); dbCamera->sub.demoCtrlMenu = DEMO_CTRL_MENU(ACTION_E, MENU_INFO); @@ -2116,7 +2118,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { func_8006376C(4, 7, 5, D_8012CF4C); func_8006376C(D_8016110C * 2 + 6, 7, 7, ">"); - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CUP)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CUP)) { if (D_8016110C > 0) { D_8016110C--; } @@ -2124,7 +2126,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { sDbCamAnim.curFrame = 0.0f; sDbCamAnim.keyframe = 0; sDbCamAnim.unk_04 = 0; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CDOWN)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CDOWN)) { if (D_8016110C < 14) { D_8016110C++; } @@ -2132,7 +2134,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { sDbCamAnim.curFrame = 0.0f; sDbCamAnim.keyframe = 0; sDbCamAnim.unk_04 = 0; - } else if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CLEFT)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CLEFT)) { sDbCamAnim.unk_0A = 0; Interface_ChangeAlpha(2); Letterbox_SetSizeTarget(0); @@ -2166,7 +2168,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_L)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_L)) { if (sp74[sCurFileIdx] == '?') { sLastFileIdx = -1; D_801612EA = '*'; @@ -2175,7 +2177,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { D_801612EA = sDbCameraCuts[idx1].letter; } if (1) {} - } else if (!CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L)) { + } else if (!CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L)) { if (sLastFileIdx != -1) { switch (sp74[sCurFileIdx]) { case '?': @@ -2217,7 +2219,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { sLastFileIdx = -1; } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_A)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_A)) { if (sp74[sCurFileIdx] == '?') { Audio_PlaySfxGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -2228,7 +2230,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_B)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_B)) { if (sp74[sCurFileIdx] != '?' && sp74[sCurFileIdx] != '-') { Audio_PlaySfxGeneral(NA_SE_SY_CANCEL, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -2237,7 +2239,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_R)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_R)) { if (sp74[sCurFileIdx] != '?' && sp74[sCurFileIdx] != '-') { Audio_PlaySfxGeneral(NA_SE_SY_DECIDE, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -2261,7 +2263,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DRIGHT)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); if (sCurFileIdx == 0x1E) { @@ -2270,22 +2272,22 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { sCurFileIdx++; } } - if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_DLEFT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_DLEFT)) { Audio_PlaySfxGeneral(NA_SE_SY_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); sCurFileIdx = (sCurFileIdx == 0) ? 0x1E : sCurFileIdx - 1; } - if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L) && - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CRIGHT)) { + if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L) && + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CRIGHT)) { for (i = 0; i < ARRAY_COUNT(sDbCameraCuts) - 1; i++) { osSyncPrintf("###%2d:(%c) (%d %d) %d %d %d\n", i, sDbCameraCuts[i].letter, sDbCameraCuts[i].position, sDbCameraCuts[i].lookAt, sDbCameraCuts[i].nFrames, sDbCameraCuts[i].nPoints, sDbCameraCuts[i].mode); } DbCamera_PrintAllCuts(cam); - } else if (CHECK_BTN_ALL(sPlay->state.input[2].cur.button, BTN_L) && - CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CLEFT)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].cur.button, BTN_L) && + CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CLEFT)) { Audio_PlaySfxGeneral(NA_SE_SY_GET_RUPY, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); for (i = 0; i < ARRAY_COUNT(sDbCameraCuts) - 1; i++) { @@ -2294,7 +2296,7 @@ s32 DbCamera_UpdateDemoControl(DbCamera* dbCamera, Camera* cam) { DbCamera_PrintCutBytes(&sDbCameraCuts[i]); } } - } else if (CHECK_BTN_ALL(sPlay->state.input[2].press.button, BTN_CRIGHT)) { + } else if (CHECK_BTN_ALL(sPlay->state.input[DBCAM_CONTROLLER_PORT].press.button, BTN_CRIGHT)) { sDbCamAnim.curFrame = 0.0f; sDbCamAnim.keyframe = 0; sDbCamAnim.unk_04 = 0.0f; diff --git a/src/code/fault.c b/src/code/fault.c index 6edb90b555..c2cfe16315 100644 --- a/src/code/fault.c +++ b/src/code/fault.c @@ -352,18 +352,25 @@ void Fault_Sleep(u32 msec) { Fault_SleepImpl(msec); } -void PadMgr_RequestPadData(Input* input, s32 mode); +#ifndef AVOID_UB +void PadMgr_RequestPadData(Input* inputs, s32 gameRequest); +#endif -void Fault_PadCallback(Input* input) { +void Fault_PadCallback(Input* inputs) { //! @bug This function is not called correctly, it is missing a leading PadMgr* argument. This //! renders the crash screen unusable. //! In Majora's Mask, PadMgr functions were changed to not require this argument, and this was //! likely just not addressed when backporting. - PadMgr_RequestPadData(input, 0); +#ifndef AVOID_UB + PadMgr_RequestPadData(inputs, false); +#else + // Guarantee crashing behavior: false -> NULL, previous value in a2 is more often non-zero than zero + PadMgr_RequestPadData((PadMgr*)inputs, NULL, true); +#endif } void Fault_UpdatePadImpl(void) { - sFaultInstance->padCallback(&sFaultInstance->padInput); + sFaultInstance->padCallback(sFaultInstance->inputs); } /** @@ -376,7 +383,7 @@ void Fault_UpdatePadImpl(void) { * DPad-Left continues and returns false */ u32 Fault_WaitForInputImpl(void) { - Input* input = &sFaultInstance->padInput; + Input* input = &sFaultInstance->inputs[0]; s32 count = 600; u32 pressedBtn; @@ -651,7 +658,7 @@ void Fault_Wait5Seconds(void) { * (L & R & Z) + DPad-Up + C-Down + C-Up + DPad-Down + DPad-Left + C-Left + C-Right + DPad-Right + (B & A & START) */ void Fault_WaitForButtonCombo(void) { - Input* input = &sFaultInstance->padInput; + Input* input = &sFaultInstance->inputs[0]; s32 state; u32 s1; u32 s2; @@ -853,7 +860,7 @@ void Fault_DrawMemDumpContents(const char* title, uintptr_t addr, u32 arg2) { * @param cRightJump Unused parameter, pressing C-Right jumps to this address */ void Fault_DrawMemDump(uintptr_t pc, uintptr_t sp, uintptr_t cLeftJump, uintptr_t cRightJump) { - Input* input = &sFaultInstance->padInput; + Input* input = &sFaultInstance->inputs[0]; uintptr_t addr = pc; s32 scrollCountdown; u32 off; diff --git a/src/code/game.c b/src/code/game.c index 053c836ff0..4d49db966b 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -227,10 +227,10 @@ void func_800C49F4(GraphicsContext* gfxCtx) { CLOSE_DISPS(gfxCtx, "../game.c", 865); } -void PadMgr_RequestPadData(PadMgr*, Input*, s32); +void PadMgr_RequestPadData(PadMgr* padMgr, Input* inputs, s32 gameRequest); void GameState_ReqPadData(GameState* gameState) { - PadMgr_RequestPadData(&gPadMgr, &gameState->input[0], 1); + PadMgr_RequestPadData(&gPadMgr, gameState->input, true); } void GameState_Update(GameState* gameState) { diff --git a/src/code/mempak.c b/src/code/mempak.c index e423c6666d..2ccf151351 100644 --- a/src/code/mempak.c +++ b/src/code/mempak.c @@ -17,14 +17,14 @@ s32 Mempak_Init(s32 controllerNb) { s32 pad; s32 ret = false; - mq = PadMgr_LockSerialMesgQueue(&gPadMgr); + mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); if (!osPfsInitPak(mq, &sMempakPfsHandle, controllerNb)) { ret = true; } osPfsFreeBlocks(&sMempakPfsHandle, &sMempakFreeBytes); - PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); return ret; } @@ -40,7 +40,7 @@ s32 Mempak_FindFile(s32 controllerNb, char start, char end) { u32 bit = 1; s32 flag = 0; - mq = PadMgr_LockSerialMesgQueue(&gPadMgr); + mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); for (idx = start; idx <= end; idx++) { sMempakExtName[0] = idx - 0x27; @@ -57,7 +57,7 @@ s32 Mempak_FindFile(s32 controllerNb, char start, char end) { osSyncPrintf("mempak: find '%c' (%d)\n", idx, error); } - PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); osSyncPrintf("mempak: find '%c' - '%c' %02x\n", start, end, flag); return flag; @@ -69,7 +69,7 @@ s32 Mempak_Write(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size) s32 ret = false; s32 pad; - mq = PadMgr_LockSerialMesgQueue(&gPadMgr); + mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); if (size < sMempakFreeBytes) { error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[idx - 'A'], 1, offset, size, buffer); @@ -78,7 +78,7 @@ s32 Mempak_Write(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size) } osSyncPrintf("mempak: write %d byte '%c' (%d)->%d\n", size, idx, sMempakFiles[idx - 'A'], error); } - PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); return ret; } @@ -89,7 +89,7 @@ s32 Mempak_Read(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size) s32 ret = false; s32 pad; - mq = PadMgr_LockSerialMesgQueue(&gPadMgr); + mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); if (size < sMempakFreeBytes) { error = osPfsReadWriteFile(&sMempakPfsHandle, sMempakFiles[idx - 'A'], 0, offset, size, buffer); @@ -98,7 +98,7 @@ s32 Mempak_Read(s32 controllerNb, char idx, void* buffer, s32 offset, s32 size) } osSyncPrintf("mempak: read %d byte '%c' (%d)<-%d\n", size, idx, sMempakFiles[idx - 'A'], error); } - PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); return ret; } @@ -109,7 +109,7 @@ s32 Mempak_Alloc(s32 controllerNb, char* idx, s32 size) { s32 i; s32 pad; - mq = PadMgr_LockSerialMesgQueue(&gPadMgr); + mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); if (*idx >= 'A' && *idx < 'L') { sMempakExtName[0] = *idx - 0x27; @@ -149,7 +149,7 @@ s32 Mempak_Alloc(s32 controllerNb, char* idx, s32 size) { ret = 1; } } - PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); return ret; } @@ -159,7 +159,7 @@ s32 Mempak_DeleteFile(s32 controllerNb, char idx) { s32 error; s32 ret = false; - mq = PadMgr_LockSerialMesgQueue(&gPadMgr); + mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); sMempakExtName[0] = idx - 0x27; error = osPfsDeleteFile(&sMempakPfsHandle, sMempakCompanyCode, sMempakGameCode, sMempakGameName, sMempakExtName); @@ -167,18 +167,18 @@ s32 Mempak_DeleteFile(s32 controllerNb, char idx) { ret = true; } osSyncPrintf("mempak: delete '%c' (%d)\n", idx, error); - PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); return ret; } s32 Mempak_GetFileSize(s32 controllerNb, char idx) { - OSMesgQueue* mq = PadMgr_LockSerialMesgQueue(&gPadMgr); + OSMesgQueue* mq = PadMgr_AcquireSerialEventQueue(&gPadMgr); OSPfsState state; s32 error = osPfsFileState(&sMempakPfsHandle, sMempakFiles[idx - 'A'], &state); s32 pad; - PadMgr_UnlockSerialMesgQueue(&gPadMgr, mq); + PadMgr_ReleaseSerialEventQueue(&gPadMgr, mq); if (error != 0) { return 0; diff --git a/src/code/padmgr.c b/src/code/padmgr.c index 160a5301f9..b8830d5a20 100644 --- a/src/code/padmgr.c +++ b/src/code/padmgr.c @@ -1,12 +1,74 @@ +/** + * @file padmgr.c + * + * This file implements communicating with joybus devices at a high level and serving the results to other threads. + * + * Any device that can be plugged into one of the four controller ports such as a standard N64 controller is a joybus + * device. Some joybus devices are also located inside the cartridge such as EEPROM for save data or the Real-Time + * Clock, however neither of these are used in Zelda64 and so this type of communication is unimplemented. Of the + * possible devices that can be plugged into the controller ports, the only device that padmgr will recognize and + * attempt to communicate with is the standard N64 controller. + * + * Communicating with these devices is broken down into various layers: + * + * Other threads : The rest of the program that will use the polled data + * | + * PadMgr : Manages devices, submits polling commands at vertical retrace + * | + * Libultra osCont* routines : Interface for building commands and safely using the Serial Interface + * | + * Serial Interface : Hardware unit for sending joybus commands and receiving data via DMA + * | + * PIF : Forwards joybus commands and receives response data from the devices + * |---¬---¬---¬-------¬ + * 1 2 3 4 5 : The joybus devices plugged into the four controller ports or on the cartridge + * + * Joybus communication is handled on another thread as polling and receiving controller data is a slow process; the + * N64 programming manual section 26.2.4.1 quotes 2 milliseconds as the expected delay from calling + * `osContStartReadData` to receiving the data. By running this on a separate thread to the game state, work can be + * done while waiting for this operation to complete. + */ #include "global.h" #include "vt.h" -s32 D_8012D280 = 1; +#define PADMGR_LOG(controllerNo, msg) \ + if (1) { \ + osSyncPrintf(VT_FGCOL(YELLOW)); \ + /* padmgr: Controller %d: %s */ \ + osSyncPrintf("padmgr: %dコン: %s\n", (controllerNo) + 1, (msg)); \ + osSyncPrintf(VT_RST); \ + } \ + (void)0 -OSMesgQueue* PadMgr_LockSerialMesgQueue(PadMgr* padMgr) { +#define LOG_SEVERITY_NOLOG 0 +#define LOG_SEVERITY_CRITICAL 1 +#define LOG_SEVERITY_ERROR 2 +#define LOG_SEVERITY_VERBOSE 3 + +s32 gPadMgrLogSeverity = LOG_SEVERITY_CRITICAL; + +/** + * Acquires exclusive access to the serial event queue. + * + * When a DMA to/from PIF RAM completes, an SI interrupt is generated to notify the process that the DMA has completed + * and a message is posted to the serial event queue. If multiple processes are trying to use the SI at the same time + * it becomes ambiguous as to which DMA has completed, so a locking system is required to arbitrate access to the SI. + * + * Once the task requiring the serial event queue is complete, it should be released with a call to + * `PadMgr_ReleaseSerialEventQueue()`. + * + * If another process tries to acquire the event queue, the current thread will be blocked until the event queue is + * released. Note the possibility for a deadlock, if the thread that already holds the serial event queue attempts to + * acquire it again it will block forever. + * + * @return The message queue to which SI interrupt events are posted. + * + * @see PadMgr_ReleaseSerialEventQueue + */ +OSMesgQueue* PadMgr_AcquireSerialEventQueue(PadMgr* padMgr) { OSMesgQueue* serialEventQueue = NULL; - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Waiting for lock" osSyncPrintf("%2d %d serialMsgQロック待ち %08x %08x %08x\n", osGetThreadId(NULL), MQ_GET_COUNT(&padMgr->serialLockQueue), padMgr, &padMgr->serialLockQueue, &serialEventQueue); @@ -14,7 +76,7 @@ OSMesgQueue* PadMgr_LockSerialMesgQueue(PadMgr* padMgr) { osRecvMesg(&padMgr->serialLockQueue, (OSMesg*)&serialEventQueue, OS_MESG_BLOCK); - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Locked" osSyncPrintf("%2d %d serialMsgQをロックしました %08x\n", osGetThreadId(NULL), MQ_GET_COUNT(&padMgr->serialLockQueue), serialEventQueue); @@ -23,8 +85,15 @@ OSMesgQueue* PadMgr_LockSerialMesgQueue(PadMgr* padMgr) { return serialEventQueue; } -void PadMgr_UnlockSerialMesgQueue(PadMgr* padMgr, OSMesgQueue* serialEventQueue) { - if (D_8012D280 > 2) { +/** + * Relinquishes access to the serial message queue, allowing another process to acquire and use it. + * + * @param serialEventQueue The serial message queue acquired by `PadMgr_AcquireSerialEventQueue` + * + * @see PadMgr_AcquireSerialEventQueue + */ +void PadMgr_ReleaseSerialEventQueue(PadMgr* padMgr, OSMesgQueue* serialEventQueue) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Unlock" osSyncPrintf("%2d %d serialMsgQロック解除します %08x %08x %08x\n", osGetThreadId(NULL), MQ_GET_COUNT(&padMgr->serialLockQueue), padMgr, &padMgr->serialLockQueue, serialEventQueue); @@ -32,97 +101,99 @@ void PadMgr_UnlockSerialMesgQueue(PadMgr* padMgr, OSMesgQueue* serialEventQueue) osSendMesg(&padMgr->serialLockQueue, (OSMesg)serialEventQueue, OS_MESG_BLOCK); - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { // "serialMsgQ Unlocked" osSyncPrintf("%2d %d serialMsgQロック解除しました %08x %08x %08x\n", osGetThreadId(NULL), MQ_GET_COUNT(&padMgr->serialLockQueue), padMgr, &padMgr->serialLockQueue, serialEventQueue); } } +/** + * Locks controller input data while padmgr is reading new inputs or another thread is using the current inputs. + * This prevents new inputs overwriting the current inputs while they are in use. + * + * @see PadMgr_UnlockPadData + */ void PadMgr_LockPadData(PadMgr* padMgr) { osRecvMesg(&padMgr->lockQueue, NULL, OS_MESG_BLOCK); } +/** + * Unlocks controller input data, allowing padmgr to read new inputs or another thread to access the most recently + * polled inputs. + * + * @see PadMgr_LockPadData + */ void PadMgr_UnlockPadData(PadMgr* padMgr) { osSendMesg(&padMgr->lockQueue, NULL, OS_MESG_BLOCK); } -void PadMgr_RumbleControl(PadMgr* padMgr) { - static u32 errcnt = 0; - static u32 frame; - s32 temp = 1; +/** + * Activates the rumble pak for all controllers it is enabled on, stops it for all controllers it is disabled on and + * attempts to initialize it for a controller if it is not already initialized. + */ +void PadMgr_UpdateRumble(PadMgr* padMgr) { + static u32 sRumbleErrorCount = 0; // original name: "errcnt" + static u32 sRumbleUpdateCounter; + s32 motorStart = MOTOR_START; // required for matching? s32 triedRumbleComm; - OSMesgQueue* serialEventQueue = PadMgr_LockSerialMesgQueue(padMgr); - s32 var4; + OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(padMgr); + s32 ret; s32 i; - triedRumbleComm = 0; + triedRumbleComm = false; - for (i = 0; i < 4; i++) { + for (i = 0; i < MAXCONTROLLERS; i++) { if (padMgr->ctrlrIsConnected[i]) { - if (padMgr->padStatus[i].status & 1) { - if (padMgr->pakType[i] == temp) { - if (padMgr->rumbleEnable[i] != 0) { - if (padMgr->rumbleCounter[i] < 3) { - // clang-format off - if (1) {} osSyncPrintf(VT_FGCOL(YELLOW)); - // clang-format on + // Check status for whether a controller pak is connected + if (padMgr->padStatus[i].status & CONT_CARD_ON) { + if (padMgr->pakType[i] == CONT_PAK_RUMBLE) { + if (padMgr->rumbleEnable[i]) { + if (padMgr->rumbleTimer[i] < 3) { + // "Rumble pack brrr" + PADMGR_LOG(i, "振動パック ぶるぶるぶるぶる"); - // "Vibration pack jumble jumble"? - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パック ぶるぶるぶるぶる"); - osSyncPrintf(VT_RST); + // This should be the osMotorStart macro, however the temporary variable motorStart is + // currently required for matching + if (__osMotorAccess(&padMgr->rumblePfs[i], motorStart) != 0) { + padMgr->pakType[i] = CONT_PAK_NONE; - if (__osMotorAccess(&padMgr->pfs[i], temp) != 0) { - padMgr->pakType[i] = 0; - osSyncPrintf(VT_FGCOL(YELLOW)); // "A communication error has occurred with the vibration pack" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックで通信エラーが発生しました"); - osSyncPrintf(VT_RST); + PADMGR_LOG(i, "振動パックで通信エラーが発生しました"); } else { - padMgr->rumbleCounter[i] = 3; + padMgr->rumbleTimer[i] = 3; } - triedRumbleComm = 1; + triedRumbleComm = true; } } else { - if (padMgr->rumbleCounter[i] != 0) { - // clang-format off - if (1) {} osSyncPrintf(VT_FGCOL(YELLOW)); - // clang-format on - + if (padMgr->rumbleTimer[i] != 0) { // "Stop vibration pack" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パック 停止"); - osSyncPrintf(VT_RST); + PADMGR_LOG(i, "振動パック 停止"); + + if (osMotorStop(&padMgr->rumblePfs[i]) != 0) { + padMgr->pakType[i] = CONT_PAK_NONE; - if (osMotorStop(&padMgr->pfs[i]) != 0) { - padMgr->pakType[i] = 0; - osSyncPrintf(VT_FGCOL(YELLOW)); // "A communication error has occurred with the vibration pack" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックで通信エラーが発生しました"); - osSyncPrintf(VT_RST); + PADMGR_LOG(i, "振動パックで通信エラーが発生しました"); } else { - padMgr->rumbleCounter[i]--; + padMgr->rumbleTimer[i]--; } - triedRumbleComm = 1; + triedRumbleComm = true; } } } } else { - if (padMgr->pakType[i] != 0) { - if (padMgr->pakType[i] == 1) { - osSyncPrintf(VT_FGCOL(YELLOW)); + if (padMgr->pakType[i] != CONT_PAK_NONE) { + if (padMgr->pakType[i] == CONT_PAK_RUMBLE) { // "It seems that a vibration pack was pulled out" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックが抜かれたようです"); - osSyncPrintf(VT_RST); - padMgr->pakType[i] = 0; + PADMGR_LOG(i, "振動パックが抜かれたようです"); + padMgr->pakType[i] = CONT_PAK_NONE; } else { - osSyncPrintf(VT_FGCOL(YELLOW)); // "It seems that a controller pack that is not a vibration pack was pulled out" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, - "振動パックではないコントローラパックが抜かれたようです"); - osSyncPrintf(VT_RST); - padMgr->pakType[i] = 0; + PADMGR_LOG(i, "振動パックではないコントローラパックが抜かれたようです"); + padMgr->pakType[i] = CONT_PAK_NONE; } } } @@ -130,128 +201,145 @@ void PadMgr_RumbleControl(PadMgr* padMgr) { } if (!triedRumbleComm) { - i = frame % 4; + // Try to initialize the rumble pak for controller port `i` if a controller pak is connected and + // not already known to be an initialized a rumble pak + i = sRumbleUpdateCounter % MAXCONTROLLERS; - if (padMgr->ctrlrIsConnected[i] && (padMgr->padStatus[i].status & 1) && (padMgr->pakType[i] != 1)) { - var4 = osMotorInit(serialEventQueue, &padMgr->pfs[i], i); + if (padMgr->ctrlrIsConnected[i] && (padMgr->padStatus[i].status & CONT_CARD_ON) && + padMgr->pakType[i] != CONT_PAK_RUMBLE) { + ret = osMotorInit(serialEventQueue, &padMgr->rumblePfs[i], i); + + if (ret == 0) { + padMgr->pakType[i] = CONT_PAK_RUMBLE; + osMotorStart(&padMgr->rumblePfs[i]); + osMotorStop(&padMgr->rumblePfs[i]); - if (var4 == 0) { - padMgr->pakType[i] = 1; - osMotorStart(&padMgr->pfs[i]); - osMotorStop(&padMgr->pfs[i]); - osSyncPrintf(VT_FGCOL(YELLOW)); // "Recognized vibration pack" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パックを認識しました"); - osSyncPrintf(VT_RST); - } else if (var4 == 11) { - padMgr->pakType[i] = 2; - } else if (var4 == 4) { - LOG_NUM("++errcnt", ++errcnt, "../padmgr.c", 282); - osSyncPrintf(VT_FGCOL(YELLOW)); + PADMGR_LOG(i, "振動パックを認識しました"); + } else if (ret == PFS_ERR_DEVICE) { + padMgr->pakType[i] = CONT_PAK_OTHER; + } else if (ret == PFS_ERR_CONTRFAIL) { + LOG_NUM("++errcnt", ++sRumbleErrorCount, "../padmgr.c", 282); + // "Controller pack communication error" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "コントローラパックの通信エラー"); - osSyncPrintf(VT_RST); + PADMGR_LOG(i, "コントローラパックの通信エラー"); } } } + sRumbleUpdateCounter++; - frame++; - PadMgr_UnlockSerialMesgQueue(padMgr, serialEventQueue); + PadMgr_ReleaseSerialEventQueue(padMgr, serialEventQueue); } +/** + * Immediately stops rumble on all controllers + */ void PadMgr_RumbleStop(PadMgr* padMgr) { s32 i; - OSMesgQueue* serialEventQueue = PadMgr_LockSerialMesgQueue(padMgr); + OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(padMgr); - for (i = 0; i < 4; i++) { - if (osMotorInit(serialEventQueue, &padMgr->pfs[i], i) == 0) { - if ((gFaultMgr.msgId == 0) && (padMgr->rumbleOnFrames != 0)) { - osSyncPrintf(VT_FGCOL(YELLOW)); - // "Stop vibration pack" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "振動パック 停止"); - osSyncPrintf(VT_RST); + for (i = 0; i < MAXCONTROLLERS; i++) { + if (osMotorInit(serialEventQueue, &padMgr->rumblePfs[i], i) == 0) { + // If there is a rumble pak attached to this controller, stop it + + if (gFaultMgr.msgId == 0 && padMgr->rumbleOnTimer != 0) { + // "Stop rumble pak" + PADMGR_LOG(i, "振動パック 停止"); } - - osMotorStop(&padMgr->pfs[i]); + osMotorStop(&padMgr->rumblePfs[i]); } } - PadMgr_UnlockSerialMesgQueue(padMgr, serialEventQueue); + PadMgr_ReleaseSerialEventQueue(padMgr, serialEventQueue); } +/** + * Prevents rumble for 3 VI, ~0.05 seconds at 60 VI/sec + */ void PadMgr_RumbleReset(PadMgr* padMgr) { - padMgr->rumbleOffFrames = 3; + padMgr->rumbleOffTimer = 3; } -void PadMgr_RumbleSetSingle(PadMgr* padMgr, u32 ctrlr, u32 rumble) { - padMgr->rumbleEnable[ctrlr] = rumble; - padMgr->rumbleOnFrames = 240; +/** + * Enables or disables rumble on controller port `port` for 240 VI, + * ~4 seconds at 60 VI/sec and ~4.8 seconds at 50 VI/sec + */ +void PadMgr_RumbleSetSingle(PadMgr* padMgr, u32 port, u32 rumble) { + padMgr->rumbleEnable[port] = rumble; + padMgr->rumbleOnTimer = 240; } -void PadMgr_RumbleSet(PadMgr* padMgr, u8* ctrlrRumbles) { +/** + * Enables or disables rumble on all controller ports for 240 VI, + * ~4 seconds at 60 VI/sec and ~4.8 seconds at 50 VI/sec + * + * @param enable Array of u8 of length MAXCONTROLLERS containing either true or false to enable or disable rumble + * for that controller + */ +void PadMgr_RumbleSet(PadMgr* padMgr, u8* enable) { s32 i; - for (i = 0; i < 4; i++) { - padMgr->rumbleEnable[i] = ctrlrRumbles[i]; + for (i = 0; i < MAXCONTROLLERS; i++) { + padMgr->rumbleEnable[i] = enable[i]; } - padMgr->rumbleOnFrames = 240; + padMgr->rumbleOnTimer = 240; } -void PadMgr_ProcessInputs(PadMgr* padMgr) { +/** + * Updates `padMgr->inputs` based on the error response of each controller + */ +void PadMgr_UpdateInputs(PadMgr* padMgr) { s32 i; Input* input; - OSContPad* padnow1; // original name + OSContPad* pad; // original name: "padnow1" s32 buttonDiff; PadMgr_LockPadData(padMgr); - input = &padMgr->inputs[0]; - padnow1 = &padMgr->pads[0]; - - for (i = 0; i < padMgr->nControllers; i++, input++, padnow1++) { + for (input = &padMgr->inputs[0], pad = &padMgr->pads[0], i = 0; i < padMgr->nControllers; i++, input++, pad++) { input->prev = input->cur; - if (1) {} // Necessary to match - - switch (padnow1->errno) { + switch (pad->errno) { case 0: - input->cur = *padnow1; + // No error, copy inputs + input->cur = *pad; if (!padMgr->ctrlrIsConnected[i]) { padMgr->ctrlrIsConnected[i] = true; - osSyncPrintf(VT_FGCOL(YELLOW)); - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "認識しました"); // "Recognized" - osSyncPrintf(VT_RST); + // "Recognized" + PADMGR_LOG(i, "認識しました"); } break; - case 4: + case (CHNL_ERR_OVERRUN >> 4): + // Overrun error, reuse previous inputs input->cur = input->prev; LOG_NUM("this->Key_switch[i]", padMgr->ctrlrIsConnected[i], "../padmgr.c", 380); - osSyncPrintf(VT_FGCOL(YELLOW)); // "Overrun error occurred" - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "オーバーランエラーが発生"); - osSyncPrintf(VT_RST); + PADMGR_LOG(i, "オーバーランエラーが発生"); break; - case 8: + case (CHNL_ERR_NORESP >> 4): + // No response error, take inputs as 0 input->cur.button = 0; input->cur.stick_x = 0; input->cur.stick_y = 0; - input->cur.errno = padnow1->errno; + input->cur.errno = pad->errno; if (padMgr->ctrlrIsConnected[i]) { + // If we get no response, consider the controller disconnected padMgr->ctrlrIsConnected[i] = false; - padMgr->pakType[i] = 0; - padMgr->rumbleCounter[i] = 0xFF; - osSyncPrintf(VT_FGCOL(YELLOW)); - // "Do not respond"? - osSyncPrintf("padmgr: %dコン: %s\n", i + 1, "応答しません"); - osSyncPrintf(VT_RST); + padMgr->pakType[i] = CONT_PAK_NONE; + padMgr->rumbleTimer[i] = UINT8_MAX; + // "Not responding" + PADMGR_LOG(i, "応答しません"); } break; default: - LOG_HEX("padnow1->errno", padnow1->errno, "../padmgr.c", 396); + // Unknown error response + LOG_HEX("padnow1->errno", pad->errno, "../padmgr.c", 396); Fault_AddHungupAndCrash("../padmgr.c", 397); + break; } + // Calculate pressed and relative inputs buttonDiff = input->prev.button ^ input->cur.button; input->press.button |= (u16)(buttonDiff & input->cur.button); input->rel.button |= (u16)(buttonDiff & input->prev.button); @@ -263,29 +351,43 @@ void PadMgr_ProcessInputs(PadMgr* padMgr) { PadMgr_UnlockPadData(padMgr); } -void PadMgr_HandleRetraceMsg(PadMgr* padMgr) { +void PadMgr_HandleRetrace(PadMgr* padMgr) { s32 i; - OSMesgQueue* serialEventQueue = PadMgr_LockSerialMesgQueue(padMgr); + OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(padMgr); u32 mask; + // Begin reading controller data osContStartReadData(serialEventQueue); - if (padMgr->retraceCallback) { + + // Execute retrace callback + if (padMgr->retraceCallback != NULL) { padMgr->retraceCallback(padMgr, padMgr->retraceCallbackValue); } + + // Wait for controller data osRecvMesg(serialEventQueue, NULL, OS_MESG_BLOCK); osContGetReadData(padMgr->pads); - if (padMgr->preNMIShutdown) { + + // If resetting, clear all controllers + if (padMgr->isResetting) { bzero(padMgr->pads, sizeof(padMgr->pads)); } - PadMgr_ProcessInputs(padMgr); + + // Update input data + PadMgr_UpdateInputs(padMgr); + + // Query controller status for all controllers osContStartQuery(serialEventQueue); osRecvMesg(serialEventQueue, NULL, OS_MESG_BLOCK); osContGetQuery(padMgr->padStatus); - PadMgr_UnlockSerialMesgQueue(padMgr, serialEventQueue); + PadMgr_ReleaseSerialEventQueue(padMgr, serialEventQueue); + + // Update the state of connected controllers mask = 0; - for (i = 0; i < 4; i++) { + for (i = 0; i < MAXCONTROLLERS; i++) { if (padMgr->padStatus[i].errno == 0) { + // Only standard N64 controllers are supported if (padMgr->padStatus[i].type == CONT_TYPE_NORMAL) { mask |= 1 << i; } else { @@ -298,53 +400,64 @@ void PadMgr_HandleRetraceMsg(PadMgr* padMgr) { padMgr->validCtrlrsMask = mask; if (gFaultMgr.msgId != 0) { + // If fault is active, no rumble PadMgr_RumbleStop(padMgr); - } else if (padMgr->rumbleOffFrames > 0) { - --padMgr->rumbleOffFrames; + } else if (padMgr->rumbleOffTimer > 0) { + // If the rumble off timer is active, no rumble + --padMgr->rumbleOffTimer; PadMgr_RumbleStop(padMgr); - } else if (padMgr->rumbleOnFrames == 0) { + } else if (padMgr->rumbleOnTimer == 0) { + // If the rumble on timer is inactive, no rumble PadMgr_RumbleStop(padMgr); - } else if (!padMgr->preNMIShutdown) { - PadMgr_RumbleControl(padMgr); - --padMgr->rumbleOnFrames; + } else if (!padMgr->isResetting) { + // If not resetting, update rumble + PadMgr_UpdateRumble(padMgr); + --padMgr->rumbleOnTimer; } } void PadMgr_HandlePreNMI(PadMgr* padMgr) { osSyncPrintf("padmgr_HandlePreNMI()\n"); - padMgr->preNMIShutdown = true; + padMgr->isResetting = true; PadMgr_RumbleReset(padMgr); } -void PadMgr_RequestPadData(PadMgr* padMgr, Input* inputs, s32 mode) { +/** + * Fetches the most recently polled inputs from padmgr + * + * @param inputs Array of Input of length MAXCONTROLLERS to copy inputs into + * @param gamePoll True if polling inputs for updating the game state + */ +void PadMgr_RequestPadData(PadMgr* padMgr, Input* inputs, s32 gameRequest) { s32 i; - Input* ogInput; - Input* newInput; + Input* inputIn; + Input* inputOut; s32 buttonDiff; PadMgr_LockPadData(padMgr); - ogInput = &padMgr->inputs[0]; - newInput = &inputs[0]; - for (i = 0; i < 4; i++) { - if (mode != 0) { - *newInput = *ogInput; - ogInput->press.button = 0; - ogInput->press.stick_x = 0; - ogInput->press.stick_y = 0; - ogInput->rel.button = 0; + for (inputIn = &padMgr->inputs[0], inputOut = &inputs[0], i = 0; i < MAXCONTROLLERS; i++, inputIn++, inputOut++) { + if (gameRequest) { + // Copy inputs as-is, press and rel are calculated prior in `PadMgr_UpdateInputs` + *inputOut = *inputIn; + // Zero parts of the press and rel inputs in the polled inputs so they are not read more than once + inputIn->press.button = 0; + inputIn->press.stick_x = 0; + inputIn->press.stick_y = 0; + inputIn->rel.button = 0; } else { - newInput->prev = newInput->cur; - newInput->cur = ogInput->cur; - buttonDiff = newInput->prev.button ^ newInput->cur.button; - newInput->press.button = newInput->cur.button & buttonDiff; - newInput->rel.button = newInput->prev.button & buttonDiff; - PadUtils_UpdateRelXY(newInput); - newInput->press.stick_x += (s8)(newInput->cur.stick_x - newInput->prev.stick_x); - newInput->press.stick_y += (s8)(newInput->cur.stick_y - newInput->prev.stick_y); + // Take as the previous inputs the inputs that are currently in the destination array + inputOut->prev = inputOut->cur; + // Copy current inputs from the polled inputs + inputOut->cur = inputIn->cur; + // Calculate press and rel from these + buttonDiff = inputOut->prev.button ^ inputOut->cur.button; + inputOut->press.button = inputOut->cur.button & buttonDiff; + inputOut->rel.button = inputOut->prev.button & buttonDiff; + PadUtils_UpdateRelXY(inputOut); + inputOut->press.stick_x += (s8)(inputOut->cur.stick_x - inputOut->prev.stick_x); + inputOut->press.stick_y += (s8)(inputOut->cur.stick_y - inputOut->prev.stick_y); } - ogInput++; - newInput++; } PadMgr_UnlockPadData(padMgr); @@ -358,7 +471,7 @@ void PadMgr_ThreadEntry(PadMgr* padMgr) { exit = false; while (!exit) { - if ((D_8012D280 > 2) && MQ_IS_EMPTY(&padMgr->interruptQueue)) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE && MQ_IS_EMPTY(&padMgr->interruptQueue)) { // "Waiting for controller thread event" osSyncPrintf("コントローラスレッドイベント待ち %lld\n", OS_CYCLES_TO_USEC(osGetTime())); } @@ -368,16 +481,15 @@ void PadMgr_ThreadEntry(PadMgr* padMgr) { switch (*msg) { case OS_SC_RETRACE_MSG: - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { osSyncPrintf("padmgr_HandleRetraceMsg START %lld\n", OS_CYCLES_TO_USEC(osGetTime())); } - PadMgr_HandleRetraceMsg(padMgr); + PadMgr_HandleRetrace(padMgr); - if (D_8012D280 > 2) { + if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { osSyncPrintf("padmgr_HandleRetraceMsg END %lld\n", OS_CYCLES_TO_USEC(osGetTime())); } - break; case OS_SC_PRE_NMI_MSG: PadMgr_HandlePreNMI(padMgr); @@ -401,13 +513,16 @@ void PadMgr_Init(PadMgr* padMgr, OSMesgQueue* serialEventQueue, IrqMgr* irqMgr, osCreateMesgQueue(&padMgr->interruptQueue, padMgr->interruptMsgBuf, ARRAY_COUNT(padMgr->interruptMsgBuf)); IrqMgr_AddClient(padMgr->irqMgr, &padMgr->irqClient, &padMgr->interruptQueue); - osCreateMesgQueue(&padMgr->serialLockQueue, padMgr->serialLockMsgBuf, ARRAY_COUNT(padMgr->serialLockMsgBuf)); - PadMgr_UnlockSerialMesgQueue(padMgr, serialEventQueue); - osCreateMesgQueue(&padMgr->lockQueue, padMgr->lockMsgBuf, ARRAY_COUNT(padMgr->lockMsgBuf)); + + osCreateMesgQueue(&padMgr->serialLockQueue, &padMgr->serialMsg, 1); + PadMgr_ReleaseSerialEventQueue(padMgr, serialEventQueue); + + osCreateMesgQueue(&padMgr->lockQueue, &padMgr->lockMsg, 1); PadMgr_UnlockPadData(padMgr); + PadSetup_Init(serialEventQueue, (u8*)&padMgr->validCtrlrsMask, padMgr->padStatus); - padMgr->nControllers = 4; + padMgr->nControllers = MAXCONTROLLERS; osContSetCh(padMgr->nControllers); osCreateThread(&padMgr->thread, id, (void (*)(void*))PadMgr_ThreadEntry, padMgr, stack, priority); diff --git a/src/code/padsetup.c b/src/code/padsetup.c index e4e8a0d687..20a546ae3f 100644 --- a/src/code/padsetup.c +++ b/src/code/padsetup.c @@ -9,16 +9,16 @@ s32 PadSetup_Init(OSMesgQueue* mq, u8* outMask, OSContStatus* status) { if (ret != 0) { return ret; } + if (*outMask == 0xFF) { if (osContStartQuery(mq) != 0) { return 1; } - osRecvMesg(mq, NULL, OS_MESG_BLOCK); osContGetQuery(status); *outMask = 0; - for (i = 0; i < 4; i++) { + for (i = 0; i < MAXCONTROLLERS; i++) { switch (status[i].errno) { case 0: if (status[i].type == CONT_TYPE_NORMAL) {