diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fede73154..058ceb4262 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,7 +124,7 @@ else() message("ao NOT found, disabling ao sound backend") endif(AO_FOUND) -check_lib(BLUEZ bluez QUIET) +#check_lib(BLUEZ bluez QUIET) if(BLUEZ_FOUND) add_definitions(-DHAVE_BLUEZ=1) message("bluez found, enabling bluetooth support") @@ -221,7 +221,6 @@ include_directories(Source/Core/InputCommon/Src) include_directories(Source/Core/InputUICommon/Src) include_directories(Source/Core/VideoCommon/Src) include_directories(Source/Core/VideoUICommon/Src) -include_directories(Source/Core/wiiuse/Src) ######################################## @@ -232,7 +231,7 @@ include_directories(Source/Core/wiiuse/Src) # - make sure to tell cmake to link them statically or dynamically (most # should be linked statically) # - place the CMakeLists.txt in the first-level subdirectory, e.g. -# Externals/WiiUse/CMakeLists.txt (that is: NOT in some Src/ subdirectory) +# Externals/CLRun/CMakeLists.txt (that is: NOT in some Src/ subdirectory) # add_subdirectory(Externals/Bochs_disasm) include_directories(Externals/Bochs_disasm) diff --git a/SConstruct b/SConstruct index 73d5683168..c89886b959 100644 --- a/SConstruct +++ b/SConstruct @@ -359,7 +359,6 @@ dirs = [ 'Source/Core/InputUICommon/Src', 'Source/Core/VideoCommon/Src', 'Source/Core/VideoUICommon/Src', - 'Source/Core/wiiuse/Src', 'Source/DSPTool/Src', 'Source/Plugins/Plugin_DSP_HLE/Src', 'Source/Plugins/Plugin_DSP_LLE/Src', diff --git a/Source/Core/CMakeLists.txt b/Source/Core/CMakeLists.txt index d0cc11b46b..f89e15aede 100644 --- a/Source/Core/CMakeLists.txt +++ b/Source/Core/CMakeLists.txt @@ -14,4 +14,3 @@ add_subdirectory(DolphinWX) add_subdirectory(DSPCore) add_subdirectory(InputCommon) add_subdirectory(VideoCommon) -add_subdirectory(wiiuse) diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index c7bfefe433..8d290ff259 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -132,16 +132,23 @@ set(SRCS Src/ActionReplay.cpp Src/PowerPC/JitCommon/JitCache.cpp Src/PowerPC/JitCommon/Jit_Util.cpp) +set(LIBS bdisasm inputcommon lua sfml-network) + if(WIN32) - set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Win32.cpp Src/stdafx.cpp) + set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Win32.cpp Src/stdafx.cpp + Src/HW/WiimoteReal/IOWin.cpp) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Apple.cpp) + set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Apple.cpp Src/HW/WiimoteReal/IOOsx.mm) elseif(UNIX) set(SRCS ${SRCS} Src/HW/BBA-TAP/TAP_Unix.cpp) + if((${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND BLUEZ_FOUND) + set(SRCS ${SRCS} Src/HW/WiimoteReal/IONix.cpp) + set(LIBS ${LIBS} bluetooth) + else() + set(SRCS ${SRCS} Src/HW/WiimoteReal/IODummy.cpp) + endif() endif() -set(LIBS bdisasm inputcommon lua sfml-network wiiuse) - if(PORTAUDIO_FOUND) set(LIBS ${LIBS} portaudio) endif(PORTAUDIO_FOUND) diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj index 1cc020a70f..e372752111 100644 --- a/Source/Core/Core/Core.vcproj +++ b/Source/Core/Core/Core.vcproj @@ -45,7 +45,7 @@ @@ -340,7 +341,7 @@ FavorSizeOrSpeed="1" OmitFramePointers="true" EnableFiberSafeOptimizations="false" - AdditionalIncludeDirectories=".\Core\Core\Src\Debugger;..\Common\Src;..\DiscIO\Src;..\wiiuse\Src;..\..\Core\InputCommon\Src;..\..\PluginSpecs;..\..\..\Externals\LZO;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib;..\..\..\Externals\Lua;..\..\..\Externals\SFML\include" + AdditionalIncludeDirectories=".\Core\Core\Src\Debugger;..\Common\Src;..\DiscIO\Src;..\..\Core\InputCommon\Src;..\..\PluginSpecs;..\..\..\Externals\LZO;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib;..\..\..\Externals\Lua;..\..\..\Externals\SFML\include" PreprocessorDefinitions="NDEBUG;_LIB;DEBUGFAST;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0" RuntimeLibrary="0" BufferSecurityCheck="true" @@ -414,7 +415,7 @@ FavorSizeOrSpeed="1" OmitFramePointers="true" EnableFiberSafeOptimizations="false" - AdditionalIncludeDirectories=".\Core\Core\Src\Debugger;..\Common\Src;..\DiscIO\Src;..\wiiuse\Src;..\..\Core\InputCommon\Src;..\..\PluginSpecs;..\..\..\Externals\LZO;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib;..\..\..\Externals\Lua;..\..\..\Externals\SFML\include" + AdditionalIncludeDirectories=".\Core\Core\Src\Debugger;..\Common\Src;..\DiscIO\Src;..\..\Core\InputCommon\Src;..\..\PluginSpecs;..\..\..\Externals\LZO;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib;..\..\..\Externals\Lua;..\..\..\Externals\SFML\include" PreprocessorDefinitions="NDEBUG;_LIB;DEBUGFAST;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0" RuntimeLibrary="0" BufferSecurityCheck="false" @@ -904,6 +905,10 @@ + + @@ -912,6 +917,10 @@ RelativePath=".\Src\HW\WiimoteReal\WiimoteReal.h" > + + diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp new file mode 100644 index 0000000000..8049e66039 --- /dev/null +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include "Common.h" +#include "WiimoteReal.h" + +namespace WiimoteReal +{ + +int FindWiimotes(Wiimote **wm, int max_wiimotes) +{ + return 0; +} + +bool Wiimote::Connect() +{ + return 0; +} + +void Wiimote::RealDisconnect() +{ + return; +} + +u8 *Wiimote::IORead() +{ + return NULL; +} + +int Wiimote::IOWrite(unsigned char* buf, int len) +{ + return 0; +} + +}; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp new file mode 100644 index 0000000000..a9233c21bb --- /dev/null +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -0,0 +1,258 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "Common.h" +#include "WiimoteReal.h" + +// Identify the wiimote device by its class +#define WM_DEV_CLASS_0 0x04 +#define WM_DEV_CLASS_1 0x25 +#define WM_DEV_CLASS_2 0x00 + +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) +{ + 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) + { + NOTICE_LOG(WIIMOTE, "Bluetooth not found."); + return found_wiimotes; + } + + // Create a socket to the device + if ((device_sock = hci_open_dev(device_id)) < 0) + { + ERROR_LOG(WIIMOTE, "Unable to open bluetooth."); + return found_wiimotes; + } + + int try_num = 0; + while ((try_num < 5) && (found_wiimotes < max_wiimotes)) + { + 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 approximately one second + found_devices = hci_inquiry(device_id, 1, 128, NULL, &scan_info, IREQ_CACHE_FLUSH); + if (found_devices < 0) + { + ERROR_LOG(WIIMOTE, "Error searching for bluetooth devices."); + return found_wiimotes; + } + + DEBUG_LOG(WIIMOTE, "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)) + { + 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; + } + } + } + try_num++; + } + + close(device_sock); + return found_wiimotes; +} + +// Connect to a wiimote with a known address. +bool Wiimote::Connect() +{ + struct sockaddr_l2 addr; + + if (IsConnected()) return false; + + addr.l2_family = AF_BLUETOOTH; + addr.l2_bdaddr = bdaddr; + addr.l2_cid = 0; + + // Output channel + addr.l2_psm = htobs(WM_OUTPUT_CHANNEL); + if ((out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1 || + connect(out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) + { + DEBUG_LOG(WIIMOTE, "Unable to open output socket to wiimote."); + close(out_sock); + out_sock = -1; + return false; + } + + // Input channel + addr.l2_psm = htobs(WM_INPUT_CHANNEL); + if ((in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP)) == -1 || + connect(in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) + { + DEBUG_LOG(WIIMOTE, "Unable to open input socket from wiimote."); + close(in_sock); + close(out_sock); + in_sock = out_sock = -1; + 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); + + return true; +} + +// Disconnect a wiimote. +void Wiimote::RealDisconnect() +{ + if (!IsConnected()) + return; + + NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i.", index + 1); + + m_connected = false; + + close(out_sock); + close(in_sock); + + out_sock = -1; + in_sock = -1; +} + +unsigned char *Wiimote::IORead() +{ + struct timeval tv; + fd_set fds; + int r; + + if (!IsConnected()) + return NULL; + + // Block select for 1/2000th of a second + tv.tv_sec = 0; + tv.tv_usec = WIIMOTE_DEFAULT_TIMEOUT * 1000; + + FD_ZERO(&fds); + FD_SET(in_sock, &fds); + + if (select(in_sock + 1, &fds, NULL, NULL, &tv) == -1) + { + ERROR_LOG(WIIMOTE, "Unable to select wiimote %i input socket.", index + 1); + return NULL; + } + + if (!FD_ISSET(in_sock, &fds)) + return NULL; + + // Read the pending message into the buffer + unsigned char *buffer = new unsigned char[MAX_PAYLOAD]; + r = read(in_sock, buffer, sizeof(buffer)); + if (r == -1) + { + // Error reading data + ERROR_LOG(WIIMOTE, "Receiving data from wiimote %i.", index + 1); + + if (errno == ENOTCONN) + { + // This can happen if the bluetooth dongle is disconnected + ERROR_LOG(WIIMOTE, "Bluetooth appears to be disconnected. " + "Wiimote %i will be disconnected.", index + 1); + RealDisconnect(); + } + + delete[] buffer; + return NULL; + } + if (!r) + { + // Disconnect + RealDisconnect(); + delete[] buffer; + return NULL; + } + return buffer; +} + +int Wiimote::IOWrite(unsigned char* buf, int len) +{ + return write(out_sock, buf, len); +} + +}; // WiimoteReal diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOOsx.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOOsx.mm new file mode 100644 index 0000000000..e7969036ed --- /dev/null +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOOsx.mm @@ -0,0 +1,298 @@ +#import +extern "C" OSErr UpdateSystemActivity(UInt8 activity); +#define BLUETOOTH_VERSION_USE_CURRENT +#import + +#include "Common.h" +#include "../Wiimote.h" +#include "WiimoteReal.h" + +@interface SearchBT: NSObject +{ + @public + unsigned int maxDevices; +} +@end + +@implementation SearchBT +- (void) deviceInquiryComplete: (IOBluetoothDeviceInquiry *) sender +error: (IOReturn) error +aborted: (BOOL) aborted +{ + CFRunLoopStop(CFRunLoopGetCurrent()); +} + +- (void) deviceInquiryDeviceFound: (IOBluetoothDeviceInquiry *) sender +device: (IOBluetoothDevice *) device +{ + NOTICE_LOG(WIIMOTE, "Discovered bluetooth device at %s: %s", + [[device getAddressString] UTF8String], + [[device getName] UTF8String]); + + if ([[sender foundDevices] count] == maxDevices) + [sender stop]; +} +@end + +@interface ConnectBT: NSObject {} +@end + +@implementation ConnectBT +- (void) l2capChannelData: (IOBluetoothL2CAPChannel *) l2capChannel +data: (unsigned char *) data +length: (NSUInteger) length +{ + IOBluetoothDevice *device = [l2capChannel getDevice]; + WiimoteReal::Wiimote *wm = NULL; + + for (int i = 0; i < MAX_WIIMOTES; i++) + { + if (WiimoteReal::g_wiimotes[i] == NULL) + continue; + if ([device isEqual: WiimoteReal::g_wiimotes[i]->btd] == TRUE) + wm = WiimoteReal::g_wiimotes[i]; + } + if (wm == NULL) + { + WARN_LOG(WIIMOTE, "Received packet for unknown wiimote"); + return; + } + + if (length > MAX_PAYLOAD) + { + WARN_LOG(WIIMOTE, "Dropping packet for wiimote %i, too large", + wm->index + 1); + return; + } + + if (wm->queue[wm->writer].len != 0) + { + WARN_LOG(WIIMOTE, "Dropping packet for wiimote %i, queue full", + wm->index + 1); + return; + } + + memcpy(wm->queue[wm->writer].data, data, length); + wm->queue[wm->writer].len = length; + + wm->writer++; + wm->outstanding++; + if (wm->writer == QUEUE_SIZE) + wm->writer = 0; + + if (wm->outstanding > wm->watermark) + { + wm->watermark = wm->outstanding; + WARN_LOG(WIIMOTE, "New queue watermark %i for wiimote %i", + wm->watermark, wm->index + 1); + } + + CFRunLoopStop(CFRunLoopGetCurrent()); + + (void)UpdateSystemActivity(1); +} + +- (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel +{ + IOBluetoothDevice *device = [l2capChannel getDevice]; + WiimoteReal::Wiimote *wm = NULL; + + for (int i = 0; i < MAX_WIIMOTES; i++) + { + if (WiimoteReal::g_wiimotes[i] == NULL) + continue; + if ([device isEqual: WiimoteReal::g_wiimotes[i]->btd] == TRUE) + wm = WiimoteReal::g_wiimotes[i]; + } + if (wm == NULL) + { + WARN_LOG(WIIMOTE, "Received packet for unknown wiimote"); + return; + } + + WARN_LOG(WIIMOTE, "L2CAP channel was closed for wiimote %i", wm->index + 1); + + if (l2capChannel == wm->cchan) + wm->cchan = nil; + + if (l2capChannel == wm->ichan) + wm->ichan = nil; +} +@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) +{ + 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) + { + WARN_LOG(WIIMOTE, "No bluetooth host controller"); + [bth release]; + return found_wiimotes; + } + + sbt = [[SearchBT alloc] init]; + sbt->maxDevices = max_wiimotes; + bti = [[IOBluetoothDeviceInquiry alloc] init]; + [bti setDelegate: sbt]; + [bti setInquiryLength: 5]; + [bti setSearchCriteria: kBluetoothServiceClassMajorAny + majorDeviceClass: kBluetoothDeviceClassMajorPeripheral + minorDeviceClass: kBluetoothDeviceClassMinorPeripheral2Joystick + ]; + [bti setUpdateNewDeviceNames: FALSE]; + + if ([bti start] == kIOReturnSuccess) + [bti retain]; + else + ERROR_LOG(WIIMOTE, "Unable to do bluetooth discovery"); + + CFRunLoopRun(); + + [bti stop]; + found_devices = [[bti foundDevices] count]; + + NOTICE_LOG(WIIMOTE, "Found %i bluetooth device%c", found_devices, + found_devices == 1 ? '\0' : 's'); + + en = [[bti foundDevices] objectEnumerator]; + for (int i = 0; (i < found_devices) && (found_wiimotes < max_wiimotes); i++) + { + IOBluetoothDevice *tmp_btd = [en nextObject]; + + 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] && [tmp_btd isEqual: wm[j]->btd] == TRUE) + 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); + wm[k]->btd = tmp_btd; + found_wiimotes++; + } + } + + [bth release]; + [bti release]; + [sbt release]; + + return found_wiimotes; +} + +// Connect to a wiimote with a known address. +bool Wiimote::Connect() +{ + ConnectBT *cbt = [[ConnectBT alloc] init]; + + if (IsConnected()) return false; + + [btd openL2CAPChannelSync: &cchan + withPSM: kBluetoothL2CAPPSMHIDControl delegate: cbt]; + [btd openL2CAPChannelSync: &ichan + withPSM: kBluetoothL2CAPPSMHIDInterrupt delegate: cbt]; + if (ichan == NULL || cchan == NULL) + { + ERROR_LOG(WIIMOTE, "Unable to open L2CAP channels for wiimote %i", + index + 1); + RealDisconnect(); + return false; + } + + NOTICE_LOG(WIIMOTE, "Connected to wiimote %i at %s", + index + 1, [[btd getAddressString] UTF8String]); + + m_connected = true; + + Handshake(); + + SetLEDs(WIIMOTE_LED_1 << index); + + [cbt release]; + + return true; +} + +// Disconnect a wiimote. +void Wiimote::RealDisconnect() +{ + if (!IsConnected()) + return; + + NOTICE_LOG(WIIMOTE, "Disconnecting wiimote %i", index + 1); + + m_connected = false; + + [cchan closeChannel]; + [ichan closeChannel]; + [btd closeConnection]; +} + +unsigned char *Wiimote::IORead() +{ + int bytes; + + if (!IsConnected()) + return NULL; + + if (outstanding == 0) + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, true); + + if (queue[reader].len == 0) + return 0; + + bytes = queue[reader].len; + unsigned char *buffer = new unsigned char[MAX_PAYLOAD]; + memcpy(buffer, queue[reader].data, bytes); + queue[reader].len = 0; + + reader++; + outstanding--; + if (reader == QUEUE_SIZE) + reader = 0; + + if (buffer[0] == '\0') + bytes = 0; + + return buffer; +} + +int Wiimote::IOWrite(unsigned char* buf, int len) +{ + IOReturn ret; + + ret = [cchan writeAsync: buf length: len refcon: nil]; + + if (ret == kIOReturnSuccess) + return len; + else + return 0; +} + +}; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp new file mode 100644 index 0000000000..e708f5203c --- /dev/null +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -0,0 +1,504 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#include +#include + +#include +#include +#include + +#include "Common.h" +#include "WiimoteReal.h" + +// Used for pair up +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WINXPSP2 +#include +#include +#pragma comment(lib, "Bthprops.lib") + +typedef struct _HIDD_ATTRIBUTES +{ + ULONG Size; + USHORT VendorID; + USHORT ProductID; + USHORT VersionNumber; +} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; + +typedef VOID (__stdcall *PHidD_GetHidGuid)(LPGUID); +typedef BOOLEAN (__stdcall *PHidD_GetAttributes)(HANDLE, PHIDD_ATTRIBUTES); +typedef BOOLEAN (__stdcall *PHidD_SetOutputReport)(HANDLE, PVOID, ULONG); + +PHidD_GetHidGuid HidD_GetHidGuid = NULL; +PHidD_GetAttributes HidD_GetAttributes = NULL; +PHidD_SetOutputReport HidD_SetOutputReport = NULL; + +HINSTANCE hid_lib = NULL; + +static int initialized = 0; + +inline void init_lib() +{ + if (!initialized) + { + hid_lib = LoadLibrary(_T("hid.dll")); + if (!hid_lib) + { + PanicAlert("Failed to load hid.dll"); + exit(EXIT_FAILURE); + } + + HidD_GetHidGuid = (PHidD_GetHidGuid)GetProcAddress(hid_lib, "HidD_GetHidGuid"); + HidD_GetAttributes = (PHidD_GetAttributes)GetProcAddress(hid_lib, "HidD_GetAttributes"); + HidD_SetOutputReport = (PHidD_SetOutputReport)GetProcAddress(hid_lib, "HidD_SetOutputReport"); + if (!HidD_GetHidGuid || !HidD_GetAttributes || !HidD_SetOutputReport) + { + PanicAlert("Failed to load hid.dll"); + exit(EXIT_FAILURE); + } + + initialized = true; + } +} + +// VID = Nintendo, PID = Wiimote +static int VIDLength = 3; +static int VID[3] = {0x057E, 0x0001, 0x0002}; +static int PID[3] = {0x0306, 0x0002, 0x00F7}; + +namespace WiimoteReal +{ + +// Find and connect 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 and connected wiimotes. +int FindWiimotes(Wiimote** wm, int max_wiimotes) +{ + GUID device_id; + HANDLE dev; + HDEVINFO device_info; + int found_wiimotes = 0; + DWORD len; + SP_DEVICE_INTERFACE_DATA device_data; + PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; + HIDD_ATTRIBUTES attr; + + init_lib(); + + // Count the number of already found wiimotes + for (int i = 0; i < MAX_WIIMOTES; ++i) + { + if (wm[i]) + found_wiimotes++; + } + + device_data.cbSize = sizeof(device_data); + + // Get the device id + HidD_GetHidGuid(&device_id); + + // Get all hid devices connected + device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); + + for (int index = 0; found_wiimotes < max_wiimotes; ++index) + { + if (detail_data) + { + free(detail_data); + detail_data = NULL; + } + + // Query the next hid device info + if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) + break; + + // Get the size of the data block required + SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL); + detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(len); + detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + // Query the data for this device + if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) + continue; + + // Determine if this wiimote has already been found. + bool found = false; + for(int i = 0; i < MAX_WIIMOTES; i++) + { + if(wm[i] && memcmp(wm[i]->devicepath, detail_data->DevicePath, 197) == 0) + { + found = true; + break; + } + } + if (found) + continue; + + // Open new device + dev = CreateFile(detail_data->DevicePath, + (GENERIC_READ | GENERIC_WRITE), + (FILE_SHARE_READ | FILE_SHARE_WRITE), + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + if (dev == INVALID_HANDLE_VALUE) + continue; + + // Get device attributes + attr.Size = sizeof(attr); + HidD_GetAttributes(dev, &attr); + + bool foundWiimote = false; + for (int i = 0; i < VIDLength; i++) + { + if (attr.VendorID == VID[i] && attr.ProductID == PID[i]) + { + foundWiimote = true; + break; + } + } + + if (foundWiimote) + { + // This is a 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); + wm[k]->dev_handle = dev; + memcpy(wm[k]->devicepath, detail_data->DevicePath, 197); + + if (!wm[k]->Connect()) + { + ERROR_LOG(WIIMOTE, "Unable to connect to wiimote %i.", wm[k]->index + 1); + delete wm[k]; + wm[k] = NULL; + } + else + ++found_wiimotes; + } + else + { + // Not a wiimote + CloseHandle(dev); + } + } + + if (detail_data) + free(detail_data); + + SetupDiDestroyDeviceInfoList(device_info); + + return found_wiimotes; +} + +// Connect to a wiimote with a known device path. +bool Wiimote::Connect() +{ + if (IsConnected()) return false; + + if (!dev_handle) + { + dev_handle = CreateFile(devicepath, + (GENERIC_READ | GENERIC_WRITE), + (FILE_SHARE_READ | FILE_SHARE_WRITE), + NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + if (dev_handle == INVALID_HANDLE_VALUE) + return false; + } + + hid_overlap.hEvent = CreateEvent(NULL, 1, 1, _T("")); + hid_overlap.Offset = 0; + hid_overlap.OffsetHigh = 0; + + m_connected = true; + + // Try a handshake to see if the device is actually connected + if (!Handshake()) + { + m_connected = false; + return false; + } + + // Set LEDs + SetLEDs(WIIMOTE_LED_1 << index); + + NOTICE_LOG(WIIMOTE, "Connected to wiimote %i.", index + 1); + + return true; +} + +void Wiimote::RealDisconnect() +{ + if (!IsConnected()) + return; + + m_connected = false; + + CloseHandle(dev_handle); + dev_handle = 0; + + ResetEvent(&hid_overlap); +} + +unsigned char *Wiimote::IORead() +{ + DWORD b, r; + + init_lib(); + + if (!IsConnected()) + return NULL; + + unsigned char *buffer = new unsigned char[MAX_PAYLOAD]; + *buffer = 0; + if (!ReadFile(dev_handle, buffer, sizeof(unsigned char) * MAX_PAYLOAD, &b, &hid_overlap)) + { + // Partial read + b = GetLastError(); + + if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) + { + // Remote disconnect + RealDisconnect(); + delete[] buffer; + return NULL; + } + + r = WaitForSingleObject(hid_overlap.hEvent, WIIMOTE_DEFAULT_TIMEOUT); + if (r == WAIT_TIMEOUT) + { + // Timeout - cancel and continue + + if (*buffer) + WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).", + WIIMOTE_DEFAULT_TIMEOUT); + + CancelIo(dev_handle); + ResetEvent(hid_overlap.hEvent); + delete[] buffer; + return NULL; + } + else if (r == WAIT_FAILED) + { + WARN_LOG(WIIMOTE, "A wait error occured on reading from wiimote %i.", index + 1); + delete[] buffer; + return NULL; + } + + if (!GetOverlappedResult(dev_handle, &hid_overlap, &b, 0)) + { + delete[] buffer; + return NULL; + } + } + + // This needs to be done even if ReadFile fails, essential during init + // Move the data over one, so we can add back in data report indicator byte (here, 0xa1) + memmove(buffer + 1, buffer, sizeof(buffer) - 1); + buffer[0] = 0xa1; + + ResetEvent(hid_overlap.hEvent); + return buffer; +} + +int Wiimote::IOWrite(unsigned char* buf, int len) +{ + DWORD bytes, dw; + int i; + + init_lib(); + + if (!IsConnected()) + return NULL; + + switch (stack) + { + case MSBT_STACK_UNKNOWN: + { + // Try to auto-detect the stack type + if (i = WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap)) + { + // Bluesoleil will always return 1 here, even if it's not connected + stack = MSBT_STACK_BLUESOLEIL; + return i; + } + + if (i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1)) + { + stack = MSBT_STACK_MS; + return i; + } + +#if 0 + dw = GetLastError(); + // Checking for 121 = timeout on semaphore/device off/disconnected to + // avoid trouble with other stacks toshiba/widcomm + // 995 = The I/O operation has been aborted because of a thread exit or + // an application request. + + if ( (dw == 121) || (dw == 995) ) + { + NOTICE_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]"); + RealDisconnect(); + } + else ERROR_LOG(WIIMOTE, + "IOWrite[MSBT_STACK_UNKNOWN]: ERROR: %08x", dw); +#endif + + + // If the part below causes trouble on WIDCOMM/TOSHIBA stack uncomment + // the lines above, and comment out the 3 lines below instead. + + NOTICE_LOG(WIIMOTE, "IOWrite[MSBT_STACK_UNKNOWN]"); + RealDisconnect(); + return 0; + } + + case MSBT_STACK_MS: + i = HidD_SetOutputReport(dev_handle, buf + 1, len - 1); + dw = GetLastError(); + + if (dw == 121) + { + // Semaphore timeout + NOTICE_LOG(WIIMOTE, "WiimoteIOWrite[MSBT_STACK_MS]: Unable to send data to wiimote"); + RealDisconnect(); + return 0; + } + return i; + + case MSBT_STACK_BLUESOLEIL: + return WriteFile(dev_handle, buf + 1, 22, &bytes, &hid_overlap); + } + + return 0; +} + +int UnPair() +{ + // TODO: + return 0; +} + +// WiiMote Pair-Up, function will return amount of either new paired or unpaired devices +// negative number on failure +int PairUp(bool unpair) +{ + int nPaired = 0; + + BLUETOOTH_DEVICE_SEARCH_PARAMS srch; + srch.dwSize = sizeof(srch); + srch.fReturnAuthenticated = true; + srch.fReturnRemembered = true; + // Does not filter properly somehow, so we need to do an additional check on + // fConnected BT Devices + srch.fReturnConnected = true; + srch.fReturnUnknown = true; + srch.fIssueInquiry = true; + srch.cTimeoutMultiplier = 2; // == (2 * 1.28) seconds + + BLUETOOTH_FIND_RADIO_PARAMS radioParam; + radioParam.dwSize = sizeof(radioParam); + + HANDLE hRadio; + + // Enumerate BT radios + HBLUETOOTH_RADIO_FIND hFindRadio = BluetoothFindFirstRadio(&radioParam, &hRadio); + + if (NULL == hFindRadio) + return -1; + + while (hFindRadio) + { + BLUETOOTH_RADIO_INFO radioInfo; + radioInfo.dwSize = sizeof(radioInfo); + + // TODO: check for SUCCEEDED() + BluetoothGetRadioInfo(hRadio, &radioInfo); + + srch.hRadio = hRadio; + + BLUETOOTH_DEVICE_INFO btdi; + btdi.dwSize = sizeof(btdi); + + // Enumerate BT devices + HBLUETOOTH_DEVICE_FIND hFindDevice = BluetoothFindFirstDevice(&srch, &btdi); + while (hFindDevice) + { + // btdi.szName is sometimes missings it's content - it's a bt feature.. + DEBUG_LOG(WIIMOTE, "authed %i connected %i remembered %i ", + btdi.fAuthenticated, btdi.fConnected, btdi.fRemembered); + + // TODO: Probably could just check for "Nintendo RVL" + if (0 == wcscmp(btdi.szName, L"Nintendo RVL-WBC-01") || + 0 == wcscmp(btdi.szName, L"Nintendo RVL-CNT-01")) + { + if (unpair) + { + if (SUCCEEDED(BluetoothRemoveDevice(&btdi.Address))) + { + NOTICE_LOG(WIIMOTE, + "Pair-Up: Automatically removed BT Device on shutdown: %08x", + GetLastError()); + ++nPaired; + } + } + else + { + if (false == btdi.fConnected) + { + // TODO: improve the read of the BT driver, esp. when batteries + // of the wiimote are removed while being 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); + } + + // Activate service + const DWORD hr = BluetoothSetServiceState(hRadio, &btdi, + &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE); + if (SUCCEEDED(hr)) + ++nPaired; + else + ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr); + } + } + } + + if (false == BluetoothFindNextDevice(hFindDevice, &btdi)) + { + BluetoothFindDeviceClose(hFindDevice); + hFindDevice = NULL; + } + } + + if (false == BluetoothFindNextRadio(hFindRadio, &hRadio)) + { + BluetoothFindRadioClose(hFindRadio); + hFindRadio = NULL; + } + } + + return nPaired; +} + +}; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index 9bb1f9d24d..64c755d299 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -22,20 +22,10 @@ #include "StringUtil.h" #include "Timer.h" -#include "wiiuse.h" #include "WiimoteReal.h" #include "../WiimoteEmu/WiimoteHid.h" -// used for pair up -#ifdef _WIN32 -#undef NTDDI_VERSION -#define NTDDI_VERSION NTDDI_WINXPSP2 -#include -#include -#pragma comment(lib, "Bthprops.lib") -#endif - #ifdef __APPLE__ #import #endif @@ -45,51 +35,48 @@ unsigned int g_wiimote_sources[MAX_WIIMOTES]; namespace WiimoteReal { -bool g_real_wiimotes_initialized = false; -wiimote_t** g_wiimotes_from_wiiuse = NULL; -unsigned int g_wiimotes_found = 0; -// removed g_wiimotes_lastfound because Refresh() isn't taking advantage of it +bool g_real_wiimotes_initialized = false; +unsigned int g_wiimotes_found = 0; volatile bool g_run_wiimote_thread = false; Common::Thread *g_wiimote_threads[MAX_WIIMOTES] = {}; Common::CriticalSection g_refresh_critsec; - THREAD_RETURN WiimoteThreadFunc(void* arg); void StartWiimoteThreads(); void StopWiimoteThreads(); Wiimote *g_wiimotes[MAX_WIIMOTES]; -Wiimote::Wiimote(wiimote_t* const _wiimote, const unsigned int _index) +Wiimote::Wiimote(const unsigned int _index) : index(_index) - , wiimote(_wiimote) - , m_last_data_report(NULL) - , m_channel(0) +#if defined(__linux__) && HAVE_BLUEZ + , out_sock(-1), in_sock(-1) +#elif defined(_WIN32) + , dev_handle(0), stack(MSBT_STACK_UNKNOWN) +#endif + , leds(0) , m_last_data_report(NULL) , m_channel(0) , m_connected(false) { - // disable reporting +#if defined(__linux__) && HAVE_BLUEZ + bdaddr = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; +#endif + DisableDataReporting(); - - // set LEDs - wiiuse_set_leds(wiimote, WIIMOTE_LED_1 << index); - - // TODO: make Dolphin connect wiimote, maybe } Wiimote::~Wiimote() { + RealDisconnect(); + ClearReadQueue(); // clear write queue Report rpt; while (m_write_reports.Pop(rpt)) delete[] rpt.first; - - // disable reporting / wiiuse might do this on shutdown anyway, o well, don't know for sure - DisableDataReporting(); } -// silly, copying data n stuff, o well, don't use this too often +// Silly, copying data n stuff, o well, don't use this too often void Wiimote::SendPacket(const u8 rpt_id, const void* const data, const unsigned int size) { Report rpt; @@ -182,13 +169,12 @@ void Wiimote::InterruptChannel(const u16 channel, const void* const data, const bool Wiimote::Read() { - if (wiiuse_io_read(wiimote)) + u8* rpt; + if ((rpt = IORead())) { if (m_channel) { - // add it to queue - u8* const rpt = new u8[MAX_PAYLOAD]; - memcpy(rpt, wiimote->event_buf, MAX_PAYLOAD); + // Add it to queue m_read_reports.Push(rpt); } @@ -203,7 +189,7 @@ bool Wiimote::Write() Report rpt; if (m_write_reports.Pop(rpt)) { - wiiuse_io_write(wiimote, rpt.first, rpt.second); + IOWrite(rpt.first, rpt.second); delete[] rpt.first; return true; @@ -212,35 +198,35 @@ bool Wiimote::Write() return false; } -// returns the next report that should be sent +// Returns the next report that should be sent u8* Wiimote::ProcessReadQueue() { - // pop through the queued reports + // Pop through the queued reports u8* rpt = m_last_data_report; while (m_read_reports.Pop(rpt)) { - // a data report if (rpt[1] >= WM_REPORT_CORE) + // A data report m_last_data_report = rpt; - // some other kind of report else + // Some other kind of report return rpt; } - // the queue was empty, or there were only data reports + // The queue was empty, or there were only data reports return rpt; } void Wiimote::Update() { - // pop through the queued reports + // Pop through the queued reports u8* const rpt = ProcessReadQueue(); - // send the report + // Send the report if (rpt && m_channel) Core::Callback_WiimoteInterruptChannel(index, m_channel, rpt, MAX_PAYLOAD); - // delete the data if it isn't also the last data rpt + // Delete the data if it isn't also the last data rpt if (rpt != m_last_data_report) delete[] rpt; } @@ -249,10 +235,91 @@ void Wiimote::Disconnect() { m_channel = 0; - // disable reporting DisableDataReporting(); } +bool Wiimote::IsConnected() +{ + return m_connected; +} + +// Rumble briefly +void Wiimote::Rumble() +{ + if (!IsConnected()) + return; + + unsigned char buffer = 0x01; + DEBUG_LOG(WIIMOTE, "Starting rumble..."); + SendRequest(WM_CMD_RUMBLE, &buffer, 1); + + SLEEP(200); + + DEBUG_LOG(WIIMOTE, "Stopping rumble..."); + buffer = 0x00; + SendRequest(WM_CMD_RUMBLE, &buffer, 1); +} + +// Set the active LEDs. +// leds is a bitwise or of WIIMOTE_LED_1 through WIIMOTE_LED_4. +void Wiimote::SetLEDs(int new_leds) +{ + unsigned char buffer; + + if (!IsConnected()) + return; + + // Remove the lower 4 bits because they control rumble + buffer = leds = (new_leds & 0xF0); + + SendRequest(WM_CMD_LED, &buffer, 1); +} + +// Send a handshake +bool Wiimote::Handshake() +{ + // Set buffer[0] to 0x04 for continuous reporting + unsigned char buffer[2] = {0x04, 0x30}; + + if (!IsConnected()) + return 0; + + DEBUG_LOG(WIIMOTE, "Sending handshake to wiimote"); + + return SendRequest(WM_CMD_REPORT_TYPE, buffer, 2); +} + +// Send a packet to the wiimote. +// report_type should be one of WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc. +bool Wiimote::SendRequest(unsigned char report_type, unsigned char* data, int length) +{ + unsigned char buffer[32] = {WM_SET_REPORT | WM_BT_OUTPUT, report_type}; + + memcpy(buffer + 2, data, length); + + return (IOWrite(buffer, length + 2) != 0); +} + +#ifndef _WIN32 +// Connect all discovered wiimotes +// Return the number of wiimotes that successfully connected. +static int ConnectWiimotes(Wiimote** wm) +{ + int connected = 0; + + for (int i = 0; i < MAX_WIIMOTES; ++i) + { + if (!wm[i] || wm[i]->IsConnected()) + continue; + + if (wm[i]->Connect()) + ++connected; + } + + return connected; +} +#endif + void LoadSettings() { std::string ini_filename = (std::string(File::GetUserPath(D_CONFIG_IDX)) + WIIMOTE_INI_NAME ".ini" ); @@ -272,57 +339,41 @@ void LoadSettings() unsigned int Initialize() { - // return if already initialized + // Return if already initialized if (g_real_wiimotes_initialized) return g_wiimotes_found; memset(g_wiimotes, 0, sizeof(g_wiimotes)); - // only call wiiuse_find with the number of slots configured for real wiimotes + // Only call FindWiimotes with the number of slots configured for real wiimotes unsigned int wanted_wiimotes = 0; for (unsigned int i = 0; i < MAX_WIIMOTES; ++i) if (WIIMOTE_SRC_REAL & g_wiimote_sources[i]) ++wanted_wiimotes; - // don't bother initializing wiiuse if we don't want any real wiimotes + // Don't bother initializing if we don't want any real wiimotes if (0 == wanted_wiimotes) { g_wiimotes_found = 0; return 0; } - // initialized + // Initialized g_real_wiimotes_initialized = true; -#ifdef _WIN32 - // Alloc memory for wiimote structure only if we're starting fresh - if(!g_wiimotes_from_wiiuse) - g_wiimotes_from_wiiuse = wiiuse_init(MAX_WIIMOTES); - // on windows wiiuse_find() expects as a 3rd parameter the amount of last connected wiimotes instead of the timeout, - // a timeout parameter is useless on win32 here, since at this points we already have the wiimotes discovered and paired up, just not connected. - g_wiimotes_found = wiiuse_find(g_wiimotes_from_wiiuse, wanted_wiimotes, 0); -#else - g_wiimotes_from_wiiuse = wiiuse_init(MAX_WIIMOTES); - g_wiimotes_found = wiiuse_find(g_wiimotes_from_wiiuse, wanted_wiimotes, 5); -#endif - DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted", - g_wiimotes_found, wanted_wiimotes); + g_wiimotes_found = FindWiimotes(g_wiimotes, wanted_wiimotes); - g_wiimotes_found = - wiiuse_connect(g_wiimotes_from_wiiuse, g_wiimotes_found); + DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted", + g_wiimotes_found, wanted_wiimotes); + +#ifndef _WIN32 + g_wiimotes_found = ConnectWiimotes(g_wiimotes); +#endif DEBUG_LOG(WIIMOTE, "Connected to %i Real Wiimotes", g_wiimotes_found); - // create real wiimote class instances, assign wiimotes - for (unsigned int i = 0, w = 0; iIsConnected())) + { + delete g_wiimotes[i]; + g_wiimotes[i] = NULL; + delete g_wiimote_threads[i]; + g_wiimote_threads[i] = NULL; + --g_wiimotes_found; + } + + // Don't scan for wiimotes if we don't want any more + if (wanted_wiimotes <= g_wiimotes_found) { - // create/assign wiimote - if (WIIMOTE_SRC_REAL & g_wiimote_sources[i] && NULL == g_wiimotes[i]) - g_wiimotes[i] = new Wiimote(g_wiimotes_from_wiiuse[w++], i); + g_refresh_critsec.Leave(); + return; } + + // Scan for wiimotes + unsigned int num_wiimotes = FindWiimotes(g_wiimotes, wanted_wiimotes); + + DEBUG_LOG(WIIMOTE, "Found %i Real Wiimotes, %i wanted", num_wiimotes, wanted_wiimotes); + +#ifndef _WIN32 + // Connect newly found wiimotes. + int num_new_wiimotes = ConnectWiimotes(g_wiimotes); + + DEBUG_LOG(WIIMOTE, "Connected to %i additional Real Wiimotes", num_new_wiimotes); +#endif g_wiimotes_found = num_wiimotes; g_refresh_critsec.Leave(); StartWiimoteThreads(); - -#else // windows/ OSX - g_refresh_critsec.Enter(); - - // should be fine i think - Shutdown(); - Initialize(); - - g_refresh_critsec.Leave(); -#endif } void InterruptChannel(int _WiimoteNumber, u16 _channelID, const void* _pData, u32 _Size) @@ -453,18 +496,17 @@ void StateChange(PLUGIN_EMUSTATE newState) void StartWiimoteThreads() { g_run_wiimote_thread = true; - for (unsigned int i=0; iWaitForDeath(); delete g_wiimote_threads[i]; g_wiimote_threads[i] = NULL; } @@ -478,19 +520,15 @@ THREAD_RETURN WiimoteThreadFunc(void* arg) Wiimote* const wiimote = (Wiimote*)arg; - { char thname[] = "Wiimote # Thread"; thname[8] = (char)('1' + wiimote->index); Common::SetCurrentThreadName(thname); - } // rumble briefly - wiiuse_rumble(wiimote->wiimote, 1); - SLEEP(200); - wiiuse_rumble(wiimote->wiimote, 0); + wiimote->Rumble(); // main loop - while (g_run_wiimote_thread) + while (g_run_wiimote_thread && wiimote->IsConnected()) { // hopefully this is alright while (wiimote->Write()) {} @@ -506,110 +544,4 @@ THREAD_RETURN WiimoteThreadFunc(void* arg) return 0; } -#ifdef _WIN32 -int UnPair() -{ - // TODO: - return 0; -} - -// WiiMote Pair-Up, function will return amount of either new paired or unpaired devices -// negative number on failure -int PairUp(bool unpair) -{ - int nPaired = 0; - - BLUETOOTH_DEVICE_SEARCH_PARAMS srch; - srch.dwSize = sizeof(srch); - 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 = true; - srch.cTimeoutMultiplier = 2; // == (2 * 1.28) seconds - - BLUETOOTH_FIND_RADIO_PARAMS radioParam; - radioParam.dwSize = sizeof(radioParam); - - HANDLE hRadio; - - // Enumerate BT radios - HBLUETOOTH_RADIO_FIND hFindRadio = BluetoothFindFirstRadio(&radioParam, &hRadio); - - if (NULL == hFindRadio) - return -1; - - while (hFindRadio) - { - BLUETOOTH_RADIO_INFO radioInfo; - radioInfo.dwSize = sizeof(radioInfo); - - // TODO: check for SUCCEEDED() - BluetoothGetRadioInfo(hRadio, &radioInfo); - - srch.hRadio = hRadio; - - BLUETOOTH_DEVICE_INFO btdi; - btdi.dwSize = sizeof(btdi); - - // Enumerate BT devices - HBLUETOOTH_DEVICE_FIND hFindDevice = BluetoothFindFirstDevice(&srch, &btdi); - while (hFindDevice) - { - //btdi.szName is sometimes missings it's content - it's a bt feature.. - DEBUG_LOG(WIIMOTE, "authed %i connected %i remembered %i ", btdi.fAuthenticated, btdi.fConnected, btdi.fRemembered); - - // TODO: Probably could just check for "Nintendo RVL" - if (0 == wcscmp(btdi.szName, L"Nintendo RVL-WBC-01") || 0 == wcscmp(btdi.szName, L"Nintendo RVL-CNT-01")) - { - if (unpair) - { - if (SUCCEEDED(BluetoothRemoveDevice(&btdi.Address))) - { - NOTICE_LOG(WIIMOTE, "Pair-Up: Automatically removed BT Device on shutdown: %08x", GetLastError()); - ++nPaired; - } - } - else - { - if (false == btdi.fConnected) - { - //TODO: improve the read of the BT driver, esp. when batteries of the wiimote are removed while being 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); - } - - // Activate service - const DWORD hr = BluetoothSetServiceState(hRadio, &btdi, &HumanInterfaceDeviceServiceClass_UUID, BLUETOOTH_SERVICE_ENABLE); - if (SUCCEEDED(hr)) - ++nPaired; - else - ERROR_LOG(WIIMOTE, "Pair-Up: BluetoothSetServiceState() returned %08x", hr); - } - } - } - - if (false == BluetoothFindNextDevice(hFindDevice, &btdi)) - { - BluetoothFindDeviceClose(hFindDevice); - hFindDevice = NULL; - } - } - - if (false == BluetoothFindNextRadio(hFindRadio, &hRadio)) - { - BluetoothFindRadioClose(hFindRadio); - hFindRadio = NULL; - } - } - - return nPaired; -} -#endif - }; // end of namespace diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index 3908a8e6ea..7f152a4205 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -19,7 +19,7 @@ #ifndef WIIMOTE_REAL_H #define WIIMOTE_REAL_H -#include "wiiuse.h" +#include "WiimoteRealBase.h" #include "ChunkFile.h" #include "Thread.h" #include "FifoQueue.h" @@ -43,38 +43,73 @@ namespace WiimoteReal class Wiimote { friend class WiimoteEmu::Wiimote; -public: - Wiimote(wiimote_t* const wm, const unsigned int index); - ~Wiimote(); + public: + Wiimote(const unsigned int _index); + ~Wiimote(); - void ControlChannel(const u16 channel, const void* const data, const u32 size); - void InterruptChannel(const u16 channel, const void* const data, const u32 size); - void Update(); + void ControlChannel(const u16 channel, const void* const data, const u32 size); + void InterruptChannel(const u16 channel, const void* const data, const u32 size); + void Update(); - u8* ProcessReadQueue(); + u8* ProcessReadQueue(); - bool Read(); - bool Write(); - void Disconnect(); - void DisableDataReporting(); + bool Read(); + bool Write(); + bool Connect(); + bool IsConnected(); + void Disconnect(); + void DisableDataReporting(); + void Rumble(); + void SendPacket(const u8 rpt_id, const void* const data, const unsigned int size); - void SendPacket(const u8 rpt_id, const void* const data, const unsigned int size); + // Pointer to data, and size of data + typedef std::pair Report; - // pointer to data, and size of data - typedef std::pair Report; + const unsigned int index; - const unsigned int index; - wiimote_t* const wiimote; +#if defined(__APPLE__) + IOBluetoothDevice *btd; + IOBluetoothL2CAPChannel *ichan; + IOBluetoothL2CAPChannel *cchan; + #define QUEUE_SIZE 64 + struct qbuffer + { + char data[MAX_PAYLOAD]; + int len; + } queue[QUEUE_SIZE]; + int reader; + int writer; + int outstanding; + int watermark; +#elif defined(__linux__) && HAVE_BLUEZ + bdaddr_t bdaddr; // Bluetooth address + int out_sock; // Output socket + int in_sock; // Input socket +#elif defined(_WIN32) + char devicepath[255]; // Unique wiimote reference + //ULONGLONG btaddr; // Bluetooth address + HANDLE dev_handle; // HID handle + OVERLAPPED hid_overlap; // Overlap handle + enum win_bt_stack_t stack; // Type of bluetooth stack to use +#endif + unsigned char leds; // Currently lit leds -protected: - u8 *m_last_data_report; - u16 m_channel; + protected: + u8 *m_last_data_report; + u16 m_channel; -private: - void ClearReadQueue(); + private: + void ClearReadQueue(); + void RealDisconnect(); + bool SendRequest(unsigned char report_type, unsigned char* data, int length); + bool Handshake(); + void SetLEDs(int leds); + unsigned char *IORead(); + int IOWrite(unsigned char* buf, int len); - Common::FifoQueue m_read_reports; - Common::FifoQueue m_write_reports; + bool m_connected; + Common::FifoQueue m_read_reports; + Common::FifoQueue m_write_reports; }; extern Common::CriticalSection g_refresh_critsec; @@ -87,6 +122,8 @@ void Update(int _WiimoteNumber); void DoState(PointerWrap &p); void StateChange(PLUGIN_EMUSTATE newState); -}; // WiiMoteReal +int FindWiimotes(Wiimote** wm, int max_wiimotes); + +}; // WiimoteReal #endif diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h new file mode 100644 index 0000000000..6765748e58 --- /dev/null +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteRealBase.h @@ -0,0 +1,75 @@ +// Copyright (C) 2003 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef WIIMOTE_COMM_H +#define WIIMOTE_COMM_H + +#ifdef _WIN32 + #include +#elif defined(__APPLE__) + #import +#elif defined(__linux__) && HAVE_BLUEZ + #include +#endif + +// Wiimote internal codes + +// Communication channels +#define WM_OUTPUT_CHANNEL 0x11 +#define WM_INPUT_CHANNEL 0x13 + +#define WM_SET_REPORT 0x50 + +// Commands +#define WM_CMD_RUMBLE 0x10 +#define WM_CMD_LED 0x11 +#define WM_CMD_REPORT_TYPE 0x12 +#define WM_CMD_IR 0x13 +#define WM_CMD_SPEAKER_ENABLE 0x14 +#define WM_CMD_CTRL_STATUS 0x15 +#define WM_CMD_WRITE_DATA 0x16 +#define WM_CMD_READ_DATA 0x17 +#define WM_CMD_SPEAKER_DATA 0x18 +#define WM_CMD_SPEAKER_MUTE 0x19 +#define WM_CMD_IR_2 0x1A + +#define WM_BT_INPUT 0x01 +#define WM_BT_OUTPUT 0x02 + +// LED bit masks +#define WIIMOTE_LED_NONE 0x00 +#define WIIMOTE_LED_1 0x10 +#define WIIMOTE_LED_2 0x20 +#define WIIMOTE_LED_3 0x40 +#define WIIMOTE_LED_4 0x80 + +// End Wiimote internal codes + +#define MAX_PAYLOAD 32 +#define WIIMOTE_DEFAULT_TIMEOUT 30 + +#ifdef _WIN32 +// Available bluetooth stacks for Windows. +typedef enum win_bt_stack_t +{ + MSBT_STACK_UNKNOWN, + MSBT_STACK_MS, + MSBT_STACK_BLUESOLEIL +} win_bt_stack_t; +#endif + +#endif // WIIMOTE_COMM_H diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript index 2ca53aee65..182c1f0392 100644 --- a/Source/Core/Core/Src/SConscript +++ b/Source/Core/Core/Src/SConscript @@ -146,10 +146,10 @@ libs = [ ] if sys.platform == 'win32': - files += [ "HW/BBA-TAP/TAP_Win32.cpp", "stdafx.cpp" ] + files += [ "HW/BBA-TAP/TAP_Win32.cpp", "stdafx.cpp", "HW/WiimoteReal/IOWin.cpp" ] elif sys.platform == 'darwin': - files += [ "HW/BBA-TAP/TAP_Apple.cpp" ] + files += [ "HW/BBA-TAP/TAP_Apple.cpp", "HW/WiimoteReal/IOOsx.mm" ] else: - files += [ "HW/BBA-TAP/TAP_Unix.cpp" ] + files += [ "HW/BBA-TAP/TAP_Unix.cpp", "HW/WiimoteReal/IONix.cpp" ] env.StaticLibrary(env['local_libs'] + 'core', files, LIBS = libs) diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt index c8cbbb819e..1cefb2411a 100644 --- a/Source/Core/DolphinWX/CMakeLists.txt +++ b/Source/Core/DolphinWX/CMakeLists.txt @@ -9,7 +9,6 @@ set(LIBS core lua z sfml-network - wiiuse SDL GL ${XRANDR_LIBRARIES} diff --git a/Source/Core/DolphinWX/Src/SConscript b/Source/Core/DolphinWX/Src/SConscript index de87eb3a86..8333092972 100644 --- a/Source/Core/DolphinWX/Src/SConscript +++ b/Source/Core/DolphinWX/Src/SConscript @@ -11,7 +11,7 @@ files = [ libs = [ 'core', 'lzo2', 'discio', 'bdisasm', - 'inputcommon', 'common', 'lua', 'z', 'sfml-network', 'wiiuse', + 'inputcommon', 'common', 'lua', 'z', 'sfml-network', ] if env['HAVE_WX']: diff --git a/Source/Core/wiiuse/CMakeLists.txt b/Source/Core/wiiuse/CMakeLists.txt deleted file mode 100644 index 069e77142c..0000000000 --- a/Source/Core/wiiuse/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -set(SRCS Src/ir.cpp - Src/wiiuse.cpp) - -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(SRCS ${SRCS} Src/io_osx.m) -elseif((${CMAKE_SYSTEM_NAME} MATCHES "Linux") AND BLUEZ_FOUND) - set(SRCS ${SRCS} Src/io_nix.cpp) - set(LIBS ${LIBS} bluetooth) -elseif(WIN32) - set(SRCS ${SRCS} Src/io_win.cpp) -else() - set(SRCS ${SRCS} Src/io_dummy.cpp) -endif() - -add_library(wiiuse STATIC ${SRCS}) -target_link_libraries(wiiuse ${LIBS}) diff --git a/Source/Core/wiiuse/Src/SConscript b/Source/Core/wiiuse/Src/SConscript deleted file mode 100644 index 64ee74c4bb..0000000000 --- a/Source/Core/wiiuse/Src/SConscript +++ /dev/null @@ -1,20 +0,0 @@ -# -*- python -*- - -Import('env') -import sys - -files = [ - "ir.cpp", - "wiiuse.cpp", - ] - -if sys.platform == 'darwin': - files += [ "io_osx.mm" ] -elif sys.platform == 'linux2' and env['HAVE_BLUEZ']: - files += [ "io_nix.cpp" ] -elif sys.platform == 'win32': - files += [ "io_win.cpp" ] -else: - files += [ "io_dummy.cpp" ] - -env.StaticLibrary(env['local_libs'] + "wiiuse", files) diff --git a/Source/Core/wiiuse/Src/io_dummy.cpp b/Source/Core/wiiuse/Src/io_dummy.cpp deleted file mode 100644 index 7e4f211dab..0000000000 --- a/Source/Core/wiiuse/Src/io_dummy.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "Common.h" -#include "wiiuse_internal.h" - -int wiiuse_find(struct wiimote_t **wm, int max_wiimotes, int timeout) -{ - return 0; -} - -int wiiuse_connect(struct wiimote_t **wm, int wiimotes) -{ - return 0; -} - -void wiiuse_disconnect(struct wiimote_t *wm) -{ - return; -} - -int wiiuse_io_read(struct wiimote_t *wm) -{ - return 0; -} - -int wiiuse_io_write(struct wiimote_t *wm, byte *buf, int len) -{ - return 0; -} diff --git a/Source/Core/wiiuse/Src/io_nix.cpp b/Source/Core/wiiuse/Src/io_nix.cpp deleted file mode 100644 index 7784767aea..0000000000 --- a/Source/Core/wiiuse/Src/io_nix.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "Common.h" -#include "wiiuse_internal.h" - -static int wiiuse_connect_single(struct wiimote_t* wm, char* address); - -// Find a wiimote or wiimotes. -// Does not replace already found wiimotes even if they are disconnected. -// wm An array of wiimote_t structures. -// max_wiimotes The number of wiimote structures in wm. -// timeout The number of seconds before the search times out. -// Returns the total number of found wiimotes. -// This function will only look for wiimote devices. -// When a device is found the address in the structures will be set. -// You can then call wiimote_connect() to connect to the found devices. -int wiiuse_find(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; - } - - int try_num = 0; - while ((try_num < timeout) && (found_wiimotes < max_wiimotes)) - { - 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 ~one second - found_devices = hci_inquiry(device_id, 1, 128, NULL, &scan_info, IREQ_CACHE_FLUSH); - if (found_devices < 0) - { - perror("hci_inquiry"); - return 0; - } - - NOTICE_LOG(WIIMOTE, "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); - - NOTICE_LOG(WIIMOTE, "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; - } - } - } - try_num++; - } - - close(device_sock); - return found_wiimotes; -} - -// Connect to a wiimote or wiimotes once an address is known. -// wm An array of wiimote_t structures. -// wiimotes The number of wiimote structures in wm. -// Return the number of wiimotes that successfully connected. -// Connect to a number of wiimotes when the address is already set -// in the wiimote_t structures. These addresses are normally set -// by the wiiuse_find() function, but can also be set manually. -int wiiuse_connect(struct wiimote_t** wm, int wiimotes) -{ - int connected = 0; - int i = 0; - - for (; i < wiimotes; ++i) - { - if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND)) - // if the device address is not set, skip it - continue; - - if (wiiuse_connect_single(wm[i], NULL)) - ++connected; - } - - return connected; -} - -// Connect to a wiimote with a known address. -// wm Pointer to a wiimote_t structure. -// address The address of the device to connect to. -// If NULL, use the address in the struct set by wiiuse_find(). -// Return 1 on success, 0 on failure -static int wiiuse_connect_single(struct wiimote_t* wm, char* address) -{ - struct sockaddr_l2 addr; - - if (!wm || WIIMOTE_IS_CONNECTED(wm)) - return 0; - - addr.l2_family = AF_BLUETOOTH; - bdaddr_t *bdaddr = &wm->bdaddr; - if (address) - // use provided address - str2ba(address, &addr.l2_bdaddr); - else - { - bdaddr_t bdaddr_any = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; - if (bacmp(bdaddr, &bdaddr_any) == 0) - return 0; - // use address of device discovered - addr.l2_bdaddr = *bdaddr; - - } - - // OUTPUT CHANNEL - wm->out_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (wm->out_sock == -1) - return 0; - - addr.l2_cid = 0; - addr.l2_psm = htobs(WM_OUTPUT_CHANNEL); - - // connect to wiimote - if (connect(wm->out_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) - { - perror("connect() output sock"); - return 0; - } - - // INPUT CHANNEL - wm->in_sock = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (wm->in_sock == -1) - { - close(wm->out_sock); - wm->out_sock = -1; - return 0; - } - - addr.l2_psm = htobs(WM_INPUT_CHANNEL); - - // connect to wiimote - if (connect(wm->in_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) - { - perror("connect() interrupt sock"); - close(wm->out_sock); - wm->out_sock = -1; - return 0; - } - - NOTICE_LOG(WIIMOTE, "Connected to wiimote [id %i].", wm->unid); - // do the handshake - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); - - wiiuse_set_report_type(wm); - - return 1; -} - -// Disconnect a wiimote. -// wm Pointer to a wiimote_t structure. -// Note that this will not free the wiimote structure. -void wiiuse_disconnect(struct wiimote_t* wm) -{ - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) - return; - - close(wm->out_sock); - close(wm->in_sock); - - wm->out_sock = -1; - wm->in_sock = -1; - wm->event = WIIUSE_NONE; - - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); -} - -int wiiuse_io_read(struct wiimote_t* wm) -{ - struct timeval tv; - fd_set fds; - int r; - if (!wm) - return 0; - - // block select() for 1/2000th of a second - tv.tv_sec = 0; - tv.tv_usec = wm->timeout * 1000; // timeout is in Milliseconds tv_usec is in Microseconds! - - FD_ZERO(&fds); - // only poll it if it is connected - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED)) - { - FD_SET(wm->in_sock, &fds); - //highest_fd = wm[i]->in_sock; - } - else - // nothing to poll - return 0; - - if (select(wm->in_sock + 1, &fds, NULL, NULL, &tv) == -1) - { - ERROR_LOG(WIIMOTE, "Unable to select() the wiimote interrupt socket(s)."); - perror("Error Details"); - return 0; - } - - // if this wiimote is not connected, skip it - if (!WIIMOTE_IS_CONNECTED(wm)) - return 0; - - if (FD_ISSET(wm->in_sock, &fds)) - { - //memset(wm->event_buf, 0, sizeof(wm->event_buf)); - // read the pending message into the buffer - r = read(wm->in_sock, wm->event_buf, sizeof(wm->event_buf)); - if (r == -1) - { - // error reading data - ERROR_LOG(WIIMOTE, "Receiving wiimote data (id %i).", wm->unid); - perror("Error Details"); - - if (errno == ENOTCONN) - { - // this can happen if the bluetooth dongle is disconnected - ERROR_LOG(WIIMOTE, "Bluetooth appears to be disconnected. Wiimote unid %i will be disconnected.", wm->unid); - wiiuse_disconnect(wm); - wm->event = WIIUSE_UNEXPECTED_DISCONNECT; - } - - return 0; - } - if (!r) - { - // remote disconnect - wiiuse_disconnected(wm); - return 0; - } - wm->event_buf[0] = 0xa2; // Make sure it's 0xa2, just in case - return 1; - } - return 0; -} - -int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) -{ - if(buf[0] == 0xa2) - buf[0] = 0x52; // May not be needed. Will be changing/correcting in the next few revisions - return write(wm->out_sock, buf, len); -} diff --git a/Source/Core/wiiuse/Src/io_osx.mm b/Source/Core/wiiuse/Src/io_osx.mm deleted file mode 100644 index 1361823457..0000000000 --- a/Source/Core/wiiuse/Src/io_osx.mm +++ /dev/null @@ -1,360 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $Header$ - * - */ - -/** - * @file - * @brief Handles device I/O for OS X. - */ - -#import -extern "C" OSErr UpdateSystemActivity(UInt8 activity); -#define BLUETOOTH_VERSION_USE_CURRENT -#import - -#include "Common.h" -#include "HW/Wiimote.h" -#include "wiiuse_internal.h" - -static int wiiuse_connect_single(struct wiimote_t *wm, char *address); - -static struct wiimote_t *motes[MAX_WIIMOTES]; - -@interface SearchBT: NSObject { -@public - unsigned int maxDevices; -} -@end - -@implementation SearchBT -- (void) deviceInquiryComplete: (IOBluetoothDeviceInquiry *) sender - error: (IOReturn) error - aborted: (BOOL) aborted -{ - CFRunLoopStop(CFRunLoopGetCurrent()); -} - -- (void) deviceInquiryDeviceFound: (IOBluetoothDeviceInquiry *) sender - device: (IOBluetoothDevice *) device -{ - NOTICE_LOG(WIIMOTE, "Discovered bluetooth device at %s: %s", - [[device getAddressString] UTF8String], - [[device getName] UTF8String]); - - if ([[sender foundDevices] count] == maxDevices) - [sender stop]; -} -@end - -@interface ConnectBT: NSObject {} -@end - -@implementation ConnectBT -- (void) l2capChannelData: (IOBluetoothL2CAPChannel *) l2capChannel - data: (byte *) data - length: (NSUInteger) length -{ - IOBluetoothDevice *device = [l2capChannel getDevice]; - struct wiimote_t *wm = NULL; - - for (int i = 0; i < MAX_WIIMOTES; i++) { - if (motes[i] == NULL) - continue; - if ([device isEqual: motes[i]->btd] == TRUE) - wm = motes[i]; - if (i == MAX_WIIMOTES && wm == NULL) { - WARN_LOG(WIIMOTE, "Received packet for unknown wiimote"); - return; - } - } - - if (length > MAX_PAYLOAD) { - WARN_LOG(WIIMOTE, "Dropping wiimote packet, too large [id %i]", - wm->unid); - return; - } - - if (wm->queue[wm->writer].len != 0) { - WARN_LOG(WIIMOTE, "Dropping wiimote packet, queue full [id %i]", - wm->unid); - return; - } - - memcpy(wm->queue[wm->writer].data, data, length); - wm->queue[wm->writer].len = length; - - wm->writer++; - wm->outstanding++; - if (wm->writer == QUEUE_SIZE) - wm->writer = 0; - - if (wm->outstanding > wm->watermark) { - wm->watermark = wm->outstanding; - WARN_LOG(WIIMOTE, "New wiimote queue watermark %i [id %i]", - wm->watermark, wm->unid); - } - - CFRunLoopStop(CFRunLoopGetCurrent()); - - (void)UpdateSystemActivity(1); -} - -- (void) l2capChannelClosed: (IOBluetoothL2CAPChannel *) l2capChannel -{ - IOBluetoothDevice *device = [l2capChannel getDevice]; - struct wiimote_t *wm = NULL; - - for (int i = 0; i < MAX_WIIMOTES; i++) { - if (motes[i] == NULL) - continue; - if ([device isEqual: motes[i]->btd] == TRUE) - wm = motes[i]; - if (i == MAX_WIIMOTES && wm == NULL) { - WARN_LOG(WIIMOTE, "Received packet for unknown wiimote"); - return; - } - } - - WARN_LOG(WIIMOTE, "L2CAP channel was closed [id %i]", wm->unid); - - if (l2capChannel == wm->cchan) - wm->cchan = nil; - - if (l2capChannel == wm->ichan) - wm->ichan = nil; -} -@end - -/** - * @brief Find a wiimote or wiimotes. - * - * @param wm An array of wiimote_t structures. - * @param max_wiimotes The number of wiimote structures in \a wm. - * @param timeout The number of seconds before timing out. - * - * @return The number of wiimotes found. - * - * @see wiiuse_connect() - * - * This function will only look for wiimote devices. - * When a device is found the address in the structures will be set. - * You can then call wiiuse_connect() to connect to the found - * devices. - */ -int wiiuse_find(struct wiimote_t **wm, int max_wiimotes, int timeout) -{ - IOBluetoothHostController *bth; - IOBluetoothDeviceInquiry *bti; - SearchBT *sbt; - NSEnumerator *en; - int i, found_devices = 0; - - if (max_wiimotes > MAX_WIIMOTES) - return 0; - - bth = [[IOBluetoothHostController alloc] init]; - if ([bth addressAsString] == nil) - { - WARN_LOG(WIIMOTE, "No bluetooth host controller"); - [bth release]; - return 0; - } - - sbt = [[SearchBT alloc] init]; - sbt->maxDevices = max_wiimotes; - bti = [[IOBluetoothDeviceInquiry alloc] init]; - [bti setDelegate: sbt]; - [bti setInquiryLength: timeout]; - [bti setSearchCriteria: kBluetoothServiceClassMajorAny - majorDeviceClass: kBluetoothDeviceClassMajorPeripheral - minorDeviceClass: kBluetoothDeviceClassMinorPeripheral2Joystick - ]; - [bti setUpdateNewDeviceNames: FALSE]; - - IOReturn ret = [bti start]; - if (ret == kIOReturnSuccess) - [bti retain]; - else - ERROR_LOG(WIIMOTE, "Unable to do bluetooth discovery"); - - CFRunLoopRun(); - - [bti stop]; - found_devices = [[bti foundDevices] count]; - - NOTICE_LOG(WIIMOTE, "Found %i bluetooth device%c", found_devices, - found_devices == 1 ? '\0' : 's'); - - en = [[bti foundDevices] objectEnumerator]; - for (i = 0; i < found_devices; i++) { - wm[i]->btd = [en nextObject]; - WIIMOTE_ENABLE_STATE(wm[i], WIIMOTE_STATE_DEV_FOUND); - motes[i] = wm[i]; - } - for (i = found_devices; i < MAX_WIIMOTES; i++) - motes[i] = NULL; - - [bth release]; - [bti release]; - [sbt release]; - - return found_devices; -} - -/** - * @brief Connect to a wiimote or wiimotes once an address is known. - * - * @param wm An array of wiimote_t structures. - * @param wiimotes The number of wiimote structures in \a wm. - * - * @return The number of wiimotes that successfully connected. - * - * @see wiiuse_find() - * @see wiiuse_connect_single() - * @see wiiuse_disconnect() - * - * Connect to a number of wiimotes when the address is already set - * in the wiimote_t structures. These addresses are normally set - * by the wiiuse_find() function, but can also be set manually. - */ -int wiiuse_connect(struct wiimote_t **wm, int wiimotes) -{ - int i, connected = 0; - - for (i = 0; i < wiimotes; ++i) - { - if (!WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_DEV_FOUND)) - continue; - - if (wiiuse_connect_single(wm[i], NULL)) - connected++; - } - - return connected; -} - -/** - * @brief Connect to a wiimote with a known address. - * - * @param wm Pointer to a wiimote_t structure. - * @param address The address of the device to connect to. If NULL, - * use the address in the struct set by wiiuse_find(). - * - * @return 1 on success, 0 on failure - */ -static int wiiuse_connect_single(struct wiimote_t *wm, char *address) -{ - ConnectBT *cbt = [[ConnectBT alloc] init]; - - if (wm == NULL || WIIMOTE_IS_CONNECTED(wm)) - return 0; - - [wm->btd openL2CAPChannelSync: &wm->cchan - withPSM: kBluetoothL2CAPPSMHIDControl delegate: cbt]; - [wm->btd openL2CAPChannelSync: &wm->ichan - withPSM: kBluetoothL2CAPPSMHIDInterrupt delegate: cbt]; - if (wm->ichan == NULL || wm->cchan == NULL) { - ERROR_LOG(WIIMOTE, "Unable to open L2CAP channels [id %i]", - wm->unid); - wiiuse_disconnect(wm); - } - - NOTICE_LOG(WIIMOTE, "Connected to wiimote at %s [id %i]", - [[wm->btd getAddressString] UTF8String], wm->unid); - - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); - wiiuse_set_report_type(wm); - - [cbt release]; - - return 1; -} - -/** - * @brief Disconnect a wiimote. - * - * @param wm Pointer to a wiimote_t structure. - * - * @see wiiuse_connect() - * - * Note that this will not free the wiimote structure. - */ -void wiiuse_disconnect(struct wiimote_t *wm) -{ - - if (wm == NULL) - return; - - NOTICE_LOG(WIIMOTE, "Disconnecting wiimote [id %i]", wm->unid); - - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); - - [wm->cchan closeChannel]; - [wm->ichan closeChannel]; - [wm->btd closeConnection]; -} - -int wiiuse_io_read(struct wiimote_t *wm) -{ - int bytes; - - if (!WIIMOTE_IS_CONNECTED(wm)) - return 0; - - if (wm->outstanding == 0) - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, true); - - if (wm->queue[wm->reader].len == 0) - return 0; - - bytes = wm->queue[wm->reader].len; - memcpy(wm->event_buf, wm->queue[wm->reader].data, bytes); - wm->queue[wm->reader].len = 0; - - wm->reader++; - wm->outstanding--; - if (wm->reader == QUEUE_SIZE) - wm->reader = 0; - - if (wm->event_buf[0] == '\0') - bytes = 0; - - return bytes; -} - -int wiiuse_io_write(struct wiimote_t *wm, byte *buf, int len) -{ - IOReturn ret; - - ret = [wm->cchan writeAsync: buf length: len refcon: nil]; - - if (ret == kIOReturnSuccess) - return len; - else - return 0; -} diff --git a/Source/Core/wiiuse/Src/io_win.cpp b/Source/Core/wiiuse/Src/io_win.cpp deleted file mode 100644 index fb0eb77231..0000000000 --- a/Source/Core/wiiuse/Src/io_win.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $Header$ - * - */ - -/** - * @file - * @brief Handles device I/O for Windows. - */ - -#ifdef _WIN32 - -#include -#include - -#include -#include -#include - -#include "Common.h" -#include "wiiuse_internal.h" - -typedef struct _HIDD_ATTRIBUTES { - ULONG Size; - USHORT VendorID; - USHORT ProductID; - USHORT VersionNumber; -} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; - -typedef VOID (__stdcall *PHidD_GetHidGuid)(LPGUID); -typedef BOOLEAN (__stdcall *PHidD_GetAttributes)(HANDLE, PHIDD_ATTRIBUTES); -typedef BOOLEAN (__stdcall *PHidD_SetOutputReport)(HANDLE, PVOID, ULONG); - -PHidD_GetHidGuid HidD_GetHidGuid = NULL; -PHidD_GetAttributes HidD_GetAttributes = NULL; -PHidD_SetOutputReport HidD_SetOutputReport = NULL; - -HINSTANCE hid_lib = NULL; - -static int initialized = 0; - -// VID = Nintendo, PID = Wiimote -static int VIDLength = 3; -static int VID[3] = {0x057E, 0x0001, 0x0002}; -static int PID[3] = {0x0306, 0x0002, 0x00F7}; - -inline void init_lib() -{ - if (!initialized) - { - hid_lib = LoadLibrary(L"hid.dll"); - if (!hid_lib) - { - PanicAlert("Failed to load hid.dll"); - exit(EXIT_FAILURE); - } - - HidD_GetHidGuid = (PHidD_GetHidGuid)GetProcAddress(hid_lib, "HidD_GetHidGuid"); - HidD_GetAttributes = (PHidD_GetAttributes)GetProcAddress(hid_lib, "HidD_GetAttributes"); - HidD_SetOutputReport = (PHidD_SetOutputReport)GetProcAddress(hid_lib, "HidD_SetOutputReport"); - if (!HidD_GetHidGuid || !HidD_GetAttributes || !HidD_SetOutputReport) - { - PanicAlert("Failed to load hid.dll"); - exit(EXIT_FAILURE); - } - - initialized = true; - } -} - -int wiiuse_remove(struct wiimote_t** wm, int wiimotes, int max_wiimotes); - -int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int wiimotes) { - GUID device_id; - HANDLE dev; - HDEVINFO device_info; - int i, x, found, index, udisc = 0; - DWORD len; - SP_DEVICE_INTERFACE_DATA device_data; - PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; - HIDD_ATTRIBUTES attr; - - init_lib(); - - // todo: handle/remove (unexpected and forced) disconnected wiimotes here - - // removal of unneeded wiimotes and exiting when we got enough wiimotes connected - if (wiiuse_remove(wm, wiimotes, max_wiimotes)) - return max_wiimotes; - - device_data.cbSize = sizeof(device_data); - - // get the device id - HidD_GetHidGuid(&device_id); - - // get all hid devices connected - device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); - - for (index = 0; wiimotes < max_wiimotes; ++index) { - - if (detail_data) { - free(detail_data); - detail_data = NULL; - } - found = 0; - - // query the next hid device info - if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) - break; - - // get the size of the data block required - i = SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL); - detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(len); - detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - - // query the data for this device - if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) - continue; - - // Wiimote already added - for(x = 0; x < wiimotes; x++) - { - if(memcmp(wm[x]->devicepath,detail_data->DevicePath,197) == 0) { - found = 1; - break; - } - } - if (found) - continue; - - // open new device - dev = CreateFile(detail_data->DevicePath, - (GENERIC_READ | GENERIC_WRITE), - (FILE_SHARE_READ | FILE_SHARE_WRITE), - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - if (dev == INVALID_HANDLE_VALUE) - continue; - - - - // get device attributes - attr.Size = sizeof(attr); - i = HidD_GetAttributes(dev, &attr); - - bool foundWiimote = false; - if((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) - { - foundWiimote = true; - } - else - { - for (int i = 0; i < VIDLength; i++) - { - if (attr.VendorID == VID[i] && attr.ProductID == PID[i]) - { - foundWiimote = true; - break; - } - } - } - - if (foundWiimote) - { - //this is a wiimote - wm[wiimotes]->dev_handle = dev; - - wm[wiimotes]->hid_overlap.hEvent = CreateEvent(NULL, 1, 1, L""); - wm[wiimotes]->hid_overlap.Offset = 0; - wm[wiimotes]->hid_overlap.OffsetHigh = 0; - - WIIMOTE_ENABLE_STATE(wm[wiimotes], WIIMOTE_STATE_DEV_FOUND); - WIIMOTE_ENABLE_STATE(wm[wiimotes], WIIMOTE_STATE_CONNECTED); - WIIMOTE_ENABLE_STATE(wm[wiimotes], WIIUSE_CONTINUOUS); - // try to set the output report to see if the device is actually connected - - if (!wiiuse_set_report_type(wm[wiimotes])) { - WIIMOTE_DISABLE_STATE(wm[wiimotes], WIIMOTE_STATE_CONNECTED); - if (wm[wiimotes]->event == WIIUSE_UNEXPECTED_DISCONNECT) - { - wiiuse_disconnect(wm[wiimotes]); - memset(wm[wiimotes],0,sizeof(wm[wiimotes])); - } - continue; - } - - memcpy(wm[wiimotes]->devicepath,detail_data->DevicePath,197); - NOTICE_LOG(WIIMOTE, "Connected to wiimote [id %i].", wm[wiimotes]->unid); - ++wiimotes; - - } - else - { - // not a wiimote - CloseHandle(dev); - } - } - - if (detail_data) - free(detail_data); - - SetupDiDestroyDeviceInfoList(device_info); - - return wiimotes; -} - -int wiiuse_connect(struct wiimote_t** wm, int wiimotes) -{ - int i, connected = 0; - - init_lib(); - - for (i = 0; i < wiimotes; ++i) - { - if (WIIMOTE_IS_SET(wm[i], WIIMOTE_STATE_CONNECTED)) - ++connected; - } - - return connected; -} - -void wiiuse_disconnect(struct wiimote_t* wm) -{ - init_lib(); - - if (!wm || WIIMOTE_IS_CONNECTED(wm)) - return; - - CloseHandle(wm->dev_handle); - wm->dev_handle = 0; - - ResetEvent(&wm->hid_overlap); - - wm->event = WIIUSE_NONE; - - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_HANDSHAKE); -} - -int wiiuse_io_read(struct wiimote_t* wm) -{ - DWORD b, r; - - init_lib(); - - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) - return 0; - - if (!ReadFile(wm->dev_handle, wm->event_buf, sizeof(wm->event_buf), &b, &wm->hid_overlap)) { - /* partial read */ - b = GetLastError(); - - if ((b == ERROR_HANDLE_EOF) || (b == ERROR_DEVICE_NOT_CONNECTED)) { - /* remote disconnect */ - wiiuse_disconnected(wm); - wm->event = WIIUSE_UNEXPECTED_DISCONNECT; - return 0; - } - - r = WaitForSingleObject(wm->hid_overlap.hEvent, wm->timeout); - if (r == WAIT_TIMEOUT) { - /* timeout - cancel and continue */ - - if (*wm->event_buf) - WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).", wm->timeout); - - CancelIo(wm->dev_handle); - ResetEvent(wm->hid_overlap.hEvent); - return 0; - } else if (r == WAIT_FAILED) { - WARN_LOG(WIIMOTE, "A wait error occured on reading from wiimote %i.", wm->unid); - return 0; - } - - if (!GetOverlappedResult(wm->dev_handle, &wm->hid_overlap, &b, 0)) - return 0; - } - - // This needs to be done even if ReadFile fails, essential during init - // Move the data over one, so we can add back in data report indicator byte (here, 0xa1) - memmove(wm->event_buf + 1, wm->event_buf, sizeof(wm->event_buf) - 1); - wm->event_buf[0] = 0xa1; - - ResetEvent(wm->hid_overlap.hEvent); - return 1; -} - -int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len) -{ - DWORD bytes, dw; - int i; - - init_lib(); - - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) - return 0; - - switch (wm->stack) { - case WIIUSE_STACK_UNKNOWN: - { - /* try to auto-detect the stack type */ - if (i = WriteFile(wm->dev_handle, buf + 1, 22, &bytes, &wm->hid_overlap)) { - /* bluesoleil will always return 1 here, even if it's not connected */ - wm->stack = WIIUSE_STACK_BLUESOLEIL; - return i; - } - - if (i = HidD_SetOutputReport(wm->dev_handle, buf + 1, len - 1)) { - wm->stack = WIIUSE_STACK_MS; - return i; - } - - /*-------------------------------------------------------------- - dw = GetLastError(); //checking for 121 = timeout on semaphore/device off/disconnected to avoid trouble with other stacks toshiba/widcomm - //995 = The I/O operation has been aborted because of either a thread exit or an application request. - - if ( (dw == 121) || (dw == 995) ) { - NOTICE_LOG(WIIMOTE, "wiiuse_io_write[WIIUSE_STACK_UNKNOWN]: WIIUSE_UNEXPECTED_DISCONNECT"); - wiiuse_disconnected(wm); - wm->event = WIIUSE_UNEXPECTED_DISCONNECT; - } - else ERROR_LOG(WIIMOTE, "wiiuse_io_write[WIIUSE_STACK_UNKNOWN]: WIIUSE_UNEXPECTED_DISCONNECT ERROR: %08x", dw); - --------------------------------------------------------------*/ - - //If the part below causes trouble on WIDCOMM/TOSHIBA stack uncomment the lines above, and comment out the 3 lines below instead. - - NOTICE_LOG(WIIMOTE, "wiiuse_io_write[WIIUSE_STACK_UNKNOWN]: WIIUSE_UNEXPECTED_DISCONNECT - time out"); - wiiuse_disconnected(wm); - wm->event = WIIUSE_UNEXPECTED_DISCONNECT; - - //ERROR_LOG(WIIMOTE, "wiiuse_io_write[WIIUSE_STACK_UNKNOWN]: Unable to determine bluetooth stack type || Wiimote timed out."); - return 0; - } - - case WIIUSE_STACK_MS: - i = HidD_SetOutputReport(wm->dev_handle, buf + 1, len - 1); - dw = GetLastError(); - - if (dw == 121) { // semaphore timeout - NOTICE_LOG(WIIMOTE, "wiiuse_io_write[WIIUSE_STACK_MS]: WIIUSE_UNEXPECTED_DISCONNECT"); - wiiuse_disconnected(wm); - wm->event = WIIUSE_UNEXPECTED_DISCONNECT; - return 0; - }/* else if (dw) - ERROR_LOG(WIIMOTE, "wiiuse_io_write[WIIUSE_STACK_MS]: WIIUSE_UNEXPECTED_DISCONNECT ERROR: %08x", dw); - */ - // it is not important to catch all errors here at this place, rest will be covered by io_reads. - return i; - - case WIIUSE_STACK_BLUESOLEIL: - return WriteFile(wm->dev_handle, buf + 1, 22, &bytes, &wm->hid_overlap); - } - - return 0; -} - -//Checks if the corresponding device to a system notification is a wiimote -//I placed the code here to avoid ddk/wdk dependencies @wiimote plugin -int wiiuse_check_system_notification(unsigned int nMsg, WPARAM wParam, LPARAM lParam) -{ - PDEV_BROADCAST_HDR pDevice = (PDEV_BROADCAST_HDR)lParam; - - init_lib(); - - switch(pDevice->dbch_devicetype) - { - case DBT_DEVTYP_DEVICEINTERFACE: - { - PDEV_BROADCAST_DEVICEINTERFACE pDeviceInfo = (PDEV_BROADCAST_DEVICEINTERFACE)pDevice; - HIDD_ATTRIBUTES attr; - char stringbuf[255]; - - HANDLE dev = CreateFile(pDeviceInfo->dbcc_name, - 0,(FILE_SHARE_READ | FILE_SHARE_WRITE), - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - - if (dev != INVALID_HANDLE_VALUE) - { - attr.Size = sizeof(attr); - HidD_GetAttributes(dev, &attr); - - //Checking PID&VID - bool foundWiimote = false; - if((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) - { - foundWiimote = true; - } - else - { - for (int i = 0; i < VIDLength; i++) - { - if (attr.VendorID == VID[i] && attr.ProductID == PID[i]) - { - foundWiimote = true; - break; - } - } - } - - if (foundWiimote) - { - CloseHandle(dev); - return 1; - } - - CloseHandle(dev); - } - else - { - // different method to acquire the "wiimote vid/pid" for a - // comparison when the device is already unavailable @CreateFile() - wcstombs(stringbuf, pDeviceInfo->dbcc_name, 255); - //ms bt stack + bluesoleil vid/pid dbccname format - if ( (strstr(stringbuf, "VID&0002057e_PID&0306") != NULL) || - (strstr(stringbuf, "VID_057e&PID_0306") != NULL) ) - { - return 1; - } - } - - return 0; - } - - default: - return 0; - - } - return 0; -} - -//register a handle for device notifications -int wiiuse_register_system_notification(HWND hwnd) -{ - DEV_BROADCAST_DEVICEINTERFACE Filter; - ZeroMemory(&Filter, sizeof(Filter)); - - init_lib(); - - //GUID wiimoteguid; - //CLSIDFromString(_T("745a17a0-74d3-11d0-b6fe-00a0c90f57da"),&wiimoteguid); - Filter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); - Filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - //Filter.dbcc_classguid = wiimoteguid; - - return (int)RegisterDeviceNotification(hwnd, &Filter, DEVICE_NOTIFY_ALL_INTERFACE_CLASSES); -} - -int wiiuse_remove(struct wiimote_t** wm, int wiimotes, int max_wiimotes) -{ - int i = 0; - NOTICE_LOG(WIIMOTE, "Remove Wiimotes, WM: %i MAX_WM: %i",wiimotes, max_wiimotes); - - //No cleanup needed, less wiimotes available than needed - if (wiimotes <= max_wiimotes) - return 0; - else if (!wm) - return 0; - - for (i = max_wiimotes; i < wiimotes; i++) { - if(wm[i]) { - wiiuse_disconnect(wm[i]); - wm[i]->state = WIIMOTE_INIT_STATES; - wm[i]->flags = WIIUSE_INIT_FLAGS; - wm[i]->event = WIIUSE_NONE; - } - } - return i; - -} - -#endif /* ifdef _WIN32 */ diff --git a/Source/Core/wiiuse/Src/ir.cpp b/Source/Core/wiiuse/Src/ir.cpp deleted file mode 100644 index 1a38fcac1d..0000000000 --- a/Source/Core/wiiuse/Src/ir.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $Header$ - * - */ - -/** - * @file - * @brief Handles IR data. - */ - -#include -#include - -#ifndef _WIN32 - #include -#endif - -#include "Common.h" -#include "wiiuse_internal.h" - -static int get_ir_sens(struct wiimote_t* wm, const char** block1, const char** block2); - -/** - * @brief Get the IR sensitivity settings. - * - * @param wm Pointer to a wiimote_t structure. - * @param block1 [out] Pointer to where block1 will be set. - * @param block2 [out] Pointer to where block2 will be set. - * - * @return Returns the sensitivity level. - */ -static int get_ir_sens(struct wiimote_t* wm, const char** block1, const char** block2) { - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL1)) { - *block1 = WM_IR_BLOCK1_LEVEL1; - *block2 = WM_IR_BLOCK2_LEVEL1; - return 1; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL2)) { - *block1 = WM_IR_BLOCK1_LEVEL2; - *block2 = WM_IR_BLOCK2_LEVEL2; - return 2; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL3)) { - *block1 = WM_IR_BLOCK1_LEVEL3; - *block2 = WM_IR_BLOCK2_LEVEL3; - return 3; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL4)) { - *block1 = WM_IR_BLOCK1_LEVEL4; - *block2 = WM_IR_BLOCK2_LEVEL4; - return 4; - } else if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR_SENS_LVL5)) { - *block1 = WM_IR_BLOCK1_LEVEL5; - *block2 = WM_IR_BLOCK2_LEVEL5; - return 5; - } - - *block1 = NULL; - *block2 = NULL; - return 0; -} - - -/** - * @brief Set the IR sensitivity. - * - * @param wm Pointer to a wiimote_t structure. - * @param level 1-5, same as Wii system sensitivity setting. - * - * If the level is < 1, then level will be set to 1. - * If the level is > 5, then level will be set to 5. - */ -void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level) { - const char* block1 = NULL; - const char* block2 = NULL; - - if (!wm) return; - - if (level > 5) level = 5; - if (level < 1) level = 1; - - WIIMOTE_DISABLE_STATE(wm, (WIIMOTE_STATE_IR_SENS_LVL1 | - WIIMOTE_STATE_IR_SENS_LVL2 | - WIIMOTE_STATE_IR_SENS_LVL3 | - WIIMOTE_STATE_IR_SENS_LVL4 | - WIIMOTE_STATE_IR_SENS_LVL5)); - - switch (level) { - case 1: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL1); - break; - case 2: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL2); - break; - case 3: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL3); - break; - case 4: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL4); - break; - case 5: - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_IR_SENS_LVL5); - break; - default: - return; - } - - /* set the new sensitivity */ - get_ir_sens(wm, &block1, &block2); - - wiiuse_write_data(wm, WM_REG_IR_BLOCK1, (byte*)block1, 9); - wiiuse_write_data(wm, WM_REG_IR_BLOCK2, (byte*)block2, 2); - - DEBUG_LOG(WIIMOTE, "Set IR sensitivity to level %i (unid %i)", level, wm->unid); -} diff --git a/Source/Core/wiiuse/Src/wiiuse.cpp b/Source/Core/wiiuse/Src/wiiuse.cpp deleted file mode 100644 index 1b9880a00c..0000000000 --- a/Source/Core/wiiuse/Src/wiiuse.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $Header$ - * - */ - -/** - * @file - * @brief General wiimote operations. - * - * The file includes functions that handle general - * tasks. Most of these are functions that are part - * of the API. - */ - -#include -#include -#include - -#ifndef _WIN32 - #include -#else - #include -#endif - -#include "Common.h" -#include "wiiuse_internal.h" - -static int g_banner = 1; - -/** - * @breif Returns the version of the library. - */ -const char* wiiuse_version() { - return WIIUSE_VERSION; -} - - -/** - * @brief Clean up wiimote_t array created by wiiuse_init() - */ -void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes) { - int i = 0; - - if (!wm) - return; - - NOTICE_LOG(WIIMOTE, "wiiuse clean up..."); - - for (; i < wiimotes; ++i) { - wiiuse_disconnect(wm[i]); - free(wm[i]); - } - - free(wm); - - return; -} - - -/** - * @brief Initialize an array of wiimote structures. - * - * @param wiimotes Number of wiimote_t structures to create. - * - * @return An array of initialized wiimote_t structures. - * - * @see wiiuse_connect() - * - * The array returned by this function can be passed to various - * functions, including wiiuse_connect(). - */ -struct wiimote_t** wiiuse_init(int wiimotes) { - int i = 0; - struct wiimote_t** wm = NULL; - - /* - * Please do not remove this banner. - * GPL asks that you please leave output credits intact. - * Thank you. - * - * This banner is only displayed once so that if you need - * to call this function again it won't be intrusive. - */ - if (!g_banner) { - printf( "wiiuse v" WIIUSE_VERSION " loaded.\n" - " By: Michael Laforest \n" - " http://wiiuse.net http://wiiuse.sf.net\n"); - g_banner = 1; - } - - if (!wiimotes) - return NULL; - - wm = (struct wiimote_t **)malloc(sizeof(struct wiimote_t*) * wiimotes); - - for (i = 0; i < wiimotes; ++i) { - wm[i] = (struct wiimote_t *)malloc(sizeof(struct wiimote_t)); - memset(wm[i], 0, sizeof(struct wiimote_t)); - - wm[i]->unid = i+1; - - #if defined __linux__ && HAVE_BLUEZ - wm[i]->bdaddr = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; - wm[i]->out_sock = -1; - wm[i]->in_sock = -1; - #elif defined(_WIN32) - wm[i]->dev_handle = 0; - wm[i]->stack = WIIUSE_STACK_UNKNOWN; - #endif - - wm[i]->timeout = WIIMOTE_DEFAULT_TIMEOUT; - wm[i]->state = WIIMOTE_INIT_STATES; - wm[i]->flags = WIIUSE_INIT_FLAGS; - wm[i]->event = WIIUSE_NONE; - } - - return wm; -} - - -/** - * @brief The wiimote disconnected. - * - * @param wm Pointer to a wiimote_t structure. - */ -void wiiuse_disconnected(struct wiimote_t* wm) { - if (!wm) return; - - NOTICE_LOG(WIIMOTE, "Wiimote disconnected [id %i].", wm->unid); - - /* disable the connected flag */ - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_CONNECTED); - - /* reset a bunch of stuff */ - wm->leds = 0; - wm->state = WIIMOTE_INIT_STATES; - memset(wm->event_buf, 0, sizeof(wm->event_buf)); - - #if defined __linux__ && HAVE_BLUEZ - wm->out_sock = -1; - wm->in_sock = -1; - #elif defined(_WIN32) - CloseHandle(wm->dev_handle); - wm->dev_handle = 0; - #endif - - wm->event = WIIUSE_DISCONNECT; -} - - -/** - * @brief Enable or disable the rumble. - * - * @param wm Pointer to a wiimote_t structure. - * @param status 1 to enable, 0 to disable. - */ -void wiiuse_rumble(struct wiimote_t* wm, int status) { - byte buf; - - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) - return; - - /* make sure to keep the current lit leds */ - buf = wm->leds; - - if (status) { - DEBUG_LOG(WIIMOTE, "Starting rumble..."); - WIIMOTE_ENABLE_STATE(wm, WIIMOTE_STATE_RUMBLE); - buf |= 0x01; - } else { - DEBUG_LOG(WIIMOTE, "Stopping rumble..."); - WIIMOTE_DISABLE_STATE(wm, WIIMOTE_STATE_RUMBLE); - } - - /* preserve IR state */ - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR)) - buf |= 0x04; - - wiiuse_send(wm, WM_CMD_RUMBLE, &buf, 1); -} - -/** - * @brief Set the enabled LEDs. - * - * @param wm Pointer to a wiimote_t structure. - * @param leds What LEDs to enable. - * - * \a leds is a bitwise or of WIIMOTE_LED_1, WIIMOTE_LED_2, WIIMOTE_LED_3, or WIIMOTE_LED_4. - */ -void wiiuse_set_leds(struct wiimote_t* wm, int leds) { - byte buf; - - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) - return; - - /* remove the lower 4 bits because they control rumble */ - wm->leds = (leds & 0xF0); - buf = wm->leds; - - /* make sure if the rumble is on that we keep it on */ - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) - buf |= 0x01; - - wiiuse_send(wm, WM_CMD_LED, &buf, 1); -} - - -/** - * @brief Set the report type based on the current wiimote state. - * - * @param wm Pointer to a wiimote_t structure. - * - * @return The report type sent. - * - * The wiimote reports formatted packets depending on the - * report type that was last requested. This function will - * update the type of report that should be sent based on - * the current state of the device. - */ -int wiiuse_set_report_type(struct wiimote_t* wm) { - byte buf[2]; - int motion, expansion, ir; - - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) - return 0; - - buf[0] = (WIIMOTE_IS_FLAG_SET(wm, WIIUSE_CONTINUOUS) ? 0x04 : 0x00); /* set to 0x04 for continuous reporting */ - - /* if rumble is enabled, make sure we keep it */ - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) - buf[0] |= 0x01; - - motion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_ACC); - expansion = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_EXP); - ir = WIIMOTE_IS_SET(wm, WIIMOTE_STATE_IR); - - buf[1] = 0x30; - - - DEBUG_LOG(WIIMOTE, "Setting report type: 0x%x", buf[1]); - - expansion = wiiuse_send(wm, WM_CMD_REPORT_TYPE, buf, 2); - if (expansion <= 0) - return expansion; - - return buf[1]; -} - - - -/** - * @brief Write data to the wiimote. - * - * @param wm Pointer to a wiimote_t structure. - * @param addr The address to write to. - * @param data The data to be written to the memory location. - * @param len The length of the block to be written. - */ -int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len) { - byte buf[21] = {0}; /* the payload is always 23 */ - - if (!wm || !WIIMOTE_IS_CONNECTED(wm)) - return 0; - if (!data || !len) - return 0; - - DEBUG_LOG(WIIMOTE, "Writing %i bytes to memory location 0x%x...", len, addr); - - #ifdef WITH_WIIUSE_DEBUG - { - int i = 0; - printf("Write data is: "); - for (; i < len; ++i) - printf("%x ", data[i]); - printf("\n"); - } - #endif - - /* the offset is in big endian */ -#ifdef __BIG_ENDIAN__ - *(int*)(buf) = addr; -#else - *(int*)(buf) = Common::swap32(addr); -#endif - - /* length */ - *(byte*)(buf + 4) = len; - - /* data */ - memcpy(buf + 5, data, len); - - wiiuse_send(wm, WM_CMD_WRITE_DATA, buf, 21); - return 1; -} - - -/** - * @brief Send a packet to the wiimote. - * - * @param wm Pointer to a wiimote_t structure. - * @param report_type The report type to send (WIIMOTE_CMD_LED, WIIMOTE_CMD_RUMBLE, etc). Found in wiiuse.h - * @param msg The payload. - * @param len Length of the payload in bytes. - * - * This function should replace any write()s directly to the wiimote device. - */ -int wiiuse_send(struct wiimote_t* wm, byte report_type, byte* msg, int len) { - byte buf[32]; /* no payload is better than this */ - int rumble = 0; - - buf[0] = WM_SET_REPORT | WM_BT_OUTPUT; - buf[1] = report_type; - - switch (report_type) { - case WM_CMD_LED: - case WM_CMD_RUMBLE: - case WM_CMD_CTRL_STATUS: - { - /* Rumble flag for: 0x11, 0x13, 0x14, 0x15, 0x19 or 0x1a */ - if (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_RUMBLE)) - rumble = 1; - break; - } - default: - break; - } - - memcpy(buf+2, msg, len); - if (rumble) - buf[2] |= 0x01; - - #ifdef WITH_WIIUSE_DEBUG - { - int x = 2; - printf("[DEBUG] (id %i) SEND: (%x) %.2x ", wm->unid, buf[0], buf[1]); - #ifndef _WIN32 - for (; x < len+2; ++x) - #else - for (; x < len+1; ++x) - #endif - printf("%.2x ", buf[x]); - printf("\n"); - } - #endif - - return wiiuse_io_write(wm, buf, len+2); -} - - -/** - * @brief Set the normal and expansion handshake timeouts. - * - * @param wm Array of wiimote_t structures. - * @param wiimotes Number of objects in the wm array. - * @param normal_timeout The timeout in milliseconds for a normal read. - * @param exp_timeout The timeout in millisecondsd to wait for an expansion handshake. - */ -void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte timeout) { - int i; - - if (!wm) return; - - for (i = 0; i < wiimotes; ++i) { - wm[i]->timeout = timeout; - } -} diff --git a/Source/Core/wiiuse/Src/wiiuse.h b/Source/Core/wiiuse/Src/wiiuse.h deleted file mode 100644 index a905a1a795..0000000000 --- a/Source/Core/wiiuse/Src/wiiuse.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $Header$ - * - */ - -/** - * @file - * - * @brief API header file. - * - * If this file is included from inside the wiiuse source - * and not from a third party program, then wiimote_internal.h - * is also included which extends this file. - */ - -#ifndef WIIUSE_H_INCLUDED -#define WIIUSE_H_INCLUDED - -#ifdef _WIN32 - #include -#elif defined(__APPLE__) - #import -#elif defined(__linux__) - #ifdef HAVE_CONFIG_H - #include "config.h" - #endif - #if HAVE_BLUEZ - #include - #endif -#endif - -#ifdef WIIUSE_INTERNAL_H_INCLUDED - #define WCONST -#else - #define WCONST const -#endif - -/* led bit masks */ -#define WIIMOTE_LED_NONE 0x00 -#define WIIMOTE_LED_1 0x10 -#define WIIMOTE_LED_2 0x20 -#define WIIMOTE_LED_3 0x40 -#define WIIMOTE_LED_4 0x80 - - -/* wiimote option flags */ -#define WIIUSE_SMOOTHING 0x01 -#define WIIUSE_CONTINUOUS 0x02 -#define WIIUSE_ORIENT_THRESH 0x04 -#define WIIUSE_INIT_FLAGS (WIIUSE_SMOOTHING | WIIUSE_ORIENT_THRESH) - - -/** - * @brief Return the IR sensitivity level. - * @param wm Pointer to a wiimote_t structure. - * @param lvl [out] Pointer to an int that will hold the level setting. - * If no level is set 'lvl' will be set to 0. - */ -#define WIIUSE_GET_IR_SENSITIVITY(dev, lvl) \ - do { \ - if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \ - else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \ - else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \ - else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \ - else if ((wm->state & 0x2000) == 0x2000) *lvl = 5; \ - else *lvl = 0; \ - } while (0) - - - -#define WIIUSE_IS_LED_SET(wm, num) ((wm->leds & WIIMOTE_LED_##num) == WIIMOTE_LED_##num) - -/* - * Largest known payload is 21 bytes. - * Add 2 for the prefix and round up to a power of 2. - */ -#define MAX_PAYLOAD 32 - -/* - * This is left over from an old hack, but it may actually - * be a useful feature to keep so it wasn't removed. - */ -#define WIIMOTE_DEFAULT_TIMEOUT 30 - -typedef unsigned char byte; -typedef char sbyte; - - -/** - * @enum win32_bt_stack_t - * @brief Available bluetooth stacks for Windows. - */ -typedef enum win_bt_stack_t { - WIIUSE_STACK_UNKNOWN, - WIIUSE_STACK_MS, - WIIUSE_STACK_BLUESOLEIL -} win_bt_stack_t; - - -/** - * @enum WIIUSE_EVENT_TYPE - * @brief Events that wiiuse can generate from a poll. - */ -typedef enum WIIUSE_EVENT_TYPE { - WIIUSE_NONE = 0, - WIIUSE_EVENT, - WIIUSE_STATUS, - WIIUSE_CONNECT, - WIIUSE_DISCONNECT, - WIIUSE_UNEXPECTED_DISCONNECT, - WIIUSE_READ_DATA, - WIIUSE_NUNCHUK_INSERTED, - WIIUSE_NUNCHUK_REMOVED, - WIIUSE_CLASSIC_CTRL_INSERTED, - WIIUSE_CLASSIC_CTRL_REMOVED, - WIIUSE_GUITAR_HERO_3_CTRL_INSERTED, - WIIUSE_GUITAR_HERO_3_CTRL_REMOVED, - WIIUSE_WII_BOARD_CTRL_INSERTED, - WIIUSE_WII_BOARD_CTRL_REMOVED, - WIIUSE_MOTION_PLUS_INSERTED, - WIIUSE_MOTION_PLUS_REMOVED -} WIIUSE_EVENT_TYPE; - -/** - * @struct wiimote_t - * @brief Wiimote structure. - */ -typedef struct wiimote_t { - WCONST int unid; /**< user specified id */ - - #if defined(__APPLE__) - WCONST IOBluetoothDevice *btd; - WCONST IOBluetoothL2CAPChannel *ichan; - WCONST IOBluetoothL2CAPChannel *cchan; - #define QUEUE_SIZE 64 - WCONST struct buffer { - char data[MAX_PAYLOAD]; - int len; - } queue[QUEUE_SIZE]; - WCONST int reader; - WCONST int writer; - WCONST int outstanding; - WCONST int watermark; - #elif defined(__linux__) && HAVE_BLUEZ - WCONST bdaddr_t bdaddr; /**< bt address (linux) */ - WCONST char bdaddr_str[18]; /**< readable bt address */ - WCONST int out_sock; /**< output socket */ - WCONST int in_sock; /**< input socket */ - #elif defined(_WIN32) - WCONST char devicepath[255]; /**< unique wiimote reference */ - //WCONST ULONGLONG btaddr; /**< bt address (windows) */ - WCONST HANDLE dev_handle; /**< HID handle */ - WCONST OVERLAPPED hid_overlap; /**< overlap handle */ - WCONST enum win_bt_stack_t stack; /**< type of bluetooth stack to use */ - #endif - WCONST int timeout; /**< read timeout */ - WCONST int state; /**< various state flags */ - WCONST byte leds; /**< currently lit leds */ - - WCONST int flags; /**< options flag */ - - WCONST WIIUSE_EVENT_TYPE event; /**< type of event that occured */ - WCONST byte event_buf[MAX_PAYLOAD]; /**< event buffer */ -} wiimote; - - -/***************************************** - * - * Include API specific stuff - * - *****************************************/ - -/* wiiuse.c */ -extern const char* wiiuse_version(); - -extern struct wiimote_t** wiiuse_init(int wiimotes); -extern void wiiuse_disconnected(struct wiimote_t* wm); -extern void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes); -extern void wiiuse_rumble(struct wiimote_t* wm, int status); -extern void wiiuse_set_leds(struct wiimote_t* wm, int leds); -extern int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len); - -/* connect.c / io_win.c */ -#ifdef _WIN32 -extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int wiimotes); -#else -extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout); -#endif -extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes); -extern void wiiuse_disconnect(struct wiimote_t* wm); -extern void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte timeout); - -#ifdef _WIN32 -extern int wiiuse_check_system_notification(unsigned int nMsg, WPARAM wParam, LPARAM lParam); -extern int wiiuse_register_system_notification(HWND hwnd); -#endif - -/* ir.c */ -extern void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level); - -/* io.c */ -extern int wiiuse_io_read(struct wiimote_t* wm); -extern int wiiuse_io_write(struct wiimote_t* wm, byte* buf, int len); - -#endif /* WIIUSE_H_INCLUDED */ - diff --git a/Source/Core/wiiuse/Src/wiiuse_internal.h b/Source/Core/wiiuse/Src/wiiuse_internal.h deleted file mode 100644 index 391bbd89c9..0000000000 --- a/Source/Core/wiiuse/Src/wiiuse_internal.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * wiiuse - * - * Written By: - * Michael Laforest < para > - * Email: < thepara (--AT--) g m a i l [--DOT--] com > - * - * Copyright 2006-2007 - * - * This file is part of wiiuse. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $Header$ - * - */ - -/** - * @file - * @brief General internal wiiuse stuff. - * - * Since Wiiuse is a library, wiiuse.h is a duplicate - * of the API header. - * - * The code that would normally go in that file, but - * which is not needed by third party developers, - * is put here. - * - * So wiiuse_internal.h is included by other files - * internally, wiiuse.h is included only here. - */ - -#ifndef WIIUSE_INTERNAL_H_INCLUDED -#define WIIUSE_INTERNAL_H_INCLUDED - -/* wiiuse version */ -#define WIIUSE_VERSION "0.12" - -/******************** - * - * Wiimote internal codes - * - ********************/ - -/* Communication channels */ -#define WM_OUTPUT_CHANNEL 0x11 -#define WM_INPUT_CHANNEL 0x13 - -#define WM_SET_REPORT 0x50 - -/* commands */ -#define WM_CMD_LED 0x11 -#define WM_CMD_REPORT_TYPE 0x12 -#define WM_CMD_RUMBLE 0x13 -#define WM_CMD_IR 0x13 -#define WM_CMD_CTRL_STATUS 0x15 -#define WM_CMD_SPEAKER_ENABLE 0x14// Size 1 -#define WM_CMD_WRITE_DATA 0x16 -#define WM_CMD_READ_DATA 0x17 -#define WM_CMD_SPEAKER_DATA 0x18// Size 21 -#define WM_CMD_SPEAKER_MUTE 0x19// Size 1 -#define WM_CMD_IR_2 0x1A - - -#define WM_BT_INPUT 0x01 -#define WM_BT_OUTPUT 0x02 - -/* Identify the wiimote device by its class */ -#define WM_DEV_CLASS_0 0x04 -#define WM_DEV_CLASS_1 0x25 -#define WM_DEV_CLASS_2 0x00 -#define WM_VENDOR_ID 0x057E -#define WM_PRODUCT_ID 0x0306 - - - -/* offsets in wiimote memory */ -#define WM_MEM_OFFSET_CALIBRATION 0x16 - -#define WM_REG_IR_BLOCK1 0x04B00000 -#define WM_REG_IR_BLOCK2 0x04B0001A - - -/* ir block data */ -#define WM_IR_BLOCK1_LEVEL1 "\x02\x00\x00\x71\x01\x00\x64\x00\xfe" -#define WM_IR_BLOCK2_LEVEL1 "\xfd\x05" -#define WM_IR_BLOCK1_LEVEL2 "\x02\x00\x00\x71\x01\x00\x96\x00\xb4" -#define WM_IR_BLOCK2_LEVEL2 "\xb3\x04" -#define WM_IR_BLOCK1_LEVEL3 "\x02\x00\x00\x71\x01\x00\xaa\x00\x64" -#define WM_IR_BLOCK2_LEVEL3 "\x63\x03" -#define WM_IR_BLOCK1_LEVEL4 "\x02\x00\x00\x71\x01\x00\xc8\x00\x36" -#define WM_IR_BLOCK2_LEVEL4 "\x35\x03" -#define WM_IR_BLOCK1_LEVEL5 "\x07\x00\x00\x71\x01\x00\x72\x00\x20" -#define WM_IR_BLOCK2_LEVEL5 "\x1f\x03" - -#define WM_IR_TYPE_BASIC 0x01 -#define WM_IR_TYPE_EXTENDED 0x03 -#define WM_IR_TYPE_FULL 0x05 - - - - -/******************** - * - * End Wiimote internal codes - * - ********************/ - -/* wiimote state flags - (some duplicated in wiiuse.h)*/ -#define WIIMOTE_STATE_DEV_FOUND 0x0001 -#define WIIMOTE_STATE_HANDSHAKE 0x0002 /* actual connection exists but no handshake yet */ -#define WIIMOTE_STATE_HANDSHAKE_COMPLETE 0x0004 /* actual connection exists but no handshake yet */ -#define WIIMOTE_STATE_CONNECTED 0x0008 -#define WIIMOTE_STATE_RUMBLE 0x0010 -#define WIIMOTE_STATE_ACC 0x0020 -#define WIIMOTE_STATE_EXP 0x0040 -#define WIIMOTE_STATE_IR 0x0080 -#define WIIMOTE_STATE_SPEAKER 0x0100 -#define WIIMOTE_STATE_IR_SENS_LVL1 0x0200 -#define WIIMOTE_STATE_IR_SENS_LVL2 0x0400 -#define WIIMOTE_STATE_IR_SENS_LVL3 0x0800 -#define WIIMOTE_STATE_IR_SENS_LVL4 0x1000 -#define WIIMOTE_STATE_IR_SENS_LVL5 0x2000 - -#define WIIMOTE_INIT_STATES (WIIMOTE_STATE_IR_SENS_LVL3) - -/* macro to manage states */ -#define WIIMOTE_IS_SET(wm, s) ((wm->state & (s)) == (s)) -#define WIIMOTE_ENABLE_STATE(wm, s) (wm->state |= (s)) -#define WIIMOTE_DISABLE_STATE(wm, s) (wm->state &= ~(s)) -#define WIIMOTE_TOGGLE_STATE(wm, s) ((wm->state & (s)) ? WIIMOTE_DISABLE_STATE(wm, s) : WIIMOTE_ENABLE_STATE(wm, s)) - -#define WIIMOTE_IS_FLAG_SET(wm, s) ((wm->flags & (s)) == (s)) -#define WIIMOTE_ENABLE_FLAG(wm, s) (wm->flags |= (s)) -#define WIIMOTE_DISABLE_FLAG(wm, s) (wm->flags &= ~(s)) -#define WIIMOTE_TOGGLE_FLAG(wm, s) ((wm->flags & (s)) ? WIIMOTE_DISABLE_FLAG(wm, s) : WIIMOTE_ENABLE_FLAG(wm, s)) - -#define NUNCHUK_IS_FLAG_SET(wm, s) ((*(wm->flags) & (s)) == (s)) - -/* misc macros */ -#define WIIMOTE_ID(wm) (wm->unid) -#define WIIMOTE_IS_CONNECTED(wm) (WIIMOTE_IS_SET(wm, WIIMOTE_STATE_CONNECTED)) - - - -#include "wiiuse.h" - -/* not part of the api */ -int wiiuse_set_report_type(struct wiimote_t* wm); -int wiiuse_send(struct wiimote_t* wm, byte report_type, byte* msg, int len); - -#endif /* WIIUSE_INTERNAL_H_INCLUDED */ diff --git a/Source/Core/wiiuse/wiiuse.sln b/Source/Core/wiiuse/wiiuse.sln deleted file mode 100644 index acfb7eec48..0000000000 --- a/Source/Core/wiiuse/wiiuse.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wiiuse", "wiiuse.vcproj", "{52F70249-373A-4401-A70A-FF22760EC1B8}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {52F70249-373A-4401-A70A-FF22760EC1B8}.Debug|Win32.ActiveCfg = Debug|Win32 - {52F70249-373A-4401-A70A-FF22760EC1B8}.Debug|Win32.Build.0 = Debug|Win32 - {52F70249-373A-4401-A70A-FF22760EC1B8}.Debug|x64.ActiveCfg = Debug|x64 - {52F70249-373A-4401-A70A-FF22760EC1B8}.Debug|x64.Build.0 = Debug|x64 - {52F70249-373A-4401-A70A-FF22760EC1B8}.Release|Win32.ActiveCfg = Release|Win32 - {52F70249-373A-4401-A70A-FF22760EC1B8}.Release|Win32.Build.0 = Release|Win32 - {52F70249-373A-4401-A70A-FF22760EC1B8}.Release|x64.ActiveCfg = Release|x64 - {52F70249-373A-4401-A70A-FF22760EC1B8}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Source/Core/wiiuse/wiiuse.vcproj b/Source/Core/wiiuse/wiiuse.vcproj deleted file mode 100644 index eecda79df2..0000000000 --- a/Source/Core/wiiuse/wiiuse.vcproj +++ /dev/null @@ -1,394 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln index 9423cd37c4..d19a52e858 100644 --- a/Source/Dolphin.sln +++ b/Source/Dolphin.sln @@ -251,11 +251,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CLRun", "..\Externals\CLRun EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SVNRevGen", "Core\Common\SVNRevGen.vcproj", "{B807E8DB-4241-4754-BC2A-2F435BCA881A}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wiiuse", "Core\wiiuse\wiiuse.vcproj", "{52F70249-373A-4401-A70A-FF22760EC1B8}" - ProjectSection(ProjectDependencies) = postProject - {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} = {C573CAF7-EE6A-458E-8049-16C0BF34C2E9} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VideoUICommon", "Core\VideoUICommon\VideoUICommon.vcproj", "{56C4B06E-F2C9-4729-A15A-DD327A9AA465}" ProjectSection(ProjectDependencies) = postProject {05C75041-D67D-4903-A362-8395A7B35C75} = {05C75041-D67D-4903-A362-8395A7B35C75}