diff --git a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp index 720f41b2d3..f88e90b1cc 100644 --- a/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp +++ b/Source/Core/InputCommon/Src/ControllerInterface/DInput/DInputJoystick.cpp @@ -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"}, diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.cpp index 082c4d9933..f39f786eaa 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.cpp @@ -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) diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.h b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.h index 1aed269dd1..75c3e482a8 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.h +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteConfigDiag.h @@ -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: diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp index b330f9fe4b..23eec2d416 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteEmu/EmuSubroutines.cpp @@ -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: diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp index be2cc345c6..867d40f1f8 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp @@ -28,6 +28,12 @@ #include "../WiimoteEmu/WiimoteHid.h" +// used for pair up +#ifdef _WIN32 +#include +#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 diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h index a2b9458223..c772ed06fa 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.h @@ -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