SDL2 support (mostly)

Makefile is adjusted, it compiles and works mostly, but
* For some reason (bug in SDL_GetRelativeMouseState() ?)
  mouse input doesn't work properly.. it seems to be bound
  to window borders, even if input is grabbed
* some keys can't be used anymore because there's no SDLK_*
  for them anymore (gotta find out if this is important)
* Maybe some of the changes need cleanup
This commit is contained in:
Daniel Gibson 2013-08-26 00:55:31 +02:00
parent ee03e7f03a
commit 51b7607548
5 changed files with 290 additions and 67 deletions

View file

@ -20,11 +20,16 @@
# User configurable options
# -------------------------
# blabla
# should be no by default in the future
WITH_SDL2:=yes
# Enables CD audio playback. CD audio playback is used
# for the background music and doesn't add any further
# dependencies. It should work on all platforms where
# CD playback is supported by SDL.
WITH_CDA:=yes
# was yes
WITH_CDA:=no
# Enables OGG/Vorbis support. OGG/Vorbis files can be
# used as a substitute of CD audio playback. Adds
@ -145,11 +150,17 @@ endif
# Extra CFLAGS for SDL
ifneq ($(OSTYPE), Windows)
ifeq ($(OSTYPE), Darwin)
# TODO: set -I.../SDL2/ or /SDL/
SDLCFLAGS :=
else
else # not darwin
ifeq ($(WITH_SDL2),yes)
SDLCFLAGS := $(shell sdl2-config --cflags)
else # not SDL2
SDLCFLAGS := $(shell sdl-config --cflags)
endif
endif
endif # SDL2
endif # darwin's else
endif # not windows
# ----------
@ -195,12 +206,17 @@ endif
# Extra LDFLAGS for SDL
ifeq ($(OSTYPE), Windows)
# TODO: SDL2 for win/osx
SDLLDFLAGS := -lSDL
else ifeq ($(OSTYPE), Darwin)
SDLLDFLAGS := -framework SDL -framework OpenGL -framework Cocoa
else
ifeq ($(WITH_SDL2),yes)
SDLLDFLAGS := $(shell sdl2-config --libs)
else
SDLLDFLAGS := $(shell sdl-config --libs)
endif
endif
# ----------
@ -248,6 +264,8 @@ config:
@echo "WITH_SYSTEMWIDE = $(WITH_SYSTEMWIDE)"
@echo "WITH_SYSTEMDIR = $(WITH_SYSTEMDIR)"
@echo "============================"
@echo ""
@echo "SDL-Debug: $(SDLCFLAGS)"
# ----------

View file

@ -37,6 +37,28 @@
#include <SDL.h>
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
#define SDLK_KP0 SDLK_KP_0
#define SDLK_KP1 SDLK_KP_1
#define SDLK_KP2 SDLK_KP_2
#define SDLK_KP3 SDLK_KP_3
#define SDLK_KP4 SDLK_KP_4
#define SDLK_KP5 SDLK_KP_5
#define SDLK_KP6 SDLK_KP_6
#define SDLK_KP7 SDLK_KP_7
#define SDLK_KP8 SDLK_KP_8
#define SDLK_KP9 SDLK_KP_9
#define SDLK_RMETA SDLK_RGUI
#define SDLK_LMETA SDLK_LGUI
#define SDLK_COMPOSE SDLK_APPLICATION // really?
#define SDLK_PRINT SDLK_PRINTSCREEN
#define SDLK_SCROLLOCK SDLK_SCROLLLOCK
#define SDLK_NUMLOCK SDLK_NUMLOCKCLEAR
#endif
#define MOUSE_MAX 3000
#define MOUSE_MIN 40
@ -61,9 +83,7 @@ int my;
Key_Event_fp_t Key_Event_fp;
extern SDL_Surface *surface;
static in_state_t *in_state;
static unsigned char KeyStates[SDLK_LAST];
static qboolean mlooking;
static cvar_t *sensitivity;
@ -232,10 +252,13 @@ IN_TranslateSDLtoQ2Key(unsigned int keysym)
case SDLK_LALT:
key = K_ALT;
break;
#if !SDL_VERSION_ATLEAST(2, 0, 0)
// TODO: delete? what is this anyway?
case SDLK_LSUPER:
case SDLK_RSUPER:
key = K_SUPER;
break;
#endif
case SDLK_KP5:
key = K_KP_5;
break;
@ -272,18 +295,24 @@ IN_TranslateSDLtoQ2Key(unsigned int keysym)
case SDLK_SYSREQ:
key = K_SYSREQ;
break;
#if !SDL_VERSION_ATLEAST(2, 0, 0)
// TODO: delete? what is this anyway?
case SDLK_BREAK:
key = K_BREAK;
break;
#endif
case SDLK_MENU:
key = K_MENU;
break;
case SDLK_POWER:
key = K_POWER;
break;
#if !SDL_VERSION_ATLEAST(2, 0, 0)
// TODO: delete? what is this anyway?
case SDLK_EURO:
key = K_EURO;
break;
#endif
case SDLK_UNDO:
key = K_UNDO;
break;
@ -298,12 +327,13 @@ IN_TranslateSDLtoQ2Key(unsigned int keysym)
break;
default:
#if !SDL_VERSION_ATLEAST(2, 0, 0)
// FIXME: how could this be used with SDL2?!
if ((keysym >= SDLK_WORLD_0) && (keysym <= SDLK_WORLD_95))
{
key = (keysym - SDLK_WORLD_0) + K_WORLD_0;
}
#endif
break;
}
}
@ -318,6 +348,11 @@ void
IN_GetEvent(SDL_Event *event)
{
unsigned int key;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Keymod modstate = SDL_GetModState();
#else
SDLMod modstate = SDL_GetModState();
#endif
switch (event->type)
{
@ -352,23 +387,10 @@ IN_GetEvent(SDL_Event *event)
case SDL_KEYDOWN:
/* Fullscreen switch via Alt-Return */
if ((KeyStates[SDLK_LALT] ||
KeyStates[SDLK_RALT]) &&
if ((modstate & KMOD_ALT) &&
(event->key.keysym.sym == SDLK_RETURN))
{
SDL_WM_ToggleFullScreen(surface);
if (surface->flags & SDL_FULLSCREEN)
{
Cvar_SetValue("vid_fullscreen", 1);
}
else
{
Cvar_SetValue("vid_fullscreen", 0);
}
vid_fullscreen->modified = false;
GLimp_ToggleFullscreen();
break;
}
@ -376,8 +398,7 @@ IN_GetEvent(SDL_Event *event)
really belongs in Key_Event(), but since
Key_ClearStates() can mess up the internal
K_SHIFT state let's do it here instead. */
if ((KeyStates[SDLK_LSHIFT] ||
KeyStates[SDLK_RSHIFT]) &&
if ((modstate & KMOD_SHIFT) &&
(event->key.keysym.sym == SDLK_ESCAPE))
{
Cbuf_ExecuteText(EXEC_NOW, "toggleconsole");
@ -385,8 +406,6 @@ IN_GetEvent(SDL_Event *event)
break;
}
KeyStates[event->key.keysym.sym] = 1;
/* Get the pressed key and add it to the key list */
key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym);
@ -401,20 +420,14 @@ IN_GetEvent(SDL_Event *event)
/* The user released a key */
case SDL_KEYUP:
/* Get the pressed key and remove it from the key list */
key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym);
if (KeyStates[event->key.keysym.sym])
if (key)
{
KeyStates[event->key.keysym.sym] = 0;
/* Get the pressed key and remove it from the key list */
key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym);
if (key)
{
keyq[keyq_head].key = key;
keyq[keyq_head].down = false;
keyq_head = (keyq_head + 1) & 127;
}
keyq[keyq_head].key = key;
keyq[keyq_head].down = false;
keyq_head = (keyq_head + 1) & 127;
}
break;
@ -445,14 +458,15 @@ IN_Update(void)
IN_GetEvent(&event);
}
/* Mouse button processing. Button 4
and 5 are the mousewheel and thus
not processed here. */
if (!mx && !my)
{
SDL_GetRelativeMouseState(&mx, &my);
}
/* Mouse button processing. Button 4
and 5 are the mousewheel and thus
not processed here. */
mouse_buttonstate = 0;
bstate = SDL_GetMouseState(NULL, NULL);
@ -487,7 +501,7 @@ IN_Update(void)
(in_grab->value == 2 && windowed_mouse->value));
if (have_grab != want_grab)
{
SDL_WM_GrabInput((want_grab ? SDL_GRAB_ON : SDL_GRAB_OFF));
GLimp_GrabInput(want_grab);
have_grab = want_grab;
}
@ -572,9 +586,16 @@ IN_KeyboardInit(Key_Event_fp_t fp)
/* SDL stuff. Moved here from IN_BackendInit because
* this must be done after video is initialized. */
#if SDL_VERSION_ATLEAST(2, 0, 0)
// TODO: keyrepeat?
// TODO: only if want_grab?
SDL_SetRelativeMouseMode(SDL_TRUE);
have_grab = GLimp_InputIsGrabbed();
#else
SDL_EnableUNICODE(0);
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
have_grab = (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
#endif
}
/*

View file

@ -51,7 +51,13 @@
#include <X11/extensions/xf86vmode.h>
#endif
SDL_Surface *surface;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Window* window = NULL;
SDL_GLContext context = NULL;
#else
SDL_Surface* window = NULL;
#endif
qboolean have_stencil = false;
char *displayname = NULL;
@ -62,6 +68,14 @@ Display *dpy;
XF86VidModeGamma x11_oldgamma;
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
// some compatibility defines
#define SDL_SRCCOLORKEY SDL_TRUE
#define SDL_FULLSCREEN SDL_WINDOW_FULLSCREEN
#define SDL_OPENGL SDL_WINDOW_OPENGL
#endif
/*
* Initialzes the SDL OpenGL context
*/
@ -70,7 +84,6 @@ GLimp_Init(void)
{
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
char driverName[64];
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
@ -78,8 +91,12 @@ GLimp_Init(void)
SDL_GetError());
return false;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
const char* driverName = SDL_GetCurrentVideoDriver();
#else
char driverName[64];
SDL_VideoDriverName(driverName, sizeof(driverName) - 1);
#endif
VID_Printf(PRINT_ALL, "SDL video driver is \"%s\".\n", driverName);
}
@ -101,6 +118,8 @@ GLimp_GetProcAddress (const char* proc)
static void
SetSDLIcon()
{
#if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Surface *icon;
SDL_Color color;
Uint8 *ptr;
@ -143,6 +162,7 @@ SetSDLIcon()
SDL_WM_SetIcon(icon, NULL);
SDL_FreeSurface(icon);
#endif
}
/*
@ -171,13 +191,80 @@ UpdateHardwareGamma(void)
void
UpdateHardwareGamma(void)
{
float gamma;
gamma = (vid_gamma->value);
#if SDL_VERSION_ATLEAST(2, 0, 0)
// FIXME: there's no more SDL_SetGamma?!
// see rbd3bfg R_SetColorMappings() ?
#else
float gamma = (vid_gamma->value);
SDL_SetGamma(gamma, gamma, gamma);
#endif
}
#endif
static qboolean IsFullscreen()
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
return !!(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN);
#else
return !!(window->flags & SDL_FULLSCREEN);
#endif
}
static qboolean CreateWindow(int flags)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
int windowPos = SDL_WINDOWPOS_UNDEFINED;
// TODO: support fullscreen on different displays with SDL_WINDOWPOS_UNDEFINED_DISPLAY(displaynum)
window = SDL_CreateWindow("Yamagi Quake II", windowPos, windowPos,
vid.width, vid.height, flags);
if(window == NULL)
{
return false;
}
context = SDL_GL_CreateContext(window);
if(context == NULL)
{
SDL_DestroyWindow(window);
window = NULL;
return false;
}
// set vsync - TODO: -1 could be set for "late swap tearing",
// i.e. only vsync if framerate is high enough
SDL_GL_SetSwapInterval(gl_swapinterval->value ? 1 : 0);
return true;
#else
window = SDL_SetVideoMode(vid.width, vid.height, 0, flags);
return window != NULL;
#endif
}
static qboolean GetWindowSize(int* w, int* h)
{
if(window == NULL || w == NULL || h == NULL)
return false;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_DisplayMode m;
if(SDL_GetWindowDisplayMode(window, &m) != 0)
{
VID_Printf(PRINT_ALL, "Can't get Displaymode: %s\n", SDL_GetError());
return false;
}
*w = m.w;
*h = m.h;
#else
*w = window->w;
*h = window->h;
#endif
return true;
}
/*
* Initializes the OpenGL window
*/
@ -189,30 +276,32 @@ GLimp_InitGraphics(qboolean fullscreen)
int stencil_bits;
char title[24];
if (surface && (surface->w == vid.width) && (surface->h == vid.height))
{
/* Are we running fullscreen? */
int isfullscreen = (surface->flags & SDL_FULLSCREEN) ? 1 : 0;
int width, height;
/* We should, but we don't */
if (fullscreen != isfullscreen)
if (GetWindowSize(&width, &height) && (width == vid.width) && (height == vid.height))
{
/* If we want fullscreen, but aren't */
if (fullscreen != IsFullscreen())
{
SDL_WM_ToggleFullScreen(surface);
GLimp_ToggleFullscreen();
}
/* Do we now? */
isfullscreen = (surface->flags & SDL_FULLSCREEN) ? 1 : 0;
if (fullscreen == isfullscreen)
/* Are we now? */
if (fullscreen == IsFullscreen())
{
return true;
}
}
/* Is the surface used? */
if (surface)
if (window)
{
SDL_FreeSurface(surface);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(window);
#else
SDL_FreeSurface(window);
#endif
}
/* Create the window */
@ -236,15 +325,17 @@ GLimp_InitGraphics(qboolean fullscreen)
/* Set the icon */
SetSDLIcon();
#if !SDL_VERSION_ATLEAST(2, 0, 0)
/* Enable vsync */
if (gl_swapinterval->value)
{
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
}
#endif
while (1)
{
if ((surface = SDL_SetVideoMode(vid.width, vid.height, 0, flags)) == NULL)
if (!CreateWindow(flags))
{
if (counter == 1)
{
@ -310,7 +401,11 @@ GLimp_InitGraphics(qboolean fullscreen)
/* Window title */
snprintf(title, sizeof(title), "Yamagi Quake II %s", VERSION);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_SetWindowTitle(window, title);
#else
SDL_WM_SetCaption(title, title);
#endif
/* No cursor */
SDL_ShowCursor(0);
@ -324,7 +419,11 @@ GLimp_InitGraphics(qboolean fullscreen)
void
GLimp_EndFrame(void)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GL_SwapWindow(window);
#else
SDL_GL_SwapBuffers();
#endif
}
/*
@ -353,6 +452,57 @@ GLimp_SetMode(int *pwidth, int *pheight, int mode, qboolean fullscreen)
return rserr_ok;
}
/*
* Toggle fullscreen.
*/
void GLimp_ToggleFullscreen(void)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
int wantFullscreen = !IsFullscreen();
SDL_SetWindowFullscreen(window, wantFullscreen ? SDL_WINDOW_FULLSCREEN : 0);
Cvar_SetValue("vid_fullscreen", wantFullscreen);
#else
SDL_WM_ToggleFullScreen(window);
if (IsFullscreen())
{
Cvar_SetValue("vid_fullscreen", 1);
}
else
{
Cvar_SetValue("vid_fullscreen", 0);
}
#endif
vid_fullscreen->modified = false;
}
/*
* (Un)grab Input
*/
void GLimp_GrabInput(qboolean grab)
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_SetWindowGrab(window, grab ? SDL_TRUE : SDL_FALSE);
#else
SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);
#endif
}
/*
* returns true if input is grabbed, else false
*/
qboolean GLimp_InputIsGrabbed()
{
#if SDL_VERSION_ATLEAST(2, 0, 0)
return SDL_GetWindowGrab(window) ? true : false;
#else
SDL_GrabMode m = SDL_WM_GrabInput(SDL_GRAB_QUERY);
return m == SDL_GRAB_ON;
#endif
}
/*
* Shuts the SDL render backend down
*/
@ -371,12 +521,22 @@ GLimp_Shutdown(void)
GLimp_EndFrame();
}
if (surface)
if (window)
{
SDL_FreeSurface(surface);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_DestroyWindow(window);
#else
SDL_FreeSurface(window);
#endif
}
surface = NULL;
window = NULL;
if(context)
{
SDL_GL_DeleteContext(context);
context = NULL;
}
if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_VIDEO)
{

View file

@ -1188,7 +1188,6 @@ SDL_Callback(void *data, Uint8 *stream, int length)
qboolean
SDL_BackendInit(void)
{
char drivername[128];
char reqdriver[128];
SDL_AudioSpec desired;
SDL_AudioSpec obtained;
@ -1215,7 +1214,7 @@ SDL_BackendInit(void)
s_sdldriver = (Cvar_Get("s_sdldriver", "dsp", CVAR_ARCHIVE));
#endif
snprintf(reqdriver, sizeof(drivername), "%s=%s", "SDL_AUDIODRIVER", s_sdldriver->string);
snprintf(reqdriver, sizeof(reqdriver), "%s=%s", "SDL_AUDIODRIVER", s_sdldriver->string);
putenv(reqdriver);
Com_Printf("Starting SDL audio callback.\n");
@ -1228,11 +1227,21 @@ SDL_BackendInit(void)
return 0;
}
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
const char* drivername = SDL_GetCurrentAudioDriver();
if(drivername == NULL)
{
drivername = "(UNKNOWN)";
}
#else
char drivername[128];
if (SDL_AudioDriverName(drivername, sizeof(drivername)) == NULL)
{
strcpy(drivername, "(UNKNOWN)");
}
#endif
Com_Printf("SDL audio driver is \"%s\".\n", drivername);

View file

@ -418,4 +418,19 @@ int GLimp_SetMode(int *pwidth, int *pheight, int mode, qboolean fullscreen);
*/
void *GLimp_GetProcAddress (const char* proc);
/*
* Toggle fullscreen.
*/
void GLimp_ToggleFullscreen(void);
/*
* (Un)grab Input
*/
void GLimp_GrabInput(qboolean grab);
/*
* returns true if input is grabbed, else false
*/
qboolean GLimp_InputIsGrabbed();
#endif