WiimoteReal: hidapi: Add support for the Balance Board
A name change isn't enough for the DolphinBar; we have to actually query the Wiimote to know if the Wiimote is a Balance Board.
This commit is contained in:
parent
d9a9e34994
commit
132ca8d02c
|
@ -70,17 +70,17 @@ void WiimoteScannerHidapi::FindWiimotes(std::vector<Wiimote*>& wiimotes, Wiimote
|
|||
if (!is_wiimote || s_known_paths.count(device->path) != 0 || !IsDeviceUsable(device->path))
|
||||
continue;
|
||||
|
||||
const bool is_balance_board = IsBalanceBoardName(name);
|
||||
NOTICE_LOG(WIIMOTE, "Found %s at %s: %ls %ls (%04hx:%04hx)",
|
||||
is_balance_board ? "balance board" : "Wiimote", device->path,
|
||||
device->manufacturer_string, device->product_string, device->vendor_id,
|
||||
device->product_id);
|
||||
|
||||
Wiimote* wiimote = new WiimoteHidapi(device->path);
|
||||
auto* wiimote = new WiimoteHidapi(device->path);
|
||||
const bool is_balance_board = IsBalanceBoardName(name) || wiimote->IsBalanceBoard();
|
||||
if (is_balance_board)
|
||||
board = wiimote;
|
||||
else
|
||||
wiimotes.push_back(wiimote);
|
||||
|
||||
NOTICE_LOG(WIIMOTE, "Found %s at %s: %ls %ls (%04hx:%04hx)",
|
||||
is_balance_board ? "balance board" : "Wiimote", device->path,
|
||||
device->manufacturer_string, device->product_string, device->vendor_id,
|
||||
device->product_id);
|
||||
}
|
||||
hid_free_enumeration(list);
|
||||
}
|
||||
|
@ -98,6 +98,9 @@ WiimoteHidapi::~WiimoteHidapi()
|
|||
|
||||
bool WiimoteHidapi::ConnectInternal()
|
||||
{
|
||||
if (m_handle != nullptr)
|
||||
return true;
|
||||
|
||||
m_handle = hid_open_path(m_device_path.c_str());
|
||||
if (m_handle == nullptr)
|
||||
{
|
||||
|
|
|
@ -242,6 +242,71 @@ bool Wiimote::Write()
|
|||
return ret != 0;
|
||||
}
|
||||
|
||||
bool Wiimote::IsBalanceBoard()
|
||||
{
|
||||
if (!ConnectInternal())
|
||||
return false;
|
||||
// Initialise the extension by writing 0x55 to 0xa400f0, then writing 0x00 to 0xa400fb.
|
||||
static const u8 init_extension_rpt1[MAX_PAYLOAD] = {
|
||||
WM_SET_REPORT | WM_BT_OUTPUT, WM_WRITE_DATA, 0x04, 0xa4, 0x00, 0xf0, 0x01, 0x55};
|
||||
static const u8 init_extension_rpt2[MAX_PAYLOAD] = {
|
||||
WM_SET_REPORT | WM_BT_OUTPUT, WM_WRITE_DATA, 0x04, 0xa4, 0x00, 0xfb, 0x01, 0x00};
|
||||
static const u8 status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0};
|
||||
if (!IOWrite(init_extension_rpt1, sizeof(init_extension_rpt1)) ||
|
||||
!IOWrite(init_extension_rpt2, sizeof(init_extension_rpt2)))
|
||||
{
|
||||
ERROR_LOG(WIIMOTE, "IsBalanceBoard(): Failed to initialise extension.");
|
||||
return false;
|
||||
}
|
||||
|
||||
int ret = IOWrite(status_report, sizeof(status_report));
|
||||
u8 buf[MAX_PAYLOAD];
|
||||
while (ret != 0)
|
||||
{
|
||||
ret = IORead(buf);
|
||||
if (ret == -1)
|
||||
continue;
|
||||
|
||||
switch (buf[1])
|
||||
{
|
||||
case WM_STATUS_REPORT:
|
||||
{
|
||||
const auto* status = reinterpret_cast<wm_status_report*>(&buf[2]);
|
||||
// A Balance Board has a Balance Board extension.
|
||||
if (!status->extension)
|
||||
return false;
|
||||
// Read two bytes from 0xa400fe to identify the extension.
|
||||
static const u8 identify_ext_rpt[] = {
|
||||
WM_SET_REPORT | WM_BT_OUTPUT, WM_READ_DATA, 0x04, 0xa4, 0x00, 0xfe, 0x02, 0x00};
|
||||
ret = IOWrite(identify_ext_rpt, sizeof(identify_ext_rpt));
|
||||
break;
|
||||
}
|
||||
case WM_READ_DATA_REPLY:
|
||||
{
|
||||
const auto* reply = reinterpret_cast<wm_read_data_reply*>(&buf[2]);
|
||||
if (Common::swap16(reply->address) != 0x00fe)
|
||||
{
|
||||
ERROR_LOG(WIIMOTE, "IsBalanceBoard(): Received unexpected data reply for address %X",
|
||||
Common::swap16(reply->address));
|
||||
return false;
|
||||
}
|
||||
// A Balance Board ext can be identified by checking for 0x0402.
|
||||
return reply->data[0] == 0x04 && reply->data[1] == 0x02;
|
||||
}
|
||||
case WM_ACK_DATA:
|
||||
{
|
||||
const auto* ack = reinterpret_cast<wm_acknowledge*>(&buf[2]);
|
||||
if (ack->reportID == WM_READ_DATA && ack->errorID != 0x00)
|
||||
{
|
||||
WARN_LOG(WIIMOTE, "Failed to read from 0xa400fe, assuming Wiimote is not a Balance Board.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool IsDataReport(const Report& rpt)
|
||||
{
|
||||
return rpt.size() >= 2 && rpt[1] >= WM_REPORT_CORE;
|
||||
|
|
|
@ -41,6 +41,8 @@ public:
|
|||
void Read();
|
||||
bool Write();
|
||||
|
||||
bool IsBalanceBoard();
|
||||
|
||||
void StartThread();
|
||||
void StopThread();
|
||||
|
||||
|
|
Loading…
Reference in New Issue