234 changes: 95 additions & 139 deletions Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp
Expand Up @@ -15,131 +15,123 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/

#include <sys/time.h>
#include <errno.h>

#include <sys/types.h>
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/l2cap.h>

#include "Common.h"
#include "WiimoteReal.h"
#include "Host.h"

namespace WiimoteReal
{

// Find wiimotes.
// Does not replace already found wiimotes even if they are disconnected.
// wm is an array of max_wiimotes wiimotes
// Returns the total number of found wiimotes.
int FindWiimotes(Wiimote** wm, int max_wiimotes)
WiimoteScanner::WiimoteScanner()
: m_run_thread()
, m_want_wiimotes()
, device_id(-1)
, device_sock(-1)
{
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 (wm[i])
found_wiimotes++;
}

// Get the id of the first bluetooth device.
if ((device_id = hci_get_route(NULL)) < 0)
device_id = hci_get_route(NULL);
if (device_id < 0)
{
NOTICE_LOG(WIIMOTE, "Bluetooth not found.");
return found_wiimotes;
return;
}

// Create a socket to the device
if ((device_sock = hci_open_dev(device_id)) < 0)
device_sock = hci_open_dev(device_id);
if (device_sock < 0)
{
ERROR_LOG(WIIMOTE, "Unable to open bluetooth.");
return found_wiimotes;
return;
}
}

int try_num = 0;
while ((try_num < 5) && (found_wiimotes < max_wiimotes))
bool WiimoteScanner::IsReady() const
{
return device_sock > 0;
}

WiimoteScanner::~WiimoteScanner()
{
if (IsReady())
close(device_sock);
}

void WiimoteScanner::Update()
{}

std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
{
std::vector<Wiimote*> found_wiimotes;

// supposedly 1.28 seconds
int const wait_len = 1;

int const max_infos = 255;
inquiry_info scan_infos[max_infos] = {};
auto* scan_infos_ptr = scan_infos;

// Scan for bluetooth devices
int const found_devices = hci_inquiry(device_id, wait_len, max_infos, NULL, &scan_infos_ptr, IREQ_CACHE_FLUSH);
if (found_devices < 0)
{
inquiry_info scan_info_arr[128];
inquiry_info* scan_info = scan_info_arr;
memset(&scan_info_arr, 0, sizeof(scan_info_arr));
ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices.");
return found_wiimotes;
}

DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices);

// Scan for bluetooth devices for approximately one second
found_devices = hci_inquiry(device_id, 1, 128, NULL, &scan_info, IREQ_CACHE_FLUSH);
if (found_devices < 0)
// Display discovered devices
for (int i = 0; i < found_devices; ++i)
{
ERROR_LOG(WIIMOTE, "found a device...");

// BT names are a maximum of 248 bytes apparently
char name[255] = {};
if (hci_read_remote_name(device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 0) < 0)
{
ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices.");
return found_wiimotes;
ERROR_LOG(WIIMOTE, "name request failed");
continue;
}

DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices);

// Display discovered devices
for (i = 0; (i < found_devices) && (found_wiimotes < max_wiimotes); ++i)
ERROR_LOG(WIIMOTE, "device name %s", name);
if (IsValidBluetoothName(name))
{
char name[1000];
memset(name, 0, sizeof(name));
ERROR_LOG(WIIMOTE, "found a device...");
if (hci_read_remote_name(device_sock, &scan_info[i].bdaddr, sizeof(name), name, 0) < 0) {
ERROR_LOG(WIIMOTE, "name request failed");
continue;
}
ERROR_LOG(WIIMOTE, "device name %s", name);
if (IsValidBluetoothName(name))
bool new_wiimote = true;

// TODO: do this

// Determine if this wiimote has already been found.
//for (int j = 0; j < MAX_WIIMOTES && new_wiimote; ++j)
//{
// if (wm[j] && bacmp(&scan_infos[i].bdaddr,&wm[j]->bdaddr) == 0)
// new_wiimote = false;
//}

if (new_wiimote)
{
bool new_wiimote = true;
// Determine if this wiimote has already been found.
for (int j = 0; j < MAX_WIIMOTES && new_wiimote; ++j)
{
if (wm[j] && bacmp(&scan_info[i].bdaddr,&wm[j]->bdaddr) == 0)
new_wiimote = false;
}

if (new_wiimote)
{
// Find an unused slot
unsigned int k = 0;
for (; k < MAX_WIIMOTES && !(WIIMOTE_SRC_REAL & g_wiimote_sources[k] && !wm[k]); ++k);
wm[k] = new Wiimote(k);

// Found a new device
char bdaddr_str[18];
ba2str(&scan_info[i].bdaddr, bdaddr_str);

NOTICE_LOG(WIIMOTE, "Found wiimote %i, (%s).",
wm[k]->index + 1, bdaddr_str);

wm[k]->bdaddr = scan_info[i].bdaddr;
++found_wiimotes;
}
// Found a new device
char bdaddr_str[18] = {};
ba2str(&scan_infos[i].bdaddr, bdaddr_str);

auto* const wm = new Wiimote;
wm->bdaddr = scan_infos[i].bdaddr;
found_wiimotes.push_back(wm);

NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str);
}
}
try_num++;
}

close(device_sock);
return found_wiimotes;
}

// Connect to a wiimote with a known address.
bool Wiimote::Connect()
{
if (IsConnected())
return false;

sockaddr_l2 addr;
addr.l2_family = AF_BLUETOOTH;
addr.l2_bdaddr = bdaddr;
Expand All @@ -148,7 +140,7 @@ bool Wiimote::Connect()
// Output channel
addr.l2_psm = htobs(WM_OUTPUT_CHANNEL);
if ((cmd_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1 ||
connect(cmd_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
connect(cmd_sock, (sockaddr*)&addr, sizeof(addr)) < 0)
{
DEBUG_LOG(WIIMOTE, "Unable to open output socket to wiimote.");
close(cmd_sock);
Expand All @@ -159,7 +151,7 @@ bool Wiimote::Connect()
// Input channel
addr.l2_psm = htobs(WM_INPUT_CHANNEL);
if ((int_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1 ||
connect(int_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
connect(int_sock, (sockaddr*)&addr, sizeof(addr)) < 0)
{
DEBUG_LOG(WIIMOTE, "Unable to open input socket from wiimote.");
close(int_sock);
Expand All @@ -168,57 +160,27 @@ bool Wiimote::Connect()
return false;
}

NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", index + 1);

m_connected = true;

// Do the handshake
Handshake();

// Set LEDs
SetLEDs(WIIMOTE_LED_1 << index);

m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this);

return true;
}

// Disconnect a wiimote.
void Wiimote::RealDisconnect()
{
if (!IsConnected())
return;

NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i.", index + 1);

m_connected = false;

if (m_wiimote_thread.joinable())
m_wiimote_thread.join();

Close();
}

void Wiimote::Close()
void Wiimote::Disconnect()
{
if (IsOpen())
{
Host_ConnectWiimote(index, false);
close(cmd_sock);
close(int_sock);

close(cmd_sock);
close(int_sock);

cmd_sock = -1;
int_sock = -1;
}
cmd_sock = -1;
int_sock = -1;
}

bool Wiimote::IsOpen() const
bool Wiimote::IsConnected() const
{
return IsConnected() && cmd_sock != -1 && int_sock != -1;
return cmd_sock != -1;// && int_sock != -1;
}

int Wiimote::IORead(unsigned char *buf)
// positive = read packet
// negative = didn't read packet
// zero = error
int Wiimote::IORead(u8* buf)
{
// Block select for 1/2000th of a second
timeval tv;
Expand All @@ -232,11 +194,11 @@ int Wiimote::IORead(unsigned char *buf)
if (select(int_sock + 1, &fds, NULL, NULL, &tv) == -1)
{
ERROR_LOG(WIIMOTE, "Unable to select wiimote %i input socket.", index + 1);
return 0;
return -1;
}

if (!FD_ISSET(int_sock, &fds))
return 0;
return -1;

// Read the pending message into the buffer
int r = read(int_sock, buf, MAX_PAYLOAD);
Expand All @@ -250,21 +212,15 @@ int Wiimote::IORead(unsigned char *buf)
// This can happen if the bluetooth dongle is disconnected
ERROR_LOG(WIIMOTE, "Bluetooth appears to be disconnected. "
"Wiimote %i will be disconnected.", index + 1);
Close();
}

return 0;
}
else if (!r)
{
// Disconnect
Close();
r = 0;
}

return r;
}

int Wiimote::IOWrite(unsigned char* buf, int len)
int Wiimote::IOWrite(u8 const* buf, int len)
{
return write(int_sock, buf, len);
}
Expand Down
542 changes: 295 additions & 247 deletions Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp

Large diffs are not rendered by default.

125 changes: 68 additions & 57 deletions Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm
Expand Up @@ -40,8 +40,11 @@ - (void) l2capChannelData: (IOBluetoothL2CAPChannel *) l2capChannel
{
IOBluetoothDevice *device = [l2capChannel getDevice];
WiimoteReal::Wiimote *wm = NULL;

std::lock_guard<std::recursive_mutex> lk(WiimoteReal::g_refresh_lock);

for (int i = 0; i < MAX_WIIMOTES; i++) {
for (int i = 0; i < MAX_WIIMOTES; i++)
{
if (WiimoteReal::g_wiimotes[i] == NULL)
continue;
if ([device isEqual: WiimoteReal::g_wiimotes[i]->btd] == TRUE)
Expand Down Expand Up @@ -77,8 +80,11 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel
{
IOBluetoothDevice *device = [l2capChannel getDevice];
WiimoteReal::Wiimote *wm = NULL;

std::lock_guard<std::recursive_mutex> lk(WiimoteReal::g_refresh_lock);

for (int i = 0; i < MAX_WIIMOTES; i++) {
for (int i = 0; i < MAX_WIIMOTES; i++)
{
if (WiimoteReal::g_wiimotes[i] == NULL)
continue;
if ([device isEqual: WiimoteReal::g_wiimotes[i]->btd] == TRUE)
Expand All @@ -92,41 +98,47 @@ - (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel

WARN_LOG(WIIMOTE, "Lost channel to wiimote %i", wm->index + 1);

wm->RealDisconnect();
wm->Disconnect();
}
@end

namespace WiimoteReal
{

// Find wiimotes.
// wm is an array of max_wiimotes wiimotes
// Returns the total number of found wiimotes.
int FindWiimotes(Wiimote **wm, int max_wiimotes)
WiimoteScanner::WiimoteScanner()
: m_run_thread()
, m_want_wiimotes()
{}

WiimoteScanner::~WiimoteScanner()
{}

void WiimoteScanner::Update()
{}

std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
{
// TODO: find the device in the constructor and save it for later

std::vector<Wiimote*> wiimotes;
IOBluetoothHostController *bth;
IOBluetoothDeviceInquiry *bti;
SearchBT *sbt;
NSEnumerator *en;
int found_devices = 0, found_wiimotes = 0;

// Count the number of already found wiimotes
for (int i = 0; i < MAX_WIIMOTES; ++i)
if (wm[i])
found_wiimotes++;

bth = [[IOBluetoothHostController alloc] init];
if ([bth addressAsString] == nil) {
if ([bth addressAsString] == nil)
{
WARN_LOG(WIIMOTE, "No bluetooth host controller");
[bth release];
return found_wiimotes;
return wiimotes;
}

sbt = [[SearchBT alloc] init];
sbt->maxDevices = max_wiimotes - found_wiimotes;
sbt->maxDevices = 32;
bti = [[IOBluetoothDeviceInquiry alloc] init];
[bti setDelegate: sbt];
[bti setInquiryLength: 5];
[bti setInquiryLength: 2];

if ([bti start] == kIOReturnSuccess)
[bti retain];
Expand All @@ -136,53 +148,55 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes)
CFRunLoopRun();

[bti stop];
found_devices = [[bti foundDevices] count];
int found_devices = [[bti foundDevices] count];

NOTICE_LOG(WIIMOTE, "Found %i bluetooth device%c", found_devices,
found_devices == 1 ? '\0' : 's');
if (found_devices)
NOTICE_LOG(WIIMOTE, "Found %i bluetooth devices", found_devices);

en = [[bti foundDevices] objectEnumerator];
for (int i = 0; i < found_devices; i++)
{
IOBluetoothDevice *dev = [en nextObject];
if (!IsValidBluetoothName([[dev name] UTF8String]))
continue;
// Find an unused slot
for (int k = 0; k < MAX_WIIMOTES; k++) {
if (wm[k] != NULL ||
!(g_wiimote_sources[k] & WIIMOTE_SRC_REAL))
continue;

wm[k] = new Wiimote(k);
wm[k]->btd = dev;
found_wiimotes++;
break;
}

Wiimote *wm = new Wiimote();
wm->btd = dev;
wiimotes.push_back(wm);
}

[bth release];
[bti release];
[sbt release];

return found_wiimotes;
return wiimotes;
}

bool WiimoteScanner::IsReady() const
{
// TODO: only return true when a BT device is present
return true;
}

// Connect to a wiimote with a known address.
bool Wiimote::Connect()
{
ConnectBT *cbt = [[ConnectBT alloc] init];

if (IsConnected())
return false;

ConnectBT *cbt = [[ConnectBT alloc] init];

[btd openL2CAPChannelSync: &cchan
withPSM: kBluetoothL2CAPPSMHIDControl delegate: cbt];
[btd openL2CAPChannelSync: &ichan
withPSM: kBluetoothL2CAPPSMHIDInterrupt delegate: cbt];
if (ichan == NULL || cchan == NULL) {
if (ichan == NULL || cchan == NULL)
{
ERROR_LOG(WIIMOTE, "Unable to open L2CAP channels "
"for wiimote %i", index + 1);
RealDisconnect();
Disconnect();

[cbt release];
return false;
}

Expand All @@ -196,40 +210,37 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes)

m_connected = true;

Handshake();
SetLEDs(WIIMOTE_LED_1 << index);

m_wiimote_thread = std::thread(std::mem_fun(&Wiimote::ThreadFunc), this);

[cbt release];

return true;
}

// Disconnect a wiimote.
void Wiimote::RealDisconnect()
void Wiimote::Disconnect()
{
if (!IsConnected())
return;

NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i", index + 1);
if (btd != NULL)
[btd closeConnection];

m_connected = false;
if (ichan != NULL)
[ichan release];

if (m_wiimote_thread.joinable())
m_wiimote_thread.join();
if (cchan != NULL)
[cchan release];

[btd closeConnection];
[ichan release];
[cchan release];
btd = NULL;
cchan = NULL;
ichan = NULL;

if (!IsConnected())
return;

NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i", index + 1);

m_connected = false;
}

bool Wiimote::IsOpen() const
bool Wiimote::IsConnected() const
{
return IsConnected();
return m_connected;
}

int Wiimote::IORead(unsigned char *buf)
Expand All @@ -246,14 +257,14 @@ int FindWiimotes(Wiimote **wm, int max_wiimotes)
return bytes;
}

int Wiimote::IOWrite(unsigned char *buf, int len)
int Wiimote::IOWrite(const unsigned char *buf, int len)
{
IOReturn ret;

if (!IsConnected())
return 0;

ret = [ichan writeAsync: buf length: len refcon: nil];
ret = [ichan writeAsync: const_cast<void*>((void *)buf) length: len refcon: nil];

if (ret == kIOReturnSuccess)
return len;
Expand Down
541 changes: 340 additions & 201 deletions Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp

Large diffs are not rendered by default.

88 changes: 68 additions & 20 deletions Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h
Expand Up @@ -20,6 +20,7 @@
#define WIIMOTE_REAL_H

#include <functional>
#include <vector>

#include "WiimoteRealBase.h"
#include "ChunkFile.h"
Expand All @@ -42,7 +43,7 @@ class Wiimote : NonCopyable
{
friend class WiimoteEmu::Wiimote;
public:
Wiimote(const unsigned int _index);
Wiimote();
~Wiimote();

void ControlChannel(const u16 channel, const void* const data, const u32 size);
Expand All @@ -53,62 +54,108 @@ friend class WiimoteEmu::Wiimote;

bool Read();
bool Write();

void StartThread();
void StopThread();

// "handshake" / stop packets
void EmuStart();
void EmuStop();

// connecting and disconnecting from physical devices
// (using address inserted by FindWiimotes)
bool Connect();
bool IsConnected() const;
bool IsOpen() const;
void Disconnect();

// TODO: change to something like IsRelevant
bool IsConnected() const;

bool Prepare(int index);

void DisableDataReporting();
void Rumble();
void SendPacket(const u8 rpt_id, const void* const data, const unsigned int size);
void RealDisconnect();

void QueueReport(u8 rpt_id, const void* data, unsigned int size);

const unsigned int index;
int index;

#if defined(__APPLE__)
IOBluetoothDevice *btd;
IOBluetoothL2CAPChannel *ichan;
IOBluetoothL2CAPChannel *cchan;
char input[MAX_PAYLOAD];
int inputlen;
bool m_connected;
#elif defined(__linux__) && HAVE_BLUEZ
bdaddr_t bdaddr; // Bluetooth address
int cmd_sock; // Command socket
int int_sock; // Interrupt socket

void Close();

#elif defined(_WIN32)
std::string devicepath; // Unique wiimote reference
//ULONGLONG btaddr; // Bluetooth address
HANDLE dev_handle; // HID handle
OVERLAPPED hid_overlap; // Overlap handle
OVERLAPPED hid_overlap_read, hid_overlap_write; // Overlap handle
enum win_bt_stack_t stack; // Type of bluetooth stack to use
#endif
unsigned char leds; // Currently lit leds

protected:
Report m_last_data_report;
u16 m_channel;

private:
void ClearReadQueue();
bool SendRequest(unsigned char report_type, unsigned char* data, int length);
bool Handshake();
void SetLEDs(int leds);
int IORead(unsigned char* buf);
int IOWrite(unsigned char* buf, int len);

int IORead(u8* buf);
int IOWrite(u8 const* buf, int len);

void ThreadFunc();

bool m_connected;
bool m_run_thread;
std::thread m_wiimote_thread;

Common::FifoQueue<Report> m_read_reports;
Common::FifoQueue<Report> m_write_reports;
Common::FifoQueue<Report> m_audio_reports;

Common::Timer last_audio_report;
Common::Timer m_last_audio_report;
};

class WiimoteScanner
{
public:
WiimoteScanner();
~WiimoteScanner();

bool IsReady() const;

void WantWiimotes(bool do_want);

void StartScanning();
void StopScanning();

std::vector<Wiimote*> FindWiimotes();

// function called when not looking for more wiimotes
void Update();

private:
void ThreadFunc();

std::thread m_scan_thread;

volatile bool m_run_thread;
volatile bool m_want_wiimotes;

#if defined(_WIN32)


#elif defined(__linux__) && HAVE_BLUEZ
int device_id;
int device_sock;
#endif
};

extern std::mutex g_refresh_lock;
extern std::recursive_mutex g_refresh_lock;
extern WiimoteScanner g_wiimote_scanner;
extern Wiimote *g_wiimotes[4];

void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size);
Expand All @@ -119,6 +166,7 @@ void DoState(PointerWrap &p);
void StateChange(EMUSTATE_CHANGE newState);

int FindWiimotes(Wiimote** wm, int max_wiimotes);
void ChangeWiimoteSource(unsigned int index, int source);

bool IsValidBluetoothName(const std::string& name);

Expand Down
6 changes: 4 additions & 2 deletions Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h
Expand Up @@ -41,6 +41,7 @@
#define WM_SET_REPORT 0xA0
#endif

// TODO: duplicated in WiimoteHid.h
// Commands
#define WM_CMD_RUMBLE 0x10
#define WM_CMD_LED 0x11
Expand All @@ -66,8 +67,9 @@

// End Wiimote internal codes

#define MAX_PAYLOAD 32
#define WIIMOTE_DEFAULT_TIMEOUT 30
// It's 23. NOT 32!
#define MAX_PAYLOAD 23
#define WIIMOTE_DEFAULT_TIMEOUT 1000

#ifdef _WIN32
// Available bluetooth stacks for Windows.
Expand Down
3 changes: 1 addition & 2 deletions Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_WiiMote.cpp
Expand Up @@ -211,8 +211,7 @@ void CWII_IPC_HLE_WiiMote::EventConnectionAccepted()
void CWII_IPC_HLE_WiiMote::EventDisconnect()
{
// Send disconnect message to plugin
u8 Message = WIIMOTE_DISCONNECT;
Wiimote::ControlChannel(m_ConnectionHandle & 0xFF, 99, &Message, 0);
Wiimote::ControlChannel(m_ConnectionHandle & 0xFF, 99, NULL, 0);

m_ConnectionState = CONN_INACTIVE;
// Clear channel flags
Expand Down
31 changes: 0 additions & 31 deletions Source/Core/DolphinWX/Src/Frame.cpp
Expand Up @@ -100,37 +100,6 @@ CPanel::CPanel(
else
SetCursor(wxNullCursor);
break;

case WIIMOTE_DISCONNECT:
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
{
const int wiimote_idx = lParam;
const int wiimote_num = wiimote_idx + 1;

//Auto reconnect if option is turned on.
//TODO: Make this only auto reconnect wiimotes that have the option activated.
SConfig::GetInstance().LoadSettingsWii();//Make sure we are using the newest settings.
if (SConfig::GetInstance().m_WiiAutoReconnect[wiimote_idx])
{
GetUsbPointer()->AccessWiiMote(wiimote_idx | 0x100)->Activate(true);
NOTICE_LOG(WIIMOTE, "Wiimote %i has been auto-reconnected...", wiimote_num);
}
else
{
// The Wiimote has been disconnected, we offer reconnect here.
wxMessageDialog *dlg = new wxMessageDialog(
this,
wxString::Format(_("Wiimote %i has been disconnected by system.\nMaybe this game doesn't support multi-wiimote,\nor maybe it is due to idle time out or other reason.\nDo you want to reconnect immediately?"), wiimote_num),
_("Reconnect Wiimote Confirm"),
wxYES_NO | wxSTAY_ON_TOP | wxICON_INFORMATION, //wxICON_QUESTION,
wxDefaultPosition);

if (dlg->ShowModal() == wxID_YES)
GetUsbPointer()->AccessWiiMote(wiimote_idx | 0x100)->Activate(true);

dlg->Destroy();
}
}
}
break;

Expand Down
4 changes: 0 additions & 4 deletions Source/Core/DolphinWX/Src/FrameTools.cpp
Expand Up @@ -1355,10 +1355,6 @@ void CFrame::ConnectWiimote(int wm_idx, bool connect)
wxString msg(wxString::Format(wxT("Wiimote %i %s"), wm_idx + 1,
connect ? wxT("Connected") : wxT("Disconnected")));
Core::DisplayMessage(msg.ToAscii(), 3000);

// Wait for the wiimote to connect
while (GetUsbPointer()->AccessWiiMote(wm_idx | 0x100)->IsConnected() != connect)
{}
Host_UpdateMainFrame();
}
}
Expand Down
4 changes: 0 additions & 4 deletions Source/Core/DolphinWX/Src/Main.cpp
Expand Up @@ -390,10 +390,6 @@ void DolphinApp::InitLanguageSupport()
int DolphinApp::OnExit()
{
WiimoteReal::Shutdown();
#ifdef _WIN32
if (SConfig::GetInstance().m_WiiAutoUnpair)
WiimoteReal::UnPair();
#endif
VideoBackend::ClearList();
SConfig::Shutdown();
LogManager::Shutdown();
Expand Down
93 changes: 25 additions & 68 deletions Source/Core/DolphinWX/Src/WiimoteConfigDiag.cpp
Expand Up @@ -4,13 +4,6 @@
#include "HW/WiimoteReal/WiimoteReal.h"
#include "Frame.h"

const wxString& ConnectedWiimotesString()
{
static wxString str;
str.Printf(_("%i connected"), WiimoteReal::Initialize());
return str;
}

WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin)
: wxDialog(parent, -1, _("Dolphin Wiimote Configuration"), wxDefaultPosition, wxDefaultSize)
, m_plugin(plugin)
Expand Down Expand Up @@ -64,27 +57,31 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin


// "Real wiimotes" controls
connected_wiimotes_txt = new wxStaticText(this, -1, ConnectedWiimotesString());

wxButton* const refresh_btn = new wxButton(this, -1, _("Refresh"), wxDefaultPosition);
refresh_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::RefreshRealWiimotes, this);

#ifdef _WIN32
wxButton* const pairup_btn = new wxButton(this, -1, _("Pair Up"), wxDefaultPosition);
pairup_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::PairUpRealWiimotes, this);
#endif


// "Real wiimotes" layout
wxStaticBoxSizer* const real_wiimotes_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Real Wiimotes"));
wxFlexGridSizer* const real_wiimotes_sizer = new wxFlexGridSizer(3, 5, 5);
real_wiimotes_sizer->Add(connected_wiimotes_txt, 0, wxALIGN_CENTER_VERTICAL);
#ifdef _WIN32
real_wiimotes_sizer->Add(pairup_btn);
#endif
real_wiimotes_sizer->Add(refresh_btn);
real_wiimotes_group->Add(real_wiimotes_sizer, 1, wxALL, 5);

wxStaticBoxSizer* const real_wiimotes_group = new wxStaticBoxSizer(wxVERTICAL, this, _("Real Wiimotes"));

wxBoxSizer* const real_wiimotes_sizer = new wxBoxSizer(wxHORIZONTAL);

if (!WiimoteReal::g_wiimote_scanner.IsReady())
real_wiimotes_group->Add(new wxStaticText(this, -1, _("A supported bluetooth device could not be found.\n"
"You must manually connect your wiimotes.")), 0, wxALIGN_CENTER | wxALL, 5);

wxCheckBox* const continuous_scanning = new wxCheckBox(this, wxID_ANY, _("Continuous Scanning"));
continuous_scanning->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnContinuousScanning, this);
continuous_scanning->SetValue(SConfig::GetInstance().m_WiimoteContinuousScanning);

auto wiimote_speaker = new wxCheckBox(this, wxID_ANY, _("Enable Speaker Data"));
wiimote_speaker->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &WiimoteConfigDiag::OnEnableSpeaker, this);
wiimote_speaker->SetValue(SConfig::GetInstance().m_WiimoteEnableSpeaker);

real_wiimotes_sizer->Add(continuous_scanning, 0, wxALIGN_CENTER_VERTICAL);
real_wiimotes_sizer->AddStretchSpacer(1);
real_wiimotes_sizer->Add(refresh_btn, 0, wxALL | wxALIGN_CENTER, 5);

real_wiimotes_group->Add(wiimote_speaker, 0);
real_wiimotes_group->Add(real_wiimotes_sizer, 0, wxEXPAND);

// "General Settings" controls
const wxString str[] = { _("Bottom"), _("Top") };
Expand Down Expand Up @@ -188,64 +185,25 @@ void WiimoteConfigDiag::ConfigEmulatedWiimote(wxCommandEvent& ev)
m_emu_config_diag->Destroy();
}

void WiimoteConfigDiag::UpdateGUI()
{
connected_wiimotes_txt->SetLabel(ConnectedWiimotesString());
}

#ifdef _WIN32
void WiimoteConfigDiag::PairUpRealWiimotes(wxCommandEvent&)
{
const int paired = WiimoteReal::PairUp();

if (paired > 0)
{
// TODO: Maybe add a label of newly paired up wiimotes?
WiimoteReal::Refresh();
UpdateGUI();
}
else if (paired < 0)
PanicAlertT("A supported bluetooth device could not be found!\n"
"If you are not using Microsoft's bluetooth stack "
"you must manually pair your wiimotes and use only the \"Refresh\" button.");
}
#endif

void WiimoteConfigDiag::RefreshRealWiimotes(wxCommandEvent&)
{
WiimoteReal::Refresh();
UpdateGUI();
}

void WiimoteConfigDiag::SelectSource(wxCommandEvent& event)
{
// This needs to be changed now in order for refresh to work right.
// Revert if the dialog is canceled.
int index = m_wiimote_index_from_ctrl_id[event.GetId()];
g_wiimote_sources[index] = event.GetInt();

WiimoteReal::ChangeWiimoteSource(index, event.GetInt());

if (g_wiimote_sources[index] != WIIMOTE_SRC_EMU && g_wiimote_sources[index] != WIIMOTE_SRC_HYBRID)
wiimote_configure_bt[index]->Disable();
else
wiimote_configure_bt[index]->Enable();
}

void WiimoteConfigDiag::UpdateWiimoteStatus()
{
for (int index = 0; index < 4; ++index)
{
if (m_orig_wiimote_sources[index] != g_wiimote_sources[index])
{
// Disconnect first, otherwise the new source doesn't seem to work
CFrame::ConnectWiimote(index, false);
// Connect wiimotes
if (WIIMOTE_SRC_EMU & g_wiimote_sources[index])
CFrame::ConnectWiimote(index, true);
else if (WIIMOTE_SRC_REAL & g_wiimote_sources[index] && WiimoteReal::g_wiimotes[index])
CFrame::ConnectWiimote(index, WiimoteReal::g_wiimotes[index]->IsConnected());
}
}
}

void WiimoteConfigDiag::RevertSource()
{
for (int i = 0; i < 4; ++i)
Expand All @@ -267,7 +225,6 @@ void WiimoteConfigDiag::Save(wxCommandEvent& event)

sec.Set("Source", (int)g_wiimote_sources[i]);
}
UpdateWiimoteStatus();

inifile.Save(ini_filename);

Expand Down
20 changes: 11 additions & 9 deletions Source/Core/DolphinWX/Src/WiimoteConfigDiag.h
Expand Up @@ -24,20 +24,13 @@ class WiimoteConfigDiag : public wxDialog
public:
WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin);

#ifdef _WIN32
void PairUpRealWiimotes(wxCommandEvent& event);
#endif
void RefreshRealWiimotes(wxCommandEvent& event);


void SelectSource(wxCommandEvent& event);
void UpdateWiimoteStatus();
void RevertSource();


void ConfigEmulatedWiimote(wxCommandEvent& event);
void Save(wxCommandEvent& event);
void UpdateGUI();

void OnSensorBarPos(wxCommandEvent& event)
{
Expand All @@ -64,6 +57,17 @@ class WiimoteConfigDiag : public wxDialog
SConfig::GetInstance().m_WiimoteReconnectOnLoad = event.IsChecked();
event.Skip();
}
void OnContinuousScanning(wxCommandEvent& event)
{
SConfig::GetInstance().m_WiimoteContinuousScanning = event.IsChecked();
WiimoteReal::Initialize();
event.Skip();
}
void OnEnableSpeaker(wxCommandEvent& event)
{
SConfig::GetInstance().m_WiimoteEnableSpeaker = event.IsChecked();
event.Skip();
}

private:
void Cancel(wxCommandEvent& event);
Expand All @@ -76,8 +80,6 @@ class WiimoteConfigDiag : public wxDialog

wxButton* wiimote_configure_bt[4];
std::map<wxWindowID, unsigned int> m_wiimote_index_from_conf_bt_id;

wxStaticText* connected_wiimotes_txt;
};


Expand Down
4 changes: 0 additions & 4 deletions Source/Core/VideoCommon/Src/EmuWindow.cpp
Expand Up @@ -205,10 +205,6 @@ LRESULT CALLBACK WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
OnKeyDown(lParam);
FreeLookInput((u32)wParam, lParam);
}
else if (wParam == WIIMOTE_DISCONNECT)
{
PostMessage(m_hParent, WM_USER, wParam, lParam);
}
break;

// Called when a screensaver wants to show up while this window is active
Expand Down