From 404d084524252767a62d36c497fe59aad4bebba3 Mon Sep 17 00:00:00 2001 From: g-cont Date: Sun, 24 Oct 2010 00:00:00 +0400 Subject: [PATCH] 24 Oct 2010 --- client/global/utils.h | 1 + common/com_model.h | 10 +++ common/const.h | 10 --- engine/client/cl_main.c | 4 +- engine/common/cm_model.c | 15 ++-- engine/common/console.c | 26 +++++++ engine/common/pm_surface.c | 6 +- engine/common/pm_trace.c | 4 +- engine/host.c | 6 ++ engine/server/sv_client.c | 4 +- engine/server/sv_edict.h | 149 +++++++++++++++++++++++++++++++++++++ engine/server/sv_game.c | 15 +++- engine/server/sv_main.c | 3 +- engine/server/sv_pmove.c | 16 +--- engine/server/sv_world.c | 10 ++- launch/cmd.c | 76 ++++++++++++++++++- launch/console.c | 1 + launch/cvar.c | 83 +++++++++++++++------ launch/filesystem.c | 11 ++- launch/launch.h | 2 + launch/system.c | 1 + public/launch_api.h | 2 + vid_gl/r_model.h | 10 +++ vid_gl/r_studio.c | 4 +- 24 files changed, 397 insertions(+), 72 deletions(-) create mode 100644 engine/server/sv_edict.h diff --git a/client/global/utils.h b/client/global/utils.h index 8eb5e4b3..7aa2afc0 100644 --- a/client/global/utils.h +++ b/client/global/utils.h @@ -11,6 +11,7 @@ extern cl_enginefuncs_t gEngfuncs; #include "event_api.h" #include "enginecallback.h" #include "shake.h" +#include "com_model.h" #define FILE_GLOBAL static #define DLL_GLOBAL diff --git a/common/com_model.h b/common/com_model.h index b6b08595..9ca057ef 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -18,6 +18,16 @@ #define CONTENTS_NODE 1 // fake contents to determine nodes +// model types +typedef enum +{ + mod_bad = -1, + mod_brush, + mod_sprite, + mod_alias, + mod_studio +} modtype_t; + typedef struct mplane_s { vec3_t normal; diff --git a/common/const.h b/common/const.h index 8486499c..fa9adcd7 100644 --- a/common/const.h +++ b/common/const.h @@ -725,16 +725,6 @@ typedef struct byte r, g, b; } color24; -// model types -typedef enum -{ - mod_bad, - mod_world, - mod_brush, - mod_studio, - mod_sprite -} modtype_t; - // link_t is only used for entity area links now typedef struct link_s { diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 6b29e59f..2b74d46d 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -755,6 +755,8 @@ void CL_SendDisconnectMessage( void ) sizebuf_t buf; byte data[32]; + if( cls.state == ca_disconnected ) return; + BF_Init( &buf, "LastMessage", data, sizeof( data )); BF_WriteByte( &buf, clc_stringcmd ); BF_WriteString( &buf, "disconnect" ); @@ -811,7 +813,6 @@ void CL_Disconnect_f( void ) void CL_Crashed_f( void ) { // already freed - if( cls.state == ca_disconnected ) return; if( host.state == HOST_CRASHED ) return; if( host.type != HOST_NORMAL ) return; if( !cls.initialized ) return; @@ -1553,6 +1554,7 @@ void CL_InitLocal( void ) cl_cmdbackup = Cvar_Get( "cl_cmdbackup", "2", CVAR_ARCHIVE, "how many additional history commands are sent" ); cl_cmdrate = Cvar_Get( "cl_cmdrate", "30", CVAR_ARCHIVE, "Max number of command packets sent to server per second" ); Cvar_Get( "hud_scale", "0", CVAR_ARCHIVE|CVAR_LATCH, "scale hud at current resolution" ); + Cvar_Get( "skin", "", CVAR_USERINFO, "player skin" ); // XDM 3.3 want this cvar // server commands Cmd_AddCommand ("noclip", NULL, "enable or disable no clipping mode" ); diff --git a/engine/common/cm_model.c b/engine/common/cm_model.c index ab4ca328..9b29c8d6 100644 --- a/engine/common/cm_model.c +++ b/engine/common/cm_model.c @@ -378,11 +378,15 @@ static void BSP_LoadSurfaces( const dlump_t *l ) out->plane = loadmodel->planes + LittleLong( in->planenum ); out->texinfo = loadmodel->texinfo + LittleLong( in->texinfo ); - if( !com.strncmp( out->texinfo->texture->name, "sky", 3 )) - out->flags |= (SURF_DRAWSKY|SURF_DRAWTILED); + // some DMC maps have bad textures + if( out->texinfo->texture ) + { + if( !com.strncmp( out->texinfo->texture->name, "sky", 3 )) + out->flags |= (SURF_DRAWSKY|SURF_DRAWTILED); - if( out->texinfo->texture->name[0] == '*' || out->texinfo->texture->name[0] == '!' ) - out->flags |= (SURF_DRAWTURB|SURF_DRAWTILED); + if( out->texinfo->texture->name[0] == '*' || out->texinfo->texture->name[0] == '!' ) + out->flags |= (SURF_DRAWTURB|SURF_DRAWTILED); + } BSP_CalcSurfaceExtents( out ); @@ -841,7 +845,7 @@ static void CM_BrushModel( model_t *mod, byte *buffer ) *starmod = *loadmodel; - starmod->type = (i == 0) ? mod_world : mod_brush; + starmod->type = mod_brush; starmod->hulls[0].firstclipnode = bm->headnode[0]; for( j = 1; j < MAX_MAP_HULLS; j++ ) @@ -1061,7 +1065,6 @@ void CM_BeginRegistration( const char *name, bool clientload, uint *checksum ) // load the newmap worldmodel = CM_ModForName( name, true ); if( !worldmodel ) Host_Error( "Couldn't load %s\n", name ); - worldmodel->type = mod_world; sv_models[1] = cm_models; // make link to world if( checksum ) *checksum = cm.checksum; diff --git a/engine/common/console.c b/engine/common/console.c index 4449a011..18c75ffe 100644 --- a/engine/common/console.c +++ b/engine/common/console.c @@ -103,6 +103,31 @@ void Con_Clear_f( void ) con.text[i] = ( ColorIndex( COLOR_DEFAULT ) << 8 ) | ' '; con.display = con.current; // go to end } + +/* +================ +Con_SetColor_f +================ +*/ +void Con_SetColor_f( void ) +{ + vec3_t color; + + switch( Cmd_Argc() ) + { + case 1: + Msg( "\"con_color\" is %i %i %i\n", g_color_table[7][0], g_color_table[7][1], g_color_table[7][2] ); + break; + case 2: + VectorSet( color, g_color_table[7][0], g_color_table[7][1], g_color_table[7][2] ); + com.atov( color, Cmd_Argv( 1 ), 3 ); + Con_DefaultColor( color[0], color[1], color[2] ); + break; + default: + Msg( "Usage: con_color \"r g b\"\n" ); + break; + } +} /* ================ @@ -507,6 +532,7 @@ void Con_Init( void ) } Cmd_AddCommand( "toggleconsole", Con_ToggleConsole_f, "opens or closes the console" ); + Cmd_AddCommand( "con_color", Con_SetColor_f, "set a custom console color" ); Cmd_AddCommand( "clear", Con_Clear_f, "clear console history" ); MsgDev( D_NOTE, "Console initialized.\n" ); diff --git a/engine/common/pm_surface.c b/engine/common/pm_surface.c index 0e1bb747..ed022e52 100644 --- a/engine/common/pm_surface.c +++ b/engine/common/pm_surface.c @@ -99,7 +99,7 @@ const char *PM_TraceTexture( physent_t *pe, vec3_t start, vec3_t end ) vec3_t temp, offset; bmodel = pe->model; - if( !bmodel || bmodel->type != mod_brush && bmodel->type != mod_world ) + if( !bmodel || bmodel->type != mod_brush ) return NULL; hull = PM_HullForBsp( pe, vec3_origin, vec3_origin, offset ); @@ -130,7 +130,9 @@ const char *PM_TraceTexture( physent_t *pe, vec3_t start, vec3_t end ) } surf = PM_RecursiveSurfCheck( &bmodel->nodes[hull->firstclipnode], start_l, end_l ); - if( !surf ) return NULL; + + if( !surf || !surf->texinfo || !surf->texinfo->texture ) + return NULL; return surf->texinfo->texture->name; } \ No newline at end of file diff --git a/engine/common/pm_trace.c b/engine/common/pm_trace.c index 05c6a5ea..e041eaf9 100644 --- a/engine/common/pm_trace.c +++ b/engine/common/pm_trace.c @@ -124,7 +124,7 @@ hull_t *PM_HullForEntity( physent_t *pe, vec3_t mins, vec3_t maxs, vec3_t offset if( pe->movetype != MOVETYPE_PUSH ) Host_Error( "SOLID_BSP without MOVETYPE_PUSH\n" ); - if( !pe->model || pe->model->type != mod_brush && pe->model->type != mod_world ) + if( !pe->model || pe->model->type != mod_brush ) Host_Error( "Entity %s has MOVETYPE_PUSH with a non bsp model\n", pe->name ); VectorSubtract( maxs, mins, size ); @@ -178,7 +178,7 @@ hull_t *PM_HullForBsp( physent_t *pe, const vec3_t mins, const vec3_t maxs, floa // decide which clipping hull to use, based on the size model = pe->model; - if( !model || ( model->type != mod_brush && model->type != mod_world )) + if( !model || model->type != mod_brush ) Host_Error( "Entity %i SOLID_BSP with a non bsp model %i\n", pe->info, model->type ); VectorSubtract( maxs, mins, size ); diff --git a/engine/host.c b/engine/host.c index b59a2175..04014a48 100644 --- a/engine/host.c +++ b/engine/host.c @@ -50,6 +50,11 @@ void Host_ShutdownServer( void ) SV_Shutdown( false ); } +void Host_Null( void ) +{ + // just a stub for some commands in dedicated-mode +} + /* ================ Host_NewGame @@ -813,6 +818,7 @@ void Host_Init( const int argc, const char **argv ) { Cmd_AddCommand( "quit", Sys_Quit, "quit the game" ); Cmd_AddCommand( "exit", Sys_Quit, "quit the game" ); + Cmd_AddCommand( "@crashed", Host_Null, "" ); // dedicated servers using settings from server.cfg file Cbuf_AddText( va( "exec %s\n", Cvar_VariableString( "servercfgfile" ))); diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index b59697d6..1781f419 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -269,7 +269,8 @@ edict_t *SV_FakeConnect( const char *netname ) break; } } - if( !newcl ) + + if( i == sv_maxclients->integer ) { MsgDev( D_INFO, "SV_DirectConnect: rejected a connection.\n"); return NULL; @@ -305,6 +306,7 @@ edict_t *SV_FakeConnect( const char *netname ) newcl->state = cs_spawned; newcl->lastmessage = host.realtime; // don't timeout newcl->lastconnect = host.realtime; + newcl->sendinfo = true; return ent; } diff --git a/engine/server/sv_edict.h b/engine/server/sv_edict.h new file mode 100644 index 00000000..eb056f57 --- /dev/null +++ b/engine/server/sv_edict.h @@ -0,0 +1,149 @@ +//======================================================================= +// Copyright XashXT Group 2008 © +// sv_edict.h - server prvm edict +//======================================================================= +#ifndef SV_EDICT_H +#define SV_EDICT_H + +struct sv_globalvars_s +{ + int pad[34]; + int pev; + int other; + int world; + float time; + float frametime; + float serverflags; + string_t mapname; + string_t startspot; + vec3_t spotoffset; + float deathmatch; + float teamplay; + float coop; + float total_secrets; + float found_secrets; + float total_monsters; + float killed_monsters; + vec3_t v_forward; + vec3_t v_right; + vec3_t v_up; + float trace_allsolid; + float trace_startsolid; + float trace_fraction; + float trace_plane_dist; + vec3_t trace_endpos; + vec3_t trace_plane_normal; + float trace_contents; + float trace_hitgroup; + float trace_flags; + int trace_ent; + func_t CreateAPI; + func_t StartFrame; + func_t EndFrame; + func_t PlayerPreThink; + func_t PlayerPostThink; + func_t ClientConnect; + func_t ClientDisconnect; + func_t PutClientInServer; + func_t ClientCommand; + func_t ClientUserInfoChanged; +}; + +struct sv_entvars_s +{ + string_t classname; + string_t globalname; + int chain; + func_t precache; + func_t activate; + func_t blocked; + func_t touch; + func_t think; + func_t use; + vec3_t origin; + vec3_t angles; + float modelindex; + vec3_t old_origin; + vec3_t old_angles; + vec3_t velocity; + vec3_t avelocity; + vec3_t m_pcentre[3]; + vec3_t m_pmatrix[4]; + vec3_t movedir; + vec3_t force; + vec3_t torque; + vec3_t post_origin; + vec3_t post_angles; + vec3_t origin_offset; + vec3_t absmin; + vec3_t absmax; + vec3_t mins; + vec3_t maxs; + vec3_t size; + float mass; + float solid; + float contents; + float movetype; + float waterlevel; + float watertype; + float ltime; + string_t model; + float skin; + float body; + float frame; + float speed; + float sequence; + float animtime; + float framerate; + float style; + float gaitsequence; + float effects; + float rendermode; + float renderfx; + float renderamt; + float colormap; + float flags; + float aiflags; + float spawnflags; + float fixangle; + vec3_t v_angle; + vec3_t view_ofs; + vec3_t punchangle; + float button0; + float button1; + float button2; + float impulse; + string_t v_model; + float v_frame; + float v_body; + float v_skin; + float v_sequence; + string_t p_model; + float p_sequence; + float p_frame; + float p_body; + float p_skin; + string_t loopsound; + float loopsndvol; + float loopsndattn; + int owner; + int enemy; + int aiment; + int goalentity; + float teleport_time; + float ideal_yaw; + float yaw_speed; + float m_flGroundSpeed; + float m_flFrameRate; + int groundentity; + float takedamage; + float nextthink; + float gravity; + float health; + float frags; + float team; +}; + +#define PROG_CRC_SERVER 8066 + +#endif//SV_EDICT_H \ No newline at end of file diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index 14df12fb..09a0cb45 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -2822,7 +2822,7 @@ pfnServerPrint void pfnServerPrint( const char *szMsg ) { // while loading in-progress we can sending message only for local client - if( sv.state == ss_loading ) MsgDev( D_INFO, szMsg ); + if( sv.state != ss_active ) MsgDev( D_INFO, szMsg ); else SV_BroadcastPrintf( PRINT_HIGH, "%s", szMsg ); } @@ -3829,7 +3829,7 @@ pfnAddServerCommand */ void pfnAddServerCommand( const char *cmd_name, void (*function)(void) ) { - Cmd_AddCommand( cmd_name, function, "" ); + Cmd_AddGameCommand( cmd_name, function ); } /* @@ -4273,6 +4273,11 @@ void SV_UnloadProgs( void ) Mem_FreePool( &svgame.stringspool ); else StringTable_Delete( svgame.hStringTable ); + if( svgame.dllFuncs2.pfnGameShutdown ) + { + svgame.dllFuncs2.pfnGameShutdown (); + } + // now we can unload cvars Cvar_FullSet( "host_gameloaded", "0", CVAR_INIT ); @@ -4292,6 +4297,7 @@ bool SV_LoadProgs( const char *name ) static APIFUNCTION2 GetEntityAPI2; static GIVEFNPTRSTODLL GiveFnptrsToDll; static NEW_DLL_FUNCTIONS_FN GiveNewDllFuncs; + static enginefuncs_t gpEngfuncs; static globalvars_t gpGlobals; static playermove_t gpMove; edict_t *e; @@ -4308,6 +4314,9 @@ bool SV_LoadProgs( const char *name ) // make sure what new dll functions is cleared Mem_Set( &svgame.dllFuncs2, 0, sizeof( svgame.dllFuncs2 )); + // make local copy of engfuncs to prevent overwrite it with bots.dll + Mem_Copy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs )); + GetEntityAPI = (APIFUNCTION)FS_GetProcAddress( svgame.hInstance, "GetEntityAPI" ); GetEntityAPI2 = (APIFUNCTION2)FS_GetProcAddress( svgame.hInstance, "GetEntityAPI2" ); GiveNewDllFuncs = (NEW_DLL_FUNCTIONS_FN)FS_GetProcAddress( svgame.hInstance, "GetNewDLLFunctions" ); @@ -4330,7 +4339,7 @@ bool SV_LoadProgs( const char *name ) return false; } - GiveFnptrsToDll( &gEngfuncs, svgame.globals ); + GiveFnptrsToDll( &gpEngfuncs, svgame.globals ); // get extended callbacks if( GiveNewDllFuncs ) diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 128864ad..3ae8dec5 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -82,6 +82,7 @@ void SV_CalcPings( void ) { cl = &svs.clients[i]; if( cl->state != cs_spawned ) continue; + if( cl->fakeclient ) continue; total = count = 0; @@ -89,7 +90,7 @@ void SV_CalcPings( void ) { client_frame_t *frame; - frame = &cl->frames[(cl->netchan.incoming_acknowledged - 1 - j) & SV_UPDATE_MASK]; + frame = &cl->frames[(cl->netchan.incoming_acknowledged - (j + 1)) & SV_UPDATE_MASK]; if( frame->latency > 0 ) { count++; diff --git a/engine/server/sv_pmove.c b/engine/server/sv_pmove.c index 93b27ef6..a1bed43b 100644 --- a/engine/server/sv_pmove.c +++ b/engine/server/sv_pmove.c @@ -306,22 +306,10 @@ static pmtrace_t *pfnTraceLine( float *start, float *end, int flags, int usehull return &tr; } -// FIXME: re-order modtypes static int pfnGetModelType( model_t *mod ) { - if( !mod ) return -1; - - switch( mod->type ) - { - case mod_brush: - case mod_world: - return 0; - case mod_studio: - return 3; - case mod_sprite: - return 1; - } - return -1; + if( !mod ) return mod_bad; + return mod->type; } static void pfnGetModelBounds( model_t *mod, float *mins, float *maxs ) diff --git a/engine/server/sv_world.c b/engine/server/sv_world.c index 7260db66..299f69bd 100644 --- a/engine/server/sv_world.c +++ b/engine/server/sv_world.c @@ -121,7 +121,7 @@ hull_t *SV_HullForEntity( edict_t *ent, int hullNumber, vec3_t mins, vec3_t maxs model = CM_ClipHandleToModel( ent->v.modelindex ); - if( !model || model->type != mod_brush && model->type != mod_world ) + if( !model || model->type != mod_brush ) Host_Error( "MOVETYPE_PUSH with a non bsp model\n" ); VectorSubtract( maxs, mins, size ); @@ -223,7 +223,7 @@ hull_t *SV_HullForBsp( edict_t *ent, const vec3_t mins, const vec3_t maxs, float // decide which clipping hull to use, based on the size model = CM_ClipHandleToModel( ent->v.modelindex ); - if( !model || ( model->type != mod_brush && model->type != mod_world )) + if( !model || model->type != mod_brush ) Host_Error( "Entity %i SOLID_BSP with a non bsp model %i\n", ent->serialnumber, model->type ); VectorSubtract( maxs, mins, size ); @@ -1066,7 +1066,7 @@ const char *SV_TraceTexture( edict_t *ent, const vec3_t start, const vec3_t end vec3_t temp, offset; bmodel = CM_ClipHandleToModel( ent->v.modelindex ); - if( !bmodel || bmodel->type != mod_brush && bmodel->type != mod_world ) + if( !bmodel || bmodel->type != mod_brush ) return NULL; hull = SV_HullForBsp( ent, vec3_origin, vec3_origin, offset ); @@ -1097,7 +1097,9 @@ const char *SV_TraceTexture( edict_t *ent, const vec3_t start, const vec3_t end } surf = SV_RecursiveSurfCheck( &bmodel->nodes[hull->firstclipnode], start_l, end_l ); - if( !surf ) return NULL; + + if( !surf || !surf->texinfo || !surf->texinfo->texture ) + return NULL; return surf->texinfo->texture->name; } diff --git a/launch/cmd.c b/launch/cmd.c index 57eb99d3..ff247dc4 100644 --- a/launch/cmd.c +++ b/launch/cmd.c @@ -318,12 +318,15 @@ void Cmd_Echo_f( void ) ============================================================================= */ +#define CMD_EXTDLL BIT( 0 ) + typedef struct cmd_function_s { struct cmd_function_s *next; char *name; char *desc; xcommand_t function; + int flags; } cmd_function_t; static int cmd_argc; @@ -336,7 +339,7 @@ static cmd_function_t *cmd_functions; // possible commands to execute Cmd_Argc ============ */ -uint Cmd_Argc (void) +uint Cmd_Argc( void ) { return cmd_argc; } @@ -465,14 +468,14 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_ cmd_function_t *cmd; // fail if the command already exists - if(Cmd_Exists( cmd_name )) + if( Cmd_Exists( cmd_name )) { MsgDev(D_INFO, "Cmd_AddCommand: %s already defined\n", cmd_name); return; } // use a small malloc to avoid zone fragmentation - cmd = Malloc(sizeof(cmd_function_t)); + cmd = Malloc( sizeof( cmd_function_t )); cmd->name = copystring( cmd_name ); cmd->desc = copystring( cmd_desc ); cmd->function = function; @@ -480,6 +483,31 @@ void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_ cmd_functions = cmd; } +/* +============ +Cmd_AddGameCommand +============ +*/ +void Cmd_AddGameCommand( const char *cmd_name, xcommand_t function ) +{ + cmd_function_t *cmd; + + // fail if the command already exists + if( Cmd_Exists( cmd_name )) + { + MsgDev(D_INFO, "Cmd_AddCommand: %s already defined\n", cmd_name); + return; + } + + // use a small malloc to avoid zone fragmentation + cmd = Malloc( sizeof( cmd_function_t )); + cmd->name = copystring( cmd_name ); + cmd->function = function; + cmd->flags = CMD_EXTDLL; + cmd->next = cmd_functions; + cmd_functions = cmd; +} + /* ============ Cmd_RemoveCommand @@ -612,6 +640,48 @@ void Cmd_List_f( void ) Msg( "%i commands\n", i ); } +/* +============ +Cmd_Unlink + +unlink all commands with flag CVAR_EXTDLL +============ +*/ +void Cmd_Unlink( void ) +{ + cmd_function_t *cmd; + cmd_function_t **prev; + int count = 0; + + if( Cvar_VariableInteger( "host_gameloaded" )) + { + Msg( "can't unlink cvars while game is loaded\n" ); + return; + } + + // unlink commands first + Cmd_Unlink (); + + prev = &cmd_functions; + while( 1 ) + { + cmd = *prev; + if( !cmd ) break; + + if( !( cmd->flags & CMD_EXTDLL )) + { + prev = &cmd->next; + continue; + } + + *prev = cmd->next; + if( cmd->name ) Mem_Free( cmd->name ); + if( cmd->desc ) Mem_Free( cmd->desc ); + Mem_Free( cmd ); + count++; + } +} + /* ============ Cmd_Init diff --git a/launch/console.c b/launch/console.c index a7c67cd0..cafd6422 100644 --- a/launch/console.c +++ b/launch/console.c @@ -508,4 +508,5 @@ void Sys_PrintLog( const char *pMsg ) { if( !Sys.logfile ) return; fprintf( Sys.logfile, pMsg ); + fflush( Sys.logfile ); } \ No newline at end of file diff --git a/launch/cvar.c b/launch/cvar.c index 0a771ea1..83531d39 100644 --- a/launch/cvar.c +++ b/launch/cvar.c @@ -230,33 +230,74 @@ Adds a freestanding variable to the variable list. */ void Cvar_RegisterVariable( cvar_t *var ) { - const char *oldstring; + convar_t **prev, *cur = NULL; + convar_t *find; ASSERT( var != NULL ); - - // first check to see if it has allready been defined - if( Cvar_FindVar( var->name )) - { - MsgDev( D_ERROR, "can't register variable %s, allready defined\n", var->name ); - return; - } - + // check for overlap with a command if( Cmd_Exists( var->name )) { MsgDev( D_ERROR, "Cvar_Register: %s is a command\n", var->name ); return; } - - // copy the value off, because future sets will Z_Free it - oldstring = var->string; - var->string = copystring( oldstring ); - var->value = com.atof( var->string ); - var->flags |= CVAR_EXTDLL; // all cvars passed this function are game cvars - // link the variable in - var->next = (cvar_t *)cvar_vars; - cvar_vars = (convar_t *)var; + // first check to see if it has allready been defined + if(( cur = Cvar_FindVar( var->name )) != NULL ) + { + // this cvar is already registered with Cvar_RegisterVariable + // so we can't replace it + if( cur->flags & CVAR_EXTDLL ) + { + MsgDev( D_ERROR, "can't register variable %s, allready defined\n", var->name ); + return; + } + } + + if( cur ) + { + prev = &cvar_vars; + + while( 1 ) + { + find = *prev; + ASSERT( find != NULL ); + + // search for previous cvar + if( cur != find->next ) + { + prev = &find->next; + continue; + } + + // link new variable + find->next = (convar_t *)var; + break; + } + + var->string = cur->string; // we already have right string + var->value = com.atof( var->string ); + var->flags |= CVAR_EXTDLL; // all cvars passed this function are game cvars + var->next = (cvar_t *)cur->next; + + // release current cvar (but keep string) + if( cur->name ) Mem_Free( cur->name ); + if( cur->latched_string ) Mem_Free( cur->latched_string ); + if( cur->reset_string ) Mem_Free( cur->reset_string ); + if( cur->description ) Mem_Free( cur->description ); + Mem_Free( cur ); + } + else + { + // copy the value off, because future sets will Z_Free it + var->string = copystring( var->string ); + var->value = com.atof( var->string ); + var->flags |= CVAR_EXTDLL; // all cvars passed this function are game cvars + + // link the variable in + var->next = (cvar_t *)cvar_vars; + cvar_vars = (convar_t *)var; + } } /* @@ -689,10 +730,8 @@ bool Cvar_Command( void ) // perform a variable print or set if( Cmd_Argc() == 1 ) { - if( v->flags & CVAR_INIT ) Msg( "%s: %s\n", v->name, v->string ); + if( v->flags & ( CVAR_INIT|CVAR_EXTDLL )) Msg( "%s: %s\n", v->name, v->string ); else Msg( "%s: %s ( ^3%s^7 )\n", v->name, v->string, v->reset_string ); - if( v->flags & CVAR_EXTDLL ) Msg( "%s: %s\n", v->name, v->string ); - else if( v->latched_string ) Msg( "%s: %s\n", v->name, v->latched_string ); return true; } @@ -1098,7 +1137,7 @@ void Cvar_LatchedAudio_f( void ) ============ Cvar_Unlink_f -Now all latched audio strings is valid +unlink all cvars with flag CVAR_EXTDLL ============ */ void Cvar_Unlink_f( void ) diff --git a/launch/filesystem.c b/launch/filesystem.c index 79f3e78f..1ad1b0e4 100644 --- a/launch/filesystem.c +++ b/launch/filesystem.c @@ -2932,7 +2932,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, bool directpath ) string dllpath; searchpath_t *search; dll_user_t *hInst; - int index; + int i, index; // check for bad exports if( !dllname || !*dllname ) @@ -2944,7 +2944,14 @@ dll_user_t *FS_FindLibrary( const char *dllname, bool directpath ) fs_ext_path = directpath; - com.strncpy( dllpath, dllname, sizeof( dllpath )); + // replace all backward slashes + for( i = 0; i < com.strlen( dllname ); i++ ) + { + if( dllname[i] == '\\' ) dllpath[i] = '/'; + else dllpath[i] = com.tolower( dllname[i] ); + } + dllpath[i] = '\0'; + FS_DefaultExtension( dllpath, ".dll" ); // trying to apply if forget search = FS_FindFile( dllpath, &index, false ); diff --git a/launch/launch.h b/launch/launch.h index 9d958b4c..329d03e3 100644 --- a/launch/launch.h +++ b/launch/launch.h @@ -409,7 +409,9 @@ uint Cmd_Argc( void ); char *Cmd_Args( void ); char *Cmd_Argv( uint arg ); void Cmd_Init( void ); +void Cmd_Unlink( void ); void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc ); +void Cmd_AddGameCommand( const char *cmd_name, xcommand_t function ); void Cmd_RemoveCommand( const char *cmd_name ); bool Cmd_Exists( const char *cmd_name ); void Cmd_LookupCmds( char *buffer, void *ptr, setpair_t callback ); diff --git a/launch/system.c b/launch/system.c index 67691e63..08c5a1b5 100644 --- a/launch/system.c +++ b/launch/system.c @@ -158,6 +158,7 @@ void Sys_GetStdAPI( void ) com.Cmd_Argv = Cmd_Argv; com.Cmd_LookupCmds = Cmd_LookupCmds; com.Cmd_AddCommand = Cmd_AddCommand; + com.Cmd_AddGameCommand = Cmd_AddGameCommand; com.Cmd_DelCommand = Cmd_RemoveCommand; com.Cmd_TokenizeString = Cmd_TokenizeString; diff --git a/public/launch_api.h b/public/launch_api.h index c62c1f97..4b87b65f 100644 --- a/public/launch_api.h +++ b/public/launch_api.h @@ -593,6 +593,7 @@ typedef struct stdilib_api_s char *(*Cmd_Argv)( uint arg ); void (*Cmd_LookupCmds)( char *buffer, void *ptr, setpair_t callback ); void (*Cmd_AddCommand)( const char *name, xcommand_t function, const char *desc ); + void (*Cmd_AddGameCommand)( const char *cmd_name, xcommand_t function ); void (*Cmd_TokenizeString)( const char *text_in ); void (*Cmd_DelCommand)( const char *name ); @@ -905,6 +906,7 @@ console commands #define Cmd_TokenizeString com.Cmd_TokenizeString #define Cmd_LookupCmds com.Cmd_LookupCmds #define Cmd_AddCommand com.Cmd_AddCommand +#define Cmd_AddGameCommand com.Cmd_AddGameCommand #define Cmd_RemoveCommand com.Cmd_DelCommand /* diff --git a/vid_gl/r_model.h b/vid_gl/r_model.h index a2f21ba8..4a1989ca 100644 --- a/vid_gl/r_model.h +++ b/vid_gl/r_model.h @@ -41,6 +41,16 @@ BRUSH MODELS // // in memory representation // +typedef enum +{ + mod_bad = -1, + mod_brush, + mod_sprite, + mod_alias, + mod_studio, + mod_world, // added +} modtype_t; + typedef struct { vec3_t mins, maxs; diff --git a/vid_gl/r_studio.c b/vid_gl/r_studio.c index a271ef80..0b01ffd9 100644 --- a/vid_gl/r_studio.c +++ b/vid_gl/r_studio.c @@ -2625,7 +2625,9 @@ void R_AddStudioModelToList( ref_entity_t *e ) void R_StudioRunEvents( ref_entity_t *e ) { - if( !e->model->extradata ) return; + if( !e || !e->model || !e->model->extradata ) + return; + if( RP_FOLLOWENTITY( e )) return; RI.currententity = e;