2004-12-09 23:39:52 +00:00
# include "quakedef.h"
# include "glquake.h"
2004-12-10 21:31:53 +00:00
# include <SDL.h>
2014-02-07 08:38:40 +00:00
# include <SDL_syswm.h>
2004-12-09 23:39:52 +00:00
2014-02-07 08:38:40 +00:00
# if SDL_MAJOR_VERSION >= 2
SDL_Window * sdlwindow ;
static SDL_GLContext * sdlcontext ;
# else
2004-12-09 23:39:52 +00:00
SDL_Surface * sdlsurf ;
2014-02-07 08:38:40 +00:00
# endif
2004-12-09 23:39:52 +00:00
2014-02-07 08:38:40 +00:00
extern cvar_t vid_vsync ;
2004-12-09 23:39:52 +00:00
extern cvar_t vid_hardwaregamma ;
extern cvar_t gl_lateswap ;
2014-02-07 08:38:40 +00:00
extern cvar_t vid_gl_context_version ;
extern cvar_t vid_gl_context_debug ;
extern cvar_t vid_gl_context_forwardcompatible ;
extern cvar_t vid_gl_context_es ;
extern cvar_t vid_gl_context_compatibility ;
2016-07-12 00:40:13 +00:00
extern qboolean gammaworks ;
2004-12-09 23:39:52 +00:00
# ifdef _WIN32 //half the rest of the code uses windows apis to focus windows. Should be fixed, but it's not too important.
HWND mainwindow ;
# endif
extern qboolean vid_isfullscreen ;
2014-02-07 08:38:40 +00:00
# if SDL_MAJOR_VERSION < 2
2004-12-09 23:39:52 +00:00
unsigned short intitialgammaramps [ 3 ] [ 256 ] ;
2014-02-07 08:38:40 +00:00
# endif
2004-12-09 23:39:52 +00:00
qboolean mouseactive ;
extern qboolean mouseusedforgui ;
2012-10-14 09:00:49 +00:00
static void * GLVID_getsdlglfunction ( char * functionname )
{
2013-08-06 02:20:56 +00:00
# ifdef GL_STATIC
//this reduces dependancies in the webgl build (removing warnings about emulation being poo)
return NULL ;
# else
2012-10-14 09:00:49 +00:00
return SDL_GL_GetProcAddress ( functionname ) ;
2013-08-06 02:20:56 +00:00
# endif
2012-10-14 09:00:49 +00:00
}
2004-12-09 23:39:52 +00:00
2015-09-18 20:30:10 +00:00
# if SDL_MAJOR_VERSION >= 2
2016-07-15 12:26:24 +00:00
void * GLVID_CreateCursor ( const char * filename , float hotx , float hoty , float scale )
2015-09-18 20:30:10 +00:00
{
int width ;
int height ;
SDL_Cursor * curs ;
SDL_Surface * surf ;
qbyte * rgbadata_start ;
qboolean hasalpha ;
void * filedata ;
int filelen ;
if ( ! filename | | ! * filename )
return NULL ;
filelen = FS_LoadFile ( filename , & filedata ) ;
if ( ! filedata )
return NULL ;
rgbadata_start = Read32BitImageFile ( filedata , filelen , & width , & height , & hasalpha , " cursor " ) ;
FS_FreeFile ( filedata ) ;
if ( ! rgbadata_start )
return NULL ;
if ( scale ! = 1 )
{
int nw , nh ;
qbyte * nd ;
nw = width * scale ;
nh = height * scale ;
if ( nw < = 0 | | nh < = 0 | | nw > 128 | | nh > 128 ) //don't go crazy.
return NULL ;
nd = BZ_Malloc ( nw * nh * 4 ) ;
Image_ResampleTexture ( ( unsigned int * ) rgbadata_start , width , height , ( unsigned int * ) nd , nw , nh ) ;
width = nw ;
height = nh ;
BZ_Free ( rgbadata_start ) ;
rgbadata_start = nd ;
}
surf = SDL_CreateRGBSurfaceFrom ( rgbadata_start , width , height , 32 , width * 4 , 0x000000ff , 0x0000ff00 , 0x00ff0000 , 0xff000000 ) ;
curs = SDL_CreateColorCursor ( surf , hotx , hoty ) ;
SDL_FreeSurface ( surf ) ;
BZ_Free ( rgbadata_start ) ;
return curs ;
}
qboolean GLVID_SetCursor ( void * cursor )
{
SDL_SetCursor ( cursor ) ;
return ! ! cursor ;
}
void GLVID_DestroyCursor ( void * cursor )
{
SDL_FreeCursor ( cursor ) ;
}
# endif
2004-12-09 23:39:52 +00:00
qboolean GLVID_Init ( rendererstate_t * info , unsigned char * palette )
{
2014-02-07 08:38:40 +00:00
int flags = 0 ;
2004-12-09 23:39:52 +00:00
SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) ;
2014-02-07 08:38:40 +00:00
# if !defined(FTE_TARGET_WEB) && SDL_MAJOR_VERSION < 2
SDL_SetVideoMode ( 0 , 0 , 0 , 0 ) ; //to get around some SDL bugs
# endif
# if SDL_MAJOR_VERSION >= 2
SDL_GL_LoadLibrary ( NULL ) ;
2013-04-02 05:18:17 +00:00
# endif
2004-12-09 23:39:52 +00:00
2014-02-07 08:38:40 +00:00
if ( info - > bpp > = 32 )
{
SDL_GL_SetAttribute ( SDL_GL_RED_SIZE , 8 ) ;
SDL_GL_SetAttribute ( SDL_GL_GREEN_SIZE , 8 ) ;
SDL_GL_SetAttribute ( SDL_GL_BLUE_SIZE , 8 ) ;
SDL_GL_SetAttribute ( SDL_GL_ALPHA_SIZE , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_STENCIL_SIZE , 8 ) ; //technically we don't always need stencil support.
}
else
{
SDL_GL_SetAttribute ( SDL_GL_RED_SIZE , 5 ) ;
SDL_GL_SetAttribute ( SDL_GL_GREEN_SIZE , 5 ) ;
SDL_GL_SetAttribute ( SDL_GL_BLUE_SIZE , 5 ) ;
SDL_GL_SetAttribute ( SDL_GL_ALPHA_SIZE , 0 ) ;
SDL_GL_SetAttribute ( SDL_GL_STENCIL_SIZE , 0 ) ;
}
SDL_GL_SetAttribute ( SDL_GL_DEPTH_SIZE , 16 ) ;
SDL_GL_SetAttribute ( SDL_GL_DOUBLEBUFFER , 1 ) ;
2004-12-09 23:39:52 +00:00
2014-02-07 08:38:40 +00:00
if ( info - > stereo )
SDL_GL_SetAttribute ( SDL_GL_STEREO , 1 ) ;
2006-03-15 20:11:37 +00:00
2014-02-07 08:38:40 +00:00
#if 0 //SDL_MAJOR_VERSION >= 2
//FIXME: this stuff isn't part of info.
//this means it shouldn't be exposed to the menu or widely advertised.
if ( * vid_gl_context_version . string )
{
int major , minor ;
char * ver = vid_gl_context_version . string ;
major = strtoul ( ver , & ver , 10 ) ;
if ( * ver = = ' . ' )
{
ver + + ;
minor = strtoul ( ver , & ver , 10 ) ;
}
else
minor = 0 ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MAJOR_VERSION , major ) ;
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_MINOR_VERSION , minor ) ;
}
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_FLAGS ,
( vid_gl_context_debug . ival ? SDL_GL_CONTEXT_DEBUG_FLAG : 0 ) |
( vid_gl_context_forwardcompatible . ival ? SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG : 0 ) |
0 ) ;
if ( vid_gl_context_es . ival )
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_ES ) ;
else if ( vid_gl_context_compatibility . ival )
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_COMPATIBILITY ) ;
else
SDL_GL_SetAttribute ( SDL_GL_CONTEXT_PROFILE_MASK , SDL_GL_CONTEXT_PROFILE_CORE ) ;
# endif
2006-03-15 20:11:37 +00:00
if ( info - > multisample )
{
SDL_GL_SetAttribute ( SDL_GL_MULTISAMPLESAMPLES , info - > multisample ) ;
SDL_GL_SetAttribute ( SDL_GL_MULTISAMPLEBUFFERS , 1 ) ;
}
2014-02-07 08:38:40 +00:00
# if SDL_MAJOR_VERSION >= 2
if ( info - > fullscreen )
flags | = SDL_WINDOW_FULLSCREEN ;
flags | = SDL_WINDOW_OPENGL ;
flags | = SDL_WINDOW_RESIZABLE ;
flags | = SDL_WINDOW_INPUT_GRABBED ;
flags | = SDL_WINDOW_SHOWN ;
# if SDL_PATCHLEVEL >= 1
flags | = SDL_WINDOW_ALLOW_HIGHDPI ;
# endif
2017-01-15 13:13:09 +00:00
sdlwindow = SDL_CreateWindow ( FULLENGINENAME , SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED , info - > width , info - > height , flags ) ;
2014-02-07 08:38:40 +00:00
if ( ! sdlwindow )
{
Con_Printf ( " Couldn't set video mode: %s \n " , SDL_GetError ( ) ) ;
return false ;
}
2015-09-18 20:30:10 +00:00
CL_UpdateWindowTitle ( ) ;
2014-02-07 08:38:40 +00:00
# if SDL_PATCHLEVEL >= 1
SDL_GL_GetDrawableSize ( sdlwindow , & vid . pixelwidth , & vid . pixelheight ) ; //get the proper physical size.
# else
SDL_GetWindowSize ( sdlwindow , & vid . pixelwidth , & vid . pixelheight ) ;
# endif
sdlcontext = SDL_GL_CreateContext ( sdlwindow ) ;
if ( ! sdlcontext )
{
Con_Printf ( " Couldn't initialize GL context: %s \n " , SDL_GetError ( ) ) ;
return false ;
}
2004-12-09 23:39:52 +00:00
2014-02-07 08:38:40 +00:00
{
SDL_Surface * iconsurf ;
# include "bymorphed.h"
2014-08-25 07:35:41 +00:00
iconsurf = SDL_CreateRGBSurfaceFrom ( ( void * ) icon . pixel_data , icon . width , icon . height , 32 , 4 * icon . height , 0x000000FF , 0x0000FF00 , 0x00FF0000 , 0xFF000000 ) ; //RGBA byte order on a little endian machine, at least...
2014-02-07 08:38:40 +00:00
SDL_SetWindowIcon ( sdlwindow , iconsurf ) ;
SDL_FreeSurface ( iconsurf ) ;
}
# else
SDL_GetGammaRamp ( intitialgammaramps [ 0 ] , intitialgammaramps [ 1 ] , intitialgammaramps [ 2 ] ) ;
2004-12-09 23:39:52 +00:00
if ( info - > fullscreen )
{
flags = SDL_FULLSCREEN ;
vid_isfullscreen = true ;
}
else
{
flags = SDL_RESIZABLE ;
vid_isfullscreen = false ;
}
2010-08-11 23:55:35 +00:00
sdlsurf = SDL_SetVideoMode ( vid . pixelwidth = info - > width , vid . pixelheight = info - > height , info - > bpp , flags | SDL_OPENGL ) ;
2004-12-09 23:39:52 +00:00
if ( ! sdlsurf )
{
2010-08-11 23:55:35 +00:00
Con_Printf ( " Couldn't set GL mode: %s \n " , SDL_GetError ( ) ) ;
2004-12-09 23:39:52 +00:00
return false ;
}
2014-02-07 08:38:40 +00:00
# endif
2016-02-10 23:23:43 +00:00
vid . activeapp = true ;
2004-12-09 23:39:52 +00:00
2017-07-12 08:15:27 +00:00
GL_Init ( info , GLVID_getsdlglfunction ) ;
2004-12-09 23:39:52 +00:00
2010-08-11 23:55:35 +00:00
qglViewport ( 0 , 0 , vid . pixelwidth , vid . pixelheight ) ;
2004-12-09 23:39:52 +00:00
mouseactive = false ;
if ( vid_isfullscreen )
IN_ActivateMouse ( ) ;
2014-02-07 08:38:40 +00:00
# if SDL_MAJOR_VERSION < 2
SDL_EnableKeyRepeat ( SDL_DEFAULT_REPEAT_DELAY , SDL_DEFAULT_REPEAT_INTERVAL ) ;
2014-02-09 09:25:28 +00:00
# else
SDL_DisableScreenSaver ( ) ;
2014-02-07 08:38:40 +00:00
# endif
vid_vsync . modified = true ;
# ifdef _WIN32
{ //win32 apis are very insistant upon having a window context for things that have nothing to do with windowing system stuff.
# if SDL_MAJOR_VERSION >= 2
SDL_SysWMinfo info ;
SDL_GetWindowWMInfo ( sdlwindow , & info ) ;
if ( info . subsystem = = SDL_SYSWM_WINDOWS )
mainwindow = info . info . win . window ;
else
mainwindow = NULL ; //if we're using an x11 subsystem but running in windows then don't feck up... here, at least.
# else
SDL_SysWMinfo wmInfo ;
SDL_GetWMInfo ( & wmInfo ) ;
mainwindow = wmInfo . window ; //note that this is usually still null
# endif
}
# endif
2015-09-18 20:30:10 +00:00
# if SDL_MAJOR_VERSION >= 2
rf - > VID_CreateCursor = GLVID_CreateCursor ;
rf - > VID_DestroyCursor = GLVID_DestroyCursor ;
rf - > VID_SetCursor = GLVID_SetCursor ;
# endif
2004-12-09 23:39:52 +00:00
return true ;
}
void GLVID_DeInit ( void )
{
2016-02-10 23:23:43 +00:00
vid . activeapp = false ;
2004-12-09 23:39:52 +00:00
IN_DeactivateMouse ( ) ;
2014-02-07 08:38:40 +00:00
# if SDL_MAJOR_VERSION >= 2
SDL_SetWindowGammaRamp ( sdlwindow , NULL , NULL , NULL ) ;
SDL_GL_DeleteContext ( sdlcontext ) ;
SDL_DestroyWindow ( sdlwindow ) ;
2014-02-07 09:36:04 +00:00
sdlwindow = NULL ;
2014-02-07 08:38:40 +00:00
# else
2004-12-09 23:39:52 +00:00
SDL_SetGammaRamp ( intitialgammaramps [ 0 ] , intitialgammaramps [ 1 ] , intitialgammaramps [ 2 ] ) ;
2014-02-07 08:38:40 +00:00
# endif
2004-12-09 23:39:52 +00:00
SDL_QuitSubSystem ( SDL_INIT_VIDEO ) ;
}
2014-03-30 00:39:37 +00:00
void GLVID_SwapBuffers ( void )
2004-12-09 23:39:52 +00:00
{
2014-02-09 09:25:28 +00:00
# if SDL_MAJOR_VERSION >= 2
2014-02-07 08:38:40 +00:00
if ( vid_vsync . modified )
{
if ( * vid_vsync . string )
{
//if swap_tear isn't supported, try without.
if ( SDL_GL_SetSwapInterval ( vid_vsync . ival ) = = - 1 & & vid_vsync . ival < 0 )
SDL_GL_SetSwapInterval ( - vid_vsync . ival ) ;
}
vid_vsync . modified = false ;
}
SDL_GL_SwapWindow ( sdlwindow ) ;
# else
SDL_GL_SwapBuffers ( ) ;
# endif
2004-12-09 23:39:52 +00:00
if ( ! vid_isfullscreen )
{
if ( ! _windowed_mouse . value )
{
2013-10-08 14:28:11 +00:00
IN_DeactivateMouse ( ) ;
2004-12-09 23:39:52 +00:00
}
else
{
2016-02-10 23:23:43 +00:00
if ( ! Key_MouseShouldBeFree ( ) & & vid . activeapp )
2004-12-09 23:39:52 +00:00
IN_ActivateMouse ( ) ;
2013-10-08 14:28:11 +00:00
else
2004-12-09 23:39:52 +00:00
IN_DeactivateMouse ( ) ;
}
}
}
2016-07-28 15:57:22 +00:00
qboolean GLVID_ApplyGammaRamps ( unsigned int gammarampsize , unsigned short * ramps )
2004-12-09 23:39:52 +00:00
{
2014-02-07 08:38:40 +00:00
# if SDL_MAJOR_VERSION >= 2
2016-07-28 15:57:22 +00:00
if ( ramps & & gammarampsize = = 256 )
2014-02-07 08:38:40 +00:00
{
if ( vid_hardwaregamma . value )
{
if ( gammaworks )
{ //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck)
SDL_SetWindowGammaRamp ( sdlwindow , & ramps [ 0 ] , & ramps [ 256 ] , & ramps [ 512 ] ) ;
return true ;
}
gammaworks = ! SDL_SetWindowGammaRamp ( sdlwindow , & ramps [ 0 ] , & ramps [ 256 ] , & ramps [ 512 ] ) ;
}
else
gammaworks = false ;
return gammaworks ;
}
else
{
SDL_SetWindowGammaRamp ( sdlwindow , NULL , NULL , NULL ) ;
return true ;
}
# else
2016-07-28 15:57:22 +00:00
if ( ramps & & gammarampsize = = 256 )
2004-12-09 23:39:52 +00:00
{
2013-05-14 06:01:02 +00:00
if ( vid_hardwaregamma . value )
2004-12-09 23:39:52 +00:00
{
2013-05-14 06:01:02 +00:00
if ( gammaworks )
{ //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck)
SDL_SetGammaRamp ( & ramps [ 0 ] , & ramps [ 256 ] , & ramps [ 512 ] ) ;
2013-05-14 18:38:42 +00:00
return true ;
2013-05-14 06:01:02 +00:00
}
gammaworks = ! SDL_SetGammaRamp ( & ramps [ 0 ] , & ramps [ 256 ] , & ramps [ 512 ] ) ;
2004-12-09 23:39:52 +00:00
}
2013-05-14 06:01:02 +00:00
else
gammaworks = false ;
2004-12-09 23:39:52 +00:00
2013-05-14 06:01:02 +00:00
return gammaworks ;
2004-12-09 23:39:52 +00:00
}
2013-05-14 06:01:02 +00:00
else
2004-12-09 23:39:52 +00:00
{
2013-05-14 06:01:02 +00:00
SDL_SetGammaRamp ( intitialgammaramps [ 0 ] , intitialgammaramps [ 1 ] , intitialgammaramps [ 2 ] ) ;
return true ;
2004-12-09 23:39:52 +00:00
}
2014-02-07 08:38:40 +00:00
# endif
2004-12-09 23:39:52 +00:00
}
2016-07-12 00:40:13 +00:00
void GLVID_SetCaption ( const char * text )
2009-04-06 14:19:29 +00:00
{
2014-02-07 08:38:40 +00:00
# if SDL_MAJOR_VERSION >= 2
SDL_SetWindowTitle ( sdlwindow , text ) ;
# else
SDL_WM_SetCaption ( text , NULL ) ;
# endif
2009-04-06 14:19:29 +00:00
}
2004-12-09 23:39:52 +00:00