mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-03-01 19:13:38 +00:00
Merge branch 'real-wiimote-minor-fixes'
This commit is contained in:
commit
53368823cb
@ -36,15 +36,16 @@ public:
|
|||||||
return (0 == m_size);
|
return (0 == m_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& Front() const
|
T& Front() const
|
||||||
{
|
{
|
||||||
return *m_read_ptr->current;
|
return *m_read_ptr->current;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Push(const T& t)
|
template <typename Arg>
|
||||||
|
void Push(Arg&& t)
|
||||||
{
|
{
|
||||||
// create the element, add it to the queue
|
// create the element, add it to the queue
|
||||||
m_write_ptr->current = new T(t);
|
m_write_ptr->current = new T(std::forward<Arg>(t));
|
||||||
// set the next pointer to a new element ptr
|
// set the next pointer to a new element ptr
|
||||||
// then advance the write pointer
|
// then advance the write pointer
|
||||||
m_write_ptr = m_write_ptr->next = new ElementPtr();
|
m_write_ptr = m_write_ptr->next = new ElementPtr();
|
||||||
@ -67,7 +68,7 @@ public:
|
|||||||
if (Empty())
|
if (Empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
t = Front();
|
t = std::move(Front());
|
||||||
Pop();
|
Pop();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -707,10 +707,10 @@ void Wiimote::Update()
|
|||||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||||
if (g_wiimotes[m_index])
|
if (g_wiimotes[m_index])
|
||||||
{
|
{
|
||||||
Report rpt = g_wiimotes[m_index]->ProcessReadQueue();
|
const Report& rpt = g_wiimotes[m_index]->ProcessReadQueue();
|
||||||
const u8 *real_data = rpt.first;
|
if (!rpt.empty())
|
||||||
if (real_data)
|
|
||||||
{
|
{
|
||||||
|
const u8 *real_data = rpt.data();
|
||||||
switch (real_data[1])
|
switch (real_data[1])
|
||||||
{
|
{
|
||||||
// use data reports
|
// use data reports
|
||||||
@ -770,13 +770,9 @@ void Wiimote::Update()
|
|||||||
// copy over report from real-wiimote
|
// copy over report from real-wiimote
|
||||||
if (-1 == rptf_size)
|
if (-1 == rptf_size)
|
||||||
{
|
{
|
||||||
memcpy(data, real_data, rpt.second);
|
std::copy(rpt.begin(), rpt.end(), data);
|
||||||
rptf_size = rpt.second;
|
rptf_size = rpt.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (real_data != g_wiimotes[m_index]->\
|
|
||||||
m_last_data_report.first)
|
|
||||||
delete[] real_data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -370,73 +370,55 @@ bool Wiimote::IsConnected() const
|
|||||||
// zero = error
|
// zero = error
|
||||||
int Wiimote::IORead(u8* buf)
|
int Wiimote::IORead(u8* buf)
|
||||||
{
|
{
|
||||||
// used below for a warning
|
// Add data report indicator byte (here, 0xa1)
|
||||||
*buf = 0;
|
buf[0] = 0xa1;
|
||||||
|
// Used below for a warning
|
||||||
|
buf[1] = 0;
|
||||||
|
|
||||||
DWORD bytes;
|
DWORD bytes = 0;
|
||||||
ResetEvent(hid_overlap_read.hEvent);
|
ResetEvent(hid_overlap_read.hEvent);
|
||||||
if (!ReadFile(dev_handle, buf, MAX_PAYLOAD - 1, &bytes, &hid_overlap_read))
|
if (!ReadFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_read))
|
||||||
{
|
{
|
||||||
auto const err = GetLastError();
|
auto const read_err = GetLastError();
|
||||||
|
|
||||||
if (ERROR_IO_PENDING == err)
|
if (ERROR_IO_PENDING == read_err)
|
||||||
{
|
{
|
||||||
auto const r = WaitForSingleObject(hid_overlap_read.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
|
auto const wait_result = WaitForSingleObject(hid_overlap_read.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
|
||||||
if (WAIT_TIMEOUT == r)
|
if (WAIT_TIMEOUT == wait_result)
|
||||||
{
|
{
|
||||||
// Timeout - cancel and continue
|
CancelIo(dev_handle);
|
||||||
if (*buf)
|
}
|
||||||
|
else if (WAIT_FAILED == wait_result)
|
||||||
|
{
|
||||||
|
WARN_LOG(WIIMOTE, "A wait error occurred on reading from Wiimote %i.", index + 1);
|
||||||
|
CancelIo(dev_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GetOverlappedResult(dev_handle, &hid_overlap_read, &bytes, TRUE))
|
||||||
|
{
|
||||||
|
auto const overlapped_err = GetLastError();
|
||||||
|
|
||||||
|
if (ERROR_OPERATION_ABORTED == overlapped_err)
|
||||||
|
{
|
||||||
|
if (buf[1] != 0)
|
||||||
WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).",
|
WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).",
|
||||||
WIIMOTE_DEFAULT_TIMEOUT);
|
WIIMOTE_DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
CancelIo(dev_handle);
|
return -1;
|
||||||
bytes = -1;
|
|
||||||
}
|
}
|
||||||
else if (WAIT_FAILED == r)
|
|
||||||
{
|
WARN_LOG(WIIMOTE, "GetOverlappedResult error %d on Wiimote %i.", overlapped_err, index + 1);
|
||||||
WARN_LOG(WIIMOTE, "A wait error occurred on reading from Wiimote %i.", index + 1);
|
return 0;
|
||||||
bytes = 0;
|
|
||||||
}
|
|
||||||
else if (WAIT_OBJECT_0 == r)
|
|
||||||
{
|
|
||||||
if (!GetOverlappedResult(dev_handle, &hid_overlap_read, &bytes, TRUE))
|
|
||||||
{
|
|
||||||
WARN_LOG(WIIMOTE, "GetOverlappedResult failed on Wiimote %i.", index + 1);
|
|
||||||
bytes = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bytes = 0;
|
WARN_LOG(WIIMOTE, "ReadFile error %d on Wiimote %i.", read_err, index + 1);
|
||||||
}
|
return 0;
|
||||||
}
|
|
||||||
else if (ERROR_HANDLE_EOF == err)
|
|
||||||
{
|
|
||||||
// Remote disconnect
|
|
||||||
bytes = 0;
|
|
||||||
}
|
|
||||||
else if (ERROR_DEVICE_NOT_CONNECTED == err)
|
|
||||||
{
|
|
||||||
// Remote disconnect
|
|
||||||
bytes = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bytes = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes > 0)
|
return bytes + 1;
|
||||||
{
|
|
||||||
// Move the data over one, so we can add back in data report indicator byte (here, 0xa1)
|
|
||||||
std::copy_n(buf, MAX_PAYLOAD - 1, buf + 1);
|
|
||||||
buf[0] = 0xa1;
|
|
||||||
|
|
||||||
// TODO: is this really needed?
|
|
||||||
bytes = MAX_PAYLOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Wiimote::IOWrite(const u8* buf, int len)
|
int Wiimote::IOWrite(const u8* buf, int len)
|
||||||
|
@ -57,7 +57,7 @@ Wiimote::Wiimote()
|
|||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
, dev_handle(0), stack(MSBT_STACK_UNKNOWN)
|
, dev_handle(0), stack(MSBT_STACK_UNKNOWN)
|
||||||
#endif
|
#endif
|
||||||
, m_last_data_report(Report((u8 *)NULL, 0))
|
, m_last_input_report()
|
||||||
, m_channel(0), m_run_thread(false)
|
, m_channel(0), m_run_thread(false)
|
||||||
{
|
{
|
||||||
#if defined(__linux__) && HAVE_BLUEZ
|
#if defined(__linux__) && HAVE_BLUEZ
|
||||||
@ -73,11 +73,7 @@ Wiimote::~Wiimote()
|
|||||||
Disconnect();
|
Disconnect();
|
||||||
|
|
||||||
ClearReadQueue();
|
ClearReadQueue();
|
||||||
|
m_write_reports.Clear();
|
||||||
// clear write queue
|
|
||||||
Report rpt;
|
|
||||||
while (m_write_reports.Pop(rpt))
|
|
||||||
delete[] rpt.first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// to be called from CPU thread
|
// to be called from CPU thread
|
||||||
@ -85,17 +81,18 @@ void Wiimote::QueueReport(u8 rpt_id, const void* _data, unsigned int size)
|
|||||||
{
|
{
|
||||||
auto const data = static_cast<const u8*>(_data);
|
auto const data = static_cast<const u8*>(_data);
|
||||||
|
|
||||||
Report rpt;
|
Report rpt(size + 2);
|
||||||
rpt.second = size + 2;
|
rpt[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
||||||
rpt.first = new u8[rpt.second];
|
rpt[1] = rpt_id;
|
||||||
rpt.first[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
std::copy_n(data, size, rpt.begin() + 2);
|
||||||
rpt.first[1] = rpt_id;
|
m_write_reports.Push(std::move(rpt));
|
||||||
std::copy(data, data + size, rpt.first + 2);
|
|
||||||
m_write_reports.Push(rpt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::DisableDataReporting()
|
void Wiimote::DisableDataReporting()
|
||||||
{
|
{
|
||||||
|
m_last_input_report.clear();
|
||||||
|
|
||||||
|
// This probably accomplishes nothing.
|
||||||
wm_report_mode rpt = {};
|
wm_report_mode rpt = {};
|
||||||
rpt.mode = WM_REPORT_CORE;
|
rpt.mode = WM_REPORT_CORE;
|
||||||
rpt.all_the_time = 0;
|
rpt.all_the_time = 0;
|
||||||
@ -108,14 +105,9 @@ void Wiimote::ClearReadQueue()
|
|||||||
{
|
{
|
||||||
Report rpt;
|
Report rpt;
|
||||||
|
|
||||||
if (m_last_data_report.first)
|
// The "Clear" function isn't thread-safe :/
|
||||||
{
|
|
||||||
delete[] m_last_data_report.first;
|
|
||||||
m_last_data_report.first = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (m_read_reports.Pop(rpt))
|
while (m_read_reports.Pop(rpt))
|
||||||
delete[] rpt.first;
|
{}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::ControlChannel(const u16 channel, const void* const data, const u32 size)
|
void Wiimote::ControlChannel(const u16 channel, const void* const data, const u32 size)
|
||||||
@ -148,65 +140,58 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const _data, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto const data = static_cast<const u8*>(_data);
|
auto const data = static_cast<const u8*>(_data);
|
||||||
|
Report rpt(data, data + size);
|
||||||
Report rpt;
|
|
||||||
rpt.first = new u8[size];
|
|
||||||
rpt.second = (u8)size;
|
|
||||||
std::copy(data, data + size, rpt.first);
|
|
||||||
|
|
||||||
// Convert output DATA packets to SET_REPORT packets.
|
// Convert output DATA packets to SET_REPORT packets.
|
||||||
// Nintendo Wiimotes work without this translation, but 3rd
|
// Nintendo Wiimotes work without this translation, but 3rd
|
||||||
// party ones don't.
|
// party ones don't.
|
||||||
if (rpt.first[0] == 0xa2)
|
if (rpt[0] == 0xa2)
|
||||||
{
|
{
|
||||||
rpt.first[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
rpt[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disallow games from turning off all of the LEDs.
|
// Disallow games from turning off all of the LEDs.
|
||||||
// It makes Wiimote connection status confusing.
|
// It makes Wiimote connection status confusing.
|
||||||
if (rpt.first[1] == WM_LEDS)
|
if (rpt[1] == WM_LEDS)
|
||||||
{
|
{
|
||||||
auto& leds_rpt = *reinterpret_cast<wm_leds*>(&rpt.first[2]);
|
auto& leds_rpt = *reinterpret_cast<wm_leds*>(&rpt[2]);
|
||||||
if (0 == leds_rpt.leds)
|
if (0 == leds_rpt.leds)
|
||||||
{
|
{
|
||||||
// Turn on ALL of the LEDs.
|
// Turn on ALL of the LEDs.
|
||||||
leds_rpt.leds = 0xf;
|
leds_rpt.leds = 0xf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (rpt.first[1] == WM_WRITE_SPEAKER_DATA
|
else if (rpt[1] == WM_WRITE_SPEAKER_DATA
|
||||||
&& !SConfig::GetInstance().m_WiimoteEnableSpeaker)
|
&& !SConfig::GetInstance().m_WiimoteEnableSpeaker)
|
||||||
{
|
{
|
||||||
// Translate speaker data reports into rumble reports.
|
// Translate speaker data reports into rumble reports.
|
||||||
rpt.first[1] = WM_CMD_RUMBLE;
|
rpt[1] = WM_RUMBLE;
|
||||||
// Keep only the rumble bit.
|
// Keep only the rumble bit.
|
||||||
rpt.first[2] &= 0x1;
|
rpt[2] &= 0x1;
|
||||||
rpt.second = 3;
|
rpt.resize(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_write_reports.Push(rpt);
|
m_write_reports.Push(std::move(rpt));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wiimote::Read()
|
bool Wiimote::Read()
|
||||||
{
|
{
|
||||||
Report rpt;
|
Report rpt(MAX_PAYLOAD);
|
||||||
|
auto const result = IORead(rpt.data());
|
||||||
|
|
||||||
rpt.first = new unsigned char[MAX_PAYLOAD];
|
if (result > 0 && m_channel > 0)
|
||||||
rpt.second = IORead(rpt.first);
|
{
|
||||||
|
// Add it to queue
|
||||||
if (0 == rpt.second)
|
rpt.resize(result);
|
||||||
|
m_read_reports.Push(std::move(rpt));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (0 == result)
|
||||||
{
|
{
|
||||||
WARN_LOG(WIIMOTE, "Wiimote::IORead failed. Disconnecting Wiimote %d.", index + 1);
|
WARN_LOG(WIIMOTE, "Wiimote::IORead failed. Disconnecting Wiimote %d.", index + 1);
|
||||||
Disconnect();
|
Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rpt.second > 0 && m_channel > 0)
|
|
||||||
{
|
|
||||||
// Add it to queue
|
|
||||||
m_read_reports.Push(rpt);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] rpt.first;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,16 +201,15 @@ bool Wiimote::Write()
|
|||||||
{
|
{
|
||||||
Report const& rpt = m_write_reports.Front();
|
Report const& rpt = m_write_reports.Front();
|
||||||
|
|
||||||
bool const is_speaker_data = rpt.first[1] == WM_WRITE_SPEAKER_DATA;
|
bool const is_speaker_data = rpt[1] == WM_WRITE_SPEAKER_DATA;
|
||||||
|
|
||||||
if (!is_speaker_data || m_last_audio_report.GetTimeDifference() > 5)
|
if (!is_speaker_data || m_last_audio_report.GetTimeDifference() > 5)
|
||||||
{
|
{
|
||||||
IOWrite(rpt.first, rpt.second);
|
IOWrite(rpt.data(), rpt.size());
|
||||||
|
|
||||||
if (is_speaker_data)
|
if (is_speaker_data)
|
||||||
m_last_audio_report.Update();
|
m_last_audio_report.Update();
|
||||||
|
|
||||||
delete[] rpt.first;
|
|
||||||
m_write_reports.Pop();
|
m_write_reports.Pop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -234,23 +218,35 @@ bool Wiimote::Write()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the next report that should be sent
|
bool IsDataReport(const Report& rpt)
|
||||||
Report Wiimote::ProcessReadQueue()
|
|
||||||
{
|
{
|
||||||
// Pop through the queued reports
|
return rpt.size() >= 2 && rpt[1] >= WM_REPORT_CORE;
|
||||||
Report rpt = m_last_data_report;
|
|
||||||
while (m_read_reports.Pop(rpt))
|
|
||||||
{
|
|
||||||
if (rpt.first[1] >= WM_REPORT_CORE)
|
|
||||||
// A data report
|
|
||||||
m_last_data_report = rpt;
|
|
||||||
else
|
|
||||||
// Some other kind of report
|
|
||||||
return rpt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The queue was empty, or there were only data reports
|
// Returns the next report that should be sent
|
||||||
return rpt;
|
const Report& Wiimote::ProcessReadQueue()
|
||||||
|
{
|
||||||
|
// Pop through the queued reports
|
||||||
|
while (m_read_reports.Pop(m_last_input_report))
|
||||||
|
{
|
||||||
|
if (!IsDataReport(m_last_input_report))
|
||||||
|
{
|
||||||
|
// A non-data report, use it.
|
||||||
|
return m_last_input_report;
|
||||||
|
|
||||||
|
// Forget the last data report as it may be of the wrong type
|
||||||
|
// or contain outdated button data
|
||||||
|
// or it's not supposed to be sent at this time
|
||||||
|
// It's just easier to be correct this way and it's probably not horrible.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the last report wasn't a data report it's irrelevant.
|
||||||
|
if (!IsDataReport(m_last_input_report))
|
||||||
|
m_last_input_report.clear();
|
||||||
|
|
||||||
|
// If it was a data report, we repeat that until something else comes in.
|
||||||
|
return m_last_input_report;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wiimote::Update()
|
void Wiimote::Update()
|
||||||
@ -262,16 +258,12 @@ void Wiimote::Update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pop through the queued reports
|
// Pop through the queued reports
|
||||||
Report const rpt = ProcessReadQueue();
|
const Report& rpt = ProcessReadQueue();
|
||||||
|
|
||||||
// Send the report
|
// Send the report
|
||||||
if (rpt.first != NULL && m_channel > 0)
|
if (!rpt.empty() && m_channel > 0)
|
||||||
Core::Callback_WiimoteInterruptChannel(index, m_channel,
|
Core::Callback_WiimoteInterruptChannel(index, m_channel,
|
||||||
rpt.first, rpt.second);
|
rpt.data(), rpt.size());
|
||||||
|
|
||||||
// Delete the data if it isn't also the last data rpt
|
|
||||||
if (rpt != m_last_data_report)
|
|
||||||
delete[] rpt.first;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wiimote::Prepare(int _index)
|
bool Wiimote::Prepare(int _index)
|
||||||
@ -279,13 +271,13 @@ bool Wiimote::Prepare(int _index)
|
|||||||
index = _index;
|
index = _index;
|
||||||
|
|
||||||
// core buttons, no continuous reporting
|
// core buttons, no continuous reporting
|
||||||
u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_REPORT_TYPE, 0, 0x30};
|
u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REPORT_MODE, 0, WM_REPORT_CORE};
|
||||||
|
|
||||||
// Set the active LEDs and turn on rumble.
|
// Set the active LEDs and turn on rumble.
|
||||||
u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_LED, u8(WIIMOTE_LED_1 << index | 0x1)};
|
u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_LEDS, u8(WIIMOTE_LED_1 << index | 0x1)};
|
||||||
|
|
||||||
// Turn off rumble
|
// Turn off rumble
|
||||||
u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_CMD_RUMBLE, 0};
|
u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_RUMBLE, 0};
|
||||||
|
|
||||||
// Request status report
|
// Request status report
|
||||||
u8 const req_status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0};
|
u8 const req_status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0};
|
||||||
|
@ -33,8 +33,7 @@
|
|||||||
|
|
||||||
#include "../../InputCommon/Src/InputConfig.h"
|
#include "../../InputCommon/Src/InputConfig.h"
|
||||||
|
|
||||||
// Pointer to data, and size of data
|
typedef std::vector<u8> Report;
|
||||||
typedef std::pair<u8*,u8> Report;
|
|
||||||
|
|
||||||
namespace WiimoteReal
|
namespace WiimoteReal
|
||||||
{
|
{
|
||||||
@ -50,7 +49,7 @@ public:
|
|||||||
void InterruptChannel(const u16 channel, const void* const data, const u32 size);
|
void InterruptChannel(const u16 channel, const void* const data, const u32 size);
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
Report ProcessReadQueue();
|
const Report& ProcessReadQueue();
|
||||||
|
|
||||||
bool Read();
|
bool Read();
|
||||||
bool Write();
|
bool Write();
|
||||||
@ -99,7 +98,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Report m_last_data_report;
|
Report m_last_input_report;
|
||||||
u16 m_channel;
|
u16 m_channel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -41,20 +41,6 @@
|
|||||||
#define WM_SET_REPORT 0xA0
|
#define WM_SET_REPORT 0xA0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: duplicated in WiimoteHid.h
|
|
||||||
// Commands
|
|
||||||
#define WM_CMD_RUMBLE 0x10
|
|
||||||
#define WM_CMD_LED 0x11
|
|
||||||
#define WM_CMD_REPORT_TYPE 0x12
|
|
||||||
#define WM_CMD_IR 0x13
|
|
||||||
#define WM_CMD_SPEAKER_ENABLE 0x14
|
|
||||||
#define WM_CMD_CTRL_STATUS 0x15
|
|
||||||
#define WM_CMD_WRITE_DATA 0x16
|
|
||||||
#define WM_CMD_READ_DATA 0x17
|
|
||||||
#define WM_CMD_SPEAKER_DATA 0x18
|
|
||||||
#define WM_CMD_SPEAKER_MUTE 0x19
|
|
||||||
#define WM_CMD_IR_2 0x1A
|
|
||||||
|
|
||||||
#define WM_BT_INPUT 0x01
|
#define WM_BT_INPUT 0x01
|
||||||
#define WM_BT_OUTPUT 0x02
|
#define WM_BT_OUTPUT 0x02
|
||||||
|
|
||||||
@ -73,12 +59,12 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Available bluetooth stacks for Windows.
|
// Available bluetooth stacks for Windows.
|
||||||
typedef enum win_bt_stack_t
|
enum win_bt_stack_t
|
||||||
{
|
{
|
||||||
MSBT_STACK_UNKNOWN,
|
MSBT_STACK_UNKNOWN,
|
||||||
MSBT_STACK_MS,
|
MSBT_STACK_MS,
|
||||||
MSBT_STACK_BLUESOLEIL
|
MSBT_STACK_BLUESOLEIL
|
||||||
} win_bt_stack_t;
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // WIIMOTE_COMM_H
|
#endif // WIIMOTE_COMM_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user