blob: 5c1afd84279fbdef03f49dcf4554c846d75354cf (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
#include "m/m_pad.h"
#include "common.h"
#include "d/d_pad.h"
#include "egg/core/eggController.h"
#include "egg/math/eggVector.h"
#include "rvl/WPAD.h" // IWYU pragma: export
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::instance();
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->isConnected()) {
// These sort of look like value, first order derivative, and second order derivative
// So perhaps value, velocity, acceleration?
EGG::Vector2f pos = ctl->getCoreStatus()->getAccelVertical();
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->getCoreStatus()->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->dpd = FALSE;
info->speaker = FALSE;
info->attach = FALSE;
info->lowBat = FALSE;
info->nearempty = FALSE;
info->battery = 0;
info->led = 0;
info->protocol = 0;
info->firmware = 0;
}
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);
}
}
static int getWPADInfoCB(int controller) {
int result = WPADGetInfoAsync(controller, &s_WPADInfoTmp[controller], async_info_callback);
if (result == -1) {
clearWPADInfo(controller);
}
return result;
}
} // namespace mPad
|