shithub: cstory

Download patch

ref: 40464a9fc096a106c2be1819810e92cbd1eca160
parent: ee7cf6799bbdfa9ec811aaeb87e2f1f2e90b7190
author: Clownacy <[email protected]>
date: Fri Apr 3 10:41:16 EDT 2020

Move-around Backend files

Hoping to introduce some degree of grouping

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -326,22 +326,22 @@
 endif()
 
 if(BACKEND_PLATFORM MATCHES "SDL2")
-	target_sources(CSE2 PRIVATE "src/Backends/Platform/SDL2.cpp" "src/Backends/Controller/SDL2.cpp")
+	target_sources(CSE2 PRIVATE "src/Backends/SDL2/Controller.cpp" "src/Backends/SDL2/Misc.cpp" "src/Backends/SDL2/SDL2.h")
 elseif(BACKEND_PLATFORM MATCHES "GLFW3")
-	target_sources(CSE2 PRIVATE "src/Backends/Platform/GLFW3.cpp" "src/Backends/Controller/GLFW3.cpp")
+	target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Controller.cpp" "src/Backends/GLFW3/Misc.cpp" "src/Backends/GLFW3/GLFW3.h")
 endif()
 
 if(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "OpenGL3")
-	target_sources(CSE2 PRIVATE "src/Backends/Window/SDL2-OpenGL3.cpp")
+	target_sources(CSE2 PRIVATE "src/Backends/SDL2/Window-OpenGL3.cpp")
 elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "OpenGLES2")
-	target_sources(CSE2 PRIVATE "src/Backends/Window/SDL2-OpenGLES2.cpp")
+	target_sources(CSE2 PRIVATE "src/Backends/SDL2/Window-OpenGLES2.cpp")
 elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "SDLTexture")
 elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "SDLSurface")
 elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "Software")
 elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "OpenGL3")
-	target_sources(CSE2 PRIVATE "src/Backends/Window/GLFW3-OpenGL3.cpp")
+	target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-OpenGL3.cpp")
 elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "OpenGLES2")
-	target_sources(CSE2 PRIVATE "src/Backends/Window/GLFW3-OpenGLES2.cpp")
+	target_sources(CSE2 PRIVATE "src/Backends/GLFW3/Window-OpenGLES2.cpp")
 else()
 	message(FATAL_ERROR "Invalid BACKEND_PLATFORM/BACKEND_RENDERER combination")
 endif()
--- a/src/Backends/Controller/GLFW3.cpp
+++ /dev/null
@@ -1,25 +1,0 @@
-#include "../Controller.h"
-
-#include "../../WindowsWrapper.h"
-
-void ControllerBackend_Deinit(void)
-{
-	
-}
-
-BOOL ControllerBackend_Init(void)
-{
-	return FALSE;
-}
-
-BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
-{
-	(void)status;
-
-	return FALSE;
-}
-
-BOOL ControllerBackend_ResetJoystickStatus(void)
-{
-	return FALSE;
-}
--- a/src/Backends/Controller/SDL2.cpp
+++ /dev/null
@@ -1,116 +1,0 @@
-#include "../Controller.h"
-
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "SDL.h"
-
-#include "../../WindowsWrapper.h"
-
-// The original names for these variables are unknown
-static SDL_Joystick *joystick = NULL;
-static int joystick_neutral_x = 0;
-static int joystick_neutral_y = 0;
-
-void ControllerBackend_Deinit(void)
-{
-	// Close opened joystick (if exists)
-	if (joystick != NULL)
-	{
-		SDL_JoystickClose(joystick);
-		joystick = NULL;
-	}
-
-	SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-}
-
-// It looks like Pixel declared his functions early, so he could forward-reference
-BOOL FindAndOpenDirectInputDevice(void);
-
-BOOL ControllerBackend_Init(void)
-{
-	SDL_InitSubSystem(SDL_INIT_JOYSTICK);
-
-	if (!FindAndOpenDirectInputDevice())
-		return FALSE;
-
-	return TRUE;
-}
-
-// The original name for this function and its variables are unknown.
-// This function finds and hooks the first available DirectInput device (or SDL Joystick, in this case).
-BOOL FindAndOpenDirectInputDevice(void)
-{
-	int i;
-
-	for (i = 0; i < SDL_NumJoysticks(); ++i)
-		printf("Joystick #%d name: %s\n", i, SDL_JoystickNameForIndex(i));
-
-	// Open first available joystick
-	for (i = 0; i < SDL_NumJoysticks(); ++i)
-	{
-		joystick = SDL_JoystickOpen(i);
-
-		// Break as soon as a joystick is properly opened
-		if (joystick != NULL)
-			return TRUE;
-	}
-
-	return FALSE;
-}
-
-BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
-{
-	if (joystick == NULL)
-		return FALSE;
-
-	// The original Input.cpp assumed there were 32 buttons (because of DirectInput's 'DIJOYSTATE' struct)
-	int numButtons = SDL_JoystickNumButtons(joystick);
-	if (numButtons > 32)
-		numButtons = 32;
-
-	// Read whatever buttons actually exist
-	int i = 0;
-	for (; i < numButtons; ++i)
-	{
-		if (SDL_JoystickGetButton(joystick, i) != 0)
-			status->bButton[i] = TRUE;
-		else
-			status->bButton[i] = FALSE;
-	}
-
-	// Blank the buttons that do not
-	for (; i < 32; ++i)
-		status->bButton[i] = FALSE;
-
-	status->bDown = FALSE;
-	status->bRight = FALSE;
-	status->bUp = FALSE;
-	status->bLeft = FALSE;
-
-	const Sint16 joystick_x = SDL_JoystickGetAxis(joystick, 0);
-	if (joystick_x < joystick_neutral_x - 10000)
-		status->bLeft = TRUE;
-	else if (joystick_x > joystick_neutral_x + 10000)
-		status->bRight = TRUE;
-
-	const Sint16 joystick_y = SDL_JoystickGetAxis(joystick, 1);
-	if (joystick_y < joystick_neutral_y - 10000)
-		status->bUp = TRUE;
-	else if (joystick_y > joystick_neutral_y + 10000)
-		status->bDown = TRUE;
-
-	return TRUE;
-}
-
-BOOL ControllerBackend_ResetJoystickStatus(void)
-{
-	if (joystick == NULL)
-		return FALSE;
-
-	joystick_neutral_x = SDL_JoystickGetAxis(joystick, 0);
-	joystick_neutral_y = SDL_JoystickGetAxis(joystick, 1);
-
-	return TRUE;
-}
--- /dev/null
+++ b/src/Backends/GLFW3/Controller.cpp
@@ -1,0 +1,25 @@
+#include "../Controller.h"
+
+#include "../../WindowsWrapper.h"
+
+void ControllerBackend_Deinit(void)
+{
+	
+}
+
+BOOL ControllerBackend_Init(void)
+{
+	return FALSE;
+}
+
+BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
+{
+	(void)status;
+
+	return FALSE;
+}
+
+BOOL ControllerBackend_ResetJoystickStatus(void)
+{
+	return FALSE;
+}
--- /dev/null
+++ b/src/Backends/GLFW3/GLFW3.h
@@ -1,0 +1,7 @@
+#pragma once
+
+#define GLFW_INCLUDE_NONE
+#include <GLFW/glfw3.h>
+#undef GLFW_INCLUDE_NONE
+
+extern GLFWwindow *window;
--- /dev/null
+++ b/src/Backends/GLFW3/Misc.cpp
@@ -1,0 +1,370 @@
+#include "../Platform.h"
+
+#include <chrono>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <thread>
+
+#include <GLFW/glfw3.h>
+
+#include "../Rendering.h"
+
+#include "../../WindowsWrapper.h"
+
+#include "GLFW3.h"
+#include "../../KeyControl.h"
+#include "../../Main.h"
+#include "../../Organya.h"
+#include "../../Profile.h"
+#include "../../Resource.h"
+
+GLFWwindow *window;
+
+BOOL bActive = TRUE;
+
+static GLFWcursor* cursor;
+
+static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
+{
+	(void)window;
+	(void)scancode;
+	(void)mods;
+
+	switch (action)
+	{
+		case GLFW_PRESS:
+			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;
+
+				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;
+	}
+}
+
+static void WindowFocusCallback(GLFWwindow *window, int focused)
+{
+	(void)window;
+
+	if (focused)
+		ActiveWindow();
+	else
+		InactiveWindow();
+}
+
+static void WindowSizeCallback(GLFWwindow *window, int width, int height)
+{
+	(void)window;
+
+	Backend_HandleWindowResize(width, height);
+}
+
+static void DragAndDropCallback(GLFWwindow *window, int count, const char **paths)
+{
+	(void)window;
+	(void)count;
+
+	LoadProfile(paths[0]);
+}
+
+void PlatformBackend_Init(void)
+{
+	glfwInit();
+}
+
+void PlatformBackend_Deinit(void)
+{
+	if (cursor != NULL)
+		glfwDestroyCursor(cursor);
+
+	glfwTerminate();
+}
+
+void PlatformBackend_PostWindowCreation(void)
+{
+	// Hook callbacks
+	glfwSetKeyCallback(window, KeyCallback);
+	glfwSetWindowFocusCallback(window, WindowFocusCallback);
+	glfwSetWindowSizeCallback(window, WindowSizeCallback);
+}
+
+BOOL PlatformBackend_GetBasePath(char *string_buffer)
+{
+	(void)string_buffer;
+
+	// GLFW3 doesn't seem to have a mechanism for this
+	return FALSE;
+}
+
+void PlatformBackend_HideMouse(void)
+{
+	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+}
+
+void PlatformBackend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+	// Convert to RGBA, since that's the only think GLFW3 accepts
+	unsigned char *rgba_pixels = (unsigned char*)malloc(width * height * 4);
+
+	const unsigned char *rgb_pointer = rgb_pixels;
+	unsigned char *rgba_pointer = rgba_pixels;
+
+	if (rgba_pixels != NULL)
+	{
+		for (unsigned int y = 0; y < height; ++y)
+		{
+			for (unsigned int x = 0; x < width; ++x)
+			{
+				*rgba_pointer++ = *rgb_pointer++;
+				*rgba_pointer++ = *rgb_pointer++;
+				*rgba_pointer++ = *rgb_pointer++;
+				*rgba_pointer++ = 0xFF;
+			}
+		}
+
+		GLFWimage glfw_image = {(int)width, (int)height, rgba_pixels};
+		glfwSetWindowIcon(window, 1, &glfw_image);
+
+		free(rgba_pixels);
+	}
+}
+
+void PlatformBackend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+	// Convert to RGBA, since that's the only think GLFW3 accepts
+	unsigned char *rgba_pixels = (unsigned char*)malloc(width * height * 4);
+
+	const unsigned char *rgb_pointer = rgb_pixels;
+	unsigned char *rgba_pointer = rgba_pixels;
+
+	if (rgba_pixels != NULL)
+	{
+		for (unsigned int y = 0; y < height; ++y)
+		{
+			for (unsigned int x = 0; x < width; ++x)
+			{
+				if (rgb_pointer[0] == 0xFF && rgb_pointer[1] == 0 && rgb_pointer[2] == 0xFF)	// Colour-key
+				{
+					*rgba_pointer++ = *rgb_pointer++;
+					*rgba_pointer++ = *rgb_pointer++;
+					*rgba_pointer++ = *rgb_pointer++;
+					*rgba_pointer++ = 0;
+				}
+				else
+				{
+					*rgba_pointer++ = *rgb_pointer++;
+					*rgba_pointer++ = *rgb_pointer++;
+					*rgba_pointer++ = *rgb_pointer++;
+					*rgba_pointer++ = 0xFF;
+				}
+			}
+		}
+
+		GLFWimage glfw_image = {(int)width, (int)height, rgba_pixels};
+		cursor = glfwCreateCursor(&glfw_image, 0, 0);
+		glfwSetCursor(window, cursor);
+
+		free(rgba_pixels);
+	}
+}
+
+void PlaybackBackend_EnableDragAndDrop(void)
+{
+	glfwSetDropCallback(window, DragAndDropCallback);
+}
+
+BOOL PlatformBackend_SystemTask(void)
+{
+	if (glfwWindowShouldClose(window))
+	{
+		StopOrganyaMusic();
+		return FALSE;
+	}
+
+	glfwPollEvents();
+
+	while (!bActive)
+		glfwWaitEvents();
+
+	return TRUE;
+}
+
+void PlatformBackend_ShowMessageBox(const char *title, const char *message)
+{
+	// GLFW3 doesn't have a message box
+	printf("ShowMessageBox - '%s' - '%s'\n", title, message);
+}
+
+unsigned long PlatformBackend_GetTicks(void)
+{
+	return (unsigned long)(glfwGetTime() * 1000.0);
+}
+
+void PlatformBackend_Delay(unsigned int ticks)
+{
+	// GLFW3 doesn't have a delay function, so here's some butt-ugly C++11
+	std::this_thread::sleep_for(std::chrono::milliseconds(ticks));
+}
--- /dev/null
+++ b/src/Backends/GLFW3/Window-OpenGL3.cpp
@@ -1,0 +1,94 @@
+#include "../Window-OpenGL.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#ifdef USE_OPENGLES2
+#include <GLES2/gl2.h>
+#else
+#include "../../../external/glad/include/glad/glad.h"
+#endif
+#include <GLFW/glfw3.h>
+
+#include "../../WindowsWrapper.h"
+
+#include "../Platform.h"
+#include "GLFW3.h"
+
+BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen)
+{
+#ifdef USE_OPENGLES2
+	glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
+#else
+	glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
+	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
+#endif
+
+	GLFWmonitor *monitor = NULL;
+
+	if (fullscreen)
+	{
+		monitor = glfwGetPrimaryMonitor();
+
+		if (monitor != NULL)
+		{
+			const GLFWvidmode *mode = glfwGetVideoMode(monitor);
+
+			*screen_width = mode->width;
+			*screen_height = mode->height;
+		}
+	}
+
+	window = glfwCreateWindow(*screen_width, *screen_height, window_title, monitor, NULL);
+
+	if (window != NULL)
+	{
+		glfwMakeContextCurrent(window);
+
+			#ifndef USE_OPENGLES2
+				if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
+				{
+					// Check if the platform supports OpenGL 3.2
+					if (GLAD_GL_VERSION_3_2)
+					{
+			#endif
+						PlatformBackend_PostWindowCreation();
+
+						return TRUE;
+			#ifndef USE_OPENGLES2
+					}
+					else
+					{
+						PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
+					}
+				}
+				else
+				{
+					PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not load OpenGL functions");
+				}
+			#endif
+
+		glfwDestroyWindow(window);
+	}
+	else
+	{
+		PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
+	}
+
+	return FALSE;
+}
+
+void WindowBackend_OpenGL_DestroyWindow(void)
+{
+	glfwDestroyWindow(window);
+}
+
+void WindowBackend_OpenGL_Display(void)
+{
+	glfwSwapBuffers(window);
+}
--- /dev/null
+++ b/src/Backends/GLFW3/Window-OpenGLES2.cpp
@@ -1,0 +1,2 @@
+#define USE_OPENGLES2
+#include "GLFW3-OpenGL3.cpp"
--- a/src/Backends/Platform/GLFW3.cpp
+++ /dev/null
@@ -1,369 +1,0 @@
-#include "../Platform.h"
-
-#include <chrono>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <thread>
-
-#include <GLFW/glfw3.h>
-
-#include "../Rendering.h"
-
-#include "../../WindowsWrapper.h"
-
-#include "../../KeyControl.h"
-#include "../../Main.h"
-#include "../../Organya.h"
-#include "../../Profile.h"
-#include "../../Resource.h"
-
-GLFWwindow *window;
-
-BOOL bActive = TRUE;
-
-static GLFWcursor* cursor;
-
-static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
-{
-	(void)window;
-	(void)scancode;
-	(void)mods;
-
-	switch (action)
-	{
-		case GLFW_PRESS:
-			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;
-
-				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;
-	}
-}
-
-static void WindowFocusCallback(GLFWwindow *window, int focused)
-{
-	(void)window;
-
-	if (focused)
-		ActiveWindow();
-	else
-		InactiveWindow();
-}
-
-static void WindowSizeCallback(GLFWwindow *window, int width, int height)
-{
-	(void)window;
-
-	Backend_HandleWindowResize(width, height);
-}
-
-static void DragAndDropCallback(GLFWwindow *window, int count, const char **paths)
-{
-	(void)window;
-	(void)count;
-
-	LoadProfile(paths[0]);
-}
-
-void PlatformBackend_Init(void)
-{
-	glfwInit();
-}
-
-void PlatformBackend_Deinit(void)
-{
-	if (cursor != NULL)
-		glfwDestroyCursor(cursor);
-
-	glfwTerminate();
-}
-
-void PlatformBackend_PostWindowCreation(void)
-{
-	// Hook callbacks
-	glfwSetKeyCallback(window, KeyCallback);
-	glfwSetWindowFocusCallback(window, WindowFocusCallback);
-	glfwSetWindowSizeCallback(window, WindowSizeCallback);
-}
-
-BOOL PlatformBackend_GetBasePath(char *string_buffer)
-{
-	(void)string_buffer;
-
-	// GLFW3 doesn't seem to have a mechanism for this
-	return FALSE;
-}
-
-void PlatformBackend_HideMouse(void)
-{
-	glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
-}
-
-void PlatformBackend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
-{
-	// Convert to RGBA, since that's the only think GLFW3 accepts
-	unsigned char *rgba_pixels = (unsigned char*)malloc(width * height * 4);
-
-	const unsigned char *rgb_pointer = rgb_pixels;
-	unsigned char *rgba_pointer = rgba_pixels;
-
-	if (rgba_pixels != NULL)
-	{
-		for (unsigned int y = 0; y < height; ++y)
-		{
-			for (unsigned int x = 0; x < width; ++x)
-			{
-				*rgba_pointer++ = *rgb_pointer++;
-				*rgba_pointer++ = *rgb_pointer++;
-				*rgba_pointer++ = *rgb_pointer++;
-				*rgba_pointer++ = 0xFF;
-			}
-		}
-
-		GLFWimage glfw_image = {(int)width, (int)height, rgba_pixels};
-		glfwSetWindowIcon(window, 1, &glfw_image);
-
-		free(rgba_pixels);
-	}
-}
-
-void PlatformBackend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
-{
-	// Convert to RGBA, since that's the only think GLFW3 accepts
-	unsigned char *rgba_pixels = (unsigned char*)malloc(width * height * 4);
-
-	const unsigned char *rgb_pointer = rgb_pixels;
-	unsigned char *rgba_pointer = rgba_pixels;
-
-	if (rgba_pixels != NULL)
-	{
-		for (unsigned int y = 0; y < height; ++y)
-		{
-			for (unsigned int x = 0; x < width; ++x)
-			{
-				if (rgb_pointer[0] == 0xFF && rgb_pointer[1] == 0 && rgb_pointer[2] == 0xFF)	// Colour-key
-				{
-					*rgba_pointer++ = *rgb_pointer++;
-					*rgba_pointer++ = *rgb_pointer++;
-					*rgba_pointer++ = *rgb_pointer++;
-					*rgba_pointer++ = 0;
-				}
-				else
-				{
-					*rgba_pointer++ = *rgb_pointer++;
-					*rgba_pointer++ = *rgb_pointer++;
-					*rgba_pointer++ = *rgb_pointer++;
-					*rgba_pointer++ = 0xFF;
-				}
-			}
-		}
-
-		GLFWimage glfw_image = {(int)width, (int)height, rgba_pixels};
-		cursor = glfwCreateCursor(&glfw_image, 0, 0);
-		glfwSetCursor(window, cursor);
-
-		free(rgba_pixels);
-	}
-}
-
-void PlaybackBackend_EnableDragAndDrop(void)
-{
-	glfwSetDropCallback(window, DragAndDropCallback);
-}
-
-BOOL PlatformBackend_SystemTask(void)
-{
-	if (glfwWindowShouldClose(window))
-	{
-		StopOrganyaMusic();
-		return FALSE;
-	}
-
-	glfwPollEvents();
-
-	while (!bActive)
-		glfwWaitEvents();
-
-	return TRUE;
-}
-
-void PlatformBackend_ShowMessageBox(const char *title, const char *message)
-{
-	// GLFW3 doesn't have a message box
-	printf("ShowMessageBox - '%s' - '%s'\n", title, message);
-}
-
-unsigned long PlatformBackend_GetTicks(void)
-{
-	return (unsigned long)(glfwGetTime() * 1000.0);
-}
-
-void PlatformBackend_Delay(unsigned int ticks)
-{
-	// GLFW3 doesn't have a delay function, so here's some butt-ugly C++11
-	std::this_thread::sleep_for(std::chrono::milliseconds(ticks));
-}
--- a/src/Backends/Platform/SDL2.cpp
+++ /dev/null
@@ -1,325 +1,0 @@
-#include "../Platform.h"
-
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "SDL.h"
-
-#include "../Rendering.h"
-
-#include "../../WindowsWrapper.h"
-
-#include "../../KeyControl.h"
-#include "../../Main.h"
-#include "../../Organya.h"
-#include "../../Profile.h"
-#include "../../Resource.h"
-
-SDL_Window *window;
-
-BOOL bActive = TRUE;
-
-static SDL_Surface *cursor_surface;
-static SDL_Cursor *cursor;
-
-void PlatformBackend_Init(void)
-{
-	SDL_Init(SDL_INIT_EVENTS);
-
-	SDL_InitSubSystem(SDL_INIT_VIDEO);
-
-	puts("Available SDL2 video drivers:");
-
-	for (int i = 0; i < SDL_GetNumVideoDrivers(); ++i)
-		puts(SDL_GetVideoDriver(i));
-
-	printf("Selected SDL2 video driver: %s\n", SDL_GetCurrentVideoDriver());
-}
-
-void PlatformBackend_Deinit(void)
-{
-	if (cursor != NULL)
-		SDL_FreeCursor(cursor);
-
-	if (cursor_surface != NULL)
-		SDL_FreeSurface(cursor_surface);
-
-	SDL_Quit();
-}
-
-void PlatformBackend_PostWindowCreation(void)
-{
-	
-}
-
-BOOL PlatformBackend_GetBasePath(char *string_buffer)
-{
-	char *base_path = SDL_GetBasePath();
-	// Trim the trailing '/'
-	size_t base_path_length = strlen(base_path);
-	base_path[base_path_length - 1] = '\0';
-	strcpy(string_buffer, base_path);
-	SDL_free(base_path);
-
-	return TRUE;
-}
-
-void PlatformBackend_HideMouse(void)
-{
-	SDL_ShowCursor(SDL_DISABLE);
-}
-
-void PlatformBackend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
-{
-	SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom((void*)rgb_pixels, width, height, 0, width * 3, SDL_PIXELFORMAT_RGB24);
-	SDL_SetWindowIcon(window, surface);
-	SDL_FreeSurface(surface);
-}
-
-void PlatformBackend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
-{
-	cursor_surface = SDL_CreateRGBSurfaceWithFormatFrom((void*)rgb_pixels, width, height, 0, width * 3, SDL_PIXELFORMAT_RGB24);
-	SDL_SetColorKey(cursor_surface, SDL_TRUE, SDL_MapRGB(cursor_surface->format, 0xFF, 0, 0xFF));
-	cursor = SDL_CreateColorCursor(cursor_surface, 0, 0);
-	SDL_SetCursor(cursor);
-}
-
-void PlaybackBackend_EnableDragAndDrop(void)
-{
-	SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
-}
-
-BOOL PlatformBackend_SystemTask(void)
-{
-	while (SDL_PollEvent(NULL) || !bActive)
-	{
-		SDL_Event event;
-
-		if (!SDL_WaitEvent(&event))
-			return FALSE;
-
-		switch (event.type)
-		{
-			case SDL_KEYDOWN:
-				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;
-						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;
-						break;
-				}
-
-				break;
-
-			case SDL_DROPFILE:
-				LoadProfile(event.drop.file);
-				SDL_free(event.drop.file);
-				break;
-
-			case SDL_WINDOWEVENT:
-				switch (event.window.event)
-				{
-					case SDL_WINDOWEVENT_FOCUS_LOST:
-						InactiveWindow();
-						break;
-
-					case SDL_WINDOWEVENT_FOCUS_GAINED:
-						ActiveWindow();
-						break;
-
-					case SDL_WINDOWEVENT_RESIZED:
-					case SDL_WINDOWEVENT_SIZE_CHANGED:
-						Backend_HandleWindowResize(event.window.data1, event.window.data2);
-						break;
-				}
-
-				break;
-
-			case SDL_QUIT:
-				StopOrganyaMusic();
-				return FALSE;
-
-			case SDL_RENDER_TARGETS_RESET:
-				Backend_HandleRenderTargetLoss();
-				break;
-
-		}
-	}
-
-	return TRUE;
-}
-
-void PlatformBackend_ShowMessageBox(const char *title, const char *message)
-{
-	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, window);
-}
-
-unsigned long PlatformBackend_GetTicks(void)
-{
-	return SDL_GetTicks();
-}
-
-void PlatformBackend_Delay(unsigned int ticks)
-{
-	SDL_Delay(ticks);
-}
--- a/src/Backends/Rendering/OpenGL3.cpp
+++ b/src/Backends/Rendering/OpenGL3.cpp
@@ -19,7 +19,7 @@
 #include "../../WindowsWrapper.h"
 
 #include "../Platform.h"
-#include "../Window.h"
+#include "../Window-OpenGL.h"
 #include "../../Resource.h"
 
 #define TOTAL_VBOS 8
--- /dev/null
+++ b/src/Backends/SDL2/Controller.cpp
@@ -1,0 +1,116 @@
+#include "../Controller.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "SDL.h"
+
+#include "../../WindowsWrapper.h"
+
+// The original names for these variables are unknown
+static SDL_Joystick *joystick = NULL;
+static int joystick_neutral_x = 0;
+static int joystick_neutral_y = 0;
+
+void ControllerBackend_Deinit(void)
+{
+	// Close opened joystick (if exists)
+	if (joystick != NULL)
+	{
+		SDL_JoystickClose(joystick);
+		joystick = NULL;
+	}
+
+	SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+}
+
+// It looks like Pixel declared his functions early, so he could forward-reference
+BOOL FindAndOpenDirectInputDevice(void);
+
+BOOL ControllerBackend_Init(void)
+{
+	SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+
+	if (!FindAndOpenDirectInputDevice())
+		return FALSE;
+
+	return TRUE;
+}
+
+// The original name for this function and its variables are unknown.
+// This function finds and hooks the first available DirectInput device (or SDL Joystick, in this case).
+BOOL FindAndOpenDirectInputDevice(void)
+{
+	int i;
+
+	for (i = 0; i < SDL_NumJoysticks(); ++i)
+		printf("Joystick #%d name: %s\n", i, SDL_JoystickNameForIndex(i));
+
+	// Open first available joystick
+	for (i = 0; i < SDL_NumJoysticks(); ++i)
+	{
+		joystick = SDL_JoystickOpen(i);
+
+		// Break as soon as a joystick is properly opened
+		if (joystick != NULL)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+BOOL ControllerBackend_GetJoystickStatus(JOYSTICK_STATUS *status)
+{
+	if (joystick == NULL)
+		return FALSE;
+
+	// The original Input.cpp assumed there were 32 buttons (because of DirectInput's 'DIJOYSTATE' struct)
+	int numButtons = SDL_JoystickNumButtons(joystick);
+	if (numButtons > 32)
+		numButtons = 32;
+
+	// Read whatever buttons actually exist
+	int i = 0;
+	for (; i < numButtons; ++i)
+	{
+		if (SDL_JoystickGetButton(joystick, i) != 0)
+			status->bButton[i] = TRUE;
+		else
+			status->bButton[i] = FALSE;
+	}
+
+	// Blank the buttons that do not
+	for (; i < 32; ++i)
+		status->bButton[i] = FALSE;
+
+	status->bDown = FALSE;
+	status->bRight = FALSE;
+	status->bUp = FALSE;
+	status->bLeft = FALSE;
+
+	const Sint16 joystick_x = SDL_JoystickGetAxis(joystick, 0);
+	if (joystick_x < joystick_neutral_x - 10000)
+		status->bLeft = TRUE;
+	else if (joystick_x > joystick_neutral_x + 10000)
+		status->bRight = TRUE;
+
+	const Sint16 joystick_y = SDL_JoystickGetAxis(joystick, 1);
+	if (joystick_y < joystick_neutral_y - 10000)
+		status->bUp = TRUE;
+	else if (joystick_y > joystick_neutral_y + 10000)
+		status->bDown = TRUE;
+
+	return TRUE;
+}
+
+BOOL ControllerBackend_ResetJoystickStatus(void)
+{
+	if (joystick == NULL)
+		return FALSE;
+
+	joystick_neutral_x = SDL_JoystickGetAxis(joystick, 0);
+	joystick_neutral_y = SDL_JoystickGetAxis(joystick, 1);
+
+	return TRUE;
+}
--- /dev/null
+++ b/src/Backends/SDL2/Misc.cpp
@@ -1,0 +1,326 @@
+#include "../Platform.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "SDL.h"
+
+#include "../Rendering.h"
+
+#include "../../WindowsWrapper.h"
+
+#include "../SDL2.h"
+#include "../../KeyControl.h"
+#include "../../Main.h"
+#include "../../Organya.h"
+#include "../../Profile.h"
+#include "../../Resource.h"
+
+SDL_Window *window;
+
+BOOL bActive = TRUE;
+
+static SDL_Surface *cursor_surface;
+static SDL_Cursor *cursor;
+
+void PlatformBackend_Init(void)
+{
+	SDL_Init(SDL_INIT_EVENTS);
+
+	SDL_InitSubSystem(SDL_INIT_VIDEO);
+
+	puts("Available SDL2 video drivers:");
+
+	for (int i = 0; i < SDL_GetNumVideoDrivers(); ++i)
+		puts(SDL_GetVideoDriver(i));
+
+	printf("Selected SDL2 video driver: %s\n", SDL_GetCurrentVideoDriver());
+}
+
+void PlatformBackend_Deinit(void)
+{
+	if (cursor != NULL)
+		SDL_FreeCursor(cursor);
+
+	if (cursor_surface != NULL)
+		SDL_FreeSurface(cursor_surface);
+
+	SDL_Quit();
+}
+
+void PlatformBackend_PostWindowCreation(void)
+{
+	
+}
+
+BOOL PlatformBackend_GetBasePath(char *string_buffer)
+{
+	char *base_path = SDL_GetBasePath();
+	// Trim the trailing '/'
+	size_t base_path_length = strlen(base_path);
+	base_path[base_path_length - 1] = '\0';
+	strcpy(string_buffer, base_path);
+	SDL_free(base_path);
+
+	return TRUE;
+}
+
+void PlatformBackend_HideMouse(void)
+{
+	SDL_ShowCursor(SDL_DISABLE);
+}
+
+void PlatformBackend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+	SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormatFrom((void*)rgb_pixels, width, height, 0, width * 3, SDL_PIXELFORMAT_RGB24);
+	SDL_SetWindowIcon(window, surface);
+	SDL_FreeSurface(surface);
+}
+
+void PlatformBackend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+	cursor_surface = SDL_CreateRGBSurfaceWithFormatFrom((void*)rgb_pixels, width, height, 0, width * 3, SDL_PIXELFORMAT_RGB24);
+	SDL_SetColorKey(cursor_surface, SDL_TRUE, SDL_MapRGB(cursor_surface->format, 0xFF, 0, 0xFF));
+	cursor = SDL_CreateColorCursor(cursor_surface, 0, 0);
+	SDL_SetCursor(cursor);
+}
+
+void PlaybackBackend_EnableDragAndDrop(void)
+{
+	SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
+}
+
+BOOL PlatformBackend_SystemTask(void)
+{
+	while (SDL_PollEvent(NULL) || !bActive)
+	{
+		SDL_Event event;
+
+		if (!SDL_WaitEvent(&event))
+			return FALSE;
+
+		switch (event.type)
+		{
+			case SDL_KEYDOWN:
+				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;
+						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;
+						break;
+				}
+
+				break;
+
+			case SDL_DROPFILE:
+				LoadProfile(event.drop.file);
+				SDL_free(event.drop.file);
+				break;
+
+			case SDL_WINDOWEVENT:
+				switch (event.window.event)
+				{
+					case SDL_WINDOWEVENT_FOCUS_LOST:
+						InactiveWindow();
+						break;
+
+					case SDL_WINDOWEVENT_FOCUS_GAINED:
+						ActiveWindow();
+						break;
+
+					case SDL_WINDOWEVENT_RESIZED:
+					case SDL_WINDOWEVENT_SIZE_CHANGED:
+						Backend_HandleWindowResize(event.window.data1, event.window.data2);
+						break;
+				}
+
+				break;
+
+			case SDL_QUIT:
+				StopOrganyaMusic();
+				return FALSE;
+
+			case SDL_RENDER_TARGETS_RESET:
+				Backend_HandleRenderTargetLoss();
+				break;
+
+		}
+	}
+
+	return TRUE;
+}
+
+void PlatformBackend_ShowMessageBox(const char *title, const char *message)
+{
+	SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, message, window);
+}
+
+unsigned long PlatformBackend_GetTicks(void)
+{
+	return SDL_GetTicks();
+}
+
+void PlatformBackend_Delay(unsigned int ticks)
+{
+	SDL_Delay(ticks);
+}
--- /dev/null
+++ b/src/Backends/SDL2/SDL2.h
@@ -1,0 +1,5 @@
+#pragma once
+
+#include "SDL.h"
+
+extern SDL_Window *window;
--- /dev/null
+++ b/src/Backends/SDL2/Window-OpenGL3.cpp
@@ -1,0 +1,98 @@
+#include "../Window-OpenGL.h"
+
+#include <stddef.h>
+
+#ifdef USE_OPENGLES2
+#include <GLES2/gl2.h>
+#else
+#include "../../../external/glad/include/glad/glad.h"
+#endif
+#include "SDL.h"
+
+#include "../../WindowsWrapper.h"
+
+#include "../Platform.h"
+#include "../SDL2.h"
+#include "../../Resource.h"
+
+static SDL_GLContext context;
+
+BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen)
+{
+#ifdef USE_OPENGLES2
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+#else
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
+	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
+#endif
+
+	window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, *screen_width, *screen_height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | (fullscreen ? SDL_WINDOW_FULLSCREEN : 0));
+
+	if (window != NULL)
+	{
+		context = SDL_GL_CreateContext(window);
+
+		if (context != NULL)
+		{
+			if (SDL_GL_MakeCurrent(window, context) == 0)
+			{
+			#ifndef USE_OPENGLES2
+				if (gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
+				{
+					// Check if the platform supports OpenGL 3.2
+					if (GLAD_GL_VERSION_3_2)
+					{
+			#endif
+						PlatformBackend_PostWindowCreation();
+
+						return TRUE;
+			#ifndef USE_OPENGLES2
+					}
+					else
+					{
+						PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
+					}
+				}
+				else
+				{
+					PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not load OpenGL functions");
+				}
+			#endif
+			}
+			else
+			{
+				PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "SDL_GL_MakeCurrent failed");
+			}
+
+			SDL_GL_DeleteContext(context);
+		}
+		else
+		{
+			PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create OpenGL context");
+		}
+
+		SDL_DestroyWindow(window);
+	}
+	else
+	{
+		PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
+	}
+
+	return FALSE;
+}
+
+void WindowBackend_OpenGL_DestroyWindow(void)
+{
+	SDL_GL_DeleteContext(context);
+	SDL_DestroyWindow(window);
+}
+
+void WindowBackend_OpenGL_Display(void)
+{
+	SDL_GL_SwapWindow(window);
+}
--- /dev/null
+++ b/src/Backends/SDL2/Window-OpenGLES2.cpp
@@ -1,0 +1,2 @@
+#define USE_OPENGLES2
+#include "SDL2-OpenGL3.cpp"
--- /dev/null
+++ b/src/Backends/Window-OpenGL.h
@@ -1,0 +1,7 @@
+#pragma once
+
+#include "../WindowsWrapper.h"
+
+BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen);
+void WindowBackend_OpenGL_DestroyWindow(void);
+void WindowBackend_OpenGL_Display(void);
--- a/src/Backends/Window.h
+++ /dev/null
@@ -1,7 +1,0 @@
-#pragma once
-
-#include "../WindowsWrapper.h"
-
-BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen);
-void WindowBackend_OpenGL_DestroyWindow(void);
-void WindowBackend_OpenGL_Display(void);
--- a/src/Backends/Window/GLFW3-OpenGL3.cpp
+++ /dev/null
@@ -1,96 +1,0 @@
-#include "../Window.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#ifdef USE_OPENGLES2
-#include <GLES2/gl2.h>
-#else
-#include "../../../external/glad/include/glad/glad.h"
-#endif
-#include <GLFW/glfw3.h>
-
-#include "../../WindowsWrapper.h"
-
-#include "../Platform.h"
-
-// Horrible hack
-extern GLFWwindow *window;
-
-BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen)
-{
-#ifdef USE_OPENGLES2
-	glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
-#else
-	glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
-	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
-	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
-#endif
-
-	GLFWmonitor *monitor = NULL;
-
-	if (fullscreen)
-	{
-		monitor = glfwGetPrimaryMonitor();
-
-		if (monitor != NULL)
-		{
-			const GLFWvidmode *mode = glfwGetVideoMode(monitor);
-
-			*screen_width = mode->width;
-			*screen_height = mode->height;
-		}
-	}
-
-	window = glfwCreateWindow(*screen_width, *screen_height, window_title, monitor, NULL);
-
-	if (window != NULL)
-	{
-		glfwMakeContextCurrent(window);
-
-			#ifndef USE_OPENGLES2
-				if (gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
-				{
-					// Check if the platform supports OpenGL 3.2
-					if (GLAD_GL_VERSION_3_2)
-					{
-			#endif
-						PlatformBackend_PostWindowCreation();
-
-						return TRUE;
-			#ifndef USE_OPENGLES2
-					}
-					else
-					{
-						PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
-					}
-				}
-				else
-				{
-					PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not load OpenGL functions");
-				}
-			#endif
-
-		glfwDestroyWindow(window);
-	}
-	else
-	{
-		PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
-	}
-
-	return FALSE;
-}
-
-void WindowBackend_OpenGL_DestroyWindow(void)
-{
-	glfwDestroyWindow(window);
-}
-
-void WindowBackend_OpenGL_Display(void)
-{
-	glfwSwapBuffers(window);
-}
--- a/src/Backends/Window/GLFW3-OpenGLES2.cpp
+++ /dev/null
@@ -1,2 +1,0 @@
-#define USE_OPENGLES2
-#include "GLFW3-OpenGL3.cpp"
--- a/src/Backends/Window/SDL2-OpenGL3.cpp
+++ /dev/null
@@ -1,99 +1,0 @@
-#include "../Window.h"
-
-#include <stddef.h>
-
-#ifdef USE_OPENGLES2
-#include <GLES2/gl2.h>
-#else
-#include "../../../external/glad/include/glad/glad.h"
-#endif
-#include "SDL.h"
-
-#include "../../WindowsWrapper.h"
-
-#include "../Platform.h"
-#include "../../Resource.h"
-
-extern SDL_Window *window;
-
-static SDL_GLContext context;
-
-BOOL WindowBackend_OpenGL_CreateWindow(const char *window_title, int *screen_width, int *screen_height, BOOL fullscreen)
-{
-#ifdef USE_OPENGLES2
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
-#else
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
-	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
-#endif
-
-	window = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, *screen_width, *screen_height, SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | (fullscreen ? SDL_WINDOW_FULLSCREEN : 0));
-
-	if (window != NULL)
-	{
-		context = SDL_GL_CreateContext(window);
-
-		if (context != NULL)
-		{
-			if (SDL_GL_MakeCurrent(window, context) == 0)
-			{
-			#ifndef USE_OPENGLES2
-				if (gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
-				{
-					// Check if the platform supports OpenGL 3.2
-					if (GLAD_GL_VERSION_3_2)
-					{
-			#endif
-						PlatformBackend_PostWindowCreation();
-
-						return TRUE;
-			#ifndef USE_OPENGLES2
-					}
-					else
-					{
-						PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Your system does not support OpenGL 3.2");
-					}
-				}
-				else
-				{
-					PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not load OpenGL functions");
-				}
-			#endif
-			}
-			else
-			{
-				PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "SDL_GL_MakeCurrent failed");
-			}
-
-			SDL_GL_DeleteContext(context);
-		}
-		else
-		{
-			PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create OpenGL context");
-		}
-
-		SDL_DestroyWindow(window);
-	}
-	else
-	{
-		PlatformBackend_ShowMessageBox("Fatal error (OpenGL rendering backend)", "Could not create window");
-	}
-
-	return FALSE;
-}
-
-void WindowBackend_OpenGL_DestroyWindow(void)
-{
-	SDL_GL_DeleteContext(context);
-	SDL_DestroyWindow(window);
-}
-
-void WindowBackend_OpenGL_Display(void)
-{
-	SDL_GL_SwapWindow(window);
-}
--- a/src/Backends/Window/SDL2-OpenGLES2.cpp
+++ /dev/null
@@ -1,2 +1,0 @@
-#define USE_OPENGLES2
-#include "SDL2-OpenGL3.cpp"