Fix include issues. Change inputcore back to namespace. Other misc cleanup.

This commit is contained in:
Anon 2017-01-15 11:08:52 -06:00
parent bd94a96d3c
commit 76b99b99a5
12 changed files with 161 additions and 200 deletions

View File

@ -45,7 +45,8 @@ static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = {
SDL_SCANCODE_L, SDL_SCANCODE_L,
// indirectly mapped keys // indirectly mapped keys
SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT}; SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT,
};
void Config::ReadValues() { void Config::ReadValues() {
// Controls // Controls

View File

@ -8,6 +8,7 @@
#define SDL_MAIN_HANDLED #define SDL_MAIN_HANDLED
#include <SDL.h> #include <SDL.h>
#include <glad/glad.h> #include <glad/glad.h>
#include "citra/emu_window/emu_window_sdl2.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/scm_rev.h" #include "common/scm_rev.h"
@ -18,8 +19,6 @@
#include "input_core/input_core.h" #include "input_core/input_core.h"
#include "video_core/video_core.h" #include "video_core/video_core.h"
#include "citra/emu_window/emu_window_sdl2.h"
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
motion_emu->Tilt(x, y); motion_emu->Tilt(x, y);

View File

@ -14,10 +14,8 @@
#include "common/string_util.h" #include "common/string_util.h"
#include "core/core.h" #include "core/core.h"
#include "core/settings.h" #include "core/settings.h"
#include "input_core/devices/keyboard.h" #include "input_core/devices/keyboard.h"
#include "input_core/input_core.h" #include "input_core/input_core.h"
#include "video_core/debug_utils/debug_utils.h" #include "video_core/debug_utils/debug_utils.h"
#include "video_core/video_core.h" #include "video_core/video_core.h"

View File

@ -23,7 +23,8 @@ const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> Config::defaults =
Qt::Key_K, Qt::Key_J, Qt::Key_L, Qt::Key_K, Qt::Key_J, Qt::Key_L,
// indirectly mapped keys // indirectly mapped keys
Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right}; Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right,
};
const QVariant Config::default_circle_pad_modifier = Qt::Key_F; const QVariant Config::default_circle_pad_modifier = Qt::Key_F;

View File

@ -8,7 +8,6 @@
#include "citra_qt/configure_input.h" #include "citra_qt/configure_input.h"
#include "citra_qt/keybinding_names.h" #include "citra_qt/keybinding_names.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "input_core/devices/keyboard.h" #include "input_core/devices/keyboard.h"
#include "input_core/input_core.h" #include "input_core/input_core.h"
@ -19,29 +18,30 @@ ConfigureInput::ConfigureInput(QWidget* parent)
// Initialize mapping of input enum to UI button. // Initialize mapping of input enum to UI button.
button_map = { button_map = {
{std::make_pair(Settings::NativeInput::Values::A, ui->buttonA)}, {Settings::NativeInput::Values::A, ui->buttonA},
{std::make_pair(Settings::NativeInput::Values::B, ui->buttonB)}, {Settings::NativeInput::Values::B, ui->buttonB},
{std::make_pair(Settings::NativeInput::Values::X, ui->buttonX)}, {Settings::NativeInput::Values::X, ui->buttonX},
{std::make_pair(Settings::NativeInput::Values::Y, ui->buttonY)}, {Settings::NativeInput::Values::Y, ui->buttonY},
{std::make_pair(Settings::NativeInput::Values::L, ui->buttonL)}, {Settings::NativeInput::Values::L, ui->buttonL},
{std::make_pair(Settings::NativeInput::Values::R, ui->buttonR)}, {Settings::NativeInput::Values::R, ui->buttonR},
{std::make_pair(Settings::NativeInput::Values::ZL, ui->buttonZL)}, {Settings::NativeInput::Values::ZL, ui->buttonZL},
{std::make_pair(Settings::NativeInput::Values::ZR, ui->buttonZR)}, {Settings::NativeInput::Values::ZR, ui->buttonZR},
{std::make_pair(Settings::NativeInput::Values::START, ui->buttonStart)}, {Settings::NativeInput::Values::START, ui->buttonStart},
{std::make_pair(Settings::NativeInput::Values::SELECT, ui->buttonSelect)}, {Settings::NativeInput::Values::SELECT, ui->buttonSelect},
{std::make_pair(Settings::NativeInput::Values::HOME, ui->buttonHome)}, {Settings::NativeInput::Values::HOME, ui->buttonHome},
{std::make_pair(Settings::NativeInput::Values::DUP, ui->buttonDpadUp)}, {Settings::NativeInput::Values::DUP, ui->buttonDpadUp},
{std::make_pair(Settings::NativeInput::Values::DDOWN, ui->buttonDpadDown)}, {Settings::NativeInput::Values::DDOWN, ui->buttonDpadDown},
{std::make_pair(Settings::NativeInput::Values::DLEFT, ui->buttonDpadLeft)}, {Settings::NativeInput::Values::DLEFT, ui->buttonDpadLeft},
{std::make_pair(Settings::NativeInput::Values::DRIGHT, ui->buttonDpadRight)}, {Settings::NativeInput::Values::DRIGHT, ui->buttonDpadRight},
{std::make_pair(Settings::NativeInput::Values::CUP, ui->buttonCStickUp)}, {Settings::NativeInput::Values::CUP, ui->buttonCStickUp},
{std::make_pair(Settings::NativeInput::Values::CDOWN, ui->buttonCStickDown)}, {Settings::NativeInput::Values::CDOWN, ui->buttonCStickDown},
{std::make_pair(Settings::NativeInput::Values::CLEFT, ui->buttonCStickLeft)}, {Settings::NativeInput::Values::CLEFT, ui->buttonCStickLeft},
{std::make_pair(Settings::NativeInput::Values::CRIGHT, ui->buttonCStickRight)}, {Settings::NativeInput::Values::CRIGHT, ui->buttonCStickRight},
{std::make_pair(Settings::NativeInput::Values::CIRCLE_UP, ui->buttonCircleUp)}, {Settings::NativeInput::Values::CIRCLE_UP, ui->buttonCircleUp},
{std::make_pair(Settings::NativeInput::Values::CIRCLE_DOWN, ui->buttonCircleDown)}, {Settings::NativeInput::Values::CIRCLE_DOWN, ui->buttonCircleDown},
{std::make_pair(Settings::NativeInput::Values::CIRCLE_LEFT, ui->buttonCircleLeft)}, {Settings::NativeInput::Values::CIRCLE_LEFT, ui->buttonCircleLeft},
{std::make_pair(Settings::NativeInput::Values::CIRCLE_RIGHT, ui->buttonCircleRight)}}; {Settings::NativeInput::Values::CIRCLE_RIGHT, ui->buttonCircleRight},
};
// Attach handle click method to each button click. // Attach handle click method to each button click.
for (const auto& entry : button_map) { for (const auto& entry : button_map) {

View File

@ -4,4 +4,4 @@
#include "input_core/devices/device.h" #include "input_core/devices/device.h"
IDevice::~IDevice() = default; InputDeviceInterface::~InputDeviceInterface() = default;

View File

@ -10,12 +10,13 @@
#include "core/settings.h" #include "core/settings.h"
#include "input_core/key_map.h" #include "input_core/key_map.h"
class IDevice { class InputDeviceInterface {
public: public:
virtual ~IDevice(); virtual ~InputDeviceInterface();
/** /**
* Initialize IDevice object with device's index and the map of keys that it will listen to. * Initialize InputDeviceInterface object with device's index and the map of keys that it will
* listen to.
* @param number: device number as ordered connected to computer. * @param number: device number as ordered connected to computer.
* @param keymap: vector of PadStates for device to listen for * @param keymap: vector of PadStates for device to listen for
* @return true if successful * @return true if successful

View File

@ -27,7 +27,7 @@ struct KeyboardKey {
return key < other.key; return key < other.key;
} }
}; };
class Keyboard : public IDevice { class Keyboard : public InputDeviceInterface {
public: public:
Keyboard(); Keyboard();
~Keyboard(); ~Keyboard();

View File

@ -10,7 +10,6 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "input_core/devices/gamecontrollerdb.h" #include "input_core/devices/gamecontrollerdb.h"
#include "input_core/devices/sdl_gamepad.h" #include "input_core/devices/sdl_gamepad.h"
@ -82,8 +81,8 @@ bool SDLGamepad::CloseDevice() {
return true; return true;
} }
std::vector<std::shared_ptr<IDevice>> SDLGamepad::GetAllDevices() { std::vector<std::shared_ptr<InputDeviceInterface>> SDLGamepad::GetAllDevices() {
std::vector<std::shared_ptr<IDevice>> devices; std::vector<std::shared_ptr<InputDeviceInterface>> devices;
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
auto gamepad = std::make_shared<SDLGamepad>(); auto gamepad = std::make_shared<SDLGamepad>();
bool success = gamepad->InitDevice( bool success = gamepad->InitDevice(

View File

@ -7,7 +7,7 @@
#include "input_core/devices/device.h" #include "input_core/devices/device.h"
struct _SDL_GameController; struct _SDL_GameController;
class SDLGamepad : public IDevice { class SDLGamepad : public InputDeviceInterface {
public: public:
SDLGamepad(); SDLGamepad();
SDLGamepad(int number_, _SDL_GameController* gamepad_); SDLGamepad(int number_, _SDL_GameController* gamepad_);
@ -20,7 +20,7 @@ public:
void Clear() override; void Clear() override;
/// Returns vector of all gamepads connected to computer. Used for keybinding setup /// Returns vector of all gamepads connected to computer. Used for keybinding setup
static std::vector<std::shared_ptr<IDevice>> GetAllDevices(); static std::vector<std::shared_ptr<InputDeviceInterface>> GetAllDevices();
enum class GamepadInputs { enum class GamepadInputs {
ButtonA, ButtonA,
ButtonB, ButtonB,

View File

@ -9,54 +9,49 @@
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hw/gpu.h" #include "core/hw/gpu.h"
#include "input_core/devices/keyboard.h" #include "input_core/devices/keyboard.h"
#include "input_core/devices/sdl_gamepad.h" #include "input_core/devices/sdl_gamepad.h"
#include "input_core/input_core.h" #include "input_core/input_core.h"
int InputCore::tick_event; int tick_event;
Service::HID::PadState InputCore::pad_state; Service::HID::PadState pad_state;
std::tuple<s16, s16> InputCore::circle_pad; std::tuple<s16, s16> circle_pad;
std::shared_ptr<Keyboard> InputCore::main_keyboard; std::shared_ptr<Keyboard> main_keyboard;
std::vector<std::shared_ptr<IDevice>> std::vector<std::shared_ptr<InputDeviceInterface>>
InputCore::devices; ///< Devices that are handling input for the game devices; ///< Devices that are handling input for the game
std::map<Settings::InputDeviceMapping, std::vector<Service::HID::PadState>> InputCore::key_mappings; std::map<Settings::InputDeviceMapping, std::vector<Service::HID::PadState>> key_mappings;
std::map<Service::HID::PadState, bool> std::map<Service::HID::PadState, bool> keys_pressed; ///< keys that were pressed on previous frame.
InputCore::keys_pressed; ///< keys that were pressed on previous frame. std::mutex pad_state_mutex;
std::mutex InputCore::pad_state_mutex; std::mutex touch_mutex;
std::mutex InputCore::touch_mutex; u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320)
u16 InputCore::touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320) u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240)
u16 InputCore::touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240) bool touch_pressed; ///< True if touchpad area is currently pressed, otherwise false
bool InputCore::touch_pressed; ///< True if touchpad area is currently pressed, otherwise false const float input_detect_threshold =
const float InputCore::input_detect_threshold =
0.45; ///< Applies to analog controls being used for digital 3ds inputs. 0.45; ///< Applies to analog controls being used for digital 3ds inputs.
void InputCore::Init() { /**
ParseSettings(); * Takes two floats and the deadzone and applies formula to
tick_event = CoreTiming::RegisterEvent("InputCore::tick_event", InputTickCallback); * correct the stick position.
CoreTiming::ScheduleEvent(GPU::frame_ticks, tick_event); */
} std::tuple<float, float> ApplyDeadzone(float x, float y, float dead_zone) {
float magnitude = std::sqrt((x * x) + (y * y));
void InputCore::Shutdown() { if (magnitude < dead_zone) {
CoreTiming::UnscheduleEvent(tick_event, 0); x = 0;
devices.clear(); y = 0;
} } else {
float normalized_x = x / magnitude;
void InputCore::InputTickCallback(u64, int cycles_late) { float normalized_y = y / magnitude;
std::vector<std::map<Settings::InputDeviceMapping, float>> inputs; x = normalized_x * ((magnitude - dead_zone) / (1 - dead_zone));
for (auto& device : devices) { y = normalized_y * ((magnitude - dead_zone) / (1 - dead_zone));
inputs.push_back(device->ProcessInput());
} }
UpdateEmulatorInputs(inputs); return std::tuple<float, float>(x, y);
Service::HID::Update();
// Reschedule recurrent event
CoreTiming::ScheduleEvent(GPU::frame_ticks - cycles_late, tick_event);
} }
void InputCore::UpdateEmulatorInputs( /**
std::vector<std::map<Settings::InputDeviceMapping, float>> inputs) { * Loops through all unique input devices, and all bound inputs to update the emulator's input
* status.
*/
void UpdateEmulatorInputs(std::vector<std::map<Settings::InputDeviceMapping, float>> inputs) {
std::lock_guard<std::mutex> lock(pad_state_mutex); std::lock_guard<std::mutex> lock(pad_state_mutex);
// Apply deadzone for circle pad // Apply deadzone for circle pad
@ -149,14 +144,16 @@ void InputCore::SetTouchState(std::tuple<u16, u16, bool> value) {
std::tie(touch_x, touch_y, touch_pressed) = value; std::tie(touch_x, touch_y, touch_pressed) = value;
} }
bool InputCore::CheckIfMappingExists(const std::set<Settings::InputDeviceMapping>& unique_mapping, /// Helper method to check if device was already initialized
bool CheckIfMappingExists(const std::set<Settings::InputDeviceMapping>& unique_mapping,
Settings::InputDeviceMapping mapping_to_check) { Settings::InputDeviceMapping mapping_to_check) {
return std::any_of( return std::any_of(
unique_mapping.begin(), unique_mapping.end(), unique_mapping.begin(), unique_mapping.end(),
[mapping_to_check](const auto& mapping) { return mapping == mapping_to_check; }); [mapping_to_check](const auto& mapping) { return mapping == mapping_to_check; });
} }
std::set<Settings::InputDeviceMapping> InputCore::GatherUniqueMappings() { /// Get unique input mappings from settings
std::set<Settings::InputDeviceMapping> GatherUniqueMappings() {
std::set<Settings::InputDeviceMapping> unique_mappings; std::set<Settings::InputDeviceMapping> unique_mappings;
for (const auto& mapping : Settings::values.input_mappings) { for (const auto& mapping : Settings::values.input_mappings) {
@ -170,7 +167,8 @@ std::set<Settings::InputDeviceMapping> InputCore::GatherUniqueMappings() {
return unique_mappings; return unique_mappings;
} }
void InputCore::BuildKeyMapping() { /// Builds map of input keys to 3ds buttons for unique device
void BuildKeyMapping() {
key_mappings.clear(); key_mappings.clear();
for (size_t i = 0; i < Settings::values.input_mappings.size(); i++) { for (size_t i = 0; i < Settings::values.input_mappings.size(); i++) {
auto key = Settings::values.input_mappings[i]; auto key = Settings::values.input_mappings[i];
@ -180,10 +178,11 @@ void InputCore::BuildKeyMapping() {
} }
} }
void InputCore::GenerateUniqueDevices() { /// Generate a device for each unique mapping
void GenerateUniqueDevices() {
auto uniqueMappings = GatherUniqueMappings(); auto uniqueMappings = GatherUniqueMappings();
devices.clear(); devices.clear();
std::shared_ptr<IDevice> input; std::shared_ptr<InputDeviceInterface> input;
for (const auto& mapping : uniqueMappings) { for (const auto& mapping : uniqueMappings) {
switch (mapping.framework) { switch (mapping.framework) {
case Settings::DeviceFramework::SDL: { case Settings::DeviceFramework::SDL: {
@ -202,25 +201,12 @@ void InputCore::GenerateUniqueDevices() {
} }
} }
void InputCore::ParseSettings() { /// Read settings to initialize devices
void ParseSettings() {
GenerateUniqueDevices(); GenerateUniqueDevices();
BuildKeyMapping(); BuildKeyMapping();
} }
std::tuple<float, float> InputCore::ApplyDeadzone(float x, float y, float dead_zone) {
float magnitude = std::sqrt((x * x) + (y * y));
if (magnitude < dead_zone) {
x = 0;
y = 0;
} else {
float normalized_x = x / magnitude;
float normalized_y = y / magnitude;
x = normalized_x * ((magnitude - dead_zone) / (1 - dead_zone));
y = normalized_y * ((magnitude - dead_zone) / (1 - dead_zone));
}
return std::tuple<float, float>(x, y);
}
void InputCore::ReloadSettings() { void InputCore::ReloadSettings() {
if (devices.empty()) if (devices.empty())
return; return;
@ -229,7 +215,7 @@ void InputCore::ReloadSettings() {
ParseSettings(); ParseSettings();
} }
std::vector<std::shared_ptr<IDevice>> InputCore::GetAllDevices() { std::vector<std::shared_ptr<InputDeviceInterface>> InputCore::GetAllDevices() {
auto all_devices = SDLGamepad::GetAllDevices(); auto all_devices = SDLGamepad::GetAllDevices();
auto keyboard = InputCore::GetKeyboard(); auto keyboard = InputCore::GetKeyboard();
all_devices.push_back(keyboard); all_devices.push_back(keyboard);
@ -261,3 +247,27 @@ Settings::InputDeviceMapping InputCore::DetectInput(int max_time,
}; };
return input_device; return input_device;
} }
void InputTickCallback(u64, int cycles_late) {
std::vector<std::map<Settings::InputDeviceMapping, float>> inputs;
for (auto& device : devices) {
inputs.push_back(device->ProcessInput());
}
UpdateEmulatorInputs(inputs);
Service::HID::Update();
// Reschedule recurrent event
CoreTiming::ScheduleEvent(GPU::frame_ticks - cycles_late, tick_event);
}
void InputCore::Init() {
ParseSettings();
tick_event = CoreTiming::RegisterEvent("InputCore::tick_event", InputTickCallback);
CoreTiming::ScheduleEvent(GPU::frame_ticks, tick_event);
}
void InputCore::Shutdown() {
CoreTiming::UnscheduleEvent(tick_event, 0);
devices.clear();
}

View File

@ -16,112 +16,64 @@
class Keyboard; class Keyboard;
class InputCore { namespace InputCore {
public: void Init();
static void Init(); void Shutdown();
static void Shutdown();
/** /**
* Threadsafe getter to the current PadState * Threadsafe getter to the current PadState
* @return Service::HID::PadState instance * @return Service::HID::PadState instance
*/ */
static Service::HID::PadState GetPadState(); Service::HID::PadState GetPadState();
/** /**
* Threadsafe setter for the current PadState * Threadsafe setter for the current PadState
* @param state New PadState to overwrite current PadState. * @param state New PadState to overwrite current PadState.
*/ */
static void SetPadState(const Service::HID::PadState& state); void SetPadState(const Service::HID::PadState& state);
/** /**
* Getter for current CirclePad * Getter for current CirclePad
* @return std::tuple<s16, s16> CirclePad state * @return std::tuple<s16, s16> CirclePad state
*/ */
static std::tuple<s16, s16> GetCirclePad(); std::tuple<s16, s16> GetCirclePad();
/** /**
* Getter for Citra's main keyboard input handler * Getter for Citra's main keyboard input handler
* @return std::shared_ptr<Keyboard> Device Keyboard instance * @return std::shared_ptr<Keyboard> Device Keyboard instance
*/ */
static std::shared_ptr<Keyboard> GetKeyboard(); std::shared_ptr<Keyboard> GetKeyboard();
/** /**
* Gets the current touch screen state (touch X/Y coordinates and whether or not it is pressed). * Gets the current touch screen state (touch X/Y coordinates and whether or not it is pressed).
* Threadsafe. * Threadsafe.
* @note This should be called by the core emu thread to get a state set by the window thread. * @note This should be called by the core emu thread to get a state set by the window thread.
* @return std::tuple of (x, y, pressed) where `x` and `y` are the touch coordinates and * @return std::tuple of (x, y, pressed) where `x` and `y` are the touch coordinates and
* `pressed` is true if the touch screen is currently being pressed * `pressed` is true if the touch screen is currently being pressed
*/ */
static std::tuple<u16, u16, bool> GetTouchState(); std::tuple<u16, u16, bool> GetTouchState();
/** /**
* Threadsafe setter for the current touch screen state. * Threadsafe setter for the current touch screen state.
* @param value New Touch State * @param value New Touch State
*/ */
static void SetTouchState(std::tuple<u16, u16, bool> value); void SetTouchState(std::tuple<u16, u16, bool> value);
/** /**
* Reload input key mapping settings during game-play * Reload input key mapping settings during game-play
*/ */
static void ReloadSettings(); void ReloadSettings();
/**
/**
* Returns vector of all available devices from user's system. * Returns vector of all available devices from user's system.
*/ */
static std::vector<std::shared_ptr<IDevice>> GetAllDevices(); std::vector<std::shared_ptr<InputDeviceInterface>> GetAllDevices();
/** /**
* Loops through all devices and detects the first device that produces an input * Loops through all devices and detects the first device that produces an input
* @param max_time: maximum amount of time to wait until input detected, in milliseconds. * @param max_time: maximum amount of time to wait until input detected, in milliseconds.
* @param update_GUI: function to run in while loop to process any gui events. * @param update_GUI: function to run in while loop to process any gui events.
* @return Settings::InputDeviceMapping of input device * @return Settings::InputDeviceMapping of input device
*/ */
static Settings::InputDeviceMapping DetectInput(int max_time, Settings::InputDeviceMapping DetectInput(int max_time, std::function<void(void)> update_GUI);
std::function<void(void)> update_GUI);
private:
static int tick_event;
static Service::HID::PadState pad_state;
static std::tuple<s16, s16> circle_pad;
static std::shared_ptr<Keyboard> main_keyboard; ///< Keyboard is always active for Citra
static std::vector<std::shared_ptr<IDevice>>
devices; ///< Devices that are handling input for the game
static std::map<Settings::InputDeviceMapping, std::vector<Service::HID::PadState>> key_mappings;
static std::map<Service::HID::PadState, bool>
keys_pressed; ///< keys that were pressed on previous frame.
static std::mutex pad_state_mutex;
static std::mutex touch_mutex;
static u16 touch_x; ///< Touchpad X-position in native 3DS pixel coordinates (0-320)
static u16 touch_y; ///< Touchpad Y-position in native 3DS pixel coordinates (0-240)
static bool touch_pressed; ///< True if touchpad area is currently pressed, otherwise false
static const float input_detect_threshold;
/**
* Loops through all unique input devices, and all bound inputs to update the emulator's input
* status.
*/
static void UpdateEmulatorInputs(
std::vector<std::map<Settings::InputDeviceMapping, float>> inputs);
static void InputTickCallback(u64, int cycles_late);
/**
* Helper methodto check if device was already initialized
*/
static bool CheckIfMappingExists(const std::set<Settings::InputDeviceMapping>& uniqueMapping,
Settings::InputDeviceMapping mappingToCheck);
static std::set<Settings::InputDeviceMapping>
GatherUniqueMappings(); /// Get unique input mappings from settings
static void BuildKeyMapping(); /// Builds map of input keys to 3ds buttons for unique device
static void GenerateUniqueDevices(); /// Generate a device for each unique mapping
static void ParseSettings(); /// Read settings to initialize devices
/**
* Takes two floats and the deadzone and applies formula to
* correct the stick position.
*/
static std::tuple<float, float> ApplyDeadzone(float x, float y, float dead_zone);
}; };