From 0cc1dd69ba771996c58be7dfd17d7c128298691f Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 11 Sep 2014 13:09:03 +0000 Subject: [PATCH] input: use scancodes instead of ASCII values when using SDL v2. --- src/Makefile.am | 2 +- src/input/input.cpp | 11 +- src/input/input.h | 110 ++++++++++--- src/input/scancodes.h | 287 ++++++++++++++++++++++++++++++++++ src/lolcore.vcxproj | 1 + src/lolcore.vcxproj.filters | 3 + src/platform/sdl/sdlinput.cpp | 13 +- 7 files changed, 391 insertions(+), 36 deletions(-) create mode 100644 src/input/scancodes.h diff --git a/src/Makefile.am b/src/Makefile.am index 54f07269..7b5fb5af 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -93,7 +93,7 @@ liblolcore_sources = \ gpu/rendercontext.cpp \ \ input/input.cpp input/input.h input/input_internal.h input/keys.h \ - input/controller.cpp input/controller.h \ + input/scancodes.h input/controller.cpp input/controller.h \ \ gpu/defaultmaterial.lolfx \ gpu/tile.lolfx gpu/palette.lolfx gpu/line.lolfx \ diff --git a/src/input/input.cpp b/src/input/input.cpp index 30acfa5d..7ed9515e 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -49,11 +49,20 @@ void InputDeviceInternal::AddCursor(const char* name) InputDeviceInternal* InputDeviceInternal::CreateStandardKeyboard() { InputDeviceInternal* keyboard = new InputDeviceInternal(g_name_keyboard.C()); - /* "value" is unused, what matters is the index. */ + +#if USE_OLD_SDL + /* TODO: deprecate this */ # define KEY_FUNC(key, value) \ keyboard->AddKey(#key); # include "input/keys.h" # undef KEY_FUNC +#else + /* "value" is unused, what matters is the index. */ +# define _SC(value, str, name) \ + keyboard->AddKey(#name); +# include "input/scancodes.h" +#endif + return keyboard; } diff --git a/src/input/input.h b/src/input/input.h index 9648e384..3bebe4bb 100644 --- a/src/input/input.h +++ b/src/input/input.h @@ -20,43 +20,103 @@ class InputDevice { public: /** Gets the name of this input device */ - const String& GetName() const { return m_name; } + const String& GetName() const + { + return m_name; + } /** Gets the index of the corresponding key, needed to call GetKey */ - ptrdiff_t GetKeyIndex(const char* name) const { return GetItemIndex(name, m_keynames); } + ptrdiff_t GetKeyIndex(const char* name) const + { + return GetItemIndex(name, m_keynames); + } + /** Gets the index of the corresponding axis, needed to call GetAxis */ - ptrdiff_t GetAxisIndex(const char* name) const { return GetItemIndex(name, m_axisnames); } + ptrdiff_t GetAxisIndex(const char* name) const + { + return GetItemIndex(name, m_axisnames); + } + /** Gets the index of the corresponding cursor, needed to call GetCursor */ - ptrdiff_t GetCursorIndex(const char* name) const { return GetItemIndex(name, m_cursornames); } + ptrdiff_t GetCursorIndex(const char* name) const + { + return GetItemIndex(name, m_cursornames); + } - /** Gets the current state of the given key, true being pressed and false being released */ - bool GetKey(ptrdiff_t index) const { return m_keys[index]; } - /** Gets the current value of the given axis. Devices should cap this value between -1 and 1 as much as possible, through it is not guaranteed */ - float GetAxis(ptrdiff_t index) const { return m_axis[index].m1 * m_axis[index].m2; } - /** Gets the current value of the given cursor, 0,0 being the bottom-left corner and 1,1 being the top-right corner */ - vec2 GetCursor(ptrdiff_t index) const { return m_cursors[index].m1; } - /** Gets the coordinate of the pixel the cursor is currently over, 0,0 being the bottom-left corner. */ - ivec2 GetCursorPixel(ptrdiff_t index) const { return m_cursors[index].m2; } + /** Gets the current state of the given key, true being pressed and + * false being released */ + bool GetKey(ptrdiff_t index) const + { + return m_keys[index]; + } + + /** Gets the current value of the given axis. Devices should try to + * clamp this value between -1 and 1, though it is not guaranteed. */ + float GetAxis(ptrdiff_t index) const + { + return m_axis[index].m1 * m_axis[index].m2; + } + /** Gets the current value of the given cursor, 0,0 being the bottom-left + * corner and 1,1 being the top-right corner */ + vec2 GetCursor(ptrdiff_t index) const + { + return m_cursors[index].m1; + } - /** Sets a per-device-axis sensitivity factor. The value returned by the operating system will be multiplied by this value before being returned by GetAxis */ - void SetAxisSensitivity(ptrdiff_t index, float sensitivity) { m_axis[index].m2 = sensitivity; } - /** Gets the per-device-axis sensitivity factor. The value returned by the operating system will be multiplied by this value before being returned by GetAxis */ - float GetAxisSensitivity(ptrdiff_t index) const { return m_axis[index].m2; } + /** Gets the coordinate of the pixel the cursor is currently over, + * 0,0 being the bottom-left corner. */ + ivec2 GetCursorPixel(ptrdiff_t index) const + { + return m_cursors[index].m2; + } + + /** Sets a per-device-axis sensitivity factor. The value returned by + * the operating system will be multiplied by this value before being + * returned by GetAxis */ + void SetAxisSensitivity(ptrdiff_t index, float sensitivity) + { + m_axis[index].m2 = sensitivity; + } + + /** Gets the per-device-axis sensitivity factor. The value returned by + * the operating system will be multiplied by this value before being + * returned by GetAxis */ + float GetAxisSensitivity(ptrdiff_t index) const + { + return m_axis[index].m2; + } /** Gets a list of the name of all available keys in this device */ - const array& GetAllKeys() const { return m_keynames; } + const array& GetAllKeys() const + { + return m_keynames; + } /** Gets a list of the name of all available axis in this device */ - const array& GetAllAxis() const { return m_axisnames; } + const array& GetAllAxis() const + { + return m_axisnames; + } /** Gets a list of the name of all available cursors in this device */ - const array& GetAllCursors() const { return m_cursornames; } + const array& GetAllCursors() const + { + return m_cursornames; + } /** Gets a list of the name of all available input devices */ static array GetAvailableDevices(); + /** Gets an input device by its name */ - static InputDevice* Get(const char* name) { return GetDevice(name); } + static InputDevice* Get(const char* name) + { + return GetDevice(name); + } + /** Sets whether the mouse cursor should be captured. */ - static void CaptureMouse(bool activated) { m_capturemouse = activated; } + static void CaptureMouse(bool activated) + { + m_capturemouse = activated; + } protected: // TODO: hide all of this in a InputDeviceData? @@ -69,8 +129,10 @@ protected: /** key states (pressed/released) */ array m_keys; + /** axis states (value and sensitivity) */ array m_axis; + /** cursor position */ array m_cursors; @@ -97,11 +159,11 @@ private: static array devices; template - ptrdiff_t GetItemIndex(const char* name, const array& array) const + ptrdiff_t GetItemIndex(const char* name, const array& a) const { - for (ptrdiff_t i = 0; i < array.Count(); ++i) + for (ptrdiff_t i = 0; i < a.Count(); ++i) { - if (array[i] == name) + if (a[i] == name) return i; } return -1; diff --git a/src/input/scancodes.h b/src/input/scancodes.h new file mode 100644 index 00000000..ea4ccdae --- /dev/null +++ b/src/input/scancodes.h @@ -0,0 +1,287 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2013 Benjamin Litzelmann +// (c) 2010-2014 Sam Hocevar +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License) Version 2) as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +/* A list of typical keyboard scancodes, along with a user-friendly + * name and, if possible, a string representation. */ + +#if !defined _SC +# error scancode.h included without the _SC macro +#endif + +_SC(0, "", Unknown) + +/* Usage page 0x07 */ + +_SC(4, "A", A) +_SC(5, "B", B) +_SC(6, "C", C) +_SC(7, "D", D) +_SC(8, "E", E) +_SC(9, "F", F) +_SC(10, "G", G) +_SC(11, "H", H) +_SC(12, "I", I) +_SC(13, "J", J) +_SC(14, "K", K) +_SC(15, "L", L) +_SC(16, "M", M) +_SC(17, "N", N) +_SC(18, "O", O) +_SC(19, "P", P) +_SC(20, "Q", Q) +_SC(21, "R", R) +_SC(22, "S", S) +_SC(23, "T", T) +_SC(24, "U", U) +_SC(25, "V", V) +_SC(26, "W", W) +_SC(27, "X", X) +_SC(28, "Y", Y) +_SC(29, "Z", Z) + +_SC(30, "1", 1) +_SC(31, "2", 2) +_SC(32, "3", 3) +_SC(33, "4", 4) +_SC(34, "5", 5) +_SC(35, "6", 6) +_SC(36, "7", 7) +_SC(37, "8", 8) +_SC(38, "9", 9) +_SC(39, "0", 0) + +_SC(40, "", Return) +_SC(41, "", Escape) +_SC(42, "", Backspace) +_SC(43, "\t", Tab) +_SC(44, " ", Space) + +_SC(45, "-", Minus) +_SC(46, "=", Equals) +_SC(47, "<", LeftBracket) +_SC(48, ">", RightBracket) +_SC(49, "\\", Backslash) + +_SC(50, "", NonUSHash) +_SC(51, ";", Semicolon) +_SC(52, "\'", Apostrophe) +_SC(53, "`", Grave) +_SC(54, ",", Comma) +_SC(55, ".", Period) +_SC(56, "/", Slash) + +_SC(57, "", CapsLock) + +_SC(58, "", F1) +_SC(59, "", F2) +_SC(60, "", F3) +_SC(61, "", F4) +_SC(62, "", F5) +_SC(63, "", F6) +_SC(64, "", F7) +_SC(65, "", F8) +_SC(66, "", F9) +_SC(67, "", F10) +_SC(68, "", F11) +_SC(69, "", F12) + +_SC(70, "", PrintScreen) +_SC(71, "", ScrollLock) +_SC(72, "", Pause) +_SC(73, "", Insert) +_SC(74, "", Home) +_SC(75, "", PageUp) +_SC(76, "", Delete) +_SC(77, "", End) +_SC(78, "", PageDown) +_SC(79, "", Right) +_SC(80, "", Left) +_SC(81, "", Down) +_SC(82, "", Up) + +_SC(83, "", NumLockClear) +_SC(84, "/", KP_Divide) +_SC(85, "*", KP_Multiply) +_SC(86, "-", KP_Minus) +_SC(87, "+", KP_Plus) +_SC(88, "", KP_Enter) +_SC(89, "1", KP_1) +_SC(90, "2", KP_2) +_SC(91, "3", KP_3) +_SC(92, "4", KP_4) +_SC(93, "5", KP_5) +_SC(94, "6", KP_6) +_SC(95, "7", KP_7) +_SC(96, "8", KP_8) +_SC(97, "9", KP_9) +_SC(98, "0", KP_0) +_SC(99, ".", KP_Period) + +_SC(100, "", NonUSBackslash) +_SC(101, "", Application) +_SC(102, "^", Power) +_SC(103, "=", KP_Equals) +_SC(104, "", F13) +_SC(105, "", F14) +_SC(106, "", F15) +_SC(107, "", F16) +_SC(108, "", F17) +_SC(109, "", F18) +_SC(110, "", F19) +_SC(111, "", F20) +_SC(112, "", F21) +_SC(113, "", F22) +_SC(114, "", F23) +_SC(115, "", F24) +_SC(116, "", Execute) +_SC(117, "", Help) +_SC(118, "", Menu) +_SC(119, "", Select) +_SC(120, "", Stop) +_SC(121, "", Again) +_SC(122, "", Undo) +_SC(123, "", Cut) +_SC(124, "", Copy) +_SC(125, "", Paste) +_SC(126, "", Find) +_SC(127, "", Mute) +_SC(128, "", VolumeUp) +_SC(129, "", VolumeDOwn) +_SC(133, "", KP_Comma) +_SC(134, "", KP_EqualsAS400) + +_SC(135, "", International1) +_SC(136, "", International2) +_SC(137, "", International3) +_SC(138, "", International4) +_SC(139, "", International5) +_SC(140, "", International6) +_SC(141, "", International7) +_SC(142, "", International8) +_SC(143, "", International9) +_SC(144, "", Lang1) +_SC(145, "", Lang2) +_SC(146, "", Lang3) +_SC(147, "", Lang4) +_SC(148, "", Lang5) +_SC(149, "", Lang6) +_SC(150, "", Lang7) +_SC(151, "", Lang8) +_SC(152, "", Lang9) + +_SC(153, "", AltErase) +_SC(154, "", SysReq) +_SC(155, "", Cancel) +_SC(156, "", Clear) +_SC(157, "", Prior) +_SC(158, "", Return2) +_SC(159, "", Separator) +_SC(160, "", Out) +_SC(161, "", Oper) +_SC(162, "", ClearAgain) +_SC(163, "", CrSel) +_SC(164, "", ExSel) + +_SC(176, "", KP_00) +_SC(177, "", KP_000) +_SC(178, "", ThousandsSeparator) +_SC(179, "", DecimalSeparator) +_SC(180, "", CurrencyUnit) +_SC(181, "", CurrencySubunit) +_SC(182, "(", KP_LeftParen) +_SC(183, ")", KP_RightParen) +_SC(184, "{", KP_LeftBrace) +_SC(185, "}", KP_RightBrace) +_SC(186, "\t", KP_Tab) +_SC(187, "", KP_Backspace) +_SC(188, "A", KP_A) +_SC(189, "B", KP_B) +_SC(190, "C", KP_C) +_SC(191, "D", KP_D) +_SC(192, "E", KP_E) +_SC(193, "F", KP_F) +_SC(194, "", KP_Xor) +_SC(195, "^", KP_Power) +_SC(196, "%", KP_Percent) +_SC(197, "<", KP_Less) +_SC(198, ">", KP_Greater) +_SC(199, "&", KP_Ampersand) +_SC(200, "&&", KP_DblAmpersand) +_SC(201, "|", KP_VerticalBar) +_SC(202, "||", KP_DblVerticalBar) +_SC(203, ":", KP_Colon) +_SC(204, "#", KP_Hash) +_SC(205, " ", KP_Space) +_SC(206, "@", KP_At) +_SC(207, "!", KP_Exclam) +_SC(208, "", KP_MemStore) +_SC(209, "", KP_MemRecall) +_SC(210, "", KP_MemClear) +_SC(211, "", KP_MemAdd) +_SC(212, "", KP_MemSubtract) +_SC(213, "", KP_MemMultiply) +_SC(214, "", KP_MemDivide) +_SC(215, "", KP_PlusMinus) +_SC(216, "", KP_Clear) +_SC(217, "", KP_ClearEntry) +_SC(218, "", KP_Binary) +_SC(219, "", KP_Octal) +_SC(220, "", KP_Decimal) +_SC(221, "", KP_Hexadecimal) + +_SC(224, "", LCtrl) +_SC(225, "", LShift) +_SC(226, "", LAlt) +_SC(227, "", LGui) +_SC(228, "", RCtrl) +_SC(229, "", RShift) +_SC(230, "", RAlt) +_SC(231, "", RGui) + +_SC(257, "", Mode) + +/* Usage page 0x0c */ + +_SC(258, "", AudioNext) +_SC(259, "", AudioPrev) +_SC(260, "", AudioStop) +_SC(261, "", AudioPlay) +_SC(262, "", AudioMute) +_SC(263, "", MediaSelect) +_SC(264, "", WWW) +_SC(265, "", Mail) +_SC(266, "", Calculator) +_SC(267, "", Computer) +_SC(268, "", AC_Search) +_SC(269, "", AC_Home) +_SC(270, "", AC_Back) +_SC(271, "", AC_Forward) +_SC(272, "", AC_Stop) +_SC(273, "", AC_Refresh) +_SC(274, "", AC_Bookmarks) + +/* Extra SDL scancodes */ + +_SC(275, "", BrightnessDown) +_SC(276, "", BrightnessUp) +_SC(277, "", DisplaySwitch) +_SC(278, "", KbdIllumToggle) +_SC(279, "", KbdIllumDown) +_SC(280, "", KbdIllumUp) +_SC(281, "", Eject) +_SC(282, "", Sleep) + +_SC(283, "", App1) +_SC(284, "", App2) + +#undef _SC + diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj index b1263986..de7b7f94 100644 --- a/src/lolcore.vcxproj +++ b/src/lolcore.vcxproj @@ -285,6 +285,7 @@ + diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters index b56b56e5..beda1076 100644 --- a/src/lolcore.vcxproj.filters +++ b/src/lolcore.vcxproj.filters @@ -738,6 +738,9 @@ input + + input + input diff --git a/src/platform/sdl/sdlinput.cpp b/src/platform/sdl/sdlinput.cpp index 6c7d03c5..b53df474 100644 --- a/src/platform/sdl/sdlinput.cpp +++ b/src/platform/sdl/sdlinput.cpp @@ -281,21 +281,14 @@ void SdlInputData::Tick(float seconds) m_prevmouse = mouse; # if USE_SDL - /* FIXME: the keyboard state now has scancodes rather than - * ASCII representations of characters. */ Uint8 const *sdlstate = SDL_GetKeyboardState(nullptr); - int keyindex = 0; -# define KEY_FUNC(name, index) \ - m_keyboard->SetKey(keyindex++, sdlstate[index] != 0); - /* FIXME: we ignore SDLK_WORLD_0, which means our list of - * keys and SDL's list of keys could be out of sync. */ -# include "input/keys.h" -# undef KEY_FUNC +# define _SC(value, str, name) \ + m_keyboard->SetKey(keyindex++, sdlstate[value] != 0); +# include "input/scancodes.h" # elif USE_OLD_SDL Uint8 *sdlstate = SDL_GetKeyState(nullptr); - int keyindex = 0; # define KEY_FUNC(name, index) \ m_keyboard->SetKey(keyindex++, sdlstate[index] != 0);