boo/lib/inputdev/DolphinSmashAdapter.cpp

124 lines
3.2 KiB
C++
Raw Normal View History

2015-08-18 22:43:30 +00:00
#include "boo/inputdev/DolphinSmashAdapter.hpp"
2015-04-22 21:48:23 +00:00
#include <stdio.h>
2015-04-24 00:24:15 +00:00
#include <string.h>
2015-04-22 21:48:23 +00:00
2015-04-29 10:24:39 +00:00
namespace boo
{
/*
* Reference: https://github.com/ToadKing/wii-u-gc-adapter/blob/master/wii-u-gc-adapter.c
2015-04-24 00:24:15 +00:00
*/
2015-08-18 19:40:26 +00:00
DolphinSmashAdapter::DolphinSmashAdapter(DeviceToken* token)
: DeviceBase(token),
2015-04-24 00:24:15 +00:00
m_callback(NULL),
m_knownControllers(0),
m_rumbleRequest(0),
m_rumbleState(0)
2015-04-22 21:48:23 +00:00
{
}
2015-08-18 19:40:26 +00:00
DolphinSmashAdapter::~DolphinSmashAdapter()
{
2015-04-24 00:24:15 +00:00
}
2015-04-29 10:24:39 +00:00
static inline EDolphinControllerType parseType(unsigned char status)
2015-04-24 00:24:15 +00:00
{
2015-04-29 10:24:39 +00:00
unsigned char type = status & (DOL_TYPE_NORMAL | DOL_TYPE_WAVEBIRD);
2015-04-24 00:24:15 +00:00
switch (type)
{
2015-04-29 10:24:39 +00:00
case DOL_TYPE_NORMAL:
case DOL_TYPE_WAVEBIRD:
return (EDolphinControllerType)type;
2015-04-24 00:24:15 +00:00
default:
2015-04-29 10:24:39 +00:00
return DOL_TYPE_NONE;
2015-04-24 00:24:15 +00:00
}
}
2015-04-29 10:24:39 +00:00
static inline EDolphinControllerType
2015-08-18 19:40:26 +00:00
parseState(DolphinControllerState* stateOut, uint8_t* payload, bool& rumble)
2015-04-24 00:24:15 +00:00
{
2015-08-18 19:40:26 +00:00
memset(stateOut, 0, sizeof(DolphinControllerState));
2015-04-24 00:24:15 +00:00
unsigned char status = payload[0];
2015-04-29 10:24:39 +00:00
EDolphinControllerType type = parseType(status);
2015-04-24 00:24:15 +00:00
rumble = ((status & 0x04) != 0) ? true : false;
2015-04-24 00:24:15 +00:00
stateOut->m_btns = (uint16_t)payload[1] << 8 | (uint16_t)payload[2];
stateOut->m_leftStick[0] = payload[3];
2015-04-26 08:25:44 +00:00
stateOut->m_leftStick[1] = payload[4];
2015-04-24 00:24:15 +00:00
stateOut->m_rightStick[0] = payload[5];
2015-04-26 08:25:44 +00:00
stateOut->m_rightStick[1] = payload[6];
2015-04-24 00:24:15 +00:00
stateOut->m_analogTriggers[0] = payload[7];
stateOut->m_analogTriggers[1] = payload[8];
return type;
2015-04-22 21:48:23 +00:00
}
2015-08-18 19:40:26 +00:00
void DolphinSmashAdapter::initialCycle()
2015-05-04 04:28:07 +00:00
{
uint8_t handshakePayload[] = {0x13};
2015-05-10 07:02:18 +00:00
sendUSBInterruptTransfer(handshakePayload, sizeof(handshakePayload));
2015-05-04 04:28:07 +00:00
}
2015-08-18 19:40:26 +00:00
void DolphinSmashAdapter::transferCycle()
2015-04-24 00:24:15 +00:00
{
uint8_t payload[37];
2015-05-10 07:02:18 +00:00
size_t recvSz = receiveUSBInterruptTransfer(payload, sizeof(payload));
if (recvSz != 37 || payload[0] != 0x21)
return;
//printf("RECEIVED DATA %zu %02X\n", recvSz, payload[0]);
if (!m_callback)
return;
/* Parse controller states */
uint8_t* controller = &payload[1];
uint8_t rumbleMask = 0;
for (int i=0 ; i<4 ; i++, controller += 9)
2015-04-24 00:24:15 +00:00
{
2015-08-18 19:40:26 +00:00
DolphinControllerState state;
bool rumble = false;
EDolphinControllerType type = parseState(&state, controller, rumble);
if (type && !(m_knownControllers & 1<<i))
2015-04-24 00:24:15 +00:00
{
m_knownControllers |= 1<<i;
m_callback->controllerConnected(i, type);
2015-04-24 00:24:15 +00:00
}
else if (!type && (m_knownControllers & 1<<i))
2015-04-24 00:24:15 +00:00
{
m_knownControllers &= ~(1<<i);
m_callback->controllerDisconnected(i, type);
2015-04-24 00:24:15 +00:00
}
if (m_knownControllers & 1<<i)
m_callback->controllerUpdate(i, type, state);
rumbleMask |= rumble ? 1<<i : 0;
}
/* Send rumble message (if needed) */
uint8_t rumbleReq = m_rumbleRequest & rumbleMask;
if (rumbleReq != m_rumbleState)
{
uint8_t rumbleMessage[5] = {0x11};
for (int i=0 ; i<4 ; ++i)
2015-05-15 01:16:36 +00:00
rumbleMessage[i+1] = (rumbleReq & 1<<i);
2015-05-10 07:02:18 +00:00
sendUSBInterruptTransfer(rumbleMessage, sizeof(rumbleMessage));
m_rumbleState = rumbleReq;
2015-04-24 00:24:15 +00:00
}
}
2015-08-18 19:40:26 +00:00
void DolphinSmashAdapter::finalCycle()
2015-04-26 08:25:44 +00:00
{
uint8_t rumbleMessage[5] = {0x11, 0, 0, 0, 0};
2015-05-10 07:02:18 +00:00
sendUSBInterruptTransfer(rumbleMessage, sizeof(rumbleMessage));
}
2015-04-26 08:25:44 +00:00
2015-08-18 19:40:26 +00:00
void DolphinSmashAdapter::deviceDisconnected()
{
}
2015-04-29 10:24:39 +00:00
}