Merge branch 'sdl2'

This commit is contained in:
Yamagi Burmeister 2013-11-09 13:21:39 +01:00
commit e7ac0653b2
8 changed files with 678 additions and 175 deletions

View file

@ -7,7 +7,7 @@
# - Quake II Game (baseq2) #
# #
# Base dependencies: #
# - SDL 1.2 #
# - SDL 1.2 or SDL 2.0 #
# - libGL #
# #
# Platforms: #
@ -24,6 +24,7 @@
# for the background music and doesn't add any further
# dependencies. It should work on all platforms where
# CD playback is supported by SDL.
# was yes
WITH_CDA:=yes
# Enables OGG/Vorbis support. OGG/Vorbis files can be
@ -41,6 +42,12 @@ WITH_OPENAL:=yes
# a dependency to libjpeg
WITH_RETEXTURING:=yes
# Use SDL2 instead of SDL1.2. Disables CD audio support,
# because SDL2 has none. Use OGG/Vorbis music instead :-)
# On Windows sdl-config isn't used, so make sure that
# you've got the SDL2 headers and libs installed.
WITH_SDL2:=yes
# Set the gamma via X11 and not via SDL. This works
# around problems in some SDL version. Adds dependencies
# to pkg-config, libX11 and libXxf86vm. Unsupported on
@ -102,6 +109,18 @@ ifeq ($(findstring $(ARCH), i386 x86_64 sparc64 ia64),)
$(error arch $(ARCH) is currently not supported)
endif
# Disable CDA for SDL2
ifeq ($(WITH_SDL2),yes)
ifeq ($(WITH_CDA),yes)
WITH_CDA:=no
# Evil hack to tell the "all" target
# that CDA was disabled because SDL2
# is enabled.
CDA_ENABLED:=yes
endif
endif
# ----------
# Base CFLAGS.
@ -146,10 +165,15 @@ endif
ifneq ($(OSTYPE), Windows)
ifeq ($(OSTYPE), Darwin)
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 +219,24 @@ endif
# Extra LDFLAGS for SDL
ifeq ($(OSTYPE), Windows)
ifeq ($(WITH_SDL2),yes)
SDLLDFLAGS := -lSDL2main -lSDL2 -mwindows -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid
else # not SDL2
SDLLDFLAGS := -lSDL
endif # SDL2
else ifeq ($(OSTYPE), Darwin)
ifeq ($(WITH_SDL2),yes)
SDLLDFLAGS := -framework SDL2 -framework OpenGL -framework Cocoa
else # not SDL2
SDLLDFLAGS := -framework SDL -framework OpenGL -framework Cocoa
else
endif # SDL2
else # not Darwin/Win
ifeq ($(WITH_SDL2),yes)
SDLLDFLAGS := $(shell sdl2-config --libs)
else # not SDL2
SDLLDFLAGS := $(shell sdl-config --libs)
endif
endif # SDL2
endif # Darwin/Win
# ----------
@ -210,6 +246,7 @@ ifneq ($(OSTYPE), Darwin)
ifeq ($(WITH_X11GAMMA),yes)
X11LDFLAGS := $(shell pkg-config x11 --libs)
X11LDFLAGS += $(shell pkg-config xxf86vm --libs)
X11LDFLAGS += $(shell pkg-config xrandr --libs)
endif
endif
endif
@ -243,11 +280,19 @@ config:
@echo "WITH_CDA = $(WITH_CDA)"
@echo "WITH_OPENAL = $(WITH_OPENAL)"
@echo "WITH_RETEXTURING = $(WITH_RETEXTURING)"
@echo "WITH_SDL2 = $(WITH_SDL2)"
@echo "WITH_X11GAMMA = $(WITH_X11GAMMA)"
@echo "WITH_ZIP = $(WITH_ZIP)"
@echo "WITH_SYSTEMWIDE = $(WITH_SYSTEMWIDE)"
@echo "WITH_SYSTEMDIR = $(WITH_SYSTEMDIR)"
@echo "============================"
@echo ""
ifeq ($(WITH_SDL2),yes)
ifeq ($(CDA_ENABLED),yes)
@echo "WARNING: CDA disabled because SDL2 doesn't support it!"
@echo ""
endif
endif
# ----------
@ -310,6 +355,10 @@ release/quake2.exe : CFLAGS += -DRETEXTURE
release/quake2.exe : LDFLAGS += -ljpeg
endif
ifeq ($(WITH_SDL2),yes)
release/quake2.exe : CFLAGS += -DSDL2
endif
release/quake2.exe : LDFLAGS += -mwindows -lopengl32
else
client:
@ -371,6 +420,10 @@ release/quake2 : LDFLAGS += -ljpeg
endif
endif
ifeq ($(WITH_SDL2),yes)
release/quake2 : CFLAGS += -DSDL2
endif
ifeq ($(OSTYPE), Darwin)
ifeq ($(OSX_APP), yes)
release/quake2 : LDFLAGS += -Xlinker -rpath -Xlinker @loader_path/../Frameworks

47
README
View file

@ -11,9 +11,10 @@ II. The main focus is single player, the gameplay and the graphics are
unchanged, but many bugs were fixed. Unlike most other Quake II ports Yamagi
Quake II is full 64 bit clean so it works perfectly on modern amd64 (x86_64)
processors and operating systems. This code should run on Windows XP or later,
Mac OS X 10.6 or higher and on most unix-like operating systems (only FreeBSD,
Linux and OpenBSD are officially supported and tested, for other systems you'd
at least have to edit the Makefile), just type "make" or "gmake" to compile.
Mac OS X 10.6 or higher (unsupported!) and on most unix-like operating systems
(only FreeBSD, Linux and OpenBSD are officially supported and tested, for other
systems you'd at least have to edit the Makefile), just type "make" or "gmake"
to compile.
This code is based upon Icculus Quake II, which itself is built upon id
Software's original code drop. Additional code and patches by many contributers
@ -147,7 +148,7 @@ it'll lead to the loss of features):
- libogg with development headers
- libvorbis with development headers
- OpenAL with development headers
- SDL with development headers and sdl-config(1)
- SDL 1.2 or 2.0 with development headers and sdl-config(1)
- ZLib
Extract the source, change into the new created directory and type "make"
@ -156,7 +157,6 @@ following files from "release/" to your installation directory preserving the
directory structure:
- q2ded
- quake2
- ref_gl.so
- baseq2/game.so
1.6 Default Configuration
@ -242,7 +242,7 @@ use the github version or want to develop on Windows. If you really want to
compile Yamagi Quake II by yourself follow these steps:
1. Grab a copy of Nuwens MinGW distribution from http://nuwen.net/mingw.html
Our code is tested with version 9.0, newer version may work but we can not
Our code is tested with version 11.0, newer version may work but we can not
guarantee that. Extract the distribution to a directory of your choice.
2. Grab a copy of OpenAL Soft from http://kcat.strangesoft.net/openal.html
(the binary release for Windows). Our code is tested with version 1.14.
@ -256,14 +256,12 @@ After compiling, copy the following files from "release\" to your Quake II
installation preserving the directory structure:
- q2ded.exe
- quake2.exe
- ref_gl.dll
- baseq2\game.dll
You'll need a "openal32.dll" and an "SDL.dll" next to "quake2.exe". You can use
and rename the OpenAL DLL that came with OpenAL Soft. We recommend to use a
"SDL.dll" from http://libsdl.org and not the one supplied with Nuwens MinGW
distribution. Known to be good DLLs can be found in the stuff/win32-libs
directory of the source code distribution.
You'll need a "openal32.dll. You can use and rename the OpenAL DLL that
came with OpenAL Soft. Known to be good DLLs can be found in the
stuff/win32-libs directory of the source code distribution. The supplied
SDL.dll is an SDL 1.2 build, required if you're still using SDL 1.2.
2.7 Default Configuration
-------------------------
@ -283,6 +281,10 @@ supported, including the IPv6 network code and the OpenAL sound backend.
Installation can be done by using the binary release (this is highly
recommended) or by compiling the source.
ATTENTION: OS X is currently unsupported. I neither have a Mac nor the time to
maintain this platform. If you're interested in spending work on OS X please
write an e-mail to quake2@yamagi.org.
3.1 Supported Systems
---------------------
Yamagi Quake II should run on every Mac with Intel CPU and OS X 10.6
@ -375,8 +377,9 @@ Now you are ready to start your brand new Quake II. Have fun.
======================
Since most modern CD-ROM and DVD drives don't have an analog audio output and
most sound codecs don't have the appropriate input header, it's not possible to
use CD audio as background music on such systems. Therefore OGG/Vorbis music
support has been added to Yamagi Quake II.
use CD audio as background music on such systems. With SDL 2.0 CD audio is
unsupported Therefore OGG/Vorbis music support has been added to Yamagi Quake
II.
4.1 Setup for the original soundtrack:
--------------------------------------
@ -649,9 +652,7 @@ My SDL sound is not working!
Does the sound work in other SDL games? Does your setup support at least five
virtual channels? In most cases it's better to not use sound servers like
Pulseaudio but the plain sound system like OSS or ALSA with libasound instead.
Also see the "Sound" section in this file! On Windows the SDL sound backend
may not work on all installations. This is due to a limitation of SDL. Use
OpenAL instead.
Also see the "Sound" section in this file!
My OpenGL is not working!
- Make sure, that OpenGL is working in other games. Use "glxinfo" and
@ -699,7 +700,7 @@ that, so that Quake II behaves like a normal window?
Hey, my screensaver crashes Quake II or I experience strange crashes after a
fixed amount of time!
- This is a known bug in some linux distributions. SDL fails to disable
- This is a known bug in some linux distributions. SDL 1.2 fails to disable
the screensaver even if we tell him to do so. See this Ubuntu bugreport:
https://bugs.launchpad.net/ubuntu/+source/gnome-screensaver/+bug/32457
As a work around use the startscript in stuff/quake-start.sh It deactivates
@ -794,4 +795,14 @@ Why is the FOV different than in id Softwares client?
Why doesn't gl_showtris work?
- gl_showtris requires gl_ext_multitexturing set to 0.
How do I disable the vsync?
- Set gl_swapinterval to 0 and type vid_restart. Beware that this may
not work with SDL 1.2 due to bugs in SDL.
I've build Yamagi Quake II with SDL 2.0 and now my mouse behaves strange.
- If it feels like your mouse is hitting the window borders you're
experiencing a problem in SDL 2.0. SDL 2.0 needs XInput 2.2 or higher
and fails when the installed version is older. So make sure that you
have XInput 2.2 or higher installed.
==============================================================================

View file

@ -29,12 +29,36 @@
#include "../../client/header/keyboard.h"
#include "../generic/header/input.h"
#ifdef _WIN32
#if defined(_WIN32) || defined(__APPLE__)
#ifdef SDL2
#include <SDL2/SDL.h>
#else // SDL1.2
#include <SDL/SDL.h>
#elif defined(__APPLE__)
#include <SDL/SDL.h>
#else
#endif //SDL2
#else // not _WIN32 || APPLE
#include <SDL.h>
#endif // _WIN32 || APPLE
#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
@ -61,9 +85,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 +254,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 +297,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 +329,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;
}
}
@ -311,6 +343,19 @@ IN_TranslateSDLtoQ2Key(unsigned int keysym)
return key;
}
// add down and up event for mousewheel to simulate a "click"
static void IN_AddMouseWheelEvents(int key)
{
assert(key == K_MWHEELUP || key == K_MWHEELDOWN);
keyq[keyq_head].key = key;
keyq[keyq_head].down = true;
keyq_head = (keyq_head + 1) & 127;
keyq[keyq_head].key = key;
keyq[keyq_head].down = false;
keyq_head = (keyq_head + 1) & 127;
}
/*
* Input event processing
*/
@ -318,32 +363,34 @@ 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)
{
/* The mouse wheel */
#if SDL_VERSION_ATLEAST(2, 0, 0)
case SDL_MOUSEWHEEL:
IN_AddMouseWheelEvents(event->wheel.y > 0 ? K_MWHEELUP : K_MWHEELDOWN);
break;
#else
case SDL_MOUSEBUTTONDOWN:
if (event->button.button == 4)
{
keyq[keyq_head].key = K_MWHEELUP;
keyq[keyq_head].down = true;
keyq_head = (keyq_head + 1) & 127;
keyq[keyq_head].key = K_MWHEELUP;
keyq[keyq_head].down = false;
keyq_head = (keyq_head + 1) & 127;
IN_AddMouseWheelEvents(K_MWHEELUP);
}
else if (event->button.button == 5)
{
keyq[keyq_head].key = K_MWHEELDOWN;
keyq[keyq_head].down = true;
keyq_head = (keyq_head + 1) & 127;
keyq[keyq_head].key = K_MWHEELDOWN;
keyq[keyq_head].down = false;
keyq_head = (keyq_head + 1) & 127;
IN_AddMouseWheelEvents(K_MWHEELDOWN);
}
break;
#endif
case SDL_MOUSEBUTTONUP:
break;
@ -352,23 +399,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 +410,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 +418,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,11 +432,6 @@ IN_GetEvent(SDL_Event *event)
/* The user released a key */
case SDL_KEYUP:
if (KeyStates[event->key.keysym.sym])
{
KeyStates[event->key.keysym.sym] = 0;
/* Get the pressed key and remove it from the key list */
key = IN_TranslateSDLtoQ2Key(event->key.keysym.sym);
@ -415,7 +441,6 @@ IN_GetEvent(SDL_Event *event)
keyq[keyq_head].down = false;
keyq_head = (keyq_head + 1) & 127;
}
}
break;
}
@ -445,14 +470,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 +513,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 +598,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

@ -18,6 +18,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* ----------------------------------------------------------------------
* CalculateGammaRamp() is derived from SDL2's SDL_CalculateGammaRamp()
* (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
* Published under zlib License: http://www.libsdl.org/license.php
*
* =======================================================================
*
* This file implements an OpenGL context via SDL
@ -32,13 +37,15 @@
#include <GL/gl.h>
#endif
#ifdef _WIN32
#if defined(_WIN32) || defined(__APPLE__)
#ifdef SDL2
#include <SDL2/SDL.h>
#else // SDL1.2
#include <SDL/SDL.h>
#elif defined(__APPLE__)
#include <SDL/SDL.h>
#else
#endif //SDL2
#else // not _WIN32 || APPLE
#include <SDL.h>
#endif
#endif // _WIN32 || APPLE
/* The window icon */
#include "icon/q2icon.xbm"
@ -49,17 +56,31 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/xf86vmode.h>
#include <X11/extensions/Xrandr.h>
#include <SDL_syswm.h>
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Window* window = NULL;
SDL_GLContext context = NULL;
#else
SDL_Surface* window = NULL;
#endif
SDL_Surface *surface;
qboolean have_stencil = false;
char *displayname = NULL;
int screen = -1;
#ifdef X11GAMMA
Display *dpy;
XF86VidModeGamma x11_oldgamma;
XRRCrtcGamma** gammaRamps = NULL;
int noGammaRamps = 0;
#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
/*
@ -70,7 +91,6 @@ GLimp_Init(void)
{
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
char driverName[64];
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
@ -78,8 +98,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);
}
@ -102,7 +126,7 @@ static void
SetSDLIcon()
{
SDL_Surface *icon;
SDL_Color color;
SDL_Color transColor, solidColor;
Uint8 *ptr;
int i;
int mask;
@ -118,17 +142,28 @@ SetSDLIcon()
SDL_SetColorKey(icon, SDL_SRCCOLORKEY, 0);
color.r = 255;
color.g = 255;
color.b = 255;
transColor.r = 255;
transColor.g = 255;
transColor.b = 255;
SDL_SetColors(icon, &color, 0, 1);
solidColor.r = 0;
solidColor.g = 16;
solidColor.b = 0;
color.r = 0;
color.g = 16;
color.b = 0;
#if SDL_VERSION_ATLEAST(2, 0, 0)
// only SDL2 has alphas there and they must be set apparently
transColor.a = 0;
solidColor.a = 255;
SDL_SetColors(icon, &color, 1, 1);
SDL_Palette* palette = SDL_AllocPalette(256);
SDL_SetPaletteColors(palette, &transColor, 0, 1);
SDL_SetPaletteColors(palette, &solidColor, 1, 1);
SDL_SetSurfacePalette(icon, palette);
#else
SDL_SetColors(icon, &transColor, 0, 1);
SDL_SetColors(icon, &solidColor, 1, 1);
#endif
ptr = (Uint8 *)icon->pixels;
@ -140,11 +175,57 @@ SetSDLIcon()
ptr++;
}
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_SetWindowIcon(window, icon);
SDL_FreePalette(palette);
#else
SDL_WM_SetIcon(icon, NULL);
#endif
SDL_FreeSurface(icon);
}
/*
* from SDL2 SDL_CalculateGammaRamp, adjusted for arbitrary ramp sizes
* because xrandr seems to support ramp sizes != 256 (in theory at least)
*/
void CalculateGammaRamp(float gamma, Uint16* ramp, int len)
{
int i;
/* Input validation */
if (gamma < 0.0f ) {
return;
}
if (ramp == NULL) {
return;
}
/* 0.0 gamma is all black */
if (gamma == 0.0f) {
for (i = 0; i < len; ++i) {
ramp[i] = 0;
}
return;
} else if (gamma == 1.0f) {
/* 1.0 gamma is identity */
for (i = 0; i < len; ++i) {
ramp[i] = (i << 8) | i;
}
return;
} else {
/* Calculate a real gamma ramp */
int value;
gamma = 1.0f / gamma;
for (i = 0; i < len; ++i) {
value = (int) (pow((double) i / (double) len, gamma) * 65535.0 + 0.5);
if (value > 65535) {
value = 65535;
}
ramp[i] = (Uint16) value;
}
}
}
/*
* Sets the hardware gamma
*/
@ -152,31 +233,264 @@ SetSDLIcon()
void
UpdateHardwareGamma(void)
{
float gamma;
XF86VidModeGamma x11_gamma;
float gamma = (vid_gamma->value);
int i;
gamma = vid_gamma->value;
Display* dpy = NULL;
SDL_SysWMinfo info;
x11_gamma.red = gamma;
x11_gamma.green = gamma;
x11_gamma.blue = gamma;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
XF86VidModeSetGamma(dpy, screen, &x11_gamma);
dpy = info.info.x11.display;
/* This forces X11 to update the gamma tables */
XF86VidModeGetGamma(dpy, screen, &x11_gamma);
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
for(i=0; i < res->ncrtc; ++i)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
size_t rampSize = len*sizeof(Uint16);
Uint16* ramp = malloc(rampSize); // TODO: check for NULL
if(ramp == NULL)
{
VID_Printf(PRINT_ALL, "Couldn't allocate &zd byte of memory for gamma ramp - OOM?!\n", rampSize);
return;
}
CalculateGammaRamp(gamma, ramp, len);
XRRCrtcGamma* gamma = XRRAllocGamma(len);
memcpy(gamma->red, ramp, rampSize);
memcpy(gamma->green, ramp, rampSize);
memcpy(gamma->blue, ramp, rampSize);
free(ramp);
XRRSetCrtcGamma(dpy, res->crtcs[i], gamma);
XRRFreeGamma(gamma);
}
XRRFreeScreenResources(res);
}
#else
#else // no X11GAMMA
void
UpdateHardwareGamma(void)
{
float gamma;
float gamma = (vid_gamma->value);
gamma = (vid_gamma->value);
SDL_SetGamma(gamma, gamma, gamma);
}
Uint16 ramp[256];
CalculateGammaRamp(gamma, ramp, 256);
#if SDL_VERSION_ATLEAST(2, 0, 0)
if(SDL_SetWindowGammaRamp(window, ramp, ramp, ramp) != 0) {
#else
if(SDL_SetGammaRamp(ramp, ramp, ramp) < 0) {
#endif
VID_Printf(PRINT_ALL, "Setting gamma failed: %s\n", SDL_GetError());
}
}
#endif // X11GAMMA
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 CreateSDLWindow(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;
}
static void InitGamma()
{
#ifdef X11GAMMA
int i=0;
SDL_SysWMinfo info;
Display* dpy = NULL;
if(gammaRamps != NULL) // already saved gamma
return;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
noGammaRamps = res->ncrtc;
gammaRamps = calloc(noGammaRamps, sizeof(XRRCrtcGamma*));
if(gammaRamps == NULL) {
VID_Printf(PRINT_ALL, "Couldn't allocate memory for %d gamma ramps - OOM?!\n", noGammaRamps);
return;
}
for(i=0; i < noGammaRamps; ++i)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
size_t rampSize = len*sizeof(Uint16);
XRRCrtcGamma* origGamma = XRRGetCrtcGamma(dpy, res->crtcs[i]);
XRRCrtcGamma* gammaCopy = XRRAllocGamma(len);
memcpy(gammaCopy->red, origGamma->red, rampSize);
memcpy(gammaCopy->green, origGamma->green, rampSize);
memcpy(gammaCopy->blue, origGamma->blue, rampSize);
gammaRamps[i] = gammaCopy;
}
XRRFreeScreenResources(res);
VID_Printf(PRINT_ALL, "Using hardware gamma via X11/xRandR.\n");
#else
VID_Printf(PRINT_ALL, "Using hardware gamma via SDL.\n");
#endif
gl_state.hwgamma = true;
vid_gamma->modified = true;
}
#ifdef X11GAMMA
static void RestoreGamma()
{
int i=0;
SDL_SysWMinfo info;
Display* dpy = NULL;
if(gammaRamps == NULL)
return;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_VERSION(&info.version);
if(!SDL_GetWindowWMInfo(window, &info))
#else
if(SDL_GetWMInfo(&info) != 1)
#endif
{
VID_Printf(PRINT_ALL, "Couldn't get Window info from SDL\n");
return;
}
dpy = info.info.x11.display;
XRRScreenResources* res = XRRGetScreenResources(dpy, info.info.x11.window);
if(res == NULL)
{
VID_Printf(PRINT_ALL, "Unable to get xrandr screen resources.\n");
return;
}
for(i=0; i < noGammaRamps; ++i)
{
// in case a display was unplugged or something, noGammaRamps may be > res->ncrtc
if(i < res->ncrtc)
{
int len = XRRGetCrtcGammaSize(dpy, res->crtcs[i]);
if(len != gammaRamps[i]->size) {
VID_Printf(PRINT_ALL, "WTF, gamma ramp size for display %d has changed from %d to %d!\n",
i, gammaRamps[i]->size, len);
continue;
}
XRRSetCrtcGamma(dpy, res->crtcs[i], gammaRamps[i]);
}
// the ramp needs to be free()d either way
XRRFreeGamma(gammaRamps[i]);
gammaRamps[i] = NULL;
}
XRRFreeScreenResources(res);
free(gammaRamps);
gammaRamps = NULL;
VID_Printf(PRINT_ALL, "Restored original Gamma\n");
}
#endif // X11GAMMA
/*
* Initializes the OpenGL window
@ -189,30 +503,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))
{
SDL_WM_ToggleFullScreen(surface);
/* If we want fullscreen, but aren't */
if (fullscreen != IsFullscreen())
{
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 */
@ -233,7 +549,8 @@ GLimp_InitGraphics(qboolean fullscreen)
flags |= SDL_FULLSCREEN;
}
/* Set the icon */
#if !SDL_VERSION_ATLEAST(2, 0, 0)
/* Set the icon - for SDL1.2 this must be done before creating the window */
SetSDLIcon();
/* Enable vsync */
@ -241,10 +558,11 @@ GLimp_InitGraphics(qboolean fullscreen)
{
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
}
#endif
while (1)
{
if ((surface = SDL_SetVideoMode(vid.width, vid.height, 0, flags)) == NULL)
if (!CreateSDLWindow(flags))
{
if (counter == 1)
{
@ -270,6 +588,10 @@ GLimp_InitGraphics(qboolean fullscreen)
break;
}
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
/* Set the icon - for SDL2 this must be done after creating the window */
SetSDLIcon();
#endif
/* Initialize the stencil buffer */
if (!SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_bits))
@ -283,34 +605,15 @@ GLimp_InitGraphics(qboolean fullscreen)
}
/* Initialize hardware gamma */
#ifdef X11GAMMA
if ((dpy = XOpenDisplay(displayname)) == NULL)
{
VID_Printf(PRINT_ALL, "Unable to open display.\n");
}
else
{
if (screen == -1)
{
screen = DefaultScreen(dpy);
}
gl_state.hwgamma = true;
vid_gamma->modified = true;
XF86VidModeGetGamma(dpy, screen, &x11_oldgamma);
VID_Printf(PRINT_ALL, "Using hardware gamma via X11.\n");
}
#else
gl_state.hwgamma = true;
vid_gamma->modified = true;
VID_Printf(PRINT_ALL, "Using hardware gamma via SDL.\n");
#endif
InitGamma();
/* 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 +627,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 +660,60 @@ 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);
if(grab)
SDL_SetRelativeMouseMode(SDL_TRUE);
#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 +732,26 @@ GLimp_Shutdown(void)
GLimp_EndFrame();
}
if (surface)
#ifdef X11GAMMA
RestoreGamma();
#endif
if (window)
{
SDL_FreeSurface(surface);
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_DestroyWindow(window);
if(context)
{
SDL_GL_DeleteContext(context);
context = NULL;
}
#else
SDL_FreeSurface(window);
#endif
}
surface = NULL;
window = NULL;
if (SDL_WasInit(SDL_INIT_EVERYTHING) == SDL_INIT_VIDEO)
{
@ -387,16 +762,6 @@ GLimp_Shutdown(void)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
#ifdef X11GAMMA
if (gl_state.hwgamma == true)
{
XF86VidModeSetGamma(dpy, screen, &x11_oldgamma);
/* This forces X11 to update the gamma tables */
XF86VidModeGetGamma(dpy, screen, &x11_oldgamma);
}
#endif
gl_state.hwgamma = false;
}

View file

@ -34,13 +34,15 @@
*/
/* SDL includes */
#ifdef _WIN32
#if defined(_WIN32) || defined(__APPLE__)
#ifdef SDL2
#include <SDL2/SDL.h>
#else // SDL1.2
#include <SDL/SDL.h>
#elif defined(__APPLE__)
#include <SDL/SDL.h>
#else
#endif //SDL2
#else // not _WIN32 || APPLE
#include <SDL.h>
#endif
#endif // _WIN32 || APPLE
/* Local includes */
#include "../../client/header/client.h"
@ -1188,7 +1190,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;
@ -1206,7 +1207,11 @@ SDL_BackendInit(void)
int sndchans = (Cvar_Get("sndchannels", "2", CVAR_ARCHIVE))->value;
#ifdef _WIN32
#if SDL_VERSION_ATLEAST(2, 0, 0)
s_sdldriver = (Cvar_Get("s_sdldriver", "directsound", CVAR_ARCHIVE));
#else
s_sdldriver = (Cvar_Get("s_sdldriver", "dsound", CVAR_ARCHIVE));
#endif
#elif __linux__
s_sdldriver = (Cvar_Get("s_sdldriver", "alsa", CVAR_ARCHIVE));
#elif __APPLE__
@ -1215,7 +1220,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 +1233,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

@ -77,6 +77,12 @@ main(int argc, char **argv)
#ifndef DEDICATED_ONLY
printf("Client build options:\n");
#ifdef SDL2
printf(" + SDL2\n");
#else
printf(" - SDL2 (using 1.2)\n");
#endif
#ifdef CDA
printf(" + CD audio\n");
#else

View file

@ -712,6 +712,11 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#ifndef DEDICATED_ONLY
printf("Client build options:\n");
#ifdef SDL2
printf(" + SDL2\n");
#else
printf(" - SDL2 (using 1.2)\n");
#endif
#ifdef CDA
printf(" + CD audio\n");
#else

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