diff --git a/Externals/WiiUseSrc/Src/io_nix.c b/Externals/WiiUseSrc/Src/io_nix.c index 7bfc996199..129a611fcd 100644 --- a/Externals/WiiUseSrc/Src/io_nix.c +++ b/Externals/WiiUseSrc/Src/io_nix.c @@ -131,6 +131,84 @@ int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { return found_wiimotes; } +// Scan for more wiimotes and add them to the wm structure. +// Does not replace already found wiimotes even if they are disconnected. +// Returns the total number of found wiimotes. +// It would probably be safe to replace wiiuse_find with this function. The only thing +// it does that this does not is reset the bdaddr fields. +int wiiuse_find_more(struct wiimote_t** wm, int max_wiimotes, int timeout) { +int device_id; +int device_sock; +int found_devices; +int found_wiimotes = 0; +int i; + +// Count the number of already found wiimotes +for (i = 0; i < max_wiimotes; ++i) { + if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND)) + found_wiimotes++; +} + +// get the id of the first bluetooth device. +device_id = hci_get_route(NULL); +if (device_id < 0) { + perror("hci_get_route"); + return 0; +} + +// create a socket to the device +device_sock = hci_open_dev(device_id); +if (device_sock < 0) { + perror("hci_open_dev"); + return 0; +} + +inquiry_info scan_info_arr[128]; +inquiry_info* scan_info = scan_info_arr; +memset(&scan_info_arr, 0, sizeof(scan_info_arr)); + +// scan for bluetooth devices for timeout seconds +found_devices = hci_inquiry(device_id, timeout, 128, NULL, &scan_info, IREQ_CACHE_FLUSH); +if (found_devices < 0) { + perror("hci_inquiry"); + return 0; +} + +WIIUSE_INFO("Found %i bluetooth device(s).", found_devices); + +// display discovered devices +for (i = 0; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i) { + if ((scan_info[i].dev_class[0] == WM_DEV_CLASS_0) && + (scan_info[i].dev_class[1] == WM_DEV_CLASS_1) && + (scan_info[i].dev_class[2] == WM_DEV_CLASS_2)) + { + int new_wiimote = 1; + int j; + // Determine if this wiimote has already been found. + for (j = 0; j < found_wiimotes && new_wiimote; ++j) + { + if (WIIMOTE_IS_SET(wm[j], WIIMOTE_STATE_DEV_FOUND) && + bacmp(&scan_info[i].bdaddr,&wm[j]->bdaddr) == 0) + new_wiimote = 0; + } + + if (new_wiimote) + { + // found a new device + ba2str(&scan_info[i].bdaddr, wm[found_wiimotes]->bdaddr_str); + + WIIUSE_INFO("Found wiimote (%s) [id %i].", wm[found_wiimotes]->bdaddr_str, wm[found_wiimotes]->unid); + + wm[found_wiimotes]->bdaddr = scan_info[i].bdaddr; + WIIMOTE_ENABLE_STATE(wm[found_wiimotes], WIIMOTE_STATE_DEV_FOUND); + ++found_wiimotes; + } + } +} + +close(device_sock); +return found_wiimotes; +} /** * @brief Connect to a wiimote or wiimotes once an address is known. diff --git a/Externals/WiiUseSrc/Src/wiiuse.h b/Externals/WiiUseSrc/Src/wiiuse.h index 4f93da46ed..5883fbf7c6 100644 --- a/Externals/WiiUseSrc/Src/wiiuse.h +++ b/Externals/WiiUseSrc/Src/wiiuse.h @@ -701,6 +701,10 @@ WIIUSE_EXPORT extern int wiiuse_check_system_notification(unsigned int nMsg, WPA WIIUSE_EXPORT extern int wiiuse_register_system_notification(HWND hwnd); #endif +#ifdef __linux__ +int wiiuse_find_more(struct wiimote_t** wm, int max_wiimotes, int timeout); +#endif + /* ir.c */ WIIUSE_EXPORT extern void wiiuse_set_ir(struct wiimote_t* wm, int status); WIIUSE_EXPORT extern void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos); diff --git a/Source/Core/InputCommon/Src/UDPWiimote.cpp b/Source/Core/InputCommon/Src/UDPWiimote.cpp index d48a58fdcb..7a5f586cfa 100644 --- a/Source/Core/InputCommon/Src/UDPWiimote.cpp +++ b/Source/Core/InputCommon/Src/UDPWiimote.cpp @@ -198,6 +198,7 @@ void UDPWiimote::mainThread() UDPWiimote::~UDPWiimote() { d->exit=true; + d->thread->WaitForDeath(); d->termLock.Enter(); d->termLock.Leave(); for (std::list::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++) diff --git a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp index a352699812..0c88f4b4f4 100644 --- a/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp +++ b/Source/Plugins/Plugin_WiimoteNew/Src/WiimoteReal/WiimoteReal.cpp @@ -102,6 +102,11 @@ Wiimote::Wiimote(wiimote_t* const wm, const unsigned int index) //SendPacket(g_wiimotes_from_wiiuse[i], WM_LEDS, &rpt, sizeof(rpt)); //} + // Rumble briefly + wiiuse_rumble(m_wiimote, 1); + SLEEP(200); + wiiuse_rumble(m_wiimote, 0); + // set LEDs wiiuse_set_leds(m_wiimote, WIIMOTE_LED_1 << m_index); @@ -340,12 +345,54 @@ void Shutdown(void) wiiuse_cleanup(g_wiimotes_from_wiiuse, MAX_WIIMOTES); } +#ifdef __linux__ +void Refresh() +{ + // find the number of slots configured for real wiimotes + unsigned int wanted_wiimotes = 0; + for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) + if (g_wiimote_sources[i] == WIIMOTE_SRC_REAL) + ++wanted_wiimotes; + + // don't scan for wiimotes if we don't want any more + if (wanted_wiimotes <= g_wiimotes_found) + return; + + // scan for wiimotes + unsigned int num_wiimotes = wiiuse_find_more(g_wiimotes_from_wiiuse, wanted_wiimotes, 5); + + DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted", num_wiimotes, wanted_wiimotes); + + int num_new_wiimotes = wiiuse_connect(g_wiimotes_from_wiiuse, num_wiimotes); + + DEBUG_LOG(WIIMOTE, "Connected to %i additional Real Wiimotes", num_new_wiimotes); + + g_wiimote_critsec.Enter(); // enter + + // create real wiimote class instances, and assign wiimotes for the new wiimotes + for (unsigned int i = g_wiimotes_found, w = g_wiimotes_found; + i < MAX_WIIMOTES && w < num_wiimotes; ++i) + { + if (g_wiimote_sources[i] != WIIMOTE_SRC_REAL || g_wiimotes[i] != NULL) + continue; + + // create/assign wiimote + g_wiimotes[i] = new Wiimote(g_wiimotes_from_wiiuse[w++], i); + } + g_wiimotes_found = num_wiimotes; + + g_wiimote_critsec.Leave(); // leave + + return; +} +#else void Refresh() { // should be fine i think Shutdown(); Initialize(); } +#endif void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) {