1
0
mirror of https://github.com/zeldaret/oot.git synced 2024-09-23 13:54:44 +00:00
oot/src/libultra_code/osRumblePak.c

118 lines
3.0 KiB
C
Raw Normal View History

2020-03-17 04:31:30 +00:00
#include <ultra64.h>
#include <global.h>
#include <ultra64/controller.h>
#define BANK_ADDR 0x400
#define MOTOR_ID 0x80
OSPifRam osPifBuffers[MAXCONTROLLERS];
2020-03-17 04:31:30 +00:00
2020-03-22 21:19:43 +00:00
// func_800CF990 in 1.0
s32 osSetRumble(OSPfs* pfs, u32 vibrate) {
2020-03-17 04:31:30 +00:00
s32 i;
s32 ret;
2020-03-22 21:19:43 +00:00
u8* buf;
buf = (u8*)&osPifBuffers[pfs->channel];
if (!(pfs->status & 8)) {
2020-03-17 04:31:30 +00:00
return 5;
}
__osSiGetAccess();
osPifBuffers[pfs->channel].status = 1;
buf += pfs->channel;
for (i = 0; i < BLOCKSIZE; i++) {
((__OSContRamHeader*)buf)->data[i] = vibrate;
2020-03-17 04:31:30 +00:00
}
2020-03-22 21:19:43 +00:00
__osContLastPoll = CONT_CMD_END;
__osSiRawStartDma(OS_WRITE, &osPifBuffers[pfs->channel]);
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
__osSiRawStartDma(OS_READ, &osPifBuffers[pfs->channel]);
osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK);
ret = ((__OSContRamHeader*)buf)->rxsize & 0xC0;
2020-03-17 04:31:30 +00:00
if (!ret) {
if (!vibrate) {
if (((__OSContRamHeader*)buf)->datacrc != 0) {
ret = PFS_ERR_CONTRFAIL;
2020-03-17 04:31:30 +00:00
}
2020-03-22 21:19:43 +00:00
} else {
if (((__OSContRamHeader*)buf)->datacrc != 0xEB) {
ret = PFS_ERR_CONTRFAIL;
2020-03-17 04:31:30 +00:00
}
}
}
__osSiRelAccess();
return ret;
}
void osSetUpMempakWrite(s32 channel, OSPifRam* buf) {
u8* bufptr = (u8*)buf;
__OSContRamHeader mempakwr;
2020-03-17 04:31:30 +00:00
s32 i;
mempakwr.unk_00 = 0xFF;
mempakwr.txsize = 0x23;
mempakwr.rxsize = 1;
mempakwr.poll = 3; // write mempak
mempakwr.hi = 0x600 >> 3;
mempakwr.lo = (u8)(osMempakAddrCRC(0x600) | (0x600 << 5));
if (channel != 0) {
for (i = 0; i < channel; ++i) {
*bufptr++ = 0;
2020-03-17 04:31:30 +00:00
}
}
*(__OSContRamHeader*)bufptr = mempakwr;
bufptr += sizeof(mempakwr);
*bufptr = 0xFE;
2020-03-17 04:31:30 +00:00
}
s32 osProbeRumblePak(OSMesgQueue* ctrlrqueue, OSPfs* pfs, u32 channel) {
2020-03-17 04:31:30 +00:00
s32 ret;
u8 sp24[BLOCKSIZE];
2020-03-22 21:19:43 +00:00
pfs->queue = ctrlrqueue;
pfs->channel = channel;
pfs->activebank = 0xFF;
pfs->status = 0;
2020-03-22 21:19:43 +00:00
ret = func_80104C80(pfs, 0xFE);
2020-03-22 21:19:43 +00:00
if (ret == 2) {
ret = func_80104C80(pfs, MOTOR_ID);
2020-03-17 04:31:30 +00:00
}
2020-03-22 21:19:43 +00:00
if (ret != 0) {
2020-03-17 04:31:30 +00:00
return ret;
}
ret = osReadMempak(ctrlrqueue, channel, BANK_ADDR, sp24);
2020-03-17 04:31:30 +00:00
ret = ret;
2020-03-22 21:19:43 +00:00
if (ret == 2) {
ret = 4; // "Controller pack communication error"
2020-03-17 04:31:30 +00:00
}
2020-03-22 21:19:43 +00:00
if (ret != 0) {
2020-03-17 04:31:30 +00:00
return ret;
}
if (sp24[BLOCKSIZE - 1] == 0xFE) {
return 0xB;
2020-03-17 04:31:30 +00:00
}
ret = func_80104C80(pfs, MOTOR_ID);
2020-03-22 21:19:43 +00:00
if (ret == 2) {
ret = 4; // "Controller pack communication error"
2020-03-17 04:31:30 +00:00
}
2020-03-22 21:19:43 +00:00
if (ret != 0) {
2020-03-17 04:31:30 +00:00
return ret;
}
ret = osReadMempak(ctrlrqueue, channel, BANK_ADDR, sp24);
2020-03-22 21:19:43 +00:00
if (ret == 2) {
ret = 4; // "Controller pack communication error"
2020-03-17 04:31:30 +00:00
}
2020-03-22 21:19:43 +00:00
if (ret != 0) {
2020-03-17 04:31:30 +00:00
return ret;
}
if (sp24[BLOCKSIZE - 1] != MOTOR_ID) {
return 0xB;
2020-03-17 04:31:30 +00:00
}
if ((pfs->status & PFS_MOTOR_INITIALIZED) == 0) {
osSetUpMempakWrite(channel, &osPifBuffers[channel]);
2020-03-17 04:31:30 +00:00
}
pfs->status = PFS_MOTOR_INITIALIZED;
return 0; // "Recognized rumble pak"
2020-03-17 04:31:30 +00:00
}