shithub: cstory

Download patch

ref: cf8789f8879dc2e6ade1a273088a4b861de5ef86
parent: 79ec91c85156980bb4ec7d652c21ae6d233015c5
author: Cameron Cawley <ccawley2011@gmail.com>
date: Mon May 11 19:30:44 EDT 2020

Initial SDL 1.2 backend

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,7 +26,7 @@
 
 set(BACKEND_RENDERER "SDLTexture" CACHE STRING "Which renderer the game should use: 'OpenGL3' for an OpenGL 3.2 renderer, 'OpenGLES2' for an OpenGL ES 2.0 renderer, 'SDLTexture' for SDL2's hardware-accelerated Texture API, 'SDLSurface' for SDL2's software-rendered Surface API, 'Wii U' for the Wii U's hardware-accelerated GX2 API, '3DS' for the 3DS's hardware accelerated Citro2D/Citro3D API, or 'Software' for a handwritten software renderer")
 set(BACKEND_AUDIO "SDL2" CACHE STRING "Which audio backend the game should use: 'SDL2', 'miniaudio', 'WiiU-Hardware', 'WiiU-Software', '3DS-Hardware', '3DS-Software', or 'Null'")
-set(BACKEND_PLATFORM "SDL2" CACHE STRING "Which platform backend the game should use: 'SDL2', 'GLFW3', 'WiiU', '3DS', or 'Null'")
+set(BACKEND_PLATFORM "SDL2" CACHE STRING "Which platform backend the game should use: 'SDL2', 'SDL1', 'GLFW3', 'WiiU', '3DS', or 'Null'")
 
 option(LTO "Enable link-time optimisation" OFF)
 option(PKG_CONFIG_STATIC_LIBS "On platforms with pkg-config, static-link the dependencies (good for Windows builds, so you don't need to bundle DLL files)" OFF)
@@ -393,10 +393,15 @@
 
 if(BACKEND_PLATFORM MATCHES "SDL2")
 	target_sources(CSE2 PRIVATE
-		"src/Backends/Controller/SDL2.cpp"
+		"src/Backends/Controller/SDL.cpp"
 		"src/Backends/Platform/SDL2.cpp"
 		"src/Backends/Shared/SDL2.h"
 	)
+elseif(BACKEND_PLATFORM MATCHES "SDL1")
+	target_sources(CSE2 PRIVATE
+		"src/Backends/Controller/SDL.cpp"
+		"src/Backends/Platform/SDL1.cpp"
+	)
 elseif(BACKEND_PLATFORM MATCHES "GLFW3")
 	target_sources(CSE2 PRIVATE
 		"src/Backends/Controller/GLFW3.cpp"
@@ -428,6 +433,8 @@
 elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "SDLSurface")
 elseif(BACKEND_PLATFORM MATCHES "SDL2" AND BACKEND_RENDERER MATCHES "Software")
 	target_sources(CSE2 PRIVATE "src/Backends/Rendering/Window/Software/SDL2.cpp")
+elseif(BACKEND_PLATFORM MATCHES "SDL1" AND BACKEND_RENDERER MATCHES "Software")
+	target_sources(CSE2 PRIVATE "src/Backends/Rendering/Window/Software/SDL1.cpp")
 elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "OpenGL3")
 	target_sources(CSE2 PRIVATE "src/Backends/Rendering/Window/OpenGL3/GLFW3.cpp")
 elseif(BACKEND_PLATFORM MATCHES "GLFW3" AND BACKEND_RENDERER MATCHES "OpenGLES2")
@@ -596,6 +603,41 @@
 		endif()
 		add_subdirectory("external/SDL2" EXCLUDE_FROM_ALL)
 		target_link_libraries(CSE2 PRIVATE SDL2-static)
+	endif()
+endif()
+
+if(BACKEND_PLATFORM MATCHES "SDL1")
+	find_package(SDL 1.2.15)
+
+	if (PKG_CONFIG_FOUND)
+		pkg_check_modules(sdl QUIET IMPORTED_TARGET sdl)
+	endif()
+
+	if(TARGET PkgConfig::sdl)
+		# pkg-config
+		if (PKG_CONFIG_STATIC_LIBS)
+			message(STATUS "Using system SDL1 (pkg-config, static)")
+			# Do not link libSDLmain.a, otherwise we get weird linker errors about SDL_main not being found.
+			# We don't need SDL's WinMain->main shim anyway, so we can just ignore it.
+			list(REMOVE_ITEM sdl_STATIC_CFLAGS "-Dmain=SDL_main")
+			list(REMOVE_ITEM sdl_STATIC_LDFLAGS "-lSDLmain")
+			target_compile_options(CSE2 PRIVATE ${sdl_STATIC_CFLAGS})
+			target_link_libraries(CSE2 PRIVATE ${sdl_STATIC_LDFLAGS})
+		else()
+			message(STATUS "Using system SDL1 (pkg-config, dynamic)")
+			# Do not link libSDLmain.a, otherwise we get weird linker errors about SDL_main not being found.
+			# We don't need SDL's WinMain->main shim anyway, so we can just ignore it.
+			list(REMOVE_ITEM sdl_CFLAGS "-Dmain=SDL_main")
+			list(REMOVE_ITEM sdl_LDFLAGS "-lSDLmain")
+			target_compile_options(CSE2 PRIVATE ${sdl_CFLAGS})
+			target_link_libraries(CSE2 PRIVATE ${sdl_LDFLAGS})
+		endif()
+	elseif(SDL_FOUND)
+		message(STATUS "Using system SDL1 (CMake)")
+		target_include_directories(CSE2 PRIVATE ${SDL_INCLUDE_DIR})
+		target_link_libraries(CSE2 PRIVATE ${SDL_LIBRARY})
+	else()
+		message(FATAL_ERROR "SDL1 not installed!")
 	endif()
 endif()
 
--- /dev/null
+++ b/src/Backends/Controller/SDL.cpp
@@ -1,0 +1,205 @@
+#include "../Controller.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include "SDL.h"
+
+#include "../Misc.h"
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+#include "../Shared/SDL2.h"
+#endif
+
+#define DEADZONE 10000
+
+static SDL_Joystick *joystick;
+
+static Sint16 *axis_neutrals;
+
+bool ControllerBackend_Init(void)
+{
+	if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
+	{
+		Backend_PrintError("Couldn't initialise joystick SDL subsystem: %s", SDL_GetError());
+		return false;
+	}
+
+	return true;
+}
+
+void ControllerBackend_Deinit(void)
+{
+	if (joystick != NULL)
+	{
+		SDL_JoystickClose(joystick);
+		joystick = NULL;
+	}
+
+	SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+}
+
+bool ControllerBackend_GetJoystickStatus(bool **buttons, unsigned int *button_count, short **axes, unsigned int *axis_count)
+{
+	if (joystick == NULL)
+		return false;
+
+	int total_sdl_buttons = SDL_JoystickNumButtons(joystick);
+	if (total_sdl_buttons < 0)
+	{
+		total_sdl_buttons = 0;
+		Backend_PrintError("Failed to get number of buttons on joystick: %s", SDL_GetError());
+	}
+
+	int total_sdl_axes = SDL_JoystickNumAxes(joystick);
+	if (total_sdl_axes < 0)
+	{
+		total_sdl_axes = 0;
+		Backend_PrintError("Failed to get number of general axis controls on joystick: %s", SDL_GetError());
+	}
+
+	int total_sdl_hats = SDL_JoystickNumHats(joystick);
+	if (total_sdl_hats < 0)
+	{
+		total_sdl_hats = 0;
+		Backend_PrintError("Failed to get number of POV hats on joystick: %s", SDL_GetError());
+	}
+
+	*button_count = total_sdl_buttons + total_sdl_axes * 2 + total_sdl_hats * 4;
+	*axis_count = total_sdl_axes;
+
+	static bool *button_buffer = NULL;
+	static short *axis_buffer = NULL;
+
+	bool *new_button_buffer = (bool*)realloc(button_buffer, *button_count * sizeof(bool));
+
+	if (new_button_buffer == NULL)
+		return false;
+
+	button_buffer = new_button_buffer;
+
+	short *new_axis_buffer = (short*)realloc(axis_buffer, *axis_count * sizeof(short));
+
+	if (new_axis_buffer == NULL)
+		return false;
+
+	axis_buffer = new_axis_buffer;
+
+	//////////////////////////
+	// Handle button inputs //
+	//////////////////////////
+
+	unsigned int current_button = 0;
+
+	// Start with the joystick buttons
+	for (int i = 0; i < total_sdl_buttons; ++i)
+		button_buffer[current_button++] = SDL_JoystickGetButton(joystick, i);
+
+	// Then the joystick axes
+	for (int i = 0; i < total_sdl_axes; ++i)
+	{
+		Sint16 axis = SDL_JoystickGetAxis(joystick, i);
+
+		button_buffer[current_button++] = axis < axis_neutrals[i] - DEADZONE;
+		button_buffer[current_button++] = axis > axis_neutrals[i] + DEADZONE;
+	}
+
+	// Then the joystick hats
+	for (int i = 0; i < total_sdl_hats; ++i)
+	{
+		Uint8 hat = SDL_JoystickGetHat(joystick, i);
+
+		button_buffer[current_button++] = hat == SDL_HAT_UP || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_RIGHTUP;
+		button_buffer[current_button++] = hat == SDL_HAT_RIGHT || hat == SDL_HAT_RIGHTUP || hat == SDL_HAT_RIGHTDOWN;
+		button_buffer[current_button++] = hat == SDL_HAT_DOWN || hat == SDL_HAT_LEFTDOWN || hat == SDL_HAT_RIGHTDOWN;
+		button_buffer[current_button++] = hat == SDL_HAT_LEFT || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_LEFTDOWN;
+	}
+
+	*buttons = button_buffer;
+
+	////////////////////////
+	// Handle axis inputs //
+	////////////////////////
+
+	for (int i = 0; i < total_sdl_axes; ++i)
+		axis_buffer[i] = SDL_JoystickGetAxis(joystick, i);
+
+	*axes = axis_buffer;
+
+	return true;
+}
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+void ControllerBackend_JoystickConnect(Sint32 joystick_id)
+{
+	const char *joystick_name = SDL_JoystickNameForIndex(joystick_id);
+
+	if (joystick_name != NULL)
+	{
+		Backend_PrintInfo("Joystick #%d connected - %s", joystick_id, joystick_name);
+	}
+	else
+	{
+		Backend_PrintError("Couldn't get joystick name: %s", SDL_GetError());
+		Backend_PrintInfo("Joystick #%d connected - Name unknown", joystick_id);
+	}
+
+	if (joystick == NULL)
+	{
+		joystick = SDL_JoystickOpen(joystick_id);
+
+		if (joystick != NULL)
+		{
+			int total_axes = SDL_JoystickNumAxes(joystick);
+			if (total_axes < 0)
+				Backend_PrintError("Couldn't get number of general axis control on connected joystick: %s", SDL_GetError());
+
+			int total_buttons = SDL_JoystickNumButtons(joystick);
+			if (total_buttons < 0)
+				Backend_PrintError("Couldn't get number of buttons on connected joystick: %s", SDL_GetError());
+
+			if (total_axes >= 2 && total_buttons >= 6)
+			{
+				Backend_PrintInfo("Joystick #%d selected", joystick_id);
+
+				// Set up neutral axes
+				axis_neutrals = (Sint16*)malloc(sizeof(Sint16) * total_axes);
+
+				if (axis_neutrals != NULL)
+				{
+					for (int i = 0; i < total_axes; ++i)
+						axis_neutrals[i] = SDL_JoystickGetAxis(joystick, i);
+
+					return;
+				}
+				else
+				{
+					Backend_PrintError("Couldn't allocate memory for neutral axes");
+				}
+			}
+
+			SDL_JoystickClose(joystick);
+			joystick = NULL;
+		}
+		else
+		{
+			Backend_PrintError("Couldn't open joystick for use: %s", SDL_GetError());
+		}
+	}
+}
+
+void ControllerBackend_JoystickDisconnect(Sint32 joystick_id)
+{
+	SDL_JoystickID current_joystick_id = SDL_JoystickInstanceID(joystick);
+	if (current_joystick_id < 0)
+		Backend_PrintError("Couldn't get instance ID for current joystick: %s", SDL_GetError());
+
+	if (joystick_id == current_joystick_id)
+	{
+		Backend_PrintInfo("Joystick #%d disconnected", joystick_id);
+		SDL_JoystickClose(joystick);
+		joystick = NULL;
+
+		free(axis_neutrals);
+	}
+}
+#endif
--- a/src/Backends/Controller/SDL2.cpp
+++ /dev/null
@@ -1,201 +1,0 @@
-#include "../Controller.h"
-
-#include <stddef.h>
-#include <stdlib.h>
-
-#include "SDL.h"
-
-#include "../Misc.h"
-#include "../Shared/SDL2.h"
-
-#define DEADZONE 10000
-
-static SDL_Joystick *joystick;
-
-static Sint16 *axis_neutrals;
-
-bool ControllerBackend_Init(void)
-{
-	if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
-	{
-		Backend_PrintError("Couldn't initialise joystick SDL subsystem: %s", SDL_GetError());
-		return false;
-	}
-
-	return true;
-}
-
-void ControllerBackend_Deinit(void)
-{
-	if (joystick != NULL)
-	{
-		SDL_JoystickClose(joystick);
-		joystick = NULL;
-	}
-
-	SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
-}
-
-bool ControllerBackend_GetJoystickStatus(bool **buttons, unsigned int *button_count, short **axes, unsigned int *axis_count)
-{
-	if (joystick == NULL)
-		return false;
-
-	int total_sdl_buttons = SDL_JoystickNumButtons(joystick);
-	if (total_sdl_buttons < 0)
-	{
-		total_sdl_buttons = 0;
-		Backend_PrintError("Failed to get number of buttons on joystick: %s", SDL_GetError());
-	}
-
-	int total_sdl_axes = SDL_JoystickNumAxes(joystick);
-	if (total_sdl_axes < 0)
-	{
-		total_sdl_axes = 0;
-		Backend_PrintError("Failed to get number of general axis controls on joystick: %s", SDL_GetError());
-	}
-
-	int total_sdl_hats = SDL_JoystickNumHats(joystick);
-	if (total_sdl_hats < 0)
-	{
-		total_sdl_hats = 0;
-		Backend_PrintError("Failed to get number of POV hats on joystick: %s", SDL_GetError());
-	}
-
-	*button_count = total_sdl_buttons + total_sdl_axes * 2 + total_sdl_hats * 4;
-	*axis_count = total_sdl_axes;
-
-	static bool *button_buffer = NULL;
-	static short *axis_buffer = NULL;
-
-	bool *new_button_buffer = (bool*)realloc(button_buffer, *button_count * sizeof(bool));
-
-	if (new_button_buffer == NULL)
-		return false;
-
-	button_buffer = new_button_buffer;
-
-	short *new_axis_buffer = (short*)realloc(axis_buffer, *axis_count * sizeof(short));
-
-	if (new_axis_buffer == NULL)
-		return false;
-
-	axis_buffer = new_axis_buffer;
-
-	//////////////////////////
-	// Handle button inputs //
-	//////////////////////////
-
-	unsigned int current_button = 0;
-
-	// Start with the joystick buttons
-	for (int i = 0; i < total_sdl_buttons; ++i)
-		button_buffer[current_button++] = SDL_JoystickGetButton(joystick, i);
-
-	// Then the joystick axes
-	for (int i = 0; i < total_sdl_axes; ++i)
-	{
-		Sint16 axis = SDL_JoystickGetAxis(joystick, i);
-
-		button_buffer[current_button++] = axis < axis_neutrals[i] - DEADZONE;
-		button_buffer[current_button++] = axis > axis_neutrals[i] + DEADZONE;
-	}
-
-	// Then the joystick hats
-	for (int i = 0; i < total_sdl_hats; ++i)
-	{
-		Uint8 hat = SDL_JoystickGetHat(joystick, i);
-
-		button_buffer[current_button++] = hat == SDL_HAT_UP || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_RIGHTUP;
-		button_buffer[current_button++] = hat == SDL_HAT_RIGHT || hat == SDL_HAT_RIGHTUP || hat == SDL_HAT_RIGHTDOWN;
-		button_buffer[current_button++] = hat == SDL_HAT_DOWN || hat == SDL_HAT_LEFTDOWN || hat == SDL_HAT_RIGHTDOWN;
-		button_buffer[current_button++] = hat == SDL_HAT_LEFT || hat == SDL_HAT_LEFTUP || hat == SDL_HAT_LEFTDOWN;
-	}
-
-	*buttons = button_buffer;
-
-	////////////////////////
-	// Handle axis inputs //
-	////////////////////////
-
-	for (int i = 0; i < total_sdl_axes; ++i)
-		axis_buffer[i] = SDL_JoystickGetAxis(joystick, i);
-
-	*axes = axis_buffer;
-
-	return true;
-}
-
-void ControllerBackend_JoystickConnect(Sint32 joystick_id)
-{
-	const char *joystick_name = SDL_JoystickNameForIndex(joystick_id);
-
-	if (joystick_name != NULL)
-	{
-		Backend_PrintInfo("Joystick #%d connected - %s", joystick_id, joystick_name);
-	}
-	else
-	{
-		Backend_PrintError("Couldn't get joystick name: %s", SDL_GetError());
-		Backend_PrintInfo("Joystick #%d connected - Name unknown", joystick_id);
-	}
-
-	if (joystick == NULL)
-	{
-		joystick = SDL_JoystickOpen(joystick_id);
-
-		if (joystick != NULL)
-		{
-			int total_axes = SDL_JoystickNumAxes(joystick);
-			if (total_axes < 0)
-				Backend_PrintError("Couldn't get number of general axis control on connected joystick: %s", SDL_GetError());
-
-			int total_buttons = SDL_JoystickNumButtons(joystick);
-			if (total_buttons < 0)
-				Backend_PrintError("Couldn't get number of buttons on connected joystick: %s", SDL_GetError());
-
-			if (total_axes >= 2 && total_buttons >= 6)
-			{
-				Backend_PrintInfo("Joystick #%d selected", joystick_id);
-
-				// Set up neutral axes
-				axis_neutrals = (Sint16*)malloc(sizeof(Sint16) * total_axes);
-
-				if (axis_neutrals != NULL)
-				{
-					for (int i = 0; i < total_axes; ++i)
-						axis_neutrals[i] = SDL_JoystickGetAxis(joystick, i);
-
-					return;
-				}
-				else
-				{
-					Backend_PrintError("Couldn't allocate memory for neutral axes");
-				}
-			}
-
-			SDL_JoystickClose(joystick);
-			joystick = NULL;
-		}
-		else
-		{
-			Backend_PrintError("Couldn't open joystick for use: %s", SDL_GetError());
-		}
-	}
-}
-
-void ControllerBackend_JoystickDisconnect(Sint32 joystick_id)
-{
-	SDL_JoystickID current_joystick_id = SDL_JoystickInstanceID(joystick);
-	if (current_joystick_id < 0)
-		Backend_PrintError("Couldn't get instance ID for current joystick: %s", SDL_GetError());
-
-	if (joystick_id == current_joystick_id)
-	{
-		Backend_PrintInfo("Joystick #%d disconnected", joystick_id);
-		SDL_JoystickClose(joystick);
-		joystick = NULL;
-
-		free(axis_neutrals);
-	}
-}
--- /dev/null
+++ b/src/Backends/Platform/SDL1.cpp
@@ -1,0 +1,254 @@
+#include "../Misc.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+
+#include "SDL.h"
+
+#include "../Rendering.h"
+#include "../../Main.h"
+#include "../../Organya.h"
+#include "../../Profile.h"
+#include "../../Resource.h"
+
+#define DO_KEY(SDL_KEY, BACKEND_KEY) \
+	case SDL_KEY: \
+		keyboard_state[BACKEND_KEY] = event.key.type == SDL_KEYDOWN; \
+		break;
+
+static bool keyboard_state[BACKEND_KEYBOARD_TOTAL];
+
+bool Backend_Init(void)
+{
+	if (SDL_Init(SDL_INIT_VIDEO) == 0)
+	{
+		char driver[20];
+		if (SDL_VideoDriverName(driver, 20) != NULL)
+		{
+			Backend_PrintInfo("Selected SDL video driver: %s", driver);
+
+			return true;
+		}
+		else
+		{
+			Backend_PrintError("No SDL video driver initialized!");
+			SDL_Quit();
+		}
+	}
+	else
+	{
+		std::string error_message = std::string("Could not initialise SDL: ") + SDL_GetError();
+		Backend_ShowMessageBox("Fatal error", error_message.c_str());
+	}
+
+	return false;
+}
+
+void Backend_Deinit(void)
+{
+	SDL_Quit();
+}
+
+void Backend_PostWindowCreation(void)
+{
+}
+
+bool Backend_GetBasePath(char *string_buffer)
+{
+	return false;
+}
+
+void Backend_HideMouse(void)
+{
+	SDL_ShowCursor(SDL_DISABLE);
+}
+
+void Backend_SetWindowIcon(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+	SDL_Surface *surface = SDL_CreateRGBSurfaceFrom((void*)rgb_pixels, width, height, 24, width * 3, 0x0000FF, 0x00FF00, 0xFF0000, 0);
+
+	if (surface != NULL)
+	{
+		SDL_WM_SetIcon(surface, NULL);
+		SDL_FreeSurface(surface);
+	}
+	else
+	{
+		Backend_PrintError("Couldn't create RGB surface for window icon: %s", SDL_GetError());
+	}
+}
+
+void Backend_SetCursor(const unsigned char *rgb_pixels, unsigned int width, unsigned int height)
+{
+	(void)rgb_pixels;
+	(void)width;
+	(void)height;
+	// SDL1 only supports black and white cursors
+}
+
+void PlaybackBackend_EnableDragAndDrop(void)
+{
+}
+
+bool Backend_SystemTask(bool active)
+{
+	if (SDL_PollEvent(NULL) || !active)
+	{
+		SDL_Event event;
+
+		if (!SDL_WaitEvent(&event))
+			return false;
+
+		switch (event.type)
+		{
+			case SDL_KEYUP:
+			case SDL_KEYDOWN:
+				switch (event.key.keysym.sym)
+				{
+					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)
+
+					default:
+						break;
+				}
+
+				break;
+
+			case SDL_ACTIVEEVENT:
+				if (event.active.state & SDL_APPINPUTFOCUS)
+				{
+					if (event.active.gain)
+						ActiveWindow();
+					else
+						InactiveWindow();
+				}
+
+				break;
+
+			case SDL_VIDEORESIZE:
+				RenderBackend_HandleWindowResize(event.resize.w, event.resize.h);
+				break;
+
+			case SDL_QUIT:
+				StopOrganyaMusic();
+				return false;
+		}
+	}
+
+	return true;
+}
+
+void Backend_GetKeyboardState(bool *out_keyboard_state)
+{
+	memcpy(out_keyboard_state, keyboard_state, sizeof(keyboard_state));
+}
+
+void Backend_ShowMessageBox(const char *title, const char *message)
+{
+	fprintf(stderr, "ShowMessageBox - '%s' - '%s'\n", title, message);
+}
+
+ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintError(const char *format, ...)
+{
+	va_list argumentList;
+	va_start(argumentList, format);
+	fputs("ERROR: ", stderr);
+	vfprintf(stderr, format, argumentList);
+	fputc('\n', stderr);
+	va_end(argumentList);
+}
+
+ATTRIBUTE_FORMAT_PRINTF(1, 2) void Backend_PrintInfo(const char *format, ...)
+{
+	va_list argumentList;
+	va_start(argumentList, format);
+	fputs("INFO: ", stdout);
+	vprintf(format, argumentList);
+	putchar('\n');
+	va_end(argumentList);
+}
+
+unsigned long Backend_GetTicks(void)
+{
+	return SDL_GetTicks();
+}
+
+void Backend_Delay(unsigned int ticks)
+{
+	SDL_Delay(ticks);
+}
--- /dev/null
+++ b/src/Backends/Rendering/Window/Software/SDL1.cpp
@@ -1,0 +1,76 @@
+#include "../Software.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string>
+
+#include "SDL.h"
+
+#include "../../../Misc.h"
+
+static Uint32 window_flags = SDL_HWSURFACE | SDL_DOUBLEBUF;
+
+static SDL_Surface *window_sdlsurface;
+static SDL_Surface *framebuffer_sdlsurface;
+
+bool WindowBackend_Software_CreateWindow(const char *window_title, int screen_width, int screen_height, bool fullscreen)
+{
+	if (fullscreen)
+		window_flags |= SDL_FULLSCREEN;
+	else
+		window_flags &= ~SDL_FULLSCREEN;
+
+	window_sdlsurface = SDL_SetVideoMode(screen_width, screen_height, 24, window_flags);
+	if (window_sdlsurface != NULL)
+	{
+		SDL_WM_SetCaption(window_title, NULL);
+		framebuffer_sdlsurface = SDL_CreateRGBSurface(SDL_SWSURFACE, window_sdlsurface->w, window_sdlsurface->h, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
+
+		if (framebuffer_sdlsurface != NULL)
+		{
+			Backend_PostWindowCreation();
+
+			return true;
+		}
+		else
+		{
+			std::string error_message = std::string("Couldn't create framebuffer surface: ") + SDL_GetError();
+			Backend_ShowMessageBox("Fatal error (software rendering backend)", error_message.c_str());
+		}
+	}
+	else
+	{
+		std::string error_message = std::string("Couldn't create window: ") + SDL_GetError();
+		Backend_ShowMessageBox("Fatal error (software rendering backend)", error_message.c_str());
+	}
+
+	return false;
+}
+
+void WindowBackend_Software_DestroyWindow(void)
+{
+	SDL_FreeSurface(framebuffer_sdlsurface);
+}
+
+unsigned char* WindowBackend_Software_GetFramebuffer(size_t *pitch)
+{
+	*pitch = framebuffer_sdlsurface->pitch;
+
+	return (unsigned char*)framebuffer_sdlsurface->pixels;
+}
+
+void WindowBackend_Software_Display(void)
+{
+	if (SDL_BlitSurface(framebuffer_sdlsurface, NULL, window_sdlsurface, NULL) < 0)
+		Backend_PrintError("Couldn't blit framebuffer surface to window surface: %s", SDL_GetError());
+
+	if (SDL_Flip(window_sdlsurface) < 0)
+		Backend_PrintError("Couldn't copy window surface to the screen: %s", SDL_GetError());
+}
+
+void WindowBackend_Software_HandleWindowResize(unsigned int width, unsigned int height)
+{
+	window_sdlsurface = SDL_SetVideoMode(width, height, 24, window_flags);
+	if (window_sdlsurface == NULL)
+		Backend_PrintError("Couldn't get SDL surface associated with window: %s", SDL_GetError());
+}