Browse Source

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
Alex Szpakowski 10 years ago
parent
commit
5c1e6014cc

+ 24 - 8
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<window::Window>(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<SDL_Keycode, love::keyboard::Keyboard::Key>::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:

+ 14 - 4
src/modules/keyboard/Keyboard.h

@@ -25,6 +25,9 @@
 #include "common/Module.h"
 #include "common/StringMap.h"
 
+// C++
+#include <vector>
+
 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(const std::vector<Key> &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 isDown(Key *keylist) const = 0;
+	virtual bool isScancodeDown(const std::vector<Scancode> &scancodelist) const = 0;
 
 	/**
 	 * Gets the key corresponding to the specified scancode according to the

+ 31 - 4
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<Key> &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<Scancode> &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.

+ 5 - 1
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<Key> &keylist) const;
+	bool isScancodeDown(const std::vector<Scancode> &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.

+ 23 - 7
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<Keyboard::Key> 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<Keyboard::Scancode> 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 }

+ 1 - 0
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);