InputCore overhaul
This commit is contained in:
28
src/input_core/CMakeLists.txt
Normal file
28
src/input_core/CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
set(SRCS
|
||||
input_core.cpp
|
||||
devices/Keyboard.cpp
|
||||
devices/SDLGamepad.cpp
|
||||
key_map.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
input_core.h
|
||||
key_map.h
|
||||
devices/IDevice.h
|
||||
devices/Keyboard.h
|
||||
devices/SDLGamepad.h
|
||||
)
|
||||
|
||||
|
||||
if(SDL2_FOUND)
|
||||
include_directories(${SDL2_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
|
||||
add_library(input_core STATIC ${SRCS} ${HEADERS})
|
||||
|
||||
if(SDL2_FOUND)
|
||||
target_link_libraries(input_core ${SDL2_LIBRARY})
|
||||
set_property(TARGET input_core APPEND PROPERTY COMPILE_DEFINITIONS HAVE_SDL2)
|
||||
endif()
|
||||
18
src/input_core/devices/IDevice.h
Normal file
18
src/input_core/devices/IDevice.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "core/settings.h"
|
||||
#include "input_core\key_map.h"
|
||||
class IDevice {
|
||||
public:
|
||||
std::map<std::string, std::vector<KeyMap::KeyTarget>> keyMapping; /// Maps the string in the settings file to the HID Padstate object
|
||||
|
||||
virtual bool InitDevice(int number, std::map<std::string, std::vector<KeyMap::KeyTarget>> keyMap) = 0;
|
||||
virtual void ProcessInput() = 0;
|
||||
virtual bool CloseDevice() = 0;
|
||||
};
|
||||
55
src/input_core/devices/Keyboard.cpp
Normal file
55
src/input_core/devices/Keyboard.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Keyboard.h"
|
||||
#include <SDL_keyboard.h>
|
||||
|
||||
Keyboard::Keyboard() {
|
||||
}
|
||||
|
||||
Keyboard::~Keyboard() {
|
||||
}
|
||||
|
||||
bool Keyboard::InitDevice(int number, std::map<std::string, std::vector<KeyMap::KeyTarget>> keyMap) {
|
||||
keyMapping = keyMap;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Keyboard::ProcessInput() {
|
||||
m.lock();
|
||||
auto keysPressedCopy = keysPressed;
|
||||
m.unlock();
|
||||
for (auto const &ent1 : keyMapping) {
|
||||
int scancode = std::stoul(ent1.first, nullptr, 16);
|
||||
KeyboardKey proxy = KeyboardKey(0, scancode, "");
|
||||
if (keysPressedCopy[proxy] == true && keysPressedLast[scancode] == false) {
|
||||
for (auto& key : ent1.second) {
|
||||
KeyMap::PressKey(key, 1.0);
|
||||
}
|
||||
keysPressedLast[scancode] = true;
|
||||
}
|
||||
else if (keysPressedCopy[proxy] == false && keysPressedLast[scancode] == true) {
|
||||
for (auto& key : ent1.second) {
|
||||
KeyMap::ReleaseKey(key);
|
||||
}
|
||||
keysPressedLast[scancode] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Keyboard::CloseDevice() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Keyboard::KeyPressed(KeyboardKey key) {
|
||||
m.lock();
|
||||
keysPressed[key] = true;
|
||||
m.unlock();
|
||||
}
|
||||
|
||||
void Keyboard::KeyReleased(KeyboardKey key) {
|
||||
m.lock();
|
||||
keysPressed[key] = false;
|
||||
m.unlock();
|
||||
}
|
||||
48
src/input_core/devices/Keyboard.h
Normal file
48
src/input_core/devices/Keyboard.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "IDevice.h"
|
||||
|
||||
struct KeyboardKey;
|
||||
|
||||
class Keyboard : public IDevice {
|
||||
private:
|
||||
std::map<KeyboardKey, bool> keysPressed;
|
||||
std::map<int, bool> keysPressedLast;
|
||||
std::mutex m; /// Keys pressed from frontend is on a separate thread.
|
||||
public:
|
||||
Keyboard();
|
||||
~Keyboard();
|
||||
bool InitDevice(int number, std::map<std::string, std::vector<KeyMap::KeyTarget>> keyMap) override;
|
||||
void ProcessInput() override;
|
||||
bool CloseDevice() override;
|
||||
void KeyPressed(KeyboardKey key);
|
||||
void KeyReleased(KeyboardKey key);
|
||||
};
|
||||
|
||||
struct KeyboardKey {
|
||||
uint32_t key;
|
||||
uint32_t scancode;
|
||||
std::string character;
|
||||
KeyboardKey(uint32_t Key, uint32_t Scancode, std::string Character) {
|
||||
key = Key;
|
||||
scancode = Scancode;
|
||||
character = Character;
|
||||
}
|
||||
bool operator==(KeyboardKey& other) {
|
||||
return (this->scancode == other.scancode);
|
||||
}
|
||||
bool operator==(uint32_t other) {
|
||||
return (this->scancode == other);
|
||||
}
|
||||
bool operator<(const KeyboardKey &o) const {
|
||||
return (this->scancode < o.scancode);
|
||||
}
|
||||
};
|
||||
86
src/input_core/devices/SDLGamepad.cpp
Normal file
86
src/input_core/devices/SDLGamepad.cpp
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <memory>
|
||||
#include <cmath>
|
||||
|
||||
#include "SDLGamepad.h"
|
||||
#include <SDL.h>
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
bool SDLGamepad::SDLInitialized = false;
|
||||
SDLGamepad::SDLGamepad() {
|
||||
}
|
||||
|
||||
SDLGamepad::~SDLGamepad() {
|
||||
CloseDevice();
|
||||
}
|
||||
|
||||
bool SDLGamepad::InitDevice(int number, std::map<std::string, std::vector<KeyMap::KeyTarget>> keyMap) {
|
||||
if (!SDLGamepad::SDLInitialized && SDL_Init(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||
LOG_CRITICAL(Input, "SDL_Init(SDL_INIT_GAMECONTROLLER) failed");
|
||||
return false;
|
||||
}
|
||||
SDL_GameControllerEventState(SDL_IGNORE);
|
||||
SDLGamepad::SDLInitialized = true;
|
||||
|
||||
if (SDL_IsGameController(number)) {
|
||||
gamepad = SDL_GameControllerOpen(number);
|
||||
if (gamepad == nullptr) {
|
||||
LOG_ERROR(Input, "Controller found but unable to open connection.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
keyMapping = keyMap;
|
||||
for (auto& entry : keyMapping) {
|
||||
keysPressed[entry.first] = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SDLGamepad::ProcessInput() {
|
||||
if (gamepad == nullptr)
|
||||
return;
|
||||
SDL_GameControllerUpdate();
|
||||
for (auto const &ent1 : keyMapping) {
|
||||
SDL_GameControllerButton button = SDL_GameControllerGetButtonFromString(friendlyNameMapping[ent1.first].c_str());
|
||||
if (button != SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_INVALID) {
|
||||
Uint8 pressed = SDL_GameControllerGetButton(gamepad, button);
|
||||
if (pressed == 1 && keysPressed[ent1.first] == false) {
|
||||
for (auto& padstate : ent1.second) {
|
||||
KeyMap::PressKey(padstate, 1.0);
|
||||
keysPressed[ent1.first] = true;
|
||||
}
|
||||
}
|
||||
else if (pressed == 0 && keysPressed[ent1.first] == true) {
|
||||
for (auto& padstate : ent1.second) {
|
||||
KeyMap::ReleaseKey(padstate);
|
||||
keysPressed[ent1.first] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Try axis if button isn't valid
|
||||
SDL_GameControllerAxis axis = SDL_GameControllerGetAxisFromString(friendlyNameMapping[ent1.first].c_str());
|
||||
if (axis != SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_INVALID) {
|
||||
Sint16 value = SDL_GameControllerGetAxis(gamepad, axis);
|
||||
for (auto& padstate : ent1.second) {
|
||||
if (abs(value) < 0.2 * 32767.0) // dont process if in deadzone. Replace later with settings for deadzone.
|
||||
KeyMap::ReleaseKey(padstate);
|
||||
else
|
||||
KeyMap::PressKey(padstate, (float)value / 32767.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SDLGamepad::CloseDevice() {
|
||||
if (gamepad != nullptr) {
|
||||
SDL_GameControllerClose(gamepad);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
48
src/input_core/devices/SDLGamepad.h
Normal file
48
src/input_core/devices/SDLGamepad.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SDL_gamecontroller.h>
|
||||
#include "IDevice.h"
|
||||
|
||||
class SDLGamepad : public IDevice {
|
||||
private:
|
||||
std::map<std::string, std::string> friendlyNameMapping = { /// Maps the friendly name shown on GUI with the string name for getting the SDL button instance.
|
||||
{ "Button A","a" },
|
||||
{ "Button B","b" },
|
||||
{ "Button X","x" },
|
||||
{ "Button Y","y" },
|
||||
{ "Left Shoulder","leftshoulder" },
|
||||
{ "Right Shoulder","rightshoulder" },
|
||||
{ "Start","start" },
|
||||
{ "Back","back" },
|
||||
{ "D-pad Up","dpup" },
|
||||
{ "D-pad Down","dpdown" },
|
||||
{ "D-pad Left","dpleft" },
|
||||
{ "D-pad Right","dpright" },
|
||||
{ "L3","leftstick" },
|
||||
{ "R3","rightstick" },
|
||||
{ "Left Trigger","lefttrigger" },
|
||||
{ "Right Trigger","righttrigger" },
|
||||
{ "Left Y+","lefty" },
|
||||
{ "Left Y-","lefty" },
|
||||
{ "Left X+","leftx" },
|
||||
{ "Left X-","leftx" },
|
||||
{ "Right Y+","righty" },
|
||||
{ "Right Y-","righty" },
|
||||
{ "Right X+","rightx" },
|
||||
{ "Right X-","rightx" },
|
||||
};
|
||||
static bool SDLInitialized;
|
||||
std::map<std::string, bool> keysPressed;
|
||||
SDL_GameController* gamepad;
|
||||
public:
|
||||
SDLGamepad();
|
||||
~SDLGamepad();
|
||||
|
||||
virtual bool InitDevice(int number, std::map<std::string, std::vector<KeyMap::KeyTarget>> keyMap) override;
|
||||
virtual void ProcessInput() override;
|
||||
bool CloseDevice() override;
|
||||
};
|
||||
108
src/input_core/input_core.cpp
Normal file
108
src/input_core/input_core.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "core/core_timing.h"
|
||||
|
||||
#include "input_core/input_core.h"
|
||||
#include "input_core/devices/Keyboard.h"
|
||||
#include "input_core/devices/SDLGamepad.h"
|
||||
|
||||
namespace InputCore {
|
||||
using std::vector;
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
constexpr u64 frame_ticks = 268123480ull / 60;
|
||||
static int tick_event;
|
||||
Service::HID::PadState pad_state;
|
||||
std::tuple<s16, s16> circle_pad = { 0,0 };
|
||||
shared_ptr<Keyboard> main_keyboard; /// Instance of main keyboard device. Always initialized regardless of settings.
|
||||
vector<shared_ptr<IDevice>> devices; ///Devices that are handling input for the game
|
||||
|
||||
static void InputTickCallback(u64, int cycles_late) {
|
||||
for (auto& device : devices)
|
||||
device->ProcessInput();
|
||||
|
||||
Service::HID::Update();
|
||||
|
||||
// Reschedule recurrent event
|
||||
CoreTiming::ScheduleEvent(frame_ticks - cycles_late, tick_event);
|
||||
}
|
||||
|
||||
void InputCore::Init() {
|
||||
devices = ParseSettings();
|
||||
tick_event = CoreTiming::RegisterEvent("InputCore::tick_event", InputTickCallback);
|
||||
CoreTiming::ScheduleEvent(frame_ticks, tick_event);
|
||||
}
|
||||
|
||||
void InputCore::Shutdown() {
|
||||
devices.clear();
|
||||
}
|
||||
|
||||
///Parse the settings to initialize necessary devices to handle input
|
||||
vector<shared_ptr<IDevice>> InputCore::ParseSettings() {
|
||||
vector<shared_ptr<IDevice>> devices;
|
||||
vector<Settings::InputDeviceMapping> uniqueMappings; //unique mappings from settings file, used to init devices.
|
||||
|
||||
//Get Unique input mappings from settings
|
||||
for (auto& mapping : Settings::values.input_mappings) {
|
||||
if (!CheckIfMappingExists(uniqueMappings, mapping)) {
|
||||
uniqueMappings.push_back(mapping);
|
||||
}
|
||||
}
|
||||
|
||||
//Generate a device for each unique mapping
|
||||
shared_ptr<IDevice> input;
|
||||
for (auto& mapping : uniqueMappings) {
|
||||
switch (mapping.framework) {
|
||||
case Settings::DeviceFramework::Qt:
|
||||
{
|
||||
main_keyboard = std::make_shared<Keyboard>();
|
||||
input = main_keyboard;
|
||||
break;
|
||||
}
|
||||
case Settings::DeviceFramework::SDL:
|
||||
{
|
||||
if (mapping.device == Settings::Device::Keyboard) {
|
||||
main_keyboard = std::make_shared<Keyboard>();
|
||||
input = main_keyboard;
|
||||
break;
|
||||
}
|
||||
else if (mapping.device == Settings::Device::Gamepad) {
|
||||
input = std::make_shared<SDLGamepad>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
devices.push_back(input);
|
||||
|
||||
//Build list of inputs to listen for, for this device
|
||||
std::map<std::string, vector<KeyMap::KeyTarget>> keyMapping;
|
||||
for (int i = 0; i < Settings::values.input_mappings.size(); i++) {
|
||||
KeyMap::KeyTarget val = KeyMap::mapping_targets[i];
|
||||
std::string key = Settings::values.input_mappings[i].key;
|
||||
if (Settings::values.input_mappings[i] == mapping) {
|
||||
keyMapping[key].push_back(val);
|
||||
}
|
||||
}
|
||||
|
||||
input->InitDevice(mapping.number, keyMapping);
|
||||
}
|
||||
if (main_keyboard == nullptr)
|
||||
main_keyboard = std::make_shared<Keyboard>();
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
///Helper method to check if device has already been initialized from the mapping.
|
||||
bool InputCore::CheckIfMappingExists(vector<Settings::InputDeviceMapping> uniqueMapping, Settings::InputDeviceMapping mappingToCheck) {
|
||||
for (auto& mapping : uniqueMapping) {
|
||||
if (mapping == mappingToCheck)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
26
src/input_core/input_core.h
Normal file
26
src/input_core/input_core.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/settings.h"
|
||||
#include "input_core\devices\IDevice.h"
|
||||
|
||||
class Keyboard;
|
||||
|
||||
namespace InputCore {
|
||||
extern Service::HID::PadState pad_state;
|
||||
extern std::tuple<s16, s16> circle_pad;
|
||||
|
||||
extern std::shared_ptr<Keyboard> main_keyboard;
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
|
||||
std::vector<std::shared_ptr<IDevice>> ParseSettings();
|
||||
bool CheckIfMappingExists(std::vector<Settings::InputDeviceMapping> uniqueMapping, Settings::InputDeviceMapping mappingToCheck);
|
||||
} // namespace
|
||||
63
src/input_core/key_map.cpp
Normal file
63
src/input_core/key_map.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "common/emu_window.h"
|
||||
|
||||
#include "input_core/key_map.h"
|
||||
#include "input_core/input_core.h"
|
||||
|
||||
namespace KeyMap {
|
||||
constexpr int MAX_CIRCLEPAD_POS = 0x9C; /// Max value for a circle pad position
|
||||
const std::array<KeyTarget, Settings::NativeInput::NUM_INPUTS> mapping_targets = { {
|
||||
Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y,
|
||||
Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR,
|
||||
Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_TOUCH,
|
||||
Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT,
|
||||
Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT,
|
||||
|
||||
Service::HID::PAD_CIRCLE_UP,
|
||||
Service::HID::PAD_CIRCLE_DOWN,
|
||||
Service::HID::PAD_CIRCLE_LEFT,
|
||||
Service::HID::PAD_CIRCLE_RIGHT,
|
||||
} };
|
||||
///Array of inputs that are analog only, and require a strength when set
|
||||
const std::array<KeyTarget, 4> analog_inputs = {
|
||||
Service::HID::PAD_CIRCLE_UP,
|
||||
Service::HID::PAD_CIRCLE_DOWN,
|
||||
Service::HID::PAD_CIRCLE_LEFT,
|
||||
Service::HID::PAD_CIRCLE_RIGHT
|
||||
};
|
||||
|
||||
void PressKey(KeyTarget target, const float strength) {
|
||||
if (std::find(std::begin(analog_inputs), std::end(analog_inputs), target) == std::end(analog_inputs)) { // If is digital keytarget
|
||||
InputCore::pad_state.hex |= target.target.direct_target_hex;
|
||||
}
|
||||
else { // it is analog input
|
||||
if (target == Service::HID::PAD_CIRCLE_UP || target == Service::HID::PAD_CIRCLE_DOWN) {
|
||||
std::get<1>(InputCore::circle_pad) = MAX_CIRCLEPAD_POS * strength * -1;
|
||||
}
|
||||
else if (target == Service::HID::PAD_CIRCLE_LEFT || target == Service::HID::PAD_CIRCLE_RIGHT) {
|
||||
std::get<0>(InputCore::circle_pad) = MAX_CIRCLEPAD_POS * strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReleaseKey(KeyTarget target) {
|
||||
if (std::find(std::begin(analog_inputs), std::end(analog_inputs), target) == std::end(analog_inputs)) { // If is digital keytarget
|
||||
InputCore::pad_state.hex &= ~target.target.direct_target_hex;
|
||||
}
|
||||
else { // it is analog input
|
||||
if (target == Service::HID::PAD_CIRCLE_UP || target == Service::HID::PAD_CIRCLE_DOWN) {
|
||||
std::get<1>(InputCore::circle_pad) = 0;
|
||||
}
|
||||
else if (target == Service::HID::PAD_CIRCLE_LEFT || target == Service::HID::PAD_CIRCLE_RIGHT) {
|
||||
std::get<0>(InputCore::circle_pad) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
src/input_core/key_map.h
Normal file
63
src/input_core/key_map.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// Copyright 2016 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
|
||||
class EmuWindow;
|
||||
|
||||
namespace KeyMap {
|
||||
/**
|
||||
* Represents key mapping targets that are not real 3DS buttons.
|
||||
* They will be handled by KeyMap and translated to 3DS input.
|
||||
*/
|
||||
enum class IndirectTarget {
|
||||
CirclePadUp,
|
||||
CirclePadDown,
|
||||
CirclePadLeft,
|
||||
CirclePadRight,
|
||||
CirclePadModifier
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a key mapping target. It can be a PadState that represents real 3DS buttons,
|
||||
* or an IndirectTarget.
|
||||
*/
|
||||
struct KeyTarget {
|
||||
bool direct;
|
||||
union {
|
||||
u32 direct_target_hex;
|
||||
IndirectTarget indirect_target;
|
||||
} target;
|
||||
|
||||
KeyTarget() : direct(true) {
|
||||
target.direct_target_hex = 0;
|
||||
}
|
||||
|
||||
KeyTarget(Service::HID::PadState pad) : direct(true) {
|
||||
target.direct_target_hex = pad.hex;
|
||||
}
|
||||
|
||||
KeyTarget(IndirectTarget i) : direct(false) {
|
||||
target.indirect_target = i;
|
||||
}
|
||||
const bool operator==(const Service::HID::PadState &other) const {
|
||||
return this->target.direct_target_hex == other.hex;
|
||||
}
|
||||
const bool operator==(const KeyTarget &other) const {
|
||||
return this->target.direct_target_hex == other.target.direct_target_hex;
|
||||
}
|
||||
};
|
||||
|
||||
extern const std::array<KeyTarget, Settings::NativeInput::NUM_INPUTS> mapping_targets;
|
||||
|
||||
///Handles the pressing of a key and modifies InputCore state
|
||||
void PressKey(KeyTarget target, float strength);
|
||||
|
||||
///Handles the releasing of a key and modifies InputCore state
|
||||
void ReleaseKey(KeyTarget target);
|
||||
}
|
||||
Reference in New Issue
Block a user