From 69910228a0b93645f190dd25b6a298571d5f16bc Mon Sep 17 00:00:00 2001 From: g-cont Date: Tue, 13 Feb 2018 00:00:00 +0300 Subject: [PATCH] 13 Feb 2018 --- common/com_model.h | 3 + common/wadfile.rar | Bin 0 -> 1591 bytes engine/client/cl_cmds.c | 18 +- engine/client/cl_demo.c | 114 ++- engine/client/cl_game.c | 12 +- engine/client/cl_main.c | 11 +- engine/client/cl_parse.c | 56 ++ engine/client/cl_pmove.c | 2 +- engine/client/cl_remap.c | 10 +- engine/client/cl_tent.c | 8 +- engine/client/client.h | 17 +- engine/client/gl_alias.c | 2 +- engine/client/gl_backend.c | 2 +- engine/client/gl_beams.c | 4 +- engine/client/gl_decals.c | 6 +- engine/client/gl_frustum.c | 8 +- engine/client/gl_image.c | 32 +- engine/client/gl_rmain.c | 22 +- engine/client/gl_rsurf.c | 2 +- engine/client/gl_sprite.c | 4 +- engine/client/gl_studio.c | 6 +- engine/client/s_mix.c | 44 +- engine/client/s_stream.c | 4 +- engine/client/vgui/list.txt | 9 - engine/client/vgui/utlmemory.h | 348 -------- engine/client/vgui/utlrbtree.h | 1289 ------------------------------ engine/client/vgui/utlvector.h | 605 -------------- engine/client/vgui/vgui_draw.c | 130 ++- engine/client/vgui/vgui_draw.h | 6 +- engine/client/vgui/vgui_font.cpp | 173 ---- engine/client/vgui/vgui_int.cpp | 3 - engine/client/vgui/vgui_main.h | 119 +-- engine/client/vgui/vgui_surf.cpp | 376 ++++++--- engine/common/cfgscript.c | 341 ++++++++ engine/common/common.h | 9 +- engine/common/con_utils.c | 7 + engine/common/crclib.c | 2 +- engine/common/cvar.c | 106 ++- engine/common/cvar.h | 1 + engine/common/host.c | 4 +- engine/common/mod_bmodel.c | 10 +- engine/common/model.c | 2 +- engine/common/net_chan.c | 2 +- engine/common/protocol.h | 8 +- engine/eiface.h | 19 + engine/engine.dsp | 4 - engine/physint.h | 1 - engine/server/sv_client.c | 42 + engine/server/sv_frame.c | 2 +- engine/server/sv_game.c | 100 ++- engine/server/sv_main.c | 7 + engine/server/sv_phys.c | 1 - engine/server/sv_pmove.c | 4 +- engine/server/sv_save.c | 30 +- utils/vgui/vgui_dll-master.zip | Bin 246376 -> 0 bytes xash.dsw | 12 + 56 files changed, 1229 insertions(+), 2930 deletions(-) create mode 100644 common/wadfile.rar delete mode 100644 engine/client/vgui/utlmemory.h delete mode 100644 engine/client/vgui/utlrbtree.h delete mode 100644 engine/client/vgui/utlvector.h delete mode 100644 engine/client/vgui/vgui_font.cpp create mode 100644 engine/common/cfgscript.c delete mode 100644 utils/vgui/vgui_dll-master.zip 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 0000000000000000000000000000000000000000..d372bf56a0c745c6cd6b54a2885f891086cce051 GIT binary patch literal 1591 zcmV-72FUqRVR9iF2LR8Ia{vGh000000000@4Rj!YDFE{Y003?d0006)0bDYnvgAq~ zGYJ470001YVPs}$Y-KKJ3>{F=jS>8q6??A|&j)H}L=4yx1kIB(bKsGXB!d5E!$8fM z6j+62j0@bd?Ay0+hy7db`m*7GTX%I$fdHA)sZHLYLO^#$^vEA48u-D54(8S*gFVfvw_E3cK$*((m2Q+;I9+&W5I5dAeL;@g{mRLd%F;>j409XyAp6OYa`~Cz4adL9 zJs_E&AdEcBfdnynN3h7c(z=3tC=tp!BLtW)*<$}L1X$8=G)bXfN=<3K1Ar;X(-Scy zH$LN0=;5R z9v;Ua!}OW(3N7`0ul`+4+3?NB3^Q{YTO5WF*E1J8$qH^O#o~}1fwmtD`B%TmJ$d}v zQLdCbPKZ)j{WP}W>5)zCLVW&UZ)_IxJ`5Om+}M54wQ9w>wW`ut zZXq5Z7Tv}?#CQ?p!Q$z68}v zHv+k%sKLz)#;sHoMI31a#A*MwL~R3qBlHdhFVzQXTQb zFO1$BCM|-vJde<;)`ezH5Ft4rvTEi1hFLBkwqD-TVuV2F)E`bL#PN-fE|&oGP|B&ON~@O;T#3l_Ko;YzI%6wJ%p9@n6~D^`LD=jI|UQbyEm)G|JsL=xt%mIHmUY^TH8ll;DxX?YhCG>Or>(k~2-bh$< zc>-Kux<;_Ed>z4{H3Z>n6k?aQL-$`5Dc6R%b;nbOt$m34bxgj-66%6qPe`FzG%*@b z&e+ACYZ+I1_3X*#*?8_UuPwI6nzHq*RH0sZEGCd&<53|5 zm8mvvO8>7tYM}h(N)+&uk>cmvmHZF#*`@v!7Sn+ zk$~^iA-kYjHXNyl$_19m#kakny?&Y!IcNVVJe(M#N@F44v|ie}p2<_M2Mwel1-+vr za3PcYa2eEm?TghCwQwy~pOwVXUvL7rJy~xxi*2)^de&@HR#OvqY1 zXczzS?<>~o3#m%mzIeVEEW3=a3w)A_#D<^7g=V(x=hWXkfIid<7h1 z5)d{bGwWx^bZj!p4NelF;|e)^V!b%LJA1-v+#FxzhCw`Oniw6$^xj!UGL`Z2f&$ZO zB1aiOe3|{q>r0w~>ZjF{!Qt_~GWgOkVCYUo^fbpD%d3A=@;Z_qfr-a57ahQHdxJ$nE^2LRK89+m(A literal 0 HcmV?d00001 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 e4dc7d01cc25bab47cdc3994b9a8c5f7a6945b9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 246376 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 b1Gw9l^lO(LNkhcCwD1*c(cz`+5f| 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∈)JxIhM6Pk2Kyu<4He>eEbg8u2_S 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Πc9K=yrk=P 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 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>