mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-12 15:38:59 +01:00
![Léo Lam](/assets/img/avatar_default.png)
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. This commit also changes the UI code to expose passthrough mode and WII_IPC_HLE to be a bit more thread safe (for the device map).
322 lines
9.1 KiB
C++
322 lines
9.1 KiB
C++
// Copyright 2015 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "Common/Common.h"
|
|
#include "Core/ConfigManager.h"
|
|
#include "Core/HotkeyManager.h"
|
|
#include "InputCommon/GCPadStatus.h"
|
|
|
|
const std::string hotkey_labels[] = {
|
|
_trans("Open"),
|
|
_trans("Change Disc"),
|
|
_trans("Refresh List"),
|
|
|
|
_trans("Toggle Pause"),
|
|
_trans("Stop"),
|
|
_trans("Reset"),
|
|
_trans("Frame Advance"),
|
|
_trans("Frame Advance Decrease Speed"),
|
|
_trans("Frame Advance Increase Speed"),
|
|
_trans("Frame Advance Reset Speed"),
|
|
|
|
_trans("Start Recording"),
|
|
_trans("Play Recording"),
|
|
_trans("Export Recording"),
|
|
_trans("Read-only mode"),
|
|
|
|
_trans("Toggle Fullscreen"),
|
|
_trans("Take Screenshot"),
|
|
_trans("Exit"),
|
|
|
|
_trans("Press Sync Button"),
|
|
_trans("Connect Wiimote 1"),
|
|
_trans("Connect Wiimote 2"),
|
|
_trans("Connect Wiimote 3"),
|
|
_trans("Connect Wiimote 4"),
|
|
_trans("Connect Balance Board"),
|
|
|
|
_trans("Volume Down"),
|
|
_trans("Volume Up"),
|
|
_trans("Volume Toggle Mute"),
|
|
|
|
_trans("Increase IR"),
|
|
_trans("Decrease IR"),
|
|
|
|
_trans("Toggle Crop"),
|
|
_trans("Toggle Aspect Ratio"),
|
|
_trans("Toggle EFB Copies"),
|
|
_trans("Toggle Fog"),
|
|
_trans("Disable Emulation Speed Limit"),
|
|
_trans("Toggle Custom Textures"),
|
|
_trans("Decrease Emulation Speed"),
|
|
_trans("Increase Emulation Speed"),
|
|
|
|
_trans("Freelook Decrease Speed"),
|
|
_trans("Freelook Increase Speed"),
|
|
_trans("Freelook Reset Speed"),
|
|
_trans("Freelook Move Up"),
|
|
_trans("Freelook Move Down"),
|
|
_trans("Freelook Move Left"),
|
|
_trans("Freelook Move Right"),
|
|
_trans("Freelook Zoom In"),
|
|
_trans("Freelook Zoom Out"),
|
|
_trans("Freelook Reset"),
|
|
|
|
_trans("Toggle 3D Side-by-side"),
|
|
_trans("Toggle 3D Top-bottom"),
|
|
_trans("Toggle 3D Anaglyph"),
|
|
_trans("Toggle 3D Vision"),
|
|
|
|
_trans("Decrease Depth"),
|
|
_trans("Increase Depth"),
|
|
_trans("Decrease Convergence"),
|
|
_trans("Increase Convergence"),
|
|
|
|
_trans("Load State Slot 1"),
|
|
_trans("Load State Slot 2"),
|
|
_trans("Load State Slot 3"),
|
|
_trans("Load State Slot 4"),
|
|
_trans("Load State Slot 5"),
|
|
_trans("Load State Slot 6"),
|
|
_trans("Load State Slot 7"),
|
|
_trans("Load State Slot 8"),
|
|
_trans("Load State Slot 9"),
|
|
_trans("Load State Slot 10"),
|
|
|
|
_trans("Save State Slot 1"),
|
|
_trans("Save State Slot 2"),
|
|
_trans("Save State Slot 3"),
|
|
_trans("Save State Slot 4"),
|
|
_trans("Save State Slot 5"),
|
|
_trans("Save State Slot 6"),
|
|
_trans("Save State Slot 7"),
|
|
_trans("Save State Slot 8"),
|
|
_trans("Save State Slot 9"),
|
|
_trans("Save State Slot 10"),
|
|
|
|
_trans("Select State Slot 1"),
|
|
_trans("Select State Slot 2"),
|
|
_trans("Select State Slot 3"),
|
|
_trans("Select State Slot 4"),
|
|
_trans("Select State Slot 5"),
|
|
_trans("Select State Slot 6"),
|
|
_trans("Select State Slot 7"),
|
|
_trans("Select State Slot 8"),
|
|
_trans("Select State Slot 9"),
|
|
_trans("Select State Slot 10"),
|
|
|
|
_trans("Save to selected slot"),
|
|
_trans("Load from selected slot"),
|
|
|
|
_trans("Load State Last 1"),
|
|
_trans("Load State Last 2"),
|
|
_trans("Load State Last 3"),
|
|
_trans("Load State Last 4"),
|
|
_trans("Load State Last 5"),
|
|
_trans("Load State Last 6"),
|
|
_trans("Load State Last 7"),
|
|
_trans("Load State Last 8"),
|
|
_trans("Load State Last 9"),
|
|
_trans("Load State Last 10"),
|
|
|
|
_trans("Save Oldest State"),
|
|
_trans("Undo Load State"),
|
|
_trans("Undo Save State"),
|
|
_trans("Save State"),
|
|
_trans("Load State"),
|
|
};
|
|
static_assert(NUM_HOTKEYS == sizeof(hotkey_labels) / sizeof(hotkey_labels[0]),
|
|
"Wrong count of hotkey_labels");
|
|
|
|
namespace HotkeyManagerEmu
|
|
{
|
|
static u32 s_hotkeyDown[(NUM_HOTKEYS + 31) / 32];
|
|
static HotkeyStatus s_hotkey;
|
|
static bool s_enabled;
|
|
|
|
static InputConfig s_config("Hotkeys", _trans("Hotkeys"), "Hotkeys");
|
|
|
|
InputConfig* GetConfig()
|
|
{
|
|
return &s_config;
|
|
}
|
|
|
|
void GetStatus()
|
|
{
|
|
s_hotkey.err = PAD_ERR_NONE;
|
|
|
|
// Get input
|
|
static_cast<HotkeyManager*>(s_config.GetController(0))->GetInput(&s_hotkey);
|
|
}
|
|
|
|
bool IsEnabled()
|
|
{
|
|
return s_enabled;
|
|
}
|
|
|
|
void Enable(bool enable_toggle)
|
|
{
|
|
s_enabled = enable_toggle;
|
|
}
|
|
|
|
bool IsPressed(int Id, bool held)
|
|
{
|
|
unsigned int set = Id / 32;
|
|
unsigned int setKey = Id % 32;
|
|
if (s_hotkey.button[set] & (1 << setKey))
|
|
{
|
|
bool pressed = !!(s_hotkeyDown[set] & (1 << setKey));
|
|
s_hotkeyDown[set] |= (1 << setKey);
|
|
if (!pressed || held)
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
s_hotkeyDown[set] &= ~(1 << setKey);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Initialize(void* const hwnd)
|
|
{
|
|
if (s_config.ControllersNeedToBeCreated())
|
|
s_config.CreateController<HotkeyManager>();
|
|
|
|
g_controller_interface.Initialize(hwnd);
|
|
g_controller_interface.RegisterHotplugCallback(LoadConfig);
|
|
|
|
// load the saved controller config
|
|
s_config.LoadConfig(true);
|
|
|
|
for (u32& key : s_hotkeyDown)
|
|
key = 0;
|
|
|
|
s_enabled = true;
|
|
}
|
|
|
|
void LoadConfig()
|
|
{
|
|
s_config.LoadConfig(true);
|
|
}
|
|
|
|
void Shutdown()
|
|
{
|
|
s_config.ClearControllers();
|
|
|
|
g_controller_interface.Shutdown();
|
|
}
|
|
}
|
|
|
|
HotkeyManager::HotkeyManager()
|
|
{
|
|
for (int key = 0; key < NUM_HOTKEYS; key++)
|
|
{
|
|
int set = key / 32;
|
|
|
|
if (key % 32 == 0)
|
|
groups.emplace_back(m_keys[set] = new Buttons(_trans("Keys")));
|
|
|
|
m_keys[set]->controls.emplace_back(new ControlGroup::Input(hotkey_labels[key]));
|
|
}
|
|
|
|
groups.emplace_back(m_options = new ControlGroup(_trans("Options")));
|
|
m_options->boolean_settings.emplace_back(
|
|
std::make_unique<ControlGroup::BackgroundInputSetting>(_trans("Background Input")));
|
|
m_options->boolean_settings.emplace_back(std::make_unique<ControlGroup::BooleanSetting>(
|
|
_trans("Iterative Input"), false, ControlGroup::SettingType::VIRTUAL));
|
|
}
|
|
|
|
HotkeyManager::~HotkeyManager()
|
|
{
|
|
}
|
|
|
|
std::string HotkeyManager::GetName() const
|
|
{
|
|
return std::string("Hotkeys") + char('1' + 0);
|
|
}
|
|
|
|
void HotkeyManager::GetInput(HotkeyStatus* const kb)
|
|
{
|
|
auto lock = ControllerEmu::GetStateLock();
|
|
for (int set = 0; set < (NUM_HOTKEYS + 31) / 32; set++)
|
|
{
|
|
std::vector<u32> bitmasks;
|
|
for (int key = 0; key < std::min(32, NUM_HOTKEYS - set * 32); key++)
|
|
bitmasks.push_back(1 << key);
|
|
|
|
kb->button[set] = 0;
|
|
m_keys[set]->GetState(&kb->button[set], bitmasks.data());
|
|
}
|
|
}
|
|
|
|
void HotkeyManager::LoadDefaults(const ControllerInterface& ciface)
|
|
{
|
|
ControllerEmu::LoadDefaults(ciface);
|
|
|
|
#ifdef _WIN32
|
|
const std::string NON = "(!(LMENU | RMENU) & !(LSHIFT | RSHIFT) & !(LCONTROL | RCONTROL))";
|
|
const std::string ALT = "((LMENU | RMENU) & !(LSHIFT | RSHIFT) & !(LCONTROL | RCONTROL))";
|
|
const std::string SHIFT = "(!(LMENU | RMENU) & (LSHIFT | RSHIFT) & !(LCONTROL | RCONTROL))";
|
|
const std::string CTRL = "(!(LMENU | RMENU) & !(LSHIFT | RSHIFT) & (LCONTROL | RCONTROL))";
|
|
#else
|
|
const std::string NON = "(!`Alt_L` & !(`Shift_L` | `Shift_R`) & !(`Control_L` | `Control_R` ))";
|
|
const std::string ALT = "(`Alt_L` & !(`Shift_L` | `Shift_R`) & !(`Control_L` | `Control_R` ))";
|
|
const std::string SHIFT = "(!`Alt_L` & (`Shift_L` | `Shift_R`) & !(`Control_L` | `Control_R` ))";
|
|
const std::string CTRL = "(!`Alt_L` & !(`Shift_L` | `Shift_R`) & (`Control_L` | `Control_R` ))";
|
|
#endif
|
|
|
|
auto set_key_expression = [this](int index, const std::string& expression) {
|
|
m_keys[index / 32]->controls[index % 32]->control_ref->expression = expression;
|
|
};
|
|
|
|
// General hotkeys
|
|
set_key_expression(HK_OPEN, CTRL + " & O");
|
|
set_key_expression(HK_PLAY_PAUSE, "`F10`");
|
|
#ifdef _WIN32
|
|
set_key_expression(HK_STOP, "ESCAPE");
|
|
set_key_expression(HK_FULLSCREEN, ALT + " & RETURN");
|
|
#else
|
|
set_key_expression(HK_STOP, "Escape");
|
|
set_key_expression(HK_FULLSCREEN, ALT + " & Return");
|
|
#endif
|
|
set_key_expression(HK_SCREENSHOT, NON + " & `F9`");
|
|
set_key_expression(HK_WIIMOTE1_CONNECT, ALT + " & `F5`");
|
|
set_key_expression(HK_WIIMOTE2_CONNECT, ALT + " & `F6`");
|
|
set_key_expression(HK_WIIMOTE3_CONNECT, ALT + " & `F7`");
|
|
set_key_expression(HK_WIIMOTE4_CONNECT, ALT + " & `F8`");
|
|
set_key_expression(HK_BALANCEBOARD_CONNECT, ALT + " & `F9`");
|
|
#ifdef _WIN32
|
|
set_key_expression(HK_TOGGLE_THROTTLE, "TAB");
|
|
#else
|
|
set_key_expression(HK_TOGGLE_THROTTLE, "Tab");
|
|
#endif
|
|
|
|
// Freelook
|
|
set_key_expression(HK_FREELOOK_DECREASE_SPEED, SHIFT + " & `1`");
|
|
set_key_expression(HK_FREELOOK_INCREASE_SPEED, SHIFT + " & `2`");
|
|
set_key_expression(HK_FREELOOK_RESET_SPEED, SHIFT + " & F");
|
|
set_key_expression(HK_FREELOOK_UP, SHIFT + " & E");
|
|
set_key_expression(HK_FREELOOK_DOWN, SHIFT + " & Q");
|
|
set_key_expression(HK_FREELOOK_LEFT, SHIFT + " & A");
|
|
set_key_expression(HK_FREELOOK_RIGHT, SHIFT + " & D");
|
|
set_key_expression(HK_FREELOOK_ZOOM_IN, SHIFT + " & W");
|
|
set_key_expression(HK_FREELOOK_ZOOM_OUT, SHIFT + " & S");
|
|
set_key_expression(HK_FREELOOK_RESET, SHIFT + " & R");
|
|
|
|
// Savestates
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
set_key_expression(HK_LOAD_STATE_SLOT_1 + i,
|
|
StringFromFormat((NON + " & `F%d`").c_str(), i + 1));
|
|
set_key_expression(HK_SAVE_STATE_SLOT_1 + i,
|
|
StringFromFormat((SHIFT + " & `F%d`").c_str(), i + 1));
|
|
}
|
|
set_key_expression(HK_UNDO_LOAD_STATE, NON + " & `F12`");
|
|
set_key_expression(HK_UNDO_SAVE_STATE, SHIFT + " & `F12`");
|
|
}
|