New Wiimote Plugin: Added a real wiimote "Pair Up" button on Windows for the Microsoft bluetooth stack, like the old plugin. The PairUp function was copied from the old plugin and cleaned up. (Mostly untested because I'm not using the MS stack) Please test. Other minor changes to emu-wiimote and DInput. (Perhaps the "Refresh" button should call PairUp() followed by Refresh() to make the dialog simpler.)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6213 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
2cddf48cde
commit
19a50b3c51
|
@ -26,9 +26,9 @@ static const struct
|
||||||
{GUID_Square, "Square"}, // DIPERIODIC ...
|
{GUID_Square, "Square"}, // DIPERIODIC ...
|
||||||
{GUID_Sine, "Sine"},
|
{GUID_Sine, "Sine"},
|
||||||
{GUID_Triangle, "Triangle"},
|
{GUID_Triangle, "Triangle"},
|
||||||
{GUID_SawtoothUp, "SawtoothUp"},
|
{GUID_SawtoothUp, "Sawtooth Up"},
|
||||||
{GUID_SawtoothDown, "SawtoothDown"},
|
{GUID_SawtoothDown, "Sawtooth Down"},
|
||||||
//{GUID_Spring, "Spring"}, // DIEFT_CUSTOMFORCE ... < i think
|
//{GUID_Spring, "Spring"}, // DICUSTOMFORCE ... < i think
|
||||||
//{GUID_Damper, "Damper"},
|
//{GUID_Damper, "Damper"},
|
||||||
//{GUID_Inertia, "Inertia"},
|
//{GUID_Inertia, "Inertia"},
|
||||||
//{GUID_Friction, "Friction"},
|
//{GUID_Friction, "Friction"},
|
||||||
|
|
|
@ -4,6 +4,13 @@
|
||||||
|
|
||||||
#define _connect_macro_(b, f, c, s) (b)->Connect(wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s)
|
#define _connect_macro_(b, f, c, s) (b)->Connect(wxID_ANY, (c), wxCommandEventHandler( f ), (wxObject*)0, (wxEvtHandler*)s)
|
||||||
|
|
||||||
|
const wxString& ConnectedWiimotesString()
|
||||||
|
{
|
||||||
|
static wxString str = wxT("Connected to . Wiimotes");
|
||||||
|
str[13] = wxChar(wxT('0') + WiimoteReal::Initialize());
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
WiimoteConfigPage::WiimoteConfigPage(wxWindow* const parent, const int index)
|
WiimoteConfigPage::WiimoteConfigPage(wxWindow* const parent, const int index)
|
||||||
: wxNotebookPage(parent, -1, wxDefaultPosition, wxDefaultSize)
|
: wxNotebookPage(parent, -1, wxDefaultPosition, wxDefaultSize)
|
||||||
, m_index(index)
|
, m_index(index)
|
||||||
|
@ -28,19 +35,26 @@ WiimoteConfigPage::WiimoteConfigPage(wxWindow* const parent, const int index)
|
||||||
|
|
||||||
// real wiimote
|
// real wiimote
|
||||||
m_connected_wiimotes_txt = new wxStaticText(this, -1, wxEmptyString);
|
m_connected_wiimotes_txt = new wxStaticText(this, -1, wxEmptyString);
|
||||||
wxStaticBoxSizer* const wiimote_real_sizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Real Wiimote"));
|
m_connected_wiimotes_txt->SetLabel(ConnectedWiimotesString());
|
||||||
|
|
||||||
wxButton* const refresh_btn = new wxButton(this, -1, wxT("Refresh"), wxDefaultPosition);
|
wxButton* const refresh_btn = new wxButton(this, -1, wxT("Refresh"), wxDefaultPosition);
|
||||||
_connect_macro_(refresh_btn, WiimoteConfigPage::RefreshRealWiimotes, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
_connect_macro_(refresh_btn, WiimoteConfigPage::RefreshRealWiimotes, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||||
|
|
||||||
wiimote_real_sizer->Add(m_connected_wiimotes_txt, 1, wxALIGN_CENTER | wxALL, 5);
|
wxStaticBoxSizer* const wiimote_real_sizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Real Wiimote"));
|
||||||
wiimote_real_sizer->Add(refresh_btn, 1, wxALIGN_CENTER | wxALL, 5);
|
wiimote_real_sizer->AddStretchSpacer(1);
|
||||||
|
wiimote_real_sizer->Add(m_connected_wiimotes_txt, 0, wxALIGN_CENTER | wxBOTTOM | wxLEFT | wxRIGHT, 5);
|
||||||
m_connected_wiimotes_txt->SetLabel(wxString(wxT("Connected to ")) + wxChar(wxT('0') + WiimoteReal::Initialize()) + wxT(" Real Wiimotes"));
|
#ifdef _WIN32
|
||||||
|
wxButton* const pairup_btn = new wxButton(this, -1, wxT("Pair Up"), wxDefaultPosition);
|
||||||
|
_connect_macro_(pairup_btn, WiimoteConfigPage::PairUpRealWiimotes, wxEVT_COMMAND_BUTTON_CLICKED, this);
|
||||||
|
wiimote_real_sizer->Add(pairup_btn, 0, wxALIGN_CENTER | wxBOTTOM, 5);
|
||||||
|
#endif
|
||||||
|
wiimote_real_sizer->Add(refresh_btn, 0, wxALIGN_CENTER, 5);
|
||||||
|
wiimote_real_sizer->AddStretchSpacer(1);
|
||||||
|
|
||||||
// sizers
|
// sizers
|
||||||
wxBoxSizer* const left_sizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* const left_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
left_sizer->Add(input_src_sizer, 1, wxEXPAND | wxBOTTOM, 5);
|
left_sizer->Add(input_src_sizer, 0, wxEXPAND | wxBOTTOM, 5);
|
||||||
left_sizer->Add(wiimote_emu_sizer, 1, wxEXPAND, 0);
|
left_sizer->Add(wiimote_emu_sizer, 0, wxEXPAND, 0);
|
||||||
|
|
||||||
wxBoxSizer* const main_sizer = new wxBoxSizer(wxHORIZONTAL);
|
wxBoxSizer* const main_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
main_sizer->Add(left_sizer, 1, wxLEFT | wxTOP | wxBOTTOM | wxEXPAND, 5);
|
main_sizer->Add(left_sizer, 1, wxLEFT | wxTOP | wxBOTTOM | wxEXPAND, 5);
|
||||||
|
@ -81,10 +95,27 @@ void WiimoteConfigDiag::ConfigEmulatedWiimote(wxCommandEvent& event)
|
||||||
m_emu_config_diag->Destroy();
|
m_emu_config_diag->Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void WiimoteConfigPage::PairUpRealWiimotes(wxCommandEvent& event)
|
||||||
|
{
|
||||||
|
const int paired = WiimoteReal::PairUp();
|
||||||
|
|
||||||
|
if (paired > 0)
|
||||||
|
{
|
||||||
|
// Will this message be anoying?
|
||||||
|
//PanicAlert("Paired %d wiimotes.", paired);
|
||||||
|
WiimoteReal::Refresh();
|
||||||
|
}
|
||||||
|
else if (paired < 0)
|
||||||
|
PanicAlert("A supported bluetooth device was not found!\n"
|
||||||
|
"(Only the Microsoft bluetooth stack is supported.)");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void WiimoteConfigPage::RefreshRealWiimotes(wxCommandEvent& event)
|
void WiimoteConfigPage::RefreshRealWiimotes(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
WiimoteReal::Refresh();
|
WiimoteReal::Refresh();
|
||||||
m_connected_wiimotes_txt->SetLabel(wxString(wxT("Connected to ")) + wxChar(wxT('0') + WiimoteReal::Initialize()) + wxT(" Real Wiimotes"));
|
m_connected_wiimotes_txt->SetLabel(ConnectedWiimotesString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WiimoteConfigPage::SelectSource(wxCommandEvent& event)
|
void WiimoteConfigPage::SelectSource(wxCommandEvent& event)
|
||||||
|
|
|
@ -20,7 +20,11 @@ class WiimoteConfigPage : public wxNotebookPage
|
||||||
public:
|
public:
|
||||||
WiimoteConfigPage(wxWindow* const parent, const int index);
|
WiimoteConfigPage(wxWindow* const parent, const int index);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
void PairUpRealWiimotes(wxCommandEvent& event);
|
||||||
|
#endif
|
||||||
void RefreshRealWiimotes(wxCommandEvent& event);
|
void RefreshRealWiimotes(wxCommandEvent& event);
|
||||||
|
|
||||||
void SelectSource(wxCommandEvent& event);
|
void SelectSource(wxCommandEvent& event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -105,6 +105,7 @@ void Wiimote::HidOutputReport(const wm_report* const sr, const bool send_ack)
|
||||||
case WM_LEDS : // 0x11
|
case WM_LEDS : // 0x11
|
||||||
//INFO_LOG(WIIMOTE, "Set LEDs: 0x%02x", sr->data[0]);
|
//INFO_LOG(WIIMOTE, "Set LEDs: 0x%02x", sr->data[0]);
|
||||||
m_status.leds = sr->data[0] >> 4;
|
m_status.leds = sr->data[0] >> 4;
|
||||||
|
return; // no ack
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_REPORT_MODE : // 0x12
|
case WM_REPORT_MODE : // 0x12
|
||||||
|
@ -114,12 +115,18 @@ void Wiimote::HidOutputReport(const wm_report* const sr, const bool send_ack)
|
||||||
case WM_IR_PIXEL_CLOCK : // 0x13
|
case WM_IR_PIXEL_CLOCK : // 0x13
|
||||||
//INFO_LOG(WIIMOTE, "WM IR Clock: 0x%02x", sr->data[0]);
|
//INFO_LOG(WIIMOTE, "WM IR Clock: 0x%02x", sr->data[0]);
|
||||||
//m_ir_clock = (sr->data[0] & 0x04) ? 1 : 0;
|
//m_ir_clock = (sr->data[0] & 0x04) ? 1 : 0;
|
||||||
|
|
||||||
|
if (0 == (sr->data[0] & 0x02)) // only ack if 0x02 bit is set
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_SPEAKER_ENABLE : // 0x14
|
case WM_SPEAKER_ENABLE : // 0x14
|
||||||
//INFO_LOG(WIIMOTE, "WM Speaker Enable: 0x%02x", sr->data[0]);
|
//INFO_LOG(WIIMOTE, "WM Speaker Enable: 0x%02x", sr->data[0]);
|
||||||
//PanicAlert( "WM Speaker Enable: %d", sr->data[0] );
|
//PanicAlert( "WM Speaker Enable: %d", sr->data[0] );
|
||||||
m_status.speaker = (sr->data[0] & 0x04) ? 1 : 0;
|
m_status.speaker = (sr->data[0] & 0x04) ? 1 : 0;
|
||||||
|
|
||||||
|
if (0 == (sr->data[0] & 0x02)) // only ack if 0x02 bit is set
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_REQUEST_STATUS : // 0x15
|
case WM_REQUEST_STATUS : // 0x15
|
||||||
|
@ -153,6 +160,9 @@ void Wiimote::HidOutputReport(const wm_report* const sr, const bool send_ack)
|
||||||
memset(&m_channel_status, 0, sizeof(m_channel_status));
|
memset(&m_channel_status, 0, sizeof(m_channel_status));
|
||||||
#endif
|
#endif
|
||||||
m_speaker_mute = (sr->data[0] & 0x04) ? 1 : 0;
|
m_speaker_mute = (sr->data[0] & 0x04) ? 1 : 0;
|
||||||
|
|
||||||
|
if (0 == (sr->data[0] & 0x02)) // only ack if 0x02 bit is set
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_IR_LOGIC: // 0x1a
|
case WM_IR_LOGIC: // 0x1a
|
||||||
|
@ -161,6 +171,9 @@ void Wiimote::HidOutputReport(const wm_report* const sr, const bool send_ack)
|
||||||
// so that WmRequestStatus() knows about it
|
// so that WmRequestStatus() knows about it
|
||||||
//INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]);
|
//INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[0]);
|
||||||
m_status.ir = (sr->data[0] & 0x04) ? 1 : 0;
|
m_status.ir = (sr->data[0] & 0x04) ? 1 : 0;
|
||||||
|
|
||||||
|
if (0 == (sr->data[0] & 0x02)) // only ack if 0x02 bit is set
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -28,6 +28,12 @@
|
||||||
|
|
||||||
#include "../WiimoteEmu/WiimoteHid.h"
|
#include "../WiimoteEmu/WiimoteHid.h"
|
||||||
|
|
||||||
|
// used for pair up
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <BluetoothAPIs.h>
|
||||||
|
#pragma comment(lib, "Bthprops.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned int g_wiimote_sources[MAX_WIIMOTES];
|
unsigned int g_wiimote_sources[MAX_WIIMOTES];
|
||||||
|
|
||||||
namespace WiimoteReal
|
namespace WiimoteReal
|
||||||
|
@ -484,4 +490,104 @@ THREAD_RETURN WiimoteThreadFunc(void* arg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
// WiiMote Pair-Up, function will return amount of either new paired or unpaired devices
|
||||||
|
// negative number on failure
|
||||||
|
int PairUp(bool unpair)
|
||||||
|
{
|
||||||
|
int nPaired = 0;
|
||||||
|
|
||||||
|
BLUETOOTH_DEVICE_SEARCH_PARAMS srch;
|
||||||
|
srch.dwSize = sizeof(srch);
|
||||||
|
srch.fReturnAuthenticated = true;
|
||||||
|
srch.fReturnRemembered = true;
|
||||||
|
srch.fReturnConnected = true; // does not filter properly somehow, so we've to do an additional check on fConnected BT Devices
|
||||||
|
srch.fReturnUnknown = true;
|
||||||
|
srch.fIssueInquiry = true;
|
||||||
|
srch.cTimeoutMultiplier = 2; // == (2 * 1.28) seconds
|
||||||
|
|
||||||
|
BLUETOOTH_FIND_RADIO_PARAMS radioParam;
|
||||||
|
radioParam.dwSize = sizeof(radioParam);
|
||||||
|
|
||||||
|
HANDLE hRadio;
|
||||||
|
|
||||||
|
// Enumerate BT radios
|
||||||
|
HBLUETOOTH_RADIO_FIND hFindRadio = BluetoothFindFirstRadio(&radioParam, &hRadio);
|
||||||
|
|
||||||
|
if (NULL == hFindRadio)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
while (hFindRadio)
|
||||||
|
{
|
||||||
|
BLUETOOTH_RADIO_INFO radioInfo;
|
||||||
|
radioInfo.dwSize = sizeof(radioInfo);
|
||||||
|
|
||||||
|
// TODO: check for SUCCEEDED()
|
||||||
|
BluetoothGetRadioInfo(hRadio, &radioInfo);
|
||||||
|
|
||||||
|
srch.hRadio = hRadio;
|
||||||
|
|
||||||
|
BLUETOOTH_DEVICE_INFO btdi;
|
||||||
|
btdi.dwSize = sizeof(btdi);
|
||||||
|
|
||||||
|
// Enumerate BT devices
|
||||||
|
HBLUETOOTH_DEVICE_FIND hFindDevice = BluetoothFindFirstDevice(&srch, &btdi);
|
||||||
|
while (hFindDevice)
|
||||||
|
{
|
||||||
|
//btdi.szName is sometimes missings it's content - it's a bt feature..
|
||||||
|
DEBUG_LOG(WIIMOTE, "authed %i connected %i remembered %i ", btdi.fAuthenticated, btdi.fConnected, btdi.fRemembered);
|
||||||
|
|
||||||
|
// TODO: Probably could just check for "Nintendo RVL"
|
||||||
|
if (0 == wcscmp(btdi.szName, L"Nintendo RVL-WBC-01") || 0 == wcscmp(btdi.szName, L"Nintendo RVL-CNT-01"))
|
||||||
|
{
|
||||||
|
if (unpair)
|
||||||
|
{
|
||||||
|
if (SUCCEEDED(BluetoothRemoveDevice(&btdi.Address)))
|
||||||
|
{
|
||||||
|
NOTICE_LOG(WIIMOTE, "Pair-Up: Automatically removed BT Device on shutdown: %08x", GetLastError());
|
||||||
|
++nPaired;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (false == btdi.fConnected)
|
||||||
|
{
|
||||||
|
//TODO: improve the read of the BT driver, esp. when batteries of the wiimote are removed while being fConnected
|
||||||
|
if (btdi.fRemembered)
|
||||||
|
{
|
||||||
|
// Make Windows forget old expired pairing
|
||||||
|
// we can pretty much ignore the return value here.
|
||||||
|
// it either worked (ERROR_SUCCESS), or the device did not exist (ERROR_NOT_FOUND)
|
||||||
|
// in both cases, there is nothing left.
|
||||||
|
BluetoothRemoveDevice(&btdi.Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate service
|
||||||
|
const DWORD hr = BluetoothSetServiceState(hRadio, &btdi, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
++nPaired;
|
||||||
|
else
|
||||||
|
ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false == BluetoothFindNextDevice(hFindDevice, &btdi))
|
||||||
|
{
|
||||||
|
BluetoothFindDeviceClose(hFindDevice);
|
||||||
|
hFindDevice = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false == BluetoothFindNextRadio(hFindRadio, &hRadio))
|
||||||
|
{
|
||||||
|
BluetoothFindRadioClose(hFindRadio);
|
||||||
|
hFindRadio = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nPaired;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}; // end of namespace
|
}; // end of namespace
|
||||||
|
|
|
@ -96,6 +96,10 @@ void Update(int _WiimoteNumber);
|
||||||
void DoState(PointerWrap &p);
|
void DoState(PointerWrap &p);
|
||||||
void StateChange(PLUGIN_EMUSTATE newState);
|
void StateChange(PLUGIN_EMUSTATE newState);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
int PairUp(bool unpair = false);
|
||||||
|
#endif
|
||||||
|
|
||||||
}; // WiiMoteReal
|
}; // WiiMoteReal
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue