mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Remove wiiuse, and use our own code. Works on linux and windows. On OSX it should compile, but I don't know about functionality. Even on linux and windows I can't promise this is bug free (wiiuse certainly wasn't). Please report issues as you find them for all platforms.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6693 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
+2
-3
@@ -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)
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -14,4 +14,3 @@ add_subdirectory(DolphinWX)
|
||||
add_subdirectory(DSPCore)
|
||||
add_subdirectory(InputCommon)
|
||||
add_subdirectory(VideoCommon)
|
||||
add_subdirectory(wiiuse)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
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="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -115,7 +115,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
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="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
@@ -189,7 +189,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="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
@@ -266,7 +266,7 @@
|
||||
OmitFramePointers="true"
|
||||
EnableFiberSafeOptimizations="false"
|
||||
WholeProgramOptimization="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="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
@@ -290,6 +290,7 @@
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
AdditionalDependencies="setupapi.lib"
|
||||
OutputFile="$(OutDir)/Core.lib"
|
||||
AdditionalLibraryDirectories=""..\..\..\Externals\LZO\$(OutDir)\lzo.lib""
|
||||
/>
|
||||
@@ -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 @@
|
||||
<Filter
|
||||
Name="Real"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\Src\HW\WiimoteReal\IOWin.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\HW\WiimoteReal\WiimoteReal.cpp"
|
||||
>
|
||||
@@ -912,6 +917,10 @@
|
||||
RelativePath=".\Src\HW\WiimoteReal\WiimoteReal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Src\HW\WiimoteReal\WiimoteRealBase.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Filter>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -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 <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
#include <bluetooth/l2cap.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include "WiimoteReal.h"
|
||||
|
||||
// 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
|
||||
@@ -0,0 +1,298 @@
|
||||
#import <CoreServices/CoreServices.h>
|
||||
extern "C" OSErr UpdateSystemActivity(UInt8 activity);
|
||||
#define BLUETOOTH_VERSION_USE_CURRENT
|
||||
#import <IOBluetooth/IOBluetooth.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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<u8*,u8> Report;
|
||||
|
||||
// pointer to data, and size of data
|
||||
typedef std::pair<u8*,u8> 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<u8*> m_read_reports;
|
||||
Common::FifoQueue<Report> m_write_reports;
|
||||
bool m_connected;
|
||||
Common::FifoQueue<u8*> m_read_reports;
|
||||
Common::FifoQueue<Report> 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
|
||||
|
||||
@@ -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 <windows.h>
|
||||
#elif defined(__APPLE__)
|
||||
#import <IOBluetooth/IOBluetooth.h>
|
||||
#elif defined(__linux__) && HAVE_BLUEZ
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#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
|
||||
@@ -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)
|
||||
|
||||
@@ -9,7 +9,6 @@ set(LIBS core
|
||||
lua
|
||||
z
|
||||
sfml-network
|
||||
wiiuse
|
||||
SDL
|
||||
GL
|
||||
${XRANDR_LIBRARIES}
|
||||
|
||||
@@ -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']:
|
||||
|
||||
@@ -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})
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/hci_lib.h>
|
||||
#include <bluetooth/l2cap.h>
|
||||
|
||||
#include "Common.h"
|
||||
#include "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);
|
||||
}
|
||||
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* $Header$
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Handles device I/O for OS X.
|
||||
*/
|
||||
|
||||
#import <CoreServices/CoreServices.h>
|
||||
extern "C" OSErr UpdateSystemActivity(UInt8 activity);
|
||||
#define BLUETOOTH_VERSION_USE_CURRENT
|
||||
#import <IOBluetooth/IOBluetooth.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user