summaryrefslogtreecommitdiff
path: root/src/m/m_pad.cpp
diff options
context:
space:
mode:
authorElijah Thomas <42302100+elijah-thomas774@users.noreply.github.com>2024-05-31 20:10:22 -0400
committerGitHub <noreply@github.com>2024-05-31 20:10:22 -0400
commitfda931e2aead6b77c099f0e09d34ebd17c2d238c (patch)
tree513414b3df3ead1c84b02e72808253d2069728ac /src/m/m_pad.cpp
parentbc9eaa1ca985315386ceed621c9fb64fc88d4eac (diff)
parent35a4b294a158286fb1b44241914b780abecde9d2 (diff)
Merge pull request #47 from robojumper/m_pad
m_pad
Diffstat (limited to 'src/m/m_pad.cpp')
-rw-r--r--src/m/m_pad.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/src/m/m_pad.cpp b/src/m/m_pad.cpp
new file mode 100644
index 00000000..3b880d96
--- /dev/null
+++ b/src/m/m_pad.cpp
@@ -0,0 +1,148 @@
+#include <common.h>
+#include <egg/core/eggController.h>
+#include <egg/math/eggVector.h>
+#include <m/m_pad.h>
+#include <rvl/WPAD.h>
+
+namespace mPad {
+
+EGG::CoreControllerMgr *g_padMg;
+int g_currentCoreId;
+EGG::CoreController *g_currentCore;
+EGG::CoreController *g_core[4];
+
+static bool g_IsConnected[4];
+static u32 g_PadFrame;
+
+static bool s_WPADInfoAvailable[4];
+static u32 s_GetWPADInfoInterval = 0;
+static u32 s_GetWPADInfoCount = 0;
+
+
+struct PadAdditionalData_t {
+ PadAdditionalData_t() {}
+ ~PadAdditionalData_t() {}
+
+ EGG::Vector2f v1;
+ EGG::Vector2f v2;
+ EGG::Vector2f v3;
+};
+
+static PadAdditionalData_t g_PadAdditionalData[4];
+static WPADInfo s_WPADInfo[4];
+static WPADInfo s_WPADInfoTmp[4];
+
+static void initWPADInfo();
+static void clearWPADInfo(int);
+static int getWPADInfoCB(int controller);
+
+void create() {
+ g_padMg = EGG::CoreControllerMgr::sInstance;
+ initWPADInfo();
+ beginPad();
+ endPad();
+}
+
+// This code looks really bad.
+// It mostly matches when writing it the obvious way
+// (just indexing the arrays normally)
+// but has an annoying regshuffle
+void beginPad() {
+
+ g_PadFrame++;
+ g_padMg->beginFrame();
+
+ EGG::CoreController *ctl;
+ EGG::CoreController **p_ctl = g_core;
+ PadAdditionalData_t *dat = g_PadAdditionalData;
+ bool *connected;
+ int i = 0;
+ connected = g_IsConnected;
+
+ for (; i < 4; i++) {
+ ctl = g_padMg->getNthController(i);
+ *p_ctl = ctl;
+ if (ctl->mFlag.onBit(0)) {
+ // These sort of look like value, first order derivative, and second order derivative
+ // So perhaps value, velocity, acceleration?
+ EGG::Vector2f pos = ctl->coreStatus[0].getUnk();
+ EGG::Vector2f v = pos - dat->v1;
+ dat->v1 = pos;
+ dat->v3 = v - dat->v2;
+ dat->v2 = v;
+
+ if (!*connected) {
+ *connected = true;
+ }
+
+ // Not sure why this checks the controller index against the tick count
+ if (s_GetWPADInfoInterval != 0 &&
+ ((s_GetWPADInfoInterval == 1 || s_GetWPADInfoCount == i) ||
+ (s_GetWPADInfoInterval <= 3 && (s_GetWPADInfoCount & 1) == (i & 1)))) {
+ getWPADInfoCB(i);
+ }
+ } else if (*connected) {
+ ctl->coreStatus->init();
+ ctl->sceneReset();
+ dat->v1.x = 0.0f;
+ dat->v1.y = 0.0f;
+ dat->v3.x = 0.0f;
+ dat->v3.y = 0.0f;
+ dat->v2.x = 0.0f;
+ dat->v2.y = 0.0f;
+ clearWPADInfo(i);
+ *connected = false;
+ }
+
+ p_ctl++;
+ dat++;
+ connected++;
+ }
+
+ if (s_GetWPADInfoInterval != 0) {
+ s_GetWPADInfoCount++;
+ if (s_GetWPADInfoCount > s_GetWPADInfoInterval) {
+ s_GetWPADInfoCount = 0;
+ }
+ }
+ g_currentCore = g_core[g_currentCoreId];
+}
+
+void endPad() {
+ g_padMg->endFrame();
+}
+
+static inline void clear(WPADInfo *info) {
+ info->field_0x00 = 0;
+ info->field_0x04 = 0;
+ info->field_0x08 = 0;
+ info->field_0x0C = 0;
+ info->field_0x10 = 0;
+ info->field_0x14 = false;
+ info->field_0x15 = false;
+ info->field_0x16 = false;
+ info->field_0x17 = false;
+}
+
+static void clearWPADInfo(int controller) {
+ s_WPADInfoAvailable[controller] = false;
+ clear(&s_WPADInfo[controller]);
+}
+
+static void initWPADInfo() {
+ for (int i = 0; i < 4; i++) {
+ clearWPADInfo(i);
+ }
+}
+
+extern "C" void fn_80058DA0(s32, s32);
+
+static int getWPADInfoCB(int controller) {
+ int result = WPADGetInfoAsync(controller, &s_WPADInfoTmp[controller], fn_80058DA0);
+ if (result == -1) {
+ clearWPADInfo(controller);
+ }
+ return result;
+}
+
+} // namespace mPad