From 6500db254f250db946917247cc0399644caea1ec Mon Sep 17 00:00:00 2001 From: fgfemperor Date: Tue, 5 Jan 2010 17:38:37 +0000 Subject: [PATCH] Now you can pair up your Real WiiMotes on the Wiimote config panel! It's really helpful since pairing up using Microsoft's Stack is a real pain! Thanks to jack.fr0st and sanchez who did most of the work! Note: IT ONLY WORKS WITH MICROSOFT BLUETOOTH STACK! Also you should press the Refresh Real WiiMotes button after everything is paired up! (Because it takes a while for the drivers to get installed) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4786 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Plugins/Plugin_VideoDX9/Src/D3DBase.cpp | 5 +- .../Plugin_Wiimote/Src/ConfigBasicDlg.cpp | 27 ++- .../Plugin_Wiimote/Src/ConfigBasicDlg.h | 3 + .../Plugin_Wiimote/Src/wiimote_real.cpp | 172 +++++++++++++++--- .../Plugins/Plugin_Wiimote/Src/wiimote_real.h | 3 + 5 files changed, 183 insertions(+), 27 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp index a15e1cc82a..2d3a78aa99 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp @@ -121,7 +121,8 @@ void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp) pp->SwapEffect = D3DSWAPEFFECT_DISCARD; pp->Windowed = FALSE; //if(g_Config.bHideCursor) - ShowCursor(false); + if(!g_Config.RenderToMainframe) + ShowCursor(FALSE); } else { @@ -132,7 +133,7 @@ void InitPP(int adapter, int f, int aa_mode, D3DPRESENT_PARAMETERS *pp) pp->SwapEffect = D3DSWAPEFFECT_DISCARD; pp->PresentationInterval = g_Config.bVSync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE; pp->Windowed = TRUE; - ShowCursor(true); + ShowCursor(TRUE); } } diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp index 18adb70c6e..04cd94a8ae 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.cpp @@ -25,6 +25,8 @@ #include "EmuMain.h" // for SetDefaultExtensionRegistry #include "EmuSubroutines.h" // for WmRequestStatus + + BEGIN_EVENT_TABLE(WiimoteBasicConfigDialog,wxDialog) EVT_CLOSE(WiimoteBasicConfigDialog::OnClose) EVT_BUTTON(ID_OK, WiimoteBasicConfigDialog::ButtonClick) @@ -32,6 +34,7 @@ BEGIN_EVENT_TABLE(WiimoteBasicConfigDialog,wxDialog) EVT_BUTTON(ID_REFRESH_REAL, WiimoteBasicConfigDialog::ButtonClick) EVT_BUTTON(ID_BUTTONMAPPING, WiimoteBasicConfigDialog::ButtonClick) EVT_BUTTON(ID_BUTTONRECORDING, WiimoteBasicConfigDialog::ButtonClick) + EVT_BUTTON(ID_BUTTONPAIRUP, WiimoteBasicConfigDialog::ButtonClick) EVT_NOTEBOOK_PAGE_CHANGED(ID_NOTEBOOK, WiimoteBasicConfigDialog::NotebookPageChanged) EVT_CHOICE(IDC_INPUT_SOURCE, WiimoteBasicConfigDialog::GeneralSettingsChanged) EVT_CHECKBOX(IDC_CONNECT_REAL, WiimoteBasicConfigDialog::GeneralSettingsChanged) @@ -107,6 +110,19 @@ void WiimoteBasicConfigDialog::ButtonClick(wxCommandEvent& event) m_RecordingConfigFrame->Destroy(); m_RecordingConfigFrame = NULL; break; +#ifdef WIN32 + case ID_BUTTONPAIRUP: + if(!g_EmulatorRunning) { + m_ButtonPairUp->Enable(false); + if (WiiMoteReal::WiimotePairUp() > 0) { //Only temporay solution TODO: 2nd step: threaded. + // sleep would be required (but not best way to solve that cuz 3000ms~ would be needed, which is not convenient),cuz BT device is not ready yet when calling DoRefreshReal() + + DoRefreshReal(); + } + m_ButtonPairUp->Enable(true); + } + break; +#endif case ID_REFRESH_REAL: DoRefreshReal(); break; @@ -232,6 +248,14 @@ void WiimoteBasicConfigDialog::CreateGUIControls() m_ButtonMapping = new wxButton(this, ID_BUTTONMAPPING, wxT("Button Mapping")); m_Recording = new wxButton(this, ID_BUTTONRECORDING, wxT("Recording")); + m_ButtonPairUp = new wxButton(this, ID_BUTTONPAIRUP, wxT("Pair Up Wiimote(s)")); + + #ifdef WIN32 + m_ButtonPairUp->SetToolTip(wxT("Pair up your Wiimote(s) with your system.\nPress the Buttons 1 and 2 on your Wiimote before pairing up.\nThis might take a few seconds.\nIt only works if you're using Microsoft's Bluetooth stack.")); // Only working with MS BT Stack. + #else + m_ButtonPairUp->Enable(false); + #endif + m_OK = new wxButton(this, ID_OK, wxT("OK")); m_OK->SetToolTip(wxT("Save changes and close")); m_Cancel = new wxButton(this, ID_CANCEL, wxT("Cancel")); @@ -240,6 +264,7 @@ void WiimoteBasicConfigDialog::CreateGUIControls() wxBoxSizer* sButtons = new wxBoxSizer(wxHORIZONTAL); sButtons->Add(m_ButtonMapping, 0, (wxALL), 0); sButtons->Add(m_Recording, 0, (wxALL), 0); + sButtons->Add(m_ButtonPairUp, 0, (wxALL), 0); sButtons->AddStretchSpacer(); sButtons->Add(m_OK, 0, (wxALL), 0); sButtons->Add(m_Cancel, 0, (wxLEFT), 5); @@ -455,6 +480,7 @@ void WiimoteBasicConfigDialog::UpdateGUI() m_ConnectRealWiimote[m_Page]->SetValue(g_Config.bConnectRealWiimote); m_ConnectRealWiimote[m_Page]->Enable(!g_EmulatorRunning); m_RefreshRealWiiMote[m_Page]->Enable(!g_EmulatorRunning && g_Config.bConnectRealWiimote); + m_ButtonPairUp->Enable(!g_EmulatorRunning); wxString Found; if(g_Config.bConnectRealWiimote) Found.Printf(wxT("Connected to %i Real WiiMote(s)"), WiiMoteReal::g_NumberOfWiiMotes); @@ -496,4 +522,3 @@ void WiimoteBasicConfigDialog::UpdateGUI() m_CheckAR169[m_Page]->SetValue(g_Config.bKeepAR169); m_Crop[m_Page]->SetValue(g_Config.bCrop); } - diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h index 380021772b..01d5b6504f 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigBasicDlg.h @@ -66,6 +66,7 @@ class WiimoteBasicConfigDialog : public wxDialog *m_Cancel, *m_ButtonMapping, *m_Recording, + *m_ButtonPairUp, *m_RefreshRealWiiMote[MAX_WIIMOTES]; wxChoice *m_InputSource[MAX_WIIMOTES], @@ -137,6 +138,8 @@ class WiimoteBasicConfigDialog : public wxDialog IDS_HEIGHT, IDS_LEFT, IDS_TOP, + + ID_BUTTONPAIRUP, }; void CreateGUIControls(); diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp index ef4750ae2c..857159c0df 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp @@ -34,7 +34,12 @@ #include "EmuDefinitions.h" #define EXCLUDE_H // Avoid certain declarations in wiimote_real.h #include "wiimote_real.h" +#ifdef WIN32 +#include +#include +#pragma comment(lib, "Bthprops.lib") +#endif extern SWiimoteInitialize g_WiimoteInitialize; namespace WiiMoteReal @@ -284,13 +289,7 @@ void FlashLights(bool Connect) if (Connect) wiiuse_rumble(WiiMoteReal::g_WiiMotesFromWiiUse[i], 1); } - - #ifndef WIN32 - usleep(200000); - #else - Sleep(200); - #endif - + SLEEP(200); for (int i = 0; i < g_NumberOfWiiMotes; i++) { if (Connect) { @@ -532,28 +531,153 @@ THREAD_RETURN ReadWiimote_ThreadFunc(void* arg) { // We need g_ThreadGoing to do a manual WaitForSingleObject() from the configuration window g_ThreadGoing = true; - /*if(g_RealWiiMoteAllocated) - {*/ - // There is at least one Real Wiimote in use - if (g_Config.bNumberRealWiimotes > 0 && !g_RunTemporary) - { - for (int i = 0; i < MAX_WIIMOTES; i++) - if (g_WiimoteInUse[i]) - g_WiiMotes[i]->ReadData(); - } - else - ReadWiimote(); - /*} + // There is at least one Real Wiimote in use + if (g_Config.bNumberRealWiimotes > 0 && !g_RunTemporary) + { + for (int i = 0; i < MAX_WIIMOTES; i++) + if (g_WiimoteInUse[i]) + g_WiiMotes[i]->ReadData(); + } else - #ifndef WIN32 - usleep(1000000); - #else - Sleep(1000); - #endif*/ + ReadWiimote(); g_ThreadGoing = false; } return 0; } + +// WiiMote Pair-Up +#ifdef WIN32 +int WiimotePairUp(void) +{ + HANDLE hRadios[256]; + int nRadios; + int nPaired = 0; + + // Enumerate BT radios + HBLUETOOTH_RADIO_FIND hFindRadio; + BLUETOOTH_FIND_RADIO_PARAMS radioParam; + + radioParam.dwSize = sizeof(BLUETOOTH_FIND_RADIO_PARAMS); + nRadios = 0; + + hFindRadio = BluetoothFindFirstRadio(&radioParam, &hRadios[nRadios++]); + if (hFindRadio) + { + while (BluetoothFindNextRadio(&radioParam, &hRadios[nRadios++])); + BluetoothFindRadioClose(hFindRadio); + } + else + { + ERROR_LOG(WIIMOTE, "Pair-Up: Error enumerating radios", GetLastError()); + return -1; + } + nRadios--; + // DEBUG_LOG(WIIMOTE, "Pair-Up: Found %d radios\n", nRadios); + + // Pair with Wii device(s) + int radio = 0; + + + for (radio = 0; radio < nRadios; radio++) + { + BLUETOOTH_RADIO_INFO radioInfo; + HBLUETOOTH_DEVICE_FIND hFind; + + BLUETOOTH_DEVICE_INFO btdi; + BLUETOOTH_DEVICE_SEARCH_PARAMS srch; + + radioInfo.dwSize = sizeof(radioInfo); + btdi.dwSize = sizeof(btdi); + srch.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS); + + BluetoothGetRadioInfo(hRadios[radio], &radioInfo); + + 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 = FALSE; + srch.cTimeoutMultiplier = 1; + srch.hRadio = hRadios[radio]; + + //DEBUG_LOG(WIIMOTE, _T("Pair-Up: Scanning for BT Device(s)")); + + hFind = BluetoothFindFirstDevice(&srch, &btdi); + + if (hFind == NULL) + { + ERROR_LOG(WIIMOTE, "Pair-Up: Error enumerating devices: %08x", GetLastError()); + return -1; + } + + //DWORD pcServices = 16; + //GUID guids[16]; + do + { + if ((!wcscmp(btdi.szName, L"Nintendo RVL-WBC-01") || !wcscmp(btdi.szName, L"Nintendo RVL-CNT-01")) && !btdi.fConnected) + { + // Wiimote found and not paired up yet + + // Wiimote unpaired(no driver installed yet): Name: Nintendo RVL-CNT-01 ClassOfDevice: 9476 fConnected: 0 fRemembered: 0 fAuthenicated: 0 + // Wiimote already paired(driver installed): Name: Nintendo RVL-CNT-01 ClassOfDevice: 9476 fConnected: 32 fRemembered: 16 fAuthenicated: 0 + // Wiimote paired but disc.(driver still active): Name: Nintendo RVL-CNT-01 ClassOfDevice: 9476 fConnected: 0 fRemembered: 16 fAuthenicated: 0 + //TODO: improve the readd of the BT driver, esp. when batteries of the wiimote are removed while beeing 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); + } + + // If this is not done, the Wii device will not remember the pairing + // same thing here, it should return ERROR_SUCCESS, or ERROR_MORE_DATA if the wiimote + // offers more than 16 services (pcServices). + //BluetoothEnumerateInstalledServices(hRadios[radio], &btdi, &pcServices, guids); + + // Activate service + DWORD hr = BluetoothSetServiceState(hRadios[radio], &btdi, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE); + + ////authentication not directly neeeded, read it w/o getting corrupted driver installation. + ////MAC address is passphrase; + //WCHAR pass[6]; + //pass[0] = radioInfo.address.rgBytes[0]; + //pass[1] = radioInfo.address.rgBytes[1]; + //pass[2] = radioInfo.address.rgBytes[2]; + //pass[3] = radioInfo.address.rgBytes[3]; + //pass[4] = radioInfo.address.rgBytes[4]; + //pass[5] = radioInfo.address.rgBytes[5]; + + //// Pair with Wii device; Pairing before enumerating and setting service state will result mostly in unsuccessfull pairing. + //if (BluetoothAuthenticateDevice(NULL, hRadios[radio], &btdi, pass, 6) != ERROR_SUCCESS) + // error = TRUE; + if (!hr == ERROR_SUCCESS) + { + nPaired++; + } + else + { + ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr); + } + + } + } while (BluetoothFindNextDevice(hFind, &btdi)); + } + + SLEEP(10); + + + // Clean up + for (radio = 0; radio < nRadios; radio++) + { + CloseHandle(hRadios[radio]); + } + + return nPaired; +} +#endif + }; // end of namespace diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h index 3b973d87c3..4c59b38c2a 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h @@ -23,10 +23,13 @@ #include "wiiuse.h" #include "ChunkFile.h" + namespace WiiMoteReal { int Initialize(); +int WiimotePairUp(); + void Allocate(); void DoState(PointerWrap &p); void Shutdown(void);