This commit is contained in:
Jack Andersen 2017-01-28 17:56:39 -10:00
commit 4be38afef3
1 changed files with 80 additions and 79 deletions

View File

@ -9,31 +9,25 @@ namespace boo
* Reference: https://github.com/ToadKing/wii-u-gc-adapter/blob/master/wii-u-gc-adapter.c * Reference: https://github.com/ToadKing/wii-u-gc-adapter/blob/master/wii-u-gc-adapter.c
*/ */
DolphinSmashAdapter::DolphinSmashAdapter(DeviceToken* token) DolphinSmashAdapter::DolphinSmashAdapter(DeviceToken* token) : DeviceBase(token) {}
: DeviceBase(token)
{
}
DolphinSmashAdapter::~DolphinSmashAdapter() DolphinSmashAdapter::~DolphinSmashAdapter() {}
{
}
static inline EDolphinControllerType parseType(unsigned char status) static inline EDolphinControllerType parseType(unsigned char status)
{ {
EDolphinControllerType type = EDolphinControllerType(status) & EDolphinControllerType type =
(EDolphinControllerType::Normal | EDolphinControllerType::Wavebird); EDolphinControllerType(status) & (EDolphinControllerType::Normal | EDolphinControllerType::Wavebird);
switch (type) switch (type)
{ {
case EDolphinControllerType::Normal: case EDolphinControllerType::Normal:
case EDolphinControllerType::Wavebird: case EDolphinControllerType::Wavebird:
return type; return type;
default: default:
return EDolphinControllerType::None; return EDolphinControllerType::None;
} }
} }
static inline EDolphinControllerType static inline EDolphinControllerType parseState(DolphinControllerState* stateOut, uint8_t* payload, bool& rumble)
parseState(DolphinControllerState* stateOut, uint8_t* payload, bool& rumble)
{ {
memset(stateOut, 0, sizeof(DolphinControllerState)); memset(stateOut, 0, sizeof(DolphinControllerState));
unsigned char status = payload[0]; unsigned char status = payload[0];
@ -43,10 +37,10 @@ parseState(DolphinControllerState* stateOut, uint8_t* payload, bool& rumble)
stateOut->m_btns = (uint16_t)payload[1] << 8 | (uint16_t)payload[2]; stateOut->m_btns = (uint16_t)payload[1] << 8 | (uint16_t)payload[2];
stateOut->m_leftStick[0] = payload[3]; stateOut->m_leftStick[0] = payload[4];
stateOut->m_leftStick[1] = payload[4]; stateOut->m_leftStick[1] = payload[3];
stateOut->m_rightStick[0] = payload[5]; stateOut->m_rightStick[0] = payload[6];
stateOut->m_rightStick[1] = payload[6]; stateOut->m_rightStick[1] = payload[5];
stateOut->m_analogTriggers[0] = payload[7]; stateOut->m_analogTriggers[0] = payload[7];
stateOut->m_analogTriggers[1] = payload[8]; stateOut->m_analogTriggers[1] = payload[8];
@ -65,7 +59,7 @@ void DolphinSmashAdapter::transferCycle()
size_t recvSz = receiveUSBInterruptTransfer(payload, sizeof(payload)); size_t recvSz = receiveUSBInterruptTransfer(payload, sizeof(payload));
if (recvSz != 37 || payload[0] != 0x21) if (recvSz != 37 || payload[0] != 0x21)
return; return;
//printf("RECEIVED DATA %zu %02X\n", recvSz, payload[0]); // printf("RECEIVED DATA %zu %02X\n", recvSz, payload[0]);
if (!m_callback) if (!m_callback)
return; return;
@ -73,24 +67,24 @@ void DolphinSmashAdapter::transferCycle()
/* Parse controller states */ /* Parse controller states */
uint8_t* controller = &payload[1]; uint8_t* controller = &payload[1];
uint8_t rumbleMask = 0; uint8_t rumbleMask = 0;
for (int i=0 ; i<4 ; i++, controller += 9) for (int i = 0; i < 4; i++, controller += 9)
{ {
DolphinControllerState state; DolphinControllerState state;
bool rumble = false; bool rumble = false;
EDolphinControllerType type = parseState(&state, controller, rumble); EDolphinControllerType type = parseState(&state, controller, rumble);
if (type != EDolphinControllerType::None && !(m_knownControllers & 1<<i)) if (type != EDolphinControllerType::None && !(m_knownControllers & 1 << i))
{ {
m_knownControllers |= 1<<i; m_knownControllers |= 1 << i;
m_callback->controllerConnected(i, type); m_callback->controllerConnected(i, type);
} }
else if (type == EDolphinControllerType::None && (m_knownControllers & 1<<i)) else if (type == EDolphinControllerType::None && (m_knownControllers & 1 << i))
{ {
m_knownControllers &= ~(1<<i); m_knownControllers &= ~(1 << i);
m_callback->controllerDisconnected(i); m_callback->controllerDisconnected(i);
} }
if (m_knownControllers & 1<<i) if (m_knownControllers & 1 << i)
m_callback->controllerUpdate(i, type, state); m_callback->controllerUpdate(i, type, state);
rumbleMask |= rumble ? 1<<i : 0; rumbleMask |= rumble ? 1 << i : 0;
} }
/* Send rumble message (if needed) */ /* Send rumble message (if needed) */
@ -98,14 +92,14 @@ void DolphinSmashAdapter::transferCycle()
if (rumbleReq != m_rumbleState) if (rumbleReq != m_rumbleState)
{ {
uint8_t rumbleMessage[5] = {0x11}; uint8_t rumbleMessage[5] = {0x11};
for (int i=0 ; i<4 ; ++i) for (int i = 0; i < 4; ++i)
{ {
if (rumbleReq & 1<<i) if (rumbleReq & 1 << i)
rumbleMessage[i+1] = 1; rumbleMessage[i + 1] = 1;
else if (m_hardStop[i]) else if (m_hardStop[i])
rumbleMessage[i+1] = 2; rumbleMessage[i + 1] = 2;
else else
rumbleMessage[i+1] = 0; rumbleMessage[i + 1] = 0;
} }
sendUSBInterruptTransfer(rumbleMessage, sizeof(rumbleMessage)); sendUSBInterruptTransfer(rumbleMessage, sizeof(rumbleMessage));
@ -123,11 +117,11 @@ void DolphinSmashAdapter::deviceDisconnected()
{ {
if (!m_callback) if (!m_callback)
return; return;
for (int i=0 ; i<4 ; i++) for (int i = 0; i < 4; i++)
{ {
if (m_knownControllers & 1<<i) if (m_knownControllers & 1 << i)
{ {
m_knownControllers &= ~(1<<i); m_knownControllers &= ~(1 << i);
m_callback->controllerDisconnected(i); m_callback->controllerDisconnected(i);
} }
} }
@ -161,21 +155,26 @@ static uint8_t pad_clampregion[8] = {30, 180, 15, 72, 40, 15, 59, 31};
static void pad_clampstick(int8_t& px, int8_t& py, int8_t max, int8_t xy, int8_t min) static void pad_clampstick(int8_t& px, int8_t& py, int8_t max, int8_t xy, int8_t min)
{ {
int32_t x, y, signX, signY, d; int x = px;
int y = py;
int signX;
int signY;
int d;
x = px; if (x > 0)
y = py; {
if (x >= 0)
signX = 1; signX = 1;
}
else else
{ {
signX = -1; signX = -1;
x = -x; x = -x;
} }
if (y >= 0) if (y > 0)
{
signY = 1; signY = 1;
}
else else
{ {
signY = -1; signY = -1;
@ -188,40 +187,41 @@ static void pad_clampstick(int8_t& px, int8_t& py, int8_t max, int8_t xy, int8_t
x -= min; x -= min;
if (y <= min) if (y <= min)
y = 0;
else
y -= min;
if (x || y)
{ {
int32_t xx, yy, maxy; y = 0;
xx = x * xy;
yy = y * xy;
maxy = max * xy;
if (yy <= xx)
{
d = (x * xy + (y * (max - xy)));
if (maxy < d)
{
x *= maxy / d;
y *= maxy / d;
}
}
else
{
d = (y * xy + (x * (max - xy)));
if (maxy < d)
{
x *= maxy / d;
y *= maxy / d;
}
}
px = int8_t(x * signX);
py = int8_t(y * signY);
} }
else else
{
y -= min;
}
if (x == 0 && y == 0)
{
px = py = 0; px = py = 0;
return;
}
if (xy * y <= xy * x)
{
d = xy * x + (max - xy) * y;
if (xy * max < d)
{
x = int8_t(xy * max * x / d);
y = int8_t(xy * max * y / d);
}
}
else
{
d = xy * y + (max - xy) * x;
if (xy * max < d)
{
x = int8_t(xy * max * x / d);
y = int8_t(xy * max * y / d);
}
}
px = int8_t(signX * x);
py = int8_t(signY * y);
} }
static void pad_clamptrigger(uint8_t& trigger) static void pad_clamptrigger(uint8_t& trigger)
@ -232,10 +232,12 @@ static void pad_clamptrigger(uint8_t& trigger)
max = pad_clampregion[1]; max = pad_clampregion[1];
if (min > trigger) if (min > trigger)
trigger = 0; trigger = 0;
else if (max < trigger)
trigger = max - min;
else else
{
if (max < trigger)
trigger = max - min;
trigger -= min; trigger -= min;
}
} }
void DolphinControllerState::clamp() void DolphinControllerState::clamp()
@ -245,5 +247,4 @@ void DolphinControllerState::clamp()
pad_clamptrigger(m_analogTriggers[0]); pad_clamptrigger(m_analogTriggers[0]);
pad_clamptrigger(m_analogTriggers[1]); pad_clamptrigger(m_analogTriggers[1]);
} }
} }