Merge pull request #4 from jonathangray/sdl

add SDL glimp/input from ioquake3
This commit is contained in:
Zachary J. Slater 2013-04-29 22:21:41 -07:00
commit bc0383bd86
28 changed files with 5008 additions and 39 deletions

View File

@ -47,11 +47,14 @@ add_definitions( -DFINAL_BUILD )
add_definitions( -D_JK2 )
add_definitions( -D_JK2MP )
include_directories(/usr/X11R6/include/)
link_directories(/usr/X11R6/lib)
find_package (SDL REQUIRED)
include_directories(${SDL_INCLUDE_DIR})
include_directories(/usr/local/include/)
link_directories(/usr/local/lib)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
find_package(OpenAL REQUIRED)
include_directories(${OPENAL_INCLUDE_DIR})
set(src_main_client
client/FXExport.cpp
@ -271,11 +274,16 @@ set(src_unix_common
set(src_main_unix
${src_unix_common}
unix/linux_glimp.cpp
unix/linux_qgl.cpp
unix/unix_glimp_common.cpp
null/null_snddma.cpp
)
set(src_sdl
sdl/sdl_gamma.cpp
sdl/sdl_glimp.cpp
sdl/sdl_input.cpp
)
set(src_botlib
botlib/be_aas_bspq3.cpp
botlib/be_aas_cluster.cpp
@ -320,6 +328,7 @@ set(src_jk2mp
${src_main_zlib}
${src_botlib}
${src_main_unix}
${src_sdl}
)
add_executable(jk2mp
@ -330,8 +339,9 @@ set_target_properties(jk2mp PROPERTIES COMPILE_DEFINITIONS "_JK2EXE;_FF_DISABLE;
target_link_libraries(jk2mp
m pthread
X11 Xxf86vm Xxf86dga
openal
${SDL_LIBRARY}
${OPENGL_gl_LIBRARY}
${OPENAL_LIBRARY}
)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")

View File

@ -76,6 +76,8 @@ char cl_cdkey[34] = " ";
#endif // USE_CD_KEY
cvar_t *cl_consoleKeys;
clientActive_t cl;
clientConnection_t clc;
clientStatic_t cls;
@ -2497,6 +2499,9 @@ void CL_Init( void ) {
Cvar_Get( "cl_maxPing", "800", CVAR_ARCHIVE );
// ~ and `, as keys and characters
cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "~ ` 0x7e 0x60", CVAR_ARCHIVE);
// userinfo
Cvar_Get ("name", "Padawan", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("rate", "4000", CVAR_USERINFO | CVAR_ARCHIVE );

View File

@ -375,6 +375,8 @@ extern cvar_t *cl_allowDownload;
extern cvar_t *cl_conXOffset;
extern cvar_t *cl_inGameVideo;
extern cvar_t *cl_consoleKeys;
//=================================================
//
@ -442,6 +444,7 @@ void IN_CenterView (void);
void CL_VerifyCode( void );
float CL_KeyState (kbutton_t *key);
int Key_StringToKeynum( char *str );
const char *Key_KeynumToString( int keynum/*, qboolean bTranslate */ ); //note: translate is only called for menu display not configs
//

View File

@ -747,6 +747,44 @@ void Parse3DMatrix (const char **buf_p, int z, int y, int x, float *m) {
COM_MatchToken( buf_p, ")" );
}
/*
===================
Com_HexStrToInt
===================
*/
int Com_HexStrToInt( const char *str )
{
if ( !str || !str[ 0 ] )
return -1;
// check for hex code
if( str[ 0 ] == '0' && str[ 1 ] == 'x' )
{
int i, n = 0;
for( i = 2; i < strlen( str ); i++ )
{
char digit;
n *= 16;
digit = tolower( str[ i ] );
if( digit >= '0' && digit <= '9' )
digit -= '0';
else if( digit >= 'a' && digit <= 'f' )
digit = digit - 'a' + 10;
else
return -1;
n += digit;
}
return n;
}
return -1;
}
/*
============================================================================

View File

@ -350,6 +350,8 @@ typedef int clipHandle_t;
#define MAX_QINT 0x7fffffff
#define MIN_QINT (-MAX_QINT-1)
#define ARRAY_LEN(x) (sizeof(x) / sizeof(*(x)))
#define STRARRAY_LEN(x) (ARRAY_LEN(x) - 1)
// angle indexes
#define PITCH 0 // up / down
@ -1028,6 +1030,7 @@ void SkipRestOfLine ( const char **data );
void Parse1DMatrix (const char **buf_p, int x, float *m);
void Parse2DMatrix (const char **buf_p, int y, int x, float *m);
void Parse3DMatrix (const char **buf_p, int z, int y, int x, float *m);
int Com_HexStrToInt( const char *str );
void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...);

View File

@ -5,7 +5,17 @@
#ifndef __QGL_H__
#define __QGL_H__
#if defined( __LINT__ )
#ifndef DYNAMIC_LINK_GL
#ifdef USE_LOCAL_HEADERS
# include "SDL_opengl.h"
#else
# include <SDL_opengl.h>
#endif
#include "qgl_linked.h"
#elif defined( __LINT__ )
#include <GL/gl.h>
@ -33,7 +43,7 @@
#include <GL/fxmesa.h>
#endif
#endif
#endif // !DYNAMIC_LINK_GL
#ifndef APIENTRY
#define APIENTRY
@ -119,6 +129,8 @@ extern void ( APIENTRY * qglUnlockArraysEXT) (void);
extern void ( APIENTRY * qglPointParameterfEXT)( GLenum, GLfloat);
extern void ( APIENTRY * qglPointParameterfvEXT)( GLenum, GLfloat *);
#ifdef DYNAMIC_LINK_GL
//===========================================================================
#if defined(MACOS_X)
@ -518,4 +530,5 @@ extern void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable );
#endif // _WIN32 && __linux__
#endif
#endif // DYNAMIC_LINK_GL
#endif // __QGL_H__

View File

@ -0,0 +1,336 @@
#define qglAccum glAccum
#define qglAlphaFunc glAlphaFunc
#define qglAreTexturesResident glAreTexturesResident
#define qglArrayElement glArrayElement
#define qglBegin glBegin
#define qglBindTexture glBindTexture
#define qglBitmap glBitmap
#define qglBlendFunc glBlendFunc
#define qglCallList glCallList
#define qglCallLists glCallLists
#define qglClear glClear
#define qglClearAccum glClearAccum
#define qglClearColor glClearColor
#define qglClearDepth glClearDepth
#define qglClearIndex glClearIndex
#define qglClearStencil glClearStencil
#define qglClipPlane glClipPlane
#define qglColor3b glColor3b
#define qglColor3bv glColor3bv
#define qglColor3d glColor3d
#define qglColor3dv glColor3dv
#define qglColor3f glColor3f
#define qglColor3fv glColor3fv
#define qglColor3i glColor3i
#define qglColor3iv glColor3iv
#define qglColor3s glColor3s
#define qglColor3sv glColor3sv
#define qglColor3ub glColor3ub
#define qglColor3ubv glColor3ubv
#define qglColor3ui glColor3ui
#define qglColor3uiv glColor3uiv
#define qglColor3us glColor3us
#define qglColor3usv glColor3usv
#define qglColor4b glColor4b
#define qglColor4bv glColor4bv
#define qglColor4d glColor4d
#define qglColor4dv glColor4dv
#define qglColor4f glColor4f
#define qglColor4fv glColor4fv
#define qglColor4i glColor4i
#define qglColor4iv glColor4iv
#define qglColor4s glColor4s
#define qglColor4sv glColor4sv
#define qglColor4ub glColor4ub
#define qglColor4ubv glColor4ubv
#define qglColor4ui glColor4ui
#define qglColor4uiv glColor4uiv
#define qglColor4us glColor4us
#define qglColor4usv glColor4usv
#define qglColorMask glColorMask
#define qglColorMaterial glColorMaterial
#define qglColorPointer glColorPointer
#define qglCopyPixels glCopyPixels
#define qglCopyTexImage1D glCopyTexImage1D
#define qglCopyTexImage2D glCopyTexImage2D
#define qglCopyTexSubImage1D glCopyTexSubImage1D
#define qglCopyTexSubImage2D glCopyTexSubImage2D
#define qglCullFace glCullFace
#define qglDeleteLists glDeleteLists
#define qglDeleteTextures glDeleteTextures
#define qglDepthFunc glDepthFunc
#define qglDepthMask glDepthMask
#define qglDepthRange glDepthRange
#define qglDisable glDisable
#define qglDisableClientState glDisableClientState
#define qglDrawArrays glDrawArrays
#define qglDrawBuffer glDrawBuffer
#define qglDrawElements glDrawElements
#define qglDrawPixels glDrawPixels
#define qglEdgeFlag glEdgeFlag
#define qglEdgeFlagPointer glEdgeFlagPointer
#define qglEdgeFlagv glEdgeFlagv
#define qglEnable glEnable
#define qglEnableClientState glEnableClientState
#define qglEnd glEnd
#define qglEndList glEndList
#define qglEvalCoord1d glEvalCoord1d
#define qglEvalCoord1dv glEvalCoord1dv
#define qglEvalCoord1f glEvalCoord1f
#define qglEvalCoord1fv glEvalCoord1fv
#define qglEvalCoord2d glEvalCoord2d
#define qglEvalCoord2dv glEvalCoord2dv
#define qglEvalCoord2f glEvalCoord2f
#define qglEvalCoord2fv glEvalCoord2fv
#define qglEvalMesh1 glEvalMesh1
#define qglEvalMesh2 glEvalMesh2
#define qglEvalPoint1 glEvalPoint1
#define qglEvalPoint2 glEvalPoint2
#define qglFeedbackBuffer glFeedbackBuffer
#define qglFinish glFinish
#define qglFlush glFlush
#define qglFogf glFogf
#define qglFogfv glFogfv
#define qglFogi glFogi
#define qglFogiv glFogiv
#define qglFrontFace glFrontFace
#define qglFrustum glFrustum
#define qglGenLists glGenLists
#define qglGenTextures glGenTextures
#define qglGetBooleanv glGetBooleanv
#define qglGetClipPlane glGetClipPlane
#define qglGetDoublev glGetDoublev
#define qglGetError glGetError
#define qglGetFloatv glGetFloatv
#define qglGetIntegerv glGetIntegerv
#define qglGetLightfv glGetLightfv
#define qglGetLightiv glGetLightiv
#define qglGetMapdv glGetMapdv
#define qglGetMapfv glGetMapfv
#define qglGetMapiv glGetMapiv
#define qglGetMaterialfv glGetMaterialfv
#define qglGetMaterialiv glGetMaterialiv
#define qglGetPixelMapfv glGetPixelMapfv
#define qglGetPixelMapuiv glGetPixelMapuiv
#define qglGetPixelMapusv glGetPixelMapusv
#define qglGetPointerv glGetPointerv
#define qglGetPolygonStipple glGetPolygonStipple
#define qglGetString glGetString
#define qglGetTexGendv glGetTexGendv
#define qglGetTexGenfv glGetTexGenfv
#define qglGetTexGeniv glGetTexGeniv
#define qglGetTexImage glGetTexImage
#define qglGetTexLevelParameterfv glGetTexLevelParameterfv
#define qglGetTexLevelParameteriv glGetTexLevelParameteriv
#define qglGetTexParameterfv glGetTexParameterfv
#define qglGetTexParameteriv glGetTexParameteriv
#define qglHint glHint
#define qglIndexMask glIndexMask
#define qglIndexPointer glIndexPointer
#define qglIndexd glIndexd
#define qglIndexdv glIndexdv
#define qglIndexf glIndexf
#define qglIndexfv glIndexfv
#define qglIndexi glIndexi
#define qglIndexiv glIndexiv
#define qglIndexs glIndexs
#define qglIndexsv glIndexsv
#define qglIndexub glIndexub
#define qglIndexubv glIndexubv
#define qglInitNames glInitNames
#define qglInterleavedArrays glInterleavedArrays
#define qglIsEnabled glIsEnabled
#define qglIsList glIsList
#define qglIsTexture glIsTexture
#define qglLightModelf glLightModelf
#define qglLightModelfv glLightModelfv
#define qglLightModeli glLightModeli
#define qglLightModeliv glLightModeliv
#define qglLightf glLightf
#define qglLightfv glLightfv
#define qglLighti glLighti
#define qglLightiv glLightiv
#define qglLineStipple glLineStipple
#define qglLineWidth glLineWidth
#define qglListBase glListBase
#define qglLoadIdentity glLoadIdentity
#define qglLoadMatrixd glLoadMatrixd
#define qglLoadMatrixf glLoadMatrixf
#define qglLoadName glLoadName
#define qglLogicOp glLogicOp
#define qglMap1d glMap1d
#define qglMap1f glMap1f
#define qglMap2d glMap2d
#define qglMap2f glMap2f
#define qglMapGrid1d glMapGrid1d
#define qglMapGrid1f glMapGrid1f
#define qglMapGrid2d glMapGrid2d
#define qglMapGrid2f glMapGrid2f
#define qglMaterialf glMaterialf
#define qglMaterialfv glMaterialfv
#define qglMateriali glMateriali
#define qglMaterialiv glMaterialiv
#define qglMatrixMode glMatrixMode
#define qglMultMatrixd glMultMatrixd
#define qglMultMatrixf glMultMatrixf
#define qglNewList glNewList
#define qglNormal3b glNormal3b
#define qglNormal3bv glNormal3bv
#define qglNormal3d glNormal3d
#define qglNormal3dv glNormal3dv
#define qglNormal3f glNormal3f
#define qglNormal3fv glNormal3fv
#define qglNormal3i glNormal3i
#define qglNormal3iv glNormal3iv
#define qglNormal3s glNormal3s
#define qglNormal3sv glNormal3sv
#define qglNormalPointer glNormalPointer
#define qglOrtho glOrtho
#define qglPassThrough glPassThrough
#define qglPixelMapfv glPixelMapfv
#define qglPixelMapuiv glPixelMapuiv
#define qglPixelMapusv glPixelMapusv
#define qglPixelStoref glPixelStoref
#define qglPixelStorei glPixelStorei
#define qglPixelTransferf glPixelTransferf
#define qglPixelTransferi glPixelTransferi
#define qglPixelZoom glPixelZoom
#define qglPointSize glPointSize
#define qglPolygonMode glPolygonMode
#define qglPolygonOffset glPolygonOffset
#define qglPolygonStipple glPolygonStipple
#define qglPopAttrib glPopAttrib
#define qglPopClientAttrib glPopClientAttrib
#define qglPopMatrix glPopMatrix
#define qglPopName glPopName
#define qglPrioritizeTextures glPrioritizeTextures
#define qglPushAttrib glPushAttrib
#define qglPushClientAttrib glPushClientAttrib
#define qglPushMatrix glPushMatrix
#define qglPushName glPushName
#define qglRasterPos2d glRasterPos2d
#define qglRasterPos2dv glRasterPos2dv
#define qglRasterPos2f glRasterPos2f
#define qglRasterPos2fv glRasterPos2fv
#define qglRasterPos2i glRasterPos2i
#define qglRasterPos2iv glRasterPos2iv
#define qglRasterPos2s glRasterPos2s
#define qglRasterPos2sv glRasterPos2sv
#define qglRasterPos3d glRasterPos3d
#define qglRasterPos3dv glRasterPos3dv
#define qglRasterPos3f glRasterPos3f
#define qglRasterPos3fv glRasterPos3fv
#define qglRasterPos3i glRasterPos3i
#define qglRasterPos3iv glRasterPos3iv
#define qglRasterPos3s glRasterPos3s
#define qglRasterPos3sv glRasterPos3sv
#define qglRasterPos4d glRasterPos4d
#define qglRasterPos4dv glRasterPos4dv
#define qglRasterPos4f glRasterPos4f
#define qglRasterPos4fv glRasterPos4fv
#define qglRasterPos4i glRasterPos4i
#define qglRasterPos4iv glRasterPos4iv
#define qglRasterPos4s glRasterPos4s
#define qglRasterPos4sv glRasterPos4sv
#define qglReadBuffer glReadBuffer
#define qglReadPixels glReadPixels
#define qglRectd glRectd
#define qglRectdv glRectdv
#define qglRectf glRectf
#define qglRectfv glRectfv
#define qglRecti glRecti
#define qglRectiv glRectiv
#define qglRects glRects
#define qglRectsv glRectsv
#define qglRenderMode glRenderMode
#define qglRotated glRotated
#define qglRotatef glRotatef
#define qglScaled glScaled
#define qglScalef glScalef
#define qglScissor glScissor
#define qglSelectBuffer glSelectBuffer
#define qglShadeModel glShadeModel
#define qglStencilFunc glStencilFunc
#define qglStencilMask glStencilMask
#define qglStencilOp glStencilOp
#define qglTexCoord1d glTexCoord1d
#define qglTexCoord1dv glTexCoord1dv
#define qglTexCoord1f glTexCoord1f
#define qglTexCoord1fv glTexCoord1fv
#define qglTexCoord1i glTexCoord1i
#define qglTexCoord1iv glTexCoord1iv
#define qglTexCoord1s glTexCoord1s
#define qglTexCoord1sv glTexCoord1sv
#define qglTexCoord2d glTexCoord2d
#define qglTexCoord2dv glTexCoord2dv
#define qglTexCoord2f glTexCoord2f
#define qglTexCoord2fv glTexCoord2fv
#define qglTexCoord2i glTexCoord2i
#define qglTexCoord2iv glTexCoord2iv
#define qglTexCoord2s glTexCoord2s
#define qglTexCoord2sv glTexCoord2sv
#define qglTexCoord3d glTexCoord3d
#define qglTexCoord3dv glTexCoord3dv
#define qglTexCoord3f glTexCoord3f
#define qglTexCoord3fv glTexCoord3fv
#define qglTexCoord3i glTexCoord3i
#define qglTexCoord3iv glTexCoord3iv
#define qglTexCoord3s glTexCoord3s
#define qglTexCoord3sv glTexCoord3sv
#define qglTexCoord4d glTexCoord4d
#define qglTexCoord4dv glTexCoord4dv
#define qglTexCoord4f glTexCoord4f
#define qglTexCoord4fv glTexCoord4fv
#define qglTexCoord4i glTexCoord4i
#define qglTexCoord4iv glTexCoord4iv
#define qglTexCoord4s glTexCoord4s
#define qglTexCoord4sv glTexCoord4sv
#define qglTexCoordPointer glTexCoordPointer
#define qglTexEnvf glTexEnvf
#define qglTexEnvfv glTexEnvfv
#define qglTexEnvi glTexEnvi
#define qglTexEnviv glTexEnviv
#define qglTexGend glTexGend
#define qglTexGendv glTexGendv
#define qglTexGenf glTexGenf
#define qglTexGenfv glTexGenfv
#define qglTexGeni glTexGeni
#define qglTexGeniv glTexGeniv
#define qglTexImage1D glTexImage1D
#define qglTexImage2D glTexImage2D
#define qglTexParameterf glTexParameterf
#define qglTexParameterfv glTexParameterfv
#define qglTexParameteri glTexParameteri
#define qglTexParameteriv glTexParameteriv
#define qglTexSubImage1D glTexSubImage1D
#define qglTexSubImage2D glTexSubImage2D
#define qglTranslated glTranslated
#define qglTranslatef glTranslatef
#define qglVertex2d glVertex2d
#define qglVertex2dv glVertex2dv
#define qglVertex2f glVertex2f
#define qglVertex2fv glVertex2fv
#define qglVertex2i glVertex2i
#define qglVertex2iv glVertex2iv
#define qglVertex2s glVertex2s
#define qglVertex2sv glVertex2sv
#define qglVertex3d glVertex3d
#define qglVertex3dv glVertex3dv
#define qglVertex3f glVertex3f
#define qglVertex3fv glVertex3fv
#define qglVertex3i glVertex3i
#define qglVertex3iv glVertex3iv
#define qglVertex3s glVertex3s
#define qglVertex3sv glVertex3sv
#define qglVertex4d glVertex4d
#define qglVertex4dv glVertex4dv
#define qglVertex4f glVertex4f
#define qglVertex4fv glVertex4fv
#define qglVertex4i glVertex4i
#define qglVertex4iv glVertex4iv
#define qglVertex4s glVertex4s
#define qglVertex4sv glVertex4sv
#define qglVertexPointer glVertexPointer
#define qglViewport glViewport

View File

@ -853,11 +853,7 @@ void R_Register( void )
r_ext_gamma_control = ri.Cvar_Get( "r_ext_gamma_control", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_ext_multitexture = ri.Cvar_Get( "r_ext_multitexture", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_ext_compiled_vertex_array = ri.Cvar_Get( "r_ext_compiled_vertex_array", "1", CVAR_ARCHIVE | CVAR_LATCH);
#ifdef __linux__ // broken on linux
r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "0", CVAR_ARCHIVE | CVAR_LATCH);
#else
r_ext_texture_env_add = ri.Cvar_Get( "r_ext_texture_env_add", "1", CVAR_ARCHIVE | CVAR_LATCH);
#endif
r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "1", CVAR_ARCHIVE );
@ -869,11 +865,7 @@ void R_Register( void )
r_texturebitslm = ri.Cvar_Get( "r_texturebitslm", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_colorbits = ri.Cvar_Get( "r_colorbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_stereo = ri.Cvar_Get( "r_stereo", "0", CVAR_ARCHIVE | CVAR_LATCH );
#ifdef __linux__
r_stencilbits = ri.Cvar_Get( "r_stencilbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
#else
r_stencilbits = ri.Cvar_Get( "r_stencilbits", "8", CVAR_ARCHIVE | CVAR_LATCH );
#endif
r_depthbits = ri.Cvar_Get( "r_depthbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH);

92
CODE-mp/sdl/sdl_gamma.cpp Normal file
View File

@ -0,0 +1,92 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifdef USE_LOCAL_HEADERS
# include "SDL.h"
#else
# include <SDL.h>
#endif
#include "../game/q_shared.h"
#include "../renderer/tr_local.h"
#include "../qcommon/qcommon.h"
/*
=================
GLimp_SetGamma
=================
*/
void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] )
{
Uint16 table[3][256];
int i, j;
if( !glConfig.deviceSupportsGamma || r_ignorehwgamma->integer > 0 )
return;
for (i = 0; i < 256; i++)
{
table[0][i] = ( ( ( Uint16 ) red[i] ) << 8 ) | red[i];
table[1][i] = ( ( ( Uint16 ) green[i] ) << 8 ) | green[i];
table[2][i] = ( ( ( Uint16 ) blue[i] ) << 8 ) | blue[i];
}
#ifdef _WIN32
#include <windows.h>
// Win2K and newer put this odd restriction on gamma ramps...
{
OSVERSIONINFO vinfo;
vinfo.dwOSVersionInfoSize = sizeof( vinfo );
GetVersionEx( &vinfo );
if( vinfo.dwMajorVersion >= 5 && vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
ri.Printf( PRINT_DEVELOPER, "performing gamma clamp.\n" );
for( j = 0 ; j < 3 ; j++ )
{
for( i = 0 ; i < 128 ; i++ )
{
if( table[ j ] [ i] > ( ( 128 + i ) << 8 ) )
table[ j ][ i ] = ( 128 + i ) << 8;
}
if( table[ j ] [127 ] > 254 << 8 )
table[ j ][ 127 ] = 254 << 8;
}
}
}
#endif
// enforce constantly increasing
for (j = 0; j < 3; j++)
{
for (i = 1; i < 256; i++)
{
if (table[j][i] < table[j][i-1])
table[j][i] = table[j][i-1];
}
}
SDL_SetGammaRamp(table[0], table[1], table[2]);
}

970
CODE-mp/sdl/sdl_glimp.cpp Normal file
View File

@ -0,0 +1,970 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifdef USE_LOCAL_HEADERS
# include "SDL.h"
#else
# include <SDL.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "../renderer/tr_local.h"
#include "sdl_local.h"
#ifdef notyet
#include "sdl_icon.h"
#endif
#define CLIENT_WINDOW_TITLE "Jedi Outcast"
#define CLIENT_WINDOW_MIN_TITLE "JO"
/* Just hack it for now. */
#ifdef MACOS_X
#include <OpenGL/OpenGL.h>
typedef CGLContextObj QGLContext;
#define GLimp_GetCurrentContext() CGLGetCurrentContext()
#define GLimp_SetCurrentContext(ctx) CGLSetCurrentContext(ctx)
#else
typedef void *QGLContext;
#define GLimp_GetCurrentContext() (NULL)
#define GLimp_SetCurrentContext(ctx)
#endif
static QGLContext opengl_context;
static float displayAspect;
typedef enum
{
RSERR_OK,
RSERR_INVALID_FULLSCREEN,
RSERR_INVALID_MODE,
RSERR_UNKNOWN
} rserr_t;
static SDL_Surface *screen = NULL;
static const SDL_VideoInfo *videoInfo = NULL;
cvar_t *r_allowSoftwareGL; // Don't abort out if a hardware visual can't be obtained
cvar_t *r_allowResize; // make window resizable
cvar_t *r_centerWindow;
cvar_t *r_sdlDriver;
cvar_t *r_noborder;
/*
===============
GLimp_Shutdown
===============
*/
void GLimp_Shutdown( void )
{
IN_Shutdown();
SDL_QuitSubSystem( SDL_INIT_VIDEO );
screen = NULL;
}
/*
===============
GLimp_Minimize
Minimize the game so that user is back at the desktop
===============
*/
void GLimp_Minimize(void)
{
SDL_WM_IconifyWindow();
}
/*
===============
GLimp_LogComment
===============
*/
void GLimp_LogComment( char *comment )
{
}
/*
===============
GLimp_CompareModes
===============
*/
static int GLimp_CompareModes( const void *a, const void *b )
{
const float ASPECT_EPSILON = 0.001f;
SDL_Rect *modeA = *(SDL_Rect **)a;
SDL_Rect *modeB = *(SDL_Rect **)b;
float aspectA = (float)modeA->w / (float)modeA->h;
float aspectB = (float)modeB->w / (float)modeB->h;
int areaA = modeA->w * modeA->h;
int areaB = modeB->w * modeB->h;
float aspectDiffA = fabs( aspectA - displayAspect );
float aspectDiffB = fabs( aspectB - displayAspect );
float aspectDiffsDiff = aspectDiffA - aspectDiffB;
if( aspectDiffsDiff > ASPECT_EPSILON )
return 1;
else if( aspectDiffsDiff < -ASPECT_EPSILON )
return -1;
else
return areaA - areaB;
}
/*
===============
GLimp_DetectAvailableModes
===============
*/
static void GLimp_DetectAvailableModes(void)
{
char buf[ MAX_STRING_CHARS ] = { 0 };
SDL_Rect **modes;
int numModes;
int i;
modes = SDL_ListModes( videoInfo->vfmt, SDL_OPENGL | SDL_FULLSCREEN );
if( !modes )
{
ri.Printf( PRINT_WARNING, "Can't get list of available modes\n" );
return;
}
if( modes == (SDL_Rect **)-1 )
{
ri.Printf( PRINT_ALL, "Display supports any resolution\n" );
return; // can set any resolution
}
for( numModes = 0; modes[ numModes ]; numModes++ );
if( numModes > 1 )
qsort( modes, numModes, sizeof( SDL_Rect* ), GLimp_CompareModes );
for( i = 0; i < numModes; i++ )
{
const char *newModeString = va( "%ux%u ", modes[ i ]->w, modes[ i ]->h );
if( strlen( newModeString ) < (int)sizeof( buf ) - strlen( buf ) )
Q_strcat( buf, sizeof( buf ), newModeString );
else
ri.Printf( PRINT_WARNING, "Skipping mode %ux%x, buffer too small\n", modes[i]->w, modes[i]->h );
}
if( *buf )
{
buf[ strlen( buf ) - 1 ] = 0;
ri.Printf( PRINT_ALL, "Available modes: '%s'\n", buf );
ri.Cvar_Set( "r_availableModes", buf );
}
}
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
const char* glstring;
int sdlcolorbits;
int colorbits, depthbits, stencilbits;
int tcolorbits, tdepthbits, tstencilbits;
int samples;
int i = 0;
SDL_Surface *vidscreen = NULL;
Uint32 flags = SDL_OPENGL;
ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");
if ( r_allowResize->integer )
flags |= SDL_RESIZABLE;
if( videoInfo == NULL )
{
static SDL_VideoInfo sVideoInfo;
static SDL_PixelFormat sPixelFormat;
videoInfo = SDL_GetVideoInfo( );
// Take a copy of the videoInfo
memcpy( &sPixelFormat, videoInfo->vfmt, sizeof( SDL_PixelFormat ) );
sPixelFormat.palette = NULL; // Should already be the case
memcpy( &sVideoInfo, videoInfo, sizeof( SDL_VideoInfo ) );
sVideoInfo.vfmt = &sPixelFormat;
videoInfo = &sVideoInfo;
if( videoInfo->current_h > 0 )
{
// Guess the display aspect ratio through the desktop resolution
// by assuming (relatively safely) that it is set at or close to
// the display's native aspect ratio
displayAspect = (float)videoInfo->current_w / (float)videoInfo->current_h;
ri.Printf( PRINT_ALL, "Estimated display aspect: %.3f\n", displayAspect );
}
else
{
ri.Printf( PRINT_ALL,
"Cannot estimate display aspect, assuming 1.333\n" );
}
}
ri.Printf (PRINT_ALL, "...setting mode %d:", mode );
if (mode == -2)
{
// use desktop video resolution
if( videoInfo->current_h > 0 )
{
glConfig.vidWidth = videoInfo->current_w;
glConfig.vidHeight = videoInfo->current_h;
}
else
{
glConfig.vidWidth = 640;
glConfig.vidHeight = 480;
ri.Printf( PRINT_ALL,
"Cannot determine display resolution, assuming 640x480\n" );
}
glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
}
else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
{
ri.Printf( PRINT_ALL, " invalid mode\n" );
return RSERR_INVALID_MODE;
}
ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);
if (fullscreen)
{
flags |= SDL_FULLSCREEN;
glConfig.isFullscreen = qtrue;
}
else
{
if (noborder)
flags |= SDL_NOFRAME;
glConfig.isFullscreen = qfalse;
}
colorbits = r_colorbits->value;
if ((!colorbits) || (colorbits >= 32))
colorbits = 24;
if (!r_depthbits->value)
depthbits = 24;
else
depthbits = r_depthbits->value;
stencilbits = r_stencilbits->value;
#ifdef notyet
samples = r_ext_multisample->value;
#else
samples = 0;
#endif
for (i = 0; i < 16; i++)
{
// 0 - default
// 1 - minus colorbits
// 2 - minus depthbits
// 3 - minus stencil
if ((i % 4) == 0 && i)
{
// one pass, reduce
switch (i / 4)
{
case 2 :
if (colorbits == 24)
colorbits = 16;
break;
case 1 :
if (depthbits == 24)
depthbits = 16;
else if (depthbits == 16)
depthbits = 8;
case 3 :
if (stencilbits == 24)
stencilbits = 16;
else if (stencilbits == 16)
stencilbits = 8;
}
}
tcolorbits = colorbits;
tdepthbits = depthbits;
tstencilbits = stencilbits;
if ((i % 4) == 3)
{ // reduce colorbits
if (tcolorbits == 24)
tcolorbits = 16;
}
if ((i % 4) == 2)
{ // reduce depthbits
if (tdepthbits == 24)
tdepthbits = 16;
else if (tdepthbits == 16)
tdepthbits = 8;
}
if ((i % 4) == 1)
{ // reduce stencilbits
if (tstencilbits == 24)
tstencilbits = 16;
else if (tstencilbits == 16)
tstencilbits = 8;
else
tstencilbits = 0;
}
sdlcolorbits = 4;
if (tcolorbits == 24)
sdlcolorbits = 8;
#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
if (sdlcolorbits == 4)
sdlcolorbits = 0; /* Use minimum size for 16-bit color */
/* Need alpha or else SGIs choose 36+ bit RGB mode */
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );
#ifdef notyet
if(r_stereoEnabled->integer)
{
glConfig.stereoEnabled = qtrue;
SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
}
else
{
glConfig.stereoEnabled = qfalse;
SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
}
#endif
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
#if 0 // See http://bugzilla.icculus.org/show_bug.cgi?id=3526
// If not allowing software GL, demand accelerated
if( !r_allowSoftwareGL->integer )
{
if( SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ) < 0 )
{
ri.Printf( PRINT_ALL, "Unable to guarantee accelerated "
"visual with libSDL < 1.2.10\n" );
}
}
#endif
if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) < 0 )
ri.Printf( PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n" );
#ifdef USE_ICON
{
SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
(void *)CLIENT_WINDOW_ICON.pixel_data,
CLIENT_WINDOW_ICON.width,
CLIENT_WINDOW_ICON.height,
CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
);
SDL_WM_SetIcon( icon, NULL );
SDL_FreeSurface( icon );
}
#endif
SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_MIN_TITLE);
SDL_ShowCursor(0);
if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
{
ri.Printf( PRINT_DEVELOPER, "SDL_SetVideoMode failed: %s\n", SDL_GetError( ) );
continue;
}
opengl_context = GLimp_GetCurrentContext();
ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);
glConfig.colorBits = tcolorbits;
glConfig.depthBits = tdepthbits;
glConfig.stencilBits = tstencilbits;
break;
}
GLimp_DetectAvailableModes();
if (!vidscreen)
{
ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
return RSERR_INVALID_MODE;
}
screen = vidscreen;
glstring = (char *) qglGetString (GL_RENDERER);
ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );
return RSERR_OK;
}
/*
===============
GLimp_StartDriverAndSetMode
===============
*/
static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qboolean noborder)
{
rserr_t err;
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
char driverName[ 64 ];
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
ri.Printf( PRINT_ALL, "SDL_Init( SDL_INIT_VIDEO ) FAILED (%s)\n",
SDL_GetError());
return qfalse;
}
SDL_VideoDriverName( driverName, sizeof( driverName ) - 1 );
ri.Printf( PRINT_ALL, "SDL using driver \"%s\"\n", driverName );
ri.Cvar_Set( "r_sdlDriver", driverName );
}
if (fullscreen && Cvar_VariableIntegerValue( "in_nograb" ) )
{
ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
ri.Cvar_Set( "r_fullscreen", "0" );
r_fullscreen->modified = qfalse;
fullscreen = qfalse;
}
err = (rserr_t) GLimp_SetMode(mode, fullscreen, noborder);
switch ( err )
{
case RSERR_INVALID_FULLSCREEN:
ri.Printf( PRINT_ALL, "...WARNING: fullscreen unavailable in this mode\n" );
return qfalse;
case RSERR_INVALID_MODE:
ri.Printf( PRINT_ALL, "...WARNING: could not set the given mode (%d)\n", mode );
return qfalse;
default:
break;
}
return qtrue;
}
static void GLW_InitTextureCompression( void )
{
qboolean newer_tc, old_tc;
// Check for available tc methods.
newer_tc = ( strstr( glConfig.extensions_string, "ARB_texture_compression" )
&& strstr( glConfig.extensions_string, "EXT_texture_compression_s3tc" )) ? qtrue : qfalse;
old_tc = ( strstr( glConfig.extensions_string, "GL_S3_s3tc" )) ? qtrue : qfalse;
if ( old_tc )
{
ri.Printf( PRINT_ALL, "...GL_S3_s3tc available\n" );
}
if ( newer_tc )
{
ri.Printf( PRINT_ALL, "...GL_EXT_texture_compression_s3tc available\n" );
}
if ( !r_ext_compressed_textures->value )
{
// Compressed textures are off
glConfig.textureCompression = TC_NONE;
ri.Printf( PRINT_ALL, "...ignoring texture compression\n" );
}
else if ( !old_tc && !newer_tc )
{
// Requesting texture compression, but no method found
glConfig.textureCompression = TC_NONE;
ri.Printf( PRINT_ALL, "...no supported texture compression method found\n" );
ri.Printf( PRINT_ALL, ".....ignoring texture compression\n" );
}
else
{
// some form of supported texture compression is avaiable, so see if the user has a preference
if ( r_ext_preferred_tc_method->integer == TC_NONE )
{
// No preference, so pick the best
if ( newer_tc )
{
ri.Printf( PRINT_ALL, "...no tc preference specified\n" );
ri.Printf( PRINT_ALL, ".....using GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
else
{
ri.Printf( PRINT_ALL, "...no tc preference specified\n" );
ri.Printf( PRINT_ALL, ".....using GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
}
else
{
// User has specified a preference, now see if this request can be honored
if ( old_tc && newer_tc )
{
// both are avaiable, so we can use the desired tc method
if ( r_ext_preferred_tc_method->integer == TC_S3TC )
{
ri.Printf( PRINT_ALL, "...using preferred tc method, GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
else
{
ri.Printf( PRINT_ALL, "...using preferred tc method, GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
}
else
{
// Both methods are not available, so this gets trickier
if ( r_ext_preferred_tc_method->integer == TC_S3TC )
{
// Preferring to user older compression
if ( old_tc )
{
ri.Printf( PRINT_ALL, "...using GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
else
{
// Drat, preference can't be honored
ri.Printf( PRINT_ALL, "...preferred tc method, GL_S3_s3tc not available\n" );
ri.Printf( PRINT_ALL, ".....falling back to GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
}
else
{
// Preferring to user newer compression
if ( newer_tc )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
else
{
// Drat, preference can't be honored
ri.Printf( PRINT_ALL, "...preferred tc method, GL_EXT_texture_compression_s3tc not available\n" );
ri.Printf( PRINT_ALL, ".....falling back to GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
}
}
}
}
}
/*
** GLW_InitExtensions
*/
cvar_t *r_ATI_NPATCH_available = NULL;
static void GLimp_InitExtensions( void )
{
if ( !r_allowExtensions->integer )
{
ri.Printf( PRINT_ALL, "*** IGNORING OPENGL EXTENSIONS ***\n" );
return;
}
ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
// Select our tc scheme
GLW_InitTextureCompression();
// GL_EXT_texture_env_add
glConfig.textureEnvAddAvailable = qfalse;
if ( strstr( glConfig.extensions_string, "EXT_texture_env_add" ) )
{
if ( r_ext_texture_env_add->integer )
{
glConfig.textureEnvAddAvailable = qtrue;
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_env_add\n" );
}
else
{
glConfig.textureEnvAddAvailable = qfalse;
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_env_add\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_texture_env_add not found\n" );
}
// GL_EXT_texture_filter_anisotropic
glConfig.textureFilterAnisotropicAvailable = qfalse;
if ( strstr( glConfig.extensions_string, "EXT_texture_filter_anisotropic" ) )
{
glConfig.textureFilterAnisotropicAvailable = qtrue;
ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic available\n" );
if ( r_ext_texture_filter_anisotropic->integer )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic\n" );
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" );
}
ri.Cvar_Set( "r_ext_texture_filter_anisotropic_avail", "1" );
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" );
ri.Cvar_Set( "r_ext_texture_filter_anisotropic_avail", "0" );
}
// GL_EXT_clamp_to_edge
glConfig.clampToEdgeAvailable = qfalse;
if ( strstr( glConfig.extensions_string, "GL_EXT_texture_edge_clamp" ) )
{
glConfig.clampToEdgeAvailable = qtrue;
ri.Printf( PRINT_ALL, "...Using GL_EXT_texture_edge_clamp\n" );
}
// GL_ARB_multitexture
qglMultiTexCoord2fARB = NULL;
qglActiveTextureARB = NULL;
qglClientActiveTextureARB = NULL;
if ( strstr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
{
if ( r_ext_multitexture->integer )
{
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) SDL_GL_GetProcAddress( "glMultiTexCoord2fARB" );
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glActiveTextureARB" );
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glClientActiveTextureARB" );
if ( qglActiveTextureARB )
{
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures );
if ( glConfig.maxActiveTextures > 1 )
{
ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
}
else
{
qglMultiTexCoord2fARB = NULL;
qglActiveTextureARB = NULL;
qglClientActiveTextureARB = NULL;
ri.Printf( PRINT_ALL, "...not using GL_ARB_multitexture, < 2 texture units\n" );
}
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" );
}
// GL_EXT_compiled_vertex_array
qglLockArraysEXT = NULL;
qglUnlockArraysEXT = NULL;
if ( strstr( glConfig.extensions_string, "GL_EXT_compiled_vertex_array" ) )
{
if ( r_ext_compiled_vertex_array->integer )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) SDL_GL_GetProcAddress( "glLockArraysEXT" );
qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) SDL_GL_GetProcAddress( "glUnlockArraysEXT" );
if (!qglLockArraysEXT || !qglUnlockArraysEXT) {
ri.Error (ERR_FATAL, "bad getprocaddress");
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_compiled_vertex_array\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
}
qglPointParameterfEXT = NULL;
qglPointParameterfvEXT = NULL;
if ( strstr( glConfig.extensions_string, "GL_EXT_point_parameters" ) )
{
if ( r_ext_compiled_vertex_array->integer || 1)
{
ri.Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" );
qglPointParameterfEXT = ( void ( APIENTRY * )( GLenum, GLfloat) ) SDL_GL_GetProcAddress( "glPointParameterfEXT" );
qglPointParameterfvEXT = ( void ( APIENTRY * )( GLenum, GLfloat *) ) SDL_GL_GetProcAddress( "glPointParameterfvEXT" );
if (!qglPointParameterfEXT || !qglPointParameterfvEXT)
{
ri.Error (ERR_FATAL, "bad getprocaddress");
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_point_parameters\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" );
}
#ifdef _NPATCH
// GL_ATI_pn_triangles
qglPNTrianglesiATI = NULL;
r_ATI_NPATCH_available = ri.Cvar_Get( "r_ATI_NPATCH_available", "0",CVAR_ROM );
/* if ( strstr( glConfig.extensions_string, "GL_ATI_pn_triangles" ) )
{
ri.Cvar_Set( "r_ATI_NPATCH_available", "1" );
if ( r_ati_pn_triangles->integer )
{
ri.Printf( PRINT_ALL, "...using GL_ATI_pn_triangles\n" );
qglPNTrianglesiATI = ( void ( APIENTRY * )( GLenum, GLint ) ) SDL_GL_GetProcAddress( "glPNTrianglesiATI" );
if (!qglPNTrianglesiATI) {
ri.Error (ERR_FATAL, "bad getprocaddress");
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_ATI_pn_triangles\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_ATI_pn_triangles not found\n" );
}
*/
#endif // _NPATCH
}
#define R_MODE_FALLBACK 3 // 640 * 480
/*
===============
GLimp_Init
This routine is responsible for initializing the OS specific portions
of OpenGL
===============
*/
void GLimp_Init( void )
{
r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH );
r_sdlDriver = ri.Cvar_Get( "r_sdlDriver", "", CVAR_ROM );
r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE );
r_centerWindow = ri.Cvar_Get( "r_centerWindow", "0", CVAR_ARCHIVE );
r_noborder = Cvar_Get( "r_noborder", "0", CVAR_ARCHIVE );
qboolean fullscreen, noborder;
if( Cvar_VariableIntegerValue( "com_abnormalExit" ) )
{
ri.Cvar_Set( "r_mode", va( "%d", R_MODE_FALLBACK ) );
ri.Cvar_Set( "r_fullscreen", "0" );
ri.Cvar_Set( "r_centerWindow", "0" );
ri.Cvar_Set( "com_abnormalExit", "0" );
}
#ifdef notyet
Sys_SetEnv( "SDL_VIDEO_CENTERED", r_centerWindow->integer ? "1" : "" );
#endif
Sys_GLimpInit( );
fullscreen = (r_fullscreen->integer) ? qtrue : qfalse;
noborder = (r_noborder->integer) ? qtrue : qfalse;
// Create the window and set up the context
if(GLimp_StartDriverAndSetMode(r_mode->integer, fullscreen, noborder))
goto success;
// Try again, this time in a platform specific "safe mode"
Sys_GLimpSafeInit( );
if(GLimp_StartDriverAndSetMode(r_mode->integer, fullscreen, qfalse))
goto success;
// Finally, try the default screen resolution
if( r_mode->integer != R_MODE_FALLBACK )
{
ri.Printf( PRINT_ALL, "Setting r_mode %d failed, falling back on r_mode %d\n",
r_mode->integer, R_MODE_FALLBACK );
if(GLimp_StartDriverAndSetMode(R_MODE_FALLBACK, qfalse, qfalse))
goto success;
}
// Nothing worked, give up
ri.Error( ERR_FATAL, "GLimp_Init() - could not load OpenGL subsystem" );
success:
#if 0
// This values force the UI to disable driver selection
glConfig.driverType = GLDRV_ICD;
glConfig.hardwareType = GLHW_GENERIC;
#endif
glConfig.deviceSupportsGamma = (SDL_SetGamma( 1.0f, 1.0f, 1.0f ) >= 0) ? qtrue : qfalse;
// Mysteriously, if you use an NVidia graphics card and multiple monitors,
// SDL_SetGamma will incorrectly return false... the first time; ask
// again and you get the correct answer. This is a suspected driver bug, see
// http://bugzilla.icculus.org/show_bug.cgi?id=4316
glConfig.deviceSupportsGamma = (SDL_SetGamma( 1.0f, 1.0f, 1.0f ) >= 0) ? qtrue : qfalse;
if ( -1 == r_ignorehwgamma->integer)
glConfig.deviceSupportsGamma = qtrue;
if ( 1 == r_ignorehwgamma->integer)
glConfig.deviceSupportsGamma = qfalse;
// get our config strings
const char* glstring;
glstring = (const char *)qglGetString (GL_VENDOR);
if (!glstring) {
glstring = "invalid driver";
}
Q_strncpyz( glConfig.vendor_string, glstring, sizeof( glConfig.vendor_string ) );
glstring = (const char *)qglGetString (GL_RENDERER);
if (!glstring) {
glstring = "invalid driver";
}
Q_strncpyz( glConfig.renderer_string, glstring, sizeof( glConfig.renderer_string ) );
glstring = (const char *)qglGetString (GL_VERSION);
if (!glstring) {
glstring = "invalid driver";
}
Q_strncpyz( glConfig.version_string, glstring, sizeof( glConfig.version_string ) );
glstring = (const char *)qglGetString (GL_EXTENSIONS);
if (!glstring) {
glstring = "invalid driver";
}
Q_strncpyz( glConfig.extensions_string, glstring, sizeof( glConfig.extensions_string ) );
// OpenGL driver constants
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.maxTextureSize );
// stubbed or broken drivers may have reported 0...
if ( glConfig.maxTextureSize <= 0 )
{
glConfig.maxTextureSize = 0;
}
// initialize extensions
GLimp_InitExtensions( );
ri.Cvar_Get( "r_availableModes", "", CVAR_ROM );
// This depends on SDL_INIT_VIDEO, hence having it here
IN_Init( );
}
/*
===============
GLimp_EndFrame
Responsible for doing a swapbuffers
===============
*/
void GLimp_EndFrame( void )
{
// don't flip if drawing to front buffer
if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 )
{
SDL_GL_SwapBuffers();
}
if( r_fullscreen->modified )
{
qboolean fullscreen;
qboolean needToToggle = qtrue;
qboolean sdlToggled = qfalse;
SDL_Surface *s = SDL_GetVideoSurface( );
if( s )
{
// Find out the current state
fullscreen = (!!( s->flags & SDL_FULLSCREEN )) ? qtrue : qfalse;
if( r_fullscreen->integer && Cvar_VariableIntegerValue( "in_nograb" ) )
{
ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
ri.Cvar_Set( "r_fullscreen", "0" );
r_fullscreen->modified = qfalse;
}
// Is the state we want different from the current state?
needToToggle = (!!r_fullscreen->integer != fullscreen) ? qtrue : qfalse;
if( needToToggle )
sdlToggled = (SDL_WM_ToggleFullScreen( s )) ? qtrue : qfalse;
}
if( needToToggle )
{
// SDL_WM_ToggleFullScreen didn't work, so do it the slow way
if( !sdlToggled )
ri.Cmd_ExecuteText(EXEC_APPEND, "vid_restart");
IN_Restart( );
}
r_fullscreen->modified = qfalse;
}
}

1107
CODE-mp/sdl/sdl_input.cpp Normal file

File diff suppressed because it is too large Load Diff

7
CODE-mp/sdl/sdl_local.h Normal file
View File

@ -0,0 +1,7 @@
void IN_Init( void );
void IN_Shutdown( void );
void IN_Restart( void );
void Sys_GLimpSafeInit( void );
void Sys_GLimpInit( void );
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );

View File

@ -0,0 +1,82 @@
#include <pthread.h>
#include <semaphore.h>
#include "../game/q_shared.h"
/*
===========================================================
SMP acceleration
===========================================================
*/
sem_t renderCommandsEvent;
sem_t renderCompletedEvent;
sem_t renderActiveEvent;
void (*glimpRenderThread)( void );
void *GLimp_RenderThreadWrapper( void *stub ) {
glimpRenderThread();
}
/*
=======================
GLimp_SpawnRenderThread
=======================
*/
pthread_t renderThreadHandle;
qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) {
sem_init( &renderCommandsEvent, 0, 0 );
sem_init( &renderCompletedEvent, 0, 0 );
sem_init( &renderActiveEvent, 0, 0 );
glimpRenderThread = function;
if (pthread_create( &renderThreadHandle, NULL,
GLimp_RenderThreadWrapper, NULL)) {
return qfalse;
}
return qtrue;
}
static void *smpData;
void *GLimp_RendererSleep( void ) {
void *data;
// after this, the front end can exit GLimp_FrontEndSleep
sem_post ( &renderCompletedEvent );
sem_wait ( &renderCommandsEvent );
data = smpData;
// after this, the main thread can exit GLimp_WakeRenderer
sem_post ( &renderActiveEvent );
return data;
}
void GLimp_FrontEndSleep( void ) {
sem_wait ( &renderCompletedEvent );
}
void GLimp_WakeRenderer( void *data ) {
smpData = data;
// after this, the renderer can continue through GLimp_RendererSleep
sem_post( &renderCommandsEvent );
sem_wait( &renderActiveEvent );
}
void Sys_GLimpInit( void )
{
}
void Sys_GLimpSafeInit( void )
{
}

View File

@ -211,7 +211,7 @@ void Sys_Init(void)
Cvar_Set( "username", Sys_GetCurrentUser() );
IN_Init();
// IN_Init();
}

View File

@ -28,8 +28,6 @@ copy *.so to your base directory
Known issues:
When running windowed the mouse does not work in the menus.
With i386 linux with i965 graphics, levels seem to be zoomed in
to point where only textures are seen. Does not seem to
affect GL rendered cutscenes or OpenBSD/i386 with slightly older mesa.

View File

@ -33,11 +33,14 @@ add_definitions( -D_IMMERSION_DISABLE )
add_definitions( -DNDEBUG )
add_definitions( -DFINAL_BUILD )
include_directories(/usr/X11R6/include/)
link_directories(/usr/X11R6/lib)
find_package (SDL REQUIRED)
include_directories(${SDL_INCLUDE_DIR})
include_directories(/usr/local/include/)
link_directories(/usr/local/lib)
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
find_package(OpenAL REQUIRED)
include_directories(${OPENAL_INCLUDE_DIR})
set(src_client
client/cl_cgame.cpp
@ -252,11 +255,16 @@ set(src_jpeg
set(src_unix
unix/unix_main.cpp
unix/unix_shared.cpp
unix/linux_glimp.cpp
unix/linux_qgl.cpp
unix/unix_glimp_common.cpp
null/null_snddma.cpp
)
set(src_sdl
sdl/sdl_gamma.cpp
sdl/sdl_glimp.cpp
sdl/sdl_input.cpp
)
set(src_starwars
${src_ff}
${src_client}
@ -270,6 +278,7 @@ set(src_starwars
${src_main_game}
${src_jpeg}
${src_unix}
${src_sdl}
)
add_executable(jk2sp
@ -280,8 +289,9 @@ set_target_properties(jk2sp PROPERTIES COMPILE_DEFINITIONS "_JK2EXE;_FF_DISABLE"
target_link_libraries(jk2sp
m pthread
X11 Xxf86vm Xxf86dga
openal
${SDL_LIBRARY}
${OPENGL_gl_LIBRARY}
${OPENAL_LIBRARY}
)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")

View File

@ -60,6 +60,8 @@ cvar_t *cl_updateInfoString;
cvar_t *cl_ingameVideo;
cvar_t *cl_consoleKeys;
clientActive_t cl;
clientConnection_t clc;
clientStatic_t cls;
@ -1187,6 +1189,9 @@ void CL_Init( void ) {
cl_updateInfoString = Cvar_Get( "cl_updateInfoString", "", CVAR_ROM );
// ~ and `, as keys and characters
cl_consoleKeys = Cvar_Get( "cl_consoleKeys", "~ ` 0x7e 0x60", CVAR_ARCHIVE);
// userinfo
Cvar_Get ("name", "Kyle", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE );

View File

@ -285,6 +285,8 @@ extern cvar_t *m_filter;
extern cvar_t *cl_activeAction;
extern cvar_t *cl_consoleKeys;
//=================================================
//
@ -330,6 +332,7 @@ void CL_WritePacket( void );
void IN_CenterView (void);
float CL_KeyState (kbutton_t *key);
int Key_StringToKeynum( char *str );
const char *Key_KeynumToString( int keynum/*, qboolean bTranslate*/ ); //note: translate is only called for menu display not configs
//
@ -429,8 +432,9 @@ void CL_FirstSnapshot( void );
//
void CL_InitUI( void );
void CL_ShutdownUI( void );
int Key_GetCatcher( void );
void CL_GenericMenu_f(void);
void CL_DataPad_f(void);
void CL_EndScreenDissolve_f(void);
#endif //__CLIENT_H__
#endif //__CLIENT_H__

View File

@ -568,6 +568,44 @@ void Parse3DMatrix ( const char **buf_p, int z, int y, int x, float *m) {
COM_MatchToken( buf_p, ")" );
}
/*
===================
Com_HexStrToInt
===================
*/
int Com_HexStrToInt( const char *str )
{
if ( !str || !str[ 0 ] )
return -1;
// check for hex code
if( str[ 0 ] == '0' && str[ 1 ] == 'x' )
{
int i, n = 0;
for( i = 2; i < strlen( str ); i++ )
{
char digit;
n *= 16;
digit = tolower( str[ i ] );
if( digit >= '0' && digit <= '9' )
digit -= '0';
else if( digit >= 'a' && digit <= 'f' )
digit = digit - 'a' + 10;
else
return -1;
n += digit;
}
return n;
}
return -1;
}
/*
============================================================================

View File

@ -196,6 +196,8 @@ typedef int clipHandle_t;
#define MAX_QINT 0x7fffffff
#define MIN_QINT (-MAX_QINT-1)
#define ARRAY_LEN(x) (sizeof(x) / sizeof(*(x)))
#define STRARRAY_LEN(x) (ARRAY_LEN(x) - 1)
// angle indexes
#define PITCH 0 // up / down
@ -918,6 +920,7 @@ void SkipRestOfLine ( const char **data );
void Parse1DMatrix (const char **buf_p, int x, float *m);
void Parse2DMatrix (const char **buf_p, int y, int x, float *m);
void Parse3DMatrix (const char **buf_p, int z, int y, int x, float *m);
int Com_HexStrToInt( const char *str );
void QDECL Com_sprintf (char *dest, int size, const char *fmt, ...);

View File

@ -5,7 +5,17 @@
#ifndef __QGL_H__
#define __QGL_H__
#if defined( __LINT__ )
#ifndef DYNAMIC_LINK_GL
#ifdef USE_LOCAL_HEADERS
# include "SDL_opengl.h"
#else
# include <SDL_opengl.h>
#endif
#include "qgl_linked.h"
#elif defined( __LINT__ )
#include <GL/gl.h>
@ -29,7 +39,7 @@
#include <GL/gl.h>
#include <GL/glx.h>
#endif
#endif // !DYNAMIC_LINK_GL
#ifndef APIENTRY
#define APIENTRY
@ -130,6 +140,8 @@ extern void ( APIENTRY * qglPNTrianglesiATI )( GLenum pname, GLint param );
//extern void ( APIENTRY * qglPNTrianglesfATI )( GLenum pname, GLfloat param );
#endif // _NPATCH
#ifdef DYNAMIC_LINK_GL
//===========================================================================
// windows systems use a function pointer for each call so we can load minidrivers
@ -510,4 +522,5 @@ extern void (*qglXSwapBuffers)( Display *dpy, GLXDrawable drawable );
#endif // _WIN32
#endif
#endif // DYNAMIC_LINK_GL
#endif // __QGL_H__

View File

@ -996,11 +996,7 @@ void R_Register( void )
r_texturebitslm = ri.Cvar_Get( "r_texturebitslm", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_colorbits = ri.Cvar_Get( "r_colorbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_stereo = ri.Cvar_Get( "r_stereo", "0", CVAR_ARCHIVE | CVAR_LATCH );
#ifdef __linux__
r_stencilbits = ri.Cvar_Get( "r_stencilbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
#else
r_stencilbits = ri.Cvar_Get( "r_stencilbits", "8", CVAR_ARCHIVE | CVAR_LATCH );
#endif
r_depthbits = ri.Cvar_Get( "r_depthbits", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_overBrightBits = ri.Cvar_Get ("r_overBrightBits", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_ignorehwgamma = ri.Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE | CVAR_LATCH);

92
code/sdl/sdl_gamma.cpp Normal file
View File

@ -0,0 +1,92 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifdef USE_LOCAL_HEADERS
# include "SDL.h"
#else
# include <SDL.h>
#endif
#include "../game/q_shared.h"
#include "../renderer/tr_local.h"
#include "../qcommon/qcommon.h"
/*
=================
GLimp_SetGamma
=================
*/
void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned char blue[256] )
{
Uint16 table[3][256];
int i, j;
if( !glConfig.deviceSupportsGamma || r_ignorehwgamma->integer > 0 )
return;
for (i = 0; i < 256; i++)
{
table[0][i] = ( ( ( Uint16 ) red[i] ) << 8 ) | red[i];
table[1][i] = ( ( ( Uint16 ) green[i] ) << 8 ) | green[i];
table[2][i] = ( ( ( Uint16 ) blue[i] ) << 8 ) | blue[i];
}
#ifdef _WIN32
#include <windows.h>
// Win2K and newer put this odd restriction on gamma ramps...
{
OSVERSIONINFO vinfo;
vinfo.dwOSVersionInfoSize = sizeof( vinfo );
GetVersionEx( &vinfo );
if( vinfo.dwMajorVersion >= 5 && vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT )
{
ri.Printf( PRINT_DEVELOPER, "performing gamma clamp.\n" );
for( j = 0 ; j < 3 ; j++ )
{
for( i = 0 ; i < 128 ; i++ )
{
if( table[ j ] [ i] > ( ( 128 + i ) << 8 ) )
table[ j ][ i ] = ( 128 + i ) << 8;
}
if( table[ j ] [127 ] > 254 << 8 )
table[ j ][ 127 ] = 254 << 8;
}
}
}
#endif
// enforce constantly increasing
for (j = 0; j < 3; j++)
{
for (i = 1; i < 256; i++)
{
if (table[j][i] < table[j][i-1])
table[j][i] = table[j][i-1];
}
}
SDL_SetGammaRamp(table[0], table[1], table[2]);
}

953
code/sdl/sdl_glimp.cpp Normal file
View File

@ -0,0 +1,953 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifdef USE_LOCAL_HEADERS
# include "SDL.h"
#else
# include <SDL.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "../renderer/tr_local.h"
#include "sdl_local.h"
#ifdef notyet
#include "sdl_icon.h"
#endif
#define CLIENT_WINDOW_TITLE "Jedi Outcast"
#define CLIENT_WINDOW_MIN_TITLE "JO"
/* Just hack it for now. */
#ifdef MACOS_X
#include <OpenGL/OpenGL.h>
typedef CGLContextObj QGLContext;
#define GLimp_GetCurrentContext() CGLGetCurrentContext()
#define GLimp_SetCurrentContext(ctx) CGLSetCurrentContext(ctx)
#else
typedef void *QGLContext;
#define GLimp_GetCurrentContext() (NULL)
#define GLimp_SetCurrentContext(ctx)
#endif
static QGLContext opengl_context;
static float displayAspect;
typedef enum
{
RSERR_OK,
RSERR_INVALID_FULLSCREEN,
RSERR_INVALID_MODE,
RSERR_UNKNOWN
} rserr_t;
static SDL_Surface *screen = NULL;
static const SDL_VideoInfo *videoInfo = NULL;
cvar_t *r_allowSoftwareGL; // Don't abort out if a hardware visual can't be obtained
cvar_t *r_allowResize; // make window resizable
cvar_t *r_centerWindow;
cvar_t *r_sdlDriver;
cvar_t *r_noborder;
/*
===============
GLimp_Shutdown
===============
*/
void GLimp_Shutdown( void )
{
IN_Shutdown();
SDL_QuitSubSystem( SDL_INIT_VIDEO );
screen = NULL;
}
/*
===============
GLimp_Minimize
Minimize the game so that user is back at the desktop
===============
*/
void GLimp_Minimize(void)
{
SDL_WM_IconifyWindow();
}
/*
===============
GLimp_LogComment
===============
*/
void GLimp_LogComment( char *comment )
{
}
/*
===============
GLimp_CompareModes
===============
*/
static int GLimp_CompareModes( const void *a, const void *b )
{
const float ASPECT_EPSILON = 0.001f;
SDL_Rect *modeA = *(SDL_Rect **)a;
SDL_Rect *modeB = *(SDL_Rect **)b;
float aspectA = (float)modeA->w / (float)modeA->h;
float aspectB = (float)modeB->w / (float)modeB->h;
int areaA = modeA->w * modeA->h;
int areaB = modeB->w * modeB->h;
float aspectDiffA = fabs( aspectA - displayAspect );
float aspectDiffB = fabs( aspectB - displayAspect );
float aspectDiffsDiff = aspectDiffA - aspectDiffB;
if( aspectDiffsDiff > ASPECT_EPSILON )
return 1;
else if( aspectDiffsDiff < -ASPECT_EPSILON )
return -1;
else
return areaA - areaB;
}
/*
===============
GLimp_DetectAvailableModes
===============
*/
static void GLimp_DetectAvailableModes(void)
{
char buf[ MAX_STRING_CHARS ] = { 0 };
SDL_Rect **modes;
int numModes;
int i;
modes = SDL_ListModes( videoInfo->vfmt, SDL_OPENGL | SDL_FULLSCREEN );
if( !modes )
{
ri.Printf( PRINT_WARNING, "Can't get list of available modes\n" );
return;
}
if( modes == (SDL_Rect **)-1 )
{
ri.Printf( PRINT_ALL, "Display supports any resolution\n" );
return; // can set any resolution
}
for( numModes = 0; modes[ numModes ]; numModes++ );
if( numModes > 1 )
qsort( modes, numModes, sizeof( SDL_Rect* ), GLimp_CompareModes );
for( i = 0; i < numModes; i++ )
{
const char *newModeString = va( "%ux%u ", modes[ i ]->w, modes[ i ]->h );
if( strlen( newModeString ) < (int)sizeof( buf ) - strlen( buf ) )
Q_strcat( buf, sizeof( buf ), newModeString );
else
ri.Printf( PRINT_WARNING, "Skipping mode %ux%x, buffer too small\n", modes[i]->w, modes[i]->h );
}
if( *buf )
{
buf[ strlen( buf ) - 1 ] = 0;
ri.Printf( PRINT_ALL, "Available modes: '%s'\n", buf );
ri.Cvar_Set( "r_availableModes", buf );
}
}
/*
===============
GLimp_SetMode
===============
*/
static int GLimp_SetMode(int mode, qboolean fullscreen, qboolean noborder)
{
const char* glstring;
int sdlcolorbits;
int colorbits, depthbits, stencilbits;
int tcolorbits, tdepthbits, tstencilbits;
int samples;
int i = 0;
SDL_Surface *vidscreen = NULL;
Uint32 flags = SDL_OPENGL;
ri.Printf( PRINT_ALL, "Initializing OpenGL display\n");
if ( r_allowResize->integer )
flags |= SDL_RESIZABLE;
if( videoInfo == NULL )
{
static SDL_VideoInfo sVideoInfo;
static SDL_PixelFormat sPixelFormat;
videoInfo = SDL_GetVideoInfo( );
// Take a copy of the videoInfo
memcpy( &sPixelFormat, videoInfo->vfmt, sizeof( SDL_PixelFormat ) );
sPixelFormat.palette = NULL; // Should already be the case
memcpy( &sVideoInfo, videoInfo, sizeof( SDL_VideoInfo ) );
sVideoInfo.vfmt = &sPixelFormat;
videoInfo = &sVideoInfo;
if( videoInfo->current_h > 0 )
{
// Guess the display aspect ratio through the desktop resolution
// by assuming (relatively safely) that it is set at or close to
// the display's native aspect ratio
displayAspect = (float)videoInfo->current_w / (float)videoInfo->current_h;
ri.Printf( PRINT_ALL, "Estimated display aspect: %.3f\n", displayAspect );
}
else
{
ri.Printf( PRINT_ALL,
"Cannot estimate display aspect, assuming 1.333\n" );
}
}
ri.Printf (PRINT_ALL, "...setting mode %d:", mode );
if (mode == -2)
{
// use desktop video resolution
if( videoInfo->current_h > 0 )
{
glConfig.vidWidth = videoInfo->current_w;
glConfig.vidHeight = videoInfo->current_h;
}
else
{
glConfig.vidWidth = 640;
glConfig.vidHeight = 480;
ri.Printf( PRINT_ALL,
"Cannot determine display resolution, assuming 640x480\n" );
}
glConfig.windowAspect = (float)glConfig.vidWidth / (float)glConfig.vidHeight;
}
else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) )
{
ri.Printf( PRINT_ALL, " invalid mode\n" );
return RSERR_INVALID_MODE;
}
ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight);
if (fullscreen)
{
flags |= SDL_FULLSCREEN;
glConfig.isFullscreen = qtrue;
}
else
{
if (noborder)
flags |= SDL_NOFRAME;
glConfig.isFullscreen = qfalse;
}
colorbits = r_colorbits->value;
if ((!colorbits) || (colorbits >= 32))
colorbits = 24;
if (!r_depthbits->value)
depthbits = 24;
else
depthbits = r_depthbits->value;
stencilbits = r_stencilbits->value;
#ifdef notyet
samples = r_ext_multisample->value;
#else
samples = 0;
#endif
for (i = 0; i < 16; i++)
{
// 0 - default
// 1 - minus colorbits
// 2 - minus depthbits
// 3 - minus stencil
if ((i % 4) == 0 && i)
{
// one pass, reduce
switch (i / 4)
{
case 2 :
if (colorbits == 24)
colorbits = 16;
break;
case 1 :
if (depthbits == 24)
depthbits = 16;
else if (depthbits == 16)
depthbits = 8;
case 3 :
if (stencilbits == 24)
stencilbits = 16;
else if (stencilbits == 16)
stencilbits = 8;
}
}
tcolorbits = colorbits;
tdepthbits = depthbits;
tstencilbits = stencilbits;
if ((i % 4) == 3)
{ // reduce colorbits
if (tcolorbits == 24)
tcolorbits = 16;
}
if ((i % 4) == 2)
{ // reduce depthbits
if (tdepthbits == 24)
tdepthbits = 16;
else if (tdepthbits == 16)
tdepthbits = 8;
}
if ((i % 4) == 1)
{ // reduce stencilbits
if (tstencilbits == 24)
tstencilbits = 16;
else if (tstencilbits == 16)
tstencilbits = 8;
else
tstencilbits = 0;
}
sdlcolorbits = 4;
if (tcolorbits == 24)
sdlcolorbits = 8;
#ifdef __sgi /* Fix for SGIs grabbing too many bits of color */
if (sdlcolorbits == 4)
sdlcolorbits = 0; /* Use minimum size for 16-bit color */
/* Need alpha or else SGIs choose 36+ bit RGB mode */
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 1);
#endif
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, sdlcolorbits );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, sdlcolorbits );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, sdlcolorbits );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, tdepthbits );
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, tstencilbits );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 );
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples );
#ifdef notyet
if(r_stereoEnabled->integer)
{
glConfig.stereoEnabled = qtrue;
SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
}
else
{
glConfig.stereoEnabled = qfalse;
SDL_GL_SetAttribute(SDL_GL_STEREO, 0);
}
#endif
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
#if 0 // See http://bugzilla.icculus.org/show_bug.cgi?id=3526
// If not allowing software GL, demand accelerated
if( !r_allowSoftwareGL->integer )
{
if( SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ) < 0 )
{
ri.Printf( PRINT_ALL, "Unable to guarantee accelerated "
"visual with libSDL < 1.2.10\n" );
}
}
#endif
if( SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, r_swapInterval->integer ) < 0 )
ri.Printf( PRINT_ALL, "r_swapInterval requires libSDL >= 1.2.10\n" );
#ifdef USE_ICON
{
SDL_Surface *icon = SDL_CreateRGBSurfaceFrom(
(void *)CLIENT_WINDOW_ICON.pixel_data,
CLIENT_WINDOW_ICON.width,
CLIENT_WINDOW_ICON.height,
CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
);
SDL_WM_SetIcon( icon, NULL );
SDL_FreeSurface( icon );
}
#endif
SDL_WM_SetCaption(CLIENT_WINDOW_TITLE, CLIENT_WINDOW_MIN_TITLE);
SDL_ShowCursor(0);
if (!(vidscreen = SDL_SetVideoMode(glConfig.vidWidth, glConfig.vidHeight, colorbits, flags)))
{
ri.Printf( PRINT_DEVELOPER, "SDL_SetVideoMode failed: %s\n", SDL_GetError( ) );
continue;
}
opengl_context = GLimp_GetCurrentContext();
ri.Printf( PRINT_ALL, "Using %d/%d/%d Color bits, %d depth, %d stencil display.\n",
sdlcolorbits, sdlcolorbits, sdlcolorbits, tdepthbits, tstencilbits);
glConfig.colorBits = tcolorbits;
glConfig.depthBits = tdepthbits;
glConfig.stencilBits = tstencilbits;
break;
}
GLimp_DetectAvailableModes();
if (!vidscreen)
{
ri.Printf( PRINT_ALL, "Couldn't get a visual\n" );
return RSERR_INVALID_MODE;
}
screen = vidscreen;
glstring = (char *) qglGetString (GL_RENDERER);
ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring );
return RSERR_OK;
}
/*
===============
GLimp_StartDriverAndSetMode
===============
*/
static qboolean GLimp_StartDriverAndSetMode(int mode, qboolean fullscreen, qboolean noborder)
{
rserr_t err;
if (!SDL_WasInit(SDL_INIT_VIDEO))
{
char driverName[ 64 ];
if (SDL_Init(SDL_INIT_VIDEO) == -1)
{
ri.Printf( PRINT_ALL, "SDL_Init( SDL_INIT_VIDEO ) FAILED (%s)\n",
SDL_GetError());
return qfalse;
}
SDL_VideoDriverName( driverName, sizeof( driverName ) - 1 );
ri.Printf( PRINT_ALL, "SDL using driver \"%s\"\n", driverName );
ri.Cvar_Set( "r_sdlDriver", driverName );
}
if (fullscreen && Cvar_VariableIntegerValue( "in_nograb" ) )
{
ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
ri.Cvar_Set( "r_fullscreen", "0" );
r_fullscreen->modified = qfalse;
fullscreen = qfalse;
}
err = (rserr_t) GLimp_SetMode(mode, fullscreen, noborder);
switch ( err )
{
case RSERR_INVALID_FULLSCREEN:
ri.Printf( PRINT_ALL, "...WARNING: fullscreen unavailable in this mode\n" );
return qfalse;
case RSERR_INVALID_MODE:
ri.Printf( PRINT_ALL, "...WARNING: could not set the given mode (%d)\n", mode );
return qfalse;
default:
break;
}
return qtrue;
}
static void GLW_InitTextureCompression( void )
{
qboolean newer_tc, old_tc;
// Check for available tc methods.
newer_tc = ( strstr( glConfig.extensions_string, "ARB_texture_compression" )
&& strstr( glConfig.extensions_string, "EXT_texture_compression_s3tc" )) ? qtrue : qfalse;
old_tc = ( strstr( glConfig.extensions_string, "GL_S3_s3tc" )) ? qtrue : qfalse;
if ( old_tc )
{
ri.Printf( PRINT_ALL, "...GL_S3_s3tc available\n" );
}
if ( newer_tc )
{
ri.Printf( PRINT_ALL, "...GL_EXT_texture_compression_s3tc available\n" );
}
if ( !r_ext_compressed_textures->value )
{
// Compressed textures are off
glConfig.textureCompression = TC_NONE;
ri.Printf( PRINT_ALL, "...ignoring texture compression\n" );
}
else if ( !old_tc && !newer_tc )
{
// Requesting texture compression, but no method found
glConfig.textureCompression = TC_NONE;
ri.Printf( PRINT_ALL, "...no supported texture compression method found\n" );
ri.Printf( PRINT_ALL, ".....ignoring texture compression\n" );
}
else
{
// some form of supported texture compression is avaiable, so see if the user has a preference
if ( r_ext_preferred_tc_method->integer == TC_NONE )
{
// No preference, so pick the best
if ( newer_tc )
{
ri.Printf( PRINT_ALL, "...no tc preference specified\n" );
ri.Printf( PRINT_ALL, ".....using GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
else
{
ri.Printf( PRINT_ALL, "...no tc preference specified\n" );
ri.Printf( PRINT_ALL, ".....using GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
}
else
{
// User has specified a preference, now see if this request can be honored
if ( old_tc && newer_tc )
{
// both are avaiable, so we can use the desired tc method
if ( r_ext_preferred_tc_method->integer == TC_S3TC )
{
ri.Printf( PRINT_ALL, "...using preferred tc method, GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
else
{
ri.Printf( PRINT_ALL, "...using preferred tc method, GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
}
else
{
// Both methods are not available, so this gets trickier
if ( r_ext_preferred_tc_method->integer == TC_S3TC )
{
// Preferring to user older compression
if ( old_tc )
{
ri.Printf( PRINT_ALL, "...using GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
else
{
// Drat, preference can't be honored
ri.Printf( PRINT_ALL, "...preferred tc method, GL_S3_s3tc not available\n" );
ri.Printf( PRINT_ALL, ".....falling back to GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
}
else
{
// Preferring to user newer compression
if ( newer_tc )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_compression_s3tc\n" );
glConfig.textureCompression = TC_S3TC_DXT;
}
else
{
// Drat, preference can't be honored
ri.Printf( PRINT_ALL, "...preferred tc method, GL_EXT_texture_compression_s3tc not available\n" );
ri.Printf( PRINT_ALL, ".....falling back to GL_S3_s3tc\n" );
glConfig.textureCompression = TC_S3TC;
}
}
}
}
}
}
/*
** GLW_InitExtensions
*/
cvar_t *r_ATI_NPATCH_available = NULL;
static void GLimp_InitExtensions( void )
{
if ( !r_allowExtensions->integer )
{
ri.Printf( PRINT_ALL, "*** IGNORING OPENGL EXTENSIONS ***\n" );
return;
}
ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
// Select our tc scheme
GLW_InitTextureCompression();
// GL_EXT_texture_env_add
glConfig.textureEnvAddAvailable = qfalse;
if ( strstr( glConfig.extensions_string, "EXT_texture_env_add" ) )
{
if ( r_ext_texture_env_add->integer )
{
glConfig.textureEnvAddAvailable = qtrue;
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_env_add\n" );
}
else
{
glConfig.textureEnvAddAvailable = qfalse;
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_env_add\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_texture_env_add not found\n" );
}
// GL_EXT_texture_filter_anisotropic
glConfig.textureFilterAnisotropicAvailable = qfalse;
if ( strstr( glConfig.extensions_string, "EXT_texture_filter_anisotropic" ) )
{
glConfig.textureFilterAnisotropicAvailable = qtrue;
ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic available\n" );
if ( r_ext_texture_filter_anisotropic->integer )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_texture_filter_anisotropic\n" );
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_texture_filter_anisotropic\n" );
}
ri.Cvar_Set( "r_ext_texture_filter_anisotropic_avail", "1" );
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_texture_filter_anisotropic not found\n" );
ri.Cvar_Set( "r_ext_texture_filter_anisotropic_avail", "0" );
}
// GL_EXT_clamp_to_edge
glConfig.clampToEdgeAvailable = qfalse;
if ( strstr( glConfig.extensions_string, "GL_EXT_texture_edge_clamp" ) )
{
glConfig.clampToEdgeAvailable = qtrue;
ri.Printf( PRINT_ALL, "...Using GL_EXT_texture_edge_clamp\n" );
}
// GL_ARB_multitexture
qglMultiTexCoord2fARB = NULL;
qglActiveTextureARB = NULL;
qglClientActiveTextureARB = NULL;
if ( strstr( glConfig.extensions_string, "GL_ARB_multitexture" ) )
{
if ( r_ext_multitexture->integer )
{
qglMultiTexCoord2fARB = ( PFNGLMULTITEXCOORD2FARBPROC ) SDL_GL_GetProcAddress( "glMultiTexCoord2fARB" );
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glActiveTextureARB" );
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC ) SDL_GL_GetProcAddress( "glClientActiveTextureARB" );
if ( qglActiveTextureARB )
{
qglGetIntegerv( GL_MAX_ACTIVE_TEXTURES_ARB, &glConfig.maxActiveTextures );
if ( glConfig.maxActiveTextures > 1 )
{
ri.Printf( PRINT_ALL, "...using GL_ARB_multitexture\n" );
}
else
{
qglMultiTexCoord2fARB = NULL;
qglActiveTextureARB = NULL;
qglClientActiveTextureARB = NULL;
ri.Printf( PRINT_ALL, "...not using GL_ARB_multitexture, < 2 texture units\n" );
}
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_ARB_multitexture\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_ARB_multitexture not found\n" );
}
// GL_EXT_compiled_vertex_array
qglLockArraysEXT = NULL;
qglUnlockArraysEXT = NULL;
if ( strstr( glConfig.extensions_string, "GL_EXT_compiled_vertex_array" ) )
{
if ( r_ext_compiled_vertex_array->integer )
{
ri.Printf( PRINT_ALL, "...using GL_EXT_compiled_vertex_array\n" );
qglLockArraysEXT = ( void ( APIENTRY * )( int, int ) ) SDL_GL_GetProcAddress( "glLockArraysEXT" );
qglUnlockArraysEXT = ( void ( APIENTRY * )( void ) ) SDL_GL_GetProcAddress( "glUnlockArraysEXT" );
if (!qglLockArraysEXT || !qglUnlockArraysEXT) {
ri.Error (ERR_FATAL, "bad getprocaddress");
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_compiled_vertex_array\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_compiled_vertex_array not found\n" );
}
qglPointParameterfEXT = NULL;
qglPointParameterfvEXT = NULL;
if ( strstr( glConfig.extensions_string, "GL_EXT_point_parameters" ) )
{
if ( r_ext_compiled_vertex_array->integer || 1)
{
ri.Printf( PRINT_ALL, "...using GL_EXT_point_parameters\n" );
qglPointParameterfEXT = ( void ( APIENTRY * )( GLenum, GLfloat) ) SDL_GL_GetProcAddress( "glPointParameterfEXT" );
qglPointParameterfvEXT = ( void ( APIENTRY * )( GLenum, GLfloat *) ) SDL_GL_GetProcAddress( "glPointParameterfvEXT" );
if (!qglPointParameterfEXT || !qglPointParameterfvEXT)
{
ri.Error (ERR_FATAL, "bad getprocaddress");
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_EXT_point_parameters\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_EXT_point_parameters not found\n" );
}
#ifdef _NPATCH
// GL_ATI_pn_triangles
qglPNTrianglesiATI = NULL;
r_ATI_NPATCH_available = ri.Cvar_Get( "r_ATI_NPATCH_available", "0",CVAR_ROM );
/* if ( strstr( glConfig.extensions_string, "GL_ATI_pn_triangles" ) )
{
ri.Cvar_Set( "r_ATI_NPATCH_available", "1" );
if ( r_ati_pn_triangles->integer )
{
ri.Printf( PRINT_ALL, "...using GL_ATI_pn_triangles\n" );
qglPNTrianglesiATI = ( void ( APIENTRY * )( GLenum, GLint ) ) SDL_GL_GetProcAddress( "glPNTrianglesiATI" );
if (!qglPNTrianglesiATI) {
ri.Error (ERR_FATAL, "bad getprocaddress");
}
}
else
{
ri.Printf( PRINT_ALL, "...ignoring GL_ATI_pn_triangles\n" );
}
}
else
{
ri.Printf( PRINT_ALL, "...GL_ATI_pn_triangles not found\n" );
}
*/
#endif // _NPATCH
}
#define R_MODE_FALLBACK 3 // 640 * 480
/*
===============
GLimp_Init
This routine is responsible for initializing the OS specific portions
of OpenGL
===============
*/
void GLimp_Init( void )
{
r_allowSoftwareGL = ri.Cvar_Get( "r_allowSoftwareGL", "0", CVAR_LATCH );
r_sdlDriver = ri.Cvar_Get( "r_sdlDriver", "", CVAR_ROM );
r_allowResize = ri.Cvar_Get( "r_allowResize", "0", CVAR_ARCHIVE );
r_centerWindow = ri.Cvar_Get( "r_centerWindow", "0", CVAR_ARCHIVE );
r_noborder = Cvar_Get( "r_noborder", "0", CVAR_ARCHIVE );
qboolean fullscreen, noborder;
if( Cvar_VariableIntegerValue( "com_abnormalExit" ) )
{
ri.Cvar_Set( "r_mode", va( "%d", R_MODE_FALLBACK ) );
ri.Cvar_Set( "r_fullscreen", "0" );
ri.Cvar_Set( "r_centerWindow", "0" );
ri.Cvar_Set( "com_abnormalExit", "0" );
}
#ifdef notyet
Sys_SetEnv( "SDL_VIDEO_CENTERED", r_centerWindow->integer ? "1" : "" );
#endif
Sys_GLimpInit( );
fullscreen = (r_fullscreen->integer) ? qtrue : qfalse;
noborder = (r_noborder->integer) ? qtrue : qfalse;
// Create the window and set up the context
if(GLimp_StartDriverAndSetMode(r_mode->integer, fullscreen, noborder))
goto success;
// Try again, this time in a platform specific "safe mode"
Sys_GLimpSafeInit( );
if(GLimp_StartDriverAndSetMode(r_mode->integer, fullscreen, qfalse))
goto success;
// Finally, try the default screen resolution
if( r_mode->integer != R_MODE_FALLBACK )
{
ri.Printf( PRINT_ALL, "Setting r_mode %d failed, falling back on r_mode %d\n",
r_mode->integer, R_MODE_FALLBACK );
if(GLimp_StartDriverAndSetMode(R_MODE_FALLBACK, qfalse, qfalse))
goto success;
}
// Nothing worked, give up
ri.Error( ERR_FATAL, "GLimp_Init() - could not load OpenGL subsystem" );
success:
#if 0
// This values force the UI to disable driver selection
glConfig.driverType = GLDRV_ICD;
glConfig.hardwareType = GLHW_GENERIC;
#endif
glConfig.deviceSupportsGamma = (SDL_SetGamma( 1.0f, 1.0f, 1.0f ) >= 0) ? qtrue : qfalse;
// Mysteriously, if you use an NVidia graphics card and multiple monitors,
// SDL_SetGamma will incorrectly return false... the first time; ask
// again and you get the correct answer. This is a suspected driver bug, see
// http://bugzilla.icculus.org/show_bug.cgi?id=4316
glConfig.deviceSupportsGamma = (SDL_SetGamma( 1.0f, 1.0f, 1.0f ) >= 0) ? qtrue : qfalse;
if ( -1 == r_ignorehwgamma->integer)
glConfig.deviceSupportsGamma = qtrue;
if ( 1 == r_ignorehwgamma->integer)
glConfig.deviceSupportsGamma = qfalse;
// get our config strings
glConfig.vendor_string = (const char *) qglGetString (GL_VENDOR);
glConfig.renderer_string = (const char *) qglGetString (GL_RENDERER);
glConfig.version_string = (const char *) qglGetString (GL_VERSION);
glConfig.extensions_string = (const char *) qglGetString (GL_EXTENSIONS);
// OpenGL driver constants
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &glConfig.maxTextureSize );
// stubbed or broken drivers may have reported 0...
if ( glConfig.maxTextureSize <= 0 )
{
glConfig.maxTextureSize = 0;
}
// initialize extensions
GLimp_InitExtensions( );
ri.Cvar_Get( "r_availableModes", "", CVAR_ROM );
// This depends on SDL_INIT_VIDEO, hence having it here
IN_Init( );
}
/*
===============
GLimp_EndFrame
Responsible for doing a swapbuffers
===============
*/
void GLimp_EndFrame( void )
{
// don't flip if drawing to front buffer
if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 )
{
SDL_GL_SwapBuffers();
}
if( r_fullscreen->modified )
{
qboolean fullscreen;
qboolean needToToggle = qtrue;
qboolean sdlToggled = qfalse;
SDL_Surface *s = SDL_GetVideoSurface( );
if( s )
{
// Find out the current state
fullscreen = (!!( s->flags & SDL_FULLSCREEN )) ? qtrue : qfalse;
if( r_fullscreen->integer && Cvar_VariableIntegerValue( "in_nograb" ) )
{
ri.Printf( PRINT_ALL, "Fullscreen not allowed with in_nograb 1\n");
ri.Cvar_Set( "r_fullscreen", "0" );
r_fullscreen->modified = qfalse;
}
// Is the state we want different from the current state?
needToToggle = (!!r_fullscreen->integer != fullscreen) ? qtrue : qfalse;
if( needToToggle )
sdlToggled = SDL_WM_ToggleFullScreen( s );
}
if( needToToggle )
{
// SDL_WM_ToggleFullScreen didn't work, so do it the slow way
if( !sdlToggled )
ri.Cmd_ExecuteText(EXEC_APPEND, "vid_restart");
IN_Restart( );
}
r_fullscreen->modified = qfalse;
}
}

1107
code/sdl/sdl_input.cpp Normal file

File diff suppressed because it is too large Load Diff

10
code/sdl/sdl_local.h Normal file
View File

@ -0,0 +1,10 @@
#include "../game/q_shared.h"
#include "../qcommon/qcommon.h"
void IN_Init( void );
void IN_Shutdown( void );
void IN_Restart( void );
void Sys_GLimpSafeInit( void );
void Sys_GLimpInit( void );
void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr );

View File

@ -0,0 +1,82 @@
#include <pthread.h>
#include <semaphore.h>
#include "../game/q_shared.h"
/*
===========================================================
SMP acceleration
===========================================================
*/
sem_t renderCommandsEvent;
sem_t renderCompletedEvent;
sem_t renderActiveEvent;
void (*glimpRenderThread)( void );
void *GLimp_RenderThreadWrapper( void *stub ) {
glimpRenderThread();
}
/*
=======================
GLimp_SpawnRenderThread
=======================
*/
pthread_t renderThreadHandle;
qboolean GLimp_SpawnRenderThread( void (*function)( void ) ) {
sem_init( &renderCommandsEvent, 0, 0 );
sem_init( &renderCompletedEvent, 0, 0 );
sem_init( &renderActiveEvent, 0, 0 );
glimpRenderThread = function;
if (pthread_create( &renderThreadHandle, NULL,
GLimp_RenderThreadWrapper, NULL)) {
return qfalse;
}
return qtrue;
}
static void *smpData;
void *GLimp_RendererSleep( void ) {
void *data;
// after this, the front end can exit GLimp_FrontEndSleep
sem_post ( &renderCompletedEvent );
sem_wait ( &renderCommandsEvent );
data = smpData;
// after this, the main thread can exit GLimp_WakeRenderer
sem_post ( &renderActiveEvent );
return data;
}
void GLimp_FrontEndSleep( void ) {
sem_wait ( &renderCompletedEvent );
}
void GLimp_WakeRenderer( void *data ) {
smpData = data;
// after this, the renderer can continue through GLimp_RendererSleep
sem_post( &renderCommandsEvent );
sem_wait( &renderActiveEvent );
}
void Sys_GLimpInit( void )
{
}
void Sys_GLimpSafeInit( void )
{
}

View File

@ -144,7 +144,7 @@ void Sys_Init(void)
Cvar_Set( "arch", "unknown" );
#endif
IN_Init();
// IN_Init();
}