Merge pull request #661 from delroth/dolphinbar

Fix WiiMote issues causing DolphinBar to not work
This commit is contained in:
Pierre Bourdon 2014-07-23 05:26:38 +02:00
commit 257d2a6faf
1 changed files with 34 additions and 28 deletions

View File

@ -140,7 +140,7 @@ namespace WiimoteReal
{ {
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len); int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written);
int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index); int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index);
void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read); void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read);
@ -257,26 +257,8 @@ int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, size_t size, int at
for (; attempts>0; --attempts) for (; attempts>0; --attempts)
{ {
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size)) if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size, &written))
{ break;
auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
if (WAIT_TIMEOUT == wait_result)
{
WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A timeout occurred on writing to Wiimote.");
CancelIo(dev_handle);
continue;
}
else if (WAIT_FAILED == wait_result)
{
WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A wait error occurred on writing to Wiimote.");
CancelIo(dev_handle);
continue;
}
if (GetOverlappedResult(dev_handle, &hid_overlap_write, &written, TRUE))
{
break;
}
}
} }
CloseHandle(hid_overlap_write.hEvent); CloseHandle(hid_overlap_write.hEvent);
@ -640,7 +622,7 @@ int Wiimote::IORead(u8* buf)
} }
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len) int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, size_t len, DWORD* written)
{ {
WiimoteEmu::Spy(nullptr, buf, len); WiimoteEmu::Spy(nullptr, buf, len);
@ -650,11 +632,11 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
{ {
// Try to auto-detect the stack type // Try to auto-detect the stack type
stack = MSBT_STACK_BLUESOLEIL; stack = MSBT_STACK_BLUESOLEIL;
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len)) if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written))
return 1; return 1;
stack = MSBT_STACK_MS; stack = MSBT_STACK_MS;
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len)) if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len, written))
return 1; return 1;
stack = MSBT_STACK_UNKNOWN; stack = MSBT_STACK_UNKNOWN;
@ -673,12 +655,17 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
// Semaphore timeout // Semaphore timeout
NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote"); NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote");
} }
else else if (err != 0x1F) // Some third-party adapters (DolphinBar) use this
// error code to signal the absence of a WiiMote
// linked to the HID device.
{ {
WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err); WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err);
} }
} }
if (written)
*written = (result ? (DWORD)len : 0);
return result; return result;
} }
case MSBT_STACK_BLUESOLEIL: case MSBT_STACK_BLUESOLEIL:
@ -695,7 +682,26 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
DWORD bytes = 0; DWORD bytes = 0;
if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write)) if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write))
{ {
// WriteFile always returns true with bluesoleil. // If the number of written bytes is requested, block until we can provide
// this information to the called.
if (written)
{
auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
if (WAIT_TIMEOUT == wait_result)
{
WARN_LOG(WIIMOTE, "_IOWrite: A timeout occurred on writing to Wiimote.");
CancelIo(dev_handle);
*written = 0;
}
else if (WAIT_FAILED == wait_result)
{
WARN_LOG(WIIMOTE, "_IOWrite: A wait error occurred on writing to Wiimote.");
CancelIo(dev_handle);
*written = 0;
}
else if (!GetOverlappedResult(dev_handle, &hid_overlap_write, written, TRUE))
*written = 0;
}
return 1; return 1;
} }
else else
@ -705,8 +711,8 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
{ {
CancelIo(dev_handle); CancelIo(dev_handle);
} }
return 0;
} }
break;
} }
} }
@ -715,7 +721,7 @@ int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stac
int Wiimote::IOWrite(const u8* buf, size_t len) int Wiimote::IOWrite(const u8* buf, size_t len)
{ {
return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len); return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len, nullptr);
} }
// invokes callback for each found wiimote bluetooth device // invokes callback for each found wiimote bluetooth device