Skip to content

Commit

Permalink
Add ability to passthrough a Bluetooth adapter
Browse files Browse the repository at this point in the history
This adds the ability to passthrough a whole Bluetooth adapter and skip
the majority of the Bluetooth emulation code. We use libusb to send HCI
commands, receive HCI events and transfer ACL data directly to the
first adapter that is found or to a specific adapter (if configured to)

This is possible because the Wii's Bluetooth module is actually just
a pretty standard Bluetooth adapter…

…except for two vendor-specific commands, for which replies are faked,
and also for the sync button. This adds a hotkey that works in the
exact same way as the sync button would on a Wii: it triggers an HCI
event, which emulated software interpret as a command to perform
a BT inquiry.

In this mode, the current emulated Wiimote will inevitably not work
at all, so this commit also disables the "connect Wiimote" menu.
  • Loading branch information
leoetlino committed Sep 7, 2016
1 parent a9f47df commit 3eb56cf
Show file tree
Hide file tree
Showing 24 changed files with 784 additions and 224 deletions.
5 changes: 3 additions & 2 deletions Source/Core/Core/CMakeLists.txt
Expand Up @@ -144,7 +144,7 @@ set(SRCS ActionReplay.cpp
IPC_HLE/WII_IPC_HLE_Device_net.cpp
IPC_HLE/WII_IPC_HLE_Device_net_ssl.cpp
IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp
IPC_HLE/WII_IPC_HLE_Device_usb.cpp
IPC_HLE/WII_IPC_HLE_Device_usb_emu.cpp
IPC_HLE/WII_IPC_HLE_Device_usb_kbd.cpp
IPC_HLE/WII_IPC_HLE_Device_usb_ven.cpp
IPC_HLE/WII_IPC_HLE_WiiMote.cpp
Expand Down Expand Up @@ -241,7 +241,8 @@ set(LIBS
if(LIBUSB_FOUND)
# Using shared LibUSB
set(LIBS ${LIBS} ${LIBUSB_LIBRARIES})
set(SRCS ${SRCS} IPC_HLE/WII_IPC_HLE_Device_hid.cpp)
set(SRCS ${SRCS} IPC_HLE/WII_IPC_HLE_Device_hid.cpp
IPC_HLE/WII_IPC_HLE_Device_usb_real.cpp)
endif(LIBUSB_FOUND)

set(LIBS ${LIBS} ${MBEDTLS_LIBRARIES})
Expand Down
20 changes: 20 additions & 0 deletions Source/Core/Core/ConfigManager.cpp
Expand Up @@ -84,6 +84,7 @@ void SConfig::SaveSettings()
SaveInputSettings(ini);
SaveFifoPlayerSettings(ini);
SaveAnalyticsSettings(ini);
SaveBluetoothPassthroughSettings(ini);

ini.Save(File::GetUserPath(F_DOLPHINCONFIG_IDX));
m_SYSCONF->Save();
Expand Down Expand Up @@ -327,6 +328,15 @@ void SConfig::SaveAnalyticsSettings(IniFile& ini)
analytics->Set("PermissionAsked", m_analytics_permission_asked);
}

void SConfig::SaveBluetoothPassthroughSettings(IniFile& ini)
{
IniFile::Section* section = ini.GetOrCreateSection("BluetoothPassthrough");

section->Set("Mode", m_bt_passthrough_mode);
section->Set("VID", m_bt_passthrough_vid);
section->Set("PID", m_bt_passthrough_pid);
}

void SConfig::LoadSettings()
{
INFO_LOG(BOOT, "Loading Settings from %s", File::GetUserPath(F_DOLPHINCONFIG_IDX).c_str());
Expand All @@ -343,6 +353,7 @@ void SConfig::LoadSettings()
LoadInputSettings(ini);
LoadFifoPlayerSettings(ini);
LoadAnalyticsSettings(ini);
LoadBluetoothPassthroughSettings(ini);

m_SYSCONF = new SysConf();
}
Expand Down Expand Up @@ -623,6 +634,15 @@ void SConfig::LoadAnalyticsSettings(IniFile& ini)
analytics->Get("PermissionAsked", &m_analytics_permission_asked, false);
}

void SConfig::LoadBluetoothPassthroughSettings(IniFile& ini)
{
IniFile::Section* section = ini.GetOrCreateSection("BluetoothPassthrough");

section->Get("Mode", &m_bt_passthrough_mode, BLUETOOTH_PASSTHROUGH_DISABLED);
section->Get("VID", &m_bt_passthrough_vid, -1);
section->Get("PID", &m_bt_passthrough_pid, -1);
}

void SConfig::LoadDefaults()
{
bEnableDebugging = false;
Expand Down
12 changes: 12 additions & 0 deletions Source/Core/Core/ConfigManager.h
Expand Up @@ -136,6 +136,16 @@ struct SConfig : NonCopyable
bool m_analytics_enabled;
bool m_analytics_permission_asked;

// Bluetooth passthrough mode settings
enum BluetoothPassthroughMode
{
BLUETOOTH_PASSTHROUGH_ENABLED,
BLUETOOTH_PASSTHROUGH_DISABLED,
};
int m_bt_passthrough_mode = BLUETOOTH_PASSTHROUGH_DISABLED;
int m_bt_passthrough_pid = -1;
int m_bt_passthrough_vid = -1;

// Fifo Player related settings
bool bLoopFifoReplay;

Expand Down Expand Up @@ -310,6 +320,7 @@ struct SConfig : NonCopyable
void SaveMovieSettings(IniFile& ini);
void SaveFifoPlayerSettings(IniFile& ini);
void SaveAnalyticsSettings(IniFile& ini);
void SaveBluetoothPassthroughSettings(IniFile& ini);

void LoadGeneralSettings(IniFile& ini);
void LoadInterfaceSettings(IniFile& ini);
Expand All @@ -321,6 +332,7 @@ struct SConfig : NonCopyable
void LoadMovieSettings(IniFile& ini);
void LoadFifoPlayerSettings(IniFile& ini);
void LoadAnalyticsSettings(IniFile& ini);
void LoadBluetoothPassthroughSettings(IniFile& ini);

static SConfig* m_Instance;
};
5 changes: 3 additions & 2 deletions Source/Core/Core/Core.cpp
Expand Up @@ -51,7 +51,7 @@
#include "Core/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h"
#include "Core/HW/Wiimote.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_emu.h"
#include "Core/IPC_HLE/WII_IPC_HLE_WiiMote.h"
#include "Core/IPC_HLE/WII_Socket.h"
#include "Core/Movie.h"
Expand Down Expand Up @@ -527,7 +527,8 @@ void EmuThread()
}

// Load and Init Wiimotes - only if we are booting in Wii mode
if (core_parameter.bWii)
if (core_parameter.bWii &&
SConfig::GetInstance().m_bt_passthrough_mode == SConfig::BLUETOOTH_PASSTHROUGH_DISABLED)
{
if (init_controllers)
Wiimote::Initialize(s_window_handle, !s_state_filename.empty() ?
Expand Down
15 changes: 11 additions & 4 deletions Source/Core/Core/Core.vcxproj
Expand Up @@ -169,7 +169,9 @@
<ClCompile Include="HW\WiiSaveCrypted.cpp" />
<ClCompile Include="IPC_HLE\ICMPWin.cpp" />
<ClCompile Include="IPC_HLE\WiiMote_HID_Attr.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE.cpp">
<DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_DI.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_es.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_FileIO.cpp" />
Expand All @@ -184,8 +186,11 @@
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_net.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_net_ssl.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_sdio_slot0.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_emu.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_kbd.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_real.cpp">
<DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.cpp" />
<ClCompile Include="IPC_HLE\WII_IPC_HLE_WiiMote.cpp" />
<ClCompile Include="IPC_HLE\WII_Socket.cpp" />
Expand Down Expand Up @@ -388,8 +393,10 @@
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_net_ssl.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_sdio_slot0.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_stm.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_base.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_emu.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_kbd.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_real.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_ven.h" />
<ClInclude Include="IPC_HLE\WII_IPC_HLE_WiiMote.h" />
<ClInclude Include="IPC_HLE\WII_Socket.h" />
Expand Down Expand Up @@ -480,4 +487,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>
15 changes: 12 additions & 3 deletions Source/Core/Core/Core.vcxproj.filters
Expand Up @@ -588,7 +588,10 @@
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_hid.cpp">
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
</ClCompile>
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb.cpp">
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_emu.cpp">
<Filter>IPC HLE %28IOS/Starlet%29\USB/BT/Wiimote</Filter>
</ClCompile>
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_usb_real.cpp">
<Filter>IPC HLE %28IOS/Starlet%29\USB/BT/Wiimote</Filter>
</ClCompile>
<ClCompile Include="IPC_HLE\WII_IPC_HLE_WiiMote.cpp">
Expand Down Expand Up @@ -1145,7 +1148,13 @@
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_hid.h">
<Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
</ClInclude>
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb.h">
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_base.h">
<Filter>IPC HLE %28IOS/Starlet%29\USB/BT/Wiimote</Filter>
</ClInclude>
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_emu.h">
<Filter>IPC HLE %28IOS/Starlet%29\USB/BT/Wiimote</Filter>
</ClInclude>
<ClInclude Include="IPC_HLE\WII_IPC_HLE_Device_usb_real.h">
<Filter>IPC HLE %28IOS/Starlet%29\USB/BT/Wiimote</Filter>
</ClInclude>
<ClInclude Include="IPC_HLE\WII_IPC_HLE_WiiMote.h">
Expand Down Expand Up @@ -1247,4 +1256,4 @@
<ItemGroup>
<Text Include="CMakeLists.txt" />
</ItemGroup>
</Project>
</Project>
1 change: 1 addition & 0 deletions Source/Core/Core/HotkeyManager.cpp
Expand Up @@ -32,6 +32,7 @@ const std::string hotkey_labels[] = {
_trans("Take Screenshot"),
_trans("Exit"),

_trans("Trigger Sync Button"),
_trans("Connect Wiimote 1"),
_trans("Connect Wiimote 2"),
_trans("Connect Wiimote 3"),
Expand Down
1 change: 1 addition & 0 deletions Source/Core/Core/HotkeyManager.h
Expand Up @@ -31,6 +31,7 @@ enum Hotkey
HK_SCREENSHOT,
HK_EXIT,

HK_TRIGGER_SYNC_BUTTON,
HK_WIIMOTE1_CONNECT,
HK_WIIMOTE2_CONNECT,
HK_WIIMOTE3_CONNECT,
Expand Down
9 changes: 7 additions & 2 deletions Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp
Expand Up @@ -50,8 +50,9 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC
#include "Core/IPC_HLE/WII_IPC_HLE_Device_net_ssl.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_stm.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_emu.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_kbd.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_real.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_ven.h"

#if defined(__LIBUSB__) || defined(_WIN32)
Expand Down Expand Up @@ -128,7 +129,11 @@ void Reinit()
num_devices = 0;

// Build hardware devices
AddDevice<CWII_IPC_HLE_Device_usb_oh1_57e_305>("/dev/usb/oh1/57e/305");
if (SConfig::GetInstance().m_bt_passthrough_mode == SConfig::BLUETOOTH_PASSTHROUGH_DISABLED)
AddDevice<CWII_IPC_HLE_Device_usb_oh1_57e_305_emu>("/dev/usb/oh1/57e/305");
else
AddDevice<CWII_IPC_HLE_Device_usb_oh1_57e_305_real>("/dev/usb/oh1/57e/305");

AddDevice<CWII_IPC_HLE_Device_stm_immediate>("/dev/stm/immediate");
AddDevice<CWII_IPC_HLE_Device_stm_eventhook>("/dev/stm/eventhook");
AddDevice<CWII_IPC_HLE_Device_fs>("/dev/fs");
Expand Down
37 changes: 21 additions & 16 deletions Source/Core/Core/IPC_HLE/WII_IPC_HLE_Device_es.cpp
Expand Up @@ -47,7 +47,7 @@
#include "Core/ConfigManager.h"
#include "Core/HW/DVDInterface.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_es.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb_emu.h"
#include "Core/IPC_HLE/WII_IPC_HLE_WiiMote.h"
#include "Core/Movie.h"
#include "Core/PowerPC/PowerPC.h"
Expand Down Expand Up @@ -998,28 +998,33 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
}
else
{
CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer();
size_t size = s_Usb->m_WiiMotes.size();
bool* wiiMoteConnected = new bool[size];
for (unsigned int i = 0; i < size; i++)
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
bool* wiiMoteConnected = new bool[MAX_BBMOTES];
if (SConfig::GetInstance().m_bt_passthrough_mode == SConfig::BLUETOOTH_PASSTHROUGH_DISABLED)
{
CWII_IPC_HLE_Device_usb_oh1_57e_305_emu* s_Usb = GetUsbPointer();
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
}

WII_IPC_HLE_Interface::Reset(true);
WII_IPC_HLE_Interface::Reinit();
s_Usb = GetUsbPointer();
for (unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); i++)

if (SConfig::GetInstance().m_bt_passthrough_mode == SConfig::BLUETOOTH_PASSTHROUGH_DISABLED)
{
if (wiiMoteConnected[i])
CWII_IPC_HLE_Device_usb_oh1_57e_305_emu* s_Usb = GetUsbPointer();
for (unsigned int i = 0; i < MAX_BBMOTES; i++)
{
s_Usb->m_WiiMotes[i].Activate(false);
s_Usb->m_WiiMotes[i].Activate(true);
}
else
{
s_Usb->m_WiiMotes[i].Activate(false);
if (wiiMoteConnected[i])
{
s_Usb->m_WiiMotes[i].Activate(false);
s_Usb->m_WiiMotes[i].Activate(true);
}
else
{
s_Usb->m_WiiMotes[i].Activate(false);
}
}
}

delete[] wiiMoteConnected;
WII_IPC_HLE_Interface::SetDefaultContentFile(tContentFile);
}
Expand Down

0 comments on commit 3eb56cf

Please sign in to comment.