summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2007-11-17 19:27:42 +0000
committerAndrey Nazarov <skuller@skuller.net>2007-11-17 19:27:42 +0000
commitb068abb528d8a705894cb3acd0696bd01ffa72d5 (patch)
treef62c52328dbb701d49b1f99e4b770500642e895b
parent4f6e8a36bdf9038bba73fafcba96c4438d8f7ce0 (diff)
Yet another batched update.
Fixed munmap() hang in OSS_Shutdown(). Added (crappy) SDL audio driver, but ALSA should work now. Made r_maxfps and cl_maxfps really separate with cl_async 1. This way, any configuration is allowed (e.g. r_maxfps 60, cl_maxfps 120). Implemented water warping via fragment program, removed subdivision code. Removed (crappy) dynamic lighting. Removed surface sorting and batching. Minimized vertex copying operations. Implemented celshading. Removed S_RawSamples and friends. Smooth handling of smaller ladder steps (e.g. those on q2next2).
-rw-r--r--build/q2pro.mk2
-rwxr-xr-xconfigure2
-rw-r--r--source/cl_ents.c3
-rw-r--r--source/cl_input.c31
-rw-r--r--source/cl_local.h2
-rw-r--r--source/cl_main.c124
-rw-r--r--source/cl_parse.c6
-rw-r--r--source/cl_pred.c19
-rw-r--r--source/com_public.h2
-rw-r--r--source/cvar.c5
-rw-r--r--source/gl_images.c88
-rw-r--r--source/gl_local.h19
-rw-r--r--source/gl_main.c101
-rw-r--r--source/gl_mesh.c46
-rw-r--r--source/gl_state.c110
-rw-r--r--source/gl_surf.c212
-rw-r--r--source/gl_tess.c1074
-rw-r--r--source/gl_world.c186
-rw-r--r--source/q_shared.h11
-rw-r--r--source/qgl_api.c20
-rw-r--r--source/qgl_api.h10
-rw-r--r--source/r_shared.h1
-rw-r--r--source/snd_dx.c46
-rw-r--r--source/snd_local.h12
-rw-r--r--source/snd_main.c241
-rw-r--r--source/snd_mix.c348
-rw-r--r--source/snd_oss.c54
-rw-r--r--source/snd_sdl.c147
-rw-r--r--source/snd_wave.c32
-rw-r--r--source/sv_game.c2
30 files changed, 950 insertions, 2006 deletions
diff --git a/build/q2pro.mk b/build/q2pro.mk
index 9dab12a..8beaa8b 100644
--- a/build/q2pro.mk
+++ b/build/q2pro.mk
@@ -117,7 +117,7 @@ ASMFILES+=snd_mixa.s
LDFLAGS+=-ldl
ifdef USE_SDL
-SRCFILES+=vid_sdl.c
+SRCFILES+=vid_sdl.c snd_sdl.c
CFLAGS+=$(SDL_CFLAGS)
LDFLAGS+=-lX11 $(SDL_LDFLAGS)
endif
diff --git a/configure b/configure
index ab65257..1b56578 100755
--- a/configure
+++ b/configure
@@ -297,6 +297,8 @@ if [ "$client" = "yes" ]; then
libraries="$libraries mod_ui$libsuffix"
fi
fi
+else
+ sdl="no"
fi
if [ "$server" = "yes" ]; then
diff --git a/source/cl_ents.c b/source/cl_ents.c
index aa9e6e3..07b1fd6 100644
--- a/source/cl_ents.c
+++ b/source/cl_ents.c
@@ -841,6 +841,9 @@ static void CL_CalcViewValues( void ) {
// smooth out stair climbing
delta = cls.realtime - cl.predicted_step_time;
+ if( cl.predicted_step < 16 ) {
+ delta <<= 1; // small steps
+ }
if( delta < 100 ) {
cl.refdef.vieworg[2] -= cl.predicted_step * ( 100 - delta ) * 0.01f;
}
diff --git a/source/cl_input.c b/source/cl_input.c
index 6899bf3..eb5c475 100644
--- a/source/cl_input.c
+++ b/source/cl_input.c
@@ -434,11 +434,34 @@ static float CL_KeyState( kbutton_t *key ) {
// FIXME: always discrete?
static float CL_ImmKeyState( kbutton_t *key ) {
+#if 0
if( key->state & 1 ) {
return 1;
}
return 0;
+#else
+ float val;
+ uint32 msec;
+
+ msec = key->msec;
+
+ if( key->state & 1 ) {
+ // still down
+ if( com_eventTime > key->downtime ) {
+ msec += com_eventTime - key->downtime;
+ }
+ }
+
+ if( !frame_msec ) {
+ return 0;
+ }
+ val = ( float )msec / frame_msec;
+
+ clamp( val, 0, 1 );
+
+ return val;
+#endif
}
@@ -520,15 +543,15 @@ CL_AdjustAngles
Moves the local angle positions
================
*/
-static void CL_AdjustAngles (void)
+static void CL_AdjustAngles (int msec)
{
float speed;
float up, down;
if (in_speed.state & 1)
- speed = cls.frametime * cl_anglespeedkey->value;
+ speed = msec * cl_anglespeedkey->value * 0.001f;
else
- speed = cls.frametime;
+ speed = msec * 0.001f;
if (!(in_strafe.state & 1))
{
@@ -652,7 +675,7 @@ void CL_UpdateCmd( int msec ) {
}
// adjust viewangles
- CL_AdjustAngles();
+ CL_AdjustAngles( msec );
// get basic movement from keyboard
CL_ImmBaseMove();
diff --git a/source/cl_local.h b/source/cl_local.h
index 44f42e9..30499f6 100644
--- a/source/cl_local.h
+++ b/source/cl_local.h
@@ -173,7 +173,9 @@ typedef struct client_state_s {
char configstrings[MAX_CONFIGSTRINGS][MAX_QPATH];
char mapname[MAX_QPATH]; // short format - q2dm1, etc
+#if USE_AUTOREPLY
int replyTime;
+#endif
char loadingString[MAX_QPATH];
diff --git a/source/cl_main.c b/source/cl_main.c
index 840e776..53beca7 100644
--- a/source/cl_main.c
+++ b/source/cl_main.c
@@ -2474,6 +2474,7 @@ static void CL_MeasureFPS( void ) {
cls.measureFramecount++;
}
+#if USE_AUTOREPLY
/*
====================
CL_CheckForReply
@@ -2494,6 +2495,22 @@ static void CL_CheckForReply( void ) {
cl.replyTime = 0;
}
+#endif
+
+static void CL_CheckTimeout( void ) {
+ if( cls.netchan->last_received > com_localTime ) {
+ cls.netchan->last_received = com_localTime;
+ }
+ if( com_localTime - cls.netchan->last_received > cl_timeout->value * 1000 )
+ {
+ // timeoutcount saves debugger
+ if ( ++cl.timeoutcount > 5 ) {
+ Com_Error( ERR_DISCONNECT, "Server connection timed out." );
+ }
+ } else {
+ cl.timeoutcount = 0;
+ }
+}
/*
@@ -2503,40 +2520,40 @@ CL_Frame
==================
*/
void CL_Frame( int msec ) {
- static int main_extra;
- static int phys_extra;
- int main_msec;
- int phys_msec;
- qboolean phys_frame;
+ static int ref_extra, phys_extra, main_extra;
+ int ref_msec, phys_msec;
+ qboolean phys_frame, ref_frame;
time_after_ref = time_before_ref = 0;
if( !cl_running->integer ) {
+ // still run cmd buffer in dedicated mode
if( cmd_buffer.waitCount > 0 ) {
cmd_buffer.waitCount--;
}
return;
}
- main_extra += msec;
+ ref_extra += msec;
+ main_extra += msec;
cls.realtime += msec;
- main_msec = 1;
+ ref_msec = 1;
if( cl_async->integer ) {
phys_extra += msec;
- phys_frame = qfalse;
+ phys_frame = qtrue;
Cvar_ClampInteger( cl_maxfps, 10, 120 );
phys_msec = 1000 / cl_maxfps->integer;
- if( phys_extra >= phys_msec ) {
- phys_frame = qtrue;
+ if( phys_extra < phys_msec ) {
+ phys_frame = qfalse;
}
if( r_maxfps->integer ) {
if( r_maxfps->integer < 10 ) {
Cvar_Set( "r_maxfps", "10" );
}
- main_msec = 1000 / r_maxfps->integer;
+ ref_msec = 1000 / r_maxfps->integer;
}
} else {
phys_frame = qtrue;
@@ -2544,10 +2561,11 @@ void CL_Frame( int msec ) {
if( cl_maxfps->integer < 10 ) {
Cvar_Set( "cl_maxfps", "10" );
}
- main_msec = 1000 / cl_maxfps->integer;
+ ref_msec = 1000 / cl_maxfps->integer;
}
}
-
+
+ ref_frame = qtrue;
if( !com_timedemo->integer ) {
if( !sv_running->integer ) {
if( !cls.appactive ) {
@@ -2564,8 +2582,11 @@ void CL_Frame( int msec ) {
}
}
}
- if( main_extra < main_msec ) {
- return;
+ if( ref_extra < ref_msec ) {
+ if( !cl_async->integer ) {
+ return; // everything ticks in sync with refresh
+ }
+ ref_frame = qfalse;
}
}
@@ -2599,67 +2620,61 @@ void CL_Frame( int msec ) {
// calculate local time
CL_SetClientTime();
+#if USE_AUTOREPLY
+ // check for version reply
CL_CheckForReply();
+#endif
+
+ // resend a connection request if necessary
+ CL_CheckForResend();
- // read user intentions
- CL_UpdateCmd( main_extra );
+ // read user intentions
+ CL_UpdateCmd( main_extra );
- // finalize pending cmd
- if( phys_frame || cl.sendPacketNow ) {
- CL_FinalizeCmd();
- phys_extra = 0;
- }
+ // finalize pending cmd
+ phys_frame |= cl.sendPacketNow;
+ if( phys_frame ) {
+ CL_FinalizeCmd();
+ phys_extra = 0;
+ }
- // send pending intentions
- CL_SendCmd();
+ // send pending cmds
+ CL_SendCmd();
// predict all unacknowledged movements
CL_PredictMovement();
- // resend a connection request if necessary
- CL_CheckForResend();
+ if( ref_frame ) {
+ // update the screen
+ if ( host_speeds->integer )
+ time_before_ref = Sys_Milliseconds();
- // update the screen
- if ( host_speeds->integer )
- time_before_ref = Sys_Milliseconds();
+ SCR_UpdateScreen();
- SCR_UpdateScreen();
+ if ( host_speeds->integer )
+ time_after_ref = Sys_Milliseconds();
- if ( host_speeds->integer )
- time_after_ref = Sys_Milliseconds();
+ // update audio after the 3D view was drawn
+ S_Update();
- // update audio after the 3D view was drawn
- S_Update();
+ ref_extra = 0;
+ }
// advance local effects for next frame
CL_RunDLights();
CL_RunLightStyles();
Con_RunConsole();
+ // check connection timeout
+ if( cls.netchan ) {
+ CL_CheckTimeout();
+ }
+
CL_MeasureFPS();
- main_extra = 0;
cls.framecount++;
- //
- // check timeout
- //
- if( !cls.netchan ) {
- return;
- }
-
- if( cls.netchan->last_received > com_localTime ) {
- cls.netchan->last_received = com_localTime;
- }
- if( com_localTime - cls.netchan->last_received > cl_timeout->value * 1000 )
- {
- // timeoutcount saves debugger
- if ( ++cl.timeoutcount > 5 ) {
- Com_Error( ERR_DISCONNECT, "Server connection timed out." );
- }
- } else {
- cl.timeoutcount = 0;
- }
+ main_extra = 0;
}
//============================================================================
@@ -2705,7 +2720,6 @@ void CL_Init( void ) {
#endif
SZ_Init( &cls.demobuff, demo_buffer, sizeof( demo_buffer ) );
- cls.demobuff.allowoverflow = qtrue;
UI_OpenMenu( UIMENU_MAIN );
diff --git a/source/cl_parse.c b/source/cl_parse.c
index 4ead25a..ae87e4a 100644
--- a/source/cl_parse.c
+++ b/source/cl_parse.c
@@ -1032,7 +1032,7 @@ noskin:
Com_sprintf( weapon_filename, sizeof( weapon_filename ),
"players/%s/%s", model_name, cl.weaponModels[i] );
ci->weaponmodel[i] = ref.RegisterModel( weapon_filename );
- if( !ci->weaponmodel[i] && strcmp( model_name, "cyborg" ) == 0 ) {
+ if( !ci->weaponmodel[i] && !Q_stricmp( model_name, "cyborg" ) ) {
// try male
Com_sprintf( weapon_filename, sizeof( weapon_filename ),
"players/male/%s", cl.weaponModels[i] );
@@ -1195,6 +1195,7 @@ static void CL_ParseReconnect( void ) {
cls.connectCount = 0;
}
+#if USE_AUTOREPLY
/*
====================
CL_CheckForVersion
@@ -1222,6 +1223,7 @@ static void CL_CheckForVersion( const char *string ) {
cl.replyTime = cls.realtime + 1024 + ( rand() & 1023 );
}
+#endif
/*
@@ -1245,7 +1247,9 @@ static void CL_ParsePrint( void ) {
return;
}
+#if USE_AUTOREPLY
CL_CheckForVersion( string );
+#endif
// disable notify
if( !cl_chat_notify->integer ) {
diff --git a/source/cl_pred.c b/source/cl_pred.c
index f8dd9a1..5b40653 100644
--- a/source/cl_pred.c
+++ b/source/cl_pred.c
@@ -33,7 +33,7 @@ void CL_CheckPredictionError( void ) {
int len;
player_state_t *ps;
- if( cls.demoplayback ) {
+ if( !cls.netchan ) {
return;
}
@@ -51,6 +51,8 @@ void CL_CheckPredictionError( void ) {
frame = cls.netchan->incoming_acknowledged & CMD_MASK;
i = cl.history[frame].cmdNumber & CMD_MASK;
+ //if( cl.history[frame].cmdNumber>cl.predicted_step_frame) Com_Printf( "wtf?!!\n" );
+
// compare what the server returned with what we had predicted it to be
VectorSubtract( ps->pmove.origin, cl.predicted_origins[i], delta );
@@ -250,7 +252,7 @@ void CL_PredictMovement( void ) {
return;
}
- if( !cl_async->integer && current == ack ) {
+ if( !cl.cmd.msec && current == ack ) {
if( cl_showmiss->integer ) {
Com_Printf( "%i: not moved\n", cl.frame.number );
}
@@ -291,16 +293,13 @@ void CL_PredictMovement( void ) {
frame = current - 1;
}
- oldz = cl.predicted_origins[frame & CMD_MASK][2];
+ oldz = cl.predicted_origins[cl.predicted_step_frame & CMD_MASK][2];
step = pm.s.origin[2] - oldz;
- if( cl.predicted_step_frame != frame &&
- step > 63 && step < 160 &&
- ( pm.s.pm_flags & PMF_ON_GROUND ) )
- {
- cl.predicted_step = step * 0.125;
- cl.predicted_step_time = cls.realtime - cls.frametime * 500;
- cl.predicted_step_frame = frame;
+ if( step > 63 && step < 160 && ( pm.s.pm_flags & PMF_ON_GROUND ) ) {
+ cl.predicted_step = step * 0.125f;
+ cl.predicted_step_time = cls.realtime;/// - cls.frametime * 500;
}
+ cl.predicted_step_frame = frame;
// copy results out for rendering
VectorScale( pm.s.origin, 0.125f, cl.predicted_origin );
diff --git a/source/com_public.h b/source/com_public.h
index 26809d3..dc17047 100644
--- a/source/com_public.h
+++ b/source/com_public.h
@@ -94,7 +94,7 @@ typedef enum {
#define CVAR_LATCHED 256
#define CVAR_USER_CREATED 512
#define CVAR_DEFAULTS_MIXED 1024
-#define CVAR_LOCAL 2048
+#define CVAR_GAME 2048
#define CVAR_INFOMASK (CVAR_USERINFO|CVAR_SERVERINFO)
#define CVAR_EXTENDED_MASK (~31)
diff --git a/source/cvar.c b/source/cvar.c
index acb1911..5126164 100644
--- a/source/cvar.c
+++ b/source/cvar.c
@@ -250,7 +250,7 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags ) {
flags &= ~CVAR_USER_CREATED;
}
- var->flags |= flags;
+ var->flags |= flags & ~CVAR_GAME;
return var;
}
@@ -622,6 +622,8 @@ void Cvar_GetLatchedVars( void ) {
cvar_t *var;
for( var = cvar_vars; var; var = var->next ) {
+ if( var->flags & CVAR_GAME )
+ var->flags &= ~CVAR_SERVERINFO;
if( !(var->flags & CVAR_LATCH) )
continue;
if( var->flags & CVAR_LATCHED )
@@ -968,6 +970,7 @@ int Cvar_BitInfo( char *info, int bit ) {
if( !( var->flags & bit ) ) {
continue;
}
+
if( !var->string[0] ) {
continue;
}
diff --git a/source/gl_images.c b/source/gl_images.c
index f023da0..5622ced 100644
--- a/source/gl_images.c
+++ b/source/gl_images.c
@@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
image_t *r_notexture;
image_t *r_particletexture;
image_t *r_beamtexture;
-image_t *r_dlightTex;
+image_t *r_warptexture;
image_t *r_whiteimage;
int gl_filter_min;
@@ -932,38 +932,7 @@ static void gl_gamma_changed( cvar_t *self ) {
video.UpdateGamma( gammatable );
}
-#define DLIGHT_TEXTURE_SIZE 16
-
-static void GL_InitDlightTexture( void ) {
- byte pixels[DLIGHT_TEXTURE_SIZE*DLIGHT_TEXTURE_SIZE*4];
- byte *dst;
- float x, y, f;
- int i, j;
-
- dst = pixels;
- for( i = 0; i < DLIGHT_TEXTURE_SIZE; i++ ) {
- for( j = 0; j < DLIGHT_TEXTURE_SIZE; j++ ) {
- x = j - DLIGHT_TEXTURE_SIZE/2 + 0.5f;
- y = i - DLIGHT_TEXTURE_SIZE/2 + 0.5f;
- f = sqrt( x * x + y * y );
- f = 1.0f - f / ( DLIGHT_TEXTURE_SIZE/2 - 1.5f );
- if( f < 0 ) f = 0;
- else if( f > 1 ) f = 1;
- dst[0] = 255 * f;
- dst[1] = 255 * f;
- dst[2] = 255 * f;
- dst[3] = 255;
- dst += 4;
- }
- }
-
- r_dlightTex = R_CreateImage( "*dlightTexture", pixels, DLIGHT_TEXTURE_SIZE,
- DLIGHT_TEXTURE_SIZE, it_pic, if_auto );
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
-}
-
-static byte dottexture[8][8] = {
+static const byte dottexture[8][8] = {
{0,0,0,0,0,0,0,0},
{0,0,1,1,0,0,0,0},
{0,1,1,1,1,0,0,0},
@@ -1028,22 +997,21 @@ static void GL_InitWhiteImage( void ) {
}
}
- r_whiteimage = R_CreateImage( "*whiteimage", pixels, 8, 8, it_pic, if_auto );
+ r_whiteimage = R_CreateImage( "*whiteimage", pixels, 8, 8,
+ it_pic, if_auto );
}
-#define BEAM_TEXTURE_SIZE 16
-
static void GL_InitBeamTexture( void ) {
- byte pixels[BEAM_TEXTURE_SIZE*BEAM_TEXTURE_SIZE*4];
+ byte pixels[16*16*4];
byte *dst;
float f;
int i, j;
dst = pixels;
- for( i = 0; i < BEAM_TEXTURE_SIZE; i++ ) {
- for( j = 0; j < BEAM_TEXTURE_SIZE; j++ ) {
- f = fabs( j - BEAM_TEXTURE_SIZE/2 ) - 0.5f;
- f = 1.0f - f / ( BEAM_TEXTURE_SIZE/2 - 2.5f );
+ for( i = 0; i < 16; i++ ) {
+ for( j = 0; j < 16; j++ ) {
+ f = fabs( j - 16/2 ) - 0.5f;
+ f = 1.0f - f / ( 16/2 - 2.5f );
if( f < 0 ) f = 0;
else if( f > 1 ) f = 1;
dst[0] = 255 * f;
@@ -1054,24 +1022,32 @@ static void GL_InitBeamTexture( void ) {
}
}
- r_beamtexture = R_CreateImage( "*beamTexture", pixels, BEAM_TEXTURE_SIZE,
- BEAM_TEXTURE_SIZE, it_pic, if_auto );
+ r_beamtexture = R_CreateImage( "*beamTexture", pixels, 16, 16,
+ it_pic, if_auto );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- // qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
- // qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
- /*
- {
- float borderColor[4];
-
- borderColor[0] = 1;
- borderColor[1] = 1;
- borderColor[2] = 1;
- borderColor[3] = 0;
+}
- qglTexParameterfv( GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor );
+static void GL_InitWarpTexture( void ) {
+ byte pixels[8*8*4];
+ byte *dst;
+ int i, j;
+
+ dst = pixels;
+ for( i = 0; i < 8; i++ ) {
+ for( j = 0; j < 8; j++ ) {
+ dst[0] = rand() & 255;
+ dst[1] = rand() & 255;
+ dst[2] = 255;
+ dst[3] = 255;
+ dst += 4;
+ }
}
- */
+
+ r_warptexture = R_CreateImage( "*warpTexture", pixels, 8, 8,
+ it_pic, if_auto );
+ qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
}
/*
@@ -1148,7 +1124,7 @@ void GL_InitImages( void ) {
/* make sure r_notexture == &r_images[0] */
GL_InitDefaultTexture();
- GL_InitDlightTexture();
+ GL_InitWarpTexture();
GL_InitParticleTexture();
GL_InitWhiteImage();
GL_InitBeamTexture();
diff --git a/source/gl_local.h b/source/gl_local.h
index 9ed3dfb..2efd669 100644
--- a/source/gl_local.h
+++ b/source/gl_local.h
@@ -43,6 +43,7 @@ typedef struct {
int maxTextureSize;
qboolean registering;
uint32 palette[256]; /* cinematic palette */
+ GLuint prog_warp;
} glStatic_t;
typedef struct {
@@ -81,17 +82,17 @@ typedef struct {
extern statCounters_t c;
+extern cvar_t *gl_celshading;
extern cvar_t *gl_partscale;
extern cvar_t *gl_znear;
extern cvar_t *gl_zfar;
extern cvar_t *gl_modulate;
extern cvar_t *gl_showtris;
extern cvar_t *gl_cull_nodes;
+extern cvar_t *gl_bind;
extern cvar_t *gl_clear;
extern cvar_t *gl_novis;
extern cvar_t *gl_lockpvs;
-extern cvar_t *gl_primitives;
-extern cvar_t *gl_sort;
extern cvar_t *gl_subdivide;
extern cvar_t *gl_fastsky;
extern cvar_t *gl_dynamic;
@@ -112,6 +113,8 @@ glCullResult_t GL_CullLocalBox( const vec3_t origin, vec3_t bounds[2] );
void GL_DrawBox( const vec3_t origin, vec3_t bounds[2] );
+void GL_ShowErrors( const char *func );
+
/*
* gl_model.c
*
@@ -252,6 +255,10 @@ void GL_Bits( glStateBits_t bits );
void GL_Setup2D( void );
void GL_Setup3D( void );
+void GL_SetDefaultState( void );
+void GL_InitPrograms( void );
+void GL_ShutdownPrograms( void );
+
/*
* gl_draw.c
@@ -296,7 +303,7 @@ void Draw_Stats( void );
extern image_t *r_notexture;
extern image_t *r_particletexture;
extern image_t *r_beamtexture;
-extern image_t *r_dlightTex;
+extern image_t *r_warptexture;
extern image_t *r_whiteimage;
extern int gl_filter_min;
@@ -333,13 +340,13 @@ typedef struct {
int numIndices;
int numFaces;
vec_t vertices[4*TESS_MAX_VERTICES];
+ vec_t normals[4*TESS_MAX_VERTICES];
byte colors[4*TESS_MAX_VERTICES];
tcoord_t tcoords[TESS_MAX_VERTICES];
tcoord_t lmtcoords[TESS_MAX_VERTICES];
int indices[TESS_MAX_INDICES];
bspSurface_t *faces[TESS_MAX_FACES];
int texnum;
- int lightmapnum;
qboolean istrans;
} tesselator_t;
@@ -350,9 +357,7 @@ void EndSurface_Single( void );
void Tess_DrawSurfaceTriangles( int *indices, int numIndices );
-void GL_AddBspSurface( bspSurface_t *surf );
-void GL_DrawSurfPoly( bspSurface_t *surf );
-void GL_SortAndDrawSurfs( qboolean doSort );
+void GL_DrawSurf( bspSurface_t *surf );
void GL_StretchPic( float x, float y, float w, float h,
float s1, float t1, float s2, float t2, const byte *color, image_t *image );
void GL_Flush2D( void );
diff --git a/source/gl_main.c b/source/gl_main.c
index ffc7c27..f4b1b25 100644
--- a/source/gl_main.c
+++ b/source/gl_main.c
@@ -47,6 +47,7 @@ cvar_t *gl_screenshot_quality;
#if USE_PNG
cvar_t *gl_screenshot_compression;
#endif
+cvar_t *gl_celshading;
cvar_t *gl_znear;
cvar_t *gl_zfar;
cvar_t *gl_modulate;
@@ -57,15 +58,15 @@ cvar_t *gl_showtris;
cvar_t *gl_cull_nodes;
cvar_t *gl_cull_models;
cvar_t *gl_showstats;
+cvar_t *gl_bind;
cvar_t *gl_clear;
cvar_t *gl_novis;
cvar_t *gl_lockpvs;
-cvar_t *gl_sort;
-cvar_t *gl_primitives;
-cvar_t *gl_sort;
cvar_t *gl_subdivide;
cvar_t *gl_fastsky;
+#if USE_DYNAMIC
cvar_t *gl_dynamic;
+#endif
cvar_t *gl_fullbright;
cvar_t *gl_hwgamma;
cvar_t *gl_fullscreen;
@@ -423,9 +424,17 @@ static char *GL_ErrorString( GLenum err ) {
return str;
}
-static void GL_RenderFrame( refdef_t *fd ) {
+void GL_ShowErrors( const char *func ) {
GLenum err;
+ if( gl_showerrors->integer ) {
+ while( ( err = qglGetError() ) != GL_NO_ERROR ) {
+ Com_EPrintf( "%s: %s\n", func, GL_ErrorString( err ) );
+ }
+ }
+}
+
+static void GL_RenderFrame( refdef_t *fd ) {
GL_Flush2D();
if( !r_world.name[0] && !( fd->rdflags & RDF_NOWORLDMODEL ) ) {
@@ -437,16 +446,11 @@ static void GL_RenderFrame( refdef_t *fd ) {
glr.fd = *fd;
glr.num_beams = 0;
+#if USE_DYNAMIC
if( !gl_dynamic->integer ) {
glr.fd.num_dlights = 0;
}
-
- AngleVectors( glr.fd.viewangles, glr.viewaxis[0], glr.viewaxis[1], glr.viewaxis[2] );
- VectorInverse( glr.viewaxis[1] );
-
- glr.scroll = -64 * ( ( glr.fd.time / 40.0f ) - ( int )( glr.fd.time / 40.0f ) );
- if( glr.scroll == 0 )
- glr.scroll = -64.0f;
+#endif
GL_Setup3D();
@@ -473,16 +477,10 @@ static void GL_RenderFrame( refdef_t *fd ) {
GL_Blend();
- if( gl_showerrors->integer ) {
- while( ( err = qglGetError() ) != GL_NO_ERROR ) {
- Com_EPrintf( "GL_RenderFrame: %s\n", GL_ErrorString( err ) );
- }
- }
+ GL_ShowErrors( __func__ );
}
static void GL_BeginFrame( void ) {
- GLenum err;
-
if( gl_log->integer ) {
QGL_LogNewFrame();
}
@@ -495,16 +493,10 @@ static void GL_BeginFrame( void ) {
qglClear( GL_COLOR_BUFFER_BIT );
}
- if( gl_showerrors->integer ) {
- while( ( err = qglGetError() ) != GL_NO_ERROR ) {
- Com_EPrintf( "GL_BeginFrame: %s\n", GL_ErrorString( err ) );
- }
- }
+ GL_ShowErrors( __func__ );
}
static void GL_EndFrame( void ) {
- GLenum err;
-
if( gl_showstats->integer ) {
Draw_Stats();
}
@@ -514,12 +506,9 @@ static void GL_EndFrame( void ) {
QGL_EnableLogging( gl_log->integer );
gl_log->modified = qfalse;
}
+
+ GL_ShowErrors( __func__ );
- if( gl_showerrors->integer ) {
- while( ( err = qglGetError() ) != GL_NO_ERROR ) {
- Com_EPrintf( "GL_EndFrame: %s\n", GL_ErrorString( err ) );
- }
- }
video.EndFrame();
}
@@ -692,6 +681,7 @@ static void GL_Register( void ) {
#if USE_PNG
gl_screenshot_compression = cvar.Get( "gl_screenshot_compression", "6", 0 );
#endif
+ gl_celshading = cvar.Get( "gl_celshading", "0", 0 );
gl_modulate = cvar.Get( "gl_modulate", "1", CVAR_ARCHIVE );
gl_hwgamma = cvar.Get( "vid_hwgamma", "0", CVAR_ARCHIVE|CVAR_LATCHED );
@@ -705,14 +695,15 @@ static void GL_Register( void ) {
gl_showstats = cvar.Get( "gl_showstats", "0", 0 );
gl_cull_nodes = cvar.Get( "gl_cull_nodes", "1", 0 );
gl_cull_models = cvar.Get( "gl_cull_models", "1", 0 );
+ gl_bind = cvar.Get( "gl_bind", "1", CVAR_CHEAT );
gl_clear = cvar.Get( "gl_clear", "0", 0 );
gl_novis = cvar.Get( "gl_novis", "0", 0 );
gl_lockpvs = cvar.Get( "gl_lockpvs", "0", CVAR_CHEAT );
- gl_primitives = cvar.Get( "gl_primitives", "0", 0 );
- gl_sort = cvar.Get( "gl_sort", "0", 0 );
gl_subdivide = cvar.Get( "gl_subdivide", "1", 0 );
gl_fastsky = cvar.Get( "gl_fastsky", "0", 0 );
+#if USE_DYNAMIC
gl_dynamic = cvar.Get( "gl_dynamic", "2", CVAR_ARCHIVE );
+#endif
gl_fullbright = cvar.Get( "r_fullbright", "0", CVAR_CHEAT );
gl_showerrors = cvar.Get( "gl_showerrors", "1", 0 );
@@ -760,7 +751,6 @@ static qboolean GL_SetupExtensions( void ) {
Com_Printf( "...enabling GL_ARB_multitexture (%d texture units)\n", integer );
qglActiveTextureARB = ( PFNGLACTIVETEXTUREARBPROC )qwglGetProcAddress( "glActiveTextureARB" );
qglClientActiveTextureARB = ( PFNGLCLIENTACTIVETEXTUREARBPROC )qwglGetProcAddress( "glClientActiveTextureARB" );
- qglMultiTexCoord2fvARB = ( PFNGLMULTITEXCOORD2FVARBPROC )qwglGetProcAddress( "glMultiTexCoord2fvARB" );
if( integer > MAX_TMUS ) {
integer = MAX_TMUS;
}
@@ -788,6 +778,17 @@ static qboolean GL_SetupExtensions( void ) {
Com_Printf( "GL_EXT_texture_filter_anisotropic not found\n" );
}
+ if( strstr( extensions, "GL_ARB_fragment_program" ) ) {
+ Com_Printf( "...enabling GL_ARB_fragment_program\n" );
+ qglProgramStringARB = ( PFNGLPROGRAMSTRINGARBPROC )qwglGetProcAddress( "glProgramStringARB" );
+ qglBindProgramARB = ( PFNGLBINDPROGRAMARBPROC )qwglGetProcAddress( "glBindProgramARB" );
+ qglDeleteProgramsARB = ( PFNGLDELETEPROGRAMSARBPROC )qwglGetProcAddress( "glDeleteProgramsARB" );
+ qglGenProgramsARB = ( PFNGLGENPROGRAMSARBPROC )qwglGetProcAddress( "glGenProgramsARB" );
+ qglProgramLocalParameter4fvARB = ( PFNGLPROGRAMLOCALPARAMETER4FVARBPROC )qwglGetProcAddress( "glProgramLocalParameter4fvARB" );
+ } else {
+ Com_Printf( "GL_ARB_fragment_program not found\n" );
+ }
+
if( !qglActiveTextureARB ) {
return qfalse;
}
@@ -800,30 +801,7 @@ static qboolean GL_SetupExtensions( void ) {
return qtrue;
}
-void GL_SetDefaultState( void ) {
- qglDrawBuffer( GL_BACK );
- qglClearColor( 0, 0, 0, 1 );
- qglClearDepth( 1 );
- qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- qglEnable( GL_DEPTH_TEST );
- qglDepthFunc( GL_LEQUAL );
- qglDepthRange( 0, 1 );
- qglDepthMask( GL_TRUE );
- qglDisable( GL_BLEND );
- qglDisable( GL_ALPHA_TEST );
- qglAlphaFunc( GL_GREATER, 0.666f );
- qglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
- qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-
- qglEnableClientState( GL_VERTEX_ARRAY );
- qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
-
- GL_SelectTMU( 0 );
- qglEnable( GL_TEXTURE_2D );
- GL_Bits( GLS_DEFAULT );
-}
-
-static void GL_SetupRenderer( void ) {
+static void GL_IdentifyRenderer( void ) {
char renderer_buffer[MAX_STRING_CHARS];
Q_strncpyz( renderer_buffer, gl_config.rendererString,
@@ -904,20 +882,19 @@ static qboolean GL_Init( qboolean total ) {
Com_Printf( "Hardware gamma is not supported by this video driver\n" );
}
- GL_SetupRenderer();
+ GL_IdentifyRenderer();
QGL_EnableLogging( gl_log->integer );
gl_log->modified = qfalse;
GL_PostInit();
+ GL_InitPrograms();
+
if( (( size_t )tess.vertices) & 15 ) {
Com_WPrintf( "tess.vertices not 16 byte aligned\n" );
}
- gl_sort = cvar.Get( "gl_sort",
- gl_config.renderer == GL_RENDERER_MESADRI ? "1" : "0", 0 );
-
Com_DPrintf( "Finished GL_Init\n" );
return qtrue;
@@ -944,6 +921,8 @@ void GL_Shutdown( qboolean total ) {
if( !total ) {
return;
}
+
+ GL_ShutdownPrograms();
/*
** shut down OS specific OpenGL stuff like contexts, etc.
diff --git a/source/gl_mesh.c b/source/gl_mesh.c
index ec137ac..00d8f58 100644
--- a/source/gl_mesh.c
+++ b/source/gl_mesh.c
@@ -172,6 +172,7 @@ void GL_SetAliasColor( vec3_t origin, vec_t *color ) {
}
}
+#define USE_CELSHADING 1
void GL_DrawAliasModel( model_t *model ) {
entity_t *ent = glr.ent;
@@ -187,6 +188,11 @@ void GL_DrawAliasModel( model_t *model ) {
glStateBits_t bits;
glCullResult_t cull;
vec4_t color;
+#if USE_CELSHADING
+ vec3_t dir;
+ float scale;
+#endif
+ int back, front;
newframeIdx = ent->frame;
if( newframeIdx < 0 || newframeIdx >= model->numFrames ) {
@@ -278,6 +284,15 @@ void GL_DrawAliasModel( model_t *model ) {
tessFunc = Tess_LerpedMesh;
}
+#if USE_CELSHADING
+ scale = 0;
+ if( gl_celshading->value > 0 && ( ent->flags & RF_SHELL_MASK ) == 0 ) {
+ VectorSubtract( origin, glr.fd.vieworg, dir );
+ scale = VectorLength( dir );
+ scale = 1.0f - scale / 700.0f;
+ }
+#endif
+
/* setup color */
GL_SetAliasColor( origin, color );
@@ -309,7 +324,12 @@ void GL_DrawAliasModel( model_t *model ) {
qglScalef( -1, 1, 1 );
qglMatrixMode( GL_MODELVIEW );
qglCullFace( GL_BACK );
- }
+ back = GL_BACK;
+ front = GL_FRONT;
+ } else {
+ back = GL_FRONT;
+ front = GL_BACK;
+ }
qglColor4fv( color );
qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
@@ -352,10 +372,28 @@ void GL_DrawAliasModel( model_t *model ) {
qglLockArraysEXT( 0, mesh->numVerts );
}
qglDrawElements( GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT,
- mesh->indices );
+ mesh->indices );
+
+#if USE_CELSHADING
+ if( scale > 0 && scale <= 1 ) {
+ qglCullFace( front );
+ qglPolygonMode( back, GL_LINE );
+ qglDisable( GL_TEXTURE_2D );
+ qglLineWidth( gl_celshading->value*scale );
+ GL_Bits( bits | GLS_BLEND_BLEND );
+ qglColor4f( 0, 0, 0, scale );
+ qglDrawElements( GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT,
+ mesh->indices );
+ qglCullFace( back );
+ qglPolygonMode( back, GL_FILL );
+ qglColor4fv( color );
+ qglEnable( GL_TEXTURE_2D );
+ }
+#endif
+
if( gl_showtris->integer ) {
- Tess_DrawSurfaceTriangles( ( int * )mesh->indices,
- mesh->numIndices );
+ //Tess_DrawSurfaceTriangles( ( int * )mesh->indices,
+ // mesh->numIndices );
}
if( qglUnlockArraysEXT ) {
qglUnlockArraysEXT();
diff --git a/source/gl_state.c b/source/gl_state.c
index 6dbfbae..f1df0fc 100644
--- a/source/gl_state.c
+++ b/source/gl_state.c
@@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "gl_local.h"
+#include "gl_arbfp.h"
glState_t gls;
@@ -26,6 +27,9 @@ void GL_BindTexture( int texnum ) {
if( gls.texnum[gls.tmu] == texnum ) {
return;
}
+ if( !gl_bind->integer ) {
+ return;
+ }
qglBindTexture( GL_TEXTURE_2D, texnum );
c.texSwitches++;
@@ -170,35 +174,26 @@ void GL_Setup2D( void ) {
GL_CullFace( GLS_CULL_DISABLE );
}
-static inline void MYgluPerspective( GLdouble fovy, GLdouble aspect,
- GLdouble zNear, GLdouble zFar )
-{
- GLdouble xmin, xmax, ymin, ymax;
-
- ymax = zNear * tan( fovy * M_PI / 360.0 );
- ymin = -ymax;
-
- xmin = ymin * aspect;
- xmax = ymax * aspect;
-
- qglFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
-}
-
void GL_Setup3D( void ) {
- float screenAspect;
- int yb;
+ GLdouble xmin, xmax, ymin, ymax, aspect;
+ int yb = glr.fd.y + glr.fd.height;
- yb = glr.fd.y + glr.fd.height;
qglViewport( glr.fd.x, gl_config.vidHeight - yb,
glr.fd.width, glr.fd.height );
- screenAspect = ( float )glr.fd.width / glr.fd.height;
qglMatrixMode( GL_PROJECTION );
qglLoadIdentity();
- MYgluPerspective( glr.fd.fov_y, screenAspect,
- gl_znear->value, gl_zfar->value );
+
+ ymax = gl_znear->value * tan( glr.fd.fov_y * M_PI / 360.0 );
+ ymin = -ymax;
+
+ aspect = ( GLdouble )glr.fd.width / glr.fd.height;
+ xmin = ymin * aspect;
+ xmax = ymax * aspect;
+
+ qglFrustum( xmin, xmax, ymin, ymax, gl_znear->value, gl_zfar->value );
- qglMatrixMode( GL_MODELVIEW );
+ qglMatrixMode( GL_MODELVIEW );
qglLoadIdentity();
qglRotatef( -90, 1, 0, 0 ); /* put z axis up */
@@ -208,9 +203,82 @@ void GL_Setup3D( void ) {
qglRotatef( -glr.fd.viewangles[YAW], 0, 0, 1 );
qglTranslatef( -glr.fd.vieworg[0], -glr.fd.vieworg[1], -glr.fd.vieworg[2] );
+ AngleVectors( glr.fd.viewangles,
+ glr.viewaxis[0], glr.viewaxis[1], glr.viewaxis[2] );
+ VectorInverse( glr.viewaxis[1] );
+
+ glr.scroll = -64 * ( ( glr.fd.time / 40.0f ) - ( int )( glr.fd.time / 40.0f ) );
+ if( glr.scroll == 0 )
+ glr.scroll = -64.0f;
+
+
+#if 0
+ {
+ vec4_t position, diffuse;
+ vec4_t ambient, material;
+ VectorMA( glr.fd.vieworg, 128, glr.viewaxis[0], position );
+ position[3]=1;
+ VectorSet( diffuse, 1, 1, 1 );
+ VectorSet( material, 1, 1, 1 );
+ VectorSet( ambient, 0, 0, 0 );
+
+ qglLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
+ qglMaterialfv( GL_BACK, GL_AMBIENT_AND_DIFFUSE, material );
+
+ qglLightfv( GL_LIGHT0, GL_POSITION, position );
+ qglLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
+ }
+ qglEnable(GL_LIGHTING);
+ qglEnable( GL_LIGHT0 );
+#endif
+
GL_Bits( GLS_DEFAULT );
GL_CullFace( GLS_CULL_FRONT );
qglClear( GL_DEPTH_BUFFER_BIT );
}
+void GL_SetDefaultState( void ) {
+ qglDrawBuffer( GL_BACK );
+ qglClearColor( 0, 0, 0, 1 );
+ qglClearDepth( 1 );
+ qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ qglEnable( GL_DEPTH_TEST );
+ qglDepthFunc( GL_LEQUAL );
+ qglDepthRange( 0, 1 );
+ qglDepthMask( GL_TRUE );
+ qglDisable( GL_BLEND );
+ qglDisable( GL_ALPHA_TEST );
+ qglAlphaFunc( GL_GREATER, 0.666f );
+ qglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
+ qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
+ qglEnableClientState( GL_VERTEX_ARRAY );
+ qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
+
+ GL_SelectTMU( 0 );
+ qglEnable( GL_TEXTURE_2D );
+ GL_Bits( GLS_DEFAULT );
+}
+
+void GL_InitPrograms( void ) {
+ if( !qglProgramStringARB ) {
+ return;
+ }
+ qglGenProgramsARB( 1, &gl_static.prog_warp );
+ qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, gl_static.prog_warp );
+ qglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ sizeof( gl_prog_warp ) - 1, gl_prog_warp );
+ //Com_Printf( "%s\n", qglGetString( GL_PROGRAM_ERROR_STRING_ARB ) );
+
+ GL_ShowErrors( __func__ );
+}
+
+void GL_ShutdownPrograms( void ) {
+ if( !qglProgramStringARB ) {
+ return;
+ }
+ qglDeleteProgramsARB( 1, &gl_static.prog_warp );
+}
+
+
diff --git a/source/gl_surf.c b/source/gl_surf.c
index aadb720..5bcadb2 100644
--- a/source/gl_surf.c
+++ b/source/gl_surf.c
@@ -34,7 +34,7 @@ cvar_t *gl_modulate_hack;
/*
=============================================================================
-LIGHTMAP TEXTURES BUILDING
+LIGHTMAPS BUILDING
=============================================================================
*/
@@ -187,7 +187,7 @@ static int LM_BuildSurfaceLightmap( bspSurface_t *surf ) {
dst += LM_BLOCK_WIDTH * 4;
}
- surf->lightmapnum = lm.numMaps + 1;
+ surf->lightmapnum = lm.numMaps;
s = ( s << 4 ) + 8;
t = ( t << 4 ) + 8;
@@ -266,9 +266,13 @@ static int GL_BuildSurfacePoly( bspSurface_t *surf ) {
surf->polys = poly;
texinfo = surf->texinfo;
- if( !surf->lightmap || ( texinfo->flags & NOLIGHT_MASK ) ||
- gl_fullbright->integer )
- {
+ if( texinfo->flags & SURF_WARP ) {
+ if( qglProgramStringARB ) {
+ surf->type = DSURF_WARP;
+ } else {
+ surf->type = DSURF_NOLM;
+ }
+ } else if( !surf->lightmap || gl_fullbright->integer || ( texinfo->flags & NOLIGHT_MASK ) ) {
surf->type = DSURF_NOLM;
} else {
surf->type = DSURF_POLY;
@@ -286,7 +290,6 @@ static int GL_BuildSurfacePoly( bspSurface_t *surf ) {
}
if( index >= r_world.numEdges ) {
- printf( "LoadFace: bad edge index" );
return -1;
}
@@ -296,10 +299,8 @@ static int GL_BuildSurfacePoly( bspSurface_t *surf ) {
VectorCopy( src_vert->point, dst_vert );
/* texture coordinates */
- dst_vert[3] = DotProduct( dst_vert, texinfo->axis[0] ) +
- texinfo->offset[0];
- dst_vert[4] = DotProduct( dst_vert, texinfo->axis[1] ) +
- texinfo->offset[1];
+ dst_vert[3] = DotProduct( dst_vert, texinfo->axis[0] ) + texinfo->offset[0];
+ dst_vert[4] = DotProduct( dst_vert, texinfo->axis[1] ) + texinfo->offset[1];
/* lightmap coordinates */
dst_vert[5] = 0;
@@ -312,200 +313,35 @@ static int GL_BuildSurfacePoly( bspSurface_t *surf ) {
}
-#define SUBDIVIDE_SIZE 64
-#define SUBDIVIDE_VERTS 64
-
-static bspSurface_t *warpsurf;
-
-static void BoundPolygon( int numVerts, const vec_t *verts,
- vec3_t mins, vec3_t maxs )
-{
- ClearBounds( mins, maxs );
-
- while( numVerts-- ) {
- AddPointToBounds( verts, mins, maxs );
- verts += 3;
- }
-}
-
-
-static void SubdividePolygon_r( int numVerts, vec_t *verts ) {
- int i, j;
- vec3_t front[SUBDIVIDE_VERTS];
- vec3_t back[SUBDIVIDE_VERTS];
- vec_t dist[SUBDIVIDE_VERTS];
- vec3_t mins, maxs;
- int f, b;
- vec_t mid, frac, scale, *v;
- bspPoly_t *poly;
- vec3_t total;
- vec_t total_s, total_t;
- bspTexinfo_t *texinfo;
-
- if( numVerts > SUBDIVIDE_VERTS - 4 ) {
- Com_Error( ERR_DROP, "SubdividePolygon_r: numVerts = %d", numVerts );
- }
-
- BoundPolygon( numVerts, verts, mins, maxs );
-
- for( i = 0; i < 3; i++ ) {
- mid = ( mins[i] + maxs[i] ) * 0.5f;
- mid = SUBDIVIDE_SIZE * floor( mid / SUBDIVIDE_SIZE + 0.5f );
- if( mid - mins[i] < 8 ) {
- continue;
- }
- if( maxs[i] - mid < 8 ) {
- continue;
- }
-
- v = verts + i;
- for( j = 0; j < numVerts; j++, v += 3 ) {
- dist[j] = *v - mid;
- }
-
- dist[j] = dist[0];
- VectorCopy( verts, v - i );
-
- f = b = 0;
- v = verts;
- for( j = 0; j < numVerts; j++, v += 3 ) {
- if( dist[j] >= 0 ) {
- VectorCopy( v, front[f] ); f++;
- }
- if( dist[j] <= 0 ) {
- VectorCopy( v, back[b] ); b++;
- }
- if( dist[j] == 0 || dist[j+1] == 0 ) {
- continue;
- }
- if( ( dist[j] > 0 ) != ( dist[j+1] > 0 ) ) {
- frac = dist[j] / ( dist[j] - dist[j+1] );
- front[f][0] = back[b][0] = v[0] + frac * ( v[3+0] - v[0] );
- front[f][1] = back[b][1] = v[1] + frac * ( v[3+1] - v[1] );
- front[f][2] = back[b][2] = v[2] + frac * ( v[3+2] - v[2] );
- f++; b++;
- }
- }
-
- SubdividePolygon_r( f, front[0] );
- SubdividePolygon_r( b, back[0] );
- return;
- }
-
- poly = sys.HunkAlloc( &r_world.pool, sizeof( *poly ) +
- sizeof( vec_t ) * VERTEX_SIZE * numVerts );
- poly->next = warpsurf->polys;
- poly->numVerts = numVerts + 1;
- poly->numIndices = numVerts * 3;
- warpsurf->polys = poly;
-
- texinfo = warpsurf->texinfo;
- VectorClear( total );
- total_s = total_t = 0;
- v = poly->vertices + VERTEX_SIZE;
- for( i = 0; i < numVerts; i++ ) {
- VectorCopy( verts, v );
- v[3] = DotProduct( verts, texinfo->axis[0] );
- v[4] = DotProduct( verts, texinfo->axis[1] );
- total_s += v[3];
- total_t += v[4];
- VectorAdd( total, verts, total );
- verts += 3; v += VERTEX_SIZE;
- }
-
- /* middle point */
- v = poly->vertices;
- scale = 1.0f / numVerts;
- VectorScale( total, scale, v );
- v[3] = total_s * scale;
- v[4] = total_t * scale;
-
-}
-
-static int GL_BuildSurfaceWarpPolys( bspSurface_t *surf ) {
- int *src_surfedge;
- dvertex_t *src_vert;
- dedge_t *src_edge;
- vec_t *dst_vert;
- int i;
- int index, vertIndex;
- int numEdges = surf->numSurfEdges;
- vec3_t verts[SUBDIVIDE_VERTS];
-
- surf->polys = NULL;
- surf->type = DSURF_WARP;
- warpsurf = surf;
-
- src_surfedge = surf->firstSurfEdge;
- dst_vert = verts[0];
- for( i = 0; i < numEdges; i++ ) {
- index = *src_surfedge++;
-
- vertIndex = 0;
- if( index < 0 ) {
- index = -index;
- vertIndex = 1;
- }
-
- if( index >= r_world.numEdges ) {
- printf( "LoadFace: bad edge index" );
- return -1;
- }
-
- src_edge = r_world.edges + index;
- src_vert = r_world.vertices + src_edge->v[vertIndex];
-
- VectorCopy( src_vert->point, dst_vert );
-
- dst_vert += 3;
- }
-
- SubdividePolygon_r( numEdges, verts[0] );
-
- return 0;
-
-}
-
static void GL_NormalizeSurfaceTexcoords( bspSurface_t *surf ) {
bspTexinfo_t *texinfo = surf->texinfo;
bspPoly_t *poly = surf->polys;
vec_t *vert;
- tcoord_t *tc;
- int i;
vec2_t scale;
-
- surf->normalizedTC = sys.HunkAlloc( &r_world.pool, sizeof( tcoord_t ) * poly->numVerts );
+ int i;
scale[0] = 1.0f / texinfo->image->width;
scale[1] = 1.0f / texinfo->image->height;
+ if( texinfo->flags & SURF_WARP && qglBindProgramARB ) {
+ scale[0] *= 0.5f;
+ scale[1] *= 0.5f;
+ }
- tc = surf->normalizedTC;
vert = poly->vertices;
for( i = 0; i < poly->numVerts; i++ ) {
vert[3] *= scale[0];
vert[4] *= scale[1];
- tc->st[0] = DotProduct( vert, texinfo->normalizedAxis[0] );
- tc->st[1] = DotProduct( vert, texinfo->normalizedAxis[1] );
-
- vert += VERTEX_SIZE; tc++;
+ vert += VERTEX_SIZE;;
}
}
int GL_PostProcessSurface( bspSurface_t *surf ) {
bspTexinfo_t *texinfo = surf->texinfo;
- if( texinfo->flags & SURF_SKY ) {
- }
- if( ( texinfo->flags & SURF_WARP ) && gl_subdivide->integer ) {
- if( GL_BuildSurfaceWarpPolys( surf ) ) {
- return -1;
- }
- } else {
- if( GL_BuildSurfacePoly( surf ) ) {
- return -1;
- }
- GL_CalcSurfaceExtents( surf );
+ if( GL_BuildSurfacePoly( surf ) ) {
+ return -1;
}
+ GL_CalcSurfaceExtents( surf );
if( surf->type == DSURF_POLY ) {
if( LM_BuildSurfaceLightmap( surf ) ) {
@@ -513,14 +349,10 @@ int GL_PostProcessSurface( bspSurface_t *surf ) {
}
}
- if( !( texinfo->flags & (SURF_SKY|SURF_WARP) ) ) {
+ if( !( texinfo->flags & SURF_SKY ) ) {
GL_NormalizeSurfaceTexcoords( surf );
}
- if( ( texinfo->flags & SURF_WARP ) && !gl_subdivide->integer ) {
- GL_NormalizeSurfaceTexcoords( surf );
- }
-
return 0;
}
@@ -566,7 +398,7 @@ void GL_EndPostProcessing( void ) {
}
}
- Com_DPrintf( "GL_EndPostProcessing: %d lightmaps built\n", lm.numMaps );
+ Com_DPrintf( "%d lightmaps built\n", lm.numMaps );
}
diff --git a/source/gl_tess.c b/source/gl_tess.c
index ed115d3..122411a 100644
--- a/source/gl_tess.c
+++ b/source/gl_tess.c
@@ -22,848 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
tesselator_t tess;
-/*
-==============================================================================
-
-BSP surfaces sorting
-
-==============================================================================
-*/
-
-typedef struct {
- uint32 key;
- bspSurface_t *surf;
-} drawSurf_t;
-
-#define MAX_DRAW_SURFS ( 1 << 16 )
-#define DRAW_SURFS_MASK ( MAX_DRAW_SURFS - 1 )
-
-static drawSurf_t drawSurfs[MAX_DRAW_SURFS];
-static drawSurf_t drawSurfsBuffer[MAX_DRAW_SURFS];
-static int numDrawSurfs;
-
-image_t *GL_TextureAnimation( bspTexinfo_t *texinfo ) {
- int count;
-
- if( !texinfo->animNext ) {
- return texinfo->image;
- }
-
- count = ( int )( glr.fd.time * 2 ) % texinfo->numFrames;
- while( count ) {
- texinfo = texinfo->animNext;
- count--;
- }
-
- return texinfo->image;
-}
-
-
-void GL_AddBspSurface( bspSurface_t *surf ) {
- drawSurf_t *drawsurf;
- bspTexinfo_t *texinfo = surf->texinfo;
- int idx, istrans, texnum;
- image_t *image;
-
- if( surf->type >= DSURF_NUM_TYPES ) {
- Com_Error( ERR_FATAL, "GL_AddBspSurface: bad surf->type" );
- }
-
- if( surf->dlightframe != glr.drawframe ) {
- surf->dlightbits = 0;
- }
-
- istrans = 0;
- if( texinfo->flags & SURF_SKY ) {
- if( !gl_fastsky->integer ) {
- R_AddSkySurface( surf );
- return;
- }
- texnum = r_whiteimage->texnum;
- } else {
- if( texinfo->flags & (SURF_TRANS33|SURF_TRANS66) ) {
- if( texinfo->flags & SURF_TRANS33 ) {
- istrans = 1;
- } else {
- istrans = 2;
- }
- }
- image = GL_TextureAnimation( texinfo );
- texnum = image->texnum;
- }
-
- idx = numDrawSurfs & DRAW_SURFS_MASK;
- drawsurf = &drawSurfs[idx];
- drawsurf->key = ( istrans << 30 ) | ( texnum << 16 ) | surf->lightmapnum;
- drawsurf->surf = surf;
-
- numDrawSurfs++;
-}
-
-#define CopyDrawSurf( dst, src ) \
- ( (( uint32 * )dst)[0] = (( uint32 * )src)[0],\
- (( uint32 * )dst)[1] = (( uint32 * )src)[1] )
-
-static void mergeArray( int left, int median, int right ) {
- int count;
- int i, j;
- drawSurf_t *src, *dst;
-
- dst = drawSurfsBuffer;
- i = left;
- j = median + 1;
- while( i <= median && j <= right ) {
- if( drawSurfs[i].key < drawSurfs[j].key ) {
- CopyDrawSurf( dst, &drawSurfs[i] ); i++;
- } else {
- CopyDrawSurf( dst, &drawSurfs[j] ); j++;
- }
- dst++;
- }
-
- while( i <= median ) {
- CopyDrawSurf( dst, &drawSurfs[i] ); i++; dst++;
- }
-
- while( j <= right ) {
- CopyDrawSurf( dst, &drawSurfs[j] ); j++; dst++;
- }
-
- src = drawSurfsBuffer;
- count = dst - src;
- dst = drawSurfs + left;
- while( count-- ) {
- CopyDrawSurf( dst, src ); src++; dst++;
- }
-}
-
-static void mergeSort_r( int left, int right ) {
- int median;
-
- if( left < right ) {
- median = ( left + right ) >> 1;
-
- mergeSort_r( left, median );
- mergeSort_r( median + 1, right );
-
- mergeArray( left, median, right );
- }
-}
-
-
-/*
-==============================================================================
-
-Surface tesselation
-
-==============================================================================
-*/
-
-#define TURB_SCALE ( 256.0f / ( 2 * M_PI ) )
-
-static float r_turbsin[256] = {
- #include "warpsin.h"
-};
-
-static inline qboolean WouldOverflow( drawSurf_t *surf ) {
- bspPoly_t *poly;
- int numVerts, numIndices;
-
- if( tess.numFaces + 1 > TESS_MAX_FACES ) {
- return qtrue;
- }
-
- numVerts = tess.numVertices;
- numIndices = tess.numIndices;
- for( poly = surf->surf->polys; poly; poly = poly->next ) {
- numVerts += poly->numVerts;
- numIndices += poly->numIndices;
- }
-
- if( numVerts > TESS_MAX_VERTICES ) {
- return qtrue;
- }
- if( numIndices > TESS_MAX_INDICES ) {
- return qtrue;
- }
-
- return qfalse;
-}
-
-static void Tess_SimplePoly( drawSurf_t *surf ) {
- bspSurface_t *bspSurf = surf->surf;
- bspPoly_t *poly = bspSurf->polys;
- vec_t *src_vert, *dst_vert;
- tcoord_t *dst_tc;
- int *dst_indices;
- int i, count, currentVert;
- float scroll;
-
- scroll = 0;
- if( bspSurf->texinfo->flags & SURF_FLOWING ) {
- scroll = glr.scroll;
- }
-
- src_vert = poly->vertices;
- dst_vert = tess.vertices + tess.numVertices * 4;
- dst_tc = tess.tcoords + tess.numVertices;
- count = poly->numVerts;
- for( i = 0; i < count; i++ ) {
- VectorCopy( src_vert, dst_vert );
- dst_tc->st[0] = src_vert[3] + scroll;
- dst_tc->st[1] = src_vert[4];
- src_vert += VERTEX_SIZE; dst_vert += 4;
- dst_tc++;
- }
-
- dst_indices = tess.indices + tess.numIndices;
- count = poly->numVerts - 2;
- currentVert = tess.numVertices;
- for( i = 0; i < count; i++ ) {
- dst_indices[0] = currentVert;
- dst_indices[1] = currentVert + ( i + 1 );
- dst_indices[2] = currentVert + ( i + 2 );
- dst_indices += 3;
- }
-
- tess.faces[ tess.numFaces++ ] = bspSurf;
- tess.numVertices += poly->numVerts;
- tess.numIndices += poly->numIndices;
- tess.dlightbits |= bspSurf->dlightbits;
-
- c.trisDrawn += count;
-
-}
-
-static void Tess_LightmappedPoly( drawSurf_t *surf ) {
- bspSurface_t *bspSurf = surf->surf;
- bspPoly_t *poly = bspSurf->polys;
- vec_t *src_vert, *dst_vert;
- tcoord_t *dst_tc;
- tcoord_t *dst_lmtc;
- int *dst_indices;
- int i, count, currentVert;
-
- src_vert = poly->vertices;
- dst_vert = tess.vertices + tess.numVertices * 4;
- dst_tc = tess.tcoords + tess.numVertices;
- dst_lmtc = tess.lmtcoords + tess.numVertices;
- count = poly->numVerts;
- for( i = 0; i < count; i++ ) {
- VectorCopy( src_vert, dst_vert );
- *( uint32 * )&dst_tc->st[0] = *( uint32 * )&src_vert[3];
- *( uint32 * )&dst_tc->st[1] = *( uint32 * )&src_vert[4];
- *( uint32 * )&dst_lmtc->st[0] = *( uint32 * )&src_vert[5];
- *( uint32 * )&dst_lmtc->st[1] = *( uint32 * )&src_vert[6];
- src_vert += VERTEX_SIZE; dst_vert += 4;
- dst_tc++; dst_lmtc++;
- }
-
- dst_indices = tess.indices + tess.numIndices;
- count = poly->numVerts - 2;
- currentVert = tess.numVertices;
- for( i = 0; i < count; i++ ) {
- dst_indices[0] = currentVert;
- dst_indices[1] = currentVert + ( i + 1 );
- dst_indices[2] = currentVert + ( i + 2 );
- dst_indices += 3;
- }
-
- tess.faces[ tess.numFaces++ ] = bspSurf;
- tess.numVertices += poly->numVerts;
- tess.numIndices += poly->numIndices;
- tess.dlightbits |= bspSurf->dlightbits;
-
- c.trisDrawn += count;
-
-}
-
-#define DIV64 ( 1.0f / 64 )
-
-static void Tess_WarpPolys( drawSurf_t *surf ) {
- bspSurface_t *bspSurf = surf->surf;
- bspPoly_t *poly = bspSurf->polys;
- vec_t *src_vert, *dst_vert;
- tcoord_t *dst_tc;
- int *dst_indices;
- int i, j, k, count, currentVert;
- vec_t s, t;
- float scroll;
-
- scroll = 0;
- if( bspSurf->texinfo->flags & SURF_FLOWING ) {
- scroll = glr.scroll;
- }
-
- for( poly = bspSurf->polys; poly; poly = poly->next ) {
- src_vert = poly->vertices;
- dst_vert = tess.vertices + tess.numVertices * 4;
- dst_tc = tess.tcoords + tess.numVertices;
- count = poly->numVerts;
- for( i = 0; i < count; i++ ) {
- VectorCopy( src_vert, dst_vert );
- dst_vert += 4;
-
- s = src_vert[3];
- t = src_vert[4];
- src_vert += VERTEX_SIZE;
-
- j = Q_ftol( ( t * 0.125f + glr.fd.time ) * TURB_SCALE );
- k = Q_ftol( ( s * 0.125f + glr.fd.time ) * TURB_SCALE );
- s += r_turbsin[ j & 255 ];
- t += r_turbsin[ k & 255 ];
-
- dst_tc->st[0] = s * DIV64 + scroll;
- dst_tc->st[1] = t * DIV64;
- dst_tc++;
- }
-
- dst_indices = tess.indices + tess.numIndices;
- count = poly->numVerts - 2;
- currentVert = tess.numVertices;
- for( i = 0; i < count; i++ ) {
- dst_indices[0] = currentVert;
- dst_indices[1] = currentVert + ( i + 1 );
- dst_indices[2] = currentVert + ( i + 2 );
- dst_indices += 3;
- }
- dst_indices[0] = currentVert;
- dst_indices[1] = currentVert + ( i + 1 );
- dst_indices[2] = currentVert + 1;
- dst_indices += 3;
-
- tess.numVertices += poly->numVerts;
- tess.numIndices += poly->numIndices;
-
- c.trisDrawn += count + 1;
- }
-
- tess.faces[ tess.numFaces++ ] = bspSurf;
- tess.dlightbits |= bspSurf->dlightbits;
-
-}
-
-typedef void (*tesselatorFunc_t)( drawSurf_t * );
-
-tesselatorFunc_t tessTable[DSURF_NUM_TYPES] = {
- Tess_LightmappedPoly, /* DSURF_POLY */
- Tess_WarpPolys, /* DSURF_WARP */
- Tess_SimplePoly /* DSURF_NOLM */
-};
-
-/*
-==============================================================================
-
-Surface drawing
-
-==============================================================================
-*/
-
-void Tess_DrawSurfaceTriangles( int *indices, int numIndices ) {
- qglDisable( GL_TEXTURE_2D );
- qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
- GL_TexEnv( GL_REPLACE );
- qglDisable( GL_DEPTH_TEST );
- qglColor4f( 1, 1, 1, 1 );
-
- qglDrawElements( GL_TRIANGLES, numIndices, GL_UNSIGNED_INT,
- indices );
-
- qglEnable( GL_DEPTH_TEST );
- qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- qglEnable( GL_TEXTURE_2D );
- qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
-}
-
-#if 0
-static void ProjectDlightTexture( void ) {
- bspSurface_t *bspSurf;
- bspTexinfo_t *texinfo;
- cplane_t *plane;
- vec3_t point;
- vec2_t local;
- vec_t dist, scale, f;
- int i, j, faceNum, numIndices;
- dlight_t *light;
- tcoord_t *src_tc;
- vec_t *dst_tc;
-static vec_t tcArray[TESS_MAX_VERTICES*2];
-static byte colorsArray[TESS_MAX_VERTICES*4];
- int cfArray[TESS_MAX_VERTICES];
- int idxArray[TESS_MAX_INDICES];
- byte *dst_col;
- int v1, v2, v3;
- int *src_idx, *dst_idx;
- int clipflags;
- color_t color;
- int currentVert, maxVert;
-
- GL_BindTexture( r_dlightTex->texnum );
-// qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
- qglTexCoordPointer( 2, GL_FLOAT, 0, tcArray );
- qglEnableClientState( GL_COLOR_ARRAY );
- qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorsArray );
-
- for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) {
- currentVert = 0;
- for( faceNum = 0; faceNum < tess.numFaces; faceNum++, currentVert = maxVert ) {
- bspSurf = tess.faces[faceNum];
- maxVert = currentVert + bspSurf->polys->numVerts;
- if( !( bspSurf->dlightbits & ( 1 << i ) ) ) {
- //continue;
- }
- plane = bspSurf->plane;
- switch( plane->type ) {
- case PLANE_X:
- dist = light->transformed[0] - plane->dist;
- break;
- case PLANE_Y:
- dist = light->transformed[1] - plane->dist;
- break;
- case PLANE_Z:
- dist = light->transformed[2] - plane->dist;
- break;
- default:
- dist = DotProduct( light->transformed, plane->normal ) - plane->dist;
- break;
- }
-
- if( dist > light->intensity || dist < -light->intensity ) {
- //continue;
- }
-
- VectorMA( light->transformed, -dist, plane->normal, point );
-
- texinfo = bspSurf->texinfo;
- local[0] = DotProduct( point, texinfo->normalizedAxis[0] );
- local[1] = DotProduct( point, texinfo->normalizedAxis[1] );
-
- scale = 1.0f / light->intensity;
-
- dist = fabs( dist );
- f = 1.0f - dist * scale;
- if( f < 0 ) f = 0;
-
- color[0] = 255 * light->color[0] * f;
- color[1] = 255 * light->color[1] * f;
- color[2] = 255 * light->color[2] * f;
- color[3] = 255;
-
- src_tc = bspSurf->normalizedTC;
- dst_tc = tcArray + currentVert * 2;
- dst_col = colorsArray + currentVert * 4;
- for( j = currentVert; j < maxVert; j++ ) {
- dst_tc[0] = ( src_tc->st[0] - local[0] ) * scale + 0.5f;
- dst_tc[1] = ( src_tc->st[1] - local[1] ) * scale + 0.5f;
-
- /*clipflags = 0;
- if( dst_tc[0] > 1 ) {
- clipflags |= 1;
- } else if( dst_tc[0] < 0 ) {
- clipflags |= 2;
- }
- if( dst_tc[1] > 1 ) {
- clipflags |= 4;
- } else if( dst_tc[1] < 0 ) {
- clipflags |= 8;
- }*/
-
- *( uint32 * )dst_col = *( uint32 * )color;
- //cfArray[j] = clipflags;
-
- dst_col += 4; src_tc++; dst_tc += 2;
- }
-
- }
-
-#if 0
- numIndices = 0;
- src_idx = tess.indices;
- dst_idx = idxArray;
- for( faceNum = 0; faceNum < tess.numFaces; faceNum++ ) {
- bspSurf = tess.faces[faceNum];
- if( !( bspSurf->dlightbits & ( 1 << i ) ) ) {
- src_idx += bspSurf->polys->numIndices;
- continue;
- }
- for( j = 0; j < bspSurf->polys->numVerts - 2; j++ ) {
- v1 = src_idx[0];
- v2 = src_idx[1];
- v3 = src_idx[2];
- src_idx += 3;
- if( cfArray[v1] & cfArray[v2] & cfArray[v3] ) {
- continue;
- }
- dst_idx[0] = v1;
- dst_idx[1] = v2;
- dst_idx[2] = v3;
-
- dst_idx += 3;
- numIndices += 3;
- }
-
- }
-
- if( numIndices ) {
- qglDrawElements( GL_TRIANGLES, numIndices,
- GL_UNSIGNED_INT, idxArray );
- }
-#endif
- }
-
-// qglDisableClientState( GL_COLOR_ARRAY );
-}
-
-// f = ( l + d ) * t
-
-void EndSurface_Multitextured( void ) {
- GL_TexEnv( GL_REPLACE );
- GL_BindTexture( lm.lightmaps[ tess.lightmapnum - 1 ]->texnum );
- qglTexCoordPointer( 2, GL_FLOAT, 0, tess.lmtcoords );
-
- GL_SelectTMU( 1 );
- if( tess.dlightbits ) {
-
- qglEnable( GL_TEXTURE_2D );
- GL_TexEnv( GL_ADD );
-
- qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
- /* if( gl_dynamic->integer == 2 ) {
- GL_Bits( GLS_BLEND_MODULATE );
- } else {
- GL_Bits( GLS_BLEND_ADD );
- }*/
-
- ProjectDlightTexture();
- }
-
- /* enable texturing on TMU1 */
- GL_SelectTMU( 2 );
- qglEnable( GL_TEXTURE_2D );
- GL_BindTexture( tess.texnum );
- GL_TexEnv( GL_MODULATE );
- qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
- qglTexCoordPointer( 2, GL_FLOAT, 0, tess.tcoords );
-
- qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
- if( qglLockArraysEXT ) {
- qglLockArraysEXT( 0, tess.numVertices );
- }
- qglDrawElements( GL_TRIANGLES, tess.numIndices, GL_UNSIGNED_INT,
- tess.indices );
-
- /* disable texturing on TMU1 */
- qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
- qglDisable( GL_TEXTURE_2D );
- GL_SelectTMU( 1 );
-
- qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
- qglDisableClientState( GL_COLOR_ARRAY );
- qglDisable( GL_TEXTURE_2D );
- GL_SelectTMU( 0 );
-
-
- if( gl_showtris->integer ) {
- Tess_DrawSurfaceTriangles( tess.indices, tess.numIndices );
- }
-
- if( qglUnlockArraysEXT ) {
- qglUnlockArraysEXT();
- }
-
-
-}
-
-#else
-
-static void ProjectDlightTexture( void ) {
- bspSurface_t *bspSurf;
- bspTexinfo_t *texinfo;
- cplane_t *plane;
- vec3_t point;
- vec2_t local;
- vec_t dist, scale, f;
- int i, j, faceNum, numIndices;
- dlight_t *light;
- tcoord_t *src_tc;
- vec_t *dst_tc;
- vec_t tcArray[TESS_MAX_VERTICES*2];
- int cfArray[TESS_MAX_VERTICES];
- int idxArray[TESS_MAX_INDICES];
- byte colorsArray[TESS_MAX_VERTICES*4];
- byte *dst_col;
- int v1, v2, v3;
- int *src_idx, *dst_idx;
- int clipflags;
- color_t color;
- int currentVert, maxVert;
-
- GL_BindTexture( r_dlightTex->texnum );
- qglTexCoordPointer( 2, GL_FLOAT, 0, tcArray );
- qglEnableClientState( GL_COLOR_ARRAY );
- qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorsArray );
-
- for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) {
- currentVert = 0;
- for( faceNum = 0; faceNum < tess.numFaces; faceNum++, currentVert = maxVert ) {
- bspSurf = tess.faces[faceNum];
- maxVert = currentVert + bspSurf->polys->numVerts;
- if( !( bspSurf->dlightbits & ( 1 << i ) ) ) {
- continue;
- }
- plane = bspSurf->plane;
- switch( plane->type ) {
- case PLANE_X:
- dist = light->transformed[0] - plane->dist;
- break;
- case PLANE_Y:
- dist = light->transformed[1] - plane->dist;
- break;
- case PLANE_Z:
- dist = light->transformed[2] - plane->dist;
- break;
- default:
- dist = DotProduct( light->transformed, plane->normal ) - plane->dist;
- break;
- }
-
- if( dist > light->intensity || dist < -light->intensity ) {
- continue;
- }
-
- VectorMA( light->transformed, -dist, plane->normal, point );
-
- texinfo = bspSurf->texinfo;
- local[0] = DotProduct( point, texinfo->normalizedAxis[0] );
- local[1] = DotProduct( point, texinfo->normalizedAxis[1] );
-
- scale = 1.0f / light->intensity;
-
- dist = fabs( dist );
- f = 1.0f - dist * scale;
-
- color[0] = 255 * light->color[0] * f;
- color[1] = 255 * light->color[1] * f;
- color[2] = 255 * light->color[2] * f;
- color[3] = 255;
-
- src_tc = bspSurf->normalizedTC;
- dst_tc = tcArray + currentVert * 2;
- dst_col = colorsArray + currentVert * 4;
- for( j = currentVert; j < maxVert; j++ ) {
- dst_tc[0] = ( src_tc->st[0] - local[0] ) * scale + 0.5f;
- dst_tc[1] = ( src_tc->st[1] - local[1] ) * scale + 0.5f;
-
- clipflags = 0;
- if( dst_tc[0] > 1 ) {
- clipflags |= 1;
- } else if( dst_tc[0] < 0 ) {
- clipflags |= 2;
- }
- if( dst_tc[1] > 1 ) {
- clipflags |= 4;
- } else if( dst_tc[1] < 0 ) {
- clipflags |= 8;
- }
-
- *( uint32 * )dst_col = *( uint32 * )color;
- cfArray[j] = clipflags;
-
- dst_col += 4; src_tc++; dst_tc += 2;
- }
-
- }
-
- numIndices = 0;
- src_idx = tess.indices;
- dst_idx = idxArray;
- for( faceNum = 0; faceNum < tess.numFaces; faceNum++ ) {
- bspSurf = tess.faces[faceNum];
- if( !( bspSurf->dlightbits & ( 1 << i ) ) ) {
- src_idx += bspSurf->polys->numIndices;
- continue;
- }
- for( j = 0; j < bspSurf->polys->numVerts - 2; j++ ) {
- v1 = src_idx[0];
- v2 = src_idx[1];
- v3 = src_idx[2];
- src_idx += 3;
- if( cfArray[v1] & cfArray[v2] & cfArray[v3] ) {
- continue;
- }
- dst_idx[0] = v1;
- dst_idx[1] = v2;
- dst_idx[2] = v3;
-
- dst_idx += 3;
- numIndices += 3;
- }
-
- }
-
- if( numIndices ) {
- qglDrawElements( GL_TRIANGLES, numIndices,
- GL_UNSIGNED_INT, idxArray );
- }
- }
-
- qglDisableClientState( GL_COLOR_ARRAY );
-
-}
-
-void EndSurface_Multitextured( void ) {
- GL_BindTexture( tess.texnum );
- qglTexCoordPointer( 2, GL_FLOAT, 0, tess.tcoords );
-
- /* enable texturing on TMU1 */
- GL_SelectTMU( 1 );
- qglEnable( GL_TEXTURE_2D );
- GL_BindTexture( lm.lightmaps[ tess.lightmapnum - 1 ]->texnum );
- GL_TexEnv( GL_MODULATE );
- qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
- qglTexCoordPointer( 2, GL_FLOAT, 0, tess.lmtcoords );
-
- qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
- if( qglLockArraysEXT ) {
- qglLockArraysEXT( 0, tess.numVertices );
- }
- qglDrawElements( GL_TRIANGLES, tess.numIndices, GL_UNSIGNED_INT,
- tess.indices );
-
- /* disable texturing on TMU1 */
- qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
- qglDisable( GL_TEXTURE_2D );
- GL_SelectTMU( 0 );
-
- if( gl_showtris->integer ) {
- Tess_DrawSurfaceTriangles( tess.indices, tess.numIndices );
- }
-
- if( qglUnlockArraysEXT ) {
- qglUnlockArraysEXT();
- }
-
- if( tess.dlightbits ) {
- GL_TexEnv( GL_MODULATE );
- if( gl_dynamic->integer == 2 ) {
- GL_Bits( GLS_BLEND_MODULATE );
- } else {
- GL_Bits( GLS_BLEND_ADD );
- }
-
- ProjectDlightTexture();
- }
-
-}
-
-#endif
-
-void EndSurface_Single( void ) {
- GL_BindTexture( tess.texnum );
-
- qglTexCoordPointer( 2, GL_FLOAT, 0, tess.tcoords );
- qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
- if( qglLockArraysEXT ) {
- qglLockArraysEXT( 0, tess.numVertices );
- }
- qglDrawElements( GL_TRIANGLES, tess.numIndices, GL_UNSIGNED_INT,
- tess.indices );
- if( gl_showtris->integer ) {
- Tess_DrawSurfaceTriangles( tess.indices, tess.numIndices );
- }
- if( qglUnlockArraysEXT ) {
- qglUnlockArraysEXT();
- }
-}
-
-typedef void (*drawSurfFunc_t)( void );
-
-static drawSurfFunc_t endSurfTable[DSURF_NUM_TYPES] = {
- EndSurface_Multitextured, /* DSURF_POLY */
- EndSurface_Single, /* DSURF_WARP */
- EndSurface_Single /* DSURF_NOLM */
-};
-
-static void EndSurface( drawSurf_t *surf ) {
- int istrans = ( surf->key >> 30 ) & 3;
-
- if( istrans ) {
- GL_Bits( GLS_BLEND_BLEND | GLS_DEPTHMASK_FALSE );
- if( istrans == 1 ) {
- qglColor4f( 1, 1, 1, 0.33f );
- } else {
- qglColor4f( 1, 1, 1, 0.66f );
- }
- } else {
- GL_Bits( GLS_DEFAULT );
- qglColor4f( 1, 1, 1, 1 );
- }
-
- GL_TexEnv( GL_MODULATE );
-
- (*endSurfTable[surf->surf->type])();
-
- tess.numFaces = 0;
- tess.numVertices = 0;
- tess.numIndices = 0;
- tess.dlightbits = 0;
- tess.texnum = 0;
-
- c.batchesDrawn++;
-}
-
-static void BeginSurface( drawSurf_t *surf ) {
- if( WouldOverflow( surf ) ) {
- return;
- }
-
- tess.texnum = ( surf->key >> 16 ) & 1023;
- tess.lightmapnum = surf->key & 0xFFFF;
-
- (*tessTable[surf->surf->type])( surf );
-}
-
-void GL_SortAndDrawSurfs( qboolean doSort ) {
- drawSurf_t *surf, *last;
- int oldkey;
-
- if( !numDrawSurfs ) {
- return;
- }
-
- if( numDrawSurfs > MAX_DRAW_SURFS ) {
- Com_DPrintf( "MAX_DRAW_SURFS exceeded\n" );
- numDrawSurfs = MAX_DRAW_SURFS;
- }
-
- if( doSort && gl_sort->integer ) {
- mergeSort_r( 0, numDrawSurfs - 1 );
- }
-
- surf = drawSurfs;
- last = drawSurfs + numDrawSurfs;
- oldkey = surf->key;
- BeginSurface( surf );
- surf++;
-
- for( ; surf != last; surf++ ) {
- if( oldkey == surf->key && !WouldOverflow( surf ) ) {
- (*tessTable[surf->surf->type])( surf );
- continue;
- }
-
- EndSurface( surf - 1 );
-
- oldkey = surf->key;
- BeginSurface( surf );
- }
-
- EndSurface( surf - 1 );
-
- numDrawSurfs = 0;
-}
-
void GL_Flush2D( void ) {
glStateBits_t bits;
@@ -878,51 +36,47 @@ void GL_Flush2D( void ) {
bits |= GLS_ALPHATEST_ENABLE;
}
+ GL_BindTexture( tess.texnum );
GL_TexEnv( GL_MODULATE );
GL_Bits( bits );
+
qglEnableClientState( GL_COLOR_ARRAY );
- qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.colors );
- EndSurface_Single();
+ qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.colors );
+ qglTexCoordPointer( 2, GL_FLOAT, 0, tess.tcoords );
+ qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
+
+ qglDrawArrays( GL_QUADS, 0, tess.numVertices );
qglDisableClientState( GL_COLOR_ARRAY );
tess.numVertices = 0;
- tess.numIndices = 0;
tess.texnum = 0;
tess.istrans = 0;
-
}
void GL_StretchPic( float x, float y, float w, float h,
float s1, float t1, float s2, float t2, const byte *color, image_t *image )
{
- int currentVert, currentIdx;
vec_t *dst_vert;
- int *dst_idx;
tcoord_t *dst_tc;
uint32 *dst_color;
if( tess.numVertices + 4 > TESS_MAX_VERTICES ||
- tess.numIndices + 6 > TESS_MAX_INDICES ||
( tess.numVertices && tess.texnum != image->texnum ) )
{
GL_Flush2D();
}
- currentVert = tess.numVertices;
- currentIdx = tess.numIndices;
- tess.numVertices += 4;
- tess.numIndices += 6;
tess.texnum = image->texnum;
- dst_vert = tess.vertices + currentVert * 4;
- VectorSet( dst_vert + 0, x, y, 0 );
- VectorSet( dst_vert + 4, x + w, y, 0 );
+ dst_vert = tess.vertices + tess.numVertices * 4;
+ VectorSet( dst_vert, x, y, 0 );
+ VectorSet( dst_vert + 4, x + w, y, 0 );
VectorSet( dst_vert + 8, x + w, y + h, 0 );
- VectorSet( dst_vert + 12, x, y + h, 0 );
+ VectorSet( dst_vert + 12, x, y + h, 0 );
- dst_color = ( uint32 * )tess.colors + currentVert;
+ dst_color = ( uint32 * )tess.colors + tess.numVertices;
dst_color[0] = *( const uint32 * )color;
dst_color[1] = *( const uint32 * )color;
dst_color[2] = *( const uint32 * )color;
@@ -939,20 +93,13 @@ void GL_StretchPic( float x, float y, float w, float h,
tess.istrans |= 2;
}
- dst_tc = tess.tcoords + currentVert;
+ dst_tc = tess.tcoords + tess.numVertices;
dst_tc[0].st[0] = s1; dst_tc[0].st[1] = t1;
dst_tc[1].st[0] = s2; dst_tc[1].st[1] = t1;
dst_tc[2].st[0] = s2; dst_tc[2].st[1] = t2;
dst_tc[3].st[0] = s1; dst_tc[3].st[1] = t2;
- dst_idx = tess.indices + currentIdx;
- dst_idx[0] = currentVert;
- dst_idx[1] = currentVert + 1;
- dst_idx[2] = currentVert + 2;
- dst_idx[3] = currentVert;
- dst_idx[4] = currentVert + 2;
- dst_idx[5] = currentVert + 3;
-
+ tess.numVertices += 4;
}
void GL_DrawParticles( void ) {
@@ -961,23 +108,25 @@ void GL_DrawParticles( void ) {
vec3_t transformed;
vec_t scale, dist;
color_t color;
- int currentVert;
+ int numVertices;
vec_t *dst_vert;
uint32 *dst_color;
tcoord_t *dst_tc;
- int *dst_idx;
if( !glr.fd.num_particles ) {
return;
}
+ GL_BindTexture( r_particletexture->texnum );
GL_TexEnv( GL_MODULATE );
GL_Bits( GLS_BLEND_BLEND | GLS_DEPTHMASK_FALSE );
+
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.colors );
+ qglTexCoordPointer( 2, GL_FLOAT, 0, tess.tcoords );
+ qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
- tess.texnum = r_particletexture->texnum;
- currentVert = 0;
+ numVertices = 0;
for( i = 0, p = glr.fd.particles; i < glr.fd.num_particles; i++, p++ ) {
VectorSubtract( p->origin, glr.fd.vieworg, transformed );
dist = DotProduct( transformed, glr.viewaxis[0] );
@@ -994,43 +143,31 @@ void GL_DrawParticles( void ) {
}
color[3] = p->alpha * 255;
- if( currentVert + 3 > TESS_MAX_VERTICES ||
- currentVert + 3 > TESS_MAX_INDICES )
- {
- tess.numVertices = tess.numIndices = currentVert;
- EndSurface_Single();
- currentVert = 0;
+ if( numVertices + 3 > TESS_MAX_VERTICES ) {
+ qglDrawArrays( GL_TRIANGLES, 0, numVertices );
+ numVertices = 0;
}
- dst_vert = tess.vertices + currentVert * 4;
+ dst_vert = tess.vertices + numVertices * 4;
// VectorMA( p->origin, -scale*0.5f, glr.viewaxis[2], dst_vert );
VectorMA( p->origin, scale*0.5f, glr.viewaxis[1], dst_vert );
VectorMA( dst_vert, scale, glr.viewaxis[2], dst_vert + 4 );
VectorMA( dst_vert, -scale, glr.viewaxis[1], dst_vert + 8 );
- dst_color = ( uint32 * )tess.colors + currentVert;
+ dst_color = ( uint32 * )tess.colors + numVertices;
dst_color[0] = *( uint32 * )color;
dst_color[1] = *( uint32 * )color;
dst_color[2] = *( uint32 * )color;
- dst_tc = tess.tcoords + currentVert;
+ dst_tc = tess.tcoords + numVertices;
dst_tc[0].st[0] = 0.0625f; dst_tc[0].st[1] = 0.0625f;
dst_tc[1].st[0] = 1.0625f; dst_tc[1].st[1] = 0.0625f;
dst_tc[2].st[0] = 0.0625f; dst_tc[2].st[1] = 1.0625f;
- dst_idx = tess.indices + currentVert;
- dst_idx[0] = currentVert;
- dst_idx[1] = currentVert + 1;
- dst_idx[2] = currentVert + 2;
-
- currentVert += 3;
+ numVertices += 3;
}
- tess.numVertices = tess.numIndices = currentVert;
- EndSurface_Single();
- tess.numVertices = tess.numIndices = 0;
- tess.texnum = 0;
-
+ qglDrawArrays( GL_TRIANGLES, 0, numVertices );
qglDisableClientState( GL_COLOR_ARRAY );
}
@@ -1042,9 +179,8 @@ void GL_DrawBeams( void ) {
vec_t *dst_vert;
uint32 *dst_color;
tcoord_t *dst_tc;
- int *dst_idx;
vec_t length;
- int currentVert, currentIdx;
+ int numVertices;
entity_t *ent;
int i;
@@ -1052,14 +188,15 @@ void GL_DrawBeams( void ) {
return;
}
+ GL_BindTexture( r_beamtexture->texnum );
GL_TexEnv( GL_MODULATE );
GL_Bits( GLS_BLEND_ADD | GLS_DEPTHMASK_FALSE );
qglEnableClientState( GL_COLOR_ARRAY );
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.colors );
+ qglTexCoordPointer( 2, GL_FLOAT, 0, tess.tcoords );
+ qglVertexPointer( 3, GL_FLOAT, 16, tess.vertices );
- tess.texnum = r_beamtexture->texnum;
- currentVert = 0;
- currentIdx = 0;
+ numVertices = 0;
for( i = 0, ent = glr.fd.entities; i < glr.fd.num_entities; i++, ent++ ) {
if( !( ent->flags & RF_BEAM ) ) {
continue;
@@ -1082,111 +219,67 @@ void GL_DrawBeams( void ) {
}
color[3] = 255 * ent->alpha;
- if( currentVert + 4 > TESS_MAX_VERTICES ||
- currentIdx + 6 > TESS_MAX_INDICES )
- {
- tess.numVertices = currentVert;
- tess.numIndices = currentIdx;
- EndSurface_Single();
- currentVert = 0;
- currentIdx = 0;
+ if( numVertices + 4 > TESS_MAX_VERTICES ) {
+ qglDrawArrays( GL_QUADS, 0, numVertices );
+ numVertices = 0;
}
- dst_vert = tess.vertices + currentVert * 4;
+ dst_vert = tess.vertices + numVertices * 4;
VectorAdd( start, d3, dst_vert );
VectorSubtract( start, d3, dst_vert + 4 );
VectorSubtract( end, d3, dst_vert + 8 );
VectorAdd( end, d3, dst_vert + 12 );
- dst_color = ( uint32 * )tess.colors + currentVert;
+ dst_color = ( uint32 * )tess.colors + numVertices;
dst_color[0] = *( uint32 * )color;
dst_color[1] = *( uint32 * )color;
dst_color[2] = *( uint32 * )color;
dst_color[3] = *( uint32 * )color;
- dst_tc = tess.tcoords + currentVert;
+ dst_tc = tess.tcoords + numVertices;
dst_tc[0].st[0] = 0; dst_tc[0].st[1] = 0;
dst_tc[1].st[0] = 1; dst_tc[1].st[1] = 0;
dst_tc[2].st[0] = 1; dst_tc[2].st[1] = length;
dst_tc[3].st[0] = 0; dst_tc[3].st[1] = length;
- dst_idx = tess.indices + currentIdx;
- dst_idx[0] = currentVert + 0;
- dst_idx[1] = currentVert + 1;
- dst_idx[2] = currentVert + 2;
- dst_idx[3] = currentVert + 2;
- dst_idx[4] = currentVert + 3;
- dst_idx[5] = currentVert + 0;
-
- currentVert += 4;
- currentIdx += 6;
+ numVertices += 4;
}
-
- tess.numVertices = currentVert;
- tess.numIndices = currentIdx;
- EndSurface_Single();
- tess.numVertices = tess.numIndices = 0;
- tess.texnum = 0;
-
+
+ qglDrawArrays( GL_QUADS, 0, numVertices );
qglDisableClientState( GL_COLOR_ARRAY );
-
- qglDisableClientState( GL_COLOR_ARRAY );
-
}
-static void GL_DrawWarpPolys( bspSurface_t *surf ) {
- bspPoly_t *poly;
- vec_t *vert;
- int i, j, k;
- vec_t s, t;
-
- for( poly = surf->polys; poly; poly = poly->next ) {
- vert = poly->vertices;
- qglBegin( GL_TRIANGLE_FAN );
- for( i = 0; i < poly->numVerts + 1; i++ ) {
- if( i == poly->numVerts ) {
- vert = poly->vertices + VERTEX_SIZE;
- }
+static void GL_DrawWarp( bspSurface_t *surf ) {
+ bspPoly_t *poly = surf->polys;
+ vec4_t param;
- j = Q_ftol( ( vert[4] * 0.125 + glr.fd.time ) * TURB_SCALE );
- k = Q_ftol( ( vert[3] * 0.125 + glr.fd.time ) * TURB_SCALE );
-
- s = vert[3] + r_turbsin[j & 255];
- s *= DIV64;
+ qglEnable( GL_FRAGMENT_PROGRAM_ARB );
+ qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, gl_static.prog_warp );
+ param[0] = glr.fd.time * 0.125f;
+ param[1] = glr.fd.time * 0.125f;
+ param[2] = param[3] = 0;
+ qglProgramLocalParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, param );
- t = vert[4] + r_turbsin[k & 255];
- t *= DIV64;
+ GL_SelectTMU( 1 );
+ qglEnable( GL_TEXTURE_2D );
+ //GL_TexEnv( GL_MODULATE );
+ GL_BindTexture( r_warptexture->texnum );
- qglTexCoord2f( s, t );
- qglVertex3fv( vert );
+ qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
+ qglTexCoordPointer( 2, GL_FLOAT, 4*VERTEX_SIZE, poly->vertices + 3 );
- vert += VERTEX_SIZE;
- }
- qglEnd();
- }
-}
+ qglDrawArrays( GL_POLYGON, 0, poly->numVerts );
-static void GL_DrawNolmPoly( bspSurface_t *surf ) {
- bspPoly_t *poly = surf->polys;
- vec_t *vert;
- int i;
+ qglDisable( GL_TEXTURE_2D );
+ qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
+ GL_SelectTMU( 0 );
- qglBegin( GL_POLYGON );
- vert = poly->vertices;
- for( i = 0; i < poly->numVerts; i++ ) {
- qglTexCoord2fv( vert + 3 );
- qglVertex3fv( vert );
- vert += VERTEX_SIZE;
- }
- qglEnd();
+ qglDisable( GL_FRAGMENT_PROGRAM_ARB );
}
-
-void GL_DrawSurfPoly( bspSurface_t *surf ) {
+void GL_DrawSurf( bspSurface_t *surf ) {
bspTexinfo_t *texinfo = surf->texinfo;
- bspPoly_t *poly;
- vec_t *vert;
- int i;
+ bspPoly_t *poly = surf->polys;
if( ( texinfo->flags & SURF_SKY ) && !gl_fastsky->integer ) {
R_AddSkySurface( surf );
@@ -1200,43 +293,40 @@ void GL_DrawSurfPoly( bspSurface_t *surf ) {
} else {
qglColor4f( 1, 1, 1, 0.66f );
}
+ GL_TexEnv( GL_MODULATE );
} else {
- qglColor4f( 1, 1, 1, 1 );
GL_Bits( GLS_DEFAULT );
- qglColor4ubv( colorWhite );
+ GL_TexEnv( GL_REPLACE );
+ qglColor4f( 1, 1, 1, 1 );
}
- GL_TexEnv( GL_MODULATE );
GL_BindTexture( texinfo->image->texnum );
- if( surf->type == DSURF_WARP ) {
- GL_DrawWarpPolys( surf );
- return;
- }
+ qglVertexPointer( 3, GL_FLOAT, 4*VERTEX_SIZE, poly->vertices );
+ qglTexCoordPointer( 2, GL_FLOAT, 4*VERTEX_SIZE, poly->vertices + 3 );
+
+ if( surf->type == DSURF_WARP ) {
+// qglDrawArrays( GL_POLYGON, 0, poly->numVerts );
+ GL_DrawWarp( surf );
+ return;
+ }
if( surf->type == DSURF_NOLM ) {
- GL_DrawNolmPoly( surf );
+ qglDrawArrays( GL_POLYGON, 0, poly->numVerts );
return;
}
GL_SelectTMU( 1 );
qglEnable( GL_TEXTURE_2D );
- GL_BindTexture( lm.lightmaps[ surf->lightmapnum - 1 ]->texnum );
GL_TexEnv( GL_MODULATE );
-
- poly = surf->polys;
- vert = poly->vertices;
- qglBegin( GL_POLYGON );
- for( i = 0; i < poly->numVerts; i++ ) {
- qglMultiTexCoord2fvARB( GL_TEXTURE0_ARB, vert + 3 );
- qglMultiTexCoord2fvARB( GL_TEXTURE1_ARB, vert + 5 );
- qglVertex3fv( vert );
- vert += VERTEX_SIZE;
-
- }
- qglEnd();
+ GL_BindTexture( lm.lightmaps[surf->lightmapnum]->texnum );
+ qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
+ qglTexCoordPointer( 2, GL_FLOAT, 4*VERTEX_SIZE, poly->vertices + 5 );
+
+ qglDrawArrays( GL_POLYGON, 0, poly->numVerts );
qglDisable( GL_TEXTURE_2D );
+ qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
GL_SelectTMU( 0 );
}
diff --git a/source/gl_world.c b/source/gl_world.c
index ea05f5c..0626c41 100644
--- a/source/gl_world.c
+++ b/source/gl_world.c
@@ -22,10 +22,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
vec3_t modelViewOrigin; /* viewer origin in model space */
+#define FACE_HASH_SIZE 32
+#define FACE_HASH_MASK ( FACE_HASH_SIZE - 1 )
+
static vec3_t lightcolor;
+static bspSurface_t *alphaFaces;
+//static bspSurface_t *warpFaces;
+static bspSurface_t *faces_hash[FACE_HASH_SIZE];
static qboolean GL_LightPoint_r( bspNode_t *node, vec3_t start, vec3_t end ) {
- cplane_t *plane;
vec_t startFrac, endFrac, midFrac;
vec3_t mid;
int side;
@@ -39,13 +44,13 @@ static qboolean GL_LightPoint_r( bspNode_t *node, vec3_t start, vec3_t end ) {
int w1, w2, w3, w4;
int color[3];
- if( !( plane = node->plane ) ) {
+ if( !node->plane ) {
return qfalse;
}
/* calculate distancies */
- startFrac = DotProduct( plane->normal, start ) - plane->dist;
- endFrac = DotProduct( plane->normal, end ) - plane->dist;
+ startFrac = PlaneDiffFast( start, node->plane );
+ endFrac = PlaneDiffFast( end, node->plane );
side = ( startFrac < 0 );
if( ( endFrac < 0 ) == side ) {
@@ -55,9 +60,7 @@ static qboolean GL_LightPoint_r( bspNode_t *node, vec3_t start, vec3_t end ) {
/* find crossing point */
midFrac = startFrac / ( startFrac - endFrac );
- mid[0] = start[0] + ( end[0] - start[0] ) * midFrac;
- mid[1] = start[1] + ( end[1] - start[1] ) * midFrac;
- mid[2] = start[2] + ( end[2] - start[2] ) * midFrac;
+ LerpVector( start, end, midFrac, mid );
/* check near side */
ret = GL_LightPoint_r( node->children[side], start, mid );
@@ -114,15 +117,16 @@ static qboolean GL_LightPoint_r( bspNode_t *node, vec3_t start, vec3_t end ) {
/* check far side */
return GL_LightPoint_r( node->children[side^1], mid, end );
-
}
void GL_LightPoint( vec3_t origin, vec3_t dest ) {
extern cvar_t *gl_modulate_hack;
vec3_t point;
+#if USE_DYNAMIC
dlight_t *light;
vec3_t dir;
vec_t dist, f;
+#endif
int i;
if( !r_world.name[0] || gl_fullbright->integer ) {
@@ -143,6 +147,7 @@ void GL_LightPoint( vec3_t origin, vec3_t dest ) {
VectorScale( lightcolor, gl_modulate->value, lightcolor );
}
+#if USE_DYNAMIC
for( i = 0, light = glr.fd.dlights; i < glr.fd.num_dlights; i++, light++ ) {
VectorSubtract( light->origin, origin, dir );
dist = VectorLength( dir );
@@ -152,6 +157,7 @@ void GL_LightPoint( vec3_t origin, vec3_t dest ) {
f = 1.0f - dist / light->intensity;
VectorMA( lightcolor, f, light->color, lightcolor );
}
+#endif
/* apply modulate twice to mimic original ref_gl behavior */
VectorScale( lightcolor, gl_modulate->value, lightcolor );
@@ -168,28 +174,15 @@ void GL_LightPoint( vec3_t origin, vec3_t dest ) {
}
+#if USE_DYNAMIC
static void GL_MarkLights_r( bspNode_t *node, dlight_t *light ) {
- cplane_t *plane;
vec_t dot;
- int lightbit, count;
+ int count;
bspSurface_t *face;
+ int lightbit = 1 << light->index;
- while( ( plane = node->plane ) != NULL ) {
- switch( plane->type ) {
- case PLANE_X:
- dot = light->transformed[0] - plane->dist;
- break;
- case PLANE_Y:
- dot = light->transformed[1] - plane->dist;
- break;
- case PLANE_Z:
- dot = light->transformed[2] - plane->dist;
- break;
- default:
- dot = DotProduct( light->transformed, plane->normal ) - plane->dist;
- break;
- }
-
+ while( node->plane ) {
+ dot = PlaneDiffFast( light->transformed, node->plane );
if( dot > light->intensity ) {
node = node->children[0];
continue;
@@ -199,7 +192,6 @@ static void GL_MarkLights_r( bspNode_t *node, dlight_t *light ) {
continue;
}
- lightbit = 1 << light->index;
face = node->firstFace;
count = node->numFaces;
while( count-- ) {
@@ -253,8 +245,8 @@ static void GL_TransformLights( bspSubmodel_t *model ) {
GL_MarkLights_r( model->headnode, light );
}
-
}
+#endif
void GL_MarkLeaves( void ) {
byte fatvis[MAX_MAP_LEAFS/8];
@@ -352,6 +344,25 @@ finish:
}
+static inline void GL_AddSurf( bspSurface_t *face ) {
+ if( face->texinfo->flags & (SURF_TRANS33|SURF_TRANS66) ) {
+ face->next = alphaFaces;
+ alphaFaces = face;
+ } /*else if( face->type == SURF_WARP ) {
+ face->next = warpFaces;
+ warpFaces = face;
+ } */else {
+#if 0
+ GL_DrawSurf( face );
+#else
+ int i = ( face->texinfo->image->texnum ^ face->lightmapnum ) & FACE_HASH_MASK;
+ face->next = faces_hash[i];
+ faces_hash[i] = face;
+#endif
+ }
+ c.facesDrawn++;
+}
+
#define NODE_CLIPPED 0
#define NODE_UNCLIPPED 15
@@ -378,15 +389,6 @@ static inline qboolean GL_ClipNodeToFrustum( bspNode_t *node, int *clipflags ) {
return qtrue;
}
-typedef void (*drawFaceFunc_t)( bspSurface_t *surf );
-
-static drawFaceFunc_t drawFaceFunc;
-static drawFaceFunc_t drawFaceFuncTable[] = {
- GL_AddBspSurface,
- GL_DrawSurfPoly
-};
-
-static bspSurface_t *alphaFaces;
#define BACKFACE_EPSILON 0.001f
@@ -398,7 +400,6 @@ void GL_DrawBspModel( bspSubmodel_t *model ) {
int count;
vec3_t bounds[2];
vec_t dot;
- cplane_t *plane;
vec3_t temp;
entity_t *ent = glr.ent;
glCullResult_t cull;
@@ -435,65 +436,45 @@ void GL_DrawBspModel( bspSubmodel_t *model ) {
glr.drawframe++;
+#if USE_DYNAMIC
if( gl_dynamic->integer ) {
GL_TransformLights( model );
}
+#endif
+
+ qglPushMatrix();
+ qglTranslatef( ent->origin[0], ent->origin[1], ent->origin[2] );
+ if( glr.entrotated ) {
+ qglRotatef( ent->angles[YAW], 0, 0, 1 );
+ qglRotatef( ent->angles[PITCH], 0, 1, 0 );
+ qglRotatef( ent->angles[ROLL], 1, 0, 0 );
+ }
/* draw visible faces */
/* FIXME: go by headnode instead? */
face = model->firstFace;
count = model->numFaces;
while( count-- ) {
- plane = face->plane;
- switch( plane->type ) {
- case PLANE_X:
- dot = modelViewOrigin[0] - plane->dist;
- break;
- case PLANE_Y:
- dot = modelViewOrigin[1] - plane->dist;
- break;
- case PLANE_Z:
- dot = modelViewOrigin[2] - plane->dist;
- break;
- default:
- dot = DotProduct( modelViewOrigin, plane->normal ) - plane->dist;
- break;
- }
+ dot = PlaneDiffFast( modelViewOrigin, face->plane );
if( ( dot < -BACKFACE_EPSILON && face->side == SIDE_FRONT ) ||
( dot > BACKFACE_EPSILON && face->side == SIDE_BACK ) )
{
c.facesCulled++;
} else {
- if( face->texinfo->flags & (SURF_TRANS33|SURF_TRANS66) ) {
- face->next = alphaFaces;
- alphaFaces = face;
- } else {
- GL_AddBspSurface( face );
- }
- c.facesDrawn++;
+ /* FIXME: warp/trans surfaces are not supported */
+ GL_DrawSurf( face );
}
face++;
}
- qglPushMatrix();
- qglTranslatef( ent->origin[0], ent->origin[1], ent->origin[2] );
- if( glr.entrotated ) {
- qglRotatef( ent->angles[YAW], 0, 0, 1 );
- qglRotatef( ent->angles[PITCH], 0, 1, 0 );
- qglRotatef( ent->angles[ROLL], 1, 0, 0 );
- }
- GL_SortAndDrawSurfs( qtrue );
qglPopMatrix();
-
}
static void GL_WorldNode_r( bspNode_t *node, int clipflags ) {
bspLeaf_t *leaf;
bspSurface_t **leafFace, *face;
int count, side, area;
- cplane_t *plane;
vec_t dot;
- uint32 type;
while( node->visframe == glr.visframe ) {
if( gl_cull_nodes->integer && clipflags != NODE_UNCLIPPED &&
@@ -521,16 +502,9 @@ static void GL_WorldNode_r( bspNode_t *node, int clipflags ) {
break;
}
- plane = node->plane;
- type = plane->type;
- if( type < 3 ) {
- dot = modelViewOrigin[type] - plane->dist;
- } else {
- dot = DotProduct( modelViewOrigin, plane->normal ) - plane->dist;
- }
+ dot = PlaneDiffFast( modelViewOrigin, node->plane );
+ side = ( dot < 0 );
- side = dot < 0;
-
GL_WorldNode_r( node->children[side], clipflags );
face = node->firstFace;
@@ -538,13 +512,7 @@ static void GL_WorldNode_r( bspNode_t *node, int clipflags ) {
while( count-- ) {
if( face->drawframe == glr.drawframe ) {
if( face->side == side ) {
- if( face->texinfo->flags & (SURF_TRANS33|SURF_TRANS66) ) {
- face->next = alphaFaces;
- alphaFaces = face;
- } else {
- drawFaceFunc( face );
- }
- c.facesDrawn++;
+ GL_AddSurf( face );
} else {
c.facesCulled++;
}
@@ -560,47 +528,49 @@ static void GL_WorldNode_r( bspNode_t *node, int clipflags ) {
}
void GL_DrawWorld( void ) {
+ int i;
+ bspSurface_t *face;
+
GL_MarkLeaves();
+#if USE_DYNAMIC
if( gl_dynamic->integer ) {
GL_MarkLights();
}
+#endif
R_ClearSkyBox();
- drawFaceFunc = drawFaceFuncTable[gl_primitives->integer & 1];
-
VectorCopy( glr.fd.vieworg, modelViewOrigin );
GL_WorldNode_r( r_world.nodes, NODE_CLIPPED );
- GL_SortAndDrawSurfs( qtrue );
+
+ for( i = 0; i < FACE_HASH_SIZE; i++ ) {
+ for( face = faces_hash[i]; face; face = face->next ) {
+ GL_DrawSurf( face );
+ }
+ faces_hash[i] = NULL;
+ }
if( !gl_fastsky->integer ) {
R_DrawSkyBox();
}
-
}
void GL_DrawAlphaFaces( void ) {
bspSurface_t *face, *next;
- face = alphaFaces;
- if( !face ) {
- return;
- }
-
- drawFaceFunc = drawFaceFuncTable[gl_primitives->integer & 1];
-
- do {
- drawFaceFunc( face );
- /* Prevent loop condition in case the same face is included twice.
- * This should never happen normally. */
- next = face->next;
- face->next = NULL;
- face = next;
- } while( face );
+ if( ( face = alphaFaces ) == NULL ) {
+ return;
+ }
- GL_SortAndDrawSurfs( qfalse );
+ do {
+ GL_DrawSurf( face );
+ next = face->next;
+ face->next = NULL;
+ face = next;
+ } while( face );
- alphaFaces = NULL;
+ alphaFaces = NULL;
}
+
diff --git a/source/q_shared.h b/source/q_shared.h
index 53553aa..2c3a406 100644
--- a/source/q_shared.h
+++ b/source/q_shared.h
@@ -250,7 +250,7 @@ static inline float Q_fabs( float f ) {
((d)[0]=(a)[0]+(c)*((b)[0]-(a)[0]), \
(d)[1]=(a)[1]+(c)*((b)[1]-(a)[1]), \
(d)[2]=(a)[2]+(c)*((b)[2]-(a)[2]))
-
+#define PlaneDiff(v,p) (DotProduct(v,(p)->normal)-(p)->dist)
#define Vector4Subtract(a,b,c) (c[0]=a[0]-b[0],c[1]=a[1]-b[1],c[2]=a[2]-b[2],c[3]=a[3]-b[3])
#define Vector4Add(a,b,c) (c[0]=a[0]+b[0],c[1]=a[1]+b[1],c[2]=a[2]+b[2],c[3]=a[3]+b[3])
@@ -734,6 +734,15 @@ static inline int BoxOnPlaneSideFast( vec3_t emins, vec3_t emaxs, cplane_t *p )
return BoxOnPlaneSide( emins, emaxs, p );
}
+static inline vec_t PlaneDiffFast( vec3_t v, cplane_t *p ) {
+ // fast axial cases
+ if( p->type < 3 ) {
+ return v[p->type] - p->dist;
+ }
+
+ // slow generic case
+ return PlaneDiff( v, p );
+}
typedef struct csurface_s
{
diff --git a/source/qgl_api.c b/source/qgl_api.c
index 1f24f30..a796ca5 100644
--- a/source/qgl_api.c
+++ b/source/qgl_api.c
@@ -382,12 +382,16 @@ void ( APIENTRY * qglUnlockArraysEXT) ( void );
void ( APIENTRY * qglPointParameterfEXT)( GLenum param, GLfloat value );
void ( APIENTRY * qglPointParameterfvEXT)( GLenum param, const GLfloat *value );
void ( APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void * );
-void ( APIENTRY * qglSelectTextureSGIS)( GLenum );
-void ( APIENTRY * qglMTexCoord2fSGIS)( GLenum, GLfloat, GLfloat );
-void ( APIENTRY * qglMultiTexCoord2fvARB)( GLenum, const GLfloat * );
+
void ( APIENTRY * qglActiveTextureARB) ( GLenum );
void ( APIENTRY * qglClientActiveTextureARB) ( GLenum );
+void ( APIENTRY * qglProgramStringARB)( GLenum target, GLenum format, GLsizei len, const GLvoid *string );
+void ( APIENTRY * qglBindProgramARB)( GLenum target, GLuint program );
+void ( APIENTRY * qglDeleteProgramsARB)( GLsizei n, const GLuint *programs );
+void ( APIENTRY * qglGenProgramsARB)( GLsizei n, GLuint *programs );
+void ( APIENTRY * qglProgramLocalParameter4fvARB)( GLenum, GLuint, const GLfloat * );
+
#ifdef _WIN32
PROC ( WINAPI * qwglGetProcAddress )( LPCSTR );
BOOL ( WINAPI * qwglSwapIntervalEXT )( int interval );
@@ -3327,12 +3331,16 @@ void QGL_Init( void ) {
qglPointParameterfEXT = 0;
qglPointParameterfvEXT = 0;
qglColorTableEXT = 0;
- qglSelectTextureSGIS = 0;
- qglMTexCoord2fSGIS = 0;
- qglMultiTexCoord2fvARB = 0;
+
qglActiveTextureARB = 0;
qglClientActiveTextureARB = 0;
+ qglProgramStringARB = 0;
+ qglBindProgramARB = 0;
+ qglDeleteProgramsARB = 0;
+ qglGenProgramsARB = 0;
+ qglProgramLocalParameter4fvARB = 0;
+
#ifdef _WIN32
qwglGetProcAddress = GPA( "wglGetProcAddress" );
#endif
diff --git a/source/qgl_api.h b/source/qgl_api.h
index a63a5a4..91599c8 100644
--- a/source/qgl_api.h
+++ b/source/qgl_api.h
@@ -377,13 +377,15 @@ extern void ( APIENTRY * qglColorTableEXT)( int, int, int, int, int, const void
extern void ( APIENTRY * qglLockArraysEXT) (int , int);
extern void ( APIENTRY * qglUnlockArraysEXT) (void);
-extern void ( APIENTRY * qglMTexCoord2fSGIS)( GLenum, GLfloat, GLfloat );
-extern void ( APIENTRY * qglSelectTextureSGIS)( GLenum );
-
-extern void ( APIENTRY * qglMultiTexCoord2fvARB)( GLenum, const GLfloat * );
extern void ( APIENTRY * qglActiveTextureARB)( GLenum );
extern void ( APIENTRY * qglClientActiveTextureARB)( GLenum );
+extern void ( APIENTRY * qglProgramStringARB)( GLenum target, GLenum format, GLsizei len, const GLvoid *string );
+extern void ( APIENTRY * qglBindProgramARB)( GLenum target, GLuint program );
+extern void ( APIENTRY * qglDeleteProgramsARB)( GLsizei n, const GLuint *programs );
+extern void ( APIENTRY * qglGenProgramsARB)( GLsizei n, GLuint *programs );
+extern void ( APIENTRY * qglProgramLocalParameter4fvARB)( GLenum, GLuint, const GLfloat * );
+
//
// OS-specific
//
diff --git a/source/r_shared.h b/source/r_shared.h
index d9732a9..70a32da 100644
--- a/source/r_shared.h
+++ b/source/r_shared.h
@@ -222,7 +222,6 @@ typedef struct bspSurface_s {
int extents[2];
#ifdef OPENGL_RENDERER
- struct tcoord_s *normalizedTC;
struct bspPoly_s *polys;
int lightmapnum;
diff --git a/source/snd_dx.c b/source/snd_dx.c
index 660543c..3160aea 100644
--- a/source/snd_dx.c
+++ b/source/snd_dx.c
@@ -209,7 +209,7 @@ DS_Init
Direct-Sound support
==================
*/
-static sndinitstat DS_Init (void) {
+static sndinitstat_t DS_Init (void) {
DSCAPS dscaps;
HRESULT hresult;
LPDIRECTSOUNDCREATE pDirectSoundCreate;
@@ -298,49 +298,32 @@ static sndinitstat DS_Init (void) {
/*
==============
-DS_GetDMAPos
+DS_BeginPainting
+
+Makes sure dma.buffer is valid.
-return the current sample position (in mono samples read)
+Returns the current sample position (in mono samples read)
inside the recirculating dma buffer, so the mixing code will know
how many sample are required to fill it up.
===============
*/
-static int DS_GetDMAPos(void) {
- MMTIME mmtime;
- int s;
- DWORD dwWrite;
-
- if (!pDSBuf) {
- return 0;
- }
-
- mmtime.wType = TIME_SAMPLES;
- IDirectSoundBuffer_GetCurrentPosition(pDSBuf, &mmtime.u.sample, &dwWrite);
- s = mmtime.u.sample - mmstarttime.u.sample;
-
- s >>= sample16;
- s &= (dma.samples-1);
-
- return s;
-}
-
-/*
-==============
-DS_BeginPainting
-
-Makes sure dma.buffer is valid
-===============
-*/
static void DS_BeginPainting (void) {
- int reps;
+ int reps, s;
DWORD dwSize2;
DWORD *pbuf, *pbuf2;
HRESULT hresult;
- DWORD dwStatus;
+ DWORD dwStatus, dwWrite;
+ MMTIME mmtime;
if (!pDSBuf)
return;
+ // get sample pos
+ mmtime.wType = TIME_SAMPLES;
+ IDirectSoundBuffer_GetCurrentPosition(pDSBuf, &mmtime.u.sample, &dwWrite);
+ s = ( mmtime.u.sample - mmstarttime.u.sample ) >> sample16;
+ dma.samplepos = s & ( dma.samples - 1 );
+
// if the buffer was lost or stopped, restore it and/or restart it
if (IDirectSoundBuffer_GetStatus (pDSBuf, &dwStatus) != DS_OK) {
Com_EPrintf ("DS_BeginPainting: Couldn't get sound buffer status\n");
@@ -417,7 +400,6 @@ static void DS_Activate (qboolean active) {
void DS_FillAPI( snddmaAPI_t *api ) {
api->Init = DS_Init;
- api->GetDMAPos = DS_GetDMAPos;
api->Shutdown = DS_Shutdown;
api->BeginPainting = DS_BeginPainting;
api->Submit = DS_Submit;
diff --git a/source/snd_local.h b/source/snd_local.h
index af0f1e1..51a84f9 100644
--- a/source/snd_local.h
+++ b/source/snd_local.h
@@ -98,17 +98,15 @@ typedef struct channel_s
====================================================================
*/
-typedef enum { SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL } sndinitstat;
+typedef enum { SIS_SUCCESS, SIS_FAILURE, SIS_NOTAVAIL } sndinitstat_t;
typedef struct snddmaAPI_s {
// initializes cycling through a DMA buffer and returns information on it
- sndinitstat (*Init)( void );
-
-// gets the current DMA position
- int (*GetDMAPos)( void );
+ sndinitstat_t (*Init)( void );
// shutdown the DMA xfer.
void (*Shutdown)( void );
+
void (*BeginPainting)( void );
void (*Submit)( void );
void (*Activate)( qboolean active );
@@ -122,13 +120,9 @@ extern snddmaAPI_t snddma;
extern channel_t channels[MAX_CHANNELS];
extern int paintedtime;
-extern int s_rawend;
extern dma_t dma;
extern playsound_t s_pendingplays;
-#define MAX_RAW_SAMPLES 8192
-extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
-
extern cvar_t *s_volume;
extern cvar_t *s_khz;
extern cvar_t *s_testsound;
diff --git a/source/snd_main.c b/source/snd_main.c
index ddc3362..4418b46 100644
--- a/source/snd_main.c
+++ b/source/snd_main.c
@@ -47,7 +47,6 @@ int listener_entnum;
qboolean s_registering;
-int soundtime; // sample PAIRS
int paintedtime; // sample PAIRS
// during registration it is possible to have more sounds
@@ -76,44 +75,46 @@ static cvar_t *s_driver;
static cvar_t *s_ambient;
-int s_rawend;
-portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
-
snddmaAPI_t snddma;
-#if (defined _WIN32)
+#if USE_WAVE
void WAVE_FillAPI( snddmaAPI_t *api );
+#endif
+
+#if USE_DSOUND
void DS_FillAPI( snddmaAPI_t *api );
-#elif (defined __unix__)
+#endif
+
+#if USE_OSS
void OSS_FillAPI( snddmaAPI_t *api );
#endif
-#if (defined _WIN32) && (defined USE_DSOUND)
-#define DEFAULT_SOUND_DRIVER "dsound"
-#else
-#define DEFAULT_SOUND_DRIVER ""
+#if USE_SDL
+void QSDL_FillSoundAPI( snddmaAPI_t *api );
#endif
-typedef struct sndDriver_s {
- char *name;
- void (*FillAPI)( snddmaAPI_t *api );
-} sndDriver_t;
-static sndDriver_t s_driverTable[] = {
- /* fallback driver should be present on all systems */
-#if (defined _WIN32)
+// the first driver is the default one
+static struct {
+ char name[16];
+ void (*FillAPI)( snddmaAPI_t *api );
+} s_driverTable[] = {
+#if USE_DSOUND
+ { "dsound", DS_FillAPI },
+#endif
+#if USE_WAVE
{ "wave", WAVE_FillAPI },
-#elif (defined __unix__)
+#endif
+#if USE_OSS
{ "oss", OSS_FillAPI },
#endif
-
- /* DirectSound driver */
-#ifdef USE_DSOUND
- { "dsound", DS_FillAPI },
+#if USE_SDL
+ { "sdl", QSDL_FillSoundAPI },
#endif
};
-static int s_numDrivers = sizeof( s_driverTable ) / sizeof( s_driverTable[0] );
+static const int s_numDrivers =
+ sizeof( s_driverTable ) / sizeof( s_driverTable[0] );
/*
==========================================================================
@@ -204,9 +205,8 @@ S_Init
*/
void S_Init( void ) {
cvar_t *cv;
- sndDriver_t *driver;
- int i;
- sndinitstat ret = SIS_FAILURE;
+ int i, j = 0;
+ sndinitstat_t ret;
cv = Cvar_Get( "s_initsound", "1", 0 );
if( !cv->integer ) {
@@ -217,48 +217,43 @@ void S_Init( void ) {
Com_Printf( "------- S_Init -------\n" );
s_volume = Cvar_Get( "s_volume", "0.7", CVAR_ARCHIVE );
- s_khz = Cvar_Get( "s_khz", "11", CVAR_ARCHIVE );
+ s_khz = Cvar_Get( "s_khz", "22", CVAR_ARCHIVE );
s_loadas8bit = Cvar_Get( "s_loadas8bit", "1", CVAR_ARCHIVE );
s_mixahead = Cvar_Get( "s_mixahead", "0.2", CVAR_ARCHIVE );
s_show = Cvar_Get( "s_show", "0", 0 );
s_testsound = Cvar_Get( "s_testsound", "0", 0 );
- s_driver = Cvar_Get( "s_driver", DEFAULT_SOUND_DRIVER, CVAR_LATCHED );
+ s_driver = Cvar_Get( "s_driver", "", CVAR_LATCHED );
s_driver->subsystem = CVAR_SYSTEM_SOUND;
s_ambient = Cvar_Get( "s_ambient", "1", 0 );
+ // determine the first driver to try
+ if( s_driver->string[0] ) {
+ for( i = 0; i < s_numDrivers; i++ ) {
+ if( !strcmp( s_driver->string, s_driverTable[i].name ) ) {
+ j = i;
+ break;
+ }
+ }
+ }
+
+ // cycle until usable driver is found
+ i = j;
while( 1 ) {
- if( s_driver->string[0] ) {
- for( i = 0, driver = s_driverTable; i < s_numDrivers; i++, driver++ ) {
- if( !strcmp( s_driver->string, driver->name ) ) {
- break;
- }
- }
- if( i == s_numDrivers ) {
- Com_Printf( "Sound driver '%s' not found, falling back to default...\n", s_driver->string );
- Cvar_Set( "s_driver", "" );
- driver = &s_driverTable[0];
- }
- } else {
- driver = &s_driverTable[0];
- }
-
- driver->FillAPI( &snddma );
+ s_driverTable[i].FillAPI( &snddma );
ret = snddma.Init();
if( ret == SIS_SUCCESS ) {
break;
}
if( ret == SIS_NOTAVAIL ) {
- Com_Printf( "Sound hardware already in use, sound disabled.\n" );
+ Com_WPrintf( "Sound hardware already in use\n" );
return;
}
- if( !s_driver->string[0] ) {
- Com_WPrintf( "Couldn't fall back to default sound driver!\n" );
- return;
- }
-
- Com_Printf( "Failed to load sound driver, falling back to default...\n" );
- Cvar_Set( "s_driver", "" );
+ i = ( i + 1 ) % s_numDrivers;
+ if( i == j ) {
+ Com_WPrintf( "No usable sound driver found\n" );
+ return;
+ }
}
Cmd_Register( c_sound );
@@ -268,7 +263,6 @@ void S_Init( void ) {
sound_started = qtrue;
num_sfx = 0;
- soundtime = 0;
paintedtime = 0;
s_registration_sequence = 1;
@@ -854,8 +848,6 @@ void S_ClearBuffer (void)
if (!sound_started)
return;
- s_rawend = 0;
-
if (dma.samplebits == 8)
clear = 0x80;
else
@@ -993,142 +985,34 @@ void S_AddLoopSounds (void)
}
}
-//=============================================================================
-
-/*
-============
-S_RawSamples
-
-Cinematic streaming and voice over network
-============
-*/
-void S_RawSamples (int samples, int rate, int width, int channels, byte *data)
-{
- int i;
- int src, dst;
- float scale;
-
- if (!sound_started)
- return;
-
- if (s_rawend < paintedtime)
- s_rawend = paintedtime;
- scale = (float)rate / dma.speed;
-
-//Com_Printf ("%i < %i < %i\n", soundtime, paintedtime, s_rawend);
- if (channels == 2 && width == 2)
- {
- if (scale == 1.0)
- { // optimized case
- for (i=0 ; i<samples ; i++)
- {
- dst = s_rawend&(MAX_RAW_SAMPLES-1);
- s_rawend++;
- s_rawsamples[dst].left =
- LittleShort(((short *)data)[i*2]) << 8;
- s_rawsamples[dst].right =
- LittleShort(((short *)data)[i*2+1]) << 8;
- }
- }
- else
- {
- for (i=0 ; ; i++)
- {
- src = i*scale;
- if (src >= samples)
- break;
- dst = s_rawend&(MAX_RAW_SAMPLES-1);
- s_rawend++;
- s_rawsamples[dst].left =
- LittleShort(((short *)data)[src*2]) << 8;
- s_rawsamples[dst].right =
- LittleShort(((short *)data)[src*2+1]) << 8;
- }
- }
- }
- else if (channels == 1 && width == 2)
- {
- for (i=0 ; ; i++)
- {
- src = i*scale;
- if (src >= samples)
- break;
- dst = s_rawend&(MAX_RAW_SAMPLES-1);
- s_rawend++;
- s_rawsamples[dst].left =
- LittleShort(((short *)data)[src]) << 8;
- s_rawsamples[dst].right =
- LittleShort(((short *)data)[src]) << 8;
- }
- }
- else if (channels == 2 && width == 1)
- {
- for (i=0 ; ; i++)
- {
- src = i*scale;
- if (src >= samples)
- break;
- dst = s_rawend&(MAX_RAW_SAMPLES-1);
- s_rawend++;
- s_rawsamples[dst].left =
- ((char *)data)[src*2] << 16;
- s_rawsamples[dst].right =
- ((char *)data)[src*2+1] << 16;
- }
- }
- else if (channels == 1 && width == 1)
- {
- for (i=0 ; ; i++)
- {
- src = i*scale;
- if (src >= samples)
- break;
- dst = s_rawend&(MAX_RAW_SAMPLES-1);
- s_rawend++;
- s_rawsamples[dst].left =
- (((byte *)data)[src]-128) << 16;
- s_rawsamples[dst].right = (((byte *)data)[src]-128) << 16;
- }
- }
-}
-
// =======================================================================
// Update sound buffer
// =======================================================================
-static void S_GetTime(void)
-{
- int samplepos;
+static int S_GetTime(void) {
static int buffers;
static int oldsamplepos;
- int fullsamples;
-
- fullsamples = dma.samples / dma.channels;
+ int fullsamples = dma.samples / dma.channels;
// it is possible to miscount buffers if it has wrapped twice between
// calls to S_Update. Oh well.
- samplepos = snddma.GetDMAPos();
-
- if (samplepos < oldsamplepos)
- {
+ if (dma.samplepos < oldsamplepos) {
buffers++; // buffer wrapped
-
- if (paintedtime > 0x40000000)
- { // time to chop things off to avoid 32 bit limits
+ if (paintedtime > 0x40000000) {
+ // time to chop things off to avoid 32 bit limits
buffers = 0;
paintedtime = fullsamples;
- S_StopAllSounds ();
+ S_StopAllSounds();
}
}
- oldsamplepos = samplepos;
+ oldsamplepos = dma.samplepos;
- soundtime = buffers*fullsamples + samplepos/dma.channels;
+ return buffers*fullsamples + dma.samplepos/dma.channels;
}
-static void S_Update_(void)
-{
- unsigned endtime;
- int samps;
+static void S_Update_(void) {
+ int soundtime, endtime;
+ int samps;
snddma.BeginPainting ();
@@ -1136,11 +1020,10 @@ static void S_Update_(void)
return;
// Updates DMA time
- S_GetTime();
+ soundtime = S_GetTime();
// check to make sure that we haven't overshot
- if (paintedtime < soundtime)
- {
+ if (paintedtime < soundtime) {
Com_DPrintf ("S_Update_ : overflow\n");
paintedtime = soundtime;
}
@@ -1150,8 +1033,8 @@ static void S_Update_(void)
//endtime = (soundtime + 4096) & ~4095;
// mix to an even submission block size
- endtime = (endtime + dma.submission_chunk-1)
- & ~(dma.submission_chunk-1);
+ endtime = (endtime + dma.submission_chunk - 1)
+ & ~(dma.submission_chunk - 1);
samps = dma.samples >> (dma.channels-1);
if (endtime - soundtime > samps)
endtime = soundtime + samps;
diff --git a/source/snd_mix.c b/source/snd_mix.c
index aedbcc4..29e3def 100644
--- a/source/snd_mix.c
+++ b/source/snd_mix.c
@@ -29,13 +29,11 @@ int *snd_p, snd_linear_count, snd_vol;
short *snd_out;
#ifndef USE_ASM
-void S_WriteLinearBlastStereo16 (void)
-{
+static void S_WriteLinearBlastStereo16 (void) {
int i;
int val;
- for (i=0 ; i<snd_linear_count ; i+=2)
- {
+ for (i=0 ; i<snd_linear_count ; i+=2) {
val = snd_p[i]>>8;
if (val > 0x7fff)
snd_out[i] = 0x7fff;
@@ -57,16 +55,14 @@ void S_WriteLinearBlastStereo16 (void)
void S_WriteLinearBlastStereo16 (void);
#endif
-void S_TransferStereo16 (unsigned long *pbuf, int endtime)
-{
+static void S_TransferStereo16 (unsigned long *pbuf, int endtime) {
int lpos;
int lpaintedtime;
snd_p = (int *) paintbuffer;
lpaintedtime = paintedtime;
- while (lpaintedtime < endtime)
- {
+ while (lpaintedtime < endtime) {
// handle recirculating buffer issues
lpos = lpaintedtime & ((dma.samples>>1)-1);
@@ -86,26 +82,57 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime)
}
}
-/*
-===================
-S_TransferPaintBuffer
-
-===================
-*/
-void S_TransferPaintBuffer(int endtime)
-{
+static void S_TransferStereo( unsigned long *pbuf, int endtime ) {
int out_idx;
int count;
int out_mask;
int *p;
int step;
int val;
- unsigned long *pbuf;
- pbuf = (unsigned long *)dma.buffer;
+ p = (int *) paintbuffer;
+ count = (endtime - paintedtime) * dma.channels;
+ out_mask = dma.samples - 1;
+ out_idx = paintedtime * dma.channels & out_mask;
+ step = 3 - dma.channels;
+
+ if (dma.samplebits == 16) {
+ short *out = (short *) pbuf;
+ while (count--) {
+ val = *p >> 8;
+ p+= step;
+ if (val > 0x7fff)
+ val = 0x7fff;
+ else if (val < (short)0x8000)
+ val = (short)0x8000;
+ out[out_idx] = val;
+ out_idx = (out_idx + 1) & out_mask;
+ }
+ } else if (dma.samplebits == 8) {
+ unsigned char *out = (unsigned char *) pbuf;
+ while (count--) {
+ val = *p >> 8;
+ p+= step;
+ if (val > 0x7fff)
+ val = 0x7fff;
+ else if (val < (short)0x8000)
+ val = (short)0x8000;
+ out[out_idx] = (val>>8) + 128;
+ out_idx = (out_idx + 1) & out_mask;
+ }
+ }
+}
+
+/*
+===================
+S_TransferPaintBuffer
+
+===================
+*/
+static void S_TransferPaintBuffer(int endtime) {
+ unsigned long *pbuf = (unsigned long *)dma.buffer;
- if (s_testsound->integer)
- {
+ if (s_testsound->integer) {
int i;
int count;
@@ -115,49 +142,12 @@ void S_TransferPaintBuffer(int endtime)
paintbuffer[i].left = paintbuffer[i].right = sin((paintedtime+i)*0.1)*20000*256;
}
-
- if (dma.samplebits == 16 && dma.channels == 2)
- { // optimized case
+ if (dma.samplebits == 16 && dma.channels == 2) {
+ // optimized case
S_TransferStereo16 (pbuf, endtime);
- }
- else
- { // general case
- p = (int *) paintbuffer;
- count = (endtime - paintedtime) * dma.channels;
- out_mask = dma.samples - 1;
- out_idx = paintedtime * dma.channels & out_mask;
- step = 3 - dma.channels;
-
- if (dma.samplebits == 16)
- {
- short *out = (short *) pbuf;
- while (count--)
- {
- val = *p >> 8;
- p+= step;
- if (val > 0x7fff)
- val = 0x7fff;
- else if (val < (short)0x8000)
- val = (short)0x8000;
- out[out_idx] = val;
- out_idx = (out_idx + 1) & out_mask;
- }
- }
- else if (dma.samplebits == 8)
- {
- unsigned char *out = (unsigned char *) pbuf;
- while (count--)
- {
- val = *p >> 8;
- p+= step;
- if (val > 0x7fff)
- val = 0x7fff;
- else if (val < (short)0x8000)
- val = (short)0x8000;
- out[out_idx] = (val>>8) + 128;
- out_idx = (out_idx + 1) & out_mask;
- }
- }
+ } else {
+ // general case
+ S_TransferStereo( pbuf, endtime );
}
}
@@ -170,11 +160,78 @@ CHANNEL MIXING
===============================================================================
*/
-void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
-void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime, int offset);
+static void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count, int offset) {
+ int data;
+ int *lscale, *rscale;
+ byte *sfx;
+ int i;
+ portable_samplepair_t *samp;
+
+ if (ch->leftvol > 255)
+ ch->leftvol = 255;
+ if (ch->rightvol > 255)
+ ch->rightvol = 255;
+
+ //ZOID-- >>11 has been changed to >>3, >>11 didn't make much sense
+ //as it would always be zero.
+ lscale = snd_scaletable[ ch->leftvol >> 3];
+ rscale = snd_scaletable[ ch->rightvol >> 3];
+ samp = &paintbuffer[offset];
+
+ sfx = sc->data + ch->pos * sc->channels;
+
+ if( sc->channels == 2 ) {
+ for( i=0 ; i<count ; i++, samp++ ) {
+ samp->left += lscale[*sfx++];
+ samp->right += rscale[*sfx++];
+ }
+ } else {
+ for( i=0 ; i<count ; i++, samp++ ) {
+ data = *sfx++;
+ samp->left += lscale[data];
+ samp->right += rscale[data];
+ }
+ }
+
+ ch->pos += count;
+}
+
+static void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset) {
+ int data;
+ int left, right;
+ int leftvol, rightvol;
+ signed short *sfx;
+ int i;
+ portable_samplepair_t *samp;
+
+ leftvol = ch->leftvol*snd_vol;
+ rightvol = ch->rightvol*snd_vol;
+ samp = &paintbuffer[offset];
+
+ sfx = (signed short *)sc->data + ch->pos * sc->channels;
+
+ if( sc->channels == 2 ) {
+ for( i=0 ; i<count ; i++, samp++ ) {
+ left = ( *sfx++ * leftvol ) >> 8;
+ right = ( *sfx++ * rightvol ) >> 8;
+ samp->left += left;
+ samp->right += right;
+ }
+ } else {
+ for( i=0 ; i<count ; i++, samp++ ) {
+ data = *sfx++;
+ left = ( data * leftvol ) >> 8;
+ right = ( data * rightvol ) >> 8;
+ samp->left += left;
+ samp->right += right;
+ }
+ }
+
+ ch->pos += count;
+}
+
-void S_PaintChannels(int endtime)
-{
+void S_PaintChannels(int endtime) {
int i;
int end;
channel_t *ch;
@@ -184,22 +241,18 @@ void S_PaintChannels(int endtime)
snd_vol = s_volume->value*256;
-//Com_Printf ("%i to %i\n", paintedtime, endtime);
- while (paintedtime < endtime)
- {
- // if paintbuffer is smaller than DMA buffer
+ while (paintedtime < endtime) {
+ // if paintbuffer is smaller than DMA buffer
end = endtime;
- if (endtime - paintedtime > PAINTBUFFER_SIZE)
+ if (end - paintedtime > PAINTBUFFER_SIZE)
end = paintedtime + PAINTBUFFER_SIZE;
// start any playsounds
- while (1)
- {
+ while (1) {
ps = s_pendingplays.next;
if (ps == &s_pendingplays)
break; // no more pending sounds
- if (ps->begin <= paintedtime)
- {
+ if (ps->begin <= paintedtime) {
S_IssuePlaysound (ps);
continue;
}
@@ -209,44 +262,15 @@ void S_PaintChannels(int endtime)
break;
}
- // clear the paint buffer
- if (s_rawend < paintedtime)
- {
-// Com_Printf ("clear\n");
- memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
- }
- else
- { // copy from the streaming sound source
- int s;
- int stop;
-
- stop = (end < s_rawend) ? end : s_rawend;
-
- for (i=paintedtime ; i<stop ; i++)
- {
- s = i&(MAX_RAW_SAMPLES-1);
- paintbuffer[i-paintedtime] = s_rawsamples[s];
- }
-// if (i != end)
-// Com_Printf ("partial stream\n");
-// else
-// Com_Printf ("full stream\n");
- for ( ; i<end ; i++)
- {
- paintbuffer[i-paintedtime].left = 0;
- paintbuffer[i-paintedtime].right = 0;
- }
- }
-
+ // clear the paint buffer
+ memset(paintbuffer, 0, (end - paintedtime) * sizeof(portable_samplepair_t));
- // paint in the channels.
+ // paint in the channels.
ch = channels;
- for (i=0; i<MAX_CHANNELS ; i++, ch++)
- {
+ for (i=0; i<MAX_CHANNELS ; i++, ch++) {
ltime = paintedtime;
- while (ltime < end)
- {
+ while (ltime < end) {
if (!ch->sfx || (!ch->leftvol && !ch->rightvol) )
break;
@@ -261,8 +285,7 @@ void S_PaintChannels(int endtime)
if (!sc)
break;
- if (count > 0 && ch->sfx)
- {
+ if (count > 0 && ch->sfx) {
if (sc->width == 1)// FIXME; 8 bit asm is wrong now
S_PaintChannelFrom8(ch, sc, count, ltime - paintedtime);
else
@@ -271,21 +294,17 @@ void S_PaintChannels(int endtime)
ltime += count;
}
- // if at end of loop, restart
- if (ltime >= ch->end)
- {
- if (ch->autosound)
- { // autolooping sounds always go back to start
+ // if at end of loop, restart
+ if (ltime >= ch->end) {
+ if (ch->autosound) {
+ // autolooping sounds always go back to start
ch->pos = 0;
ch->end = ltime + sc->length;
- }
- else if (sc->loopstart >= 0)
- {
+ } else if (sc->loopstart >= 0) {
ch->pos = sc->loopstart;
ch->end = ltime + sc->length - ch->pos;
- }
- else
- { // channel just stopped
+ } else {
+ // channel just stopped
ch->sfx = NULL;
}
}
@@ -293,102 +312,23 @@ void S_PaintChannels(int endtime)
}
- // transfer out according to DMA format
+ // transfer out according to DMA format
S_TransferPaintBuffer(end);
paintedtime = end;
}
}
-void S_InitScaletable (void)
-{
+void S_InitScaletable (void) {
int i, j;
int scale;
Cvar_ClampValue( s_volume, 0, 2 );
s_volume->modified = qfalse;
- for (i=0 ; i<32 ; i++)
- {
+ for (i=0 ; i<32 ; i++) {
scale = i * 8 * 256 * s_volume->value;
for (j=0 ; j<256 ; j++)
snd_scaletable[i][j] = ((signed char)j) * scale;
}
}
-
-
-
-void S_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count, int offset)
-{
- int data;
- int *lscale, *rscale;
- byte *sfx;
- int i;
- portable_samplepair_t *samp;
-
- if (ch->leftvol > 255)
- ch->leftvol = 255;
- if (ch->rightvol > 255)
- ch->rightvol = 255;
-
- //ZOID-- >>11 has been changed to >>3, >>11 didn't make much sense
- //as it would always be zero.
- lscale = snd_scaletable[ ch->leftvol >> 3];
- rscale = snd_scaletable[ ch->rightvol >> 3];
- samp = &paintbuffer[offset];
-
- sfx = sc->data + ch->pos * sc->channels;
-
- if( sc->channels == 2 ) {
- for( i=0 ; i<count ; i++, samp++ ) {
- samp->left += lscale[*sfx++];
- samp->right += rscale[*sfx++];
- }
- } else {
- for( i=0 ; i<count ; i++, samp++ ) {
- data = *sfx++;
- samp->left += lscale[data];
- samp->right += rscale[data];
- }
- }
-
- ch->pos += count;
-}
-
-
-
-void S_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count, int offset)
-{
- int data;
- int left, right;
- int leftvol, rightvol;
- signed short *sfx;
- int i;
- portable_samplepair_t *samp;
-
- leftvol = ch->leftvol*snd_vol;
- rightvol = ch->rightvol*snd_vol;
- samp = &paintbuffer[offset];
-
- sfx = (signed short *)sc->data + ch->pos * sc->channels;
-
- if( sc->channels == 2 ) {
- for( i=0 ; i<count ; i++, samp++ ) {
- left = ( *sfx++ * leftvol ) >> 8;
- right = ( *sfx++ * rightvol ) >> 8;
- samp->left += left;
- samp->right += right;
- }
- } else {
- for( i=0 ; i<count ; i++, samp++ ) {
- data = *sfx++;
- left = ( data * leftvol ) >> 8;
- right = ( data * rightvol ) >> 8;
- samp->left += left;
- samp->right += right;
- }
- }
-
- ch->pos += count;
-}
-
diff --git a/source/snd_oss.c b/source/snd_oss.c
index f47dd86..e1dd69c 100644
--- a/source/snd_oss.c
+++ b/source/snd_oss.c
@@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <stdio.h>
#include <errno.h>
-#include "cl_local.h"
+#include "com_local.h"
#include "snd_local.h"
static int audio_fd;
@@ -47,7 +47,7 @@ static cvar_t *snddevice;
static int tryrates[] = { 22050, 11025, 44100, 48000, 8000 };
-static sndinitstat OSS_Init ( void ) {
+static sndinitstat_t OSS_Init ( void ) {
int rc;
int fmt;
int tmp;
@@ -74,16 +74,6 @@ static sndinitstat OSS_Init ( void ) {
return SIS_FAILURE;
}
-#if 0
- rc = ioctl ( audio_fd, SNDCTL_DSP_RESET, 0 );
- if ( rc < 0 ) {
- perror ( snddevice->string );
- Com_Printf ( "Could not reset %s\n", snddevice->string );
- close ( audio_fd );
- return SIS_FAILURE;
- }
-#endif
-
if ( ioctl ( audio_fd, SNDCTL_DSP_GETCAPS, &caps ) == -1 ) {
Com_WPrintf ( "Could not get caps of %s: %s\n", snddevice->string,
strerror ( errno ) );
@@ -216,43 +206,39 @@ fail:
return SIS_FAILURE;
}
-static int OSS_GetDMAPos ( void ) {
+static void OSS_Shutdown ( void ) {
+ if ( snd_inited ) {
+ Com_Printf ( "Shutting down OSS\n" );
+ ioctl ( audio_fd, SNDCTL_DSP_RESET );
+ munmap ( dma.buffer, info.fragstotal * info.fragsize );
+ close ( audio_fd );
+ snd_inited = qfalse;
+ }
+}
+
+static void OSS_BeginPainting ( void ) {
struct count_info count;
if ( !snd_inited )
- return 0;
+ return;
- if ( ioctl ( audio_fd, SNDCTL_DSP_GETOPTR, &count ) ==-1 ) {
+ if ( ioctl ( audio_fd, SNDCTL_DSP_GETOPTR, &count ) == -1 ) {
Com_EPrintf ( "SNDCTL_DSP_GETOPTR failed on %s: %s\n",
snddevice->string, strerror ( errno ) );
- munmap ( dma.buffer, info.fragstotal * info.fragsize );
- close ( audio_fd );
- snd_inited = qfalse;
- return 0;
+ OSS_Shutdown();
+ return;
}
dma.samplepos = count.ptr / ( dma.samplebits >> 3 );
-
- return dma.samplepos;
}
-static void OSS_Shutdown ( void ) {
- if ( snd_inited ) {
- Com_Printf ( "Shutting down OSS\n" );
- munmap ( dma.buffer, info.fragstotal * info.fragsize );
- close ( audio_fd );
- snd_inited = qfalse;
- }
+static void OSS_Submit ( void ) {
}
-static void OSS_Submit ( void ) {}
-
-static void OSS_BeginPainting ( void ) {}
-
-static void OSS_Activate ( qboolean active ) {}
+static void OSS_Activate ( qboolean active ) {
+}
void OSS_FillAPI ( snddmaAPI_t *api ) {
api->Init = OSS_Init;
- api->GetDMAPos = OSS_GetDMAPos;
api->Shutdown = OSS_Shutdown;
api->BeginPainting = OSS_BeginPainting;
api->Submit = OSS_Submit;
diff --git a/source/snd_sdl.c b/source/snd_sdl.c
new file mode 100644
index 0000000..f727718
--- /dev/null
+++ b/source/snd_sdl.c
@@ -0,0 +1,147 @@
+/*
+Copyright (C) 2003-2007 Andrey Nazarov
+
+This program 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.
+
+This program 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 this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+//
+// snd_sdl.c
+//
+
+#include "com_local.h"
+#include "snd_local.h"
+#include <SDL.h>
+
+static void filler( void *userdata, Uint8 *stream, int len ) {
+ int size = dma.samples << 1;
+ int pos = dma.samplepos << 1;
+ int wrapped = pos + len - size;
+
+ if( wrapped < 0 ) {
+ memcpy( stream, dma.buffer + pos, len );
+ dma.samplepos += len >> 1;
+ } else {
+ int remaining = size - pos;
+ memcpy( stream, dma.buffer + pos, remaining );
+ memcpy( stream + remaining, dma.buffer, wrapped );
+ dma.samplepos = wrapped >> 1;
+ }
+}
+
+static void QSDL_ShutdownSound( void ) {
+ Com_Printf( "Shutting down SDL audio\n" );
+
+ SDL_CloseAudio();
+ if( SDL_WasInit( SDL_INIT_EVERYTHING ) == SDL_INIT_AUDIO ) {
+ SDL_Quit();
+ } else {
+ SDL_QuitSubSystem( SDL_INIT_AUDIO );
+ }
+
+ if( dma.buffer ) {
+ Z_Free( dma.buffer );
+ dma.buffer = NULL;
+ }
+}
+
+static sndinitstat_t QSDL_InitSound( void ) {
+ SDL_AudioSpec desired, obtained;
+ char buffer[MAX_QPATH];
+ int ret;
+
+ if( SDL_WasInit( SDL_INIT_EVERYTHING ) == 0 ) {
+ ret = SDL_Init( SDL_INIT_AUDIO|SDL_INIT_NOPARACHUTE );
+ } else {
+ ret = SDL_InitSubSystem( SDL_INIT_AUDIO );
+ }
+ if( ret == -1 ) {
+ Com_EPrintf( "Couldn't initialize SDL audio: %s\n", SDL_GetError() );
+ return SIS_FAILURE;
+ }
+
+ memset( &desired, 0, sizeof( desired ) );
+ switch( s_khz->integer ) {
+ case 48:
+ desired.freq = 48000;
+ break;
+ case 44:
+ desired.freq = 44100;
+ break;
+ case 22:
+ desired.freq = 22050;
+ break;
+ default:
+ desired.freq = 11025;
+ break;
+ }
+
+ desired.format = AUDIO_S16LSB;
+ desired.samples = 512;
+ desired.channels = 2;
+ desired.callback = filler;
+ ret = SDL_OpenAudio( &desired, &obtained );
+ if( ret == -1 ) {
+ Com_EPrintf( "Couldn't open SDL audio: %s\n", SDL_GetError() );
+ return SIS_FAILURE;
+ }
+
+ if( obtained.format != AUDIO_S16LSB ) {
+ Com_EPrintf( "SDL audio format %d unsupported\n", obtained.format );
+ QSDL_ShutdownSound();
+ return SIS_FAILURE;
+ }
+
+ dma.speed = obtained.freq;
+ dma.channels = obtained.channels;
+ dma.samples = 2048 * obtained.channels;
+ dma.submission_chunk = 1;
+ dma.samplebits = 16;
+ dma.buffer = Z_Malloc( dma.samples * 2 );
+ dma.samplepos = 0;
+
+ Com_Printf( "Using SDL audio driver: %s\n",
+ SDL_AudioDriverName( buffer, sizeof( buffer ) ) );
+
+ SDL_PauseAudio( 0 );
+
+ return SIS_SUCCESS;
+}
+
+static void QSDL_BeginPainting( void ) {
+ SDL_LockAudio();
+}
+
+static void QSDL_Submit( void ) {
+ SDL_UnlockAudio();
+}
+
+static void QSDL_ActivateSound( qboolean active ) {
+ if( active ) {
+ SDL_PauseAudio( 0 );
+ } else {
+ SDL_PauseAudio( 1 );
+ }
+}
+
+void QSDL_FillSoundAPI ( snddmaAPI_t *api ) {
+ api->Init = QSDL_InitSound;
+ api->Shutdown = QSDL_ShutdownSound;
+ api->BeginPainting = QSDL_BeginPainting;
+ api->Submit = QSDL_Submit;
+ api->Activate = QSDL_ActivateSound;
+}
+
diff --git a/source/snd_wave.c b/source/snd_wave.c
index eadd895..f036b83 100644
--- a/source/snd_wave.c
+++ b/source/snd_wave.c
@@ -98,7 +98,7 @@ WAVE_Init
Crappy windows multimedia base
==================
*/
-static sndinitstat WAVE_Init (void) {
+static sndinitstat_t WAVE_Init (void) {
WAVEFORMATEX format;
int i;
HRESULT hr;
@@ -237,39 +237,26 @@ static sndinitstat WAVE_Init (void) {
return SIS_SUCCESS;
}
-
/*
==============
-WAVE_GetDMAPos
+WAVE_BeginPainting
-return the current sample position (in mono samples read)
+Makes sure dma.buffer is valid.
+
+Returns the current sample position (in mono samples read)
inside the recirculating dma buffer, so the mixing code will know
how many sample are required to fill it up.
===============
*/
-static int WAVE_GetDMAPos(void) {
+static void WAVE_BeginPainting (void) {
int s;
if( !wav_init ) {
- return 0;
+ return;
}
- s = snd_sent * WAV_BUFFER_SIZE;
-
- s >>= sample16;
- s &= (dma.samples-1);
-
- return s;
-}
-
-/*
-==============
-WAVE_BeginPainting
-
-Makes sure dma.buffer is valid
-===============
-*/
-static void WAVE_BeginPainting (void) {
+ s = ( snd_sent * WAV_BUFFER_SIZE ) >> sample16;
+ dma.samplepos = s & ( dma.samples - 1 );
}
/*
@@ -344,7 +331,6 @@ static void WAVE_Activate (qboolean active) {
void WAVE_FillAPI( snddmaAPI_t *api ) {
api->Init = WAVE_Init;
- api->GetDMAPos = WAVE_GetDMAPos;
api->Shutdown = WAVE_Shutdown;
api->BeginPainting = WAVE_BeginPainting;
api->Submit = WAVE_Submit;
diff --git a/source/sv_game.c b/source/sv_game.c
index e7a6896..f25fb7c 100644
--- a/source/sv_game.c
+++ b/source/sv_game.c
@@ -714,7 +714,7 @@ static cvar_t *PF_cvar( const char *name, const char *value, int flags ) {
flags &= ~CVAR_EXTENDED_MASK;
}
- var = Cvar_Get( name, value, flags );
+ var = Cvar_Get( name, value, flags | CVAR_GAME );
if( !var->subsystem ) {
var->subsystem = CVAR_SYSTEM_GAME;
}