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:
Jordan Woyak 2010-09-16 22:50:18 +00:00
parent 2cddf48cde
commit 19a50b3c51
6 changed files with 169 additions and 11 deletions

View File

@ -26,9 +26,9 @@ static const struct
{GUID_Square, "Square"}, // DIPERIODIC ...
{GUID_Sine, "Sine"},
{GUID_Triangle, "Triangle"},
{GUID_SawtoothUp, "SawtoothUp"},
{GUID_SawtoothDown, "SawtoothDown"},
//{GUID_Spring, "Spring"}, // DIEFT_CUSTOMFORCE ... < i think
{GUID_SawtoothUp, "Sawtooth Up"},
{GUID_SawtoothDown, "Sawtooth Down"},
//{GUID_Spring, "Spring"}, // DICUSTOMFORCE ... < i think
//{GUID_Damper, "Damper"},
//{GUID_Inertia, "Inertia"},
//{GUID_Friction, "Friction"},

View File

@ -4,6 +4,13 @@
#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)
: wxNotebookPage(parent, -1, wxDefaultPosition, wxDefaultSize)
, m_index(index)
@ -28,19 +35,26 @@ WiimoteConfigPage::WiimoteConfigPage(wxWindow* const parent, const int index)
// real wiimote
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);
_connect_macro_(refresh_btn, WiimoteConfigPage::RefreshRealWiimotes, wxEVT_COMMAND_BUTTON_CLICKED, this);
wiimote_real_sizer->Add(m_connected_wiimotes_txt, 1, wxALIGN_CENTER | wxALL, 5);
wiimote_real_sizer->Add(refresh_btn, 1, wxALIGN_CENTER | wxALL, 5);
m_connected_wiimotes_txt->SetLabel(wxString(wxT("Connected to ")) + wxChar(wxT('0') + WiimoteReal::Initialize()) + wxT(" Real Wiimotes"));
wxStaticBoxSizer* const wiimote_real_sizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Real Wiimote"));
wiimote_real_sizer->AddStretchSpacer(1);
wiimote_real_sizer->Add(m_connected_wiimotes_txt, 0, wxALIGN_CENTER | wxBOTTOM | wxLEFT | wxRIGHT, 5);
#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
wxBoxSizer* const left_sizer = new wxBoxSizer(wxVERTICAL);
left_sizer->Add(input_src_sizer, 1, wxEXPAND | wxBOTTOM, 5);
left_sizer->Add(wiimote_emu_sizer, 1, wxEXPAND, 0);
left_sizer->Add(input_src_sizer, 0, wxEXPAND | wxBOTTOM, 5);
left_sizer->Add(wiimote_emu_sizer, 0, wxEXPAND, 0);
wxBoxSizer* const main_sizer = new wxBoxSizer(wxHORIZONTAL);
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();
}
#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)
{
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)

View File

@ -20,7 +20,11 @@ class WiimoteConfigPage : public wxNotebookPage
public:
WiimoteConfigPage(wxWindow* const parent, const int index);
#ifdef _WIN32
void PairUpRealWiimotes(wxCommandEvent& event);
#endif
void RefreshRealWiimotes(wxCommandEvent& event);
void SelectSource(wxCommandEvent& event);
private:

View File

@ -105,6 +105,7 @@ void Wiimote::HidOutputReport(const wm_report* const sr, const bool send_ack)
case WM_LEDS : // 0x11
//INFO_LOG(WIIMOTE, "Set LEDs: 0x%02x", sr->data[0]);
m_status.leds = sr->data[0] >> 4;
return; // no ack
break;
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
//INFO_LOG(WIIMOTE, "WM IR Clock: 0x%02x", sr->data[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;
case WM_SPEAKER_ENABLE : // 0x14
//INFO_LOG(WIIMOTE, "WM Speaker Enable: 0x%02x", sr->data[0]);
//PanicAlert( "WM Speaker Enable: %d", sr->data[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;
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));
#endif
m_speaker_mute = (sr->data[0] & 0x04) ? 1 : 0;
if (0 == (sr->data[0] & 0x02)) // only ack if 0x02 bit is set
return;
break;
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
//INFO_LOG(WIIMOTE, "WM IR Enable: 0x%02x", sr->data[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;
default:

View File

@ -28,6 +28,12 @@
#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];
namespace WiimoteReal
@ -484,4 +490,104 @@ THREAD_RETURN WiimoteThreadFunc(void* arg)
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

View File

@ -96,6 +96,10 @@ void Update(int _WiimoteNumber);
void DoState(PointerWrap &p);
void StateChange(PLUGIN_EMUSTATE newState);
#ifdef _WIN32
int PairUp(bool unpair = false);
#endif
}; // WiiMoteReal
#endif