mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-06-03 18:35:52 -04:00
1553 lines
43 KiB
C
1553 lines
43 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/pak.h"
|
|
#include "bss.h"
|
|
#include "lib/main.h"
|
|
#include "lib/joy.h"
|
|
#include "data.h"
|
|
#include "types.h"
|
|
|
|
/**
|
|
* PD polls the controllers from the scheduler's thread. The scheduler polls the
|
|
* controllers on each retrace and stores teh results inside g_JoyData->samples.
|
|
* This allows the main thread to access a history of controller states since
|
|
* the last rendered frame. For example, under laggy conditions the player might
|
|
* press and release a button between two frames and the main thread can tell
|
|
* that this has happened even if the button was unpressed during both the
|
|
* previous and current frame.
|
|
*
|
|
* The samples array contains 20 elements and is written to in a cyclic manner.
|
|
* These samples are split into two partitions: cur and next. cur refers to
|
|
* samples which are currently visible to the main thread on this frame, and
|
|
* samples in next are samples which have been added since the start of the
|
|
* current frame and will be made visible on the next frame.
|
|
*
|
|
* At the start of a frame, the main thread informs the joy system that it's
|
|
* ready to consume more samples. The joy system then moves the partition
|
|
* boundaries so that the old next partition becomes the new cur, and everything
|
|
* else becomes available for next.
|
|
*
|
|
* If all 20 samples are in use, the joy system will overwrite the most recent
|
|
* sample in the next partition.
|
|
*/
|
|
|
|
struct joydata g_JoyData[2];
|
|
s32 g_JoyDisableCooldown[4];
|
|
OSMesgQueue g_PiMesgQueue;
|
|
OSMesg var80099e90[10];
|
|
OSMesg var80099eb8[2];
|
|
OSMesgQueue g_JoyStopCyclicPollingMesgQueue;
|
|
OSMesg var80099ed8[2];
|
|
OSMesgQueue g_JoyStopCyclicPollingDoneMesgQueue;
|
|
OSMesg var80099ef8[2];
|
|
OSMesgQueue g_JoyStartCyclicPollingMesgQueue;
|
|
OSMesg var80099f18[2];
|
|
OSMesgQueue g_JoyStartCyclicPollingDoneMesgQueue;
|
|
OSContStatus var80099f38[4];
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
u8 g_JoyPfsStates[100];
|
|
u32 var80099fac;
|
|
u32 var80099fb0;
|
|
#endif
|
|
|
|
const char var70054080[] = "joyReset\n";
|
|
const char var7005408c[] = "joyReset: doing nothing\n";
|
|
|
|
struct joydata *g_JoyDataPtr = &g_JoyData[0];
|
|
bool g_JoyBusy = false;
|
|
u32 var8005ee68 = 0;
|
|
|
|
// Number of times per pad that different inputs were attempted to be read
|
|
// when controller was disconnected or not ready.
|
|
u32 g_JoyBadReadsStickX[4] = {0};
|
|
u32 g_JoyBadReadsStickY[4] = {0};
|
|
u32 g_JoyBadReadsButtons[4] = {0};
|
|
u32 g_JoyBadReadsButtonsPressed[4] = {0};
|
|
|
|
u8 g_JoyConnectedControllers = 0;
|
|
bool g_JoyQueuesCreated = false;
|
|
bool g_JoyInitDone = false;
|
|
bool g_JoyNeedsInit = true;
|
|
u32 g_JoyCyclicPollDisableCount = 0;
|
|
u32 var8005eec0 = 1;
|
|
s32 (*var8005eec4)(struct contsample *samples, s32 samplenum) = NULL;
|
|
void (*var8005eec8)(struct contsample *samples, s32 samplenum, s32 samplenum2) = NULL;
|
|
s32 g_JoyNextPfsStateIndex = (VERSION >= VERSION_NTSC_1_0 ? 0 : 30);
|
|
u32 var8005eed0 = 0;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
u32 var8005eed4 = 0;
|
|
#endif
|
|
|
|
u8 var8005eed8 = 0;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
bool var8005eedc = true;
|
|
s32 var8005eee0 = 0;
|
|
s32 var8005eee4 = -1;
|
|
u32 var8005eee8 = 0;
|
|
u32 var8005eeec = 0;
|
|
u32 var8005eef0 = 1;
|
|
#else
|
|
u32 var800612c8nb = 3;
|
|
u8 var800612ccnb = 0;
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void joy00013900(void)
|
|
{
|
|
if (var8005eef0) {
|
|
joyDisableCyclicPolling();
|
|
var8005eef0 = false;
|
|
}
|
|
}
|
|
|
|
void joy00013938(void)
|
|
{
|
|
if (!var8005eef0) {
|
|
joyEnableCyclicPolling();
|
|
var8005eef0 = true;
|
|
}
|
|
}
|
|
|
|
void joy00013974(u32 value)
|
|
{
|
|
var8005eeec = value;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
u32 joy00013980(void)
|
|
{
|
|
return var8005eeec;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Note: Some of the variables in this file are misnamed in NTSC beta.
|
|
* @TODO: Untangle these.
|
|
*/
|
|
void joy0001398c(s32 value)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
var8005eee4 = var8005eee0 = value * 11000;
|
|
#else
|
|
g_JoyNextPfsStateIndex = value;
|
|
#endif
|
|
}
|
|
|
|
void joy000139c8(void)
|
|
{
|
|
joy0001398c(VERSION >= VERSION_NTSC_1_0 ? 10 : 30);
|
|
}
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
// Same function as the one a couple above, just relocated
|
|
u32 joy00013980(void)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
return var8005eeec;
|
|
#else
|
|
return var8005eed8;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
/**
|
|
* Remove an item from the beginning of the g_JoyPfsStates array,
|
|
* shift the rest of the array back and return the removed item.
|
|
*/
|
|
s32 joyShiftPfsStates(void)
|
|
{
|
|
s32 pfsstate = 0;
|
|
s32 i;
|
|
|
|
if (g_JoyNextPfsStateIndex) {
|
|
pfsstate = g_JoyPfsStates[0];
|
|
|
|
if (g_JoyNextPfsStateIndex > 1) {
|
|
for (i = 0; i < g_JoyNextPfsStateIndex; i++) {
|
|
g_JoyPfsStates[i] = g_JoyPfsStates[i + 1];
|
|
}
|
|
|
|
g_JoyNextPfsStateIndex--;
|
|
}
|
|
}
|
|
|
|
return pfsstate;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void joyRecordPfsState(u8 pfsstate)
|
|
{
|
|
if (g_JoyNextPfsStateIndex + 1 >= 100) {
|
|
joyShiftPfsStates();
|
|
}
|
|
|
|
if (g_JoyNextPfsStateIndex == 0 || pfsstate != g_JoyPfsStates[g_JoyNextPfsStateIndex - 1]) {
|
|
g_JoyPfsStates[g_JoyNextPfsStateIndex] = pfsstate;
|
|
g_JoyNextPfsStateIndex++;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
/**
|
|
* Scan controllers for controller paks, but only under certain conditions.
|
|
* Seems to be timer based, or can be forced by passing 2 as arg0.
|
|
*/
|
|
void joyCheckPfs(s32 arg0)
|
|
{
|
|
static u32 thiscount = 0; // 8005eef4
|
|
static u32 prevcount = 0; // 8005eef8
|
|
static u32 doingit = false; // 8005eefc
|
|
u32 diffcount;
|
|
u32 value;
|
|
|
|
if (var8005eedc
|
|
&& (arg0 == 2 || (var8005eee0 && (arg0 || ((g_JoyCyclicPollDisableCount == 0 || var8005eef0 == 0) && var8005eeec))))
|
|
&& !doingit) {
|
|
doingit = true;
|
|
prevcount = thiscount;
|
|
thiscount = osGetCount();
|
|
diffcount = (thiscount - prevcount) / 256;
|
|
value = var8005eee0 * 2;
|
|
|
|
if (diffcount > value) {
|
|
diffcount = value;
|
|
}
|
|
|
|
var8005eee4 -= diffcount;
|
|
|
|
if (var8005eee4 < 0
|
|
|| arg0 == 2
|
|
|| (arg0 == 1 && var8005eee4 < 0 && var8005eee0 < -var8005eee4)) {
|
|
u8 bitpattern = 0;
|
|
|
|
var8005eee8++;
|
|
|
|
if (arg0) {
|
|
joyDisableCyclicPolling();
|
|
}
|
|
|
|
osPfsIsPlug(&g_PiMesgQueue, &bitpattern);
|
|
|
|
if (arg0) {
|
|
joyEnableCyclicPolling();
|
|
}
|
|
|
|
bitpattern |= 0x10;
|
|
|
|
joyRecordPfsState(bitpattern);
|
|
|
|
var8005eee4 = var8005eee0;
|
|
}
|
|
|
|
doingit = false;
|
|
}
|
|
|
|
#if VERSION < VERSION_PAL_BETA
|
|
if (arg0) {
|
|
// empty
|
|
}
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* "Temporarily" because the next time joyCheckPfs runs, the true state will be
|
|
* recorded.
|
|
*
|
|
* Note that var8005eed8 is always zero, so this record will suggest that this
|
|
* pak is the only one connected.
|
|
*/
|
|
void joySetPfsTemporarilyPlugged(s8 index)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
u8 bitpattern = var8005eed8 & ~(1 << index);
|
|
|
|
joyRecordPfsState(bitpattern);
|
|
#else
|
|
var8005eed8 &= ~(1 << index);
|
|
#endif
|
|
}
|
|
|
|
void joyInit(void)
|
|
{
|
|
s32 i;
|
|
s32 j;
|
|
|
|
osCreateMesgQueue(&g_JoyStopCyclicPollingMesgQueue, var80099eb8, 1);
|
|
osCreateMesgQueue(&g_JoyStopCyclicPollingDoneMesgQueue, var80099ed8, 1);
|
|
osCreateMesgQueue(&g_JoyStartCyclicPollingMesgQueue, var80099ef8, 1);
|
|
osCreateMesgQueue(&g_JoyStartCyclicPollingDoneMesgQueue, var80099f18, 1);
|
|
osCreateMesgQueue(&g_PiMesgQueue, var80099e90, ARRAYCOUNT(var80099e90));
|
|
|
|
osSetEventMesg(OS_EVENT_SI, &g_PiMesgQueue, NULL);
|
|
|
|
g_JoyQueuesCreated = true;
|
|
|
|
var8005eec4 = NULL;
|
|
var8005eec8 = NULL;
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
g_JoyData[i].curlast = 0;
|
|
g_JoyData[i].curstart = 0;
|
|
g_JoyData[i].nextlast = 0;
|
|
g_JoyData[i].nextsecondlast = 0;
|
|
g_JoyData[i].unk200 = -1;
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
g_JoyData[i].samples[0].pads[j].button = 0;
|
|
g_JoyData[i].samples[0].pads[j].stick_x = 0;
|
|
g_JoyData[i].samples[0].pads[j].stick_y = 0;
|
|
g_JoyData[i].samples[0].pads[j].errno = 0;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
g_JoyDisableCooldown[i] = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Disable all input on all controllers for 60 frames, or until the player has
|
|
* released all inputs.
|
|
*
|
|
* It's used to prevent the player from accidentally skipping cutscenes and
|
|
* progressing past endscreens if they are holding buttons when they are
|
|
* started.
|
|
*/
|
|
void joyDisableTemporarily(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
g_JoyDisableCooldown[i] = TICKS(60);
|
|
}
|
|
}
|
|
|
|
void joyReset(void)
|
|
{
|
|
OSMesg msg;
|
|
|
|
if (g_JoyQueuesCreated) {
|
|
osSendMesg(&g_JoyStopCyclicPollingMesgQueue, &msg, OS_MESG_NOBLOCK);
|
|
osRecvMesg(&g_JoyStopCyclicPollingDoneMesgQueue, &msg, OS_MESG_BLOCK);
|
|
|
|
joy00013e84();
|
|
|
|
osSendMesg(&g_JoyStartCyclicPollingMesgQueue, &msg, OS_MESG_NOBLOCK);
|
|
osRecvMesg(&g_JoyStartCyclicPollingDoneMesgQueue, &msg, OS_MESG_BLOCK);
|
|
|
|
var8005eec0 = 1;
|
|
}
|
|
}
|
|
|
|
void joy00013e84(void)
|
|
{
|
|
static u8 var8005ef00 = 0xff;
|
|
|
|
// osContInit should be called only once. The first time this function is
|
|
// called it'll take the first branch here, and all subsequent calls will
|
|
// take the second branch.
|
|
if (g_JoyNeedsInit) {
|
|
s32 i;
|
|
g_JoyNeedsInit = false;
|
|
osContInit(&g_PiMesgQueue, &g_JoyConnectedControllers, var80099f38);
|
|
g_JoyInitDone = true;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
joyStopRumble(i, false);
|
|
}
|
|
} else {
|
|
u32 slots = 0xf;
|
|
s32 i;
|
|
|
|
osContStartQuery(&g_PiMesgQueue);
|
|
osRecvMesg(&g_PiMesgQueue, NULL, OS_MESG_BLOCK);
|
|
osContGetQuery(var80099f38);
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (var80099f38[i].errno & CONT_NO_RESPONSE_ERROR) {
|
|
slots -= 1 << i;
|
|
}
|
|
}
|
|
|
|
g_JoyConnectedControllers = slots;
|
|
}
|
|
|
|
if (var8005ef00 != g_JoyConnectedControllers) {
|
|
s32 i = 0;
|
|
s32 index = 0;
|
|
|
|
for (; i < 4; i++) {
|
|
if (g_JoyConnectedControllers & (1 << i)) {
|
|
g_Vars.playertojoymap[index++] = i;
|
|
}
|
|
}
|
|
|
|
var8005ef00 = g_JoyConnectedControllers;
|
|
}
|
|
}
|
|
|
|
s8 contGetFreeSlot(void)
|
|
{
|
|
s32 i;
|
|
|
|
if (g_JoyDataPtr->unk200 >= 0) {
|
|
return g_JoyDataPtr->unk200;
|
|
}
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if ((g_JoyConnectedControllers & (1 << i)) == 0) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return 4;
|
|
}
|
|
|
|
u32 joyGetConnectedControllers(void)
|
|
{
|
|
return g_JoyConnectedControllers;
|
|
}
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
void func00014e9cnb(void *callback, s32 value2)
|
|
{
|
|
var8005eec4 = callback;
|
|
g_JoyData[1].unk200 = value2;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
void func00014eb0nb(void *value)
|
|
{
|
|
var8005eec8 = value;
|
|
}
|
|
#endif
|
|
|
|
void joyConsumeSamples(struct joydata *joydata)
|
|
{
|
|
s8 i;
|
|
s32 samplenum;
|
|
u16 buttons1;
|
|
u16 buttons2;
|
|
|
|
joydata->curstart = joydata->curlast;
|
|
joydata->curlast = joydata->nextlast;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
joydata->buttonspressed[i] = 0;
|
|
joydata->buttonsreleased[i] = 0;
|
|
|
|
if (joydata->curlast != joydata->curstart) {
|
|
samplenum = (joydata->curstart + 1) % 20; while (true) {
|
|
buttons1 = joydata->samples[samplenum].pads[i].button;
|
|
buttons2 = joydata->samples[(samplenum + 19) % 20].pads[i].button;
|
|
|
|
joydata->buttonspressed[i] |= buttons1 & ~buttons2;
|
|
joydata->buttonsreleased[i] |= ~buttons1 & buttons2;
|
|
|
|
if (g_JoyDisableCooldown[i] > 0) {
|
|
if (joydata->samples[samplenum].pads[i].button == 0
|
|
&& joydata->samples[samplenum].pads[i].stick_x < 15
|
|
&& joydata->samples[samplenum].pads[i].stick_x > -15
|
|
&& joydata->samples[samplenum].pads[i].stick_y < 15
|
|
&& joydata->samples[samplenum].pads[i].stick_y > -15) {
|
|
g_JoyDisableCooldown[i] = 0;
|
|
} else {
|
|
g_JoyDisableCooldown[i]--;
|
|
}
|
|
}
|
|
|
|
if (samplenum == joydata->curlast) {
|
|
break;
|
|
}
|
|
|
|
samplenum = (samplenum + 1) % 20;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
GLOBAL_ASM(
|
|
glabel func0001509cnb
|
|
/* 1509c: 3c0e8006 */ lui $t6,0x8006
|
|
/* 150a0: 8dce12d4 */ lw $t6,0x12d4($t6)
|
|
/* 150a4: 27bdffe8 */ addiu $sp,$sp,-24
|
|
/* 150a8: afbf0014 */ sw $ra,0x14($sp)
|
|
/* 150ac: 15c00019 */ bnez $t6,.NB00015114
|
|
/* 150b0: 3c028006 */ lui $v0,0x8006
|
|
/* 150b4: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* 150b8: 3c018006 */ lui $at,0x8006
|
|
/* 150bc: 244212c0 */ addiu $v0,$v0,0x12c0
|
|
/* 150c0: ac2f12d4 */ sw $t7,0x12d4($at)
|
|
/* 150c4: 3c188006 */ lui $t8,0x8006
|
|
/* 150c8: 8f1812bc */ lw $t8,0x12bc($t8)
|
|
/* 150cc: 8c590000 */ lw $t9,0x0($v0)
|
|
/* 150d0: 0319082a */ slt $at,$t8,$t9
|
|
/* 150d4: 1020000d */ beqz $at,.NB0001510c
|
|
/* 150d8: 00000000 */ sll $zero,$zero,0x0
|
|
/* 150dc: 0c005332 */ jal joy00013e84
|
|
/* 150e0: ac400000 */ sw $zero,0x0($v0)
|
|
/* 150e4: 3c04800a */ lui $a0,0x800a
|
|
/* 150e8: 3c058006 */ lui $a1,0x8006
|
|
/* 150ec: 24a512c4 */ addiu $a1,$a1,0x12c4
|
|
/* 150f0: 0c014228 */ jal osPfsIsPlug
|
|
/* 150f4: 2484e5d8 */ addiu $a0,$a0,-6696
|
|
/* 150f8: 3c028006 */ lui $v0,0x8006
|
|
/* 150fc: 244212c4 */ addiu $v0,$v0,0x12c4
|
|
/* 15100: 90480000 */ lbu $t0,0x0($v0)
|
|
/* 15104: 35090010 */ ori $t1,$t0,0x10
|
|
/* 15108: a0490000 */ sb $t1,0x0($v0)
|
|
.NB0001510c:
|
|
/* 1510c: 3c018006 */ lui $at,0x8006
|
|
/* 15110: ac2012d4 */ sw $zero,0x12d4($at)
|
|
.NB00015114:
|
|
/* 15114: 8fbf0014 */ lw $ra,0x14($sp)
|
|
/* 15118: 27bd0018 */ addiu $sp,$sp,0x18
|
|
/* 1511c: 03e00008 */ jr $ra
|
|
/* 15120: 00000000 */ sll $zero,$zero,0x0
|
|
);
|
|
#endif
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
u32 var800612d4nb = 0;
|
|
#endif
|
|
|
|
/**
|
|
* The use of the static variable suggests that the function is able to be
|
|
* called recursively, but its behaviour should not be run when recursing.
|
|
*/
|
|
void joy00014238(void)
|
|
{
|
|
static bool doingit = false;
|
|
s32 i;
|
|
|
|
if (doingit == false) {
|
|
doingit = true;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (joy000155f4(i) == PAK010_13) {
|
|
pakSetUnk010(i, PAK010_11);
|
|
}
|
|
}
|
|
|
|
if (var8005eec4 == NULL) {
|
|
joysTickRumble();
|
|
}
|
|
|
|
doingit = false;
|
|
}
|
|
}
|
|
|
|
u32 var8005ef08 = 0;
|
|
|
|
void joyDebugJoy(void)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
mainOverrideVariable("debugjoy", &var8005ef08);
|
|
#else
|
|
mainOverrideVariable("joyforce", &var800612c8nb);
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_Vars.paksconnected) {
|
|
joyCheckPfs(1);
|
|
}
|
|
#endif
|
|
|
|
if (var8005eec4) {
|
|
g_JoyData[1].nextlast = var8005eec4(g_JoyData[1].samples, g_JoyData[1].curlast);
|
|
joyConsumeSamples(&g_JoyData[1]);
|
|
}
|
|
|
|
joyConsumeSamples(&g_JoyData[0]);
|
|
|
|
if (var8005eec8) {
|
|
var8005eec8(g_JoyData[0].samples, g_JoyData[0].curstart, g_JoyData[0].curlast);
|
|
}
|
|
|
|
if (joyIsCyclicPollingEnabled() && var8005eec0 && joyGetNumSamples() <= 0) {
|
|
#if VERSION >= VERSION_NTSC_FINAL
|
|
joyDisableCyclicPolling();
|
|
joy00014238();
|
|
joyEnableCyclicPolling();
|
|
joyConsumeSamples(&g_JoyData[0]);
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
joyDisableCyclicPolling();
|
|
joyEnableCyclicPolling();
|
|
joyConsumeSamples(&g_JoyData[0]);
|
|
joy00014238();
|
|
#else
|
|
joyDisableCyclicPolling(500, "joy.c");
|
|
joy00014238();
|
|
func0001509cnb();
|
|
joyEnableCyclicPolling(507, "joy.c");
|
|
joyConsumeSamples(&g_JoyData[0]);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
const char var700540b4[] = "JOY : g_EnableCyclicPolling=%d";
|
|
const char var700540d4[] = "JOY : g_JoyReCheckInterval=%d";
|
|
const char var700540f4[] = "JOY : g_JoyReCheckEventIn=%d";
|
|
const char var70054114[] = "JOY : g_JoyRecheckDone=%d";
|
|
#endif
|
|
|
|
const char var70054130[] = "osContStartReadData -> Failed - CONT_NO_RESPONSE_ERROR\n";
|
|
const char var70054168[] = "osContStartReadData -> Failed - CONT_OVERRUN_ERROR\n";
|
|
const char var7005419c[] = "joyTickRetrace:joy%derrno%d->%d\n";
|
|
const char var700541c0[] = "joyTickRetrace:joy%derrno%d->%d\n";
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
const char var70055958nb[] = "joy.c";
|
|
const char var70055960nb[] = "joy.c";
|
|
#endif
|
|
|
|
s32 joyStartReadData(OSMesgQueue *mq)
|
|
{
|
|
return osContStartReadData(mq);
|
|
}
|
|
|
|
void joyReadData(void)
|
|
{
|
|
s32 index = (g_JoyData[0].nextlast + 1) % 20;
|
|
|
|
if (index == g_JoyData[0].curstart) {
|
|
// If the sample queue is full, don't overwrite the oldest sample.
|
|
// Instead, overwrite the most recent.
|
|
index = g_JoyData[0].nextlast;
|
|
}
|
|
|
|
osContGetReadData(g_JoyData[0].samples[index].pads);
|
|
|
|
g_JoyData[0].nextlast = index;
|
|
g_JoyData[0].nextsecondlast = (g_JoyData[0].nextlast + 19) % 20;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void joysTick(void)
|
|
{
|
|
OSMesg msg;
|
|
s8 i;
|
|
|
|
if (osRecvMesg(&g_JoyStopCyclicPollingMesgQueue, &msg, OS_MESG_NOBLOCK) == 0) {
|
|
if (g_JoyBusy) {
|
|
osRecvMesg(&g_PiMesgQueue, &msg, OS_MESG_BLOCK);
|
|
|
|
g_JoyBusy = false;
|
|
joyReadData();
|
|
|
|
// Check if error state has changed for any controller
|
|
for (i = 0; i < 4; i++) {
|
|
if ((g_JoyData[0].samples[g_JoyData[0].nextlast].pads[i].errno == 0 && g_JoyData[0].samples[g_JoyData[0].nextsecondlast].pads[i].errno != 0)
|
|
|| (g_JoyData[0].samples[g_JoyData[0].nextlast].pads[i].errno != 0 && g_JoyData[0].samples[g_JoyData[0].nextsecondlast].pads[i].errno == 0)) {
|
|
joy00013e84();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
osSendMesg(&g_JoyStopCyclicPollingDoneMesgQueue, &msg, OS_MESG_NOBLOCK);
|
|
|
|
var8005ee68++;
|
|
|
|
joyCheckPfs(0);
|
|
return;
|
|
}
|
|
|
|
if (osRecvMesg(&g_JoyStartCyclicPollingMesgQueue, &msg, OS_MESG_NOBLOCK) == 0) {
|
|
var8005ee68--;
|
|
|
|
if (var8005ee68 == 0) {
|
|
joyStartReadData(&g_PiMesgQueue);
|
|
g_JoyBusy = true;
|
|
}
|
|
|
|
osSendMesg(&g_JoyStartCyclicPollingDoneMesgQueue, &msg, OS_MESG_NOBLOCK);
|
|
return;
|
|
}
|
|
|
|
if (g_JoyInitDone) {
|
|
if (var8005ee68) {
|
|
joyCheckPfs(0);
|
|
return;
|
|
}
|
|
|
|
if (osRecvMesg(&g_PiMesgQueue, &msg, OS_MESG_NOBLOCK) == 0) {
|
|
static s32 count = 0;
|
|
|
|
g_JoyBusy = false;
|
|
joyReadData();
|
|
|
|
// Check if error state has changed for any controller
|
|
for (i = 0; i < 4; i++) {
|
|
if ((g_JoyData[0].samples[g_JoyData[0].nextlast].pads[i].errno == 0 && g_JoyData[0].samples[g_JoyData[0].nextsecondlast].pads[i].errno != 0)
|
|
|| (g_JoyData[0].samples[g_JoyData[0].nextlast].pads[i].errno != 0 && g_JoyData[0].samples[g_JoyData[0].nextsecondlast].pads[i].errno == 0)) {
|
|
joy00013e84();
|
|
break;
|
|
}
|
|
}
|
|
|
|
joy00014238();
|
|
joyCheckPfs(0);
|
|
|
|
joyStartReadData(&g_PiMesgQueue);
|
|
g_JoyBusy = true;
|
|
|
|
count++;
|
|
|
|
if (count >= 60) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (g_JoyBadReadsStickX[i] || g_JoyBadReadsStickY[i] || g_JoyBadReadsButtons[i] || g_JoyBadReadsButtonsPressed[i]) {
|
|
g_JoyBadReadsStickX[i] = 0;
|
|
g_JoyBadReadsStickY[i] = 0;
|
|
g_JoyBadReadsButtons[i] = 0;
|
|
g_JoyBadReadsButtonsPressed[i] = 0;
|
|
}
|
|
}
|
|
|
|
count = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
GLOBAL_ASM(
|
|
glabel joysTick
|
|
/* 1536c: 3c028006 */ lui $v0,0x8006
|
|
/* 15370: 244212c0 */ addiu $v0,$v0,0x12c0
|
|
/* 15374: 8c4e0000 */ lw $t6,0x0($v0)
|
|
/* 15378: 27bdffc8 */ addiu $sp,$sp,-56
|
|
/* 1537c: afbf0014 */ sw $ra,0x14($sp)
|
|
/* 15380: 3c04800a */ lui $a0,0x800a
|
|
/* 15384: 25cf0001 */ addiu $t7,$t6,0x1
|
|
/* 15388: ac4f0000 */ sw $t7,0x0($v0)
|
|
/* 1538c: 2484e620 */ addiu $a0,$a0,-6624
|
|
/* 15390: 27a50034 */ addiu $a1,$sp,0x34
|
|
/* 15394: 0c0126b0 */ jal osRecvMesg
|
|
/* 15398: 00003025 */ or $a2,$zero,$zero
|
|
/* 1539c: 14400045 */ bnez $v0,.NB000154b4
|
|
/* 153a0: 3c188006 */ lui $t8,0x8006
|
|
/* 153a4: 8f181254 */ lw $t8,0x1254($t8)
|
|
/* 153a8: 3c04800a */ lui $a0,0x800a
|
|
/* 153ac: 2484e5d8 */ addiu $a0,$a0,-6696
|
|
/* 153b0: 13000035 */ beqz $t8,.NB00015488
|
|
/* 153b4: 27a50034 */ addiu $a1,$sp,0x34
|
|
/* 153b8: 0c0126b0 */ jal osRecvMesg
|
|
/* 153bc: 24060001 */ addiu $a2,$zero,0x1
|
|
/* 153c0: 3c018006 */ lui $at,0x8006
|
|
/* 153c4: 0c0054bc */ jal joyReadData
|
|
/* 153c8: ac201254 */ sw $zero,0x1254($at)
|
|
/* 153cc: 3c19800a */ lui $t9,0x800a
|
|
/* 153d0: 8f39e3a8 */ lw $t9,-0x1c58($t9)
|
|
/* 153d4: 3c09800a */ lui $t1,0x800a
|
|
/* 153d8: 2529e1c0 */ addiu $t1,$t1,-7744
|
|
/* 153dc: 00194080 */ sll $t0,$t9,0x2
|
|
/* 153e0: 01194023 */ subu $t0,$t0,$t9
|
|
/* 153e4: 000840c0 */ sll $t0,$t0,0x3
|
|
/* 153e8: 3c04800a */ lui $a0,0x800a
|
|
/* 153ec: 2484e1c0 */ addiu $a0,$a0,-7744
|
|
/* 153f0: 01093821 */ addu $a3,$t0,$t1
|
|
/* 153f4: 00002825 */ or $a1,$zero,$zero
|
|
/* 153f8: 24060006 */ addiu $a2,$zero,0x6
|
|
.NB000153fc:
|
|
/* 153fc: 00a60019 */ multu $a1,$a2
|
|
/* 15400: 00001012 */ mflo $v0
|
|
/* 15404: 00e25021 */ addu $t2,$a3,$v0
|
|
/* 15408: 91430004 */ lbu $v1,0x4($t2)
|
|
/* 1540c: 1460000a */ bnez $v1,.NB00015438
|
|
/* 15410: 00000000 */ sll $zero,$zero,0x0
|
|
/* 15414: 8c8b01ec */ lw $t3,0x1ec($a0)
|
|
/* 15418: 000b6080 */ sll $t4,$t3,0x2
|
|
/* 1541c: 018b6023 */ subu $t4,$t4,$t3
|
|
/* 15420: 000c60c0 */ sll $t4,$t4,0x3
|
|
/* 15424: 008c6821 */ addu $t5,$a0,$t4
|
|
/* 15428: 01a27021 */ addu $t6,$t5,$v0
|
|
/* 1542c: 91cf0004 */ lbu $t7,0x4($t6)
|
|
/* 15430: 15e0000c */ bnez $t7,.NB00015464
|
|
/* 15434: 00000000 */ sll $zero,$zero,0x0
|
|
.NB00015438:
|
|
/* 15438: 1060000e */ beqz $v1,.NB00015474
|
|
/* 1543c: 24a50001 */ addiu $a1,$a1,0x1
|
|
/* 15440: 8c9801ec */ lw $t8,0x1ec($a0)
|
|
/* 15444: 0018c880 */ sll $t9,$t8,0x2
|
|
/* 15448: 0338c823 */ subu $t9,$t9,$t8
|
|
/* 1544c: 0019c8c0 */ sll $t9,$t9,0x3
|
|
/* 15450: 00994021 */ addu $t0,$a0,$t9
|
|
/* 15454: 01024821 */ addu $t1,$t0,$v0
|
|
/* 15458: 912a0004 */ lbu $t2,0x4($t1)
|
|
/* 1545c: 55400006 */ bnezl $t2,.NB00015478
|
|
/* 15460: 00055e00 */ sll $t3,$a1,0x18
|
|
.NB00015464:
|
|
/* 15464: 0c005332 */ jal joy00013e84
|
|
/* 15468: 00000000 */ sll $zero,$zero,0x0
|
|
/* 1546c: 10000006 */ beqz $zero,.NB00015488
|
|
/* 15470: 00000000 */ sll $zero,$zero,0x0
|
|
.NB00015474:
|
|
/* 15474: 00055e00 */ sll $t3,$a1,0x18
|
|
.NB00015478:
|
|
/* 15478: 000b2e03 */ sra $a1,$t3,0x18
|
|
/* 1547c: 28a10004 */ slti $at,$a1,0x4
|
|
/* 15480: 1420ffde */ bnez $at,.NB000153fc
|
|
/* 15484: 00000000 */ sll $zero,$zero,0x0
|
|
.NB00015488:
|
|
/* 15488: 3c04800a */ lui $a0,0x800a
|
|
/* 1548c: 2484e640 */ addiu $a0,$a0,-6592
|
|
/* 15490: 27a50034 */ addiu $a1,$sp,0x34
|
|
/* 15494: 0c01272c */ jal osSendMesg
|
|
/* 15498: 00003025 */ or $a2,$zero,$zero
|
|
/* 1549c: 3c038006 */ lui $v1,0x8006
|
|
/* 154a0: 24631258 */ addiu $v1,$v1,0x1258
|
|
/* 154a4: 8c6d0000 */ lw $t5,0x0($v1)
|
|
/* 154a8: 25ae0001 */ addiu $t6,$t5,0x1
|
|
/* 154ac: 1000008c */ beqz $zero,.NB000156e0
|
|
/* 154b0: ac6e0000 */ sw $t6,0x0($v1)
|
|
.NB000154b4:
|
|
/* 154b4: 3c04800a */ lui $a0,0x800a
|
|
/* 154b8: 2484e660 */ addiu $a0,$a0,-6560
|
|
/* 154bc: 27a50034 */ addiu $a1,$sp,0x34
|
|
/* 154c0: 0c0126b0 */ jal osRecvMesg
|
|
/* 154c4: 00003025 */ or $a2,$zero,$zero
|
|
/* 154c8: 14400013 */ bnez $v0,.NB00015518
|
|
/* 154cc: 3c038006 */ lui $v1,0x8006
|
|
/* 154d0: 24631258 */ addiu $v1,$v1,0x1258
|
|
/* 154d4: 8c6f0000 */ lw $t7,0x0($v1)
|
|
/* 154d8: 3c04800a */ lui $a0,0x800a
|
|
/* 154dc: 25f8ffff */ addiu $t8,$t7,-1
|
|
/* 154e0: 17000006 */ bnez $t8,.NB000154fc
|
|
/* 154e4: ac780000 */ sw $t8,0x0($v1)
|
|
/* 154e8: 0c0054b4 */ jal joyStartReadData
|
|
/* 154ec: 2484e5d8 */ addiu $a0,$a0,-6696
|
|
/* 154f0: 24080001 */ addiu $t0,$zero,0x1
|
|
/* 154f4: 3c018006 */ lui $at,0x8006
|
|
/* 154f8: ac281254 */ sw $t0,0x1254($at)
|
|
.NB000154fc:
|
|
/* 154fc: 3c04800a */ lui $a0,0x800a
|
|
/* 15500: 2484e680 */ addiu $a0,$a0,-6528
|
|
/* 15504: 27a50034 */ addiu $a1,$sp,0x34
|
|
/* 15508: 0c01272c */ jal osSendMesg
|
|
/* 1550c: 00003025 */ or $a2,$zero,$zero
|
|
/* 15510: 10000074 */ beqz $zero,.NB000156e4
|
|
/* 15514: 8fbf0014 */ lw $ra,0x14($sp)
|
|
.NB00015518:
|
|
/* 15518: 3c038006 */ lui $v1,0x8006
|
|
/* 1551c: 24631258 */ addiu $v1,$v1,0x1258
|
|
/* 15520: 8c690000 */ lw $t1,0x0($v1)
|
|
/* 15524: 3c0a8006 */ lui $t2,0x8006
|
|
/* 15528: 5520006e */ bnezl $t1,.NB000156e4
|
|
/* 1552c: 8fbf0014 */ lw $ra,0x14($sp)
|
|
/* 15530: 8d4a12a4 */ lw $t2,0x12a4($t2)
|
|
/* 15534: 3c04800a */ lui $a0,0x800a
|
|
/* 15538: 2484e5d8 */ addiu $a0,$a0,-6696
|
|
/* 1553c: 11400068 */ beqz $t2,.NB000156e0
|
|
/* 15540: 27a50034 */ addiu $a1,$sp,0x34
|
|
/* 15544: 0c0126b0 */ jal osRecvMesg
|
|
/* 15548: 00003025 */ or $a2,$zero,$zero
|
|
/* 1554c: 14400064 */ bnez $v0,.NB000156e0
|
|
/* 15550: 3c018006 */ lui $at,0x8006
|
|
/* 15554: 0c0054bc */ jal joyReadData
|
|
/* 15558: ac201254 */ sw $zero,0x1254($at)
|
|
/* 1555c: 3c0b800a */ lui $t3,0x800a
|
|
/* 15560: 8d6be3a8 */ lw $t3,-0x1c58($t3)
|
|
/* 15564: 3c0d800a */ lui $t5,0x800a
|
|
/* 15568: 25ade1c0 */ addiu $t5,$t5,-7744
|
|
/* 1556c: 000b6080 */ sll $t4,$t3,0x2
|
|
/* 15570: 018b6023 */ subu $t4,$t4,$t3
|
|
/* 15574: 000c60c0 */ sll $t4,$t4,0x3
|
|
/* 15578: 3c04800a */ lui $a0,0x800a
|
|
/* 1557c: 2484e1c0 */ addiu $a0,$a0,-7744
|
|
/* 15580: 018d3821 */ addu $a3,$t4,$t5
|
|
/* 15584: 00002825 */ or $a1,$zero,$zero
|
|
/* 15588: 24060006 */ addiu $a2,$zero,0x6
|
|
.NB0001558c:
|
|
/* 1558c: 00a60019 */ multu $a1,$a2
|
|
/* 15590: 00001012 */ mflo $v0
|
|
/* 15594: 00e27021 */ addu $t6,$a3,$v0
|
|
/* 15598: 91c30004 */ lbu $v1,0x4($t6)
|
|
/* 1559c: 1460000a */ bnez $v1,.NB000155c8
|
|
/* 155a0: 00000000 */ sll $zero,$zero,0x0
|
|
/* 155a4: 8c8f01ec */ lw $t7,0x1ec($a0)
|
|
/* 155a8: 000fc080 */ sll $t8,$t7,0x2
|
|
/* 155ac: 030fc023 */ subu $t8,$t8,$t7
|
|
/* 155b0: 0018c0c0 */ sll $t8,$t8,0x3
|
|
/* 155b4: 0098c821 */ addu $t9,$a0,$t8
|
|
/* 155b8: 03224021 */ addu $t0,$t9,$v0
|
|
/* 155bc: 91090004 */ lbu $t1,0x4($t0)
|
|
/* 155c0: 1520000c */ bnez $t1,.NB000155f4
|
|
/* 155c4: 00000000 */ sll $zero,$zero,0x0
|
|
.NB000155c8:
|
|
/* 155c8: 1060000e */ beqz $v1,.NB00015604
|
|
/* 155cc: 24a50001 */ addiu $a1,$a1,0x1
|
|
/* 155d0: 8c8a01ec */ lw $t2,0x1ec($a0)
|
|
/* 155d4: 000a5880 */ sll $t3,$t2,0x2
|
|
/* 155d8: 016a5823 */ subu $t3,$t3,$t2
|
|
/* 155dc: 000b58c0 */ sll $t3,$t3,0x3
|
|
/* 155e0: 008b6021 */ addu $t4,$a0,$t3
|
|
/* 155e4: 01826821 */ addu $t5,$t4,$v0
|
|
/* 155e8: 91ae0004 */ lbu $t6,0x4($t5)
|
|
/* 155ec: 55c00006 */ bnezl $t6,.NB00015608
|
|
/* 155f0: 00057e00 */ sll $t7,$a1,0x18
|
|
.NB000155f4:
|
|
/* 155f4: 0c005332 */ jal joy00013e84
|
|
/* 155f8: 00000000 */ sll $zero,$zero,0x0
|
|
/* 155fc: 10000006 */ beqz $zero,.NB00015618
|
|
/* 15600: 00000000 */ sll $zero,$zero,0x0
|
|
.NB00015604:
|
|
/* 15604: 00057e00 */ sll $t7,$a1,0x18
|
|
.NB00015608:
|
|
/* 15608: 000f2e03 */ sra $a1,$t7,0x18
|
|
/* 1560c: 28a10004 */ slti $at,$a1,0x4
|
|
/* 15610: 1420ffde */ bnez $at,.NB0001558c
|
|
/* 15614: 00000000 */ sll $zero,$zero,0x0
|
|
.NB00015618:
|
|
/* 15618: 0c005449 */ jal joy00014238
|
|
/* 1561c: 00000000 */ sll $zero,$zero,0x0
|
|
/* 15620: 0c005427 */ jal func0001509cnb
|
|
/* 15624: 00000000 */ sll $zero,$zero,0x0
|
|
/* 15628: 3c04800a */ lui $a0,0x800a
|
|
/* 1562c: 0c0054b4 */ jal joyStartReadData
|
|
/* 15630: 2484e5d8 */ addiu $a0,$a0,-6696
|
|
/* 15634: 3c038006 */ lui $v1,0x8006
|
|
/* 15638: 8c6312dc */ lw $v1,0x12dc($v1)
|
|
/* 1563c: 24190001 */ addiu $t9,$zero,0x1
|
|
/* 15640: 3c018006 */ lui $at,0x8006
|
|
/* 15644: ac391254 */ sw $t9,0x1254($at)
|
|
/* 15648: 3c018006 */ lui $at,0x8006
|
|
/* 1564c: 24630001 */ addiu $v1,$v1,0x1
|
|
/* 15650: ac2312dc */ sw $v1,0x12dc($at)
|
|
/* 15654: 2861003c */ slti $at,$v1,0x3c
|
|
/* 15658: 14200021 */ bnez $at,.NB000156e0
|
|
/* 1565c: 3c038006 */ lui $v1,0x8006
|
|
/* 15660: 3c048006 */ lui $a0,0x8006
|
|
/* 15664: 3c058006 */ lui $a1,0x8006
|
|
/* 15668: 3c028006 */ lui $v0,0x8006
|
|
/* 1566c: 3c068006 */ lui $a2,0x8006
|
|
/* 15670: 24c6129c */ addiu $a2,$a2,0x129c
|
|
/* 15674: 2442128c */ addiu $v0,$v0,0x128c
|
|
/* 15678: 24a5127c */ addiu $a1,$a1,0x127c
|
|
/* 1567c: 2484126c */ addiu $a0,$a0,0x126c
|
|
/* 15680: 2463125c */ addiu $v1,$v1,0x125c
|
|
.NB00015684:
|
|
/* 15684: 8c680000 */ lw $t0,0x0($v1)
|
|
/* 15688: 5500000b */ bnezl $t0,.NB000156b8
|
|
/* 1568c: ac600000 */ sw $zero,0x0($v1)
|
|
/* 15690: 8c890000 */ lw $t1,0x0($a0)
|
|
/* 15694: 55200008 */ bnezl $t1,.NB000156b8
|
|
/* 15698: ac600000 */ sw $zero,0x0($v1)
|
|
/* 1569c: 8caa0000 */ lw $t2,0x0($a1)
|
|
/* 156a0: 55400005 */ bnezl $t2,.NB000156b8
|
|
/* 156a4: ac600000 */ sw $zero,0x0($v1)
|
|
/* 156a8: 8c4b0000 */ lw $t3,0x0($v0)
|
|
/* 156ac: 51600006 */ beqzl $t3,.NB000156c8
|
|
/* 156b0: 24420004 */ addiu $v0,$v0,0x4
|
|
/* 156b4: ac600000 */ sw $zero,0x0($v1)
|
|
.NB000156b8:
|
|
/* 156b8: ac800000 */ sw $zero,0x0($a0)
|
|
/* 156bc: aca00000 */ sw $zero,0x0($a1)
|
|
/* 156c0: ac400000 */ sw $zero,0x0($v0)
|
|
/* 156c4: 24420004 */ addiu $v0,$v0,0x4
|
|
.NB000156c8:
|
|
/* 156c8: 24630004 */ addiu $v1,$v1,0x4
|
|
/* 156cc: 24840004 */ addiu $a0,$a0,0x4
|
|
/* 156d0: 1446ffec */ bne $v0,$a2,.NB00015684
|
|
/* 156d4: 24a50004 */ addiu $a1,$a1,0x4
|
|
/* 156d8: 3c018006 */ lui $at,0x8006
|
|
/* 156dc: ac2012dc */ sw $zero,0x12dc($at)
|
|
.NB000156e0:
|
|
/* 156e0: 8fbf0014 */ lw $ra,0x14($sp)
|
|
.NB000156e4:
|
|
/* 156e4: 27bd0038 */ addiu $sp,$sp,0x38
|
|
/* 156e8: 03e00008 */ jr $ra
|
|
/* 156ec: 00000000 */ sll $zero,$zero,0x0
|
|
);
|
|
#endif
|
|
|
|
void joy00014810(bool value)
|
|
{
|
|
var8005eec0 = value;
|
|
}
|
|
|
|
s32 joyGetNumSamples(void)
|
|
{
|
|
return (g_JoyDataPtr->curlast - g_JoyDataPtr->curstart + 20) % 20;
|
|
}
|
|
|
|
s32 joyGetStickXOnSample(s32 samplenum, s8 contpadnum)
|
|
{
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsStickX[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
return g_JoyDataPtr->samples[(g_JoyDataPtr->curstart + samplenum + 1) % 20].pads[contpadnum].stick_x;
|
|
}
|
|
|
|
s32 joyGetStickYOnSample(s32 samplenum, s8 contpadnum)
|
|
{
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsStickY[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
return g_JoyDataPtr->samples[(g_JoyDataPtr->curstart + samplenum + 1) % 20].pads[contpadnum].stick_y;
|
|
}
|
|
|
|
s32 joyGetStickYOnSampleIndex(s32 samplenum, s8 contpadnum)
|
|
{
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsStickY[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
return g_JoyDataPtr->samples[(g_JoyDataPtr->curstart + samplenum) % 20].pads[contpadnum].stick_y;
|
|
}
|
|
|
|
u16 joyGetButtonsOnSample(s32 samplenum, s8 contpadnum, u16 mask)
|
|
{
|
|
u16 button;
|
|
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsButtons[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
button = g_JoyDataPtr->samples[(g_JoyDataPtr->curstart + samplenum + 1) % 20].pads[contpadnum].button;
|
|
|
|
return button & mask;
|
|
}
|
|
|
|
u16 joyGetButtonsPressedOnSample(s32 samplenum, s8 contpadnum, u16 mask)
|
|
{
|
|
u16 button1;
|
|
u16 button2;
|
|
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsButtonsPressed[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
button1 = g_JoyDataPtr->samples[(g_JoyDataPtr->curstart + samplenum + 1) % 20].pads[contpadnum].button;
|
|
button2 = g_JoyDataPtr->samples[(g_JoyDataPtr->curstart + samplenum) % 20].pads[contpadnum].button;
|
|
|
|
return (button1 & ~button2) & mask;
|
|
}
|
|
|
|
/**
|
|
* Count the number of times the buttons specified by mask were held during the
|
|
* specific samples given in checksamples.
|
|
*
|
|
* For example, if checksamples[5] is nonzero and a button was pressed on
|
|
* samplenum 5 which matches the mask, count is incremented.
|
|
*/
|
|
s32 joyCountButtonsOnSpecificSamples(u32 *checksamples, s8 contpadnum, u16 mask)
|
|
{
|
|
s32 count = 0;
|
|
s32 index = 0;
|
|
s32 i;
|
|
u16 button;
|
|
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsButtons[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
i = (g_JoyDataPtr->curstart + 1) % 20;
|
|
|
|
while (true) {
|
|
if (checksamples == NULL || checksamples[index]) {
|
|
button = g_JoyDataPtr->samples[i].pads[contpadnum].button;
|
|
|
|
if (button & mask) {
|
|
count++;
|
|
}
|
|
}
|
|
|
|
if (i == g_JoyDataPtr->curlast) {
|
|
break;
|
|
}
|
|
|
|
i = (i + 1) % 20;
|
|
index++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
s8 joyGetStickX(s8 contpadnum)
|
|
{
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsStickX[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
return g_JoyDataPtr->samples[g_JoyDataPtr->curlast].pads[contpadnum].stick_x;
|
|
}
|
|
|
|
s8 joyGetStickY(s8 contpadnum)
|
|
{
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsStickY[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
return g_JoyDataPtr->samples[g_JoyDataPtr->curlast].pads[contpadnum].stick_y;
|
|
}
|
|
|
|
u16 joyGetButtons(s8 contpadnum, u16 mask)
|
|
{
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsButtons[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
return g_JoyDataPtr->samples[g_JoyDataPtr->curlast].pads[contpadnum].button & mask;
|
|
}
|
|
|
|
u16 joyGetButtonsPressedThisFrame(s8 contpadnum, u16 mask)
|
|
{
|
|
if (g_JoyDataPtr->unk200 < 0 && (g_JoyConnectedControllers >> contpadnum & 1) == 0) {
|
|
g_JoyBadReadsButtonsPressed[contpadnum]++;
|
|
return 0;
|
|
}
|
|
|
|
if (g_JoyDisableCooldown[contpadnum] > 0) {
|
|
return 0;
|
|
}
|
|
|
|
return g_JoyDataPtr->buttonspressed[contpadnum] & mask;
|
|
}
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
GLOBAL_ASM(
|
|
glabel func00015fa4nb
|
|
/* 15fa4: 3c038006 */ lui $v1,0x8006
|
|
/* 15fa8: 8c631250 */ lw $v1,0x1250($v1)
|
|
/* 15fac: afa40000 */ sw $a0,0x0($sp)
|
|
/* 15fb0: afa50004 */ sw $a1,0x4($sp)
|
|
/* 15fb4: 8c790200 */ lw $t9,0x200($v1)
|
|
/* 15fb8: 00047600 */ sll $t6,$a0,0x18
|
|
/* 15fbc: 000e7e03 */ sra $t7,$t6,0x18
|
|
/* 15fc0: 30b8ffff */ andi $t8,$a1,0xffff
|
|
/* 15fc4: 03002825 */ or $a1,$t8,$zero
|
|
/* 15fc8: 0721000f */ bgez $t9,.NB00016008
|
|
/* 15fcc: 01e02025 */ or $a0,$t7,$zero
|
|
/* 15fd0: 3c088006 */ lui $t0,0x8006
|
|
/* 15fd4: 9108129c */ lbu $t0,0x129c($t0)
|
|
/* 15fd8: 3c0c8006 */ lui $t4,0x8006
|
|
/* 15fdc: 258c128c */ addiu $t4,$t4,0x128c
|
|
/* 15fe0: 01e84807 */ srav $t1,$t0,$t7
|
|
/* 15fe4: 312a0001 */ andi $t2,$t1,0x1
|
|
/* 15fe8: 15400007 */ bnez $t2,.NB00016008
|
|
/* 15fec: 000f5880 */ sll $t3,$t7,0x2
|
|
/* 15ff0: 016c1821 */ addu $v1,$t3,$t4
|
|
/* 15ff4: 8c6d0000 */ lw $t5,0x0($v1)
|
|
/* 15ff8: 00001025 */ or $v0,$zero,$zero
|
|
/* 15ffc: 25ae0001 */ addiu $t6,$t5,0x1
|
|
/* 16000: 03e00008 */ jr $ra
|
|
/* 16004: ac6e0000 */ sw $t6,0x0($v1)
|
|
.NB00016008:
|
|
/* 16008: 00047880 */ sll $t7,$a0,0x2
|
|
/* 1600c: 3c18800a */ lui $t8,0x800a
|
|
/* 16010: 030fc021 */ addu $t8,$t8,$t7
|
|
/* 16014: 8f18e5c8 */ lw $t8,-0x1a38($t8)
|
|
/* 16018: 5b000004 */ blezl $t8,.NB0001602c
|
|
/* 1601c: 0004c840 */ sll $t9,$a0,0x1
|
|
/* 16020: 03e00008 */ jr $ra
|
|
/* 16024: 00001025 */ or $v0,$zero,$zero
|
|
/* 16028: 0004c840 */ sll $t9,$a0,0x1
|
|
.NB0001602c:
|
|
/* 1602c: 00794021 */ addu $t0,$v1,$t9
|
|
/* 16030: 950901f8 */ lhu $t1,0x1f8($t0)
|
|
/* 16034: 01251024 */ and $v0,$t1,$a1
|
|
/* 16038: 304affff */ andi $t2,$v0,0xffff
|
|
/* 1603c: 01401025 */ or $v0,$t2,$zero
|
|
/* 16040: 03e00008 */ jr $ra
|
|
/* 16044: 00000000 */ sll $zero,$zero,0x0
|
|
);
|
|
#endif
|
|
|
|
bool joyIsCyclicPollingEnabled(void)
|
|
{
|
|
return g_JoyCyclicPollDisableCount ? false : true;
|
|
}
|
|
|
|
/**
|
|
* If cyclic polling is enabled, send a message to the scheduler thread telling
|
|
* it to update the joy state (connected controllers, PFS etc). Then block while
|
|
* waiting for its done message to come back, and increment the disable count.
|
|
*
|
|
* If cyclic polling was already disabled, simply increase the disable count.
|
|
*/
|
|
void joyDisableCyclicPolling(
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void
|
|
#else
|
|
s32 line, char *file
|
|
#endif
|
|
)
|
|
{
|
|
OSMesg msg;
|
|
|
|
if (g_JoyCyclicPollDisableCount == 0) {
|
|
osSendMesg(&g_JoyStopCyclicPollingMesgQueue, &msg, OS_MESG_NOBLOCK);
|
|
osRecvMesg(&g_JoyStopCyclicPollingDoneMesgQueue, &msg, OS_MESG_BLOCK);
|
|
}
|
|
|
|
g_JoyCyclicPollDisableCount++;
|
|
}
|
|
|
|
/**
|
|
* Indicate that the caller is done with cyclic polling being disabled,
|
|
* and enable cyclic polling if there are no callers left who want it disabled.
|
|
*/
|
|
void joyEnableCyclicPolling(
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void
|
|
#else
|
|
s32 line, char *file
|
|
#endif
|
|
)
|
|
{
|
|
OSMesg msg;
|
|
|
|
g_JoyCyclicPollDisableCount--;
|
|
|
|
if (g_JoyCyclicPollDisableCount == 0) {
|
|
osSendMesg(&g_JoyStartCyclicPollingMesgQueue, &msg, OS_MESG_NOBLOCK);
|
|
osRecvMesg(&g_JoyStartCyclicPollingDoneMesgQueue, &msg, OS_MESG_BLOCK);
|
|
}
|
|
}
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
void joySetDataIndex(s32 arg0)
|
|
{
|
|
g_JoyDataPtr = &g_JoyData[arg0];
|
|
}
|
|
|
|
s32 joyGetDataIndex(void)
|
|
{
|
|
return g_JoyDataPtr - g_JoyData;
|
|
}
|
|
#endif
|
|
|
|
void joyDestroy(void)
|
|
{
|
|
s32 i;
|
|
|
|
osCreateMesgQueue(&g_PiMesgQueue, var80099e90, ARRAYCOUNT(var80099e90));
|
|
osSetEventMesg(OS_EVENT_SI, &g_PiMesgQueue, 0);
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (osMotorProbe(&g_PiMesgQueue, PFS(i), i) == 0) {
|
|
osMotorStop(PFS(i));
|
|
osMotorStop(PFS(i));
|
|
osMotorStop(PFS(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void joyGetContpadNumsForPlayer(s8 playernum, s32 *pad1, s32 *pad2)
|
|
{
|
|
if (g_Vars.normmplayerisrunning) {
|
|
*pad1 = g_Vars.playerstats[playernum].mpindex;
|
|
*pad2 = -1;
|
|
return;
|
|
}
|
|
|
|
*pad1 = playernum;
|
|
|
|
if (g_PlayerConfigsArray[g_Vars.playerstats[playernum].mpindex].controlmode >= CONTROLMODE_21) {
|
|
*pad2 = PLAYERCOUNT() + playernum;
|
|
return;
|
|
}
|
|
|
|
*pad2 = -1;
|
|
}
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
void joyStopRumble(s8 device, bool disablepolling)
|
|
{
|
|
u32 stack;
|
|
|
|
if (device != SAVEDEVICE_GAMEPAK) {
|
|
if (g_Paks[device].type != PAKTYPE_MEMORY && g_Paks[device].type != PAKTYPE_GAMEBOY) {
|
|
if (disablepolling) {
|
|
joyDisableCyclicPolling();
|
|
}
|
|
|
|
if (osMotorProbe(&g_PiMesgQueue, PFS(device), device) == 0) {
|
|
osMotorStop(PFS(device));
|
|
osMotorStop(PFS(device));
|
|
osMotorStop(PFS(device));
|
|
}
|
|
|
|
if (disablepolling) {
|
|
joyEnableCyclicPolling();
|
|
}
|
|
|
|
if (g_Paks[device].rumblestate != RUMBLESTATE_DISABLED_STOPPING
|
|
&& g_Paks[device].rumblestate != RUMBLESTATE_DISABLED_STOPPED) {
|
|
g_Paks[device].rumblestate = RUMBLESTATE_ENABLED_STOPPING;
|
|
}
|
|
|
|
g_Paks[device].rumblettl = -1;
|
|
}
|
|
}
|
|
|
|
if (device) {
|
|
// empty
|
|
}
|
|
}
|
|
#else
|
|
GLOBAL_ASM(
|
|
glabel joyStopRumble
|
|
/* 162b0: 27bdffd8 */ addiu $sp,$sp,-40
|
|
/* 162b4: 00047600 */ sll $t6,$a0,0x18
|
|
/* 162b8: 000e7e03 */ sra $t7,$t6,0x18
|
|
/* 162bc: 24010004 */ addiu $at,$zero,0x4
|
|
/* 162c0: afbf0014 */ sw $ra,0x14($sp)
|
|
/* 162c4: afa40028 */ sw $a0,0x28($sp)
|
|
/* 162c8: 11e10073 */ beq $t7,$at,.NB00016498
|
|
/* 162cc: afa5002c */ sw $a1,0x2c($sp)
|
|
/* 162d0: 3c06800a */ lui $a2,0x800a
|
|
/* 162d4: 00cf3021 */ addu $a2,$a2,$t7
|
|
/* 162d8: 90c6eb9c */ lbu $a2,-0x1464($a2)
|
|
/* 162dc: 3c19800a */ lui $t9,0x800a
|
|
/* 162e0: 27396870 */ addiu $t9,$t9,0x6870
|
|
/* 162e4: 0006c080 */ sll $t8,$a2,0x2
|
|
/* 162e8: 0306c023 */ subu $t8,$t8,$a2
|
|
/* 162ec: 0018c080 */ sll $t8,$t8,0x2
|
|
/* 162f0: 0306c023 */ subu $t8,$t8,$a2
|
|
/* 162f4: 0018c0c0 */ sll $t8,$t8,0x3
|
|
/* 162f8: 0306c021 */ addu $t8,$t8,$a2
|
|
/* 162fc: 0018c0c0 */ sll $t8,$t8,0x3
|
|
/* 16300: 03194021 */ addu $t0,$t8,$t9
|
|
/* 16304: afa8001c */ sw $t0,0x1c($sp)
|
|
/* 16308: 8d020000 */ lw $v0,0x0($t0)
|
|
/* 1630c: 24010002 */ addiu $at,$zero,0x2
|
|
/* 16310: 10410061 */ beq $v0,$at,.NB00016498
|
|
/* 16314: 24010003 */ addiu $at,$zero,0x3
|
|
/* 16318: 50410060 */ beql $v0,$at,.NB0001649c
|
|
/* 1631c: 8fbf0014 */ lw $ra,0x14($sp)
|
|
/* 16320: 10a00006 */ beqz $a1,.NB0001633c
|
|
/* 16324: 2404041e */ addiu $a0,$zero,0x41e
|
|
/* 16328: 3c057005 */ lui $a1,0x7005
|
|
/* 1632c: 24a55958 */ addiu $a1,$a1,0x5958
|
|
/* 16330: 0c00581b */ jal joyDisableCyclicPolling
|
|
/* 16334: afa60024 */ sw $a2,0x24($sp)
|
|
/* 16338: 8fa60024 */ lw $a2,0x24($sp)
|
|
.NB0001633c:
|
|
/* 1633c: 24010004 */ addiu $at,$zero,0x4
|
|
/* 16340: 14c10003 */ bne $a2,$at,.NB00016350
|
|
/* 16344: 3c04800a */ lui $a0,0x800a
|
|
/* 16348: 10000009 */ beqz $zero,.NB00016370
|
|
/* 1634c: 00003825 */ or $a3,$zero,$zero
|
|
.NB00016350:
|
|
/* 16350: 00065080 */ sll $t2,$a2,0x2
|
|
/* 16354: 01465023 */ subu $t2,$t2,$a2
|
|
/* 16358: 000a5080 */ sll $t2,$t2,0x2
|
|
/* 1635c: 01465021 */ addu $t2,$t2,$a2
|
|
/* 16360: 3c0b800a */ lui $t3,0x800a
|
|
/* 16364: 256b7658 */ addiu $t3,$t3,0x7658
|
|
/* 16368: 000a50c0 */ sll $t2,$t2,0x3
|
|
/* 1636c: 014b3821 */ addu $a3,$t2,$t3
|
|
.NB00016370:
|
|
/* 16370: 2484e5d8 */ addiu $a0,$a0,-6696
|
|
/* 16374: 00e02825 */ or $a1,$a3,$zero
|
|
/* 16378: 0c01440d */ jal osMotorProbe
|
|
/* 1637c: afa60024 */ sw $a2,0x24($sp)
|
|
/* 16380: 14400032 */ bnez $v0,.NB0001644c
|
|
/* 16384: 8fa60024 */ lw $a2,0x24($sp)
|
|
/* 16388: 24010004 */ addiu $at,$zero,0x4
|
|
/* 1638c: 14c10003 */ bne $a2,$at,.NB0001639c
|
|
/* 16390: 00002825 */ or $a1,$zero,$zero
|
|
/* 16394: 10000009 */ beqz $zero,.NB000163bc
|
|
/* 16398: 00003825 */ or $a3,$zero,$zero
|
|
.NB0001639c:
|
|
/* 1639c: 00066080 */ sll $t4,$a2,0x2
|
|
/* 163a0: 01866023 */ subu $t4,$t4,$a2
|
|
/* 163a4: 000c6080 */ sll $t4,$t4,0x2
|
|
/* 163a8: 01866021 */ addu $t4,$t4,$a2
|
|
/* 163ac: 3c0d800a */ lui $t5,0x800a
|
|
/* 163b0: 25ad7658 */ addiu $t5,$t5,0x7658
|
|
/* 163b4: 000c60c0 */ sll $t4,$t4,0x3
|
|
/* 163b8: 018d3821 */ addu $a3,$t4,$t5
|
|
.NB000163bc:
|
|
/* 163bc: 00e02025 */ or $a0,$a3,$zero
|
|
/* 163c0: 0c014370 */ jal __osMotorAccess
|
|
/* 163c4: afa60024 */ sw $a2,0x24($sp)
|
|
/* 163c8: 8fa60024 */ lw $a2,0x24($sp)
|
|
/* 163cc: 24010004 */ addiu $at,$zero,0x4
|
|
/* 163d0: 00002825 */ or $a1,$zero,$zero
|
|
/* 163d4: 14c10003 */ bne $a2,$at,.NB000163e4
|
|
/* 163d8: 00067080 */ sll $t6,$a2,0x2
|
|
/* 163dc: 10000008 */ beqz $zero,.NB00016400
|
|
/* 163e0: 00003825 */ or $a3,$zero,$zero
|
|
.NB000163e4:
|
|
/* 163e4: 01c67023 */ subu $t6,$t6,$a2
|
|
/* 163e8: 000e7080 */ sll $t6,$t6,0x2
|
|
/* 163ec: 01c67021 */ addu $t6,$t6,$a2
|
|
/* 163f0: 3c0f800a */ lui $t7,0x800a
|
|
/* 163f4: 25ef7658 */ addiu $t7,$t7,0x7658
|
|
/* 163f8: 000e70c0 */ sll $t6,$t6,0x3
|
|
/* 163fc: 01cf3821 */ addu $a3,$t6,$t7
|
|
.NB00016400:
|
|
/* 16400: 00e02025 */ or $a0,$a3,$zero
|
|
/* 16404: 0c014370 */ jal __osMotorAccess
|
|
/* 16408: afa60024 */ sw $a2,0x24($sp)
|
|
/* 1640c: 8fa60024 */ lw $a2,0x24($sp)
|
|
/* 16410: 24010004 */ addiu $at,$zero,0x4
|
|
/* 16414: 00002825 */ or $a1,$zero,$zero
|
|
/* 16418: 14c10003 */ bne $a2,$at,.NB00016428
|
|
/* 1641c: 0006c080 */ sll $t8,$a2,0x2
|
|
/* 16420: 10000008 */ beqz $zero,.NB00016444
|
|
/* 16424: 00003825 */ or $a3,$zero,$zero
|
|
.NB00016428:
|
|
/* 16428: 0306c023 */ subu $t8,$t8,$a2
|
|
/* 1642c: 0018c080 */ sll $t8,$t8,0x2
|
|
/* 16430: 0306c021 */ addu $t8,$t8,$a2
|
|
/* 16434: 3c19800a */ lui $t9,0x800a
|
|
/* 16438: 27397658 */ addiu $t9,$t9,0x7658
|
|
/* 1643c: 0018c0c0 */ sll $t8,$t8,0x3
|
|
/* 16440: 03193821 */ addu $a3,$t8,$t9
|
|
.NB00016444:
|
|
/* 16444: 0c014370 */ jal __osMotorAccess
|
|
/* 16448: 00e02025 */ or $a0,$a3,$zero
|
|
.NB0001644c:
|
|
/* 1644c: 8fa8002c */ lw $t0,0x2c($sp)
|
|
/* 16450: 2404042a */ addiu $a0,$zero,0x42a
|
|
/* 16454: 3c057005 */ lui $a1,0x7005
|
|
/* 16458: 51000004 */ beqzl $t0,.NB0001646c
|
|
/* 1645c: 8fa3001c */ lw $v1,0x1c($sp)
|
|
/* 16460: 0c005834 */ jal joyEnableCyclicPolling
|
|
/* 16464: 24a55960 */ addiu $a1,$a1,0x5960
|
|
/* 16468: 8fa3001c */ lw $v1,0x1c($sp)
|
|
.NB0001646c:
|
|
/* 1646c: 24010006 */ addiu $at,$zero,0x6
|
|
/* 16470: 8c620004 */ lw $v0,0x4($v1)
|
|
/* 16474: 10410004 */ beq $v0,$at,.NB00016488
|
|
/* 16478: 24010007 */ addiu $at,$zero,0x7
|
|
/* 1647c: 10410002 */ beq $v0,$at,.NB00016488
|
|
/* 16480: 24090005 */ addiu $t1,$zero,0x5
|
|
/* 16484: ac690004 */ sw $t1,0x4($v1)
|
|
.NB00016488:
|
|
/* 16488: 3c01bf80 */ lui $at,0xbf80
|
|
/* 1648c: 44812000 */ mtc1 $at,$f4
|
|
/* 16490: 00000000 */ sll $zero,$zero,0x0
|
|
/* 16494: e46402b4 */ swc1 $f4,0x2b4($v1)
|
|
.NB00016498:
|
|
/* 16498: 8fbf0014 */ lw $ra,0x14($sp)
|
|
.NB0001649c:
|
|
/* 1649c: 27bd0028 */ addiu $sp,$sp,0x28
|
|
/* 164a0: 03e00008 */ jr $ra
|
|
/* 164a4: 00000000 */ sll $zero,$zero,0x0
|
|
);
|
|
#endif
|
|
|
|
s32 joy000155b4(s8 device)
|
|
{
|
|
return g_Paks[device].unk010;
|
|
}
|
|
|
|
s32 joy000155f4(s8 device)
|
|
{
|
|
return joy000155b4(device);
|
|
}
|
|
|
|
void joysTickRumble(void)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < 4; i++) {
|
|
if (g_Paks[i].unk010 == PAK010_11 && g_Paks[i].type == PAKTYPE_RUMBLE) {
|
|
switch (g_Paks[i].rumblestate) {
|
|
case RUMBLESTATE_ENABLED_STARTING:
|
|
g_Paks[i].rumblestate = RUMBLESTATE_ENABLED_RUMBLING;
|
|
osMotorStart(PFS(i));
|
|
break;
|
|
case RUMBLESTATE_ENABLED_RUMBLING:
|
|
if (g_Paks[i].rumblepulsestopat != -1) {
|
|
if (g_Paks[i].rumblepulsetimer == 0) {
|
|
osMotorStart(PFS(i));
|
|
} else if (g_Paks[i].rumblepulsestopat == g_Paks[i].rumblepulsetimer) {
|
|
osMotorStop(PFS(i));
|
|
}
|
|
|
|
g_Paks[i].rumblepulsetimer++;
|
|
|
|
if (g_Paks[i].rumblepulselen == g_Paks[i].rumblepulsetimer) {
|
|
g_Paks[i].rumblepulsetimer = 0;
|
|
}
|
|
}
|
|
|
|
g_Paks[i].rumblettl--;
|
|
|
|
if (g_Paks[i].rumblettl < 0) {
|
|
g_Paks[i].rumblestate = RUMBLESTATE_ENABLED_STOPPING;
|
|
}
|
|
break;
|
|
case RUMBLESTATE_ENABLED_STOPPING:
|
|
g_Paks[i].rumblestate = RUMBLESTATE_ENABLED_STOPPED;
|
|
osMotorStop(PFS(i));
|
|
break;
|
|
case RUMBLESTATE_DISABLED_STOPPING:
|
|
osMotorStop(PFS(i));
|
|
g_Paks[i].rumblestate = RUMBLESTATE_DISABLED_STOPPED;
|
|
break;
|
|
case RUMBLESTATE_ENABLING:
|
|
g_Paks[i].rumblestate = RUMBLESTATE_ENABLED_STOPPED;
|
|
g_Paks[i].rumblettl = -1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|