diff --git a/common/com_model.h b/common/com_model.h index 894d0aac..1ea3e5c5 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -385,6 +385,9 @@ typedef struct player_info_s vec3_t prevgaitorigin; customization_t customdata; + + // hashed cd key + char hashedcdkey[16]; } player_info_t; // diff --git a/common/wadfile.rar b/common/wadfile.rar new file mode 100644 index 00000000..d372bf56 Binary files /dev/null and b/common/wadfile.rar differ diff --git a/engine/client/cl_cmds.c b/engine/client/cl_cmds.c index 2bb9c7b0..765bebf1 100644 --- a/engine/client/cl_cmds.c +++ b/engine/client/cl_cmds.c @@ -62,6 +62,7 @@ Emulate audio-cd system void CL_PlayCDTrack_f( void ) { const char *command; + const char *pszTrack; static int track = 0; static qboolean paused = false; static qboolean looped = false; @@ -69,21 +70,30 @@ void CL_PlayCDTrack_f( void ) if( Cmd_Argc() < 2 ) return; command = Cmd_Argv( 1 ); + pszTrack = Cmd_Argv( 2 ); if( !enabled && Q_stricmp( command, "on" )) return; // CD-player is disabled if( !Q_stricmp( command, "play" )) { - track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS ); - S_StartBackgroundTrack( clgame.cdtracks[track-1], NULL, 0 ); + if( Q_isdigit( pszTrack )) + { + track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS ); + S_StartBackgroundTrack( clgame.cdtracks[track-1], NULL, 0 ); + } + else S_StartBackgroundTrack( pszTrack, NULL, 0 ); paused = false; looped = false; } else if( !Q_stricmp( command, "loop" )) { - track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS ); - S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0 ); + if( Q_isdigit( pszTrack )) + { + track = bound( 1, Q_atoi( Cmd_Argv( 2 )), MAX_CDTRACKS ); + S_StartBackgroundTrack( clgame.cdtracks[track-1], clgame.cdtracks[track-1], 0 ); + } + else S_StartBackgroundTrack( pszTrack, pszTrack, 0 ); paused = false; looped = true; } diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 80ea87fe..ff9a72d3 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -30,8 +30,16 @@ GNU General Public License for more details. #define DEMO_STARTUP 0 // this lump contains startup info needed to spawn into the server #define DEMO_NORMAL 1 // this lump contains playback info of messages, etc., needed during playback. +// Demo flags +#define FDEMO_TITLE 0x01 // Show title +#define FDEMO_PLAY 0x04 // Playing cd track +#define FDEMO_FADE_IN_SLOW 0x08 // Fade in (slow) +#define FDEMO_FADE_IN_FAST 0x10 // Fade in (fast) +#define FDEMO_FADE_OUT_SLOW 0x20 // Fade out (slow) +#define FDEMO_FADE_OUT_FAST 0x40 // Fade out (fast) + #define IDEMOHEADER (('M'<<24)+('E'<<16)+('D'<<8)+'I') // little-endian "IDEM" -#define DEMO_PROTOCOL 2 +#define DEMO_PROTOCOL 3 const char *demo_cmd[dem_lastcmd+1] = { @@ -63,6 +71,8 @@ typedef struct int playback_frames; // # of frames in track int offset; // file offset of track data int length; // length of track + int flags; // FX-flags + char description[64]; // entry description } demoentry_t; typedef struct @@ -171,6 +181,8 @@ overwrite host.frametime */ double CL_GetDemoFramerate( void ) { + if( cls.timedemo ) + return 0.0; return bound( MIN_FPS, demo.header.host_fps, MAX_FPS ); } @@ -185,7 +197,7 @@ void CL_WriteDemoCmdHeader( byte cmd, file_t *file ) { float dt; - ASSERT( cmd >= 1 && cmd <= dem_lastcmd ); + Assert( cmd >= 1 && cmd <= dem_lastcmd ); if( !file ) return; // command @@ -256,7 +268,7 @@ so that we can play the demo correctly. */ void CL_WriteDemoSequence( file_t *file ) { - ASSERT( file ); + Assert( file ); FS_Write( file, &cls.netchan.incoming_sequence, sizeof( int )); FS_Write( file, &cls.netchan.incoming_acknowledged, sizeof( int )); @@ -392,6 +404,8 @@ void CL_WriteDemoHeader( const char *name ) demo.starttime = CL_GetDemoRecordClock(); // setup the demo starttime demo.realstarttime = demo.starttime; demo.framecount = 0; + cls.td_startframe = host.framecount; + cls.td_lastframe = -1; // get a new message this frame // now move on to entry # 1, the first data chunk. curpos = FS_Tell( cls.demofile ); @@ -425,6 +439,7 @@ void CL_StopRecord( void ) { int i, curpos; float stoptime; + int frames; if( !cls.demorecording ) return; @@ -459,11 +474,14 @@ void CL_StopRecord( void ) cls.demofile = NULL; cls.demorecording = false; cls.demoname[0] = '\0'; + cls.td_lastframe = host.framecount; gameui.globals->demoname[0] = '\0'; demo.header.host_fps = 0.0; + frames = cls.td_lastframe - cls.td_startframe; + Msg( "Completed demo\n" ); - MsgDev( D_INFO, "Recording time: %02d:%02d\n", (int)(cls.demotime / 60.0f ), (int)fmod( cls.demotime, 60.0f )); + MsgDev( D_INFO, "Recording time: %02d:%02d, frames %i\n", (int)(cls.demotime / 60.0f ), (int)fmod( cls.demotime, 60.0f ), frames ); cls.demotime = 0.0; } @@ -508,7 +526,7 @@ void CL_ReadDemoCmdHeader( byte *cmd, float *dt ) { // read the command FS_Read( cls.demofile, cmd, sizeof( byte )); - ASSERT( *cmd >= 1 && *cmd <= dem_lastcmd ); + Assert( *cmd >= 1 && *cmd <= dem_lastcmd ); // read the timestamp FS_Read( cls.demofile, dt, sizeof( float )); @@ -624,6 +642,7 @@ void CL_DemoAborted( void ) FS_Close( cls.demofile ); cls.demoplayback = false; cls.changedemo = false; + cls.timedemo = false; demo.framecount = 0; cls.demofile = NULL; cls.demonum = -1; @@ -683,8 +702,8 @@ qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length ) { int msglen = 0; - ASSERT( buffer != NULL ); - ASSERT( length != NULL ); + Assert( buffer != NULL ); + Assert( length != NULL ); *length = 0; // assume we fail FS_Read( cls.demofile, &msglen, sizeof( int )); @@ -730,12 +749,13 @@ reads demo data and write it to client */ qboolean CL_DemoReadMessage( byte *buffer, size_t *length ) { - size_t curpos = 0, lastpos = 0; - float fElapsedTime = 0.0f; - qboolean swallowmessages = true; - byte *userbuf = NULL; - size_t size; - byte cmd; + size_t curpos = 0, lastpos = 0; + float fElapsedTime = 0.0f; + qboolean swallowmessages = true; + static int tdlastdemoframe = 0; + byte *userbuf = NULL; + size_t size; + byte cmd; if( !cls.demofile ) { @@ -763,7 +783,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length ) CL_ReadDemoCmdHeader( &cmd, &demo.timestamp ); fElapsedTime = CL_GetDemoPlaybackClock() - demo.starttime; - bSkipMessage = ((demo.timestamp - cl_serverframetime()) >= fElapsedTime) ? true : false; + if( !cls.timedemo ) bSkipMessage = ((demo.timestamp - cl_serverframetime()) >= fElapsedTime) ? true : false; if( cls.changelevel ) demo.framecount = 1; // changelevel issues @@ -818,6 +838,16 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length ) } } while( swallowmessages ); + // If we are playing back a timedemo, and we've already passed on a + // frame update for this host_frame tag, then we'll just skip this message. + if( cls.timedemo && ( tdlastdemoframe == host.framecount )) + { + FS_Seek( cls.demofile, FS_Tell ( cls.demofile ) - 5, SEEK_SET ); + return false; + } + + tdlastdemoframe = host.framecount; + if( !cls.demofile ) return false; @@ -826,7 +856,7 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length ) { // We are now on the second frame of a new section, // if so, reset start time (unless in a timedemo) - if( demo.framecount == 1 ) + if( demo.framecount == 1 && !cls.timedemo ) { // cheat by moving the relative start time forward. demo.starttime = CL_GetDemoPlaybackClock(); @@ -844,6 +874,8 @@ void CL_DemoFindInterpolatedViewAngles( float t, float *frac, demoangle_t **prev int i, i0, i1, imod; float at; + if( cls.timedemo ) return; + imod = demo.angle_position - 1; i0 = (imod + 1) & ANGLE_MASK; i1 = (imod + 0) & ANGLE_MASK; @@ -912,6 +944,28 @@ void CL_DemoInterpolateAngles( void ) else VectorCopy( cl.cmd->viewangles, cl.viewangles ); } +/* +============== +CL_FinishTimeDemo + +show stats +============== +*/ +void CL_FinishTimeDemo( void ) +{ + int frames; + double time; + + cls.timedemo = false; + + // the first frame didn't count + frames = (host.framecount - cls.td_startframe) - 1; + time = host.realtime - cls.td_starttime; + if( !time ) time = 1.0; + + Msg( "%i frames %5.3f seconds %5.3f fps\n", frames, time, frames / time ); +} + /* ============== CL_StopPlayback @@ -931,6 +985,7 @@ void CL_StopPlayback( void ) cls.olddemonum = Q_max( -1, cls.demonum - 1 ); Mem_Free( demo.directory.entries ); + cls.td_lastframe = host.framecount; demo.directory.numentries = 0; demo.directory.entries = NULL; demo.header.host_fps = 0.0; @@ -939,6 +994,9 @@ void CL_StopPlayback( void ) cls.demoname[0] = '\0'; // clear demoname too gameui.globals->demoname[0] = '\0'; + if( cls.timedemo ) + CL_FinishTimeDemo(); + if( cls.changedemo ) { S_StopAllSounds( true ); @@ -949,6 +1007,7 @@ void CL_StopPlayback( void ) // let game known about demo state Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY ); cls.state = ca_disconnected; + S_StopBackgroundTrack(); cls.connect_time = 0; cls.demonum = -1; cls.signon = 0; @@ -1298,6 +1357,31 @@ void CL_PlayDemo_f( void ) // begin a playback demo } +/* +==================== +CL_TimeDemo_f + +timedemo +==================== +*/ +void CL_TimeDemo_f( void ) +{ + if( Cmd_Argc() != 2 ) + { + Msg( "Usage: timedemo \n" ); + return; + } + + CL_PlayDemo_f (); + + // cls.td_starttime will be grabbed at the second frame of the demo, so + // all the loading time doesn't get counted + cls.timedemo = true; + cls.td_starttime = host.realtime; + cls.td_startframe = host.framecount; + cls.td_lastframe = -1; // get a new message this frame +} + /* ================== CL_StartDemos_f diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index b7d7ab86..f3864725 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -767,7 +767,7 @@ cl_entity_t *CL_GetLocalPlayer( void ) cl_entity_t *player; player = CL_EDICT_NUM( cl.playernum + 1 ); - ASSERT( player != NULL ); + Assert( player != NULL ); return player; } @@ -1057,7 +1057,7 @@ void CL_LinkUserMessage( char *pszName, const int svc_num, int iSize ) void CL_FreeEntity( cl_entity_t *pEdict ) { - ASSERT( pEdict ); + Assert( pEdict ); R_RemoveEfrags( pEdict ); CL_KillDeadBeams( pEdict ); } @@ -1077,7 +1077,7 @@ void CL_ClearWorld( void ) void CL_InitEdicts( void ) { - ASSERT( clgame.entities == NULL ); + Assert( clgame.entities == NULL ); if( !clgame.mempool ) return; // Host_Error without client @@ -1150,7 +1150,7 @@ static qboolean CL_LoadHudSprite( const char *szSpriteName, model_t *m_pSprite, size_t size; qboolean loaded; - ASSERT( m_pSprite != NULL ); + Assert( m_pSprite != NULL ); buf = FS_LoadFile( szSpriteName, &size, false ); if( !buf ) return false; @@ -3111,7 +3111,7 @@ void NetAPI_Status( net_status_t *status ) qboolean connected = false; int packet_loss = 0; - ASSERT( status != NULL ); + Assert( status != NULL ); if( cls.state > ca_disconnected && cls.state != ca_cinematic ) connected = true; @@ -3171,7 +3171,7 @@ void NetAPI_SendRequest( int context, int request, int flags, double timeout, ne } } - ASSERT( nr != NULL ); + Assert( nr != NULL ); // clear slot memset( nr, 0, sizeof( *nr )); diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index f421170e..8cf9f9cf 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -112,6 +112,11 @@ qboolean CL_IsRecordDemo( void ) return cls.demorecording; } +qboolean CL_IsTimeDemo( void ) +{ + return cls.timedemo; +} + qboolean CL_DisableVisibility( void ) { return cls.envshot_disable_vis; @@ -664,8 +669,8 @@ void CL_WriteUsercmd( sizebuf_t *msg, int from, int to ) usercmd_t nullcmd; usercmd_t *f, *t; - ASSERT( from == -1 || ( from >= 0 && from < MULTIPLAYER_BACKUP )); - ASSERT( to >= 0 && to < MULTIPLAYER_BACKUP ); + Assert( from == -1 || ( from >= 0 && from < MULTIPLAYER_BACKUP )); + Assert( to >= 0 && to < MULTIPLAYER_BACKUP ); if( from == -1 ) { @@ -2257,6 +2262,7 @@ void CL_InitLocal( void ) Cmd_AddCommand ("localservers", CL_LocalServers_f, "collect info about local servers" ); Cmd_AddCommand ("internetservers", CL_InternetServers_f, "collect info about internet servers" ); Cmd_AddCommand ("cd", CL_PlayCDTrack_f, "Play cd-track (not real cd-player of course)" ); + Cmd_AddCommand ("mp3", CL_PlayCDTrack_f, "Play mp3-track (based on virtual cd-player)" ); Cmd_AddCommand ("setinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of userinfo)" ); Cmd_AddCommand ("userinfo", CL_SetInfo_f, "examine or change the userinfo string (alias of setinfo)" ); @@ -2264,6 +2270,7 @@ void CL_InitLocal( void ) Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" ); Cmd_AddCommand ("record", CL_Record_f, "record a demo" ); Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "play a demo" ); + Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "demo benchmark" ); Cmd_AddCommand ("killdemo", CL_DeleteDemo_f, "delete a specified demo file and demoshot" ); Cmd_AddCommand ("startdemos", CL_StartDemos_f, "start playing back the selected demos sequentially" ); Cmd_AddCommand ("demos", CL_Demos_f, "restart looping demos defined by the last startdemos command" ); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 128d6cb8..3f2c136d 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1491,6 +1491,56 @@ void CL_ParseScreenFade( sizebuf_t *msg ) } } +/* +============== +CL_ParseCvarValue + +Find the client cvar value +and sent it back to the server +============== +*/ +void CL_ParseCvarValue( sizebuf_t *msg ) +{ + const char *cvarName = MSG_ReadString( msg ); + convar_t *cvar = Cvar_FindVar( cvarName ); + + // build the answer + MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue ); + MSG_WriteString( &cls.netchan.message, cvar ? cvar->string : "Not Found" ); +} + +/* +============== +CL_ParseCvarValue2 + +Find the client cvar value +and sent it back to the server +============== +*/ +void CL_ParseCvarValue2( sizebuf_t *msg ) +{ + int requestID = MSG_ReadLong( msg ); + const char *cvarName = MSG_ReadString( msg ); + convar_t *cvar = Cvar_FindVar( cvarName ); + + // build the answer + MSG_BeginClientCmd( &cls.netchan.message, clc_requestcvarvalue2 ); + MSG_WriteLong( &cls.netchan.message, requestID ); + MSG_WriteString( &cls.netchan.message, cvarName ); + + if( cvar ) + { + // cheater can change value ignoring Cvar_Set so we responce incorrect value + if( cvar->value != Q_atof( cvar->string )) + MSG_WriteString( &cls.netchan.message, va( "%s (%g)", cvar->string, cvar->value )); + else MSG_WriteString( &cls.netchan.message, cvar->string ); + } + else + { + MSG_WriteString( &cls.netchan.message, "Not Found" ); + } +} + /* ============== CL_DispatchUserMessage @@ -1867,6 +1917,12 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message ) case svc_studiodecal: CL_ParseStudioDecal( msg ); break; + case svc_querycvarvalue: + CL_ParseCvarValue( msg ); + break; + case svc_querycvarvalue2: + CL_ParseCvarValue2( msg ); + break; default: CL_ParseUserMessage( msg, cmd ); cl.frames[cl.parsecountmod].graphdata.usr += MSG_GetNumBytesRead( msg ) - bufStart; diff --git a/engine/client/cl_pmove.c b/engine/client/cl_pmove.c index 92489fd1..ed4de21a 100644 --- a/engine/client/cl_pmove.c +++ b/engine/client/cl_pmove.c @@ -313,7 +313,7 @@ void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient ) void CL_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr ) { - ASSERT( tr != NULL ); + Assert( tr != NULL ); if( clgame.dllFuncs.pfnClipMoveToEntity != NULL ) { diff --git a/engine/client/cl_remap.c b/engine/client/cl_remap.c index 43ef5344..c3d4f3e8 100644 --- a/engine/client/cl_remap.c +++ b/engine/client/cl_remap.c @@ -71,7 +71,7 @@ byte *CL_CreateRawTextureFromPixels( texture_t *tx, size_t *size, int topcolor, static mstudiotexture_t pin; byte *pal; - ASSERT( size != NULL ); + Assert( size != NULL ); *size = sizeof( pin ) + (tx->width * tx->height) + 768; @@ -119,7 +119,7 @@ void CL_DuplicateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomco break; // found } - ASSERT( tx != NULL ); + Assert( tx != NULL ); // backup original palette pal = (byte *)(tx + 1) + (tx->width * tx->height); @@ -169,7 +169,7 @@ void CL_UpdateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor break; // found } - ASSERT( tx != NULL ); + Assert( tx != NULL ); // backup original palette pal = (byte *)(tx + 1) + (tx->width * tx->height); @@ -189,7 +189,7 @@ void CL_UpdateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor // restore original palette memcpy( pal, paletteBackup, 768 ); - ASSERT( index == ptexture->index ); + Assert( index == ptexture->index ); } /* @@ -317,7 +317,7 @@ void CL_FreeRemapInfo( remap_info_t *info ) { int i; - ASSERT( info != NULL ); + Assert( info != NULL ); // release all colormap texture copies for( i = 0; i < info->numtextures; i++ ) diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 8f4d2a6b..34d14330 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -292,7 +292,7 @@ void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp ) qboolean isshellcasing = false; int zvel; - ASSERT( pTemp != NULL ); + Assert( pTemp != NULL ); fvol = 0.8f; @@ -373,7 +373,7 @@ int CL_TempEntAddEntity( cl_entity_t *pEntity ) { vec3_t mins, maxs; - ASSERT( pEntity != NULL ); + Assert( pEntity != NULL ); if( !pEntity->model ) return 0; @@ -2412,8 +2412,8 @@ void CL_SetLightstyle( int style, const char *s, float f ) lightstyle_t *ls; float val1, val2; - ASSERT( s ); - ASSERT( style >= 0 && style < MAX_LIGHTSTYLES ); + Assert( s ); + Assert( style >= 0 && style < MAX_LIGHTSTYLES ); ls = &cl.lightstyles[style]; diff --git a/engine/client/client.h b/engine/client/client.h index 93721eb9..402a9609 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -37,7 +37,7 @@ GNU General Public License for more details. #define MAX_MOVIES 8 #define MAX_CDTRACKS 32 #define MAX_IMAGES 256 // SpriteTextures -#define MAX_EFRAGS 8192 +#define MAX_EFRAGS 8192 // Arcane Dimensions required #define MAX_REQUESTS 64 // screenshot types @@ -50,7 +50,7 @@ GNU General Public License for more details. // client sprite types #define SPR_CLIENT 0 // client sprite for temp-entities or user-textures #define SPR_HUDSPRITE 1 // hud sprite -#define SPR_MAPSPRITE 2 // contain overview subdivided into frames 128x128 +#define SPR_MAPSPRITE 2 // contain overview.bmp that diced into frames 128x128 typedef int sound_t; @@ -164,8 +164,8 @@ typedef struct model_t *model; } player_model_t; -// the client_t structure is wiped completely at every -// server map change +// the client_t structure is wiped completely +// at every server map change typedef struct { int timeoutcount; @@ -244,8 +244,8 @@ typedef struct char event_precache[MAX_EVENTS][MAX_QPATH]; lightstyle_t lightstyles[MAX_LIGHTSTYLES]; - short sound_index[MAX_SOUNDS]; - short decal_index[MAX_DECALS]; + short sound_index[MAX_SOUNDS]; + short decal_index[MAX_DECALS]; cl_entity_t *world; model_t *worldmodel; // pointer to world @@ -552,6 +552,10 @@ typedef struct int lastoutgoingcommand; // sequence number of last outgoing command int lastupdate_sequence; // prediction stuff + int td_lastframe; // to meter out one message a frame + int td_startframe; // host_framecount at start + double td_starttime; // realtime at second frame of timedemo + // game images int pauseIcon; // draw 'paused' when game in-pause int tileImage; // for draw any areas not covered by the refresh @@ -708,6 +712,7 @@ void CL_CloseDemoHeader( void ); void CL_StopPlayback( void ); void CL_StopRecord( void ); void CL_PlayDemo_f( void ); +void CL_TimeDemo_f( void ); void CL_StartDemos_f( void ); void CL_Demos_f( void ); void CL_DeleteDemo_f( void ); diff --git a/engine/client/gl_alias.c b/engine/client/gl_alias.c index d7ab44b5..c2de19fc 100644 --- a/engine/client/gl_alias.c +++ b/engine/client/gl_alias.c @@ -719,7 +719,7 @@ void Mod_UnloadAliasModel( model_t *mod ) aliashdr_t *palias; int i, j; - ASSERT( mod != NULL ); + Assert( mod != NULL ); if( mod->type != mod_alias ) return; // not an alias diff --git a/engine/client/gl_backend.c b/engine/client/gl_backend.c index 47d03fd5..7e8714ea 100644 --- a/engine/client/gl_backend.c +++ b/engine/client/gl_backend.c @@ -109,7 +109,7 @@ GL_LoadTexMatrixExt */ void GL_LoadTexMatrixExt( const float *glmatrix ) { - ASSERT( glmatrix != NULL ); + Assert( glmatrix != NULL ); pglMatrixMode( GL_TEXTURE ); pglLoadMatrixf( glmatrix ); glState.texIdentityMatrix[glState.activeTMU] = false; diff --git a/engine/client/gl_beams.c b/engine/client/gl_beams.c index 5f82a963..101e31c9 100644 --- a/engine/client/gl_beams.c +++ b/engine/client/gl_beams.c @@ -469,7 +469,7 @@ static void R_DrawSegs( vec3_t source, vec3_t delta, float width, float scale, f beamseg_t nextSeg; vec3_t vPoint1, vPoint2; - ASSERT( noiseIndex < ( NOISE_DIVISIONS << 16 )); + Assert( noiseIndex < ( NOISE_DIVISIONS << 16 )); fraction = i * div; @@ -1468,7 +1468,7 @@ Check for expired beams */ qboolean CL_BeamAttemptToDie( BEAM *pBeam ) { - ASSERT( pBeam != NULL ); + Assert( pBeam != NULL ); // premanent beams never die automatically if( FBitSet( pBeam->flags, FBEAM_FOREVER )) diff --git a/engine/client/gl_decals.c b/engine/client/gl_decals.c index 4cf943ec..196f1188 100644 --- a/engine/client/gl_decals.c +++ b/engine/client/gl_decals.c @@ -693,7 +693,7 @@ static void R_DecalNode( model_t *model, mnode_t *node, decalinfo_t *decalinfo ) mplane_t *splitplane; float dist; - ASSERT( node ); + Assert( node ); if( node->contents < 0 ) { @@ -888,7 +888,7 @@ void DrawSurfaceDecals( msurface_t *fa, qboolean single, qboolean reverse ) if( !fa->pdecals ) return; e = RI.currententity; - ASSERT( e != NULL ); + Assert( e != NULL ); if( single ) { @@ -1027,7 +1027,7 @@ void DrawDecalsBatch( void ) return; e = RI.currententity; - ASSERT( e != NULL ); + Assert( e != NULL ); if( e->curstate.rendermode != kRenderTransTexture ) { diff --git a/engine/client/gl_frustum.c b/engine/client/gl_frustum.c index 595da913..d7586e8a 100644 --- a/engine/client/gl_frustum.c +++ b/engine/client/gl_frustum.c @@ -19,7 +19,7 @@ GNU General Public License for more details. void GL_FrustumEnablePlane( gl_frustum_t *out, int side ) { - ASSERT( side >= 0 && side < FRUSTUM_PLANES ); + Assert( side >= 0 && side < FRUSTUM_PLANES ); // make sure what plane is ready if( !VectorIsNull( out->planes[side].normal )) @@ -28,13 +28,13 @@ void GL_FrustumEnablePlane( gl_frustum_t *out, int side ) void GL_FrustumDisablePlane( gl_frustum_t *out, int side ) { - ASSERT( side >= 0 && side < FRUSTUM_PLANES ); + Assert( side >= 0 && side < FRUSTUM_PLANES ); ClearBits( out->clipFlags, BIT( side )); } void GL_FrustumSetPlane( gl_frustum_t *out, int side, const vec3_t vecNormal, float flDist ) { - ASSERT( side >= 0 && side < FRUSTUM_PLANES ); + Assert( side >= 0 && side < FRUSTUM_PLANES ); out->planes[side].type = PlaneTypeForNormal( vecNormal ); out->planes[side].signbits = SignbitsForPlane( vecNormal ); @@ -48,7 +48,7 @@ void GL_FrustumNormalizePlane( gl_frustum_t *out, int side ) { float length; - ASSERT( side >= 0 && side < FRUSTUM_PLANES ); + Assert( side >= 0 && side < FRUSTUM_PLANES ); // normalize length = VectorLength( out->planes[side].normal ); diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index 3ac94cb4..9705a1c6 100644 --- a/engine/client/gl_image.c +++ b/engine/client/gl_image.c @@ -80,7 +80,7 @@ void GL_Bind( GLint tmu, GLenum texnum ) // missed texture ? if( texnum <= 0 ) texnum = tr.defaultTexture; - ASSERT( texnum > 0 && texnum < MAX_TEXTURES ); + Assert( texnum > 0 && texnum < MAX_TEXTURES ); if( tmu != GL_KEEP_UNIT ) GL_SelectTexture( tmu ); @@ -116,7 +116,7 @@ void GL_ApplyTextureParams( gltexture_t *tex ) { vec4_t border = { 0.0f, 0.0f, 0.0f, 1.0f }; - ASSERT( tex != NULL ); + Assert( tex != NULL ); // set texture filter if( FBitSet( tex->flags, TF_DEPTHMAP )) @@ -249,7 +249,7 @@ static void GL_UpdateTextureParams( int iTexture ) { gltexture_t *tex = &r_textures[iTexture]; - ASSERT( tex != NULL ); + Assert( tex != NULL ); if( !tex->texnum ) return; // free slot @@ -470,7 +470,7 @@ static int GL_CalcMipmapCount( gltexture_t *tex, qboolean haveBuffer ) int width, height; int mipcount; - ASSERT( tex != NULL ); + Assert( tex != NULL ); if( !haveBuffer || tex->target == GL_TEXTURE_3D ) return 1; @@ -501,7 +501,7 @@ static void GL_SetTextureDimensions( gltexture_t *tex, int width, int height, in int maxTextureSize; int maxDepthSize = 1; - ASSERT( tex != NULL ); + Assert( tex != NULL ); switch( tex->target ) { @@ -574,8 +574,8 @@ GL_SetTextureTarget */ static void GL_SetTextureTarget( gltexture_t *tex, rgbdata_t *pic ) { - ASSERT( pic != NULL ); - ASSERT( tex != NULL ); + Assert( pic != NULL ); + Assert( tex != NULL ); // correct depth size pic->depth = Q_max( 1, pic->depth ); @@ -628,7 +628,7 @@ static void GL_SetTextureFormat( gltexture_t *tex, pixformat_t format, int chann qboolean haveColor = ( channelMask & IMAGE_HAS_COLOR ); qboolean haveAlpha = ( channelMask & IMAGE_HAS_ALPHA ); - ASSERT( tex != NULL ); + Assert( tex != NULL ); if( ImageDXT( format )) { @@ -1016,7 +1016,7 @@ static void GL_TextureImageRAW( gltexture_t *tex, GLint side, GLint level, GLint GLenum inFormat = PFDesc[type].glFormat; GLint dataType = GL_UNSIGNED_BYTE; - ASSERT( tex != NULL ); + Assert( tex != NULL ); if( tex->flags & TF_DEPTHMAP ) inFormat = GL_DEPTH_COMPONENT; @@ -1048,7 +1048,7 @@ static void GL_TextureImageDXT( gltexture_t *tex, GLint side, GLint level, GLint GLuint cubeTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; qboolean subImage = ( tex->flags & TF_IMG_UPLOADED ); - ASSERT( tex != NULL ); + Assert( tex != NULL ); if( tex->target == GL_TEXTURE_1D ) { @@ -1083,7 +1083,7 @@ static void GL_CheckTexImageError( gltexture_t *tex ) { int err; - ASSERT( tex != NULL ); + Assert( tex != NULL ); // catch possible errors if(( err = pglGetError()) != GL_NO_ERROR ) @@ -1107,8 +1107,8 @@ static qboolean GL_UploadTexture( gltexture_t *tex, rgbdata_t *pic ) qboolean normalMap; const byte *bufend; - ASSERT( pic != NULL ); - ASSERT( tex != NULL ); + Assert( pic != NULL ); + Assert( tex != NULL ); GL_SetTextureTarget( tex, pic ); // must be first @@ -1729,7 +1729,7 @@ void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor ) int flags = 0; if( texnum <= 0 ) return; // missed image - ASSERT( texnum > 0 && texnum < MAX_TEXTURES ); + Assert( texnum > 0 && texnum < MAX_TEXTURES ); image = &r_textures[texnum]; // select mode @@ -1845,7 +1845,7 @@ void GL_FreeTexture( GLenum texnum ) if( texnum <= 0 || !glw_state.initialized ) return; - ASSERT( texnum > 0 && texnum < MAX_TEXTURES ); + Assert( texnum > 0 && texnum < MAX_TEXTURES ); R_FreeImage( &r_textures[texnum] ); } @@ -1860,7 +1860,7 @@ void R_FreeImage( gltexture_t *image ) gltexture_t *cur; gltexture_t **prev; - ASSERT( image != NULL ); + Assert( image != NULL ); if( !image->name[0] ) { diff --git a/engine/client/gl_rmain.c b/engine/client/gl_rmain.c index 1ffafb79..6f85e607 100644 --- a/engine/client/gl_rmain.c +++ b/engine/client/gl_rmain.c @@ -559,7 +559,7 @@ static gltexture_t *R_RecursiveFindWaterTexture( const mnode_t *node, const mnod // assure the initial node is not null // we could check it here, but we would rather check it // outside the call to get rid of one additional recursion level - ASSERT( node != NULL ); + Assert( node != NULL ); // ignore solid nodes if( node->contents == CONTENTS_SOLID ) @@ -757,8 +757,8 @@ void R_DrawEntitiesOnList( void ) RI.currententity = tr.solid_entities[i]; RI.currentmodel = RI.currententity->model; - ASSERT( RI.currententity != NULL ); - ASSERT( RI.currententity->model != NULL ); + Assert( RI.currententity != NULL ); + Assert( RI.currentmodel != NULL ); switch( RI.currentmodel->type ) { @@ -789,8 +789,8 @@ void R_DrawEntitiesOnList( void ) RI.currententity = tr.solid_entities[i]; RI.currentmodel = RI.currententity->model; - ASSERT( RI.currententity != NULL ); - ASSERT( RI.currententity->model != NULL ); + Assert( RI.currententity != NULL ); + Assert( RI.currentmodel != NULL ); switch( RI.currentmodel->type ) { @@ -822,8 +822,8 @@ void R_DrawEntitiesOnList( void ) tr.blend = CL_FxBlend( RI.currententity ) / 255.0f; if( tr.blend <= 0.0f ) continue; - ASSERT( RI.currententity != NULL ); - ASSERT( RI.currententity->model != NULL ); + Assert( RI.currententity != NULL ); + Assert( RI.currentmodel != NULL ); switch( RI.currentmodel->type ) { @@ -1149,7 +1149,7 @@ static int GL_RenderGetParm( int parm, int arg ) #endif return 0; case PARM_TEX_SKYBOX: - ASSERT( arg >= 0 && arg < 6 ); + Assert( arg >= 0 && arg < 6 ); return tr.skyboxTextures[arg]; case PARM_TEX_SKYTEXNUM: return tr.skytexturenum; @@ -1295,19 +1295,19 @@ static int R_FatPVS( const vec3_t org, float radius, byte *visbuffer, qboolean m static lightstyle_t *CL_GetLightStyle( int number ) { - ASSERT( number >= 0 && number < MAX_LIGHTSTYLES ); + Assert( number >= 0 && number < MAX_LIGHTSTYLES ); return &cl.lightstyles[number]; } static dlight_t *CL_GetDynamicLight( int number ) { - ASSERT( number >= 0 && number < MAX_DLIGHTS ); + Assert( number >= 0 && number < MAX_DLIGHTS ); return &cl_dlights[number]; } static dlight_t *CL_GetEntityLight( int number ) { - ASSERT( number >= 0 && number < MAX_ELIGHTS ); + Assert( number >= 0 && number < MAX_ELIGHTS ); return &cl_elights[number]; } diff --git a/engine/client/gl_rsurf.c b/engine/client/gl_rsurf.c index 5c399c1a..9c0068c4 100644 --- a/engine/client/gl_rsurf.c +++ b/engine/client/gl_rsurf.c @@ -311,7 +311,7 @@ void GL_BuildPolygonFromSurface( model_t *mod, msurface_t *fa ) { glt = R_GetTexture( fa->texinfo->texture->gl_texturenum ); tex = fa->texinfo->texture; - ASSERT( glt != NULL && tex != NULL ); + Assert( glt != NULL && tex != NULL ); // update conveyor widths for keep properly speed of scrolling glt->srcWidth = tex->width; diff --git a/engine/client/gl_sprite.c b/engine/client/gl_sprite.c index ad892b6a..92bcfabe 100644 --- a/engine/client/gl_sprite.c +++ b/engine/client/gl_sprite.c @@ -426,7 +426,7 @@ void Mod_UnloadSpriteModel( model_t *mod ) mspriteframe_t *pspriteframe; int i, j; - ASSERT( mod != NULL ); + Assert( mod != NULL ); if( mod->type != mod_sprite ) return; // not a sprite @@ -477,7 +477,7 @@ mspriteframe_t *R_GetSpriteFrame( const model_t *pModel, int frame, float yaw ) int i, numframes; float targettime; - ASSERT( pModel ); + Assert( pModel ); psprite = pModel->cache.data; if( frame < 0 ) diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index 9e7010ec..a6025c18 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -1400,7 +1400,7 @@ void R_StudioBuildNormalTable( void ) mstudiomesh_t *pmesh; int i, j; - ASSERT( m_pSubModel ); + Assert( m_pSubModel ); // reset chrome cache for( i = 0; i < m_pStudioHeader->numbones; i++ ) @@ -1452,7 +1452,7 @@ void R_StudioGenerateNormals( void ) mstudiomesh_t *pmesh; int i, j; - ASSERT( m_pSubModel ); + Assert( m_pSubModel ); for( i = 0; i < m_pSubModel->numverts; i++ ) VectorClear( g_studio.norms[i] ); @@ -3945,7 +3945,7 @@ void Mod_UnloadStudioModel( model_t *mod ) mstudiotexture_t *ptexture; int i; - ASSERT( mod != NULL ); + Assert( mod != NULL ); if( mod->type != mod_studio ) return; // not a studio diff --git a/engine/client/s_mix.c b/engine/client/s_mix.c index e655be78..8784474f 100644 --- a/engine/client/s_mix.c +++ b/engine/client/s_mix.c @@ -113,22 +113,22 @@ void S_TransferPaintBuffer( int endtime ) // MIX_MixChannelsToPaintbuffer, according to flags _inline void MIX_ActivatePaintbuffer( int ipaintbuffer ) { - ASSERT( ipaintbuffer < CPAINTBUFFERS ); + Assert( ipaintbuffer < CPAINTBUFFERS ); paintbuffers[ipaintbuffer].factive = true; } // don't mix into this paintbuffer _inline void MIX_DeactivatePaintbuffer( int ipaintbuffer ) { - ASSERT( ipaintbuffer < CPAINTBUFFERS ); + Assert( ipaintbuffer < CPAINTBUFFERS ); paintbuffers[ipaintbuffer].factive = false; } _inline void MIX_SetCurrentPaintbuffer( int ipaintbuffer ) { - ASSERT( ipaintbuffer < CPAINTBUFFERS ); + Assert( ipaintbuffer < CPAINTBUFFERS ); g_curpaintbuffer = paintbuffers[ipaintbuffer].pbuf; - ASSERT( g_curpaintbuffer != NULL ); + Assert( g_curpaintbuffer != NULL ); } _inline int MIX_GetCurrentPaintbufferIndex( void ) @@ -147,7 +147,7 @@ _inline paintbuffer_t *MIX_GetCurrentPaintbufferPtr( void ) { int ipaint = MIX_GetCurrentPaintbufferIndex(); - ASSERT( ipaint < CPAINTBUFFERS ); + Assert( ipaint < CPAINTBUFFERS ); return &paintbuffers[ipaint]; } @@ -171,20 +171,20 @@ _inline void MIX_ResetPaintbufferFilterCounters( void ) _inline void MIX_ResetPaintbufferFilterCounter( int ipaintbuffer ) { - ASSERT( ipaintbuffer < CPAINTBUFFERS ); + Assert( ipaintbuffer < CPAINTBUFFERS ); paintbuffers[ipaintbuffer].ifilter = 0; } // return pointer to front paintbuffer pbuf, given index _inline portable_samplepair_t *MIX_GetPFrontFromIPaint( int ipaintbuffer ) { - ASSERT( ipaintbuffer < CPAINTBUFFERS ); + Assert( ipaintbuffer < CPAINTBUFFERS ); return paintbuffers[ipaintbuffer].pbuf; } _inline paintbuffer_t *MIX_GetPPaintFromIPaint( int ipaint ) { - ASSERT( ipaint < CPAINTBUFFERS ); + Assert( ipaint < CPAINTBUFFERS ); return &paintbuffers[ipaint]; } @@ -399,7 +399,7 @@ void S_MixChannel( channel_t *pChannel, void *pData, int outputOffset, int input wavdata_t *pSource = pChannel->sfx->cache; portable_samplepair_t *pbuf; - ASSERT( pSource != NULL ); + Assert( pSource != NULL ); pvol[0] = bound( 0, pChannel->leftvol, 255 ); pvol[1] = bound( 0, pChannel->rightvol, 255 ); @@ -476,7 +476,7 @@ int S_MixDataToDevice( channel_t *pChannel, int sampleCount, int outRate, int ou } // Verify that we won't get a buffer overrun. - ASSERT( floor( sampleFrac + rate * ( outSampleCount - 1 )) <= availableSamples ); + Assert( floor( sampleFrac + rate * ( outSampleCount - 1 )) <= availableSamples ); // save current paintbuffer j = MIX_GetCurrentPaintbufferIndex(); @@ -541,10 +541,10 @@ void MIX_MixChannelsToPaintbuffer( int endtime, int rate, int outputRate ) ch = channels; // validate parameters - ASSERT( outputRate <= SOUND_DMA_SPEED ); + Assert( outputRate <= SOUND_DMA_SPEED ); // make sure we're not discarding data - ASSERT( !(( endtime - paintedtime ) & 0x3 ) || ( outputRate == SOUND_DMA_SPEED )); + Assert( !(( endtime - paintedtime ) & 0x3 ) || ( outputRate == SOUND_DMA_SPEED )); // 44k: try to mix this many samples at outputRate sampleCount = ( endtime - paintedtime ) / ( SOUND_DMA_SPEED / outputRate ); @@ -688,7 +688,7 @@ void S_Interpolate2xCubic( portable_samplepair_t *pbuffer, portable_samplepair_t portable_samplepair_t *psamp3; int outpos = 0; - ASSERT( upCount <= PAINTBUFFER_SIZE ); + Assert( upCount <= PAINTBUFFER_SIZE ); // pfiltermem holds 6 samples from previous buffer pass // process 'count' samples @@ -731,10 +731,10 @@ void S_Interpolate2xCubic( portable_samplepair_t *pbuffer, portable_samplepair_t // write out interpolated sample, increment output counter temppaintbuffer[outpos++].right = a/8 + b/4 + c/2 + x0; - ASSERT( outpos <= ( sizeof( temppaintbuffer ) / sizeof( temppaintbuffer[0] ))); + Assert( outpos <= ( sizeof( temppaintbuffer ) / sizeof( temppaintbuffer[0] ))); } - ASSERT( cfltmem >= 3 ); + Assert( cfltmem >= 3 ); // save last 3 samples from paintbuffer pfiltermem[0] = pbuffer[upCount - 5]; @@ -755,8 +755,8 @@ void S_Interpolate2xLinear( portable_samplepair_t *pbuffer, portable_samplepair_ { int i, upCount = count<<1; - ASSERT( upCount <= PAINTBUFFER_SIZE ); - ASSERT( cfltmem >= 1 ); + Assert( upCount <= PAINTBUFFER_SIZE ); + Assert( cfltmem >= 1 ); // use interpolation value from previous mix pbuffer[0].left = (pfiltermem->left + pbuffer[0].left) >> 1; @@ -842,10 +842,10 @@ void MIX_MixPaintbuffers( int ibuf1, int ibuf2, int ibuf3, int count, float fgai gain = 256 * fgain; - ASSERT( count <= PAINTBUFFER_SIZE ); - ASSERT( ibuf1 < CPAINTBUFFERS ); - ASSERT( ibuf2 < CPAINTBUFFERS ); - ASSERT( ibuf3 < CPAINTBUFFERS ); + Assert( count <= PAINTBUFFER_SIZE ); + Assert( ibuf1 < CPAINTBUFFERS ); + Assert( ibuf2 < CPAINTBUFFERS ); + Assert( ibuf3 < CPAINTBUFFERS ); pbuf1 = paintbuffers[ibuf1].pbuf; pbuf2 = paintbuffers[ibuf2].pbuf; @@ -889,7 +889,7 @@ void S_MixUpsample( int sampleCount, int filtertype ) paintbuffer_t *ppaint = MIX_GetCurrentPaintbufferPtr(); int ifilter = ppaint->ifilter; - ASSERT( ifilter < CPAINTFILTERS ); + Assert( ifilter < CPAINTFILTERS ); S_MixBufferUpsample2x( sampleCount, ppaint->pbuf, &(ppaint->fltmem[ifilter][0]), CPAINTFILTERMEM, filtertype ); diff --git a/engine/client/s_stream.c b/engine/client/s_stream.c index 3af856fc..3b644272 100644 --- a/engine/client/s_stream.c +++ b/engine/client/s_stream.c @@ -193,7 +193,7 @@ void S_StreamBackgroundTrack( void ) ch = S_FindRawChannel( S_RAW_SOUND_BACKGROUNDTRACK, true ); - ASSERT( ch != NULL ); + Assert( ch != NULL ); // see how many samples should be copied into the raw buffer if( ch->s_rawend < soundtime ) @@ -294,7 +294,7 @@ void S_StreamSoundTrack( void ) ch = S_FindRawChannel( S_RAW_SOUND_SOUNDTRACK, true ); - ASSERT( ch != NULL ); + Assert( ch != NULL ); // see how many samples should be copied into the raw buffer if( ch->s_rawend < soundtime ) diff --git a/engine/client/vgui/list.txt b/engine/client/vgui/list.txt index 0f68d3cd..11d24bb7 100644 --- a/engine/client/vgui/list.txt +++ b/engine/client/vgui/list.txt @@ -1,12 +1,3 @@ -VGUI_EngineSurface.h -VGUI_EngineSurface.cpp -vgui_intwrap.h -vgui_intwrap.cpp -vgui_int.h -vgui_int.cpp - -Host_Frame->SCR_UpdateScreen->VGui_Paint->VGuiWrap_Paint - colorstrings support: Font.cpp TextImage.cpp \ No newline at end of file diff --git a/engine/client/vgui/utlmemory.h b/engine/client/vgui/utlmemory.h deleted file mode 100644 index 27b12975..00000000 --- a/engine/client/vgui/utlmemory.h +++ /dev/null @@ -1,348 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// $Header: $ -// $NoKeywords: $ -// -// A growable memory class. -//============================================================================= - -#ifndef UTLMEMORY_H -#define UTLMEMORY_H - -#ifdef _WIN32 -#pragma once -#endif - -#include -#include -#include "common.h" - -//----------------------------------------------------------------------------- -// Methods to invoke the constructor, copy constructor, and destructor -//----------------------------------------------------------------------------- - -template -inline void Construct( T* pMemory ) -{ - new( pMemory ) T; -} - -template -inline void CopyConstruct( T* pMemory, T const& src ) -{ - new( pMemory ) T(src); -} - -template -inline void Destruct( T* pMemory ) -{ - pMemory->~T(); - -#ifdef _DEBUG - memset( pMemory, 0xDD, sizeof(T) ); -#endif -} - -#pragma warning (disable:4100) -#pragma warning (disable:4514) - -//----------------------------------------------------------------------------- -// The CUtlMemory class: -// A growable memory class which doubles in size by default. -//----------------------------------------------------------------------------- -template< class T > -class CUtlMemory -{ -public: - // constructor, destructor - CUtlMemory( int nGrowSize = 0, int nInitSize = 0 ); - CUtlMemory( T* pMemory, int numElements ); - ~CUtlMemory(); - - // element access - T& operator[]( int i ); - T const& operator[]( int i ) const; - T& Element( int i ); - T const& Element( int i ) const; - - // Can we use this index? - bool IsIdxValid( int i ) const; - - // Gets the base address (can change when adding elements!) - T* Base(); - T const* Base() const; - - // Attaches the buffer to external memory.... - void SetExternalBuffer( T* pMemory, int numElements ); - - // Size - int NumAllocated() const; - int Count() const; - - // Grows the memory, so that at least allocated + num elements are allocated - void Grow( int num = 1 ); - - // Makes sure we've got at least this much memory - void EnsureCapacity( int num ); - - // Memory deallocation - void Purge(); - - // is the memory externally allocated? - bool IsExternallyAllocated() const; - - // Set the size by which the memory grows - void SetGrowSize( int size ); - -private: - enum - { - EXTERNAL_BUFFER_MARKER = -1, - }; - - T* m_pMemory; - int m_nAllocationCount; - int m_nGrowSize; -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- -template< class T > -CUtlMemory::CUtlMemory( int nGrowSize, int nInitAllocationCount ) : m_pMemory(0), - m_nAllocationCount( nInitAllocationCount ), m_nGrowSize( nGrowSize ) -{ - Assert( (nGrowSize >= 0) && (nGrowSize != EXTERNAL_BUFFER_MARKER) ); - if (m_nAllocationCount) - { - m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) ); - } -} - -template< class T > -CUtlMemory::CUtlMemory( T* pMemory, int numElements ) : m_pMemory(pMemory), - m_nAllocationCount( numElements ) -{ - // Special marker indicating externally supplied memory - m_nGrowSize = EXTERNAL_BUFFER_MARKER; -} - -template< class T > -CUtlMemory::~CUtlMemory() -{ - Purge(); -} - - -//----------------------------------------------------------------------------- -// Attaches the buffer to external memory.... -//----------------------------------------------------------------------------- -template< class T > -void CUtlMemory::SetExternalBuffer( T* pMemory, int numElements ) -{ - // Blow away any existing allocated memory - Purge(); - - m_pMemory = pMemory; - m_nAllocationCount = numElements; - - // Indicate that we don't own the memory - m_nGrowSize = EXTERNAL_BUFFER_MARKER; -} - - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- -template< class T > -inline T& CUtlMemory::operator[]( int i ) -{ - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - -template< class T > -inline T const& CUtlMemory::operator[]( int i ) const -{ - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - -template< class T > -inline T& CUtlMemory::Element( int i ) -{ - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - -template< class T > -inline T const& CUtlMemory::Element( int i ) const -{ - Assert( IsIdxValid(i) ); - return m_pMemory[i]; -} - - -//----------------------------------------------------------------------------- -// is the memory externally allocated? -//----------------------------------------------------------------------------- -template< class T > -bool CUtlMemory::IsExternallyAllocated() const -{ - return m_nGrowSize == EXTERNAL_BUFFER_MARKER; -} - - -template< class T > -void CUtlMemory::SetGrowSize( int nSize ) -{ - Assert( (nSize >= 0) && (nSize != EXTERNAL_BUFFER_MARKER) ); - m_nGrowSize = nSize; -} - - -//----------------------------------------------------------------------------- -// Gets the base address (can change when adding elements!) -//----------------------------------------------------------------------------- -template< class T > -inline T* CUtlMemory::Base() -{ - return m_pMemory; -} - -template< class T > -inline T const* CUtlMemory::Base() const -{ - return m_pMemory; -} - - -//----------------------------------------------------------------------------- -// Size -//----------------------------------------------------------------------------- -template< class T > -inline int CUtlMemory::NumAllocated() const -{ - return m_nAllocationCount; -} - -template< class T > -inline int CUtlMemory::Count() const -{ - return m_nAllocationCount; -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- -template< class T > -inline bool CUtlMemory::IsIdxValid( int i ) const -{ - return (i >= 0) && (i < m_nAllocationCount); -} - - -//----------------------------------------------------------------------------- -// Grows the memory -//----------------------------------------------------------------------------- -template< class T > -void CUtlMemory::Grow( int num ) -{ - Assert( num > 0 ); - - if (IsExternallyAllocated()) - { - // Can't grow a buffer whose memory was externally allocated - Assert(0); - return; - } - - // Make sure we have at least numallocated + num allocations. - // Use the grow rules specified for this memory (in m_nGrowSize) - int nAllocationRequested = m_nAllocationCount + num; - while (m_nAllocationCount < nAllocationRequested) - { - if ( m_nAllocationCount != 0 ) - { - if (m_nGrowSize) - { - m_nAllocationCount += m_nGrowSize; - } - else - { - m_nAllocationCount += m_nAllocationCount; - } - } - else - { - // Compute an allocation which is at least as big as a cache line... - m_nAllocationCount = (31 + sizeof(T)) / sizeof(T); - Assert(m_nAllocationCount != 0); - } - } - - if (m_pMemory) - { - m_pMemory = (T*)realloc( m_pMemory, m_nAllocationCount * sizeof(T) ); - } - else - { - m_pMemory = (T*)malloc( m_nAllocationCount * sizeof(T) ); - } -} - - -//----------------------------------------------------------------------------- -// Makes sure we've got at least this much memory -//----------------------------------------------------------------------------- -template< class T > -inline void CUtlMemory::EnsureCapacity( int num ) -{ - if (m_nAllocationCount >= num) - return; - - if (IsExternallyAllocated()) - { - // Can't grow a buffer whose memory was externally allocated - Assert(0); - return; - } - - m_nAllocationCount = num; - if (m_pMemory) - { - m_pMemory = (T*)realloc( m_pMemory, m_nAllocationCount * sizeof(T) ); - } - else - { - m_pMemory = (T*)alloc( m_nAllocationCount * sizeof(T) ); - } -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- -template< class T > -void CUtlMemory::Purge() -{ - if (!IsExternallyAllocated()) - { - if (m_pMemory) - { - free( (void*)m_pMemory ); - m_pMemory = 0; - } - m_nAllocationCount = 0; - } -} - - -#endif//UTLMEMORY_H \ No newline at end of file diff --git a/engine/client/vgui/utlrbtree.h b/engine/client/vgui/utlrbtree.h deleted file mode 100644 index 61f1f811..00000000 --- a/engine/client/vgui/utlrbtree.h +++ /dev/null @@ -1,1289 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Header: $ -// $NoKeywords: $ -//============================================================================= - -#ifndef UTLRBTREE_H -#define UTLRBTREE_H - -#include "utlmemory.h" - -//----------------------------------------------------------------------------- -// Tool to generate a default compare function for any type that implements -// operator<, including all simple types -//----------------------------------------------------------------------------- - -template -class CDefOps -{ -public: - static bool LessFunc( const T &lhs, const T &rhs ) { return ( lhs < rhs ); } -}; - -#define DefLessFunc( type ) CDefOps::LessFunc - -//------------------------------------- - -inline bool StringLessThan( const char * const &lhs, const char * const &rhs) { return ( Q_strcmp( lhs, rhs) < 0 ); } -inline bool CaselessStringLessThan( const char * const &lhs, const char * const &rhs ) { return ( Q_stricmp( lhs, rhs) < 0 ); } - -//------------------------------------- -// inline these two templates to stop multiple definitions of the same code -template <> inline bool CDefOps::LessFunc( const char * const &lhs, const char * const &rhs ) { return StringLessThan( lhs, rhs ); } -template <> inline bool CDefOps::LessFunc( char * const &lhs, char * const &rhs ) { return StringLessThan( lhs, rhs ); } - -//------------------------------------- - -template -void SetDefLessFunc( RBTREE_T &RBTree ) -{ -#ifdef _WIN32 - RBTree.SetLessFunc( DefLessFunc( RBTREE_T::KeyType_t ) ); -#elif _LINUX - RBTree.SetLessFunc( DefLessFunc( typename RBTREE_T::KeyType_t ) ); -#endif -} - -//----------------------------------------------------------------------------- -// A red-black binary search tree -//----------------------------------------------------------------------------- - -template -class CUtlRBTree -{ -public: - // Less func typedef - // Returns true if the first parameter is "less" than the second - typedef bool (*LessFunc_t)( T const &, T const & ); - - typedef T KeyType_t; - typedef T ElemType_t; - typedef I IndexType_t; - - // constructor, destructor - // Left at growSize = 0, the memory will first allocate 1 element and double in size - // at each increment. - // LessFunc_t is required, but may be set after the constructor using SetLessFunc() below - CUtlRBTree( int growSize = 0, int initSize = 0, LessFunc_t lessfunc = 0 ); - ~CUtlRBTree( ); - - // gets particular elements - T& Element( I i ); - T const &Element( I i ) const; - T& operator[]( I i ); - T const &operator[]( I i ) const; - - // Gets the root - I Root() const; - - // Num elements - unsigned int Count() const; - - // Max "size" of the vector - I MaxElement() const; - - // Gets the children - I Parent( I i ) const; - I LeftChild( I i ) const; - I RightChild( I i ) const; - - // Tests if a node is a left or right child - bool IsLeftChild( I i ) const; - bool IsRightChild( I i ) const; - - // Tests if root or leaf - bool IsRoot( I i ) const; - bool IsLeaf( I i ) const; - - // Checks if a node is valid and in the tree - bool IsValidIndex( I i ) const; - - // Checks if the tree as a whole is valid - bool IsValid() const; - - // Invalid index - static I InvalidIndex(); - - // returns the tree depth (not a very fast operation) - int Depth( I node ) const; - int Depth() const; - - // Sets the less func - void SetLessFunc( LessFunc_t func ); - - // Allocation method - I NewNode(); - - // Insert method (inserts in order) - I Insert( T const &insert ); - void Insert( const T *pArray, int nItems ); - - // Find method - I Find( T const &search ) const; - - // Remove methods - void RemoveAt( I i ); - bool Remove( T const &remove ); - void RemoveAll( ); - - // Allocation, deletion - void FreeNode( I i ); - - // Iteration - I FirstInorder() const; - I NextInorder( I i ) const; - I PrevInorder( I i ) const; - I LastInorder() const; - - I FirstPreorder() const; - I NextPreorder( I i ) const; - I PrevPreorder( I i ) const; - I LastPreorder( ) const; - - I FirstPostorder() const; - I NextPostorder( I i ) const; - - // If you change the search key, this can be used to reinsert the - // element into the tree. - void Reinsert( I elem ); - -protected: - enum NodeColor_t - { - RED = 0, - BLACK - }; - - struct Links_t - { - I m_Left; - I m_Right; - I m_Parent; - I m_Tag; - }; - - struct Node_t : public Links_t - { - T m_Data; - }; - - // Sets the children - void SetParent( I i, I parent ); - void SetLeftChild( I i, I child ); - void SetRightChild( I i, I child ); - void LinkToParent( I i, I parent, bool isLeft ); - - // Gets at the links - Links_t const &Links( I i ) const; - Links_t &Links( I i ); - - // Checks if a link is red or black - bool IsRed( I i ) const; - bool IsBlack( I i ) const; - - // Sets/gets node color - NodeColor_t Color( I i ) const; - void SetColor( I i, NodeColor_t c ); - - // operations required to preserve tree balance - void RotateLeft(I i); - void RotateRight(I i); - void InsertRebalance(I i); - void RemoveRebalance(I i); - - // Insertion, removal - I InsertAt( I parent, bool leftchild ); - - // copy constructors not allowed - CUtlRBTree( CUtlRBTree const &tree ); - - // Inserts a node into the tree, doesn't copy the data in. - void FindInsertionPosition( T const &insert, I &parent, bool &leftchild ); - - // Remove and add back an element in the tree. - void Unlink( I elem ); - void Link( I elem ); - - // Used for sorting. - LessFunc_t m_LessFunc; - - CUtlMemory m_Elements; - I m_Root; - I m_NumElements; - I m_FirstFree; - I m_TotalElements; - - Node_t* m_pElements; - - void ResetDbgInfo() - { - m_pElements = (Node_t*)m_Elements.Base(); - } -}; - - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template -CUtlRBTree::CUtlRBTree( int growSize, int initSize, LessFunc_t lessfunc ) : - m_Elements( growSize, initSize ), - m_LessFunc( lessfunc ), - m_Root( InvalidIndex() ), - m_NumElements( 0 ), m_TotalElements( 0 ), - m_FirstFree( InvalidIndex() ) -{ - ResetDbgInfo(); -} - -template -CUtlRBTree::~CUtlRBTree() -{ -} - -//----------------------------------------------------------------------------- -// gets particular elements -//----------------------------------------------------------------------------- - -template -inline T &CUtlRBTree::Element( I i ) -{ - return m_Elements[i].m_Data; -} - -template -inline T const &CUtlRBTree::Element( I i ) const -{ - return m_Elements[i].m_Data; -} - -template -inline T &CUtlRBTree::operator[]( I i ) -{ - return Element(i); -} - -template -inline T const &CUtlRBTree::operator[]( I i ) const -{ - return Element(i); -} - -//----------------------------------------------------------------------------- -// -// various accessors -// -//----------------------------------------------------------------------------- - -//----------------------------------------------------------------------------- -// Gets the root -//----------------------------------------------------------------------------- - -template -inline I CUtlRBTree::Root() const -{ - return m_Root; -} - -//----------------------------------------------------------------------------- -// Num elements -//----------------------------------------------------------------------------- - -template -inline unsigned int CUtlRBTree::Count() const -{ - return (unsigned int)m_NumElements; -} - -//----------------------------------------------------------------------------- -// Max "size" of the vector -//----------------------------------------------------------------------------- - -template -inline I CUtlRBTree::MaxElement() const -{ - return (I)m_TotalElements; -} - - -//----------------------------------------------------------------------------- -// Gets the children -//----------------------------------------------------------------------------- - -template -inline I CUtlRBTree::Parent( I i ) const -{ - return Links(i).m_Parent; -} - -template -inline I CUtlRBTree::LeftChild( I i ) const -{ - return Links(i).m_Left; -} - -template -inline I CUtlRBTree::RightChild( I i ) const -{ - return Links(i).m_Right; -} - -//----------------------------------------------------------------------------- -// Tests if a node is a left or right child -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsLeftChild( I i ) const -{ - return LeftChild(Parent(i)) == i; -} - -template -inline bool CUtlRBTree::IsRightChild( I i ) const -{ - return RightChild(Parent(i)) == i; -} - - -//----------------------------------------------------------------------------- -// Tests if root or leaf -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsRoot( I i ) const -{ - return i == m_Root; -} - -template -inline bool CUtlRBTree::IsLeaf( I i ) const -{ - return (LeftChild(i) == InvalidIndex()) && (RightChild(i) == InvalidIndex()); -} - - -//----------------------------------------------------------------------------- -// Checks if a node is valid and in the tree -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsValidIndex( I i ) const -{ - return LeftChild(i) != i; -} - - -//----------------------------------------------------------------------------- -// Invalid index -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::InvalidIndex() -{ - return (I)~0; -} - - -//----------------------------------------------------------------------------- -// returns the tree depth (not a very fast operation) -//----------------------------------------------------------------------------- - -template -inline int CUtlRBTree::Depth() const -{ - return Depth(Root()); -} - -//----------------------------------------------------------------------------- -// Sets the children -//----------------------------------------------------------------------------- - -template -inline void CUtlRBTree::SetParent( I i, I parent ) -{ - Links(i).m_Parent = parent; -} - -template -inline void CUtlRBTree::SetLeftChild( I i, I child ) -{ - Links(i).m_Left = child; -} - -template -inline void CUtlRBTree::SetRightChild( I i, I child ) -{ - Links(i).m_Right = child; -} - -//----------------------------------------------------------------------------- -// Gets at the links -//----------------------------------------------------------------------------- - -template -inline typename CUtlRBTree::Links_t const &CUtlRBTree::Links( I i ) const -{ - // Sentinel node, makes life easier - static Links_t s_Sentinel = - { - InvalidIndex(), InvalidIndex(), InvalidIndex(), CUtlRBTree::BLACK - }; - - return (i != InvalidIndex()) ? *(Links_t*)&m_Elements[i] : - *(Links_t*)&s_Sentinel; -} - -template -inline typename CUtlRBTree::Links_t &CUtlRBTree::Links( I i ) -{ - Assert(i != InvalidIndex()); - return *(Links_t *)&m_Elements[i]; -} - -//----------------------------------------------------------------------------- -// Checks if a link is red or black -//----------------------------------------------------------------------------- - -template -inline bool CUtlRBTree::IsRed( I i ) const -{ - return (Links(i).m_Tag == RED); -} - -template -inline bool CUtlRBTree::IsBlack( I i ) const -{ - return (Links(i).m_Tag == BLACK); -} - - -//----------------------------------------------------------------------------- -// Sets/gets node color -//----------------------------------------------------------------------------- - -template -inline typename CUtlRBTree::NodeColor_t CUtlRBTree::Color( I i ) const -{ - return (NodeColor_t)Links(i).m_Tag; -} - -template -inline void CUtlRBTree::SetColor( I i, typename CUtlRBTree::NodeColor_t c ) -{ - Links(i).m_Tag = (I)c; -} - -//----------------------------------------------------------------------------- -// Allocates/ deallocates nodes -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::NewNode() -{ - I newElem; - - // Nothing in the free list; add. - if (m_FirstFree == InvalidIndex()) - { - if (m_Elements.NumAllocated() == m_TotalElements) - m_Elements.Grow(); - newElem = m_TotalElements++; - } - else - { - newElem = m_FirstFree; - m_FirstFree = RightChild(m_FirstFree); - } - -#ifdef _DEBUG - // reset links to invalid.... - Links_t &node = Links(newElem); - node.m_Left = node.m_Right = node.m_Parent = InvalidIndex(); -#endif - - Construct( &Element(newElem) ); - ResetDbgInfo(); - - return newElem; -} - -template -void CUtlRBTree::FreeNode( I i ) -{ - Assert( IsValidIndex(i) && (i != InvalidIndex()) ); - Destruct( &Element(i) ); - SetLeftChild( i, i ); // indicates it's in not in the tree - SetRightChild( i, m_FirstFree ); - m_FirstFree = i; -} - - -//----------------------------------------------------------------------------- -// Rotates node i to the left -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RotateLeft(I elem) -{ - I rightchild = RightChild(elem); - SetRightChild( elem, LeftChild(rightchild) ); - if (LeftChild(rightchild) != InvalidIndex()) - SetParent( LeftChild(rightchild), elem ); - - if (rightchild != InvalidIndex()) - SetParent( rightchild, Parent(elem) ); - if (!IsRoot(elem)) - { - if (IsLeftChild(elem)) - SetLeftChild( Parent(elem), rightchild ); - else - SetRightChild( Parent(elem), rightchild ); - } - else - m_Root = rightchild; - - SetLeftChild( rightchild, elem ); - if (elem != InvalidIndex()) - SetParent( elem, rightchild ); -} - - -//----------------------------------------------------------------------------- -// Rotates node i to the right -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RotateRight(I elem) -{ - I leftchild = LeftChild(elem); - SetLeftChild( elem, RightChild(leftchild) ); - if (RightChild(leftchild) != InvalidIndex()) - SetParent( RightChild(leftchild), elem ); - - if (leftchild != InvalidIndex()) - SetParent( leftchild, Parent(elem) ); - if (!IsRoot(elem)) - { - if (IsRightChild(elem)) - SetRightChild( Parent(elem), leftchild ); - else - SetLeftChild( Parent(elem), leftchild ); - } - else - m_Root = leftchild; - - SetRightChild( leftchild, elem ); - if (elem != InvalidIndex()) - SetParent( elem, leftchild ); -} - - -//----------------------------------------------------------------------------- -// Rebalances the tree after an insertion -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::InsertRebalance(I elem) -{ - while ( !IsRoot(elem) && (Color(Parent(elem)) == RED) ) - { - I parent = Parent(elem); - I grandparent = Parent(parent); - - /* we have a violation */ - if (IsLeftChild(parent)) - { - I uncle = RightChild(grandparent); - if (IsRed(uncle)) - { - /* uncle is RED */ - SetColor(parent, BLACK); - SetColor(uncle, BLACK); - SetColor(grandparent, RED); - elem = grandparent; - } - else - { - /* uncle is BLACK */ - if (IsRightChild(elem)) - { - /* make x a left child, will change parent and grandparent */ - elem = parent; - RotateLeft(elem); - parent = Parent(elem); - grandparent = Parent(parent); - } - /* recolor and rotate */ - SetColor(parent, BLACK); - SetColor(grandparent, RED); - RotateRight(grandparent); - } - } - else - { - /* mirror image of above code */ - I uncle = LeftChild(grandparent); - if (IsRed(uncle)) - { - /* uncle is RED */ - SetColor(parent, BLACK); - SetColor(uncle, BLACK); - SetColor(grandparent, RED); - elem = grandparent; - } - else - { - /* uncle is BLACK */ - if (IsLeftChild(elem)) - { - /* make x a right child, will change parent and grandparent */ - elem = parent; - RotateRight(parent); - parent = Parent(elem); - grandparent = Parent(parent); - } - /* recolor and rotate */ - SetColor(parent, BLACK); - SetColor(grandparent, RED); - RotateLeft(grandparent); - } - } - } - SetColor( m_Root, BLACK ); -} - - -//----------------------------------------------------------------------------- -// Insert a node into the tree -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::InsertAt( I parent, bool leftchild ) -{ - I i = NewNode(); - LinkToParent( i, parent, leftchild ); - ++m_NumElements; - return i; -} - -template -void CUtlRBTree::LinkToParent( I i, I parent, bool isLeft ) -{ - Links_t &elem = Links(i); - elem.m_Parent = parent; - elem.m_Left = elem.m_Right = InvalidIndex(); - elem.m_Tag = RED; - - /* insert node in tree */ - if (parent != InvalidIndex()) - { - if (isLeft) - Links(parent).m_Left = i; - else - Links(parent).m_Right = i; - } - else - { - m_Root = i; - } - - InsertRebalance(i); - - Assert(IsValid()); -} - -//----------------------------------------------------------------------------- -// Rebalance the tree after a deletion -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RemoveRebalance(I elem) -{ - while (elem != m_Root && IsBlack(elem)) - { - I parent = Parent(elem); - - // If elem is the left child of the parent - if (elem == LeftChild(parent)) - { - // Get our sibling - I sibling = RightChild(parent); - if (IsRed(sibling)) - { - SetColor(sibling, BLACK); - SetColor(parent, RED); - RotateLeft(parent); - - // We may have a new parent now - parent = Parent(elem); - sibling = RightChild(parent); - } - if ( (IsBlack(LeftChild(sibling))) && (IsBlack(RightChild(sibling))) ) - { - if (sibling != InvalidIndex()) - SetColor(sibling, RED); - elem = parent; - } - else - { - if (IsBlack(RightChild(sibling))) - { - SetColor(LeftChild(sibling), BLACK); - SetColor(sibling, RED); - RotateRight(sibling); - - // rotation may have changed this - parent = Parent(elem); - sibling = RightChild(parent); - } - SetColor( sibling, Color(parent) ); - SetColor( parent, BLACK ); - SetColor( RightChild(sibling), BLACK ); - RotateLeft( parent ); - elem = m_Root; - } - } - else - { - // Elem is the right child of the parent - I sibling = LeftChild(parent); - if (IsRed(sibling)) - { - SetColor(sibling, BLACK); - SetColor(parent, RED); - RotateRight(parent); - - // We may have a new parent now - parent = Parent(elem); - sibling = LeftChild(parent); - } - if ( (IsBlack(RightChild(sibling))) && (IsBlack(LeftChild(sibling))) ) - { - if (sibling != InvalidIndex()) - SetColor( sibling, RED ); - elem = parent; - } - else - { - if (IsBlack(LeftChild(sibling))) - { - SetColor( RightChild(sibling), BLACK ); - SetColor( sibling, RED ); - RotateLeft( sibling ); - - // rotation may have changed this - parent = Parent(elem); - sibling = LeftChild(parent); - } - SetColor( sibling, Color(parent) ); - SetColor( parent, BLACK ); - SetColor( LeftChild(sibling), BLACK ); - RotateRight( parent ); - elem = m_Root; - } - } - } - SetColor( elem, BLACK ); -} - -template -void CUtlRBTree::Unlink( I elem ) -{ - if ( elem != InvalidIndex() ) - { - I x, y; - - if ((LeftChild(elem) == InvalidIndex()) || - (RightChild(elem) == InvalidIndex())) - { - /* y has a NIL node as a child */ - y = elem; - } - else - { - /* find tree successor with a NIL node as a child */ - y = RightChild(elem); - while (LeftChild(y) != InvalidIndex()) - y = LeftChild(y); - } - - /* x is y's only child */ - if (LeftChild(y) != InvalidIndex()) - x = LeftChild(y); - else - x = RightChild(y); - - /* remove y from the parent chain */ - if (x != InvalidIndex()) - SetParent( x, Parent(y) ); - if (!IsRoot(y)) - { - if (IsLeftChild(y)) - SetLeftChild( Parent(y), x ); - else - SetRightChild( Parent(y), x ); - } - else - m_Root = x; - - // need to store this off now, we'll be resetting y's color - NodeColor_t ycolor = Color(y); - if (y != elem) - { - // Standard implementations copy the data around, we cannot here. - // Hook in y to link to the same stuff elem used to. - SetParent( y, Parent(elem) ); - SetRightChild( y, RightChild(elem) ); - SetLeftChild( y, LeftChild(elem) ); - - if (!IsRoot(elem)) - if (IsLeftChild(elem)) - SetLeftChild( Parent(elem), y ); - else - SetRightChild( Parent(elem), y ); - else - m_Root = y; - - if (LeftChild(y) != InvalidIndex()) - SetParent( LeftChild(y), y ); - if (RightChild(y) != InvalidIndex()) - SetParent( RightChild(y), y ); - - SetColor( y, Color(elem) ); - } - - if ((x != InvalidIndex()) && (ycolor == BLACK)) - RemoveRebalance(x); - } -} - -template -void CUtlRBTree::Link( I elem ) -{ - if ( elem != InvalidIndex() ) - { - I parent; - bool leftchild; - - FindInsertionPosition( Element( elem ), parent, leftchild ); - - LinkToParent( elem, parent, leftchild ); - } -} - -//----------------------------------------------------------------------------- -// Delete a node from the tree -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RemoveAt(I elem) -{ - if ( elem != InvalidIndex() ) - { - Unlink( elem ); - - FreeNode(elem); - --m_NumElements; - } -} - - -//----------------------------------------------------------------------------- -// remove a node in the tree -//----------------------------------------------------------------------------- - -template bool CUtlRBTree::Remove( T const &search ) -{ - I node = Find( search ); - if (node != InvalidIndex()) - { - RemoveAt(node); - return true; - } - return false; -} - - -//----------------------------------------------------------------------------- -// Removes all nodes from the tree -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::RemoveAll() -{ - // Just iterate through the whole list and add to free list - // much faster than doing all of the rebalancing - // also, do it so the free list is pointing to stuff in order - // to get better cache coherence when re-adding stuff to this tree. - I prev = InvalidIndex(); - for (int i = (int)m_TotalElements; --i >= 0; ) - { - I idx = (I)i; - if (IsValidIndex(idx)) - Destruct( &Element(idx) ); - SetRightChild( idx, prev ); - SetLeftChild( idx, idx ); - prev = idx; - } - m_FirstFree = m_TotalElements ? (I)0 : InvalidIndex(); - m_Root = InvalidIndex(); - m_NumElements = 0; -} - - -//----------------------------------------------------------------------------- -// iteration -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::FirstInorder() const -{ - I i = m_Root; - while (LeftChild(i) != InvalidIndex()) - i = LeftChild(i); - return i; -} - -template -I CUtlRBTree::NextInorder( I i ) const -{ - Assert(IsValidIndex(i)); - - if (RightChild(i) != InvalidIndex()) - { - i = RightChild(i); - while (LeftChild(i) != InvalidIndex()) - i = LeftChild(i); - return i; - } - - I parent = Parent(i); - while (IsRightChild(i)) - { - i = parent; - if (i == InvalidIndex()) break; - parent = Parent(i); - } - return parent; -} - -template -I CUtlRBTree::PrevInorder( I i ) const -{ - Assert(IsValidIndex(i)); - - if (LeftChild(i) != InvalidIndex()) - { - i = LeftChild(i); - while (RightChild(i) != InvalidIndex()) - i = RightChild(i); - return i; - } - - I parent = Parent(i); - while (IsLeftChild(i)) - { - i = parent; - if (i == InvalidIndex()) break; - parent = Parent(i); - } - return parent; -} - -template -I CUtlRBTree::LastInorder() const -{ - I i = m_Root; - while (RightChild(i) != InvalidIndex()) - i = RightChild(i); - return i; -} - -template -I CUtlRBTree::FirstPreorder() const -{ - return m_Root; -} - -template -I CUtlRBTree::NextPreorder( I i ) const -{ - if (LeftChild(i) != InvalidIndex()) - return LeftChild(i); - - if (RightChild(i) != InvalidIndex()) - return RightChild(i); - - I parent = Parent(i); - while( parent != InvalidIndex()) - { - if (IsLeftChild(i) && (RightChild(parent) != InvalidIndex())) - return RightChild(parent); - i = parent; - parent = Parent(parent); - } - return InvalidIndex(); -} - -template -I CUtlRBTree::PrevPreorder( I i ) const -{ - Assert(0); // not implemented yet - return InvalidIndex(); -} - -template -I CUtlRBTree::LastPreorder() const -{ - I i = m_Root; - while (1) - { - while (RightChild(i) != InvalidIndex()) - i = RightChild(i); - - if (LeftChild(i) != InvalidIndex()) - i = LeftChild(i); - else - break; - } - return i; -} - -template -I CUtlRBTree::FirstPostorder() const -{ - I i = m_Root; - while (!IsLeaf(i)) - { - if (LeftChild(i)) - i = LeftChild(i); - else - i = RightChild(i); - } - return i; -} - -template -I CUtlRBTree::NextPostorder( I i ) const -{ - I parent = Parent(i); - if (parent == InvalidIndex()) - return InvalidIndex(); - - if (IsRightChild(i)) - return parent; - - if (RightChild(parent) == InvalidIndex()) - return parent; - - i = RightChild(parent); - while (!IsLeaf(i)) - { - if (LeftChild(i)) - i = LeftChild(i); - else - i = RightChild(i); - } - return i; -} - - -template -void CUtlRBTree::Reinsert( I elem ) -{ - Unlink( elem ); - Link( elem ); -} - - -//----------------------------------------------------------------------------- -// returns the tree depth (not a very fast operation) -//----------------------------------------------------------------------------- - -template -int CUtlRBTree::Depth( I node ) const -{ - if (node == InvalidIndex()) - return 0; - - int depthright = Depth( RightChild(node) ); - int depthleft = Depth( LeftChild(node) ); - return max(depthright, depthleft) + 1; -} - - -//----------------------------------------------------------------------------- -// Makes sure the tree is valid after every operation -//----------------------------------------------------------------------------- - -template -bool CUtlRBTree::IsValid() const -{ - if ( !Count() ) - return true; - - if (( Root() >= MaxElement()) || ( Parent( Root() ) != InvalidIndex() )) - goto InvalidTree; - -#ifdef UTLTREE_PARANOID - - // First check to see that mNumEntries matches reality. - // count items on the free list - int numFree = 0; - int curr = m_FirstFree; - while (curr != InvalidIndex()) - { - ++numFree; - curr = RightChild(curr); - if ( (curr > MaxElement()) && (curr != InvalidIndex()) ) - goto InvalidTree; - } - if (MaxElement() - numFree != Count()) - goto InvalidTree; - - // iterate over all elements, looking for validity - // based on the self pointers - int numFree2 = 0; - for (curr = 0; curr < MaxElement(); ++curr) - { - if (!IsValidIndex(curr)) - ++numFree2; - else - { - int right = RightChild(curr); - int left = LeftChild(curr); - if ((right == left) && (right != InvalidIndex()) ) - goto InvalidTree; - - if (right != InvalidIndex()) - { - if (!IsValidIndex(right)) - goto InvalidTree; - if (Parent(right) != curr) - goto InvalidTree; - if (IsRed(curr) && IsRed(right)) - goto InvalidTree; - } - - if (left != InvalidIndex()) - { - if (!IsValidIndex(left)) - goto InvalidTree; - if (Parent(left) != curr) - goto InvalidTree; - if (IsRed(curr) && IsRed(left)) - goto InvalidTree; - } - } - } - if (numFree2 != numFree) - goto InvalidTree; - -#endif // UTLTREE_PARANOID - - return true; - -InvalidTree: - return false; -} - - -//----------------------------------------------------------------------------- -// Sets the less func -//----------------------------------------------------------------------------- - -template -void CUtlRBTree::SetLessFunc( typename CUtlRBTree::LessFunc_t func ) -{ - if (!m_LessFunc) - m_LessFunc = func; - else - { - // need to re-sort the tree here.... - Assert(0); - } -} - - -//----------------------------------------------------------------------------- -// inserts a node into the tree -//----------------------------------------------------------------------------- - -// Inserts a node into the tree, doesn't copy the data in. -template -void CUtlRBTree::FindInsertionPosition( T const &insert, I &parent, bool &leftchild ) -{ - Assert( m_LessFunc != NULL ); - - /* find where node belongs */ - I current = m_Root; - parent = InvalidIndex(); - leftchild = false; - while (current != InvalidIndex()) - { - parent = current; - if (m_LessFunc( insert, Element(current) )) - { - leftchild = true; current = LeftChild(current); - } - else - { - leftchild = false; current = RightChild(current); - } - } -} - -template -I CUtlRBTree::Insert( T const &insert ) -{ - // use copy constructor to copy it in - I parent; - bool leftchild; - FindInsertionPosition( insert, parent, leftchild ); - I newNode = InsertAt( parent, leftchild ); - CopyConstruct( &Element( newNode ), insert ); - return newNode; -} - - -template -void CUtlRBTree::Insert( const T *pArray, int nItems ) -{ - while ( nItems-- ) - { - Insert( *pArray++ ); - } -} - -//----------------------------------------------------------------------------- -// finds a node in the tree -//----------------------------------------------------------------------------- - -template -I CUtlRBTree::Find( T const &search ) const -{ - Assert( m_LessFunc != NULL ); - - I current = m_Root; - while (current != InvalidIndex()) - { - if (m_LessFunc( search, Element(current) )) - current = LeftChild(current); - else if (m_LessFunc( Element(current), search )) - current = RightChild(current); - else - break; - } - return current; -} - -#endif//UTLRBTREE_H \ No newline at end of file diff --git a/engine/client/vgui/utlvector.h b/engine/client/vgui/utlvector.h deleted file mode 100644 index aa169e0b..00000000 --- a/engine/client/vgui/utlvector.h +++ /dev/null @@ -1,605 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// $Header: $ -// $NoKeywords: $ -// -// A growable array class that maintains a free list and keeps elements -// in the same location -//============================================================================= - -#ifndef UTLVECTOR_H -#define UTLVECTOR_H - -#ifdef _WIN32 -#pragma once -#endif - - -#include -#include "utlmemory.h" - - -//----------------------------------------------------------------------------- -// The CUtlVector class: -// A growable array class which doubles in size by default. -// It will always keep all elements consecutive in memory, and may move the -// elements around in memory (via a realloc) when elements are inserted or -// removed. Clients should therefore refer to the elements of the vector -// by index (they should *never* maintain pointers to elements in the vector). -//----------------------------------------------------------------------------- - -template< class T > -class CUtlVector -{ -public: - typedef T ElemType_t; - - // constructor, destructor - CUtlVector( int growSize = 0, int initSize = 0 ); - CUtlVector( T* pMemory, int numElements ); - ~CUtlVector(); - - // Copy the array. - CUtlVector& operator=( const CUtlVector &other ); - - // element access - T& operator[]( int i ); - T const& operator[]( int i ) const; - T& Element( int i ); - T const& Element( int i ) const; - - // Gets the base address (can change when adding elements!) - T* Base(); - T const* Base() const; - - // Returns the number of elements in the vector - // SIZE IS DEPRECATED! - int Count() const; - int Size() const; // don't use me! - - // Is element index valid? - bool IsValidIndex( int i ) const; - static int InvalidIndex( void ); - - // Adds an element, uses default constructor - int AddToHead(); - int AddToTail(); - int InsertBefore( int elem ); - int InsertAfter( int elem ); - - // Adds an element, uses copy constructor - int AddToHead( T const& src ); - int AddToTail( T const& src ); - int InsertBefore( int elem, T const& src ); - int InsertAfter( int elem, T const& src ); - - // Adds multiple elements, uses default constructor - int AddMultipleToHead( int num ); - int AddMultipleToTail( int num, const T *pToCopy=NULL ); - int InsertMultipleBefore( int elem, int num, const T *pToCopy=NULL ); // If pToCopy is set, then it's an array of length 'num' and - int InsertMultipleAfter( int elem, int num ); - - // Calls RemoveAll() then AddMultipleToTail. - void SetSize( int size ); - void SetCount( int count ); - - // Calls SetSize and copies each element. - void CopyArray( T const *pArray, int size ); - - // Add the specified array to the tail. - int AddVectorToTail( CUtlVector const &src ); - - // Finds an element (element needs operator== defined) - int Find( T const& src ) const; - - bool HasElement( T const& src ); - - // Makes sure we have enough memory allocated to store a requested # of elements - void EnsureCapacity( int num ); - - // Makes sure we have at least this many elements - void EnsureCount( int num ); - - // Element removal - void FastRemove( int elem ); // doesn't preserve order - void Remove( int elem ); // preserves order, shifts elements - void FindAndRemove( T const& src ); // removes first occurrence of src, preserves order, shifts elements - void RemoveMultiple( int elem, int num ); // preserves order, shifts elements - void RemoveAll(); // doesn't deallocate memory - - // Memory deallocation - void Purge(); - - // Purges the list and calls delete on each element in it. - void PurgeAndDeleteElements(); - - // Set the size by which it grows when it needs to allocate more memory. - void SetGrowSize( int size ); - -protected: - // Can't copy this unless we explicitly do it! - CUtlVector( CUtlVector const& vec ) { Assert(0); } - - // Grows the vector - void GrowVector( int num = 1 ); - - // Shifts elements.... - void ShiftElementsRight( int elem, int num = 1 ); - void ShiftElementsLeft( int elem, int num = 1 ); - - // For easier access to the elements through the debugger - void ResetDbgInfo(); - - CUtlMemory m_Memory; - int m_Size; - - // For easier access to the elements through the debugger - // it's in release builds so this can be used in libraries correctly - T *m_pElements; -}; - - -//----------------------------------------------------------------------------- -// For easier access to the elements through the debugger -//----------------------------------------------------------------------------- - -template< class T > -inline void CUtlVector::ResetDbgInfo() -{ - m_pElements = m_Memory.Base(); -} - -//----------------------------------------------------------------------------- -// constructor, destructor -//----------------------------------------------------------------------------- - -template< class T > -inline CUtlVector::CUtlVector( int growSize, int initSize ) : - m_Memory(growSize, initSize), m_Size(0) -{ - ResetDbgInfo(); -} - -template< class T > -inline CUtlVector::CUtlVector( T* pMemory, int numElements ) : - m_Memory(pMemory, numElements), m_Size(0) -{ - ResetDbgInfo(); -} - -template< class T > -inline CUtlVector::~CUtlVector() -{ - Purge(); -} - -template -inline CUtlVector& CUtlVector::operator=( const CUtlVector &other ) -{ - CopyArray( other.Base(), other.Count() ); - return *this; -} - -//----------------------------------------------------------------------------- -// element access -//----------------------------------------------------------------------------- - -template< class T > -inline T& CUtlVector::operator[]( int i ) -{ - Assert( IsValidIndex(i) ); - return m_Memory[i]; -} - -template< class T > -inline T const& CUtlVector::operator[]( int i ) const -{ - Assert( IsValidIndex(i) ); - return m_Memory[i]; -} - -template< class T > -inline T& CUtlVector::Element( int i ) -{ - Assert( IsValidIndex(i) ); - return m_Memory[i]; -} - -template< class T > -inline T const& CUtlVector::Element( int i ) const -{ - Assert( IsValidIndex(i) ); - return m_Memory[i]; -} - - -//----------------------------------------------------------------------------- -// Gets the base address (can change when adding elements!) -//----------------------------------------------------------------------------- - -template< class T > -inline T* CUtlVector::Base() -{ - return m_Memory.Base(); -} - -template< class T > -inline T const* CUtlVector::Base() const -{ - return m_Memory.Base(); -} - -//----------------------------------------------------------------------------- -// Count -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::Size() const -{ - return m_Size; -} - -template< class T > -inline int CUtlVector::Count() const -{ - return m_Size; -} - - -//----------------------------------------------------------------------------- -// Is element index valid? -//----------------------------------------------------------------------------- - -template< class T > -inline bool CUtlVector::IsValidIndex( int i ) const -{ - return (i >= 0) && (i < m_Size); -} - - -//----------------------------------------------------------------------------- -// Returns in invalid index -//----------------------------------------------------------------------------- -template< class T > -inline int CUtlVector::InvalidIndex( void ) -{ - return -1; -} - - -//----------------------------------------------------------------------------- -// Grows the vector -//----------------------------------------------------------------------------- -template< class T > -void CUtlVector::GrowVector( int num ) -{ - if (m_Size + num - 1 >= m_Memory.NumAllocated()) - { - m_Memory.Grow( m_Size + num - m_Memory.NumAllocated() ); - } - - m_Size += num; - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Makes sure we have enough memory allocated to store a requested # of elements -//----------------------------------------------------------------------------- -template< class T > -void CUtlVector::EnsureCapacity( int num ) -{ - m_Memory.EnsureCapacity(num); - ResetDbgInfo(); -} - - -//----------------------------------------------------------------------------- -// Makes sure we have at least this many elements -//----------------------------------------------------------------------------- -template< class T > -void CUtlVector::EnsureCount( int num ) -{ - if (Count() < num) - AddMultipleToTail( num - Count() ); -} - - -//----------------------------------------------------------------------------- -// Shifts elements -//----------------------------------------------------------------------------- -template< class T > -void CUtlVector::ShiftElementsRight( int elem, int num ) -{ - Assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 )); - int numToMove = m_Size - elem - num; - if ((numToMove > 0) && (num > 0)) - memmove( &Element(elem+num), &Element(elem), numToMove * sizeof(T) ); -} - -template< class T > -void CUtlVector::ShiftElementsLeft( int elem, int num ) -{ - Assert( IsValidIndex(elem) || ( m_Size == 0 ) || ( num == 0 )); - int numToMove = m_Size - elem - num; - if ((numToMove > 0) && (num > 0)) - { - memmove( &Element(elem), &Element(elem+num), numToMove * sizeof(T) ); - -#ifdef _DEBUG - memset( &Element(m_Size-num), 0xDD, num * sizeof(T) ); -#endif - } -} - -//----------------------------------------------------------------------------- -// Adds an element, uses default constructor -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::AddToHead() -{ - return InsertBefore(0); -} - -template< class T > -inline int CUtlVector::AddToTail() -{ - return InsertBefore( m_Size ); -} - -template< class T > -inline int CUtlVector::InsertAfter( int elem ) -{ - return InsertBefore( elem + 1 ); -} - -template< class T > -int CUtlVector::InsertBefore( int elem ) -{ - // Can insert at the end - Assert( (elem == Count()) || IsValidIndex(elem) ); - - GrowVector(); - ShiftElementsRight(elem); - Construct( &Element(elem) ); - return elem; -} - - -//----------------------------------------------------------------------------- -// Adds an element, uses copy constructor -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::AddToHead( T const& src ) -{ - return InsertBefore( 0, src ); -} - -template< class T > -inline int CUtlVector::AddToTail( T const& src ) -{ - return InsertBefore( m_Size, src ); -} - -template< class T > -inline int CUtlVector::InsertAfter( int elem, T const& src ) -{ - return InsertBefore( elem + 1, src ); -} - -template< class T > -int CUtlVector::InsertBefore( int elem, T const& src ) -{ - // Can insert at the end - Assert( (elem == Count()) || IsValidIndex(elem) ); - - GrowVector(); - ShiftElementsRight(elem); - CopyConstruct( &Element(elem), src ); - return elem; -} - - -//----------------------------------------------------------------------------- -// Adds multiple elements, uses default constructor -//----------------------------------------------------------------------------- - -template< class T > -inline int CUtlVector::AddMultipleToHead( int num ) -{ - return InsertMultipleBefore( 0, num ); -} - -template< class T > -inline int CUtlVector::AddMultipleToTail( int num, const T *pToCopy ) -{ - return InsertMultipleBefore( m_Size, num, pToCopy ); -} - -template< class T > -int CUtlVector::InsertMultipleAfter( int elem, int num ) -{ - return InsertMultipleBefore( elem + 1, num ); -} - - -template< class T > -void CUtlVector::SetCount( int count ) -{ - RemoveAll(); - AddMultipleToTail( count ); -} - -template< class T > -inline void CUtlVector::SetSize( int size ) -{ - SetCount( size ); -} - -template< class T > -void CUtlVector::CopyArray( T const *pArray, int size ) -{ - SetSize( size ); - for( int i=0; i < size; i++ ) - (*this)[i] = pArray[i]; -} - -template< class T > -int CUtlVector::AddVectorToTail( CUtlVector const &src ) -{ - int base = Count(); - - // Make space. - AddMultipleToTail( src.Count() ); - - // Copy the elements. - for ( int i=0; i < src.Count(); i++ ) - (*this)[base + i] = src[i]; - - return base; -} - -template< class T > -inline int CUtlVector::InsertMultipleBefore( int elem, int num, const T *pToInsert ) -{ - if( num == 0 ) - return elem; - - // Can insert at the end - Assert( (elem == Count()) || IsValidIndex(elem) ); - - GrowVector(num); - ShiftElementsRight(elem, num); - - // Invoke default constructors - for (int i = 0; i < num; ++i) - Construct( &Element(elem+i) ); - - // Copy stuff in? - if ( pToInsert ) - { - for ( int i=0; i < num; i++ ) - { - Element( elem+i ) = pToInsert[i]; - } - } - - return elem; -} - -//----------------------------------------------------------------------------- -// Finds an element (element needs operator== defined) -//----------------------------------------------------------------------------- -template< class T > -int CUtlVector::Find( T const& src ) const -{ - for ( int i = 0; i < Count(); ++i ) - { - if (Element(i) == src) - return i; - } - return -1; -} - -template< class T > -bool CUtlVector::HasElement( T const& src ) -{ - return ( Find(src) >= 0 ); -} - -//----------------------------------------------------------------------------- -// Element removal -//----------------------------------------------------------------------------- - -template< class T > -void CUtlVector::FastRemove( int elem ) -{ - Assert( IsValidIndex(elem) ); - - Destruct( &Element(elem) ); - if (m_Size > 0) - { - memcpy( &Element(elem), &Element(m_Size-1), sizeof(T) ); - --m_Size; - } -} - -template< class T > -void CUtlVector::Remove( int elem ) -{ - Destruct( &Element(elem) ); - ShiftElementsLeft(elem); - --m_Size; -} - -template< class T > -void CUtlVector::FindAndRemove( T const& src ) -{ - int elem = Find( src ); - if ( elem != -1 ) - { - Remove( elem ); - } -} - -template< class T > -void CUtlVector::RemoveMultiple( int elem, int num ) -{ - Assert( IsValidIndex(elem) ); - Assert( elem + num <= Count() ); - - for (int i = elem + num; --i >= elem; ) - Destruct(&Element(i)); - - ShiftElementsLeft(elem, num); - m_Size -= num; -} - -template< class T > -void CUtlVector::RemoveAll() -{ - for (int i = m_Size; --i >= 0; ) - Destruct(&Element(i)); - - m_Size = 0; -} - - -//----------------------------------------------------------------------------- -// Memory deallocation -//----------------------------------------------------------------------------- - -template< class T > -void CUtlVector::Purge() -{ - RemoveAll(); - m_Memory.Purge( ); - ResetDbgInfo(); -} - - -template -inline void CUtlVector::PurgeAndDeleteElements() -{ - for( int i=0; i < m_Size; i++ ) - delete Element(i); - - Purge(); -} - - -template< class T > -void CUtlVector::SetGrowSize( int size ) -{ - m_Memory.SetGrowSize( size ); -} - - -#endif//UTLVECTOR_H \ No newline at end of file diff --git a/engine/client/vgui/vgui_draw.c b/engine/client/vgui/vgui_draw.c index fc7c6db1..a8db6252 100644 --- a/engine/client/vgui/vgui_draw.c +++ b/engine/client/vgui/vgui_draw.c @@ -19,10 +19,8 @@ GNU General Public License for more details. #include "vgui_draw.h" convar_t *vgui_colorstrings; -convar_t *vgui_emulatemouse; int g_textures[VGUI_MAX_TEXTURES]; int g_textureId = 0; -int g_iBoundTexture; /* ================ @@ -34,17 +32,16 @@ Startup VGUI backend void VGUI_DrawInit( void ) { memset( g_textures, 0, sizeof( g_textures )); - g_textureId = g_iBoundTexture = 0; + g_textureId = 0; vgui_colorstrings = Cvar_Get( "vgui_colorstrings", "0", FCVAR_ARCHIVE, "allow colorstrings in VGUI texts" ); - vgui_emulatemouse = Cvar_Get( "vgui_emulatemouse", "0", FCVAR_ARCHIVE, "emulate system cursor" ); } /* ================ VGUI_DrawShutdown -Release all textures +Release all the textures ================ */ void VGUI_DrawShutdown( void ) @@ -53,7 +50,7 @@ void VGUI_DrawShutdown( void ) for( i = 1; i < g_textureId; i++ ) { - GL_FreeImage( va( "*vgui%i", i )); + GL_FreeImage( va( "*vgui%i", i )); } } @@ -100,53 +97,15 @@ void VGUI_UploadTexture( int id, const char *buffer, int width, int height ) r_image.buffer = (byte *)buffer; g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE, false ); - g_iBoundTexture = id; } /* ================ -VGUI_CreateTexture +VGUI_SetupDrawingRect -Create empty rgba texture and upload them into video memory +setup transparency etc ================ */ -void VGUI_CreateTexture( int id, int width, int height ) -{ - rgbdata_t r_image; - char texName[32]; - - if( id <= 0 || id >= VGUI_MAX_TEXTURES ) - { - MsgDev( D_ERROR, "VGUI_CreateTexture: bad texture %i. Ignored\n", id ); - return; - } - - Q_snprintf( texName, sizeof( texName ), "*vgui%i", id ); - memset( &r_image, 0, sizeof( r_image )); - - r_image.width = width; - r_image.height = height; - r_image.type = PF_RGBA_32; - r_image.size = r_image.width * r_image.height * 4; - r_image.flags = IMAGE_HAS_ALPHA; - r_image.buffer = NULL; - - g_textures[id] = GL_LoadTextureInternal( texName, &r_image, TF_IMAGE|TF_NEAREST, false ); - g_iBoundTexture = id; -} - -void VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ) -{ - if( id <= 0 || id >= VGUI_MAX_TEXTURES || g_textures[id] == 0 || g_textures[id] == tr.whiteTexture ) - { - MsgDev( D_ERROR, "VGUI_UploadTextureBlock: bad texture %i. Ignored\n", id ); - return; - } - - pglTexSubImage2D( GL_TEXTURE_2D, 0, drawX, drawY, blockWidth, blockHeight, GL_RGBA, GL_UNSIGNED_BYTE, rgba ); - g_iBoundTexture = id; -} - void VGUI_SetupDrawingRect( int *pColor ) { pglEnable( GL_BLEND ); @@ -155,15 +114,13 @@ void VGUI_SetupDrawingRect( int *pColor ) pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); } -void VGUI_SetupDrawingText( int *pColor ) -{ - pglEnable( GL_BLEND ); - pglEnable( GL_ALPHA_TEST ); - pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); - pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); -} +/* +================ +VGUI_SetupDrawingImage +setup transparency etc +================ +*/ void VGUI_SetupDrawingImage( int *pColor ) { pglEnable( GL_BLEND ); @@ -173,42 +130,26 @@ void VGUI_SetupDrawingImage( int *pColor ) pglColor4ub( pColor[0], pColor[1], pColor[2], 255 - pColor[3] ); } +/* +================ +VGUI_BindTexture + +bind VGUI texture through private index +================ +*/ void VGUI_BindTexture( int id ) { if( id > 0 && id < VGUI_MAX_TEXTURES && g_textures[id] ) { GL_Bind( GL_TEXTURE0, g_textures[id] ); - g_iBoundTexture = id; } else { // NOTE: same as bogus index 2700 in GoldSrc - id = g_iBoundTexture = 1; - GL_Bind( GL_TEXTURE0, g_textures[id] ); + GL_Bind( GL_TEXTURE0, g_textures[1] ); } } -/* -================ -VGUI_GetTextureSizes - -returns wide and tall for currently binded texture -================ -*/ -void VGUI_GetTextureSizes( int *width, int *height ) -{ - gltexture_t *glt; - int texnum; - - if( g_iBoundTexture ) - texnum = g_textures[g_iBoundTexture]; - else texnum = tr.defaultTexture; - - glt = R_GetTexture( texnum ); - if( width ) *width = glt->srcWidth; - if( height ) *height = glt->srcHeight; -} - /* ================ VGUI_EnableTexture @@ -231,9 +172,6 @@ generic method to fill rectangle */ void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ) { - Assert( ul != NULL ); - Assert( lr != NULL ); - pglBegin( GL_QUADS ); pglTexCoord2f( ul->coord[0], ul->coord[1] ); pglVertex2f( ul->point[0], ul->point[1] ); @@ -247,4 +185,34 @@ void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ) pglTexCoord2f( ul->coord[0], lr->coord[1] ); pglVertex2f( ul->point[0], lr->point[1] ); pglEnd(); +} + +/* +================ +VGUI_DrawBuffer + +render the quads array +================ +*/ +void VGUI_DrawBuffer( const vpoint_t *buffer, int numVerts ) +{ + if( numVerts <= 0 ) return; + + pglEnable( GL_BLEND ); + pglEnable( GL_ALPHA_TEST ); + pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + + pglEnableClientState( GL_VERTEX_ARRAY ); + pglEnableClientState( GL_TEXTURE_COORD_ARRAY ); + pglEnableClientState( GL_COLOR_ARRAY ); + + pglTexCoordPointer( 2, GL_FLOAT, sizeof( vpoint_t ), &buffer->coord[0] ); + pglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( vpoint_t ), &buffer->color[0] ); + pglVertexPointer( 2, GL_FLOAT, sizeof( vpoint_t ), &buffer->point[0] ); + pglDrawArrays( GL_QUADS, 0, numVerts ); + + pglDisableClientState( GL_VERTEX_ARRAY ); + pglDisableClientState( GL_TEXTURE_COORD_ARRAY ); + pglDisableClientState( GL_COLOR_ARRAY ); } \ No newline at end of file diff --git a/engine/client/vgui/vgui_draw.h b/engine/client/vgui/vgui_draw.h index 597073c3..59e69586 100644 --- a/engine/client/vgui/vgui_draw.h +++ b/engine/client/vgui/vgui_draw.h @@ -30,6 +30,7 @@ typedef struct { vec2_t point; vec2_t coord; + byte color[4]; } vpoint_t; // @@ -38,17 +39,14 @@ typedef struct void VGUI_DrawInit( void ); void VGUI_DrawShutdown( void ); -void VGUI_SetupDrawingText( int *pColor ); void VGUI_SetupDrawingRect( int *pColor ); void VGUI_SetupDrawingImage( int *pColor ); void VGUI_BindTexture( int id ); void VGUI_EnableTexture( qboolean enable ); -void VGUI_CreateTexture( int id, int width, int height ); void VGUI_UploadTexture( int id, const char *buffer, int width, int height ); -void VGUI_UploadTextureBlock( int id, int drawX, int drawY, const byte *rgba, int blockWidth, int blockHeight ); LONG VGUI_SurfaceWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); void VGUI_DrawQuad( const vpoint_t *ul, const vpoint_t *lr ); -void VGUI_GetTextureSizes( int *width, int *height ); +void VGUI_DrawBuffer( const vpoint_t *buffer, int numVerts ); int VGUI_GenerateTexture( void ); void *VGui_GetPanel( void ); diff --git a/engine/client/vgui/vgui_font.cpp b/engine/client/vgui/vgui_font.cpp deleted file mode 100644 index 2293a1b0..00000000 --- a/engine/client/vgui/vgui_font.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* -vgui_font.cpp - fonts management -Copyright (C) 2011 Uncle Mike - -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 3 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. -*/ - -#include "common.h" -#include "vgui_draw.h" -#include "vgui_main.h" - -int FontCache::s_pFontPageSize[FONT_PAGE_SIZE_COUNT] = { 16, 32, 64, 128 }; - -FontCache::FontCache() : m_CharCache( 0, 256, CacheEntryLessFunc ) -{ - CacheEntry_t listHead = { 0, 0 }; - - m_LRUListHeadIndex = m_CharCache.Insert( listHead ); - m_CharCache[m_LRUListHeadIndex].nextEntry = m_LRUListHeadIndex; - m_CharCache[m_LRUListHeadIndex].prevEntry = m_LRUListHeadIndex; - - for( int i = 0; i < FONT_PAGE_SIZE_COUNT; i++ ) - { - m_pCurrPage[i] = -1; - } -} - -bool FontCache::CacheEntryLessFunc( CacheEntry_t const &lhs, CacheEntry_t const &rhs ) -{ - if( lhs.font < rhs.font ) - return true; - else if( lhs.font > rhs.font ) - return false; - - return ( lhs.ch < rhs.ch ); -} - -bool FontCache::GetTextureForChar( Font *font, char ch, int *textureID, float **texCoords ) -{ - static CacheEntry_t cacheitem; - - cacheitem.font = font; - cacheitem.ch = ch; - - Assert( texCoords != NULL ); - - *texCoords = cacheitem.texCoords; - - HCacheEntry cacheHandle = m_CharCache.Find( cacheitem ); - - if( m_CharCache.IsValidIndex( cacheHandle )) - { - // we have an entry already, return that - int page = m_CharCache[cacheHandle].page; - *textureID = m_PageList[page].textureID; - *texCoords = m_CharCache[cacheHandle].texCoords; - return true; - } - - // get the char details - int fontTall = font->getTall(); - int a, b, c; - font->getCharABCwide( (byte)ch, a, b, c ); - int fontWide = b; - - // get a texture to render into - int page, drawX, drawY, twide, ttall; - if( !AllocatePageForChar( fontWide, fontTall, page, drawX, drawY, twide, ttall )) - return false; - - // create a buffer and render the character into it - int nByteCount = s_pFontPageSize[FONT_PAGE_SIZE_COUNT-1] * s_pFontPageSize[FONT_PAGE_SIZE_COUNT-1] * 4; - byte * rgba = (byte *)Z_Malloc( nByteCount ); - font->getCharRGBA( (byte)ch, 0, 0, fontWide, fontTall, rgba ); - - // upload the new sub texture - VGUI_BindTexture( m_PageList[page].textureID ); - VGUI_UploadTextureBlock( m_PageList[page].textureID, drawX, drawY, rgba, fontWide, fontTall ); - - // set the cache info - cacheitem.page = page; - - cacheitem.texCoords[0] = (float)((double)drawX / ((double)twide)); - cacheitem.texCoords[1] = (float)((double)drawY / ((double)ttall)); - cacheitem.texCoords[2] = (float)((double)(drawX + fontWide) / (double)twide); - cacheitem.texCoords[3] = (float)((double)(drawY + fontTall) / (double)ttall); - - m_CharCache.Insert( cacheitem ); - - // return the data - *textureID = m_PageList[page].textureID; - // memcpy( texCoords, cacheitem.texCoords, sizeof( float ) * 4 ); - return true; -} - -int FontCache::ComputePageType( int charTall ) const -{ - for( int i = 0; i < FONT_PAGE_SIZE_COUNT; i++ ) - { - if( charTall < s_pFontPageSize[i] ) - return i; - } - return -1; -} - -bool FontCache::AllocatePageForChar( int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall ) -{ - // see if there is room in the last page for this character - int nPageType = ComputePageType( charTall ); - pageIndex = m_pCurrPage[nPageType]; - - int nNextX = 0; - bool bNeedsNewPage = true; - - if( pageIndex > -1 ) - { - Page_t &page = m_PageList[pageIndex]; - - nNextX = page.nextX + charWide; - - // make sure we have room on the current line of the texture page - if( nNextX > page.wide ) - { - // move down a line - page.nextX = 0; - nNextX = charWide; - page.nextY += page.fontHeight + 1; - } - - bNeedsNewPage = (( page.nextY + page.fontHeight + 1 ) > page.tall ); - } - - if( bNeedsNewPage ) - { - // allocate a new page - pageIndex = m_PageList.AddToTail(); - Page_t &newPage = m_PageList[pageIndex]; - m_pCurrPage[nPageType] = pageIndex; - - newPage.textureID = VGUI_GenerateTexture(); - - newPage.fontHeight = s_pFontPageSize[nPageType]; - newPage.wide = 256; - newPage.tall = 256; - newPage.nextX = 0; - newPage.nextY = 0; - - nNextX = charWide; - - // create empty texture - VGUI_CreateTexture( newPage.textureID, 256, 256 ); - } - - // output the position - Page_t &page = m_PageList[pageIndex]; - drawX = page.nextX; - drawY = page.nextY; - twide = page.wide; - ttall = page.tall; - - // update the next position to draw in - page.nextX = nNextX + 1; - - return true; -} \ No newline at end of file diff --git a/engine/client/vgui/vgui_int.cpp b/engine/client/vgui/vgui_int.cpp index 80a1af7c..723ec092 100644 --- a/engine/client/vgui/vgui_int.cpp +++ b/engine/client/vgui/vgui_int.cpp @@ -57,10 +57,7 @@ void VGui_RunFrame( void ) void VGui_SetRootPanelSize( void ) { if( rootPanel != NULL ) - { rootPanel->setBounds( 0, 0, gameui.globals->scrWidth, gameui.globals->scrHeight ); -// rootPanel->setSize( gameui.globals->scrWidth, gameui.globals->scrHeight ); - } } void VGui_Startup( void ) diff --git a/engine/client/vgui/vgui_main.h b/engine/client/vgui/vgui_main.h index 42e4b0bf..1eb15fcf 100644 --- a/engine/client/vgui/vgui_main.h +++ b/engine/client/vgui/vgui_main.h @@ -16,9 +16,6 @@ GNU General Public License for more details. #ifndef VGUI_MAIN_H #define VGUI_MAIN_H -#include "utlvector.h" -#include "utlrbtree.h" - #include #include #include @@ -31,106 +28,36 @@ GNU General Public License for more details. using namespace vgui; -class FontCache +struct PaintStack { -public: - FontCache(); - ~FontCache() { } - - // returns a texture ID and a pointer to an array of 4 texture coords for the given character & font - // uploads more texture if necessary - bool GetTextureForChar( Font *font, char ch, int *textureID, float **texCoords ); -private: - // NOTE: If you change this, change s_pFontPageSize - enum - { - FONT_PAGE_SIZE_16, - FONT_PAGE_SIZE_32, - FONT_PAGE_SIZE_64, - FONT_PAGE_SIZE_128, - FONT_PAGE_SIZE_COUNT, - }; - - // a single character in the cache - typedef unsigned short HCacheEntry; - struct CacheEntry_t - { - Font *font; - char ch; - byte page; - float texCoords[4]; - - HCacheEntry nextEntry; // doubly-linked list for use in the LRU - HCacheEntry prevEntry; - }; - - // a single texture page - struct Page_t - { - short textureID; - short fontHeight; - short wide, tall; // total size of the page - short nextX, nextY; // position to draw any new character positions - }; - - // allocates a new page for a given character - bool AllocatePageForChar( int charWide, int charTall, int &pageIndex, int &drawX, int &drawY, int &twide, int &ttall ); - - // Computes the page size given a character height - int ComputePageType( int charTall ) const; - - static bool CacheEntryLessFunc( const CacheEntry_t &lhs, const CacheEntry_t &rhs ); - - // cache - typedef CUtlVector FontPageList_t; - - CUtlRBTree m_CharCache; - FontPageList_t m_PageList; - int m_pCurrPage[FONT_PAGE_SIZE_COUNT]; - HCacheEntry m_LRUListHeadIndex; - - static int s_pFontPageSize[FONT_PAGE_SIZE_COUNT]; + Panel *m_pPanel; + int iTranslateX; + int iTranslateY; + int iScissorLeft; + int iScissorRight; + int iScissorTop; + int iScissorBottom; }; class CEngineSurface : public SurfaceBase { private: - struct paintState_t - { - Panel *m_pPanel; - int iTranslateX; - int iTranslateY; - int iScissorLeft; - int iScissorRight; - int iScissorTop; - int iScissorBottom; - }; - - // point translation for current panel - int _translateX; - int _translateY; - - // the size of the window to draw into - int _surfaceExtents[4]; - - CUtlVector _paintStack; - - void SetupPaintState( const paintState_t &paintState ); void InitVertex( vpoint_t &vertex, int x, int y, float u, float v ); public: CEngineSurface( Panel *embeddedPanel ); ~CEngineSurface(); public: - virtual Panel *getEmbeddedPanel( void ); - virtual bool setFullscreenMode( int wide, int tall, int bpp ); - virtual void setWindowedMode( void ); + // not used in engine instance + virtual bool setFullscreenMode( int wide, int tall, int bpp ) { return false; } + virtual void setWindowedMode( void ) { } virtual void setTitle( const char *title ) { } virtual void createPopup( Panel* embeddedPanel ) { } virtual bool isWithin( int x, int y ) { return true; } + void SetupPaintState( const PaintStack *paintState ); #ifdef NEW_VGUI_DLL - virtual void GetMousePos( int &x, int &y ); + virtual void GetMousePos( int &x, int &y ) { } #endif - virtual bool hasFocus( void ); + virtual bool hasFocus( void ) { return true; } protected: virtual int createNewTextureID( void ); virtual void drawSetColor( int r, int g, int b, int a ); @@ -143,37 +70,37 @@ protected: virtual void drawSetTextureRGBA( int id, const char* rgba, int wide, int tall ); virtual void drawSetTexture( int id ); virtual void drawTexturedRect( int x0, int y0, int x1, int y1 ); - virtual bool createPlat( void ) { return false; } - virtual bool recreateContext( void ) { return false; } + virtual void drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] ); + virtual void addCharToBuffer( const vpoint_t *ul, const vpoint_t *lr, int color[4] ); virtual void setCursor( Cursor* cursor ); virtual void pushMakeCurrent( Panel* panel, bool useInsets ); virtual void popMakeCurrent( Panel* panel ); - // not used in engine instance + virtual bool createPlat( void ) { return false; } + virtual bool recreateContext( void ) { return false; } virtual void enableMouseCapture( bool state ) { } virtual void invalidate( Panel *panel ) { } virtual void setAsTopMost( bool state ) { } virtual void applyChanges( void ) { } virtual void swapBuffers( void ) { } + virtual void flushBuffer( void ); protected: - Font* _hCurrentFont; - Cursor* _hCurrentCursor; int _drawTextPos[2]; int _drawColor[4]; int _drawTextColor[4]; - friend class App; - friend class Panel; + int _translateX, _translateY; + int _currentTexture; }; // initialize VGUI::App as external (part of engine) class CEngineApp : public App { public: - virtual void main( int argc, char* argv[] ) { } // stub + virtual void main( int argc, char* argv[] ) { } virtual void setCursorPos( int x, int y ); // we need to recompute abs position to window virtual void getCursorPos( int &x,int &y ); protected: - virtual void platTick(void) { } // stub + virtual void platTick(void) { } }; extern Panel *rootPanel; diff --git a/engine/client/vgui/vgui_surf.cpp b/engine/client/vgui/vgui_surf.cpp index df6f1d77..092cc8b3 100644 --- a/engine/client/vgui/vgui_surf.cpp +++ b/engine/client/vgui/vgui_surf.cpp @@ -18,19 +18,43 @@ GNU General Public License for more details. #include "vgui_draw.h" #include "vgui_main.h" -static FontCache g_FontCache; +#define MAXVERTEXBUFFERS 1024 +#define MAX_PAINT_STACK 8 +#define FONT_SIZE 512 +#define FONT_PAGES 8 + +static char staticRGBA[FONT_SIZE * FONT_SIZE * 4]; +static vpoint_t g_VertexBuffer[MAXVERTEXBUFFERS]; +static int g_iVertexBufferEntriesUsed = 0; +static int staticContextCount = 0; + +struct FontInfo +{ + int id; + int pageCount; + int pageForChar[256]; + int bindIndex[FONT_PAGES]; + float texCoord[256][FONT_PAGES]; + int contextCount; +}; + +static Font* staticFont = NULL; +static FontInfo* staticFontInfo; +static Dar staticFontInfoDar; +static PaintStack paintStack[MAX_PAINT_STACK]; +static staticPaintStackPos = 0; CEngineSurface :: CEngineSurface( Panel *embeddedPanel ):SurfaceBase( embeddedPanel ) { - _embeddedPanel = embeddedPanel; - _drawColor[0] = _drawColor[1] = _drawColor[2] = _drawColor[3] = 255; _drawTextColor[0] = _drawTextColor[1] = _drawTextColor[2] = _drawTextColor[3] = 255; + _drawColor[0] = _drawColor[1] = _drawColor[2] = _drawColor[3] = 255; + _drawTextPos[0] = _drawTextPos[1] = _currentTexture = 0; - _surfaceExtents[0] = _surfaceExtents[1] = 0; - _surfaceExtents[2] = gameui.globals->scrWidth; - _surfaceExtents[3] = gameui.globals->scrHeight; - _drawTextPos[0] = _drawTextPos[1] = 0; - _hCurrentFont = null; + staticFont = NULL; + staticFontInfo = NULL; + staticFontInfoDar.setCount( 0 ); + staticPaintStackPos = 0; + staticContextCount++; VGUI_InitCursors (); } @@ -39,16 +63,6 @@ CEngineSurface :: ~CEngineSurface( void ) { VGUI_DrawShutdown (); } - -Panel *CEngineSurface :: getEmbeddedPanel( void ) -{ - return _embeddedPanel; -} - -bool CEngineSurface :: hasFocus( void ) -{ - return host.state != HOST_NOFOCUS; -} void CEngineSurface :: setCursor( Cursor *cursor ) { @@ -56,25 +70,11 @@ void CEngineSurface :: setCursor( Cursor *cursor ) VGUI_CursorSelect( cursor ); } -#ifdef NEW_VGUI_DLL -void CEngineSurface :: GetMousePos( int &x, int &y ) +void CEngineSurface :: SetupPaintState( const PaintStack *paintState ) { - POINT curpos; - - GetCursorPos( &curpos ); - ScreenToClient( host.hWnd, &curpos ); - - x = curpos.x; - y = curpos.y; -} -#endif - -void CEngineSurface :: SetupPaintState( const paintState_t &paintState ) -{ - _translateX = paintState.iTranslateX; - _translateY = paintState.iTranslateY; - SetScissorRect( paintState.iScissorLeft, paintState.iScissorTop, - paintState.iScissorRight, paintState.iScissorBottom ); + _translateX = paintState->iTranslateX; + _translateY = paintState->iTranslateY; + SetScissorRect( paintState->iScissorLeft, paintState->iScissorTop, paintState->iScissorRight, paintState->iScissorBottom ); } void CEngineSurface :: InitVertex( vpoint_t &vertex, int x, int y, float u, float v ) @@ -138,7 +138,101 @@ void CEngineSurface :: drawOutlinedRect( int x0, int y0, int x1, int y1 ) void CEngineSurface :: drawSetTextFont( Font *font ) { - _hCurrentFont = font; + staticFont = font; + + if( font ) + { + bool buildFont = false; + + staticFontInfo = NULL; + + for( int i = 0; i < staticFontInfoDar.getCount(); i++ ) + { + if( staticFontInfoDar[i]->id == font->getId( )) + { + staticFontInfo = staticFontInfoDar[i]; + if( staticFontInfo->contextCount != staticContextCount ) + buildFont = true; + } + } + + if( !staticFontInfo || buildFont ) + { + staticFontInfo = new FontInfo; + staticFontInfo->id = 0; + staticFontInfo->pageCount = 0; + staticFontInfo->bindIndex[0] = 0; + staticFontInfo->bindIndex[1] = 0; + staticFontInfo->bindIndex[2] = 0; + staticFontInfo->bindIndex[3] = 0; + memset( staticFontInfo->pageForChar, 0, sizeof( staticFontInfo->pageForChar )); + staticFontInfo->contextCount = -1; + staticFontInfo->id = staticFont->getId(); + staticFontInfoDar.putElement( staticFontInfo ); + staticFontInfo->contextCount = staticContextCount; + + int currentPage = 0; + int x = 0, y = 0; + + memset( staticRGBA, 0, sizeof( staticRGBA )); + + for( int i = 0; i < 256; i++ ) + { + int abcA, abcB, abcC; + staticFont->getCharABCwide( i, abcA, abcB, abcC ); + + int wide = abcB; + + if( isspace( i )) continue; + + int tall = staticFont->getTall(); + + if( x + wide + 1 > FONT_SIZE ) + { + x = 0; + y += tall + 1; + } + + if( y + tall + 1 > FONT_SIZE ) + { + if( !staticFontInfo->bindIndex[currentPage] ) + { + int bindIndex = createNewTextureID(); + staticFontInfo->bindIndex[currentPage] = bindIndex; + } + + drawSetTextureRGBA( staticFontInfo->bindIndex[currentPage], staticRGBA, FONT_SIZE, FONT_SIZE ); + currentPage++; + + if( currentPage == FONT_PAGES ) + break; + + memset( staticRGBA, 0, sizeof( staticRGBA )); + x = y = 0; + } + + staticFont->getCharRGBA( i, x, y, FONT_SIZE, FONT_SIZE, (byte *)staticRGBA ); + staticFontInfo->pageForChar[i] = currentPage; + staticFontInfo->texCoord[i][0] = (float)((double)x / (double)FONT_SIZE ); + staticFontInfo->texCoord[i][1] = (float)((double)y / (double)FONT_SIZE ); + staticFontInfo->texCoord[i][2] = (float)((double)(x + wide)/(double)FONT_SIZE ); + staticFontInfo->texCoord[i][3] = (float)((double)(y + tall)/(double)FONT_SIZE ); + x += wide + 1; + } + + if( currentPage != FONT_PAGES ) + { + if( !staticFontInfo->bindIndex[currentPage] ) + { + int bindIndex = createNewTextureID(); + staticFontInfo->bindIndex[currentPage] = bindIndex; + } + + drawSetTextureRGBA( staticFontInfo->bindIndex[currentPage], staticRGBA, FONT_SIZE, FONT_SIZE ); + } + staticFontInfo->pageCount = currentPage + 1; + } + } } void CEngineSurface :: drawSetTextPos( int x, int y ) @@ -147,31 +241,109 @@ void CEngineSurface :: drawSetTextPos( int x, int y ) _drawTextPos[1] = y; } -void CEngineSurface :: drawPrintText( const char* text, int textLen ) +void CEngineSurface :: addCharToBuffer( const vpoint_t *ul, const vpoint_t *lr, int color[4] ) +{ + if( g_iVertexBufferEntriesUsed >= MAXVERTEXBUFFERS ) + flushBuffer(); + + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].coord[0] = ul->coord[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].coord[1] = ul->coord[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].point[0] = ul->point[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].point[1] = ul->point[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[0] = color[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[1] = color[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[2] = color[2]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 0].color[3] = 255 - color[3]; + + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].coord[0] = lr->coord[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].coord[1] = ul->coord[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].point[0] = lr->point[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].point[1] = ul->point[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[0] = color[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[1] = color[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[2] = color[2]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 1].color[3] = 255 - color[3]; + + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].coord[0] = lr->coord[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].coord[1] = lr->coord[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].point[0] = lr->point[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].point[1] = lr->point[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[0] = color[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[1] = color[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[2] = color[2]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 2].color[3] = 255 - color[3]; + + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].coord[0] = ul->coord[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].coord[1] = lr->coord[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].point[0] = ul->point[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].point[1] = lr->point[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[0] = color[0]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[1] = color[1]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[2] = color[2]; + g_VertexBuffer[g_iVertexBufferEntriesUsed + 3].color[3] = 255 - color[3]; + + g_iVertexBufferEntriesUsed += 4; +} + +void CEngineSurface :: flushBuffer( void ) +{ + if( g_iVertexBufferEntriesUsed <= 0 ) + return; + + VGUI_DrawBuffer( g_VertexBuffer, g_iVertexBufferEntriesUsed ); + g_iVertexBufferEntriesUsed = 0; +} + +void CEngineSurface :: drawPrintChar( int x, int y, int wide, int tall, float s0, float t0, float s1, float t1, int color[4] ) +{ + vpoint_t ul, lr; + + ul.point[0] = x; + ul.point[1] = y; + lr.point[0] = x + wide; + lr.point[1] = y + tall; + + // gets at the texture coords for this character in its texture page + ul.coord[0] = s0; + ul.coord[1] = t0; + lr.coord[0] = s1; + lr.coord[1] = t1; + + vpoint_t clippedRect[2]; + + if( !ClipRect( ul, lr, &clippedRect[0], &clippedRect[1] )) + return; +#if 1 + // TESTTEST: needs to be more tested + addCharToBuffer( &clippedRect[0], &clippedRect[1], color ); +#else + VGUI_SetupDrawingImage( color ); + VGUI_DrawQuad( &clippedRect[0], &clippedRect[1] ); // draw the letter +#endif +} + +void CEngineSurface :: drawPrintText( const char *text, int textLen ) { static bool hasColor = 0; static int numColor = 7; - if( !text || !_hCurrentFont || _drawTextColor[3] >= 255 ) + if( !text || !staticFont || !staticFontInfo ) return; int x = _drawTextPos[0] + _translateX; int y = _drawTextPos[1] + _translateY; - - int iTall = _hCurrentFont->getTall(); - - int j, iTotalWidth = 0; + int tall = staticFont->getTall(); int curTextColor[4]; // HACKHACK: allow color strings in VGUI if( numColor != 7 && vgui_colorstrings->value ) { - for( j = 0; j < 3; j++ ) // grab predefined color + for( int j = 0; j < 3; j++ ) // grab predefined color curTextColor[j] = g_color_table[numColor][j]; } else { - for( j = 0; j < 3; j++ ) // revert default color + for( int j = 0; j < 3; j++ ) // revert default color curTextColor[j] = _drawTextColor[j]; } curTextColor[3] = _drawTextColor[3]; // copy alpha @@ -194,61 +366,38 @@ void CEngineSurface :: drawPrintText( const char* text, int textLen ) for( int i = 0; i < textLen; i++ ) { - char ch = text[i]; + int abcA, abcB, abcC; + int curCh = (byte)text[i]; - int abcA,abcB,abcC; - _hCurrentFont->getCharABCwide( ch, abcA, abcB, abcC ); + staticFont->getCharABCwide( curCh, abcA, abcB, abcC ); - iTotalWidth += abcA; - int iWide = abcB; + float s0 = staticFontInfo->texCoord[curCh][0]; + float t0 = staticFontInfo->texCoord[curCh][1]; + float s1 = staticFontInfo->texCoord[curCh][2]; + float t1 = staticFontInfo->texCoord[curCh][3]; + int wide = abcB; - if( !iswspace( ch )) - { - // get the character texture from the cache - int iTexId = 0; - float *texCoords = NULL; - - if( !g_FontCache.GetTextureForChar( _hCurrentFont, ch, &iTexId, &texCoords )) - continue; - - Assert( texCoords != NULL ); - - vpoint_t ul, lr; - - ul.point[0] = x + iTotalWidth; - ul.point[1] = y; - lr.point[0] = ul.point[0] + iWide; - lr.point[1] = ul.point[1] + iTall; - - // gets at the texture coords for this character in its texture page - ul.coord[0] = texCoords[0]; - ul.coord[1] = texCoords[1]; - lr.coord[0] = texCoords[2]; - lr.coord[1] = texCoords[3]; - - vpoint_t clippedRect[2]; - - if( !ClipRect( ul, lr, &clippedRect[0], &clippedRect[1] )) - continue; - - drawSetTexture( iTexId ); - VGUI_SetupDrawingText( curTextColor ); - VGUI_DrawQuad( &clippedRect[0], &clippedRect[1] ); // draw the letter - } - - iTotalWidth += iWide + abcC; + drawSetTexture( staticFontInfo->bindIndex[staticFontInfo->pageForChar[curCh]] ); + drawPrintChar( x, y, wide, tall, s0, t0, s1, t1, curTextColor ); + x += abcA + abcB + abcC; } - _drawTextPos[0] += iTotalWidth; + _drawTextPos[0] += x; } void CEngineSurface :: drawSetTextureRGBA( int id, const char* rgba, int wide, int tall ) { VGUI_UploadTexture( id, rgba, wide, tall ); + _currentTexture = id; } void CEngineSurface :: drawSetTexture( int id ) { + if( _currentTexture != id ) + { + _currentTexture = id; + flushBuffer(); + } VGUI_BindTexture( id ); } @@ -270,62 +419,47 @@ void CEngineSurface :: drawTexturedRect( int x0, int y0, int x1, int y1 ) void CEngineSurface :: pushMakeCurrent( Panel* panel, bool useInsets ) { - int inSets[4] = { 0, 0, 0, 0 }; + int insets[4] = { 0, 0, 0, 0 }; int absExtents[4]; int clipRect[4]; if( useInsets ) - { - panel->getInset( inSets[0], inSets[1], inSets[2], inSets[3] ); - } - + panel->getInset( insets[0], insets[1], insets[2], insets[3] ); panel->getAbsExtents( absExtents[0], absExtents[1], absExtents[2], absExtents[3] ); panel->getClipRect( clipRect[0], clipRect[1], clipRect[2], clipRect[3] ); - int i = _paintStack.AddToTail(); - paintState_t &paintState = _paintStack[i]; - paintState.m_pPanel = panel; + PaintStack *paintState = &paintStack[staticPaintStackPos]; + + ASSERT( staticPaintStackPos < MAX_PAINT_STACK ); + + paintState->m_pPanel = panel; // determine corrected top left origin - paintState.iTranslateX = inSets[0] + absExtents[0] - _surfaceExtents[0]; - paintState.iTranslateY = inSets[1] + absExtents[1] - _surfaceExtents[1]; - + paintState->iTranslateX = insets[0] + absExtents[0]; + paintState->iTranslateY = insets[1] + absExtents[1]; // setup clipping rectangle for scissoring - paintState.iScissorLeft = clipRect[0] - _surfaceExtents[0]; - paintState.iScissorTop = clipRect[1] - _surfaceExtents[1]; - paintState.iScissorRight = clipRect[2] - _surfaceExtents[0]; - paintState.iScissorBottom = clipRect[3] - _surfaceExtents[1]; + paintState->iScissorLeft = clipRect[0]; + paintState->iScissorTop = clipRect[1]; + paintState->iScissorRight = clipRect[2]; + paintState->iScissorBottom = clipRect[3]; SetupPaintState( paintState ); + staticPaintStackPos++; } void CEngineSurface :: popMakeCurrent( Panel *panel ) { - int top = _paintStack.Count() - 1; + flushBuffer(); + + int top = staticPaintStackPos - 1; // more pops that pushes? Assert( top >= 0 ); // didn't pop in reverse order of push? - Assert( _paintStack[top].m_pPanel == panel ); + Assert( paintStack[top]->m_pPanel == panel ); - _paintStack.Remove( top ); - - if( top > 0 ) SetupPaintState( _paintStack[top-1] ); -} + staticPaintStackPos--; -bool CEngineSurface :: setFullscreenMode( int wide, int tall, int bpp ) -{ - // NOTE: Xash3D always working in 32-bit mode - if( R_DescribeVIDMode( wide, tall )) - { - Cvar_SetValue( "fullscreen", 1.0f ); - return true; - } - return false; -} - -void CEngineSurface :: setWindowedMode( void ) -{ - Cvar_SetValue( "fullscreen", 0.0f ); + if( top > 0 ) SetupPaintState( &paintStack[top-1] ); } \ No newline at end of file diff --git a/engine/common/cfgscript.c b/engine/common/cfgscript.c new file mode 100644 index 00000000..4ed52a1f --- /dev/null +++ b/engine/common/cfgscript.c @@ -0,0 +1,341 @@ +/* +cfgscript.c - "Valve script" parsing routines +Copyright (C) 2016 mittorn + +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 3 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. +*/ + +#include "common.h" + +typedef enum +{ + T_NONE = 0, + T_BOOL, + T_NUMBER, + T_LIST, + T_STRING, + T_COUNT +} cvartype_t; + +char *cvartypes[] = { NULL, "BOOL" , "NUMBER", "LIST", "STRING" }; + +typedef struct parserstate_s +{ + char *buf; + char token[MAX_STRING]; + const char *filename; +} parserstate_t; + +typedef struct scrvardef_s +{ + char name[MAX_STRING]; + char value[MAX_STRING]; + char desc[MAX_STRING]; + float fMin, fMax; + cvartype_t type; + int flags; + qboolean fHandled; +} scrvardef_t; + +/* +=================== +CSCR_ExpectString + +Return true if next token is pExpext and skip it +=================== +*/ +qboolean CSCR_ExpectString( parserstate_t *ps, const char *pExpect, qboolean skip, qboolean error ) +{ + char *tmp = COM_ParseFile( ps->buf, ps->token ); + + if( !Q_stricmp( ps->token, pExpect ) ) + { + ps->buf = tmp; + return true; + } + + if( skip ) ps->buf = tmp; + if( error ) MsgDev( D_ERROR, "Syntax error in %s: got \"%s\" instead of \"%s\"\n", ps->filename, ps->token, pExpect ); + + return false; +} + +/* +=================== +CSCR_ParseType + +Determine script variable type +=================== +*/ +cvartype_t CSCR_ParseType( parserstate_t *ps ) +{ + int i; + + for( i = 1; i < T_COUNT; i++ ) + { + if( CSCR_ExpectString( ps, cvartypes[i], false, false )) + return i; + } + + MsgDev( D_ERROR, "Cannot parse %s: Bad type %s\n", ps->filename, ps->token ); + return T_NONE; +} + + + +/* +========================= +CSCR_ParseSingleCvar +========================= +*/ +qboolean CSCR_ParseSingleCvar( parserstate_t *ps, scrvardef_t *result ) +{ + // read the name + ps->buf = COM_ParseFile( ps->buf, result->name ); + + if( !CSCR_ExpectString( ps, "{", false, true )) + return false; + + // read description + ps->buf = COM_ParseFile( ps->buf, result->desc ); + + if( !CSCR_ExpectString( ps, "{", false, true )) + return false; + + result->type = CSCR_ParseType( ps ); + + switch( result->type ) + { + case T_BOOL: + // bool only has description + if( !CSCR_ExpectString( ps, "}", false, true )) + return false; + break; + case T_NUMBER: + // min + ps->buf = COM_ParseFile( ps->buf, ps->token ); + result->fMin = Q_atof( ps->token ); + + // max + ps->buf = COM_ParseFile( ps->buf, ps->token ); + result->fMax = Q_atof( ps->token ); + + if( !CSCR_ExpectString( ps, "}", false, true )) + return false; + break; + case T_STRING: + if( !CSCR_ExpectString( ps, "}", false, true )) + return false; + break; + case T_LIST: + while( !CSCR_ExpectString( ps, "}", true, false )) + { + // read token for each item here + } + break; + default: + return false; + } + + if( !CSCR_ExpectString( ps, "{", false, true )) + return false; + + // default value + ps->buf = COM_ParseFile( ps->buf, result->value ); + + if( !CSCR_ExpectString( ps, "}", false, true )) + return false; + + if( CSCR_ExpectString( ps, "SetInfo", false, false )) + result->flags |= FCVAR_USERINFO; + + if( !CSCR_ExpectString( ps, "}", false, true )) + return false; + + return true; +} + +/* +====================== +CSCR_ParseHeader + +Check version and seek to first cvar name +====================== +*/ +qboolean CSCR_ParseHeader( parserstate_t *ps ) +{ + if( !CSCR_ExpectString( ps, "VERSION", false, true )) + return false; + + // Parse in the version # + // Get the first token. + ps->buf = COM_ParseFile( ps->buf, ps->token ); + + if( Q_atof( ps->token ) != 1 ) + { + MsgDev( D_ERROR, "File %s has wrong version %s!\n", ps->filename, ps->token ); + return false; + } + + if( !CSCR_ExpectString( ps, "DESCRIPTION", false, true )) + return false; + + ps->buf = COM_ParseFile( ps->buf, ps->token ); + + if( Q_stricmp( ps->token, "INFO_OPTIONS") && Q_stricmp( ps->token, "SERVER_OPTIONS" )) + { + MsgDev( D_ERROR, "DESCRIPTION must be INFO_OPTIONS or SERVER_OPTIONS\n"); + return false; + } + + if( !CSCR_ExpectString( ps, "{", false, true )) + return false; + + return true; +} + +/* +====================== +CSCR_WriteGameCVars + +Print all cvars declared in script to game.cfg file +====================== +*/ +int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename ) +{ + parserstate_t state = { 0 }; + qboolean success = false; + int count = 0; + long length = 0; + char *start; + + state.filename = scriptfilename; + state.buf = start = (char *)FS_LoadFile( scriptfilename, &length, true ); + + if( !state.buf || !length ) + return 0; + + MsgDev( D_INFO, "Reading config script file %s\n", scriptfilename ); + + if( !CSCR_ParseHeader( &state )) + { + MsgDev( D_ERROR, "Failed to parse header!\n" ); + goto finish; + } + + FS_Printf( cfg, "// declared in %s:\n", scriptfilename ); + + while( !CSCR_ExpectString( &state, "}", false, false )) + { + scrvardef_t var = { 0 }; + + if( CSCR_ParseSingleCvar( &state, &var ) ) + { + convar_t *cvar = Cvar_FindVar( var.name ); + + if( cvar && !FBitSet( cvar->flags, FCVAR_SERVER|FCVAR_ARCHIVE )) + { + // cvars will be placed in game.cfg and restored on map start + if( var.flags & FCVAR_USERINFO ) + FS_Printf( cfg, "// %s ( %s )\nsetu %s \"%s\"\n", var.desc, var.value, var.name, cvar->string ); + else FS_Printf( cfg, "// %s ( %s )\nset %s \"%s\"\n", var.desc, var.value, var.name, cvar->string ); + } + count++; + } + else + { + break; + } + + if( count > 1024 ) + break; + } + + if( COM_ParseFile( state.buf, state.token )) + MsgDev( D_ERROR, "Got extra tokens!\n" ); + else success = true; +finish: + if( !success ) + { + state.token[sizeof( state.token ) - 1] = 0; + + if( start && state.buf ) + MsgDev( D_ERROR, "Parse error in %s, byte %d, token %s\n", scriptfilename, (int)( state.buf - start ), state.token ); + else MsgDev( D_ERROR, "Parse error in %s, token %s\n", scriptfilename, state.token ); + } + + if( start ) Mem_Free( start ); + + return count; +} + +/* +====================== +CSCR_LoadDefaultCVars + +Register all cvars declared in config file and set default values +====================== +*/ +int CSCR_LoadDefaultCVars( const char *scriptfilename ) +{ + parserstate_t state = { 0 }; + qboolean success = false; + int count = 0; + long length = 0; + char *start; + + state.filename = scriptfilename; + state.buf = start = (char *)FS_LoadFile( scriptfilename, &length, true ); + + if( !state.buf || !length ) + return 0; + + MsgDev( D_INFO, "Reading config script file %s\n", scriptfilename ); + + if( !CSCR_ParseHeader( &state )) + { + MsgDev( D_ERROR, "Failed to parse header!\n" ); + goto finish; + } + + while( !CSCR_ExpectString( &state, "}", false, false )) + { + scrvardef_t var = { 0 }; + + // Create a new object + if( CSCR_ParseSingleCvar( &state, &var ) ) + { + Cvar_Get( var.name, var.value, var.flags|FCVAR_TEMPORARY, var.desc ); + count++; + } + else + break; + + if( count > 1024 ) + break; + } + + if( COM_ParseFile( state.buf, state.token )) + MsgDev( D_ERROR, "Got extra tokens!\n" ); + else success = true; +finish: + if( !success ) + { + state.token[sizeof( state.token ) - 1] = 0; + if( start && state.buf ) + MsgDev( D_ERROR, "Parse error in %s, byte %d, token %s\n", scriptfilename, (int)( state.buf - start ), state.token ); + else MsgDev( D_ERROR, "Parse error in %s, token %s\n", scriptfilename, state.token ); + } + + if( start ) Mem_Free( start ); + + return count; +} diff --git a/engine/common/common.h b/engine/common/common.h index fe19dc4a..9ee2f4ab 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -108,7 +108,7 @@ typedef enum #include "crtlib.h" #include "cvar.h" -#define XASH_VERSION 0.99f // engine current version +#define XASH_VERSION 1.0f // engine current version // PERFORMANCE INFO #define MIN_FPS 20.0 // host minimum fps value for maxfps. @@ -748,6 +748,12 @@ void MD5Final( byte digest[16], MD5Context_t *ctx ); qboolean MD5_HashFile( byte digest[16], const char *pszFileName, uint seed[4] ); uint Com_HashKey( const char *string, uint hashSize ); +// +// cfgscript.c +// +int CSCR_LoadDefaultCVars( const char *scriptfilename ); +int CSCR_WriteGameCVars( file_t *cfg, const char *scriptfilename ); + // // hpak.c // @@ -802,6 +808,7 @@ qboolean CL_IsInConsole( void ); qboolean CL_IsThirdPerson( void ); qboolean CL_IsIntermission( void ); qboolean CL_Initialized( void ); +qboolean CL_IsTimeDemo( void ); char *CL_Userinfo( void ); float CL_GetLerpFrac( void ); void CL_CharEvent( int key ); diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index 29e56066..4b8ca612 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -808,6 +808,7 @@ autocomplete_list_t cmd_list[] = { "map_background", Cmd_GetMapList }, { "changelevel", Cmd_GetMapList }, { "playdemo", Cmd_GetDemoList, }, +{ "timedemo", Cmd_GetDemoList, }, { "playvol", Cmd_GetSoundList }, { "hpkval", Cmd_GetCustomList }, { "entpatch", Cmd_GetMapList }, @@ -956,6 +957,10 @@ void Host_WriteServerConfig( const char *name ) file_t *f; SV_InitGameProgs(); // collect user variables + + // FIXME: move this out until menu parser is done + CSCR_LoadDefaultCVars( "settings.scr" ); + CSCR_LoadDefaultCVars( "user.scr" ); if(( f = FS_Open( name, "w", false )) != NULL ) { @@ -964,6 +969,8 @@ void Host_WriteServerConfig( const char *name ) FS_Printf( f, "//\t\tgame.cfg - multiplayer server temporare config\n" ); FS_Printf( f, "//=======================================================================\n" ); Cvar_WriteVariables( f, FCVAR_SERVER ); + CSCR_WriteGameCVars( f, "user.scr" ); + CSCR_WriteGameCVars( f, "settings.scr" ); FS_Close( f ); } else MsgDev( D_ERROR, "Couldn't write %s.\n", name ); diff --git a/engine/common/crclib.c b/engine/common/crclib.c index 2778f22f..0aa3be59 100644 --- a/engine/common/crclib.c +++ b/engine/common/crclib.c @@ -210,7 +210,7 @@ qboolean CRC32_File( dword *crcvalue, const char *filename ) f = FS_Open( filename, "rb", false ); if( !f ) return false; - ASSERT( crcvalue != NULL ); + Assert( crcvalue != NULL ); CRC32_Init( crcvalue ); while( 1 ) diff --git a/engine/common/cvar.c b/engine/common/cvar.c index cf0a7aaa..75b9c4cb 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -157,6 +157,58 @@ const char *Cvar_ValidateString( convar_t *var, const char *value ) return pszValue; } +/* +============ +Cvar_UnlinkVar + +unlink the variable +============ +*/ +int Cvar_UnlinkVar( const char *var_name, int group ) +{ + int count = 0; + convar_t **prev; + convar_t *var; + + prev = &cvar_vars; + + while( 1 ) + { + var = *prev; + if( !var ) break; + + // do filter by name + if( var_name && Q_strcmp( var->name, var_name )) + { + prev = &var->next; + continue; + } + + // do filter by specified group + if( group && !FBitSet( var->flags, group )) + { + prev = &var->next; + continue; + } + + // unlink variable from list + freestring( var->string ); + *prev = var->next; + + // only allocated cvars can throw these fields + if( FBitSet( var->flags, FCVAR_ALLOCATED )) + { + freestring( var->name ); + freestring( var->def_string ); + freestring( var->desc ); + Mem_Free( var ); + } + count++; + } + + return count; +} + /* ============ Cvar_Changed @@ -166,7 +218,7 @@ Tell the engine parts about cvar changing */ static void Cvar_Changed( convar_t *var ) { - ASSERT( var != NULL ); + Assert( var != NULL ); // tell about changes SetBits( var->flags, FCVAR_CHANGED ); @@ -229,7 +281,7 @@ convar_t *Cvar_Get( const char *name, const char *value, int flags, const char * { convar_t *cur, *find, *var; - ASSERT( name != NULL ); + ASSERT( name && *name ); // check for command coexisting if( Cmd_Exists( name )) @@ -313,15 +365,23 @@ Adds a freestanding variable to the variable list. */ void Cvar_RegisterVariable( convar_t *var ) { - convar_t *cur, *find; + convar_t *cur, *find, *dup; ASSERT( var != NULL ); // first check to see if it has allready been defined - if( Cvar_FindVar( var->name )) + dup = Cvar_FindVar( var->name ); + + if( dup ) { - MsgDev( D_ERROR, "can't register variable '%s', is already defined\n", var->name ); - return; + if( !FBitSet( dup->flags, FCVAR_TEMPORARY )) + { + MsgDev( D_ERROR, "can't register variable '%s', is already defined\n", var->name ); + return; + } + + // time to replace temp variable with real + Cvar_UnlinkVar( var->name, FCVAR_TEMPORARY ); } // check for overlap with a command @@ -760,9 +820,7 @@ unlink all cvars with specified flag */ void Cvar_Unlink( int group ) { - convar_t *var; - convar_t **prev; - int count = 0; + int count; if( Cvar_VariableInteger( "host_gameloaded" ) && FBitSet( group, FCVAR_EXTDLL )) { @@ -782,35 +840,7 @@ void Cvar_Unlink( int group ) return; } - prev = &cvar_vars; - - while( 1 ) - { - var = *prev; - if( !var ) break; - - // do filter by specified group - if( group && !FBitSet( var->flags, group )) - { - prev = &var->next; - continue; - } - - // unlink variable from list - freestring( var->string ); - *prev = var->next; - - // only allocated cvars can throw these fields - if( FBitSet( var->flags, FCVAR_ALLOCATED )) - { - freestring( var->name ); - freestring( var->def_string ); - freestring( var->desc ); - Mem_Free( var ); - } - count++; - } - + count = Cvar_UnlinkVar( NULL, group ); MsgDev( D_REPORT, "unlink %i cvars\n", count ); } diff --git a/engine/common/cvar.h b/engine/common/cvar.h index 49516a27..bfb20e53 100644 --- a/engine/common/cvar.h +++ b/engine/common/cvar.h @@ -42,6 +42,7 @@ typedef struct convar_s #define FCVAR_EXTENDED (1<<18) // this is convar_t (sets on registration) #define FCVAR_ALLOCATED (1<<19) // this convar_t is fully dynamic allocated (include description) #define FCVAR_VIDRESTART (1<<20) // recreate the window is cvar with this flag was changed +#define FCVAR_TEMPORARY (1<<21) // these cvars holds their values and can be unlink in any time #define CVAR_DEFINE( cv, cvname, cvstr, cvflags, cvdesc ) convar_t cv = { cvname, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } #define CVAR_DEFINE_AUTO( cv, cvstr, cvflags, cvdesc ) convar_t cv = { #cv, cvstr, cvflags, 0.0f, (void *)CVAR_SENTINEL, cvdesc } diff --git a/engine/common/host.c b/engine/common/host.c index 8a56551d..58ec73ca 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -537,7 +537,7 @@ double Host_CalcFPS( void ) } // probably left part of this condition is redundant :-) - if( host.type != HOST_DEDICATED && Host_IsLocalGame( )) + if( host.type != HOST_DEDICATED && Host_IsLocalGame( ) && !CL_IsTimeDemo( )) { // ajdust fps for vertical synchronization if( gl_vsync != NULL && gl_vsync->value ) @@ -581,7 +581,7 @@ qboolean Host_FilterTime( float time ) oldtime = host.realtime; // NOTE: allow only in singleplayer while demos are not active - if( host_framerate->value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo()) + if( host_framerate->value > 0.0f && Host_IsLocalGame() && !CL_IsPlaybackDemo() && !CL_IsRecordDemo( )) host.frametime = bound( MIN_FRAMETIME, host_framerate->value, MAX_FRAMETIME ); else host.frametime = bound( MIN_FRAMETIME, host.frametime, MAX_FRAMETIME ); diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index 202a911b..a0ff0c11 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -498,7 +498,7 @@ Mod_PointInLeaf */ mleaf_t *Mod_PointInLeaf( const vec3_t p, mnode_t *node ) { - ASSERT( node != NULL ); + Assert( node != NULL ); while( 1 ) { @@ -524,7 +524,7 @@ byte *Mod_GetPVSForPoint( const vec3_t p ) mnode_t *node; mleaf_t *leaf = NULL; - ASSERT( worldmodel != NULL ); + Assert( worldmodel != NULL ); node = worldmodel->nodes; @@ -1245,7 +1245,7 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod ) in = FS_LoadFile( path, &litdatasize, false ); - ASSERT( in != NULL ); + Assert( in != NULL ); if( *(uint *)in != IDDELUXEMAPHEADER || *((uint *)in + 1) != DELUXEMAP_VERSION ) { @@ -1295,7 +1295,7 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod ) in = FS_LoadFile( path, &deluxdatasize, false ); - ASSERT( in != NULL ); + Assert( in != NULL ); if( *(uint *)in != IDDELUXEMAPHEADER || *((uint *)in + 1) != DELUXEMAP_VERSION ) { @@ -2738,7 +2738,7 @@ void Mod_UnloadBrushModel( model_t *mod ) texture_t *tx; int i; - ASSERT( mod != NULL ); + Assert( mod != NULL ); if( mod->type != mod_brush ) return; // not a bmodel diff --git a/engine/common/model.c b/engine/common/model.c index 8e117e7e..c59cb155 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -556,7 +556,7 @@ void Mod_LoadCacheFile( const char *filename, cache_user_t *cu ) string name; size_t i, j, size; - ASSERT( cu != NULL ); + Assert( cu != NULL ); if( !filename || !filename[0] ) return; diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index e29606aa..1645e3d3 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -132,7 +132,7 @@ void Netchan_ReportFlow( netchan_t *chan ) if( CL_IsPlaybackDemo( )) return; - ASSERT( chan != NULL ); + Assert( chan != NULL ); Q_strcpy( incoming, Q_pretifymem((float)chan->flow[FLOW_INCOMING].totalbytes, 3 )); Q_strcpy( outgoing, Q_pretifymem((float)chan->flow[FLOW_OUTGOING].totalbytes, 3 )); diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 48de7c1f..a96573c6 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -76,8 +76,8 @@ GNU General Public License for more details. #define svc_eventindex 54 // [index][eventname] // reserved #define svc_resourcelocation 56 // [string] -// reserved -// reserved +#define svc_querycvarvalue 57 // [string] +#define svc_querycvarvalue2 58 // [string][long] (context) #define svc_lastmsg 58 // start user messages at this point // client to server @@ -90,8 +90,8 @@ GNU General Public License for more details. // reserved #define clc_fileconsistency 7 #define clc_voicedata 8 -// reserved -// reserved +#define clc_requestcvarvalue 9 +#define clc_requestcvarvalue2 10 #define clc_lastmsg 10 // end client messages #define MAX_VISIBLE_PACKET_BITS 11 // 2048 visible entities per frame (hl1 has 256) diff --git a/engine/eiface.h b/engine/eiface.h index 6163920e..c69e1806 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -258,6 +258,23 @@ typedef struct enginefuncs_s qboolean (*pfnVoice_SetClientListening)(int iReceiver, int iSender, qboolean bListen); const char *(*pfnGetPlayerAuthId) ( edict_t *e ); + + void (*pfnUnused1)( void ); + void (*pfnUnused2)( void ); + void (*pfnUnused3)( void ); + void (*pfnUnused4)( void ); + void (*pfnUnused5)( void ); + void (*pfnUnused6)( void ); + void (*pfnUnused7)( void ); + void (*pfnUnused8)( void ); + void (*pfnUnused9)( void ); + void (*pfnUnused10)( void ); + void (*pfnUnused11)( void ); + + // three useable funcs + void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName ); + void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID ); + int (*pfnCheckParm)( char *parm, char **ppnext ); } enginefuncs_t; // ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138 @@ -468,6 +485,8 @@ typedef struct void (*pfnOnFreeEntPrivateData)( edict_t *pEnt ); void (*pfnGameShutdown)(void); int (*pfnShouldCollide)( edict_t *pentTouched, edict_t *pentOther ); + void (*pfnCvarValue)( const edict_t *pEnt, const char *value ); + void (*pfnCvarValue2)( const edict_t *pEnt, int requestID, const char *cvarName, const char *value ); } NEW_DLL_FUNCTIONS; typedef int (*NEW_DLL_FUNCTIONS_FN)( NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); diff --git a/engine/engine.dsp b/engine/engine.dsp index c929ab07..02d46371 100644 --- a/engine/engine.dsp +++ b/engine/engine.dsp @@ -543,10 +543,6 @@ SOURCE=.\client\vgui\vgui_draw.c # End Source File # Begin Source File -SOURCE=.\client\vgui\vgui_font.cpp -# End Source File -# Begin Source File - SOURCE=.\client\vgui\vgui_input.cpp # End Source File # Begin Source File diff --git a/engine/physint.h b/engine/physint.h index 21f917cb..a3115766 100644 --- a/engine/physint.h +++ b/engine/physint.h @@ -106,7 +106,6 @@ typedef struct server_physics_api_s const byte *(*pfnLoadImagePixels)( const char *filename, int *width, int *height ); const char* (*pfnGetModelName)( int modelindex ); - int (*pfnCheckParm)( char *parm, char **ppnext ); } server_physics_api_t; // physic callbacks diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 65665954..7c045424 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -2365,6 +2365,42 @@ void SV_ParseResourceList( sv_client_t *cl, sizebuf_t *msg ) Netchan_FragSend( &cl->netchan ); } +/* +=================== +SV_ParseCvarValue + +Parse a requested value from client cvar +=================== +*/ +void SV_ParseCvarValue( sv_client_t *cl, sizebuf_t *msg ) +{ + const char *value = MSG_ReadString( msg ); + + if( svgame.dllFuncs2.pfnCvarValue != NULL ) + svgame.dllFuncs2.pfnCvarValue( cl->edict, value ); + MsgDev( D_REPORT, "Cvar query response: name:%s, value:%s\n", cl->name, value ); +} + +/* +=================== +SV_ParseCvarValue2 + +Parse a requested value from client cvar +=================== +*/ +void SV_ParseCvarValue2( sv_client_t *cl, sizebuf_t *msg ) +{ + string name, value; + int requestID = MSG_ReadLong( msg ); + + Q_strcpy( name, MSG_ReadString( msg )); + Q_strcpy( value, MSG_ReadString( msg )); + + if( svgame.dllFuncs2.pfnCvarValue2 != NULL ) + svgame.dllFuncs2.pfnCvarValue2( cl->edict, requestID, name, value ); + MsgDev( D_REPORT, "Cvar query response: name:%s, request ID %d, cvar:%s, value:%s\n", cl->name, requestID, name, value ); +} + /* =================== SV_ExecuteClientMessage @@ -2436,6 +2472,12 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg ) case clc_resourcelist: SV_ParseResourceList( cl, msg ); break; + case clc_requestcvarvalue: + SV_ParseCvarValue( cl, msg ); + break; + case clc_requestcvarvalue2: + SV_ParseCvarValue2( cl, msg ); + break; default: MsgDev( D_ERROR, "SV_ReadClientMessage: clc_bad\n" ); SV_DropClient( cl ); diff --git a/engine/server/sv_frame.c b/engine/server/sv_frame.c index f7432d9e..dfa5e42f 100644 --- a/engine/server/sv_frame.c +++ b/engine/server/sv_frame.c @@ -73,7 +73,7 @@ static void SV_AddEntitiesToPacket( edict_t *pViewEnt, edict_t *pClient, client_ cl = SV_ClientFromEdict( pClient, true ); - ASSERT( cl != NULL ); + Assert( cl != NULL ); // portals can't change hostflags if( pClient && from_client ) diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 7c432301..7c315377 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -93,7 +93,7 @@ void SV_SetMinMaxSize( edict_t *e, const float *min, const float *max, qboolean { int i; - ASSERT( min != NULL && max != NULL ); + Assert( min != NULL && max != NULL ); if( !SV_IsValidEdict( e )) return; @@ -454,8 +454,8 @@ void SV_CreateStudioDecal( sizebuf_t *msg, const float *origin, const float *sta if( !entityIndex || !modelIndex ) return; - ASSERT( origin ); - ASSERT( start ); + Assert( origin != NULL ); + Assert( start != NULL ); // this can happens if serialized map contain 4096 static decals... if( MSG_GetNumBytesLeft( msg ) < 50 ) @@ -769,7 +769,7 @@ void SV_FreePrivateData( edict_t *pEdict ) void SV_InitEdict( edict_t *pEdict ) { - ASSERT( pEdict ); + Assert( pEdict != NULL ); SV_FreePrivateData( pEdict ); memset( &pEdict->v, 0, sizeof( entvars_t )); @@ -786,8 +786,8 @@ void SV_InitEdict( edict_t *pEdict ) void SV_FreeEdict( edict_t *pEdict ) { - ASSERT( pEdict != NULL ); - ASSERT( pEdict->free == false ); + Assert( pEdict != NULL ); + Assert( pEdict->free == false ); // unlink from world SV_UnlinkEdict( pEdict ); @@ -2899,7 +2899,7 @@ pfnPvAllocEntPrivateData */ void *pfnPvAllocEntPrivateData( edict_t *pEdict, long cb ) { - ASSERT( pEdict ); + Assert( pEdict != NULL ); SV_FreePrivateData( pEdict ); @@ -3937,7 +3937,7 @@ byte *pfnSetFatPVS( const float *org ) if( !sv.worldmodel->visdata || sv_novis->value || !org || CL_DisableVisibility( )) fullvis = true; - ASSERT( svs.currentPlayerNum >= 0 && svs.currentPlayerNum < MAX_CLIENTS ); + Assert( svs.currentPlayerNum >= 0 && svs.currentPlayerNum < MAX_CLIENTS ); // portals can't change viewpoint! if( !FBitSet( sv.hostflags, SVF_MERGE_VISIBILITY )) @@ -3987,7 +3987,7 @@ byte *pfnSetFatPAS( const float *org ) if( !sv.worldmodel->visdata || sv_novis->value || !org || CL_DisableVisibility( )) fullvis = true; - ASSERT( svs.currentPlayerNum >= 0 && svs.currentPlayerNum < MAX_CLIENTS ); + Assert( svs.currentPlayerNum >= 0 && svs.currentPlayerNum < MAX_CLIENTS ); // portals can't change viewpoint! if( !FBitSet( sv.hostflags, SVF_MERGE_VISIBILITY )) @@ -4331,6 +4331,72 @@ const char *pfnGetPlayerAuthId( edict_t *e ) return result; } + +/* +============= +pfnQueryClientCvarValue + +request client cvar value +============= +*/ +void pfnQueryClientCvarValue( const edict_t *player, const char *cvarName ) +{ + sv_client_t *cl; + + if( !cvarName || !*cvarName ) + return; + + if(( cl = SV_ClientFromEdict( player, true )) != NULL ) + { + MSG_BeginServerCmd( &cl->netchan.message, svc_querycvarvalue ); + MSG_WriteString( &cl->netchan.message, cvarName ); + } + else + { + if( svgame.dllFuncs2.pfnCvarValue ) + svgame.dllFuncs2.pfnCvarValue( player, "Bad Player" ); + MsgDev( D_ERROR, "QueryClientCvarValue: tried to send to a non-client!\n" ); + } +} + +/* +============= +pfnQueryClientCvarValue2 + +request client cvar value (bugfixed) +============= +*/ +void pfnQueryClientCvarValue2( const edict_t *player, const char *cvarName, int requestID ) +{ + sv_client_t *cl; + + if( !cvarName || !*cvarName ) + return; + + if(( cl = SV_ClientFromEdict( player, true )) != NULL ) + { + MSG_BeginServerCmd( &cl->netchan.message, svc_querycvarvalue2 ); + MSG_WriteLong( &cl->netchan.message, requestID ); + MSG_WriteString( &cl->netchan.message, cvarName ); + } + else + { + if( svgame.dllFuncs2.pfnCvarValue2 ) + svgame.dllFuncs2.pfnCvarValue2( player, requestID, cvarName, "Bad Player" ); + MsgDev( D_ERROR, "QueryClientCvarValue: tried to send to a non-client!\n" ); + } +} + +/* +============= +pfnEngineStub + +extended iface stubs +============= +*/ +static void pfnEngineStub( void ) +{ +} // engine callbacks static enginefuncs_t gEngfuncs = @@ -4479,6 +4545,20 @@ static enginefuncs_t gEngfuncs = pfnVoice_GetClientListening, pfnVoice_SetClientListening, pfnGetPlayerAuthId, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnEngineStub, + pfnQueryClientCvarValue, + pfnQueryClientCvarValue2, + COM_CheckParm, }; /* @@ -4628,7 +4708,7 @@ void SV_LoadFromFile( const char *mapname, char *entities ) int inhibited; edict_t *ent; - ASSERT( entities != NULL ); + Assert( entities != NULL ); // user dll can override spawn entities function (Xash3D extension) if( !svgame.physFuncs.SV_LoadEntities || !svgame.physFuncs.SV_LoadEntities( mapname, entities )) diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 60327c3f..a927d1c3 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -101,6 +101,7 @@ CVAR_DEFINE( sv_changetime, "host_changetime", "0.001", FCVAR_ARCHIVE, "host.fra // obsolete cvars which we should keep because game DLL's will be relies on it CVAR_DEFINE_AUTO( showtriggers, "0", FCVAR_LATCH, "debug cvar shows triggers" ); CVAR_DEFINE_AUTO( sv_airmove, "1", FCVAR_SERVER, "obsolete, compatibility issues" ); +CVAR_DEFINE_AUTO( sv_version, "", FCVAR_READ_ONLY, "engine version string" ); // gore-related cvars CVAR_DEFINE_AUTO( violence_hblood, "1", 0, "draw human blood" ); @@ -699,6 +700,8 @@ Only called at startup, not for each game */ void SV_Init( void ) { + string versionString; + SV_InitHostCommands(); Cvar_Get ("protocol", va( "%i", PROTOCOL_VERSION ), FCVAR_READ_ONLY, "displays server protocol version" ); @@ -777,6 +780,7 @@ void SV_Init( void ) Cvar_RegisterVariable (&sv_allow_download); Cvar_RegisterVariable (&sv_send_logos); Cvar_RegisterVariable (&sv_send_resources); + Cvar_RegisterVariable (&sv_version); sv_sendvelocity = Cvar_Get( "sv_sendvelocity", "1", FCVAR_ARCHIVE, "force to send velocity for event_t structure across network" ); Cvar_RegisterVariable (&sv_consistency); sv_novis = Cvar_Get( "sv_novis", "0", 0, "force to ignore server visibility" ); @@ -795,6 +799,9 @@ void SV_Init( void ) SV_ClearSaveDir (); // delete all temporary *.hl files MSG_Init( &net_message, "NetMessage", net_message_buffer, sizeof( net_message_buffer )); + + Q_snprintf( versionString, sizeof( versionString ), "%s: %.2f,%i,%i", "Xash3D", XASH_VERSION, PROTOCOL_VERSION, Q_buildnum() ); + Cvar_FullSet( "sv_version", versionString, FCVAR_READ_ONLY ); } /* diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 3569dc59..a46042f7 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -2042,7 +2042,6 @@ static server_physics_api_t gPhysicsAPI = COM_SaveFile, pfnLoadImagePixels, pfnGetModelName, - COM_CheckParm, }; /* diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index 82f05f19..9a6f4121 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -42,7 +42,7 @@ qboolean SV_PlayerIsFrozen( edict_t *pClient ) void SV_ClipPMoveToEntity( physent_t *pe, const vec3_t start, vec3_t mins, vec3_t maxs, const vec3_t end, pmtrace_t *tr ) { - ASSERT( tr != NULL ); + Assert( tr != NULL ); if( svgame.physFuncs.ClipPMoveToEntity != NULL ) { @@ -198,7 +198,7 @@ void SV_AddLinksToPmove( areanode_t *node, const vec3_t pmove_mins, const vec3_t physent_t *pe; pl = EDICT_NUM( svgame.pmove->player_index + 1 ); - ASSERT( SV_IsValidEdict( pl )); + Assert( SV_IsValidEdict( pl )); // touch linked edicts for( l = node->solid_edicts.next; l != &node->solid_edicts; l = next ) diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index 883a3816..d989177d 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -281,7 +281,7 @@ void SaveRestore_InitEntityTable( SAVERESTOREDATA *pSaveData, ENTITYTABLE *pNewT ENTITYTABLE *pTable; int i; - ASSERT( pSaveData->pTable == NULL ); + Assert( pSaveData->pTable == NULL ); pSaveData->tableCount = entityCount; pSaveData->pTable = pNewTable; @@ -306,7 +306,7 @@ ENTITYTABLE *SaveRestore_DetachEntityTable( SAVERESTOREDATA *pSaveData ) void SaveRestore_InitSymbolTable( SAVERESTOREDATA *pSaveData, char **pNewTokens, int sizeTable ) { - ASSERT( pSaveData->pTokens == NULL ); + Assert( pSaveData->pTokens == NULL ); pSaveData->tokenCount = sizeTable; pSaveData->pTokens = pNewTokens; @@ -330,7 +330,7 @@ qboolean SaveRestore_DefineSymbol( SAVERESTOREDATA *pSaveData, const char *pszTo return true; } - ASSERT( 0 ); + Assert( 0 ); return false; } @@ -909,10 +909,7 @@ SAVERESTOREDATA *SV_LoadSaveData( const char *level ) for( i = 0; i < sectionsInfo.nSymbols; i++ ) { if( *pszTokenList ) - { - ASSERT( SaveRestore_DefineSymbol( pSaveData, pszTokenList, i )); - } - + SaveRestore_DefineSymbol( pSaveData, pszTokenList, i ); // find next token (after next null) while( *pszTokenList++ ); } @@ -922,7 +919,7 @@ SAVERESTOREDATA *SV_LoadSaveData( const char *level ) SaveRestore_InitSymbolTable( pSaveData, NULL, 0 ); } - ASSERT( pszTokenList - (char *)(pSaveData + 1) == sectionsInfo.nBytesSymbols ); + Assert( pszTokenList - (char *)(pSaveData + 1) == sectionsInfo.nBytesSymbols ); // set up the restore basis size = SumBytes( §ionsInfo ) - sectionsInfo.nBytesSymbols; @@ -1588,7 +1585,7 @@ int SV_LoadGameState( char const *level, qboolean createPlayers ) { if( pEntInfo->id == 0 ) // worldspawn { - ASSERT( i == 0 ); + Assert( i == 0 ); pent = EDICT_NUM( 0 ); @@ -1602,14 +1599,14 @@ int SV_LoadGameState( char const *level, qboolean createPlayers ) if(!( pEntInfo->flags & FENTTABLE_PLAYER )) { MsgDev( D_WARN, "ENTITY IS NOT A PLAYER: %d\n", i ); - ASSERT( 0 ); + Assert( 0 ); } ed = EDICT_NUM( pEntInfo->id ); if( ed && createPlayers ) { - ASSERT( ed->free == false ); + Assert( ed->free == false ); // create the player pent = SV_CreateNamedEntity( ed, pEntInfo->classname ); } @@ -1713,16 +1710,16 @@ int SV_CreateEntityTransitionList( SAVERESTOREDATA *pSaveData, int levelMask ) active = (pEntInfo->flags & levelMask) ? 1 : 0; // spawn players - if(( pEntInfo->id > 0) && ( pEntInfo->id < svgame.globals->maxClients + 1 )) + if(( pEntInfo->id > 0 ) && ( pEntInfo->id < svgame.globals->maxClients + 1 )) { edict_t *ed = EDICT_NUM( pEntInfo->id ); if( active && ed && !ed->free ) { - if(!( pEntInfo->flags & FENTTABLE_PLAYER )) + if( !FBitSet( pEntInfo->flags, FENTTABLE_PLAYER )) { MsgDev( D_WARN, "ENTITY IS NOT A PLAYER: %d\n", i ); - ASSERT( 0 ); + Assert( 0 ); } pent = SV_CreateNamedEntity( ed, pEntInfo->classname ); @@ -2088,10 +2085,7 @@ int SV_SaveReadHeader( file_t *pFile, GAME_HEADER *pHeader ) for( i = 0; i < tokenCount; i++ ) { if( *pszTokenList ) - { - ASSERT( SaveRestore_DefineSymbol( pSaveData, pszTokenList, i )); - } - + SaveRestore_DefineSymbol( pSaveData, pszTokenList, i ); while( *pszTokenList++ ); // find next token (after next null) } } diff --git a/utils/vgui/vgui_dll-master.zip b/utils/vgui/vgui_dll-master.zip deleted file mode 100644 index e4dc7d01..00000000 Binary files a/utils/vgui/vgui_dll-master.zip and /dev/null differ diff --git a/xash.dsw b/xash.dsw index 88cfb178..05979804 100644 --- a/xash.dsw +++ b/xash.dsw @@ -51,6 +51,18 @@ Package=<4> ############################################################################### +Project: "mainui2"=.\mainui2\mainui2.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + Project: "vgui"=.\utils\vgui\lib\vgui.dsp - Package Owner=<4> Package=<5>