mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-07 18:31:37 +00:00
fd5a5a2156
Also add it in JoystickAxis enum of common/events Many gamepads have HATs instead of DPAD buttons, ie. they send movement events instead of button presses for the DPAD directions
619 lines
20 KiB
C++
619 lines
20 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "backends/keymapper/hardware-input.h"
|
|
|
|
#include "backends/keymapper/keymapper.h"
|
|
|
|
#include "common/tokenizer.h"
|
|
#include "common/translation.h"
|
|
|
|
namespace Common {
|
|
|
|
// TODO: Maybe make 'Command' a separate mac-specific modifier so we can define
|
|
// defaults key bindings from the original mac game versions without binding
|
|
// them to the meta key on other platforms?
|
|
#if defined(WIN32)
|
|
#define META_KEY_NAME "Win"
|
|
#elif defined(MACOSX) || defined(IPHONE)
|
|
#define META_KEY_NAME "Cmd"
|
|
#else
|
|
#define META_KEY_NAME "Meta"
|
|
#endif
|
|
|
|
const KeyTableEntry defaultKeys[] = {
|
|
{"BACKSPACE", KEYCODE_BACKSPACE, "Backspace"},
|
|
{"TAB", KEYCODE_TAB, "Tab"},
|
|
{"CLEAR", KEYCODE_CLEAR, "Clear"},
|
|
{"RETURN", KEYCODE_RETURN, "Return"},
|
|
{"PAUSE", KEYCODE_PAUSE, "Pause"},
|
|
{"ESCAPE", KEYCODE_ESCAPE, "Esc"},
|
|
{"SPACE", KEYCODE_SPACE, "Space"},
|
|
{"EXCLAIM", KEYCODE_EXCLAIM, "!"},
|
|
{"QUOTEDBL", KEYCODE_QUOTEDBL, "\""},
|
|
{"HASH", KEYCODE_HASH, "#"},
|
|
{"DOLLAR", KEYCODE_DOLLAR, "$"},
|
|
{"PERCENT", KEYCODE_PERCENT, "%"},
|
|
{"AMPERSAND", KEYCODE_AMPERSAND, "&"},
|
|
{"QUOTE", KEYCODE_QUOTE, "'"},
|
|
{"LEFTPAREN", KEYCODE_LEFTPAREN, "("},
|
|
{"RIGHTPAREN", KEYCODE_RIGHTPAREN, ")"},
|
|
{"ASTERISK", KEYCODE_ASTERISK, "*"},
|
|
{"PLUS", KEYCODE_PLUS, "+"},
|
|
{"COMMA", KEYCODE_COMMA, ","},
|
|
{"MINUS", KEYCODE_MINUS, "-"},
|
|
{"PERIOD", KEYCODE_PERIOD, "."},
|
|
{"SLASH", KEYCODE_SLASH, "/"},
|
|
{"0", KEYCODE_0, "0"},
|
|
{"1", KEYCODE_1, "1"},
|
|
{"2", KEYCODE_2, "2"},
|
|
{"3", KEYCODE_3, "3"},
|
|
{"4", KEYCODE_4, "4"},
|
|
{"5", KEYCODE_5, "5"},
|
|
{"6", KEYCODE_6, "6"},
|
|
{"7", KEYCODE_7, "7"},
|
|
{"8", KEYCODE_8, "8"},
|
|
{"9", KEYCODE_9, "9"},
|
|
{"COLON", KEYCODE_COLON, ":"},
|
|
{"SEMICOLON", KEYCODE_SEMICOLON, ";"},
|
|
{"LESS", KEYCODE_LESS, "<"},
|
|
{"EQUALS", KEYCODE_EQUALS, "="},
|
|
{"GREATER", KEYCODE_GREATER, ">"},
|
|
{"QUESTION", KEYCODE_QUESTION, "?"},
|
|
{"AT", KEYCODE_AT, "@"},
|
|
|
|
{"LEFTBRACKET", KEYCODE_LEFTBRACKET, "["},
|
|
{"BACKSLASH", KEYCODE_BACKSLASH, "\\"},
|
|
{"RIGHTBRACKET", KEYCODE_RIGHTBRACKET, "]"},
|
|
{"CARET", KEYCODE_CARET, "^"},
|
|
{"UNDERSCORE", KEYCODE_UNDERSCORE, "_"},
|
|
{"BACKQUOTE", KEYCODE_BACKQUOTE, "`"},
|
|
{"a", KEYCODE_a, "a"},
|
|
{"b", KEYCODE_b, "b"},
|
|
{"c", KEYCODE_c, "c"},
|
|
{"d", KEYCODE_d, "d"},
|
|
{"e", KEYCODE_e, "e"},
|
|
{"f", KEYCODE_f, "f"},
|
|
{"g", KEYCODE_g, "g"},
|
|
{"h", KEYCODE_h, "h"},
|
|
{"i", KEYCODE_i, "i"},
|
|
{"j", KEYCODE_j, "j"},
|
|
{"k", KEYCODE_k, "k"},
|
|
{"l", KEYCODE_l, "l"},
|
|
{"m", KEYCODE_m, "m"},
|
|
{"n", KEYCODE_n, "n"},
|
|
{"o", KEYCODE_o, "o"},
|
|
{"p", KEYCODE_p, "p"},
|
|
{"q", KEYCODE_q, "q"},
|
|
{"r", KEYCODE_r, "r"},
|
|
{"s", KEYCODE_s, "s"},
|
|
{"t", KEYCODE_t, "t"},
|
|
{"u", KEYCODE_u, "u"},
|
|
{"v", KEYCODE_v, "v"},
|
|
{"w", KEYCODE_w, "w"},
|
|
{"x", KEYCODE_x, "x"},
|
|
{"y", KEYCODE_y, "y"},
|
|
{"z", KEYCODE_z, "z"},
|
|
{"DELETE", KEYCODE_DELETE, "Del"},
|
|
|
|
// Numeric keypad
|
|
{"KP0", KEYCODE_KP0, "KP0"},
|
|
{"KP1", KEYCODE_KP1, "KP1"},
|
|
{"KP2", KEYCODE_KP2, "KP2"},
|
|
{"KP3", KEYCODE_KP3, "KP3"},
|
|
{"KP4", KEYCODE_KP4, "KP4"},
|
|
{"KP5", KEYCODE_KP5, "KP5"},
|
|
{"KP6", KEYCODE_KP6, "KP6"},
|
|
{"KP7", KEYCODE_KP7, "KP7"},
|
|
{"KP8", KEYCODE_KP8, "KP8"},
|
|
{"KP9", KEYCODE_KP9, "KP9"},
|
|
{"KP_PERIOD", KEYCODE_KP_PERIOD, "KP."},
|
|
{"KP_DIVIDE", KEYCODE_KP_DIVIDE, "KP/"},
|
|
{"KP_MULTIPLY", KEYCODE_KP_MULTIPLY, "KP*"},
|
|
{"KP_MINUS", KEYCODE_KP_MINUS, "KP-"},
|
|
{"KP_PLUS", KEYCODE_KP_PLUS, "KP+"},
|
|
{"KP_ENTER", KEYCODE_KP_ENTER, "KP Enter"},
|
|
{"KP_EQUALS", KEYCODE_KP_EQUALS, "KP="},
|
|
|
|
// Arrows + Home/End pad
|
|
{"UP", KEYCODE_UP, "Up"},
|
|
{"DOWN", KEYCODE_DOWN, "Down"},
|
|
{"RIGHT", KEYCODE_RIGHT, "Right"},
|
|
{"LEFT", KEYCODE_LEFT, "Left"},
|
|
{"INSERT", KEYCODE_INSERT, "Insert"},
|
|
{"HOME", KEYCODE_HOME, "Home"},
|
|
{"END", KEYCODE_END, "End"},
|
|
{"PAGEUP", KEYCODE_PAGEUP, "PgUp"},
|
|
{"PAGEDOWN", KEYCODE_PAGEDOWN, "PgDn"},
|
|
|
|
// Function keys
|
|
{"F1", KEYCODE_F1, "F1"},
|
|
{"F2", KEYCODE_F2, "F2"},
|
|
{"F3", KEYCODE_F3, "F3"},
|
|
{"F4", KEYCODE_F4, "F4"},
|
|
{"F5", KEYCODE_F5, "F5"},
|
|
{"F6", KEYCODE_F6, "F6"},
|
|
{"F7", KEYCODE_F7, "F7"},
|
|
{"F8", KEYCODE_F8, "F8"},
|
|
{"F9", KEYCODE_F9, "F9"},
|
|
{"F10", KEYCODE_F10, "F10"},
|
|
{"F11", KEYCODE_F11, "F11"},
|
|
{"F12", KEYCODE_F12, "F12"},
|
|
{"F13", KEYCODE_F13, "F13"},
|
|
{"F14", KEYCODE_F14, "F14"},
|
|
{"F15", KEYCODE_F15, "F15"},
|
|
{"F16", KEYCODE_F16, "F16"},
|
|
{"F17", KEYCODE_F17, "F17"},
|
|
{"F18", KEYCODE_F18, "F18"},
|
|
|
|
// Miscellaneous function keys
|
|
{"HELP", KEYCODE_HELP, "Help"},
|
|
{"PRINT", KEYCODE_PRINT, "Print"},
|
|
{"SYSREQ", KEYCODE_SYSREQ, "SysRq"},
|
|
{"BREAK", KEYCODE_BREAK, "Break"},
|
|
{"MENU", KEYCODE_MENU, "Menu"},
|
|
// Power Macintosh power key
|
|
{"POWER", KEYCODE_POWER, "Power"},
|
|
// Some european keyboards
|
|
{"EURO", KEYCODE_EURO, "Euro"},
|
|
// Atari keyboard has Undo
|
|
{"UNDO", KEYCODE_UNDO, "Undo"},
|
|
{"SLEEP", KEYCODE_SLEEP, "Sleep"},
|
|
{"MUTE", KEYCODE_MUTE, "Mute"},
|
|
{"EJECT", KEYCODE_EJECT, "Eject"},
|
|
{"VOLUMEUP", KEYCODE_VOLUMEUP, "Volume Up"},
|
|
{"VOLUMEDOWN", KEYCODE_VOLUMEDOWN, "Volume Down"},
|
|
{"LEFTSOFT", KEYCODE_LEFTSOFT, "Left Soft"},
|
|
{"RIGHTSOFT", KEYCODE_RIGHTSOFT, "Right Soft"},
|
|
{"CALL", KEYCODE_CALL, "Call"},
|
|
{"HANGUP", KEYCODE_HANGUP, "Hang up"},
|
|
{"CAMERA", KEYCODE_CAMERA, "Camera"},
|
|
{"WWW", KEYCODE_WWW, "WWW"},
|
|
{"MAIL", KEYCODE_MAIL, "Mail"},
|
|
{"CALCULATOR", KEYCODE_CALCULATOR, "Calculator"},
|
|
{"CUT", KEYCODE_CUT, "Cut"},
|
|
{"COPY", KEYCODE_COPY, "Copy"},
|
|
{"PASTE", KEYCODE_PASTE, "Paste"},
|
|
{"SELECT", KEYCODE_SELECT, "Select"},
|
|
{"CANCEL", KEYCODE_CANCEL, "Cancel"},
|
|
|
|
// Action keys
|
|
{"AC_SEARCH", KEYCODE_AC_SEARCH, "AC Search"},
|
|
{"AC_HOME", KEYCODE_AC_HOME, "AC Home"},
|
|
{"AC_BACK", KEYCODE_AC_BACK, "AC Back"},
|
|
{"AC_FORWARD", KEYCODE_AC_FORWARD, "AC Forward"},
|
|
{"AC_STOP", KEYCODE_AC_STOP, "AC Stop"},
|
|
{"AC_REFRESH", KEYCODE_AC_REFRESH, "AC Refresh"},
|
|
{"AC_BOOKMARKS", KEYCODE_AC_BOOKMARKS, "AC Bookmarks"},
|
|
|
|
// Audio keys
|
|
{"AUDIONEXT", KEYCODE_AUDIONEXT, "Audio Next"},
|
|
{"AUDIOPREV", KEYCODE_AUDIOPREV, "Audio Previous"},
|
|
{"AUDIOSTOP", KEYCODE_AUDIOSTOP, "Audio Stop"},
|
|
{"AUDIOPLAY", KEYCODE_AUDIOPLAY, "Audio Play"},
|
|
{"AUDIOPAUSE", KEYCODE_AUDIOPAUSE, "Audio Pause"},
|
|
{"AUDIOPLAYPAUSE", KEYCODE_AUDIOPLAYPAUSE, "Audio Play/Pause"},
|
|
{"AUDIOMUTE", KEYCODE_AUDIOMUTE, "Audio Mute"},
|
|
{"AUDIOREWIND", KEYCODE_AUDIOREWIND, "Audio Rewind"},
|
|
{"AUDIOFASTFORWARD", KEYCODE_AUDIOFASTFORWARD, "Audio Fast-Forward"},
|
|
|
|
// Modifier keys
|
|
{"SCROLLOCK", KEYCODE_SCROLLOCK, "Scroll Lock" },
|
|
{"CAPSLOCK", KEYCODE_CAPSLOCK, "Caps Lock" },
|
|
{"NUMLOCK", KEYCODE_NUMLOCK, "Num Lock" },
|
|
{"LSHIFT", KEYCODE_LSHIFT, "Left Shift" },
|
|
{"RSHIFT", KEYCODE_RSHIFT, "Right Shift" },
|
|
{"LALT", KEYCODE_LALT, "Left Alt" },
|
|
{"RALT", KEYCODE_RALT, "Right Alt" },
|
|
{"LCTRL", KEYCODE_LCTRL, "Left Control" },
|
|
{"RCTRL", KEYCODE_RCTRL, "Right Control" },
|
|
{"LMETA", KEYCODE_LMETA, "Left " META_KEY_NAME },
|
|
{"RMETA", KEYCODE_RMETA, "Right " META_KEY_NAME },
|
|
|
|
{nullptr, KEYCODE_INVALID, nullptr}
|
|
};
|
|
|
|
// TODO: Add NUM_LOCK
|
|
const ModifierTableEntry defaultModifiers[] = {
|
|
{ KBD_CTRL, "C", "Ctrl+" },
|
|
{ KBD_SHIFT, "S", "Shift+" },
|
|
{ KBD_ALT, "A", "Alt+" },
|
|
{ KBD_META, "M", META_KEY_NAME "+" },
|
|
{ 0, nullptr, nullptr }
|
|
};
|
|
|
|
const HardwareInputTableEntry defaultMouseButtons[] = {
|
|
{ "MOUSE_LEFT", MOUSE_BUTTON_LEFT, _s("Left Mouse Button") },
|
|
{ "MOUSE_RIGHT", MOUSE_BUTTON_RIGHT, _s("Right Mouse Button") },
|
|
{ "MOUSE_MIDDLE", MOUSE_BUTTON_MIDDLE, _s("Middle Mouse Button") },
|
|
{ "MOUSE_WHEEL_UP", MOUSE_WHEEL_UP, _s("Mouse Wheel Up") },
|
|
{ "MOUSE_WHEEL_DOWN", MOUSE_WHEEL_DOWN, _s("Mouse Wheel Down") },
|
|
{ "MOUSE_X1", MOUSE_BUTTON_X1, _s("X1 Mouse Button") },
|
|
{ "MOUSE_X2", MOUSE_BUTTON_X2, _s("X2 Mouse Button") },
|
|
{ nullptr, 0, nullptr }
|
|
};
|
|
|
|
const HardwareInputTableEntry defaultJoystickButtons[] = {
|
|
{ "JOY_A", JOYSTICK_BUTTON_A, _s("Joy A") },
|
|
{ "JOY_B", JOYSTICK_BUTTON_B, _s("Joy B") },
|
|
{ "JOY_X", JOYSTICK_BUTTON_X, _s("Joy X") },
|
|
{ "JOY_Y", JOYSTICK_BUTTON_Y, _s("Joy Y") },
|
|
{ "JOY_BACK", JOYSTICK_BUTTON_BACK, _s("Joy Back") },
|
|
{ "JOY_GUIDE", JOYSTICK_BUTTON_GUIDE, _s("Joy Guide") },
|
|
{ "JOY_START", JOYSTICK_BUTTON_START, _s("Joy Start") },
|
|
{ "JOY_LEFT_STICK", JOYSTICK_BUTTON_LEFT_STICK, _s("Left Stick") },
|
|
{ "JOY_RIGHT_STICK", JOYSTICK_BUTTON_RIGHT_STICK, _s("Right Stick") },
|
|
{ "JOY_LEFT_SHOULDER", JOYSTICK_BUTTON_LEFT_SHOULDER, _s("Left Shoulder") },
|
|
{ "JOY_RIGHT_SHOULDER", JOYSTICK_BUTTON_RIGHT_SHOULDER, _s("Right Shoulder") },
|
|
{ "JOY_UP", JOYSTICK_BUTTON_DPAD_UP, _s("D-pad Up") },
|
|
{ "JOY_DOWN", JOYSTICK_BUTTON_DPAD_DOWN, _s("D-pad Down") },
|
|
{ "JOY_LEFT", JOYSTICK_BUTTON_DPAD_LEFT, _s("D-pad Left") },
|
|
{ "JOY_RIGHT", JOYSTICK_BUTTON_DPAD_RIGHT, _s("D-pad Right") },
|
|
{ "JOY_CENTER", JOYSTICK_BUTTON_DPAD_CENTER, _s("D-pad Center") },
|
|
{ nullptr, 0, nullptr }
|
|
};
|
|
|
|
const AxisTableEntry defaultJoystickAxes[] = {
|
|
{ "JOY_LEFT_TRIGGER", JOYSTICK_AXIS_LEFT_TRIGGER, kAxisTypeHalf, _s("Left Trigger") },
|
|
{ "JOY_RIGHT_TRIGGER", JOYSTICK_AXIS_RIGHT_TRIGGER, kAxisTypeHalf, _s("Right Trigger") },
|
|
{ "JOY_LEFT_STICK_X", JOYSTICK_AXIS_LEFT_STICK_X, kAxisTypeFull, _s("Left Stick X") },
|
|
{ "JOY_LEFT_STICK_Y", JOYSTICK_AXIS_LEFT_STICK_Y, kAxisTypeFull, _s("Left Stick Y") },
|
|
{ "JOY_RIGHT_STICK_X", JOYSTICK_AXIS_RIGHT_STICK_X, kAxisTypeFull, _s("Right Stick X") },
|
|
{ "JOY_RIGHT_STICK_Y", JOYSTICK_AXIS_RIGHT_STICK_Y, kAxisTypeFull, _s("Right Stick Y") },
|
|
{ "JOY_HAT_X", JOYSTICK_AXIS_HAT_X, kAxisTypeFull, _s("Hat X") },
|
|
{ "JOY_HAT_Y", JOYSTICK_AXIS_HAT_Y, kAxisTypeFull, _s("Hat Y") },
|
|
{ nullptr, 0, kAxisTypeFull, nullptr }
|
|
};
|
|
|
|
HardwareInputSet::~HardwareInputSet() {
|
|
}
|
|
|
|
KeyboardHardwareInputSet::KeyboardHardwareInputSet(const KeyTableEntry *keys, const ModifierTableEntry *modifiers) :
|
|
_keys(keys),
|
|
_modifiers(modifiers) {
|
|
assert(_keys);
|
|
assert(_modifiers);
|
|
}
|
|
|
|
HardwareInput KeyboardHardwareInputSet::findHardwareInput(const String &id) const {
|
|
StringTokenizer tokenizer(id, "+");
|
|
|
|
byte modifierFlags = 0;
|
|
|
|
// TODO: Normalize modifier order
|
|
U32String fullKeyDesc;
|
|
|
|
String token;
|
|
while (!tokenizer.empty()) {
|
|
token = tokenizer.nextToken();
|
|
|
|
const ModifierTableEntry *modifier = nullptr;
|
|
for (modifier = _modifiers; modifier->id; modifier++) {
|
|
if (token == modifier->id) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (modifier && modifier->id) {
|
|
modifierFlags |= modifier->flag;
|
|
fullKeyDesc += _(modifier->desc);
|
|
} else {
|
|
// We reached the end of the modifiers, the token is a keycode
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!tokenizer.empty()) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
const KeyTableEntry *key = nullptr;
|
|
for (key = _keys; key->hwId; key++) {
|
|
if (token.equals(key->hwId)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!key || !key->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
const KeyState keystate = KeyState(key->keycode, 0, modifierFlags);
|
|
return HardwareInput::createKeyboard(id, keystate, fullKeyDesc + _(key->desc));
|
|
}
|
|
|
|
HardwareInput KeyboardHardwareInputSet::findHardwareInput(const Event &event) const {
|
|
switch (event.type) {
|
|
case EVENT_KEYDOWN:
|
|
case EVENT_KEYUP: {
|
|
KeyState normalizedKeystate = normalizeKeyState(event.kbd);
|
|
|
|
const KeyTableEntry *key = nullptr;
|
|
for (key = _keys; key->hwId; key++) {
|
|
if (normalizedKeystate.keycode == key->keycode) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!key || !key->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
String id;
|
|
U32String fullKeyDesc;
|
|
byte modifierFlags = 0;
|
|
|
|
for (const ModifierTableEntry *modifier = _modifiers; modifier->id; modifier++) {
|
|
if (normalizedKeystate.flags & modifier->flag) {
|
|
id += modifier->id;
|
|
id += "+";
|
|
fullKeyDesc += _(modifier->desc);
|
|
modifierFlags |= modifier->flag;
|
|
}
|
|
}
|
|
|
|
const KeyState keystate = KeyState(key->keycode, 0, modifierFlags);
|
|
return HardwareInput::createKeyboard(id + key->hwId, keystate, fullKeyDesc + _(key->desc));
|
|
}
|
|
default:
|
|
return HardwareInput();
|
|
}
|
|
}
|
|
|
|
KeyState KeyboardHardwareInputSet::normalizeKeyState(const KeyState &keystate) {
|
|
KeyState normalizedKeystate = keystate;
|
|
|
|
// We ignore the sticky modifiers as they traditionally
|
|
// have no impact on the outcome of key presses.
|
|
// TODO: Maybe Num Lock should act as a modifier for the keypad.
|
|
normalizedKeystate.flags &= ~KBD_STICKY;
|
|
|
|
// Modifier keypresses ignore the corresponding modifier flag.
|
|
// That way, for example, `Left Shift` is not identified
|
|
// as `Shift+Left Shift` by the keymapper.
|
|
switch (normalizedKeystate.keycode) {
|
|
case KEYCODE_LSHIFT:
|
|
case KEYCODE_RSHIFT:
|
|
normalizedKeystate.flags &= ~KBD_SHIFT;
|
|
break;
|
|
case KEYCODE_LCTRL:
|
|
case KEYCODE_RCTRL:
|
|
normalizedKeystate.flags &= ~KBD_CTRL;
|
|
break;
|
|
case KEYCODE_LALT:
|
|
case KEYCODE_RALT:
|
|
normalizedKeystate.flags &= ~KBD_ALT;
|
|
break;
|
|
case KEYCODE_LMETA:
|
|
case KEYCODE_RMETA:
|
|
normalizedKeystate.flags &= ~KBD_META;
|
|
break;
|
|
case KEYCODE_SCROLLOCK:
|
|
normalizedKeystate.flags &= ~KBD_SCRL;
|
|
break;
|
|
case KEYCODE_CAPSLOCK:
|
|
normalizedKeystate.flags &= ~KBD_CAPS;
|
|
break;
|
|
case KEYCODE_NUMLOCK:
|
|
normalizedKeystate.flags &= ~KBD_NUM;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return normalizedKeystate;
|
|
}
|
|
|
|
MouseHardwareInputSet::MouseHardwareInputSet(const HardwareInputTableEntry *buttonEntries) :
|
|
_buttonEntries(buttonEntries) {
|
|
assert(_buttonEntries);
|
|
}
|
|
|
|
HardwareInput MouseHardwareInputSet::findHardwareInput(const String &id) const {
|
|
const HardwareInputTableEntry *hw = HardwareInputTableEntry::findWithId(_buttonEntries, id);
|
|
if (!hw || !hw->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
return HardwareInput::createMouse(hw->hwId, hw->code, _(hw->desc));
|
|
}
|
|
|
|
HardwareInput MouseHardwareInputSet::findHardwareInput(const Event &event) const {
|
|
int button;
|
|
switch (event.type) {
|
|
case EVENT_LBUTTONDOWN:
|
|
case EVENT_LBUTTONUP:
|
|
button = MOUSE_BUTTON_LEFT;
|
|
break;
|
|
case EVENT_RBUTTONDOWN:
|
|
case EVENT_RBUTTONUP:
|
|
button = MOUSE_BUTTON_RIGHT;
|
|
break;
|
|
case EVENT_MBUTTONDOWN:
|
|
case EVENT_MBUTTONUP:
|
|
button = MOUSE_BUTTON_MIDDLE;
|
|
break;
|
|
case Common::EVENT_WHEELUP:
|
|
button = MOUSE_WHEEL_UP;
|
|
break;
|
|
case Common::EVENT_WHEELDOWN:
|
|
button = MOUSE_WHEEL_DOWN;
|
|
break;
|
|
case EVENT_X1BUTTONDOWN:
|
|
case EVENT_X1BUTTONUP:
|
|
button = MOUSE_BUTTON_X1;
|
|
break;
|
|
case EVENT_X2BUTTONDOWN:
|
|
case EVENT_X2BUTTONUP:
|
|
button = MOUSE_BUTTON_X2;
|
|
break;
|
|
default:
|
|
button = -1;
|
|
break;
|
|
}
|
|
|
|
if (button == -1) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
const HardwareInputTableEntry *hw = HardwareInputTableEntry::findWithCode(_buttonEntries, button);
|
|
if (!hw || !hw->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
return HardwareInput::createMouse(hw->hwId, hw->code, _(hw->desc));
|
|
}
|
|
|
|
JoystickHardwareInputSet::JoystickHardwareInputSet(const HardwareInputTableEntry *buttonEntries, const AxisTableEntry *axisEntries) :
|
|
_buttonEntries(buttonEntries),
|
|
_axisEntries(axisEntries) {
|
|
assert(_buttonEntries);
|
|
assert(_axisEntries);
|
|
}
|
|
|
|
HardwareInput JoystickHardwareInputSet::findHardwareInput(const String &id) const {
|
|
const HardwareInputTableEntry *hw = HardwareInputTableEntry::findWithId(_buttonEntries, id);
|
|
if (hw && hw->hwId) {
|
|
return HardwareInput::createJoystickButton(hw->hwId, hw->code, _(hw->desc));
|
|
}
|
|
|
|
bool hasHalfSuffix = id.lastChar() == '-' || id.lastChar() == '+';
|
|
Common::String tableId = hasHalfSuffix ? Common::String(id.c_str(), id.size() - 1) : id;
|
|
const AxisTableEntry *axis = AxisTableEntry::findWithId(_axisEntries, tableId);
|
|
if (axis && axis->hwId) {
|
|
if (hasHalfSuffix && axis->type == kAxisTypeHalf) {
|
|
return HardwareInput(); // Half axes can't be split in halves
|
|
} else if (!hasHalfSuffix && axis->type == kAxisTypeFull) {
|
|
return HardwareInput(); // For now it's only possible to bind half axes
|
|
}
|
|
|
|
if (axis->type == kAxisTypeHalf) {
|
|
return HardwareInput::createJoystickHalfAxis(axis->hwId, axis->code, true, _(axis->desc));
|
|
} else {
|
|
bool positiveHalf = id.lastChar() == '+';
|
|
Common::U32String desc = U32String::format("%S%c", _(axis->desc).c_str(), id.lastChar());
|
|
return HardwareInput::createJoystickHalfAxis(id, axis->code, positiveHalf, desc);
|
|
}
|
|
}
|
|
|
|
return HardwareInput();
|
|
}
|
|
|
|
HardwareInput JoystickHardwareInputSet::findHardwareInput(const Event &event) const {
|
|
switch (event.type) {
|
|
case EVENT_JOYBUTTON_DOWN:
|
|
case EVENT_JOYBUTTON_UP: {
|
|
const HardwareInputTableEntry *hw = HardwareInputTableEntry::findWithCode(_buttonEntries, event.joystick.button);
|
|
if (!hw || !hw->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
return HardwareInput::createJoystickButton(hw->hwId, hw->code, _(hw->desc));
|
|
}
|
|
case EVENT_JOYAXIS_MOTION: {
|
|
if (ABS(event.joystick.position) < (JOYAXIS_MAX / 2)) {
|
|
return HardwareInput(); // Ignore incomplete presses for remapping purposes
|
|
}
|
|
|
|
const AxisTableEntry *hw = AxisTableEntry::findWithCode(_axisEntries, event.joystick.axis);
|
|
if (!hw || !hw->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
if (hw->type == kAxisTypeHalf) {
|
|
return HardwareInput::createJoystickHalfAxis(hw->hwId, hw->code, true, _(hw->desc));
|
|
} else {
|
|
bool positiveHalf = event.joystick.position >= 0;
|
|
char halfSuffix = positiveHalf ? '+' : '-';
|
|
Common::String hwId = String::format("%s%c", hw->hwId, halfSuffix);
|
|
Common::U32String desc = U32String::format("%S%c", _(hw->desc).c_str(), halfSuffix);
|
|
return HardwareInput::createJoystickHalfAxis(hwId, hw->code, positiveHalf, desc);
|
|
}
|
|
}
|
|
|
|
default:
|
|
return HardwareInput();
|
|
}
|
|
}
|
|
|
|
CustomHardwareInputSet::CustomHardwareInputSet(const HardwareInputTableEntry *hardwareEntries) :
|
|
_hardwareEntries(hardwareEntries) {
|
|
assert(_hardwareEntries);
|
|
}
|
|
|
|
HardwareInput CustomHardwareInputSet::findHardwareInput(const String &id) const {
|
|
const HardwareInputTableEntry *hw = HardwareInputTableEntry::findWithId(_hardwareEntries, id);
|
|
if (!hw || !hw->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
return HardwareInput::createCustom(hw->hwId, hw->code, _(hw->desc));
|
|
}
|
|
|
|
HardwareInput CustomHardwareInputSet::findHardwareInput(const Event &event) const {
|
|
switch (event.type) {
|
|
case EVENT_CUSTOM_BACKEND_HARDWARE: {
|
|
const HardwareInputTableEntry *hw = HardwareInputTableEntry::findWithCode(_hardwareEntries, event.customType);
|
|
if (!hw || !hw->hwId) {
|
|
return HardwareInput();
|
|
}
|
|
|
|
return HardwareInput::createCustom(hw->hwId, hw->code, _(hw->desc));
|
|
}
|
|
default:
|
|
return HardwareInput();
|
|
}
|
|
}
|
|
|
|
CompositeHardwareInputSet::~CompositeHardwareInputSet() {
|
|
for (uint i = 0; i < _inputSets.size(); i++) {
|
|
delete _inputSets[i];
|
|
}
|
|
}
|
|
|
|
HardwareInput CompositeHardwareInputSet::findHardwareInput(const String &id) const {
|
|
for (uint i = 0; i < _inputSets.size(); i++) {
|
|
HardwareInput hardwareInput = _inputSets[i]->findHardwareInput(id);
|
|
if (hardwareInput.type != kHardwareInputTypeInvalid) {
|
|
return hardwareInput;
|
|
}
|
|
}
|
|
|
|
return HardwareInput();
|
|
}
|
|
|
|
HardwareInput CompositeHardwareInputSet::findHardwareInput(const Event &event) const {
|
|
for (uint i = 0; i < _inputSets.size(); i++) {
|
|
HardwareInput hardwareInput = _inputSets[i]->findHardwareInput(event);
|
|
if (hardwareInput.type != kHardwareInputTypeInvalid) {
|
|
return hardwareInput;
|
|
}
|
|
}
|
|
|
|
return HardwareInput();
|
|
}
|
|
|
|
void CompositeHardwareInputSet::addHardwareInputSet(HardwareInputSet *hardwareInputSet) {
|
|
_inputSets.push_back(hardwareInputSet);
|
|
}
|
|
|
|
} //namespace Common
|