shithub: cstory

Download patch

ref: 39ddfd97911fa42c5e3ebacc5490e0a03cdf207d
parent: c2f6ccdeb6cc2f2a60661da507c201d0f93b9ed8
author: Clownacy <Clownacy@users.noreply.github.com>
date: Sat Apr 4 13:42:56 EDT 2020

Abstract-away keyboard input

Now, instead of keyboard input being completely-handled in the
backend, it's merely abstracted, while still otherwise being handled
in the game itself. This will be useful for the enhanced branch's
key-rebinding menu.

--- a/src/Backends/GLFW3/Misc.cpp
+++ b/src/Backends/GLFW3/Misc.cpp
@@ -4,6 +4,7 @@
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <thread>
 
 #include <GLFW/glfw3.h>
@@ -13,15 +14,31 @@
 #include "../../WindowsWrapper.h"
 
 #include "GLFW3.h"
-#include "../../KeyControl.h"
 #include "../../Main.h"
 #include "../../Organya.h"
 #include "../../Profile.h"
 #include "../../Resource.h"
 
+#define DO_KEY(GLFW_KEY, BACKEND_KEY) \
+	case GLFW_KEY: \
+		switch (action) \
+		{ \
+			case GLFW_PRESS: \
+				backend_keyboard_state[BACKEND_KEY] = TRUE; \
+				break; \
+ \
+			case GLFW_RELEASE: \
+				backend_keyboard_state[BACKEND_KEY] = FALSE; \
+				break; \
+		} \
+ \
+		break;
+
 GLFWwindow *window;
 
 BOOL bActive = TRUE;
+BOOL backend_keyboard_state[BACKEND_KEYBOARD_TOTAL];
+BOOL backend_previous_keyboard_state[BACKEND_KEYBOARD_TOTAL];
 
 static GLFWcursor* cursor;
 
@@ -33,175 +50,91 @@
 
 	switch (action)
 	{
+		case GLFW_RELEASE:
 		case GLFW_PRESS:
 			switch (key)
 			{
-				case GLFW_KEY_ESCAPE:
-					gKey |= KEY_ESCAPE;
-					break;
+				DO_KEY(GLFW_KEY_A, BACKEND_KEYBOARD_A)
+				DO_KEY(GLFW_KEY_B, BACKEND_KEYBOARD_B)
+				DO_KEY(GLFW_KEY_C, BACKEND_KEYBOARD_C)
+				DO_KEY(GLFW_KEY_D, BACKEND_KEYBOARD_D)
+				DO_KEY(GLFW_KEY_E, BACKEND_KEYBOARD_E)
+				DO_KEY(GLFW_KEY_F, BACKEND_KEYBOARD_F)
+				DO_KEY(GLFW_KEY_G, BACKEND_KEYBOARD_G)
+				DO_KEY(GLFW_KEY_H, BACKEND_KEYBOARD_H)
+				DO_KEY(GLFW_KEY_I, BACKEND_KEYBOARD_I)
+				DO_KEY(GLFW_KEY_J, BACKEND_KEYBOARD_J)
+				DO_KEY(GLFW_KEY_K, BACKEND_KEYBOARD_K)
+				DO_KEY(GLFW_KEY_L, BACKEND_KEYBOARD_L)
+				DO_KEY(GLFW_KEY_M, BACKEND_KEYBOARD_M)
+				DO_KEY(GLFW_KEY_N, BACKEND_KEYBOARD_N)
+				DO_KEY(GLFW_KEY_O, BACKEND_KEYBOARD_O)
+				DO_KEY(GLFW_KEY_P, BACKEND_KEYBOARD_P)
+				DO_KEY(GLFW_KEY_Q, BACKEND_KEYBOARD_Q)
+				DO_KEY(GLFW_KEY_R, BACKEND_KEYBOARD_R)
+				DO_KEY(GLFW_KEY_S, BACKEND_KEYBOARD_S)
+				DO_KEY(GLFW_KEY_T, BACKEND_KEYBOARD_T)
+				DO_KEY(GLFW_KEY_U, BACKEND_KEYBOARD_U)
+				DO_KEY(GLFW_KEY_V, BACKEND_KEYBOARD_V)
+				DO_KEY(GLFW_KEY_W, BACKEND_KEYBOARD_W)
+				DO_KEY(GLFW_KEY_X, BACKEND_KEYBOARD_X)
+				DO_KEY(GLFW_KEY_Y, BACKEND_KEYBOARD_Y)
+				DO_KEY(GLFW_KEY_Z, BACKEND_KEYBOARD_Z)
+				DO_KEY(GLFW_KEY_0, BACKEND_KEYBOARD_0)
+				DO_KEY(GLFW_KEY_1, BACKEND_KEYBOARD_1)
+				DO_KEY(GLFW_KEY_2, BACKEND_KEYBOARD_2)
+				DO_KEY(GLFW_KEY_3, BACKEND_KEYBOARD_3)
+				DO_KEY(GLFW_KEY_4, BACKEND_KEYBOARD_4)
+				DO_KEY(GLFW_KEY_5, BACKEND_KEYBOARD_5)
+				DO_KEY(GLFW_KEY_6, BACKEND_KEYBOARD_6)
+				DO_KEY(GLFW_KEY_7, BACKEND_KEYBOARD_7)
+				DO_KEY(GLFW_KEY_8, BACKEND_KEYBOARD_8)
+				DO_KEY(GLFW_KEY_9, BACKEND_KEYBOARD_9)
+				DO_KEY(GLFW_KEY_F1, BACKEND_KEYBOARD_F1)
+				DO_KEY(GLFW_KEY_F2, BACKEND_KEYBOARD_F2)
+				DO_KEY(GLFW_KEY_F3, BACKEND_KEYBOARD_F3)
+				DO_KEY(GLFW_KEY_F4, BACKEND_KEYBOARD_F4)
+				DO_KEY(GLFW_KEY_F5, BACKEND_KEYBOARD_F5)
+				DO_KEY(GLFW_KEY_F6, BACKEND_KEYBOARD_F6)
+				DO_KEY(GLFW_KEY_F7, BACKEND_KEYBOARD_F7)
+				DO_KEY(GLFW_KEY_F8, BACKEND_KEYBOARD_F8)
+				DO_KEY(GLFW_KEY_F9, BACKEND_KEYBOARD_F9)
+				DO_KEY(GLFW_KEY_F10, BACKEND_KEYBOARD_F10)
+				DO_KEY(GLFW_KEY_F11, BACKEND_KEYBOARD_F11)
+				DO_KEY(GLFW_KEY_F12, BACKEND_KEYBOARD_F12)
+				DO_KEY(GLFW_KEY_UP, BACKEND_KEYBOARD_UP)
+				DO_KEY(GLFW_KEY_DOWN, BACKEND_KEYBOARD_DOWN)
+				DO_KEY(GLFW_KEY_LEFT, BACKEND_KEYBOARD_LEFT)
+				DO_KEY(GLFW_KEY_RIGHT, BACKEND_KEYBOARD_RIGHT)
+				DO_KEY(GLFW_KEY_ESCAPE, BACKEND_KEYBOARD_ESCAPE)
+				DO_KEY(GLFW_KEY_GRAVE_ACCENT, BACKEND_KEYBOARD_BACK_QUOTE)
+				DO_KEY(GLFW_KEY_TAB, BACKEND_KEYBOARD_TAB)
+				DO_KEY(GLFW_KEY_CAPS_LOCK, BACKEND_KEYBOARD_CAPS_LOCK)
+				DO_KEY(GLFW_KEY_LEFT_SHIFT, BACKEND_KEYBOARD_LEFT_SHIFT)
+				DO_KEY(GLFW_KEY_LEFT_CONTROL, BACKEND_KEYBOARD_LEFT_CTRL)
+				DO_KEY(GLFW_KEY_LEFT_ALT, BACKEND_KEYBOARD_LEFT_ALT)
+				DO_KEY(GLFW_KEY_SPACE, BACKEND_KEYBOARD_SPACE)
+				DO_KEY(GLFW_KEY_RIGHT_ALT, BACKEND_KEYBOARD_RIGHT_ALT)
+				DO_KEY(GLFW_KEY_RIGHT_CONTROL, BACKEND_KEYBOARD_RIGHT_CTRL)
+				DO_KEY(GLFW_KEY_RIGHT_SHIFT, BACKEND_KEYBOARD_RIGHT_SHIFT)
+				DO_KEY(GLFW_KEY_ENTER, BACKEND_KEYBOARD_ENTER)
+				DO_KEY(GLFW_KEY_BACKSPACE, BACKEND_KEYBOARD_BACKSPACE)
+				DO_KEY(GLFW_KEY_MINUS, BACKEND_KEYBOARD_MINUS)
+				DO_KEY(GLFW_KEY_EQUAL, BACKEND_KEYBOARD_EQUALS)
+				DO_KEY(GLFW_KEY_LEFT_BRACKET, BACKEND_KEYBOARD_LEFT_BRACKET)
+				DO_KEY(GLFW_KEY_RIGHT_BRACKET, BACKEND_KEYBOARD_RIGHT_BRACKET)
+				DO_KEY(GLFW_KEY_BACKSLASH, BACKEND_KEYBOARD_BACK_SLASH)
+				DO_KEY(GLFW_KEY_SEMICOLON, BACKEND_KEYBOARD_SEMICOLON)
+				DO_KEY(GLFW_KEY_APOSTROPHE, BACKEND_KEYBOARD_APOSTROPHE)
+				DO_KEY(GLFW_KEY_COMMA, BACKEND_KEYBOARD_COMMA)
+				DO_KEY(GLFW_KEY_PERIOD, BACKEND_KEYBOARD_PERIOD)
+				DO_KEY(GLFW_KEY_SLASH, BACKEND_KEYBOARD_FORWARD_SLASH)
 
-				case GLFW_KEY_W:
-					gKey |= KEY_MAP;
+				default:
 					break;
-
-				case GLFW_KEY_LEFT:
-					gKey |= KEY_LEFT;
-					break;
-
-				case GLFW_KEY_RIGHT:
-					gKey |= KEY_RIGHT;
-					break;
-
-				case GLFW_KEY_UP:
-					gKey |= KEY_UP;
-					break;
-
-				case GLFW_KEY_DOWN:
-					gKey |= KEY_DOWN;
-					break;
-
-				case GLFW_KEY_X:
-					gKey |= KEY_X;
-					break;
-
-				case GLFW_KEY_Z:
-					gKey |= KEY_Z;
-					break;
-
-				case GLFW_KEY_S:
-					gKey |= KEY_ARMS;
-					break;
-
-				case GLFW_KEY_A:
-					gKey |= KEY_ARMSREV;
-					break;
-
-				case GLFW_KEY_LEFT_SHIFT:
-				case GLFW_KEY_RIGHT_SHIFT:
-					gKey |= KEY_SHIFT;
-					break;
-
-				case GLFW_KEY_F1:
-					gKey |= KEY_F1;
-					break;
-
-				case GLFW_KEY_F2:
-					gKey |= KEY_F2;
-					break;
-
-				case GLFW_KEY_Q:
-					gKey |= KEY_ITEM;
-					break;
-
-				case GLFW_KEY_COMMA:
-					gKey |= KEY_ALT_LEFT;
-					break;
-
-				case GLFW_KEY_PERIOD:
-					gKey |= KEY_ALT_DOWN;
-					break;
-
-				case GLFW_KEY_SLASH:
-					gKey |= KEY_ALT_RIGHT;
-					break;
-
-				case GLFW_KEY_L:
-					gKey |= KEY_L;
-					break;
-
-				case GLFW_KEY_EQUAL:
-					gKey |= KEY_PLUS;
-					break;
-
-				case GLFW_KEY_F5:
-					gbUseJoystick = FALSE;
-					break;
 			}
 
 			break;
-
-		case GLFW_RELEASE:
-			switch (key)
-			{
-				case GLFW_KEY_ESCAPE:
-					gKey &= ~KEY_ESCAPE;
-					break;
-
-				case GLFW_KEY_W:
-					gKey &= ~KEY_MAP;
-					break;
-
-				case GLFW_KEY_LEFT:
-					gKey &= ~KEY_LEFT;
-					break;
-
-				case GLFW_KEY_RIGHT:
-					gKey &= ~KEY_RIGHT;
-					break;
-
-				case GLFW_KEY_UP:
-					gKey &= ~KEY_UP;
-					break;
-
-				case GLFW_KEY_DOWN:
-					gKey &= ~KEY_DOWN;
-					break;
-
-				case GLFW_KEY_X:
-					gKey &= ~KEY_X;
-					break;
-
-				case GLFW_KEY_Z:
-					gKey &= ~KEY_Z;
-					break;
-
-				case GLFW_KEY_S:
-					gKey &= ~KEY_ARMS;
-					break;
-
-				case GLFW_KEY_A:
-					gKey &= ~KEY_ARMSREV;
-					break;
-
-				case GLFW_KEY_LEFT_SHIFT:
-				case GLFW_KEY_RIGHT_SHIFT:
-					gKey &= ~KEY_SHIFT;
-					break;
-
-				case GLFW_KEY_F1:
-					gKey &= ~KEY_F1;
-					break;
-
-				case GLFW_KEY_F2:
-					gKey &= ~KEY_F2;
-					break;
-
-				case GLFW_KEY_Q:
-					gKey &= ~KEY_ITEM;
-					break;
-
-				case GLFW_KEY_COMMA:
-					gKey &= ~KEY_ALT_LEFT;
-					break;
-
-				case GLFW_KEY_PERIOD:
-					gKey &= ~KEY_ALT_DOWN;
-					break;
-
-				case GLFW_KEY_SLASH:
-					gKey &= ~KEY_ALT_RIGHT;
-					break;
-
-				case GLFW_KEY_L:
-					gKey &= ~KEY_L;
-					break;
-
-				case GLFW_KEY_EQUAL:
-					gKey &= ~KEY_PLUS;
-					break;
-			}
-
-			break;
 	}
 }
 
@@ -343,6 +276,8 @@
 		StopOrganyaMusic();
 		return FALSE;
 	}
+
+	memcpy(backend_previous_keyboard_state, backend_keyboard_state, sizeof(backend_keyboard_state));
 
 	glfwPollEvents();
 
--- a/src/Backends/Platform.h
+++ b/src/Backends/Platform.h
@@ -2,7 +2,90 @@
 
 #include "../WindowsWrapper.h"
 
+enum
+{
+	// Based on US QWERTY
+	BACKEND_KEYBOARD_A,
+	BACKEND_KEYBOARD_B,
+	BACKEND_KEYBOARD_C,
+	BACKEND_KEYBOARD_D,
+	BACKEND_KEYBOARD_E,
+	BACKEND_KEYBOARD_F,
+	BACKEND_KEYBOARD_G,
+	BACKEND_KEYBOARD_H,
+	BACKEND_KEYBOARD_I,
+	BACKEND_KEYBOARD_J,
+	BACKEND_KEYBOARD_K,
+	BACKEND_KEYBOARD_L,
+	BACKEND_KEYBOARD_M,
+	BACKEND_KEYBOARD_N,
+	BACKEND_KEYBOARD_O,
+	BACKEND_KEYBOARD_P,
+	BACKEND_KEYBOARD_Q,
+	BACKEND_KEYBOARD_R,
+	BACKEND_KEYBOARD_S,
+	BACKEND_KEYBOARD_T,
+	BACKEND_KEYBOARD_U,
+	BACKEND_KEYBOARD_V,
+	BACKEND_KEYBOARD_W,
+	BACKEND_KEYBOARD_X,
+	BACKEND_KEYBOARD_Y,
+	BACKEND_KEYBOARD_Z,
+	BACKEND_KEYBOARD_0,
+	BACKEND_KEYBOARD_1,
+	BACKEND_KEYBOARD_2,
+	BACKEND_KEYBOARD_3,
+	BACKEND_KEYBOARD_4,
+	BACKEND_KEYBOARD_5,
+	BACKEND_KEYBOARD_6,
+	BACKEND_KEYBOARD_7,
+	BACKEND_KEYBOARD_8,
+	BACKEND_KEYBOARD_9,
+	BACKEND_KEYBOARD_F1,
+	BACKEND_KEYBOARD_F2,
+	BACKEND_KEYBOARD_F3,
+	BACKEND_KEYBOARD_F4,
+	BACKEND_KEYBOARD_F5,
+	BACKEND_KEYBOARD_F6,
+	BACKEND_KEYBOARD_F7,
+	BACKEND_KEYBOARD_F8,
+	BACKEND_KEYBOARD_F9,
+	BACKEND_KEYBOARD_F10,
+	BACKEND_KEYBOARD_F11,
+	BACKEND_KEYBOARD_F12,
+	BACKEND_KEYBOARD_UP,
+	BACKEND_KEYBOARD_DOWN,
+	BACKEND_KEYBOARD_LEFT,
+	BACKEND_KEYBOARD_RIGHT,
+	BACKEND_KEYBOARD_ESCAPE,
+	BACKEND_KEYBOARD_BACK_QUOTE,
+	BACKEND_KEYBOARD_TAB,
+	BACKEND_KEYBOARD_CAPS_LOCK,
+	BACKEND_KEYBOARD_LEFT_SHIFT,
+	BACKEND_KEYBOARD_LEFT_CTRL,
+	BACKEND_KEYBOARD_LEFT_ALT,
+	BACKEND_KEYBOARD_SPACE,
+	BACKEND_KEYBOARD_RIGHT_ALT,
+	BACKEND_KEYBOARD_RIGHT_CTRL,
+	BACKEND_KEYBOARD_RIGHT_SHIFT,
+	BACKEND_KEYBOARD_ENTER,
+	BACKEND_KEYBOARD_BACKSPACE,
+	BACKEND_KEYBOARD_MINUS,
+	BACKEND_KEYBOARD_EQUALS,
+	BACKEND_KEYBOARD_LEFT_BRACKET,
+	BACKEND_KEYBOARD_RIGHT_BRACKET,
+	BACKEND_KEYBOARD_BACK_SLASH,
+	BACKEND_KEYBOARD_SEMICOLON,
+	BACKEND_KEYBOARD_APOSTROPHE,
+	BACKEND_KEYBOARD_COMMA,
+	BACKEND_KEYBOARD_PERIOD,
+	BACKEND_KEYBOARD_FORWARD_SLASH,
+	BACKEND_KEYBOARD_TOTAL
+};
+
 extern BOOL bActive;
+extern BOOL backend_keyboard_state[BACKEND_KEYBOARD_TOTAL];
+extern BOOL backend_previous_keyboard_state[BACKEND_KEYBOARD_TOTAL];
 
 void PlatformBackend_Init(void);
 void PlatformBackend_Deinit(void);
--- a/src/Backends/SDL2/Misc.cpp
+++ b/src/Backends/SDL2/Misc.cpp
@@ -11,15 +11,21 @@
 #include "../../WindowsWrapper.h"
 
 #include "SDL2.h"
-#include "../../KeyControl.h"
 #include "../../Main.h"
 #include "../../Organya.h"
 #include "../../Profile.h"
 #include "../../Resource.h"
 
+#define DO_KEY(SDL_KEY, BACKEND_KEY) \
+	case SDL_KEY: \
+		backend_keyboard_state[BACKEND_KEY] = event.key.type == SDL_KEYDOWN; \
+		break;
+
 SDL_Window *window;
 
 BOOL bActive = TRUE;
+BOOL backend_keyboard_state[BACKEND_KEYBOARD_TOTAL];
+BOOL backend_previous_keyboard_state[BACKEND_KEYBOARD_TOTAL];
 
 static SDL_Surface *cursor_surface;
 static SDL_Cursor *cursor;
@@ -93,6 +99,8 @@
 
 BOOL PlatformBackend_SystemTask(void)
 {
+	memcpy(backend_previous_keyboard_state, backend_keyboard_state, sizeof(backend_keyboard_state));
+
 	while (SDL_PollEvent(NULL) || !bActive)
 	{
 		SDL_Event event;
@@ -102,171 +110,87 @@
 
 		switch (event.type)
 		{
+			case SDL_KEYUP:
 			case SDL_KEYDOWN:
 				switch (event.key.keysym.sym)
 				{
-					case SDLK_ESCAPE:
-						gKey |= KEY_ESCAPE;
-						break;
+					DO_KEY(SDLK_a, BACKEND_KEYBOARD_A)
+					DO_KEY(SDLK_b, BACKEND_KEYBOARD_B)
+					DO_KEY(SDLK_c, BACKEND_KEYBOARD_C)
+					DO_KEY(SDLK_d, BACKEND_KEYBOARD_D)
+					DO_KEY(SDLK_e, BACKEND_KEYBOARD_E)
+					DO_KEY(SDLK_f, BACKEND_KEYBOARD_F)
+					DO_KEY(SDLK_g, BACKEND_KEYBOARD_G)
+					DO_KEY(SDLK_h, BACKEND_KEYBOARD_H)
+					DO_KEY(SDLK_i, BACKEND_KEYBOARD_I)
+					DO_KEY(SDLK_j, BACKEND_KEYBOARD_J)
+					DO_KEY(SDLK_k, BACKEND_KEYBOARD_K)
+					DO_KEY(SDLK_l, BACKEND_KEYBOARD_L)
+					DO_KEY(SDLK_m, BACKEND_KEYBOARD_M)
+					DO_KEY(SDLK_n, BACKEND_KEYBOARD_N)
+					DO_KEY(SDLK_o, BACKEND_KEYBOARD_O)
+					DO_KEY(SDLK_p, BACKEND_KEYBOARD_P)
+					DO_KEY(SDLK_q, BACKEND_KEYBOARD_Q)
+					DO_KEY(SDLK_r, BACKEND_KEYBOARD_R)
+					DO_KEY(SDLK_s, BACKEND_KEYBOARD_S)
+					DO_KEY(SDLK_t, BACKEND_KEYBOARD_T)
+					DO_KEY(SDLK_u, BACKEND_KEYBOARD_U)
+					DO_KEY(SDLK_v, BACKEND_KEYBOARD_V)
+					DO_KEY(SDLK_w, BACKEND_KEYBOARD_W)
+					DO_KEY(SDLK_x, BACKEND_KEYBOARD_X)
+					DO_KEY(SDLK_y, BACKEND_KEYBOARD_Y)
+					DO_KEY(SDLK_z, BACKEND_KEYBOARD_Z)
+					DO_KEY(SDLK_0, BACKEND_KEYBOARD_0)
+					DO_KEY(SDLK_1, BACKEND_KEYBOARD_1)
+					DO_KEY(SDLK_2, BACKEND_KEYBOARD_2)
+					DO_KEY(SDLK_3, BACKEND_KEYBOARD_3)
+					DO_KEY(SDLK_4, BACKEND_KEYBOARD_4)
+					DO_KEY(SDLK_5, BACKEND_KEYBOARD_5)
+					DO_KEY(SDLK_6, BACKEND_KEYBOARD_6)
+					DO_KEY(SDLK_7, BACKEND_KEYBOARD_7)
+					DO_KEY(SDLK_8, BACKEND_KEYBOARD_8)
+					DO_KEY(SDLK_9, BACKEND_KEYBOARD_9)
+					DO_KEY(SDLK_F1, BACKEND_KEYBOARD_F1)
+					DO_KEY(SDLK_F2, BACKEND_KEYBOARD_F2)
+					DO_KEY(SDLK_F3, BACKEND_KEYBOARD_F3)
+					DO_KEY(SDLK_F4, BACKEND_KEYBOARD_F4)
+					DO_KEY(SDLK_F5, BACKEND_KEYBOARD_F5)
+					DO_KEY(SDLK_F6, BACKEND_KEYBOARD_F6)
+					DO_KEY(SDLK_F7, BACKEND_KEYBOARD_F7)
+					DO_KEY(SDLK_F8, BACKEND_KEYBOARD_F8)
+					DO_KEY(SDLK_F9, BACKEND_KEYBOARD_F9)
+					DO_KEY(SDLK_F10, BACKEND_KEYBOARD_F10)
+					DO_KEY(SDLK_F11, BACKEND_KEYBOARD_F11)
+					DO_KEY(SDLK_F12, BACKEND_KEYBOARD_F12)
+					DO_KEY(SDLK_UP, BACKEND_KEYBOARD_UP)
+					DO_KEY(SDLK_DOWN, BACKEND_KEYBOARD_DOWN)
+					DO_KEY(SDLK_LEFT, BACKEND_KEYBOARD_LEFT)
+					DO_KEY(SDLK_RIGHT, BACKEND_KEYBOARD_RIGHT)
+					DO_KEY(SDLK_ESCAPE, BACKEND_KEYBOARD_ESCAPE)
+					DO_KEY(SDLK_BACKQUOTE, BACKEND_KEYBOARD_BACK_QUOTE)
+					DO_KEY(SDLK_TAB, BACKEND_KEYBOARD_TAB)
+					DO_KEY(SDLK_CAPSLOCK, BACKEND_KEYBOARD_CAPS_LOCK)
+					DO_KEY(SDLK_LSHIFT, BACKEND_KEYBOARD_LEFT_SHIFT)
+					DO_KEY(SDLK_LCTRL, BACKEND_KEYBOARD_LEFT_CTRL)
+					DO_KEY(SDLK_LALT, BACKEND_KEYBOARD_LEFT_ALT)
+					DO_KEY(SDLK_SPACE, BACKEND_KEYBOARD_SPACE)
+					DO_KEY(SDLK_RALT, BACKEND_KEYBOARD_RIGHT_ALT)
+					DO_KEY(SDLK_RCTRL, BACKEND_KEYBOARD_RIGHT_CTRL)
+					DO_KEY(SDLK_RSHIFT, BACKEND_KEYBOARD_RIGHT_SHIFT)
+					DO_KEY(SDLK_RETURN, BACKEND_KEYBOARD_ENTER)
+					DO_KEY(SDLK_BACKSPACE, BACKEND_KEYBOARD_BACKSPACE)
+					DO_KEY(SDLK_MINUS, BACKEND_KEYBOARD_MINUS)
+					DO_KEY(SDLK_EQUALS, BACKEND_KEYBOARD_EQUALS)
+					DO_KEY(SDLK_LEFTBRACKET, BACKEND_KEYBOARD_LEFT_BRACKET)
+					DO_KEY(SDLK_RIGHTBRACKET, BACKEND_KEYBOARD_RIGHT_BRACKET)
+					DO_KEY(SDLK_BACKSLASH, BACKEND_KEYBOARD_BACK_SLASH)
+					DO_KEY(SDLK_SEMICOLON, BACKEND_KEYBOARD_SEMICOLON)
+					DO_KEY(SDLK_QUOTE, BACKEND_KEYBOARD_APOSTROPHE)
+					DO_KEY(SDLK_COMMA, BACKEND_KEYBOARD_COMMA)
+					DO_KEY(SDLK_PERIOD, BACKEND_KEYBOARD_PERIOD)
+					DO_KEY(SDLK_SLASH, BACKEND_KEYBOARD_FORWARD_SLASH)
 
-					case SDLK_w:
-						gKey |= KEY_MAP;
-						break;
-
-					case SDLK_LEFT:
-						gKey |= KEY_LEFT;
-						break;
-
-					case SDLK_RIGHT:
-						gKey |= KEY_RIGHT;
-						break;
-
-					case SDLK_UP:
-						gKey |= KEY_UP;
-						break;
-
-					case SDLK_DOWN:
-						gKey |= KEY_DOWN;
-						break;
-
-					case SDLK_x:
-						gKey |= KEY_X;
-						break;
-
-					case SDLK_z:
-						gKey |= KEY_Z;
-						break;
-
-					case SDLK_s:
-						gKey |= KEY_ARMS;
-						break;
-
-					case SDLK_a:
-						gKey |= KEY_ARMSREV;
-						break;
-
-					case SDLK_LSHIFT:
-					case SDLK_RSHIFT:
-						gKey |= KEY_SHIFT;
-						break;
-
-					case SDLK_F1:
-						gKey |= KEY_F1;
-						break;
-
-					case SDLK_F2:
-						gKey |= KEY_F2;
-						break;
-
-					case SDLK_q:
-						gKey |= KEY_ITEM;
-						break;
-
-					case SDLK_COMMA:
-						gKey |= KEY_ALT_LEFT;
-						break;
-
-					case SDLK_PERIOD:
-						gKey |= KEY_ALT_DOWN;
-						break;
-
-					case SDLK_SLASH:
-						gKey |= KEY_ALT_RIGHT;
-						break;
-
-					case SDLK_l:
-						gKey |= KEY_L;
-						break;
-
-					case SDLK_PLUS:
-						gKey |= KEY_PLUS;
-						break;
-
-					case SDLK_F5:
-						gbUseJoystick = FALSE;
-						break;
-				}
-
-				break;
-
-			case SDL_KEYUP:
-				switch (event.key.keysym.sym)
-				{
-					case SDLK_ESCAPE:
-						gKey &= ~KEY_ESCAPE;
-						break;
-
-					case SDLK_w:
-						gKey &= ~KEY_MAP;
-						break;
-
-					case SDLK_LEFT:
-						gKey &= ~KEY_LEFT;
-						break;
-
-					case SDLK_RIGHT:
-						gKey &= ~KEY_RIGHT;
-						break;
-
-					case SDLK_UP:
-						gKey &= ~KEY_UP;
-						break;
-
-					case SDLK_DOWN:
-						gKey &= ~KEY_DOWN;
-						break;
-
-					case SDLK_x:
-						gKey &= ~KEY_X;
-						break;
-
-					case SDLK_z:
-						gKey &= ~KEY_Z;
-						break;
-
-					case SDLK_s:
-						gKey &= ~KEY_ARMS;
-						break;
-
-					case SDLK_a:
-						gKey &= ~KEY_ARMSREV;
-						break;
-
-					case SDLK_LSHIFT:
-					case SDLK_RSHIFT:
-						gKey &= ~KEY_SHIFT;
-						break;
-
-					case SDLK_F1:
-						gKey &= ~KEY_F1;
-						break;
-
-					case SDLK_F2:
-						gKey &= ~KEY_F2;
-						break;
-
-					case SDLK_q:
-						gKey &= ~KEY_ITEM;
-						break;
-
-					case SDLK_COMMA:
-						gKey &= ~KEY_ALT_LEFT;
-						break;
-
-					case SDLK_PERIOD:
-						gKey &= ~KEY_ALT_DOWN;
-						break;
-
-					case SDLK_SLASH:
-						gKey &= ~KEY_ALT_RIGHT;
-						break;
-
-					case SDLK_l:
-						gKey &= ~KEY_L;
-						break;
-
-					case SDLK_PLUS:
-						gKey &= ~KEY_PLUS;
+					default:
 						break;
 				}
 
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -382,6 +382,178 @@
 	if (!PlatformBackend_SystemTask())
 		return FALSE;
 
+	for (unsigned int i = 0; i < BACKEND_KEYBOARD_TOTAL; ++i)
+	{
+		if ((backend_keyboard_state[i] ^ backend_previous_keyboard_state[i]) & backend_keyboard_state[i])
+		{
+			switch (i)
+			{
+				case BACKEND_KEYBOARD_ESCAPE:
+					gKey |= KEY_ESCAPE;
+					break;
+
+				case BACKEND_KEYBOARD_W:
+					gKey |= KEY_MAP;
+					break;
+
+				case BACKEND_KEYBOARD_LEFT:
+					gKey |= KEY_LEFT;
+					break;
+
+				case BACKEND_KEYBOARD_RIGHT:
+					gKey |= KEY_RIGHT;
+					break;
+
+				case BACKEND_KEYBOARD_UP:
+					gKey |= KEY_UP;
+					break;
+
+				case BACKEND_KEYBOARD_DOWN:
+					gKey |= KEY_DOWN;
+					break;
+
+				case BACKEND_KEYBOARD_X:
+					gKey |= KEY_X;
+					break;
+
+				case BACKEND_KEYBOARD_Z:
+					gKey |= KEY_Z;
+					break;
+
+				case BACKEND_KEYBOARD_S:
+					gKey |= KEY_ARMS;
+					break;
+
+				case BACKEND_KEYBOARD_A:
+					gKey |= KEY_ARMSREV;
+					break;
+
+				case BACKEND_KEYBOARD_LEFT_SHIFT:
+				case BACKEND_KEYBOARD_RIGHT_SHIFT:
+					gKey |= KEY_SHIFT;
+					break;
+
+				case BACKEND_KEYBOARD_F1:
+					gKey |= KEY_F1;
+					break;
+
+				case BACKEND_KEYBOARD_F2:
+					gKey |= KEY_F2;
+					break;
+
+				case BACKEND_KEYBOARD_Q:
+					gKey |= KEY_ITEM;
+					break;
+
+				case BACKEND_KEYBOARD_COMMA:
+					gKey |= KEY_ALT_LEFT;
+					break;
+
+				case BACKEND_KEYBOARD_PERIOD:
+					gKey |= KEY_ALT_DOWN;
+					break;
+
+				case BACKEND_KEYBOARD_FORWARD_SLASH:
+					gKey |= KEY_ALT_RIGHT;
+					break;
+
+				case BACKEND_KEYBOARD_L:
+					gKey |= KEY_L;
+					break;
+
+				case BACKEND_KEYBOARD_EQUALS:
+					gKey |= KEY_PLUS;
+					break;
+
+				case BACKEND_KEYBOARD_F5:
+					gbUseJoystick = FALSE;
+					break;
+			}
+		}
+		else if ((backend_keyboard_state[i] ^ backend_previous_keyboard_state[i]) & backend_previous_keyboard_state[i])
+		{
+			switch (i)
+			{
+				case BACKEND_KEYBOARD_ESCAPE:
+					gKey &= ~KEY_ESCAPE;
+					break;
+
+				case BACKEND_KEYBOARD_W:
+					gKey &= ~KEY_MAP;
+					break;
+
+				case BACKEND_KEYBOARD_LEFT:
+					gKey &= ~KEY_LEFT;
+					break;
+
+				case BACKEND_KEYBOARD_RIGHT:
+					gKey &= ~KEY_RIGHT;
+					break;
+
+				case BACKEND_KEYBOARD_UP:
+					gKey &= ~KEY_UP;
+					break;
+
+				case BACKEND_KEYBOARD_DOWN:
+					gKey &= ~KEY_DOWN;
+					break;
+
+				case BACKEND_KEYBOARD_X:
+					gKey &= ~KEY_X;
+					break;
+
+				case BACKEND_KEYBOARD_Z:
+					gKey &= ~KEY_Z;
+					break;
+
+				case BACKEND_KEYBOARD_S:
+					gKey &= ~KEY_ARMS;
+					break;
+
+				case BACKEND_KEYBOARD_A:
+					gKey &= ~KEY_ARMSREV;
+					break;
+
+				case BACKEND_KEYBOARD_LEFT_SHIFT:
+				case BACKEND_KEYBOARD_RIGHT_SHIFT:
+					gKey &= ~KEY_SHIFT;
+					break;
+
+				case BACKEND_KEYBOARD_F1:
+					gKey &= ~KEY_F1;
+					break;
+
+				case BACKEND_KEYBOARD_F2:
+					gKey &= ~KEY_F2;
+					break;
+
+				case BACKEND_KEYBOARD_Q:
+					gKey &= ~KEY_ITEM;
+					break;
+
+				case BACKEND_KEYBOARD_COMMA:
+					gKey &= ~KEY_ALT_LEFT;
+					break;
+
+				case BACKEND_KEYBOARD_PERIOD:
+					gKey &= ~KEY_ALT_DOWN;
+					break;
+
+				case BACKEND_KEYBOARD_FORWARD_SLASH:
+					gKey &= ~KEY_ALT_RIGHT;
+					break;
+
+				case BACKEND_KEYBOARD_L:
+					gKey &= ~KEY_L;
+					break;
+
+				case BACKEND_KEYBOARD_EQUALS:
+					gKey &= ~KEY_PLUS;
+					break;
+			}
+		}
+	}
+
 	// Run joystick code
 	if (gbUseJoystick)
 		JoystickProc();