From 5c1e6014cc5db0f61d9e2436e62145eb1aaed3ab Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 16 Feb 2015 17:10:03 -0400 Subject: [PATCH] Changed the love.keypressed and love.keyreleased event callbacks to be love.keypressed(key, scancode, isrepeat) and love.keyreleased(key, scancode). Added love.keyboard.isScancodeDown. Resolves issue #993. --HG-- branch : minor --- src/modules/event/sdl/Event.cpp | 32 +++++++++++++++++------ src/modules/keyboard/Keyboard.h | 18 ++++++++++--- src/modules/keyboard/sdl/Keyboard.cpp | 35 +++++++++++++++++++++++--- src/modules/keyboard/sdl/Keyboard.h | 6 ++++- src/modules/keyboard/wrap_Keyboard.cpp | 30 ++++++++++++++++------ src/modules/keyboard/wrap_Keyboard.h | 1 + 6 files changed, 98 insertions(+), 24 deletions(-) diff --git a/src/modules/event/sdl/Event.cpp b/src/modules/event/sdl/Event.cpp index 5367135dc..79f2b9667 100644 --- a/src/modules/event/sdl/Event.cpp +++ b/src/modules/event/sdl/Event.cpp @@ -22,7 +22,7 @@ #include "filesystem/DroppedFile.h" #include "filesystem/Filesystem.h" -#include "keyboard/Keyboard.h" +#include "keyboard/sdl/Keyboard.h" #include "mouse/Mouse.h" #include "joystick/JoystickModule.h" #include "joystick/sdl/Joystick.h" @@ -53,6 +53,7 @@ static void windowToPixelCoords(double *x, double *y) *y = window->toPixels(*y); } +#ifndef LOVE_MACOSX static void normalizedToPixelCoords(double *x, double *y) { window::Window *window = Module::getInstance(Module::M_WINDOW); @@ -66,6 +67,7 @@ static void normalizedToPixelCoords(double *x, double *y) if (y) *y = ((*y) * (double) h); } +#endif const char *Event::getName() const { @@ -128,15 +130,21 @@ Message *Event::convert(const SDL_Event &e) const vargs.reserve(4); love::keyboard::Keyboard *kb = nullptr; - love::touch::sdl::Touch *touchmodule = nullptr; love::filesystem::Filesystem *filesystem = nullptr; - love::keyboard::Keyboard::Key key; + love::keyboard::Keyboard::Key key = love::keyboard::Keyboard::KEY_UNKNOWN; + love::keyboard::Keyboard::Scancode scancode = love::keyboard::Keyboard::SCANCODE_UNKNOWN; love::mouse::Mouse::Button button; - love::touch::Touch::TouchInfo touchinfo; + const char *txt; + const char *txt2; std::map::const_iterator keyit; +#ifndef LOVE_MACOSX + love::touch::sdl::Touch *touchmodule = nullptr; + love::touch::Touch::TouchInfo touchinfo; +#endif + switch (e.type) { case SDL_KEYDOWN: @@ -150,12 +158,16 @@ Message *Event::convert(const SDL_Event &e) const keyit = keys.find(e.key.keysym.sym); if (keyit != keys.end()) key = keyit->second; - else - key = love::keyboard::Keyboard::KEY_UNKNOWN; if (!love::keyboard::Keyboard::getConstant(key, txt)) txt = "unknown"; + + love::keyboard::sdl::Keyboard::getConstant(e.key.keysym.scancode, scancode); + if (!love::keyboard::Keyboard::getConstant(scancode, txt2)) + txt2 = "unknown"; + vargs.push_back(new Variant(txt, strlen(txt))); + vargs.push_back(new Variant(txt2, strlen(txt2))); vargs.push_back(new Variant(e.key.repeat != 0)); msg = new Message("keypressed", vargs); break; @@ -163,12 +175,16 @@ Message *Event::convert(const SDL_Event &e) const keyit = keys.find(e.key.keysym.sym); if (keyit != keys.end()) key = keyit->second; - else - key = love::keyboard::Keyboard::KEY_UNKNOWN; if (!love::keyboard::Keyboard::getConstant(key, txt)) txt = "unknown"; + + love::keyboard::sdl::Keyboard::getConstant(e.key.keysym.scancode, scancode); + if (!love::keyboard::Keyboard::getConstant(scancode, txt2)) + txt2 = "unknown"; + vargs.push_back(new Variant(txt, strlen(txt))); + vargs.push_back(new Variant(txt2, strlen(txt2))); msg = new Message("keyreleased", vargs); break; case SDL_TEXTINPUT: diff --git a/src/modules/keyboard/Keyboard.h b/src/modules/keyboard/Keyboard.h index 80fbed5c8..513bb2dbc 100644 --- a/src/modules/keyboard/Keyboard.h +++ b/src/modules/keyboard/Keyboard.h @@ -25,6 +25,9 @@ #include "common/Module.h" #include "common/StringMap.h" +// C++ +#include + namespace love { namespace keyboard @@ -534,11 +537,18 @@ public: virtual bool hasKeyRepeat() const = 0; /** - * Checks whether certain keys are down or not. - * @param keylist An array of key identifiers, terminated by KEY_MAX_ENUM. - * @return boolean + * Checks whether certain keys are pressed or not. + * @param keylist A list of key identifiers. + * @return Whether any of the specified keys are pressed. **/ - virtual bool isDown(Key *keylist) const = 0; + virtual bool isDown(const std::vector &keylist) const = 0; + + /** + * Checks whether certain scancodes are pressed or not. + * @param scancodelist A list of scancodes. + * @return Whether any of the specified scancodes are pressed. + **/ + virtual bool isScancodeDown(const std::vector &scancodelist) const = 0; /** * Gets the key corresponding to the specified scancode according to the diff --git a/src/modules/keyboard/sdl/Keyboard.cpp b/src/modules/keyboard/sdl/Keyboard.cpp index c19895011..77e4ee296 100644 --- a/src/modules/keyboard/sdl/Keyboard.cpp +++ b/src/modules/keyboard/sdl/Keyboard.cpp @@ -47,14 +47,31 @@ bool Keyboard::hasKeyRepeat() const return key_repeat; } -bool Keyboard::isDown(Key *keylist) const +bool Keyboard::isDown(const std::vector &keylist) const { - const Uint8 *keystate = SDL_GetKeyboardState(nullptr); + const Uint8 *state = SDL_GetKeyboardState(nullptr); - for (Key key = *keylist; key != KEY_MAX_ENUM; key = *(++keylist)) + for (Key key : keylist) { SDL_Scancode scancode = SDL_GetScancodeFromKey(keymap[key]); - if (keystate[scancode]) + if (state[scancode]) + return true; + } + + return false; +} + +bool Keyboard::isScancodeDown(const std::vector &scancodelist) const +{ + const Uint8 *state = SDL_GetKeyboardState(nullptr); + + for (Scancode scancode : scancodelist) + { + SDL_Scancode sdlscancode = SDL_SCANCODE_UNKNOWN; + if (!scancodes.find(scancode, sdlscancode)) + continue; + + if (state[sdlscancode]) return true; } @@ -105,6 +122,16 @@ bool Keyboard::hasTextInput() const return SDL_IsTextInputActive(); } +bool Keyboard::getConstant(Scancode in, SDL_Scancode &out) +{ + return scancodes.find(in, out); +} + +bool Keyboard::getConstant(SDL_Scancode in, Scancode &out) +{ + return scancodes.find(in, out); +} + const SDL_Keycode *Keyboard::createKeyMap() { // Array must be static so its lifetime continues once the function returns. diff --git a/src/modules/keyboard/sdl/Keyboard.h b/src/modules/keyboard/sdl/Keyboard.h index 7f4a83338..9e777f9bd 100644 --- a/src/modules/keyboard/sdl/Keyboard.h +++ b/src/modules/keyboard/sdl/Keyboard.h @@ -46,7 +46,8 @@ public: void setKeyRepeat(bool enable); bool hasKeyRepeat() const; - bool isDown(Key *keylist) const; + bool isDown(const std::vector &keylist) const; + bool isScancodeDown(const std::vector &scancodelist) const; Key getKeyFromScancode(Scancode scancode) const; Scancode getScancodeFromKey(Key key) const; @@ -54,6 +55,9 @@ public: void setTextInput(bool enable); bool hasTextInput() const; + static bool getConstant(Scancode in, SDL_Scancode &out); + static bool getConstant(SDL_Scancode in, Scancode &out); + private: // Whether holding down a key triggers repeated key press events. diff --git a/src/modules/keyboard/wrap_Keyboard.cpp b/src/modules/keyboard/wrap_Keyboard.cpp index a2eb77eb9..3c8e1ed53 100644 --- a/src/modules/keyboard/wrap_Keyboard.cpp +++ b/src/modules/keyboard/wrap_Keyboard.cpp @@ -46,19 +46,34 @@ int w_hasKeyRepeat(lua_State *L) int w_isDown(lua_State *L) { Keyboard::Key k; - unsigned int num = lua_gettop(L); - Keyboard::Key *keylist = new Keyboard::Key[num+1]; - unsigned int counter = 0; + int num = lua_gettop(L); + std::vector keylist; + keylist.reserve(num); - for (unsigned int i = 0; i < num; i++) + for (int i = 0; i < num; i++) { if (Keyboard::getConstant(luaL_checkstring(L, i+1), k)) - keylist[counter++] = k; + keylist.push_back(k); } - keylist[counter] = Keyboard::KEY_MAX_ENUM; luax_pushboolean(L, instance()->isDown(keylist)); - delete[] keylist; + return 1; +} + +int w_isScancodeDown(lua_State *L) +{ + Keyboard::Scancode scancode; + int num = lua_gettop(L); + std::vector scancodelist; + scancodelist.reserve(num); + + for (int i = 0; i < num; i++) + { + if (Keyboard::getConstant(luaL_checkstring(L, i+1), scancode)) + scancodelist.push_back(scancode); + } + + luax_pushboolean(L, instance()->isScancodeDown(scancodelist)); return 1; } @@ -116,6 +131,7 @@ static const luaL_Reg functions[] = { "setTextInput", w_setTextInput }, { "hasTextInput", w_hasTextInput }, { "isDown", w_isDown }, + { "isScancodeDown", w_isScancodeDown }, { "getScancodeFromKey", w_getScancodeFromKey }, { "getKeyFromScancode", w_getKeyFromScancode }, { 0, 0 } diff --git a/src/modules/keyboard/wrap_Keyboard.h b/src/modules/keyboard/wrap_Keyboard.h index 49f5239e7..28657d17d 100644 --- a/src/modules/keyboard/wrap_Keyboard.h +++ b/src/modules/keyboard/wrap_Keyboard.h @@ -33,6 +33,7 @@ namespace keyboard int w_setKeyRepeat(lua_State *L); int w_hasKeyRepeat(lua_State *L); int w_isDown(lua_State *L); +int w_isScancodeDown(lua_State *L); int w_getKeyFromScancode(lua_State *L); int w_getScancodeFromkey(lua_State *L); int w_setTextInput(lua_State *L);