diff --git a/changelog.txt b/changelog.txt index 7207974..9211d39 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,16 @@ +DD Mmm 18 - 1.51 + +add: /unset to remove a user-created cvar + +add: /setempty to set a string cvar to an empty string + +add: /toggle can now accept a value sequence (2 or more entries) to loop through + syntax: /toggle [ [value3]..] + if the cvar's current value is in the sequence and not in the last spot, the next one is used + otherwise, the first value in the sequence is used + + 12 Feb 18 - 1.50 add: on Windows, "/crashreport:yes" and "/crashreport:no" command-line arguments diff --git a/code/qcommon/common_help.h b/code/qcommon/common_help.h index ab4d43e..fb58327 100644 --- a/code/qcommon/common_help.h +++ b/code/qcommon/common_help.h @@ -7,7 +7,13 @@ #define help_toggle \ "toggles the boolean value of a variable\n" \ -"Non-" S_COLOR_VAL "0 " S_COLOR_HELP "becomes " S_COLOR_VAL "0 " S_COLOR_HELP "and " S_COLOR_VAL "0 " S_COLOR_HELP "becomes " S_COLOR_VAL "1" S_COLOR_HELP "." +"Example: " S_COLOR_CMD "toggle " S_COLOR_CVAR "v\n" S_COLOR_HELP \ +" non-" S_COLOR_VAL "0 " S_COLOR_HELP "=> " S_COLOR_VAL "0 \n" \ +" 0 " S_COLOR_HELP "=> " S_COLOR_VAL "1\n" S_COLOR_HELP \ +"Example: " S_COLOR_CMD "toggle " S_COLOR_CVAR "v " S_COLOR_VAL "a b c\n" S_COLOR_HELP \ +" non-" S_COLOR_VAL "abc " S_COLOR_HELP "=> " S_COLOR_VAL "a\n" \ +" a " S_COLOR_HELP "=> " S_COLOR_VAL "b " S_COLOR_HELP "| " S_COLOR_VAL "b " S_COLOR_HELP "=> " S_COLOR_VAL "c " \ + S_COLOR_HELP "| " S_COLOR_VAL "c " S_COLOR_HELP "=> " S_COLOR_VAL "a" #define help_cvarlist \ "lists and filters all cvars\n" \ diff --git a/code/qcommon/cvar.cpp b/code/qcommon/cvar.cpp index e71a339..7d2e520 100644 --- a/code/qcommon/cvar.cpp +++ b/code/qcommon/cvar.cpp @@ -837,13 +837,111 @@ static void Cvar_CompleteName( int startArg, int compArg ) static void Cvar_Toggle_f( void ) { - if ( Cmd_Argc() != 2 ) { - Com_Printf ("usage: toggle \n"); + const int argc = Cmd_Argc(); + if ( argc != 2 && argc < 4 ) { + Com_Printf( "usage: toggle [ [value3]..]\n" ); return; } - int v = !Cvar_VariableValue( Cmd_Argv( 1 ) ); - Cvar_Set2( Cmd_Argv(1), va("%i", v), qfalse ); + const char* const name = Cmd_Argv(1); + const cvar_t* const cvar = Cvar_FindVar( name ); + if ( !cvar ) + return; + + if ( argc == 2 ) { + const int v = !Cvar_VariableIntegerValue( name ); + Cvar_Set2( name, va("%i", v), qfalse ); + return; + } + + // set the next value - if none found, set the first value + int index = -1; + const int valueOffset = 2; + const int valueCount = argc - valueOffset; + for ( int i = 0; i < valueCount; ++i ) + { + if ( !Q_stricmp(Cmd_Argv(i + valueOffset), cvar->string) ) { + index = (i + 1) % valueCount; + break; + } + } + if ( index < 0 ) + index = 0; + + Cvar_Set2( name, Cmd_Argv(index + valueOffset), qfalse ); +} + + +// frees resources associated to a cvar, then clears it + +static void Cvar_Nuke( cvar_t* var ) +{ + if ( var->name ) + Z_Free( var->name ); + + if ( var->string ) + Z_Free( var->string ); + + if ( var->latchedString ) + Z_Free( var->latchedString ); + + if ( var->resetString ) + Z_Free( var->resetString ); + + if ( var->desc ) + Z_Free( var->desc ); + + if ( var->help ) + Z_Free( var->help ); + + // clear the var completely, since we + // can't remove the index from the list + Com_Memset( var, 0, sizeof( var ) ); +} + + +// removes a user-created cvar + +static void Cvar_Unset_f( void ) +{ + if ( Cmd_Argc() != 2 ) { + Com_Printf( "usage: unset \n" ); + return; + } + + const char* const name = Cmd_Argv(1); + cvar_t** prev = &cvar_vars; + while ( 1 ) { + cvar_t* const var = *prev; + if ( !var ) + break; + + if ( (var->flags & CVAR_USER_CREATED) != 0 && !Q_stricmp(var->name, name) ) { + *prev = var->next; + Cvar_Nuke( var ); + break; + } + + prev = &var->next; + } +} + + +// sets a cvar to an empty string + +static void Cvar_SetEmpty_f( void ) +{ + if ( Cmd_Argc() != 2 ) { + Com_Printf( "usage: setempty \n" ); + return; + } + + const char* const name = Cmd_Argv(1); + const cvar_t* const cvar = Cvar_FindVar( name ); + if ( !cvar || cvar->type != CVART_STRING ) + return; + + Cvar_Set( Cmd_Argv(1), "" ); } @@ -985,27 +1083,7 @@ static void Cvar_Restart( qbool reset ) // throw out any variables the user created if ( var->flags & CVAR_USER_CREATED ) { *prev = var->next; - if ( var->name ) { - Z_Free( var->name ); - } - if ( var->string ) { - Z_Free( var->string ); - } - if ( var->latchedString ) { - Z_Free( var->latchedString ); - } - if ( var->resetString ) { - Z_Free( var->resetString ); - } - if ( var->desc ) { - Z_Free( var->desc ); - } - if ( var->help ) { - Z_Free( var->help ); - } - // clear the var completely, since we - // can't remove the index from the list - Com_Memset( var, 0, sizeof( var ) ); + Cvar_Nuke( var ); continue; } @@ -1154,6 +1232,8 @@ static const cmdTableItem_t cl_cmds[] = { "setu", Cvar_SetU_f, Cvar_CompleteName, "like /set with the user info flag" }, { "seta", Cvar_SetA_f, Cvar_CompleteName, "like /set with the archive flag" }, { "reset", Cvar_Reset_f, Cvar_CompleteName, "sets a cvar back to its default value" }, + { "unset", Cvar_Unset_f, Cvar_CompleteName, "removes a user-created cvar" }, + { "setempty", Cvar_SetEmpty_f, Cvar_CompleteName, "sets a cvar to an empty string" }, { "cvarlist", Cvar_List_f, NULL, help_cvarlist }, { "cvar_restart", Cvar_Restart_f, NULL, "restarts the cvar system" }, { "cvar_trim", Cvar_Trim_f, NULL, "removes user-created cvars" }