summaryrefslogtreecommitdiff
path: root/src/libultra_code_O2/osRumblePak.c
diff options
context:
space:
mode:
authorRandom <28494085+Random06457@users.noreply.github.com>2020-10-03 17:22:44 +0200
committerGitHub <noreply@github.com>2020-10-03 11:22:44 -0400
commit174af7384d1cfcbf15da02d9069bf02bdc433c20 (patch)
treee4fb18346f71047c123ec4d34a80ae7e4d8ab9ea /src/libultra_code_O2/osRumblePak.c
parent6136ee6debd570a63fc695a6f4664553303f2324 (diff)
libultra cleanup (#215)
* cleanup libultra * fixes - use quotes instead of <> for includes - add macros for zelda specific thread priorities - fix Makefile - properly format the remaining pfs structs * fix button macros + add CHECK_BTN_ANY/CHECK_BTN_ALL * remove ULTRA_ABS * fix includes * update z_player.c/z_lib.c + run format.sh * merge upstream/master * fix include in En_Goroiwa * fix includes
Diffstat (limited to 'src/libultra_code_O2/osRumblePak.c')
-rw-r--r--src/libultra_code_O2/osRumblePak.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/src/libultra_code_O2/osRumblePak.c b/src/libultra_code_O2/osRumblePak.c
new file mode 100644
index 000000000..96e86c4df
--- /dev/null
+++ b/src/libultra_code_O2/osRumblePak.c
@@ -0,0 +1,115 @@
+#include "global.h"
+
+#define BANK_ADDR 0x400
+#define MOTOR_ID 0x80
+
+OSPifRam osPifBuffers[MAXCONTROLLERS];
+
+// func_800CF990 in 1.0
+s32 osSetRumble(OSPfs* pfs, u32 vibrate) {
+ s32 i;
+ s32 ret;
+ u8* buf;
+
+ buf = (u8*)&osPifBuffers[pfs->channel];
+ if (!(pfs->status & 8)) {
+ return 5;
+ }
+ __osSiGetAccess();
+ osPifBuffers[pfs->channel].status = 1;
+ buf += pfs->channel;
+ for (i = 0; i < BLOCKSIZE; i++) {
+ ((__OSContRamHeader*)buf)->data[i] = vibrate;
+ }
+
+ __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;
+ if (!ret) {
+ if (!vibrate) {
+ if (((__OSContRamHeader*)buf)->datacrc != 0) {
+ ret = PFS_ERR_CONTRFAIL;
+ }
+ } else {
+ if (((__OSContRamHeader*)buf)->datacrc != 0xEB) {
+ ret = PFS_ERR_CONTRFAIL;
+ }
+ }
+ }
+ __osSiRelAccess();
+ return ret;
+}
+
+void osSetUpMempakWrite(s32 channel, OSPifRam* buf) {
+ u8* bufptr = (u8*)buf;
+ __OSContRamHeader mempakwr;
+ s32 i;
+ mempakwr.unk_00 = 0xFF;
+ mempakwr.txsize = 0x23;
+ mempakwr.rxsize = 1;
+ mempakwr.poll = 3; // write mempak
+ mempakwr.hi = 0x600 >> 3;
+ mempakwr.lo = (u8)(__osContAddressCrc(0x600) | (0x600 << 5));
+ if (channel != 0) {
+ for (i = 0; i < channel; ++i) {
+ *bufptr++ = 0;
+ }
+ }
+ *(__OSContRamHeader*)bufptr = mempakwr;
+ bufptr += sizeof(mempakwr);
+ *bufptr = 0xFE;
+}
+
+s32 osProbeRumblePak(OSMesgQueue* ctrlrqueue, OSPfs* pfs, u32 channel) {
+ s32 ret;
+ u8 sp24[BLOCKSIZE];
+
+ pfs->queue = ctrlrqueue;
+ pfs->channel = channel;
+ pfs->activebank = 0xFF;
+ pfs->status = 0;
+
+ ret = __osPfsSelectBank(pfs, 0xFE);
+ if (ret == 2) {
+ ret = __osPfsSelectBank(pfs, MOTOR_ID);
+ }
+ if (ret != 0) {
+ return ret;
+ }
+ ret = __osContRamRead(ctrlrqueue, channel, BANK_ADDR, sp24);
+ ret = ret;
+ if (ret == 2) {
+ ret = 4; // "Controller pack communication error"
+ }
+ if (ret != 0) {
+ return ret;
+ }
+ if (sp24[BLOCKSIZE - 1] == 0xFE) {
+ return 0xB;
+ }
+ ret = __osPfsSelectBank(pfs, MOTOR_ID);
+ if (ret == 2) {
+ ret = 4; // "Controller pack communication error"
+ }
+ if (ret != 0) {
+ return ret;
+ }
+ ret = __osContRamRead(ctrlrqueue, channel, BANK_ADDR, sp24);
+ if (ret == 2) {
+ ret = 4; // "Controller pack communication error"
+ }
+ if (ret != 0) {
+ return ret;
+ }
+ if (sp24[BLOCKSIZE - 1] != MOTOR_ID) {
+ return 0xB;
+ }
+ if ((pfs->status & PFS_MOTOR_INITIALIZED) == 0) {
+ osSetUpMempakWrite(channel, &osPifBuffers[channel]);
+ }
+ pfs->status = PFS_MOTOR_INITIALIZED;
+ return 0; // "Recognized rumble pak"
+}