Make the refresh button on the Wiimote New plugin add new wiimotes in linux, instead of disconnecting and reconnecting those that were already connected. This makes it possible to connect new wiimotes during a game by openning the wiimote configuration dialog and refreshing. You still need to tell dolphin that a new wiimote is connected using Ctrl+F5-F8 or the corresponding menu entries.

Also fixed a segmentation fault caused by the UDP Wiimote stuff when a thread was not properly ended.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5847 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Glenn Rice 2010-07-07 02:19:16 +00:00
parent 539f63b58b
commit c37bca75b6
4 changed files with 130 additions and 0 deletions

View File

@ -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.

View File

@ -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);

View File

@ -198,6 +198,7 @@ void UDPWiimote::mainThread()
UDPWiimote::~UDPWiimote()
{
d->exit=true;
d->thread->WaitForDeath();
d->termLock.Enter();
d->termLock.Leave();
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)

View File

@ -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)
{