mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-25 07:21:14 +01:00
Merge branch 'wii_bb'
Adds Balance Board support.
This commit is contained in:
commit
86b4a87fef
@ -394,10 +394,10 @@ void EmuThread()
|
||||
Wiimote::Initialize(g_pWindowHandle);
|
||||
|
||||
// Activate wiimotes which don't have source set to "None"
|
||||
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i)
|
||||
for (unsigned int i = 0; i != MAX_BBMOTES; ++i)
|
||||
if (g_wiimote_sources[i])
|
||||
GetUsbPointer()->AccessWiiMote(i | 0x100)->
|
||||
Activate(true);
|
||||
GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(true);
|
||||
|
||||
}
|
||||
|
||||
// The hardware is initialized.
|
||||
|
@ -42,9 +42,10 @@ void Shutdown()
|
||||
void Initialize(void* const hwnd)
|
||||
{
|
||||
// add 4 wiimotes
|
||||
for (unsigned int i = 0; i<4; ++i)
|
||||
for (unsigned int i = WIIMOTE_CHAN_0; i<MAX_BBMOTES; ++i)
|
||||
g_plugin.controllers.push_back(new WiimoteEmu::Wiimote(i));
|
||||
|
||||
|
||||
|
||||
g_controller_interface.SetHwnd(hwnd);
|
||||
g_controller_interface.Initialize();
|
||||
|
||||
@ -134,7 +135,7 @@ void Update(int _number)
|
||||
unsigned int GetAttached()
|
||||
{
|
||||
unsigned int attached = 0;
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
for (unsigned int i=0; i<MAX_BBMOTES; ++i)
|
||||
if (g_wiimote_sources[i])
|
||||
attached |= (1 << i);
|
||||
return attached;
|
||||
@ -151,7 +152,7 @@ void DoState(u8 **ptr, PointerWrap::Mode mode)
|
||||
// TODO:
|
||||
|
||||
PointerWrap p(ptr, mode);
|
||||
for (unsigned int i=0; i<4; ++i)
|
||||
for (unsigned int i=0; i<MAX_BBMOTES; ++i)
|
||||
((WiimoteEmu::Wiimote*)g_plugin.controllers[i])->DoState(p);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,16 @@
|
||||
#include "../../InputCommon/Src/InputConfig.h"
|
||||
#include "ChunkFile.h"
|
||||
|
||||
#define MAX_WIIMOTES 4
|
||||
enum {
|
||||
WIIMOTE_CHAN_0 = 0,
|
||||
WIIMOTE_CHAN_1,
|
||||
WIIMOTE_CHAN_2,
|
||||
WIIMOTE_CHAN_3,
|
||||
WIIMOTE_BALANCE_BOARD,
|
||||
MAX_WIIMOTES = WIIMOTE_BALANCE_BOARD,
|
||||
MAX_BBMOTES = 5,
|
||||
};
|
||||
|
||||
|
||||
#define WIIMOTE_INI_NAME "WiimoteNew"
|
||||
|
||||
@ -20,7 +29,7 @@ enum
|
||||
WIIMOTE_SRC_HYBRID = 3, // emu + real
|
||||
};
|
||||
|
||||
extern unsigned int g_wiimote_sources[MAX_WIIMOTES];
|
||||
extern unsigned int g_wiimote_sources[MAX_BBMOTES];
|
||||
|
||||
namespace Wiimote
|
||||
{
|
||||
|
@ -32,9 +32,10 @@ WiimoteScanner::~WiimoteScanner()
|
||||
void WiimoteScanner::Update()
|
||||
{}
|
||||
|
||||
std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
|
||||
{
|
||||
return std::vector<Wiimote*>();
|
||||
found_wiimotes.clear();
|
||||
found_board = NULL;
|
||||
}
|
||||
|
||||
bool WiimoteScanner::IsReady() const
|
||||
|
@ -63,23 +63,22 @@ WiimoteScanner::~WiimoteScanner()
|
||||
void WiimoteScanner::Update()
|
||||
{}
|
||||
|
||||
std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
|
||||
{
|
||||
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;
|
||||
|
||||
found_board = NULL;
|
||||
|
||||
// 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)
|
||||
{
|
||||
ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices.");
|
||||
return found_wiimotes;
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(WIIMOTE, "Found %i bluetooth device(s).", found_devices);
|
||||
@ -91,7 +90,7 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
|
||||
// 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)
|
||||
if (hci_read_remote_name(device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 1000) < 0)
|
||||
{
|
||||
ERROR_LOG(WIIMOTE, "name request failed");
|
||||
continue;
|
||||
@ -119,14 +118,20 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
|
||||
auto* const wm = new Wiimote;
|
||||
wm->bdaddr = scan_infos[i].bdaddr;
|
||||
found_wiimotes.push_back(wm);
|
||||
|
||||
NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str);
|
||||
if(IsBalanceBoardName(name))
|
||||
{
|
||||
found_board = wm;
|
||||
NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
found_wiimotes.push_back(wm);
|
||||
NOTICE_LOG(WIIMOTE, "Found wiimote (%s).", bdaddr_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found_wiimotes;
|
||||
}
|
||||
|
||||
// Connect to a wiimote with a known address.
|
||||
|
@ -138,6 +138,10 @@ inline void init_lib()
|
||||
|
||||
namespace WiimoteReal
|
||||
{
|
||||
|
||||
|
||||
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len);
|
||||
int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index);
|
||||
|
||||
template <typename T>
|
||||
void ProcessWiimotes(bool new_scan, T& callback);
|
||||
@ -183,7 +187,7 @@ void WiimoteScanner::Update()
|
||||
// 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 and connected wiimotes.
|
||||
std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
|
||||
{
|
||||
ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo, BLUETOOTH_DEVICE_INFO_STRUCT& btdi)
|
||||
{
|
||||
@ -198,8 +202,6 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
// Get all hid devices connected
|
||||
HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));
|
||||
|
||||
std::vector<Wiimote*> wiimotes;
|
||||
|
||||
SP_DEVICE_INTERFACE_DATA device_data;
|
||||
device_data.cbSize = sizeof(device_data);
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL;
|
||||
@ -214,10 +216,24 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
|
||||
// Query the data for this device
|
||||
if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL))
|
||||
{
|
||||
{
|
||||
auto const wm = new Wiimote;
|
||||
wm->devicepath = detail_data->DevicePath;
|
||||
wiimotes.push_back(wm);
|
||||
bool real_wiimote = false, is_bb = false;
|
||||
|
||||
CheckDeviceType(wm->devicepath, real_wiimote, is_bb);
|
||||
if (is_bb)
|
||||
{
|
||||
found_board = wm;
|
||||
}
|
||||
else if (real_wiimote)
|
||||
{
|
||||
found_wiimotes.push_back(wm);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(wm);
|
||||
}
|
||||
}
|
||||
|
||||
free(detail_data);
|
||||
@ -229,7 +245,178 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
//if (!wiimotes.empty())
|
||||
// SLEEP(2000);
|
||||
|
||||
return wiimotes;
|
||||
}
|
||||
int CheckDeviceType_Write(HANDLE &dev_handle, const u8* buf, int size, int attempts)
|
||||
{
|
||||
OVERLAPPED hid_overlap_write = OVERLAPPED();
|
||||
hid_overlap_write.hEvent = CreateEvent(NULL, true, false, NULL);
|
||||
enum win_bt_stack_t stack = MSBT_STACK_UNKNOWN;
|
||||
|
||||
DWORD written = 0;
|
||||
|
||||
for (; attempts>0; --attempts)
|
||||
{
|
||||
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, size))
|
||||
{
|
||||
auto const wait_result = WaitForSingleObject(hid_overlap_write.hEvent, WIIMOTE_DEFAULT_TIMEOUT);
|
||||
if (WAIT_TIMEOUT == wait_result)
|
||||
{
|
||||
WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A timeout occurred on writing to Wiimote.");
|
||||
CancelIo(dev_handle);
|
||||
continue;
|
||||
}
|
||||
else if (WAIT_FAILED == wait_result)
|
||||
{
|
||||
WARN_LOG(WIIMOTE, "CheckDeviceType_Write: A wait error occurred on writing to Wiimote.");
|
||||
CancelIo(dev_handle);
|
||||
continue;
|
||||
}
|
||||
if (GetOverlappedResult(dev_handle, &hid_overlap_write, &written, TRUE))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hid_overlap_write.hEvent);
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
int CheckDeviceType_Read(HANDLE &dev_handle, u8* buf, int attempts)
|
||||
{
|
||||
OVERLAPPED hid_overlap_read = OVERLAPPED();
|
||||
hid_overlap_read.hEvent = CreateEvent(NULL, true, false, NULL);
|
||||
int read = 0;
|
||||
for (; attempts>0; --attempts)
|
||||
{
|
||||
read = _IORead(dev_handle, hid_overlap_read, buf, 1);
|
||||
if (read > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
CloseHandle(hid_overlap_read.hEvent);
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
// A convoluted way of checking if a device is a Wii Balance Board and if it is a connectable Wiimote.
|
||||
// Because nothing on Windows should be easy.
|
||||
// (We can't seem to easily identify the bluetooth device an HID device belongs to...)
|
||||
void WiimoteScanner::CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb)
|
||||
{
|
||||
real_wiimote = false;
|
||||
is_bb = false;
|
||||
|
||||
#ifdef SHARE_WRITE_WIIMOTES
|
||||
std::lock_guard<std::mutex> lk(g_connected_wiimotes_lock);
|
||||
if (g_connected_wiimotes.count(devicepath) != 0)
|
||||
return;
|
||||
#endif
|
||||
|
||||
HANDLE dev_handle = CreateFile(devicepath.c_str(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
|
||||
NULL);
|
||||
if (dev_handle == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
// enable to only check for official nintendo wiimotes/bb's
|
||||
bool check_vidpid = false;
|
||||
HIDD_ATTRIBUTES attrib;
|
||||
attrib.Size = sizeof(attrib);
|
||||
if (!check_vidpid ||
|
||||
(HidD_GetAttributes(dev_handle, &attrib) &&
|
||||
(attrib.VendorID == 0x057e) &&
|
||||
(attrib.ProductID == 0x0306)))
|
||||
{
|
||||
int rc = 0;
|
||||
// max_cycles insures we are never stuck here due to bad coding...
|
||||
int max_cycles = 20;
|
||||
u8 buf[MAX_PAYLOAD] = {0};
|
||||
|
||||
u8 const req_status_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REQUEST_STATUS, 0};
|
||||
|
||||
rc = CheckDeviceType_Write(dev_handle,
|
||||
req_status_report,
|
||||
sizeof(req_status_report),
|
||||
1);
|
||||
while (rc > 0 && --max_cycles > 0)
|
||||
{
|
||||
if ((rc = CheckDeviceType_Read(dev_handle, buf, 1)) <= 0)
|
||||
{
|
||||
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: Read failed...");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (buf[1])
|
||||
{
|
||||
case WM_STATUS_REPORT:
|
||||
{
|
||||
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Status Report");
|
||||
wm_status_report * wsr = (wm_status_report*)&buf[2];
|
||||
if (wsr->extension)
|
||||
{
|
||||
// Wiimote with extension, we ask it what kind.
|
||||
u8 read_ext[MAX_PAYLOAD] = {0};
|
||||
read_ext[0] = WM_SET_REPORT | WM_BT_OUTPUT;
|
||||
read_ext[1] = WM_READ_DATA;
|
||||
// Extension type register.
|
||||
*(u32*)&read_ext[2] = Common::swap32(0x4a400fa);
|
||||
// Size.
|
||||
*(u16*)&read_ext[6] = Common::swap16(6);
|
||||
rc = CheckDeviceType_Write(dev_handle, read_ext, 8, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
real_wiimote = true;
|
||||
// Normal Wiimote, exit while and be happy.
|
||||
rc = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_ACK_DATA:
|
||||
{
|
||||
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Ack");
|
||||
break;
|
||||
}
|
||||
case WM_READ_DATA_REPLY:
|
||||
{
|
||||
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: Got Data Reply");
|
||||
wm_read_data_reply * wrdr
|
||||
= (wm_read_data_reply*)&buf[2];
|
||||
// Check if it has returned what we asked.
|
||||
if (Common::swap16(wrdr->address) == 0x00fa)
|
||||
{
|
||||
real_wiimote = true;
|
||||
// 0x020420A40000ULL means balance board.
|
||||
u64 ext_type = (*(u64*)&wrdr->data[0]);
|
||||
// DEBUG_LOG(WIIMOTE,
|
||||
// "CheckDeviceType: GOT EXT TYPE %llX",
|
||||
// ext_type);
|
||||
is_bb = ext_type == 0x020420A40000ULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(WIIMOTE,
|
||||
"CheckDeviceType: GOT UNREQUESTED ADDRESS %X",
|
||||
Common::swap16(wrdr->address));
|
||||
}
|
||||
// force end
|
||||
rc = -1;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// We let read try again incase there is another packet waiting.
|
||||
// DEBUG_LOG(WIIMOTE, "CheckDeviceType: GOT UNKNOWN REPLY: %X", buf[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(dev_handle);
|
||||
}
|
||||
|
||||
bool WiimoteScanner::IsReady() const
|
||||
@ -355,7 +542,7 @@ bool Wiimote::IsConnected() const
|
||||
// positive = read packet
|
||||
// negative = didn't read packet
|
||||
// zero = error
|
||||
int Wiimote::IORead(u8* buf)
|
||||
int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index)
|
||||
{
|
||||
// Add data report indicator byte (here, 0xa1)
|
||||
buf[0] = 0xa1;
|
||||
@ -408,78 +595,92 @@ int Wiimote::IORead(u8* buf)
|
||||
return bytes + 1;
|
||||
}
|
||||
|
||||
int Wiimote::IOWrite(const u8* buf, int len)
|
||||
// positive = read packet
|
||||
// negative = didn't read packet
|
||||
// zero = error
|
||||
int Wiimote::IORead(u8* buf)
|
||||
{
|
||||
return _IORead(dev_handle, hid_overlap_read, buf, index);
|
||||
}
|
||||
|
||||
|
||||
int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len)
|
||||
{
|
||||
switch (stack)
|
||||
{
|
||||
case MSBT_STACK_UNKNOWN:
|
||||
{
|
||||
// Try to auto-detect the stack type
|
||||
stack = MSBT_STACK_BLUESOLEIL;
|
||||
if (IOWrite(buf, len))
|
||||
return 1;
|
||||
|
||||
stack = MSBT_STACK_MS;
|
||||
if (IOWrite(buf, len))
|
||||
return 1;
|
||||
|
||||
stack = MSBT_STACK_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
case MSBT_STACK_MS:
|
||||
{
|
||||
auto result = HidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, len - 1);
|
||||
//FlushFileBuffers(dev_handle);
|
||||
|
||||
if (!result)
|
||||
case MSBT_STACK_UNKNOWN:
|
||||
{
|
||||
auto err = GetLastError();
|
||||
if (err == 121)
|
||||
// Try to auto-detect the stack type
|
||||
stack = MSBT_STACK_BLUESOLEIL;
|
||||
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len))
|
||||
return 1;
|
||||
|
||||
stack = MSBT_STACK_MS;
|
||||
if (_IOWrite(dev_handle, hid_overlap_write, stack, buf, len))
|
||||
return 1;
|
||||
|
||||
stack = MSBT_STACK_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
case MSBT_STACK_MS:
|
||||
{
|
||||
auto result = HidD_SetOutputReport(dev_handle, const_cast<u8*>(buf) + 1, len - 1);
|
||||
//FlushFileBuffers(dev_handle);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
// Semaphore timeout
|
||||
NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote");
|
||||
auto err = GetLastError();
|
||||
if (err == 121)
|
||||
{
|
||||
// Semaphore timeout
|
||||
NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to the Wiimote");
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
case MSBT_STACK_BLUESOLEIL:
|
||||
{
|
||||
u8 big_buf[MAX_PAYLOAD];
|
||||
if (len < MAX_PAYLOAD)
|
||||
{
|
||||
std::copy(buf, buf + len, big_buf);
|
||||
std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0);
|
||||
buf = big_buf;
|
||||
}
|
||||
|
||||
ResetEvent(hid_overlap_write.hEvent);
|
||||
DWORD bytes = 0;
|
||||
if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write))
|
||||
{
|
||||
// WriteFile always returns true with bluesoleil.
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN_LOG(WIIMOTE, "IOWrite[MSBT_STACK_MS]: ERROR: %08x", err);
|
||||
auto const err = GetLastError();
|
||||
if (ERROR_IO_PENDING == err)
|
||||
{
|
||||
CancelIo(dev_handle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
break;
|
||||
}
|
||||
case MSBT_STACK_BLUESOLEIL:
|
||||
{
|
||||
u8 big_buf[MAX_PAYLOAD];
|
||||
if (len < MAX_PAYLOAD)
|
||||
{
|
||||
std::copy(buf, buf + len, big_buf);
|
||||
std::fill(big_buf + len, big_buf + MAX_PAYLOAD, 0);
|
||||
buf = big_buf;
|
||||
}
|
||||
|
||||
ResetEvent(hid_overlap_write.hEvent);
|
||||
DWORD bytes = 0;
|
||||
if (WriteFile(dev_handle, buf + 1, MAX_PAYLOAD - 1, &bytes, &hid_overlap_write))
|
||||
{
|
||||
// WriteFile always returns true with bluesoleil.
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto const err = GetLastError();
|
||||
if (ERROR_IO_PENDING == err)
|
||||
{
|
||||
CancelIo(dev_handle);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Wiimote::IOWrite(const u8* buf, int len)
|
||||
{
|
||||
return _IOWrite(dev_handle, hid_overlap_write, stack, buf, len);
|
||||
}
|
||||
|
||||
// invokes callback for each found wiimote bluetooth device
|
||||
template <typename T>
|
||||
void ProcessWiimotes(bool new_scan, T& callback)
|
||||
@ -498,7 +699,7 @@ void ProcessWiimotes(bool new_scan, T& callback)
|
||||
|
||||
BLUETOOTH_FIND_RADIO_PARAMS radioParam;
|
||||
radioParam.dwSize = sizeof(radioParam);
|
||||
|
||||
|
||||
HANDLE hRadio;
|
||||
|
||||
// TODO: save radio(s) in the WiimoteScanner constructor?
|
||||
|
@ -116,22 +116,21 @@ WiimoteScanner::~WiimoteScanner()
|
||||
void WiimoteScanner::Update()
|
||||
{}
|
||||
|
||||
std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board)
|
||||
{
|
||||
// TODO: find the device in the constructor and save it for later
|
||||
|
||||
std::vector<Wiimote*> wiimotes;
|
||||
IOBluetoothHostController *bth;
|
||||
IOBluetoothDeviceInquiry *bti;
|
||||
SearchBT *sbt;
|
||||
NSEnumerator *en;
|
||||
found_board = NULL;
|
||||
|
||||
bth = [[IOBluetoothHostController alloc] init];
|
||||
if ([bth addressAsString] == nil)
|
||||
{
|
||||
WARN_LOG(WIIMOTE, "No bluetooth host controller");
|
||||
[bth release];
|
||||
return wiimotes;
|
||||
return;
|
||||
}
|
||||
|
||||
sbt = [[SearchBT alloc] init];
|
||||
@ -162,14 +161,20 @@ std::vector<Wiimote*> WiimoteScanner::FindWiimotes()
|
||||
|
||||
Wiimote *wm = new Wiimote();
|
||||
wm->btd = dev;
|
||||
wiimotes.push_back(wm);
|
||||
|
||||
if(IsBalanceBoardName([[dev name] UTF8String]))
|
||||
{
|
||||
found_board = wm;
|
||||
}
|
||||
else
|
||||
{
|
||||
found_wiimotes.push_back(wm);
|
||||
}
|
||||
}
|
||||
|
||||
[bth release];
|
||||
[bti release];
|
||||
[sbt release];
|
||||
|
||||
return wiimotes;
|
||||
}
|
||||
|
||||
bool WiimoteScanner::IsReady() const
|
||||
|
@ -17,12 +17,13 @@
|
||||
|
||||
#include "../WiimoteEmu/WiimoteHid.h"
|
||||
|
||||
unsigned int g_wiimote_sources[MAX_WIIMOTES];
|
||||
unsigned int g_wiimote_sources[MAX_BBMOTES];
|
||||
|
||||
namespace WiimoteReal
|
||||
{
|
||||
|
||||
void HandleFoundWiimotes(const std::vector<Wiimote*>&);
|
||||
void TryToConnectBalanceBoard(Wiimote*);
|
||||
void TryToConnectWiimote(Wiimote*);
|
||||
void HandleWiimoteDisconnect(int index);
|
||||
void DoneWithWiimote(int index);
|
||||
@ -31,8 +32,7 @@ bool g_real_wiimotes_initialized = false;
|
||||
|
||||
std::recursive_mutex g_refresh_lock;
|
||||
|
||||
Wiimote* g_wiimotes[MAX_WIIMOTES];
|
||||
|
||||
Wiimote* g_wiimotes[MAX_BBMOTES];
|
||||
WiimoteScanner g_wiimote_scanner;
|
||||
|
||||
Wiimote::Wiimote()
|
||||
@ -285,7 +285,7 @@ bool Wiimote::Prepare(int _index)
|
||||
u8 const mode_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_REPORT_MODE, 0, WM_REPORT_CORE};
|
||||
|
||||
// Set the active LEDs and turn on rumble.
|
||||
u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_LEDS, u8(WIIMOTE_LED_1 << index | 0x1)};
|
||||
u8 const led_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_LEDS, u8(WIIMOTE_LED_1 << (index%WIIMOTE_BALANCE_BOARD) | 0x1)};
|
||||
|
||||
// Turn off rumble
|
||||
u8 rumble_report[] = {WM_SET_REPORT | WM_BT_OUTPUT, WM_RUMBLE, 0};
|
||||
@ -325,11 +325,25 @@ unsigned int CalculateWantedWiimotes()
|
||||
return wanted_wiimotes;
|
||||
}
|
||||
|
||||
unsigned int CalculateWantedBB()
|
||||
{
|
||||
unsigned int wanted_bb = 0;
|
||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD] && !g_wiimotes[WIIMOTE_BALANCE_BOARD])
|
||||
++wanted_bb;
|
||||
return wanted_bb;
|
||||
}
|
||||
|
||||
void WiimoteScanner::WantWiimotes(bool do_want)
|
||||
{
|
||||
m_want_wiimotes = do_want;
|
||||
}
|
||||
|
||||
|
||||
void WiimoteScanner::WantBB(bool do_want)
|
||||
{
|
||||
m_want_bb = do_want;
|
||||
}
|
||||
|
||||
void WiimoteScanner::StartScanning()
|
||||
{
|
||||
if (!m_run_thread)
|
||||
@ -352,7 +366,7 @@ void CheckForDisconnectedWiimotes()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i)
|
||||
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
||||
if (g_wiimotes[i] && !g_wiimotes[i]->IsConnected())
|
||||
HandleWiimoteDisconnect(i);
|
||||
}
|
||||
@ -366,12 +380,13 @@ void WiimoteScanner::ThreadFunc()
|
||||
while (m_run_thread)
|
||||
{
|
||||
std::vector<Wiimote*> found_wiimotes;
|
||||
Wiimote* found_board = NULL;
|
||||
|
||||
//NOTICE_LOG(WIIMOTE, "In loop");
|
||||
|
||||
if (m_want_wiimotes)
|
||||
if (m_want_wiimotes || m_want_bb)
|
||||
{
|
||||
found_wiimotes = FindWiimotes();
|
||||
FindWiimotes(found_wiimotes, found_board);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -384,7 +399,10 @@ void WiimoteScanner::ThreadFunc()
|
||||
// TODO: this is a fairly lame place for this
|
||||
CheckForDisconnectedWiimotes();
|
||||
|
||||
HandleFoundWiimotes(found_wiimotes);
|
||||
if(m_want_wiimotes)
|
||||
HandleFoundWiimotes(found_wiimotes);
|
||||
if(m_want_bb && found_board)
|
||||
TryToConnectBalanceBoard(found_board);
|
||||
|
||||
//std::this_thread::yield();
|
||||
Common::SleepCurrentThread(500);
|
||||
@ -439,6 +457,10 @@ void LoadSettings()
|
||||
|
||||
sec.Get("Source", &g_wiimote_sources[i], i ? WIIMOTE_SRC_NONE : WIIMOTE_SRC_EMU);
|
||||
}
|
||||
|
||||
std::string secname("BalanceBoard");
|
||||
IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
|
||||
sec.Get("Source", &g_wiimote_sources[WIIMOTE_BALANCE_BOARD], WIIMOTE_SRC_NONE);
|
||||
}
|
||||
|
||||
// config dialog calls this when some settings change
|
||||
@ -452,6 +474,7 @@ void Initialize()
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
|
||||
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
|
||||
|
||||
if (g_real_wiimotes_initialized)
|
||||
return;
|
||||
@ -474,20 +497,21 @@ void Shutdown(void)
|
||||
|
||||
g_real_wiimotes_initialized = false;
|
||||
|
||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||
for (unsigned int i = 0; i < MAX_BBMOTES; ++i)
|
||||
HandleWiimoteDisconnect(i);
|
||||
}
|
||||
|
||||
void ChangeWiimoteSource(unsigned int index, int source)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
g_wiimote_sources[index] = source;
|
||||
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
|
||||
|
||||
// kill real connection (or swap to different slot)
|
||||
DoneWithWiimote(index);
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
g_wiimote_sources[index] = source;
|
||||
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
|
||||
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
|
||||
|
||||
|
||||
// kill real connection (or swap to different slot)
|
||||
DoneWithWiimote(index);
|
||||
}
|
||||
|
||||
// reconnect to the emulator
|
||||
@ -500,7 +524,7 @@ void TryToConnectWiimote(Wiimote* wm)
|
||||
{
|
||||
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i)
|
||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||
{
|
||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]
|
||||
&& !g_wiimotes[i])
|
||||
@ -525,16 +549,41 @@ void TryToConnectWiimote(Wiimote* wm)
|
||||
delete wm;
|
||||
}
|
||||
|
||||
void TryToConnectBalanceBoard(Wiimote* wm)
|
||||
{
|
||||
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[WIIMOTE_BALANCE_BOARD]
|
||||
&& !g_wiimotes[WIIMOTE_BALANCE_BOARD])
|
||||
{
|
||||
if (wm->Connect() && wm->Prepare(WIIMOTE_BALANCE_BOARD))
|
||||
{
|
||||
NOTICE_LOG(WIIMOTE, "Connected to Balance Board %i.", WIIMOTE_BALANCE_BOARD + 1);
|
||||
|
||||
std::swap(g_wiimotes[WIIMOTE_BALANCE_BOARD], wm);
|
||||
g_wiimotes[WIIMOTE_BALANCE_BOARD]->StartThread();
|
||||
|
||||
Host_ConnectWiimote(WIIMOTE_BALANCE_BOARD, true);
|
||||
}
|
||||
}
|
||||
|
||||
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
|
||||
|
||||
lk.unlock();
|
||||
|
||||
delete wm;
|
||||
}
|
||||
|
||||
void DoneWithWiimote(int index)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
|
||||
if (g_wiimotes[index])
|
||||
{
|
||||
g_wiimotes[index]->StopThread();
|
||||
|
||||
// First see if we can use this real Wiimote in another slot.
|
||||
for (unsigned int i = 0; i != MAX_WIIMOTES; ++i)
|
||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||
{
|
||||
if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]
|
||||
&& !g_wiimotes[i])
|
||||
@ -560,9 +609,11 @@ void HandleWiimoteDisconnect(int index)
|
||||
Wiimote* wm = NULL;
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
std::swap(wm, g_wiimotes[index]);
|
||||
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
std::swap(wm, g_wiimotes[index]);
|
||||
g_wiimote_scanner.WantWiimotes(0 != CalculateWantedWiimotes());
|
||||
g_wiimote_scanner.WantBB(0 != CalculateWantedBB());
|
||||
}
|
||||
|
||||
if (wm)
|
||||
@ -583,31 +634,35 @@ void Refresh()
|
||||
g_wiimote_scanner.StopScanning();
|
||||
|
||||
{
|
||||
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
|
||||
std::vector<Wiimote*> found_wiimotes;
|
||||
|
||||
if (0 != CalculateWantedWiimotes())
|
||||
{
|
||||
// Don't hang Dolphin when searching
|
||||
lk.unlock();
|
||||
found_wiimotes = g_wiimote_scanner.FindWiimotes();
|
||||
lk.lock();
|
||||
}
|
||||
|
||||
CheckForDisconnectedWiimotes();
|
||||
|
||||
// Brief rumble for already connected Wiimotes.
|
||||
for (int i = 0; i != MAX_WIIMOTES; ++i)
|
||||
{
|
||||
if (g_wiimotes[i])
|
||||
std::unique_lock<std::recursive_mutex> lk(g_refresh_lock);
|
||||
std::vector<Wiimote*> found_wiimotes;
|
||||
Wiimote* found_board = NULL;
|
||||
|
||||
if (0 != CalculateWantedWiimotes() || 0 != CalculateWantedBB())
|
||||
{
|
||||
g_wiimotes[i]->StopThread();
|
||||
g_wiimotes[i]->Prepare(i);
|
||||
g_wiimotes[i]->StartThread();
|
||||
// Don't hang Dolphin when searching
|
||||
lk.unlock();
|
||||
g_wiimote_scanner.FindWiimotes(found_wiimotes, found_board);
|
||||
lk.lock();
|
||||
}
|
||||
}
|
||||
|
||||
HandleFoundWiimotes(found_wiimotes);
|
||||
CheckForDisconnectedWiimotes();
|
||||
|
||||
// Brief rumble for already connected Wiimotes.
|
||||
// Don't do this for Balance Board as it doesn't have rumble anyway.
|
||||
for (int i = 0; i < MAX_WIIMOTES; ++i)
|
||||
{
|
||||
if (g_wiimotes[i])
|
||||
{
|
||||
g_wiimotes[i]->StopThread();
|
||||
g_wiimotes[i]->Prepare(i);
|
||||
g_wiimotes[i]->StartThread();
|
||||
}
|
||||
}
|
||||
|
||||
HandleFoundWiimotes(found_wiimotes);
|
||||
if(found_board)
|
||||
TryToConnectBalanceBoard(found_board);
|
||||
}
|
||||
|
||||
Initialize();
|
||||
@ -616,7 +671,6 @@ void Refresh()
|
||||
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size)
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lk(g_refresh_lock);
|
||||
|
||||
if (g_wiimotes[_WiimoteNumber])
|
||||
g_wiimotes[_WiimoteNumber]->InterruptChannel(_channelID, _pData, _Size);
|
||||
}
|
||||
@ -656,7 +710,14 @@ bool IsValidBluetoothName(const std::string& name)
|
||||
{
|
||||
return
|
||||
"Nintendo RVL-CNT-01" == name ||
|
||||
"Nintendo RVL-CNT-01-TR" == name;
|
||||
"Nintendo RVL-CNT-01-TR" == name ||
|
||||
IsBalanceBoardName(name);
|
||||
}
|
||||
|
||||
bool IsBalanceBoardName(const std::string& name)
|
||||
{
|
||||
return
|
||||
"Nintendo RVL-WBC-01" == name;
|
||||
}
|
||||
|
||||
}; // end of namespace
|
||||
|
@ -117,11 +117,12 @@ public:
|
||||
bool IsReady() const;
|
||||
|
||||
void WantWiimotes(bool do_want);
|
||||
void WantBB(bool do_want);
|
||||
|
||||
void StartScanning();
|
||||
void StopScanning();
|
||||
|
||||
std::vector<Wiimote*> FindWiimotes();
|
||||
void FindWiimotes(std::vector<Wiimote*>&, Wiimote*&);
|
||||
|
||||
// function called when not looking for more wiimotes
|
||||
void Update();
|
||||
@ -133,10 +134,10 @@ private:
|
||||
|
||||
volatile bool m_run_thread;
|
||||
volatile bool m_want_wiimotes;
|
||||
volatile bool m_want_bb;
|
||||
|
||||
#if defined(_WIN32)
|
||||
|
||||
|
||||
void CheckDeviceType(std::basic_string<TCHAR> &devicepath, bool &real_wiimote, bool &is_bb);
|
||||
#elif defined(__linux__) && HAVE_BLUEZ
|
||||
int device_id;
|
||||
int device_sock;
|
||||
@ -145,7 +146,7 @@ private:
|
||||
|
||||
extern std::recursive_mutex g_refresh_lock;
|
||||
extern WiimoteScanner g_wiimote_scanner;
|
||||
extern Wiimote *g_wiimotes[4];
|
||||
extern Wiimote *g_wiimotes[MAX_BBMOTES];
|
||||
|
||||
void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size);
|
||||
void ControlChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size);
|
||||
@ -158,6 +159,7 @@ int FindWiimotes(Wiimote** wm, int max_wiimotes);
|
||||
void ChangeWiimoteSource(unsigned int index, int source);
|
||||
|
||||
bool IsValidBluetoothName(const std::string& name);
|
||||
bool IsBalanceBoardName(const std::string& name);
|
||||
|
||||
}; // WiimoteReal
|
||||
|
||||
|
@ -32,7 +32,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 maxWM = min<u8>(BT_DINF.num_registered, CONF_PAD_MAX_ACTIVE);
|
||||
u8 maxWM = min<u8>(BT_DINF.num_registered, MAX_BBMOTES);
|
||||
bdaddr_t tmpBD = BDADDR_ANY;
|
||||
u8 i = 0;
|
||||
while (i < maxWM)
|
||||
@ -43,28 +43,60 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
|
||||
tmpBD.b[2] = BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3];
|
||||
tmpBD.b[1] = BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4];
|
||||
tmpBD.b[0] = BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5];
|
||||
if(i == WIIMOTE_BALANCE_BOARD)
|
||||
{
|
||||
const char * wmName = "Nintendo RVL-WBC-01";
|
||||
memcpy(BT_DINF.registered[i].name, wmName, 20);
|
||||
memcpy(BT_DINF.balance_board.name, wmName, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * wmName = "Nintendo RVL-CNT-01";
|
||||
memcpy(BT_DINF.registered[i].name, wmName, 20);
|
||||
memcpy(BT_DINF.active[i].name, wmName, 20);
|
||||
}
|
||||
|
||||
INFO_LOG(WII_IPC_WIIMOTE, "Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
|
||||
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
|
||||
i++;
|
||||
}
|
||||
while (i < CONF_PAD_MAX_ACTIVE)
|
||||
while (i < MAX_BBMOTES)
|
||||
{
|
||||
const char * wmName = "Nintendo RVL-CNT-01";
|
||||
++BT_DINF.num_registered;
|
||||
BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i;
|
||||
BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0;
|
||||
BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79;
|
||||
BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19;
|
||||
BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2;
|
||||
BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11;
|
||||
memcpy(BT_DINF.registered[i].name, wmName, 20);
|
||||
if(i == WIIMOTE_BALANCE_BOARD)
|
||||
{
|
||||
const char * wmName = "Nintendo RVL-WBC-01";
|
||||
++BT_DINF.num_registered;
|
||||
BT_DINF.balance_board.bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i;
|
||||
BT_DINF.balance_board.bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0;
|
||||
BT_DINF.balance_board.bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79;
|
||||
BT_DINF.balance_board.bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19;
|
||||
BT_DINF.balance_board.bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2;
|
||||
BT_DINF.balance_board.bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11;
|
||||
memcpy(BT_DINF.registered[i].name, wmName, 20);
|
||||
memcpy(BT_DINF.balance_board.name, wmName, 20);
|
||||
|
||||
INFO_LOG(WII_IPC_WIIMOTE, "Balance Board %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
|
||||
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * wmName = "Nintendo RVL-CNT-01";
|
||||
++BT_DINF.num_registered;
|
||||
BT_DINF.active[i].bdaddr[0] = BT_DINF.registered[i].bdaddr[0] = tmpBD.b[5] = i;
|
||||
BT_DINF.active[i].bdaddr[1] = BT_DINF.registered[i].bdaddr[1] = tmpBD.b[4] = 0;
|
||||
BT_DINF.active[i].bdaddr[2] = BT_DINF.registered[i].bdaddr[2] = tmpBD.b[3] = 0x79;
|
||||
BT_DINF.active[i].bdaddr[3] = BT_DINF.registered[i].bdaddr[3] = tmpBD.b[2] = 0x19;
|
||||
BT_DINF.active[i].bdaddr[4] = BT_DINF.registered[i].bdaddr[4] = tmpBD.b[1] = 2;
|
||||
BT_DINF.active[i].bdaddr[5] = BT_DINF.registered[i].bdaddr[5] = tmpBD.b[0] = 0x11;
|
||||
memcpy(BT_DINF.registered[i].name, wmName, 20);
|
||||
|
||||
INFO_LOG(WII_IPC_WIIMOTE, "Adding to SYSConf Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
|
||||
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
|
||||
INFO_LOG(WII_IPC_WIIMOTE, "Adding to SYSConf Wiimote %d BT ID %x,%x,%x,%x,%x,%x", i, tmpBD.b[0], tmpBD.b[1], tmpBD.b[2], tmpBD.b[3], tmpBD.b[4], tmpBD.b[5]);
|
||||
m_WiiMotes.push_back(CWII_IPC_HLE_WiiMote(this, i, tmpBD, false));
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
// save now so that when games load sysconf file it includes the new wiimotes
|
||||
// and the correct order for connected wiimotes
|
||||
if (!SConfig::GetInstance().m_SYSCONF->SetArrayData("BT.DINF", (u8*)&BT_DINF, sizeof(_conf_pads)) || !SConfig::GetInstance().m_SYSCONF->Save())
|
||||
@ -99,18 +131,18 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::DoState(PointerWrap &p)
|
||||
p.DoPOD(m_HCIEndpoint);
|
||||
p.DoPOD(m_ACLEndpoint);
|
||||
p.Do(m_last_ticks);
|
||||
p.DoArray(m_PacketCount,4);
|
||||
p.DoArray(m_PacketCount,MAX_BBMOTES);
|
||||
p.Do(m_ScanEnable);
|
||||
p.Do(m_EventQueue);
|
||||
m_acl_pool.DoState(p);
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
|
||||
m_WiiMotes[i].DoState(p);
|
||||
|
||||
// Reset the connection of real and hybrid wiimotes
|
||||
if (p.GetMode() == PointerWrap::MODE_READ && SConfig::GetInstance().m_WiimoteReconnectOnLoad)
|
||||
{
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
|
||||
{
|
||||
if (WIIMOTE_SRC_EMU == g_wiimote_sources[i] || WIIMOTE_SRC_NONE == g_wiimote_sources[i])
|
||||
continue;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "WII_IPC_HLE.h"
|
||||
#include "WII_IPC_HLE_Device.h"
|
||||
#include "WII_IPC_HLE_WiiMote.h"
|
||||
#include "../HW/Wiimote.h"
|
||||
|
||||
struct SQueuedEvent
|
||||
{
|
||||
@ -193,7 +194,7 @@ private:
|
||||
}
|
||||
} m_acl_pool;
|
||||
|
||||
u32 m_PacketCount[4];
|
||||
u32 m_PacketCount[MAX_BBMOTES];
|
||||
u64 m_last_ticks;
|
||||
|
||||
// Send ACL data to a device (wiimote)
|
||||
@ -274,7 +275,6 @@ private:
|
||||
|
||||
#pragma pack(push,1)
|
||||
#define CONF_PAD_MAX_REGISTERED 10
|
||||
#define CONF_PAD_MAX_ACTIVE 4
|
||||
|
||||
struct _conf_pad_device
|
||||
{
|
||||
@ -286,7 +286,7 @@ private:
|
||||
{
|
||||
u8 num_registered;
|
||||
_conf_pad_device registered[CONF_PAD_MAX_REGISTERED];
|
||||
_conf_pad_device active[CONF_PAD_MAX_ACTIVE];
|
||||
_conf_pad_device active[MAX_WIIMOTES];
|
||||
_conf_pad_device balance_board;
|
||||
u8 unknown[0x45];
|
||||
};
|
||||
|
@ -37,7 +37,7 @@ CWII_IPC_HLE_WiiMote::CWII_IPC_HLE_WiiMote(CWII_IPC_HLE_Device_usb_oh1_57e_305*
|
||||
, m_HIDInterruptChannel_Config(false)
|
||||
, m_HIDInterruptChannel_ConfigWait(false)
|
||||
, m_BD(_BD)
|
||||
, m_Name("Nintendo RVL-CNT-01")
|
||||
, m_Name(_Number == WIIMOTE_BALANCE_BOARD ? "Nintendo RVL-WBC-01" : "Nintendo RVL-CNT-01")
|
||||
, m_pHost(_pHost)
|
||||
{
|
||||
DEBUG_LOG(WII_IPC_WIIMOTE, "Wiimote: #%i Constructed", _Number);
|
||||
@ -277,13 +277,13 @@ void CWII_IPC_HLE_WiiMote::ExecuteL2capCmd(u8* _pData, u32 _Size)
|
||||
break;
|
||||
|
||||
case L2CAP_PSM_HID_CNTL:
|
||||
if (number < 4)
|
||||
if (number < MAX_BBMOTES)
|
||||
Wiimote::ControlChannel(number, pHeader->dcid, pData, DataSize);
|
||||
break;
|
||||
|
||||
case L2CAP_PSM_HID_INTR:
|
||||
{
|
||||
if (number < 4)
|
||||
if (number < MAX_BBMOTES)
|
||||
{
|
||||
DEBUG_LOG(WIIMOTE, "Wiimote_InterruptChannel");
|
||||
DEBUG_LOG(WIIMOTE, " Channel ID: %04x", pHeader->dcid);
|
||||
|
@ -392,7 +392,7 @@ void ChangeWiiPads(bool instantly)
|
||||
if (instantly && (g_numPads >> 4) == controllers)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (int i = 0; i < MAX_BBMOTES; i++)
|
||||
{
|
||||
g_wiimote_sources[i] = IsUsingWiimote(i) ? WIIMOTE_SRC_EMU : WIIMOTE_SRC_NONE;
|
||||
GetUsbPointer()->AccessWiiMote(i | 0x100)->Activate(IsUsingWiimote(i));
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "InputConfigDiag.h"
|
||||
#include "UDPConfigDiag.h"
|
||||
#include "WxUtils.h"
|
||||
#include "HW/Wiimote.h"
|
||||
|
||||
void GamepadPage::ConfigUDPWii(wxCommandEvent &event)
|
||||
{
|
||||
@ -947,7 +948,7 @@ InputConfigDialog::InputConfigDialog(wxWindow* const parent, InputPlugin& plugin
|
||||
, m_plugin(plugin)
|
||||
{
|
||||
m_pad_notebook = new wxNotebook(this, -1, wxDefaultPosition, wxDefaultSize, wxNB_DEFAULT);
|
||||
for (unsigned int i = 0; i < plugin.controllers.size(); ++i)
|
||||
for (unsigned int i = 0; i < std::min(plugin.controllers.size(), (size_t)MAX_WIIMOTES); ++i)
|
||||
{
|
||||
GamepadPage* gp = new GamepadPage(m_pad_notebook, m_plugin, i, this);
|
||||
m_padpages.push_back(gp);
|
||||
|
@ -15,7 +15,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
|
||||
wxStaticText* wiimote_label[4];
|
||||
wxChoice* wiimote_source_ch[4];
|
||||
|
||||
for (unsigned int i = 0; i < 4; ++i)
|
||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||
{
|
||||
wxString str;
|
||||
str.Printf(_("Wiimote %i"), i + 1);
|
||||
@ -54,8 +54,25 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
|
||||
wiimote_sizer->Add(wiimote_configure_bt[i]);
|
||||
}
|
||||
wiimote_group->Add(wiimote_sizer, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
// "BalanceBoard" layout
|
||||
wxStaticBoxSizer* const bb_group = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Balance Board"));
|
||||
wxFlexGridSizer* const bb_sizer = new wxFlexGridSizer(1, 5, 5);
|
||||
int source_ctrl_id = wxWindow::NewControlId();
|
||||
m_wiimote_index_from_ctrl_id.insert(std::pair<wxWindowID, unsigned int>(source_ctrl_id, WIIMOTE_BALANCE_BOARD));
|
||||
const wxString src_choices[] = { _("None"), _("Real Balance Board") };
|
||||
wxChoice* bb_source = new wxChoice(this, source_ctrl_id, wxDefaultPosition, wxDefaultSize, sizeof(src_choices)/sizeof(*src_choices), src_choices);
|
||||
bb_source->Bind(wxEVT_COMMAND_CHOICE_SELECTED, &WiimoteConfigDiag::SelectSource, this);
|
||||
|
||||
m_orig_wiimote_sources[WIIMOTE_BALANCE_BOARD] = g_wiimote_sources[WIIMOTE_BALANCE_BOARD];
|
||||
bb_source->Select(m_orig_wiimote_sources[WIIMOTE_BALANCE_BOARD] ? 1 : 0);
|
||||
|
||||
bb_sizer->Add(bb_source, 0, wxALIGN_CENTER_VERTICAL);
|
||||
|
||||
bb_group->Add(bb_sizer, 1, wxEXPAND, 5 );
|
||||
|
||||
|
||||
|
||||
// "Real wiimotes" controls
|
||||
wxButton* const refresh_btn = new wxButton(this, -1, _("Refresh"), wxDefaultPosition);
|
||||
refresh_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &WiimoteConfigDiag::RefreshRealWiimotes, this);
|
||||
@ -166,6 +183,7 @@ WiimoteConfigDiag::WiimoteConfigDiag(wxWindow* const parent, InputPlugin& plugin
|
||||
|
||||
// Dialog layout
|
||||
main_sizer->Add(wiimote_group, 0, wxEXPAND | wxALL, 5);
|
||||
main_sizer->Add(bb_group, 0, wxEXPAND | wxALL, 5);
|
||||
main_sizer->Add(real_wiimotes_group, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
main_sizer->Add(general_sizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
main_sizer->Add(CreateButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5);
|
||||
@ -196,17 +214,23 @@ void WiimoteConfigDiag::SelectSource(wxCommandEvent& event)
|
||||
// Revert if the dialog is canceled.
|
||||
int index = m_wiimote_index_from_ctrl_id[event.GetId()];
|
||||
|
||||
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();
|
||||
if(index != WIIMOTE_BALANCE_BOARD)
|
||||
{
|
||||
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();
|
||||
}
|
||||
else
|
||||
wiimote_configure_bt[index]->Enable();
|
||||
{
|
||||
WiimoteReal::ChangeWiimoteSource(index, event.GetInt() ? WIIMOTE_SRC_REAL : WIIMOTE_SRC_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
void WiimoteConfigDiag::RevertSource()
|
||||
{
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < MAX_BBMOTES; ++i)
|
||||
g_wiimote_sources[i] = m_orig_wiimote_sources[i];
|
||||
}
|
||||
|
||||
@ -225,6 +249,10 @@ void WiimoteConfigDiag::Save(wxCommandEvent& event)
|
||||
|
||||
sec.Set("Source", (int)g_wiimote_sources[i]);
|
||||
}
|
||||
|
||||
std::string secname("BalanceBoard");
|
||||
IniFile::Section& sec = *inifile.GetOrCreateSection(secname.c_str());
|
||||
sec.Set("Source", (int)g_wiimote_sources[WIIMOTE_BALANCE_BOARD]);
|
||||
|
||||
inifile.Save(ini_filename);
|
||||
|
||||
|
@ -76,9 +76,9 @@ private:
|
||||
wxNotebook* m_pad_notebook;
|
||||
|
||||
std::map<wxWindowID, unsigned int> m_wiimote_index_from_ctrl_id;
|
||||
unsigned int m_orig_wiimote_sources[4];
|
||||
unsigned int m_orig_wiimote_sources[MAX_BBMOTES];
|
||||
|
||||
wxButton* wiimote_configure_bt[4];
|
||||
wxButton* wiimote_configure_bt[MAX_WIIMOTES];
|
||||
std::map<wxWindowID, unsigned int> m_wiimote_index_from_conf_bt_id;
|
||||
};
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "InputConfig.h"
|
||||
#include "../../Core/Src/ConfigManager.h"
|
||||
#include "../../Core/Src/HW/Wiimote.h"
|
||||
|
||||
InputPlugin::~InputPlugin()
|
||||
{
|
||||
@ -18,9 +19,9 @@ bool InputPlugin::LoadConfig(bool isGC)
|
||||
{
|
||||
IniFile inifile;
|
||||
IniFile game_ini;
|
||||
bool useProfile[4] = {false, false, false, false};
|
||||
std::string num[4] = {"1", "2", "3", "4"};
|
||||
std::string profile[4];
|
||||
bool useProfile[MAX_BBMOTES] = {false, false, false, false, false};
|
||||
std::string num[MAX_BBMOTES] = {"1", "2", "3", "4", "BB"};
|
||||
std::string profile[MAX_BBMOTES];
|
||||
std::string path;
|
||||
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.GetUniqueID() != "00000000")
|
||||
|
Loading…
x
Reference in New Issue
Block a user