Initial SDL 1.2 backend

This commit is contained in:
Cameron Cawley 2020-05-11 23:30:44 +01:00
parent 79ec91c851
commit cf8789f887
4 changed files with 378 additions and 2 deletions
CMakeLists.txt
src/Backends
Controller
Platform
Rendering/Window/Software

View file

@ -26,7 +26,7 @@ option(FREETYPE_FONTS "Use FreeType2 to render the DejaVu Mono (English) or Migu
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 @@ endif()
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 "SDLTexture"
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")
@ -599,6 +606,41 @@ if(BACKEND_PLATFORM MATCHES "SDL2" OR BACKEND_AUDIO MATCHES "SDL2")
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()
if(FREETYPE_FONTS)
if(NOT FORCE_LOCAL_LIBS)
find_package(Freetype)

View file

@ -6,7 +6,9 @@
#include "SDL.h"
#include "../Misc.h"
#if SDL_VERSION_ATLEAST(2, 0, 0)
#include "../Shared/SDL2.h"
#endif
#define DEADZONE 10000
@ -126,6 +128,7 @@ bool ControllerBackend_GetJoystickStatus(bool **buttons, unsigned int *button_co
return true;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
void ControllerBackend_JoystickConnect(Sint32 joystick_id)
{
const char *joystick_name = SDL_JoystickNameForIndex(joystick_id);
@ -199,3 +202,4 @@ void ControllerBackend_JoystickDisconnect(Sint32 joystick_id)
free(axis_neutrals);
}
}
#endif

View file

@ -0,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);
}

View file

@ -0,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());
}