dolphin/Source/Core/Core/HotkeyManager.cpp
Léo Lam 93f5df4195 ControllerInterface: Add RemoveDevice()
This adds RemoveDevice() to ControllerInterface, fixes ExpressionParser
and some other code to support device removals without crashing,
and adds an IsValid() method to Device, to prepare for hotplugging.
2016-07-29 17:18:37 +02:00

320 lines
9.0 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("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("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`");
}