From ec5b6793f728ac2cf5cceab6a9c7178c07c02e3e Mon Sep 17 00:00:00 2001 From: Krispy Date: Fri, 30 Aug 2024 18:15:53 -0500 Subject: [PATCH] Added CommandLink and Callback system from idTech5 --- neo/framework/CVarSystem.cpp | 33 +++++ neo/framework/CVarSystem.h | 3 + neo/framework/CmdSystem.cpp | 15 ++- neo/framework/CmdSystem.h | 76 +++++++++++ neo/framework/Common.cpp | 182 +++++++++++++++------------ neo/framework/ConsoleHistory.cpp | 4 - neo/framework/Dhewm3SettingsMenu.cpp | 22 ---- neo/framework/Session.cpp | 104 ++++++--------- neo/framework/Session_menu.cpp | 2 +- neo/idlib/CMakeLists.txt | 1 + neo/idlib/Callback.h | 173 +++++++++++++++++++++++++ neo/idlib/CmdArgs.cpp | 6 +- neo/idlib/CmdArgs.h | 2 +- neo/idlib/CommandLink.cpp | 59 +++++++++ 14 files changed, 505 insertions(+), 177 deletions(-) create mode 100644 neo/idlib/Callback.h create mode 100644 neo/idlib/CommandLink.cpp diff --git a/neo/framework/CVarSystem.cpp b/neo/framework/CVarSystem.cpp index 799c566ef..3f7ee8fcf 100644 --- a/neo/framework/CVarSystem.cpp +++ b/neo/framework/CVarSystem.cpp @@ -61,6 +61,8 @@ class idInternalCVar : public idCVar { idStr valueString; // value idStr descriptionString; // description + virtual const char * InternalGetResetString() const; + virtual void InternalSetString( const char *newValue ); virtual void InternalServerSetString( const char *newValue ); virtual void InternalSetBool( const bool newValue ); @@ -364,6 +366,15 @@ void idInternalCVar::Reset( void ) { UpdateValue(); } +/* +============ +idInternalCVar::InternalGetResetString +============ +*/ +const char * idInternalCVar::InternalGetResetString() const { + return resetString; +} + /* ============ idInternalCVar::InternalSetString @@ -482,6 +493,7 @@ class idCVarSystemLocal : public idCVarSystem { static void ListByFlags( const idCmdArgs &args, cvarFlags_t flags ); static void List_f( const idCmdArgs &args ); static void Restart_f( const idCmdArgs &args ); + static void CvarAdd_f( const idCmdArgs &args ); }; idCVarSystemLocal localCVarSystem; @@ -581,6 +593,7 @@ void idCVarSystemLocal::Init( void ) { cmdSystem->AddCommand( "reset", Reset_f, CMD_FL_SYSTEM, "resets a cvar" ); cmdSystem->AddCommand( "listCvars", List_f, CMD_FL_SYSTEM, "lists cvars" ); cmdSystem->AddCommand( "cvar_restart", Restart_f, CMD_FL_SYSTEM, "restart the cvar system" ); + cmdSystem->AddCommand( "cvarAdd", CvarAdd_f, CMD_FL_SYSTEM, "adds a value to a numeric cvar" ); initialized = true; } @@ -1052,6 +1065,26 @@ void idCVarSystemLocal::Reset_f( const idCmdArgs &args ) { cvar->Reset(); } +/* +============ +idCVarSystemLocal::CvarAdd_f +============ +*/ +void idCVarSystemLocal::CvarAdd_f( const idCmdArgs &args ) { + if ( args.Argc() != 3 ) { + common->Printf ("usage: cvarAdd \n"); + } + + idInternalCVar *cvar = localCVarSystem.FindInternal( args.Argv( 1 ) ); + if ( !cvar ) { + return; + } + + const float newValue = cvar->GetFloat() + atof( args.Argv( 2 ) ); + cvar->SetFloat( newValue ); + common->Printf( "%s = %f\n", cvar->GetName(), newValue ); +} + /* ============ idCVarSystemLocal::ListByFlags diff --git a/neo/framework/CVarSystem.h b/neo/framework/CVarSystem.h index 9927f59fb..e83047479 100644 --- a/neo/framework/CVarSystem.h +++ b/neo/framework/CVarSystem.h @@ -138,6 +138,7 @@ class idCVar { void SetModified( void ) { internalVar->flags |= CVAR_MODIFIED; } void ClearModified( void ) { internalVar->flags &= ~CVAR_MODIFIED; } + const char * GetDefaultString( void ) const { return internalVar->InternalGetResetString(); } const char * GetString( void ) const { return internalVar->value; } bool GetBool( void ) const { return ( internalVar->integerValue != 0 ); } int GetInteger( void ) const { return internalVar->integerValue; } @@ -175,6 +176,8 @@ class idCVar { virtual void InternalSetInteger( const int newValue ) {} virtual void InternalSetFloat( const float newValue ) {} + virtual const char * InternalGetResetString() const { return value; } + static idCVar * staticVars; }; diff --git a/neo/framework/CmdSystem.cpp b/neo/framework/CmdSystem.cpp index b09f68de4..fc759f8c7 100644 --- a/neo/framework/CmdSystem.cpp +++ b/neo/framework/CmdSystem.cpp @@ -46,7 +46,11 @@ typedef struct commandDef_s { char * description; } commandDef_t; - +/* +================================================ +idCmdSystemLocal +================================================ +*/ class idCmdSystemLocal : public idCmdSystem { public: virtual void Init( void ); @@ -58,6 +62,8 @@ class idCmdSystemLocal : public idCmdSystem { virtual void CommandCompletion( void(*callback)( const char *s ) ); virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ); + virtual void ExecuteCommandText( const char * text ); + virtual void AppendCommandText( const char * text ); virtual void BufferCommandText( cmdExecution_t exec, const char *text ); virtual void ExecuteCommandBuffer( void ); @@ -93,9 +99,7 @@ class idCmdSystemLocal : public idCmdSystem { private: void ExecuteTokenizedString( const idCmdArgs &args ); - void ExecuteCommandText( const char *text ); void InsertCommandText( const char *text ); - void AppendCommandText( const char *text ); static void ListByFlags( const idCmdArgs &args, cmdFlags_t flags ); static void List_f( const idCmdArgs &args ); @@ -329,6 +333,11 @@ void idCmdSystemLocal::Init( void ) { AddCommand( "parse", Parse_f, CMD_FL_SYSTEM, "prints tokenized string" ); AddCommand( "wait", Wait_f, CMD_FL_SYSTEM, "delays remaining buffered commands one or more frames" ); + // link in all the commands declared with static idCommandLink variables or CONSOLE_COMMAND macros + for ( idCommandLink * link = CommandLinks(); link != NULL; link = link->next ) { + AddCommand( link->cmdName_, link->function_, CMD_FL_SYSTEM, link->description_, link->argCompletion_ ); + } + completionString = "*"; textLength = 0; diff --git a/neo/framework/CmdSystem.h b/neo/framework/CmdSystem.h index af8b52e71..fffdadd37 100644 --- a/neo/framework/CmdSystem.h +++ b/neo/framework/CmdSystem.h @@ -68,6 +68,74 @@ typedef void (*cmdFunction_t)( const idCmdArgs &args ); // argument completion function typedef void (*argCompletion_t)( const idCmdArgs &args, void(*callback)( const char *s ) ); +/* +================================================ +idCommandLink is a convenient way to get a function registered as a +ConsoleCommand without having to add an explicit call to idCmdSystem->AddCommand() in a startup +function somewhere. Simply declare a static variable with the parameters and it will get +executed before main(). For example: + +static idCommandLink sys_dumpMemory( "sys_dumpMemory", Sys_DumpMemory_f, "Walks the heap and reports stats" ); +================================================ +*/ + +class idCommandLink { +public: + idCommandLink( const char *cmdName, cmdFunction_t function, + const char *description, argCompletion_t argCompletion = NULL ); + idCommandLink * next; + const char * cmdName_; + cmdFunction_t function_; + const char * description_; + argCompletion_t argCompletion_; +}; + +// The command system will create commands for all the static definitions +// when it initializes. +idCommandLink *CommandLinks( idCommandLink *cl = NULL ); + +/* +================================================ +The CONSOLE_COMMAND macro is an even easier way to create a console command by +automatically generating the idCommandLink variable, and it also allows all the +command code to be stripped from a build with a single define. For example: + +CONSOLE_COMMAND( Sys_DumpMemory, "Walks the heap and reports stats" ) { + // do stuff +} + +NOTE: All CONSOLE_COMMANDs will be stripped with the shipping build unless it's +created using the CONSOLE_COMMAND_SHIP macro. +================================================ +*/ + +#if defined ( ID_RETAIL ) +#define CONSOLE_COMMAND_SHIP CONSOLE_COMMAND_COMPILE +#define CONSOLE_COMMAND CONSOLE_COMMAND_NO_COMPILE +// We need to disable this warning to get commands that were made friends +// of classes to compile as inline. +// warning C4211: nonstandard extension used : redefined extern to static +#pragma warning( disable : 4211 ) +// warning C4505: 'xxx' : unreferenced local function has been removed +#pragma warning( disable : 4505 ) +#else +#define CONSOLE_COMMAND_SHIP CONSOLE_COMMAND_COMPILE +#define CONSOLE_COMMAND CONSOLE_COMMAND_COMPILE +#endif + +// Turn console commands into static inline code, which will cause them to be +// removed from the build. +#define CONSOLE_COMMAND_NO_COMPILE( name, comment, completion ) \ + static inline void name ## _f( const idCmdArgs &args ) + +// lint incorrectly gives this for all console commands: Issue 1568: (Warning -- Variable 'TestAtomicString_v' accesses variable 'atomicStringManager' before the latter is initialized through calls: 'TestAtomicString_f() => idAtomicString::FreeDynamic()') +// I can't figure out how to disable this just around CONSOLE_COMMAND, so it must stay disabled everywhere, +// which is a shame. +//lint -e1568 +#define CONSOLE_COMMAND_COMPILE( name, comment, completion ) \ + void name ## _f( const idCmdArgs &args ); \ + idCommandLink name ## _v( #name, name ## _f, comment, completion ); \ + void name ## _f( const idCmdArgs &args ) class idCmdSystem { public: @@ -87,6 +155,9 @@ class idCmdSystem { virtual void CommandCompletion( void(*callback)( const char *s ) ) = 0; virtual void ArgCompletion( const char *cmdString, void(*callback)( const char *s ) ) = 0; + virtual void ExecuteCommandText( const char * text ) = 0; + virtual void AppendCommandText( const char * text ) = 0; + // Adds command text to the command buffer, does not add a final \n virtual void BufferCommandText( cmdExecution_t exec, const char *text ) = 0; // Pulls off \n \r or ; terminated lines of text from the command buffer and @@ -119,6 +190,7 @@ class idCmdSystem { static void ArgCompletion_ModelName( const idCmdArgs &args, void(*callback)( const char *s ) ); static void ArgCompletion_SoundName( const idCmdArgs &args, void(*callback)( const char *s ) ); static void ArgCompletion_ImageName( const idCmdArgs &args, void(*callback)( const char *s ) ); + static void ArgCompletion_GuiName( const idCmdArgs &args, void(*callback)( const char *s ) ); static void ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) ); static void ArgCompletion_ConfigName( const idCmdArgs &args, void(*callback)( const char *s ) ); static void ArgCompletion_SaveGame( const idCmdArgs &args, void(*callback)( const char *s ) ); @@ -169,6 +241,10 @@ ID_INLINE void idCmdSystem::ArgCompletion_ImageName( const idCmdArgs &args, void cmdSystem->ArgCompletion_FolderExtension( args, callback, "/", false, ".tga", ".dds", ".jpg", ".png", NULL ); } +ID_INLINE void idCmdSystem::ArgCompletion_GuiName( const idCmdArgs &args, void(*callback)( const char *s ) ) { + cmdSystem->ArgCompletion_FolderExtension( args, callback, "guis/", false, ".gui", NULL ); +} + ID_INLINE void idCmdSystem::ArgCompletion_VideoName( const idCmdArgs &args, void(*callback)( const char *s ) ) { cmdSystem->ArgCompletion_FolderExtension( args, callback, "video/", false, ".roq", NULL ); } diff --git a/neo/framework/Common.cpp b/neo/framework/Common.cpp index 64bc675ea..eeae1faff 100644 --- a/neo/framework/Common.cpp +++ b/neo/framework/Common.cpp @@ -1108,7 +1108,7 @@ idCmdSystemLocal::PrintMemInfo_f This prints out memory debugging data ============ */ -static void PrintMemInfo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( printMemInfo, "prints memory debugging data", NULL ) { MemInfo_t mi; memset( &mi, 0, sizeof( mi ) ); @@ -1136,12 +1136,13 @@ static void PrintMemInfo_f( const idCmdArgs &args ) { return; } - f->Printf( "total(%s ) image(%s ) model(%s ) sound(%s ): %s\n", idStr::FormatNumber( mi.assetTotals ).c_str(), idStr::FormatNumber( mi.imageAssetsTotal ).c_str(), + f->Printf( "total(%s ) image(%s ) model(%s ) sound(%s ): %s\n", idStr::FormatNumber( mi.assetTotals ).c_str(), idStr::FormatNumber( mi.imageAssetsTotal ).c_str(), idStr::FormatNumber( mi.modelAssetsTotal ).c_str(), idStr::FormatNumber( mi.soundAssetsTotal ).c_str(), mi.filebase.c_str() ); fileSystem->CloseFile( f ); } + #ifdef ID_ALLOW_TOOLS /* ================== @@ -1204,6 +1205,7 @@ static void Com_EditScripts_f( const idCmdArgs &args ) { #endif // ID_ALLOW_TOOLS #ifdef _DEBUG + /* ================== Com_Error_f @@ -1211,12 +1213,7 @@ Com_Error_f Just throw a fatal error to test error shutdown procedures. ================== */ -static void Com_Error_f( const idCmdArgs &args ) { - if ( !com_developer.GetBool() ) { - commonLocal.Printf( "error may only be used in developer mode\n" ); - return; - } - +CONSOLE_COMMAND( error, "causes an error", NULL ) { if ( args.Argc() > 1 ) { commonLocal.FatalError( "Testing fatal error" ); } else { @@ -1231,7 +1228,7 @@ Com_Freeze_f Just freeze in place for a given number of seconds to test error recovery. ================== */ -static void Com_Freeze_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( freeze, "freezes the game for a number of seconds", NULL ) { float s; int start, now; @@ -1240,11 +1237,6 @@ static void Com_Freeze_f( const idCmdArgs &args ) { return; } - if ( !com_developer.GetBool() ) { - commonLocal.Printf( "freeze may only be used in developer mode\n" ); - return; - } - s = atof( args.Argv(1) ); start = eventLoop->Milliseconds(); @@ -1264,12 +1256,7 @@ Com_Crash_f A way to force a bus error for development reasons ================= */ -static void Com_Crash_f( const idCmdArgs &args ) { - if ( !com_developer.GetBool() ) { - commonLocal.Printf( "crash may only be used in developer mode\n" ); - return; - } - +CONSOLE_COMMAND( crash, "causes a crash", NULL ) { #ifdef __GNUC__ __builtin_trap(); #else @@ -1283,7 +1270,7 @@ static void Com_Crash_f( const idCmdArgs &args ) { Com_Quit_f ================= */ -static void Com_Quit_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( quit, "quits the game", NULL ) { commonLocal.Quit(); } @@ -1294,7 +1281,7 @@ Com_WriteConfig_f Write the config file to a specific name =============== */ -void Com_WriteConfig_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( writeConfig, "writes a config file", NULL ) { idStr filename; if ( args.Argc() != 2 ) { @@ -1313,7 +1300,7 @@ void Com_WriteConfig_f( const idCmdArgs &args ) { Com_SetMachineSpecs_f ================= */ -void Com_SetMachineSpec_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( setMachineSpec, "detects system capabilities and sets com_machineSpec to appropriate value", NULL ) { commonLocal.SetMachineSpec(); } @@ -1326,7 +1313,7 @@ Com_ExecMachineSpecs_f void OSX_GetVideoCard( int& outVendorId, int& outDeviceId ); bool OSX_GetCPUIdentification( int& cpuId, bool& oldArchitecture ); #endif -void Com_ExecMachineSpec_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( execMachineSpec, "execs the appropriate config files and sets cvars based on com_machineSpec", NULL ) { // DG: add an optional "nores" argument for "don't change the resolution" (r_mode) bool nores = args.Argc() > 1 && idStr::Icmp( args.Argv(1), "nores" ) == 0; cvarSystem->SetCVarInteger( "r_useSoftParticles", 0, CVAR_ARCHIVE ); // DG: disable soft particles for all but ultra @@ -1445,7 +1432,7 @@ void Com_ExecMachineSpec_f( const idCmdArgs &args ) { Com_ReloadEngine_f ================= */ -void Com_ReloadEngine_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( reloadEngine, "reloads the engine down to including the file system", NULL ) { bool menu = false; if ( !commonLocal.IsInitialized() ) { @@ -1711,7 +1698,7 @@ void idCommonLocal::LocalizeGui( const char *fileName, idLangDict &langDict ) { ReloadLanguage_f ================= */ -void Com_ReloadLanguage_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( reloadLanguage, "reload language dict", NULL ) { commonLocal.InitLanguageDict(); } @@ -1918,7 +1905,7 @@ int LocalizeMap(const char* mapName, idLangDict &langDict, ListHash& listHash, i LocalizeMaps_f ================= */ -void Com_LocalizeMaps_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( localizeMaps, "localize maps", NULL ) { if ( args.Argc() < 2 ) { common->Printf( "Usage: localizeMaps \n" ); return; @@ -1989,7 +1976,7 @@ void Com_LocalizeMaps_f( const idCmdArgs &args ) { LocalizeGuis_f ================= */ -void Com_LocalizeGuis_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( localizeGuis, "localize guis", NULL ) { if ( args.Argc() != 2 ) { common->Printf( "Usage: localizeGuis \n" ); @@ -2034,7 +2021,12 @@ void Com_LocalizeGuis_f( const idCmdArgs &args ) { strTable.Save( filename ); } -void Com_LocalizeGuiParmsTest_f( const idCmdArgs &args ) { +/* +================= +LocalizeGuiParmsTest_f +================= +*/ +CONSOLE_COMMAND( localizeGuiParmsTest, "Create test files that show gui parms localized and ignored.", NULL ) { common->SetRefreshOnPrint( true ); @@ -2080,8 +2072,12 @@ void Com_LocalizeGuiParmsTest_f( const idCmdArgs &args ) { common->SetRefreshOnPrint( false ); } - -void Com_LocalizeMapsTest_f( const idCmdArgs &args ) { +/* +================= +LocalizeMapsTest_f +================= +*/ +CONSOLE_COMMAND( localizeMapsTest, "Create test files that shows which strings will be localized.", NULL ) { ListHash listHash; LoadMapLocalizeData(listHash); @@ -2169,7 +2165,7 @@ void Com_LocalizeMapsTest_f( const idCmdArgs &args ) { Com_StartBuild_f ================= */ -void Com_StartBuild_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( StartBuild, "prepares to make a build.", NULL ) { globalImages->StartBuild(); } @@ -2178,19 +2174,84 @@ void Com_StartBuild_f( const idCmdArgs &args ) { Com_FinishBuild_f ================= */ -void Com_FinishBuild_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( finishBuild, "finishes the build process.", NULL ) { if ( game ) { game->CacheDictionaryMedia( NULL ); } globalImages->FinishBuild( ( args.Argc() > 1 ) ); } +/* +================= +ShowMemoryUsage_f +================= +*/ +CONSOLE_COMMAND( memoryDump, "creates a memory dump", NULL ) { + Mem_Dump_f( args ); +} + +/* +================= +ShowMemoryUsage_f +================= +*/ +CONSOLE_COMMAND( memoryDumpCompressed, "creates a compressed memory dump", NULL ) { + Mem_DumpCompressed_f( args ); +} + + +/* +================= +ShowMemoryUsage_f +================= +*/ +CONSOLE_COMMAND( showStringMemory, "shows memory used by strings", NULL ) { + idStr::ShowMemoryUsage_f( args ); +} + +/* +================= +ShowMemoryUsage_f +================= +*/ +CONSOLE_COMMAND( showDictMemory, "shows memory used by dictionaries", NULL ) { + idDict::ShowMemoryUsage_f( args ); +} + +/* +================= +ListKeys_f +================= +*/ +CONSOLE_COMMAND( listDictKeys, "lists all keys used by dictionaries", NULL ) { + idDict::ListKeys_f( args ); +} + +/* +================= +ListValues_f +================= +*/ +CONSOLE_COMMAND( listDictValues, "lists all values used by dictionaries", NULL ) { + idDict::ListValues_f( args ); +} + +/* +================= +Test_f +================= +*/ +CONSOLE_COMMAND( testSIMD, "test SIMD code", NULL ) { + idSIMD::Test_f( args ); +} + +#ifdef ID_DEDICATED /* ============== Com_Help_f ============== */ -void Com_Help_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( help, "shows help", NULL ) { common->Printf( "\nCommonly used commands:\n" ); common->Printf( " spawnServer - start the server.\n" ); common->Printf( " disconnect - shut down the server.\n" ); @@ -2211,6 +2272,7 @@ void Com_Help_f( const idCmdArgs &args ) { common->Printf( " g_mapCycle - name of .scriptcfg file for cycling maps.\n" ); common->Printf( "See mapcycle.scriptcfg for an example of a mapcyle script.\n\n" ); } +#endif /* ================= @@ -2218,18 +2280,6 @@ idCommonLocal::InitCommands ================= */ void idCommonLocal::InitCommands( void ) { -#ifdef _DEBUG - cmdSystem->AddCommand( "error", Com_Error_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "causes an error" ); - cmdSystem->AddCommand( "crash", Com_Crash_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "causes a crash" ); - cmdSystem->AddCommand( "freeze", Com_Freeze_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "freezes the game for a number of seconds" ); -#endif - cmdSystem->AddCommand( "quit", Com_Quit_f, CMD_FL_SYSTEM, "quits the game" ); - cmdSystem->AddCommand( "exit", Com_Quit_f, CMD_FL_SYSTEM, "exits the game" ); - cmdSystem->AddCommand( "writeConfig", Com_WriteConfig_f, CMD_FL_SYSTEM, "writes a config file" ); - cmdSystem->AddCommand( "reloadEngine", Com_ReloadEngine_f, CMD_FL_SYSTEM, "reloads the engine down to including the file system" ); - cmdSystem->AddCommand( "setMachineSpec", Com_SetMachineSpec_f, CMD_FL_SYSTEM, "detects system capabilities and sets com_machineSpec to appropriate value" ); - cmdSystem->AddCommand( "execMachineSpec", Com_ExecMachineSpec_f, CMD_FL_SYSTEM, "execs the appropriate config files and sets cvars based on com_machineSpec" ); - #if !defined( ID_DEDICATED ) // compilers cmdSystem->AddCommand( "dmap", Dmap_f, CMD_FL_TOOL, "compiles a map", idCmdSystem::ArgCompletion_MapName ); @@ -2243,42 +2293,14 @@ void idCommonLocal::InitCommands( void ) { #ifdef ID_ALLOW_TOOLS // editors cmdSystem->AddCommand( "editLights", Com_EditLights_f, CMD_FL_TOOL, "launches the in-game Light Editor" ); - //cmdSystem->AddCommand( "editSounds", Com_EditSounds_f, CMD_FL_TOOL, "launches the in-game Sound Editor" ); - //cmdSystem->AddCommand( "editDecls", Com_EditDecls_f, CMD_FL_TOOL, "launches the in-game Declaration Editor" ); + cmdSystem->AddCommand( "editSounds", Com_EditSounds_f, CMD_FL_TOOL, "launches the in-game Sound Editor" ); + cmdSystem->AddCommand( "editDecls", Com_EditDecls_f, CMD_FL_TOOL, "launches the in-game Declaration Editor" ); cmdSystem->AddCommand( "editAFs", Com_EditAFs_f, CMD_FL_TOOL, "launches the in-game Articulated Figure Editor" ); - //cmdSystem->AddCommand( "editParticles", Com_EditParticles_f, CMD_FL_TOOL, "launches the in-game Particle Editor" ); - //cmdSystem->AddCommand( "editScripts", Com_EditScripts_f, CMD_FL_TOOL, "launches the in-game Script Editor" ); + cmdSystem->AddCommand( "editParticles", Com_EditParticles_f, CMD_FL_TOOL, "launches the in-game Particle Editor" ); + cmdSystem->AddCommand( "editScripts", Com_EditScripts_f, CMD_FL_TOOL, "launches the in-game Script Editor" ); cmdSystem->AddCommand( "editGUIs", Com_EditGUIs_f, CMD_FL_TOOL, "launches the GUI Editor" ); cmdSystem->AddCommand( "debugger", Com_ScriptDebugger_f, CMD_FL_TOOL, "launches the Script Debugger" ); #endif - - cmdSystem->AddCommand( "printMemInfo", PrintMemInfo_f, CMD_FL_SYSTEM, "prints memory debugging data" ); - - // idLib commands - cmdSystem->AddCommand( "memoryDump", Mem_Dump_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "creates a memory dump" ); - cmdSystem->AddCommand( "memoryDumpCompressed", Mem_DumpCompressed_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "creates a compressed memory dump" ); - cmdSystem->AddCommand( "showStringMemory", idStr::ShowMemoryUsage_f, CMD_FL_SYSTEM, "shows memory used by strings" ); - cmdSystem->AddCommand( "showDictMemory", idDict::ShowMemoryUsage_f, CMD_FL_SYSTEM, "shows memory used by dictionaries" ); - cmdSystem->AddCommand( "listDictKeys", idDict::ListKeys_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "lists all keys used by dictionaries" ); - cmdSystem->AddCommand( "listDictValues", idDict::ListValues_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "lists all values used by dictionaries" ); - cmdSystem->AddCommand( "testSIMD", idSIMD::Test_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "test SIMD code" ); - - // localization - cmdSystem->AddCommand( "localizeGuis", Com_LocalizeGuis_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "localize guis" ); - cmdSystem->AddCommand( "localizeMaps", Com_LocalizeMaps_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "localize maps" ); - cmdSystem->AddCommand( "reloadLanguage", Com_ReloadLanguage_f, CMD_FL_SYSTEM, "reload language dict" ); - - //D3XP Localization - cmdSystem->AddCommand( "localizeGuiParmsTest", Com_LocalizeGuiParmsTest_f, CMD_FL_SYSTEM, "Create test files that show gui parms localized and ignored." ); - cmdSystem->AddCommand( "localizeMapsTest", Com_LocalizeMapsTest_f, CMD_FL_SYSTEM, "Create test files that shows which strings will be localized." ); - - // build helpers - cmdSystem->AddCommand( "startBuild", Com_StartBuild_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "prepares to make a build" ); - cmdSystem->AddCommand( "finishBuild", Com_FinishBuild_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "finishes the build process" ); - -#ifdef ID_DEDICATED - cmdSystem->AddCommand( "help", Com_Help_f, CMD_FL_SYSTEM, "shows help" ); -#endif } /* @@ -3078,7 +3100,7 @@ void idCommonLocal::InitGame( void ) { idCmdArgs args; if ( sysDetect ) { SetMachineSpec(); - Com_ExecMachineSpec_f( args ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "execMachineSpec %s", args ) ); } // initialize the renderSystem data structures, but don't start OpenGL yet @@ -3166,7 +3188,7 @@ void idCommonLocal::InitGame( void ) { // to mess with all the gl init at this point.. an old vid card will never qualify for if ( sysDetect ) { SetMachineSpec(); - Com_ExecMachineSpec_f( args ); + cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "execMachineSpec %s", args ) ); cvarSystem->SetCVarInteger( "s_numberOfSpeakers", 6 ); cmdSystem->BufferCommandText( CMD_EXEC_NOW, "s_restart\n" ); cmdSystem->ExecuteCommandBuffer(); diff --git a/neo/framework/ConsoleHistory.cpp b/neo/framework/ConsoleHistory.cpp index ec9d6c478..355f61689 100644 --- a/neo/framework/ConsoleHistory.cpp +++ b/neo/framework/ConsoleHistory.cpp @@ -177,19 +177,15 @@ void idConsoleHistory::ClearHistory() { history ======================== */ -/* CONSOLE_COMMAND_SHIP( history, "Displays the console command history", 0 ) { consoleHistory.PrintHistory(); } -*/ /* ======================== clearHistory ======================== */ -/* CONSOLE_COMMAND_SHIP( clearHistory, "Clears the console history", 0 ) { consoleHistory.ClearHistory(); } -*/ \ No newline at end of file diff --git a/neo/framework/Dhewm3SettingsMenu.cpp b/neo/framework/Dhewm3SettingsMenu.cpp index 58fe0de12..665dc727c 100644 --- a/neo/framework/Dhewm3SettingsMenu.cpp +++ b/neo/framework/Dhewm3SettingsMenu.cpp @@ -2504,30 +2504,8 @@ void Com_OpenCloseSettingsMenu( bool open ) { } } -void Com_Settings_f( const idCmdArgs &args ) { - bool menuOpen = ( imguiLocal.GetOpenWindowsMask() & idImGuiWindow::WINDOW_SETTINGS ) != 0; - if ( !menuOpen ) { - imguiLocal.OpenWindow( idImGuiWindow::WINDOW_SETTINGS ); - } else { - if ( ImGui::IsWindowFocused( ImGuiFocusedFlags_AnyWindow ) ) { - // if the settings window is open and an ImGui window has focus, - // close the settings window when "settings" is executed - imguiLocal.CloseWindow( idImGuiWindow::WINDOW_SETTINGS ); - } else { - // if the settings window is open but no ImGui window has focus, - // give focus to one of the ImGui windows. - // useful to get the cursor back when ingame.. - ImGui::SetNextWindowFocus(); - } - } -} - #else // IMGUI_DISABLE - just a stub function #include "Common.h" -void Com_Settings_f( const idCmdArgs &args ) { - common->Warning( "Dear ImGui is disabled in this build, so the settings menu is not available!" ); -} - #endif diff --git a/neo/framework/Session.cpp b/neo/framework/Session.cpp index 6b6ff127c..5df63ae3d 100644 --- a/neo/framework/Session.cpp +++ b/neo/framework/Session.cpp @@ -72,7 +72,7 @@ void RandomizeStack( void ) { Session_RescanSI_f ================= */ -void Session_RescanSI_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( rescanSI, "internal - rescan serverinfo cvars and tell game", idCmdSystem::ArgCompletion_MapName ) { sessLocal.mapSpawnData.serverInfo = *cvarSystem->MoveCVarsToDict( CVAR_SERVERINFO ); if ( game && idAsyncNetwork::server.IsActive() ) { game->SetServerInfo( sessLocal.mapSpawnData.serverInfo ); @@ -87,7 +87,7 @@ Session_Map_f Restart the server on a different map ================== */ -static void Session_Map_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( map, "loads a map", idCmdSystem::ArgCompletion_MapName ) { idStr map, string; findFile_t ff; idCmdArgs rl_args; @@ -128,6 +128,17 @@ static void Session_Map_f( const idCmdArgs &args ) { sessLocal.StartNewGame( map, true ); } +/* +================== +Session_RestartMap_f +================== +*/ +CONSOLE_COMMAND_SHIP( restartMap, "restarts the current map", NULL ) { + /*if ( g_demoMode.GetBool() )*/ { + cmdSystem->AppendCommandText( va( "devmap %s %d\n", sessLocal.GetCurrentMapName(), 0 ) ); + } +} + /* ================== Session_DevMap_f @@ -135,7 +146,7 @@ Session_DevMap_f Restart the server on a different map in developer mode ================== */ -static void Session_DevMap_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( devmap, "loads a map in developer mode", idCmdSystem::ArgCompletion_MapName ) { idStr map, string; findFile_t ff; idCmdArgs rl_args; @@ -174,7 +185,7 @@ static void Session_DevMap_f( const idCmdArgs &args ) { Session_TestMap_f ================== */ -static void Session_TestMap_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( testmap, "tests a map", idCmdSystem::ArgCompletion_MapName ) { idStr map, string; map = args.Argv(1); @@ -198,7 +209,7 @@ static void Session_TestMap_f( const idCmdArgs &args ) { Sess_WritePrecache_f ================== */ -static void Sess_WritePrecache_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( writePrecache, "writes precache commands", NULL ) { if ( args.Argc() != 2 ) { common->Printf( "USAGE: writePrecache \n" ); return; @@ -481,7 +492,7 @@ void idSessionLocal::ClearWipe( void ) { Session_TestGUI_f ================ */ -static void Session_TestGUI_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( testGUI, "tests a gui", idCmdSystem::ArgCompletion_GuiName ) { sessLocal.TestGUI( args.Argv(1) ); } @@ -523,7 +534,7 @@ static idStr FindUnusedFileName( const char *format ) { Session_DemoShot_f ================ */ -static void Session_DemoShot_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( demoShot, "writes a screenshot as a demo", NULL ) { if ( args.Argc() != 2 ) { idStr filename = FindUnusedFileName( "demos/shot%03i.demo" ); sessLocal.DemoShot( filename ); @@ -538,7 +549,7 @@ static void Session_DemoShot_f( const idCmdArgs &args ) { Session_RecordDemo_f ================ */ -static void Session_RecordDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( recordDemo, "records a demo", NULL ) { if ( args.Argc() != 2 ) { idStr filename = FindUnusedFileName( "demos/demo%03i.demo" ); sessLocal.StartRecordingRenderDemo( filename ); @@ -552,7 +563,7 @@ static void Session_RecordDemo_f( const idCmdArgs &args ) { Session_CompressDemo_f ================ */ -static void Session_CompressDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( compressDemo, "compresses a demo file", idCmdSystem::ArgCompletion_DemoName ) { if ( args.Argc() == 2 ) { sessLocal.CompressDemoFile( "2", args.Argv(1) ); } else if ( args.Argc() == 3 ) { @@ -567,7 +578,7 @@ static void Session_CompressDemo_f( const idCmdArgs &args ) { Session_StopRecordingDemo_f ================ */ -static void Session_StopRecordingDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( stopRecording, "stops demo recording", NULL ) { sessLocal.StopRecordingRenderDemo(); } @@ -576,7 +587,7 @@ static void Session_StopRecordingDemo_f( const idCmdArgs &args ) { Session_PlayDemo_f ================ */ -static void Session_PlayDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( playDemo, "plays back a demo", idCmdSystem::ArgCompletion_DemoName ) { if ( args.Argc() >= 2 ) { sessLocal.StartPlayingRenderDemo( va( "demos/%s", args.Argv(1) ) ); } @@ -587,7 +598,7 @@ static void Session_PlayDemo_f( const idCmdArgs &args ) { Session_TimeDemo_f ================ */ -static void Session_TimeDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( timeDemo, "times a demo", idCmdSystem::ArgCompletion_DemoName ) { if ( args.Argc() >= 2 ) { sessLocal.TimeRenderDemo( va( "demos/%s", args.Argv(1) ), ( args.Argc() > 2 ) ); } @@ -598,7 +609,7 @@ static void Session_TimeDemo_f( const idCmdArgs &args ) { Session_TimeDemoQuit_f ================ */ -static void Session_TimeDemoQuit_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( timeDemoQuit, "times a demo and quits", idCmdSystem::ArgCompletion_DemoName ) { sessLocal.TimeRenderDemo( va( "demos/%s", args.Argv(1) ) ); if ( sessLocal.timeDemo == TD_YES ) { // this allows hardware vendors to automate some testing @@ -611,7 +622,7 @@ static void Session_TimeDemoQuit_f( const idCmdArgs &args ) { Session_AVIDemo_f ================ */ -static void Session_AVIDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( aviDemo, "writes AVIs for a demo", idCmdSystem::ArgCompletion_DemoName ) { sessLocal.AVIRenderDemo( va( "demos/%s", args.Argv(1) ) ); } @@ -620,7 +631,7 @@ static void Session_AVIDemo_f( const idCmdArgs &args ) { Session_AVIGame_f ================ */ -static void Session_AVIGame_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( aviGame, "writes AVIs for the current game", NULL ) { sessLocal.AVIGame( args.Argv(1) ); } @@ -629,7 +640,7 @@ static void Session_AVIGame_f( const idCmdArgs &args ) { Session_AVICmdDemo_f ================ */ -static void Session_AVICmdDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( aviCmdDemo, "writes writes AVIs for a command demo", NULL ) { sessLocal.AVICmdDemo( args.Argv(1) ); } @@ -638,7 +649,7 @@ static void Session_AVICmdDemo_f( const idCmdArgs &args ) { Session_WriteCmdDemo_f ================ */ -static void Session_WriteCmdDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( writeCmdDemo, "writes a command demo", NULL ) { if ( args.Argc() == 1 ) { idStr filename = FindUnusedFileName( "demos/cmdDemo%03i.cdemo" ); sessLocal.WriteCmdDemo( filename ); @@ -654,7 +665,7 @@ static void Session_WriteCmdDemo_f( const idCmdArgs &args ) { Session_PlayCmdDemo_f ================ */ -static void Session_PlayCmdDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( playCmdDemo, "plays back a command demo", NULL ) { sessLocal.StartPlayingCmdDemo( args.Argv(1) ); } @@ -663,7 +674,7 @@ static void Session_PlayCmdDemo_f( const idCmdArgs &args ) { Session_TimeCmdDemo_f ================ */ -static void Session_TimeCmdDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( timeCmdDemo, "times a command demo", NULL ) { sessLocal.TimeCmdDemo( args.Argv(1) ); } #endif @@ -673,7 +684,7 @@ static void Session_TimeCmdDemo_f( const idCmdArgs &args ) { Session_Disconnect_f ================ */ -static void Session_Disconnect_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( disconnect, "disconnects from a game", NULL ) { sessLocal.Stop(); sessLocal.StartMenu(); if ( soundSystem ) { @@ -687,7 +698,7 @@ static void Session_Disconnect_f( const idCmdArgs &args ) { Session_ExitCmdDemo_f ================ */ -static void Session_ExitCmdDemo_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( exitCmdDemo, "exits a command demo", NULL ) { if ( !sessLocal.cmdDemoFile ) { common->Printf( "not reading from a cmdDemo\n" ); return; @@ -1642,12 +1653,13 @@ void idSessionLocal::ExecuteMapChange( bool noFadeWipe ) { Sys_ClearEvents(); } +#ifndef ID_DEDICATED /* =============== -LoadGame_f +Session_LoadGame_f =============== */ -void LoadGame_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( loadGame, "loads a game", idCmdSystem::ArgCompletion_SaveGame ) { console->Close(); if ( args.Argc() < 2 || idStr::Icmp(args.Argv(1), "quick" ) == 0 ) { sessLocal.QuickLoad(); @@ -1658,10 +1670,10 @@ void LoadGame_f( const idCmdArgs &args ) { /* =============== -SaveGame_f +Session_SaveGame_f =============== */ -void SaveGame_f( const idCmdArgs &args ) { +CONSOLE_COMMAND_SHIP( saveGame, "saves a game", NULL ) { if ( args.Argc() < 2 || idStr::Icmp( args.Argv(1), "quick" ) == 0 ) { sessLocal.QuickSave(); } else { @@ -1676,7 +1688,7 @@ void SaveGame_f( const idCmdArgs &args ) { Session_Hitch_f =============== */ -void Session_Hitch_f( const idCmdArgs &args ) { +CONSOLE_COMMAND( hitch, "hitches the game", NULL ) { idSoundWorld *sw = soundSystem->GetPlayingSoundWorld(); if ( sw ) { soundSystem->SetMute(true); @@ -1694,6 +1706,7 @@ void Session_Hitch_f( const idCmdArgs &args ) { soundSystem->SetMute(false); } } +#endif /* =============== @@ -2716,45 +2729,6 @@ void idSessionLocal::Init() { common->Printf( "----- Initializing Session -----\n" ); - cmdSystem->AddCommand( "writePrecache", Sess_WritePrecache_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "writes precache commands" ); - -#ifndef ID_DEDICATED - cmdSystem->AddCommand( "map", Session_Map_f, CMD_FL_SYSTEM, "loads a map", idCmdSystem::ArgCompletion_MapName ); - cmdSystem->AddCommand( "devmap", Session_DevMap_f, CMD_FL_SYSTEM, "loads a map in developer mode", idCmdSystem::ArgCompletion_MapName ); - cmdSystem->AddCommand( "testmap", Session_TestMap_f, CMD_FL_SYSTEM, "tests a map", idCmdSystem::ArgCompletion_MapName ); - - cmdSystem->AddCommand( "writeCmdDemo", Session_WriteCmdDemo_f, CMD_FL_SYSTEM, "writes a command demo" ); - cmdSystem->AddCommand( "playCmdDemo", Session_PlayCmdDemo_f, CMD_FL_SYSTEM, "plays back a command demo" ); - cmdSystem->AddCommand( "timeCmdDemo", Session_TimeCmdDemo_f, CMD_FL_SYSTEM, "times a command demo" ); - cmdSystem->AddCommand( "exitCmdDemo", Session_ExitCmdDemo_f, CMD_FL_SYSTEM, "exits a command demo" ); - cmdSystem->AddCommand( "aviCmdDemo", Session_AVICmdDemo_f, CMD_FL_SYSTEM, "writes AVIs for a command demo" ); - cmdSystem->AddCommand( "aviGame", Session_AVIGame_f, CMD_FL_SYSTEM, "writes AVIs for the current game" ); - - cmdSystem->AddCommand( "recordDemo", Session_RecordDemo_f, CMD_FL_SYSTEM, "records a demo" ); - cmdSystem->AddCommand( "stopRecording", Session_StopRecordingDemo_f, CMD_FL_SYSTEM, "stops demo recording" ); - cmdSystem->AddCommand( "playDemo", Session_PlayDemo_f, CMD_FL_SYSTEM, "plays back a demo", idCmdSystem::ArgCompletion_DemoName ); - cmdSystem->AddCommand( "timeDemo", Session_TimeDemo_f, CMD_FL_SYSTEM, "times a demo", idCmdSystem::ArgCompletion_DemoName ); - cmdSystem->AddCommand( "timeDemoQuit", Session_TimeDemoQuit_f, CMD_FL_SYSTEM, "times a demo and quits", idCmdSystem::ArgCompletion_DemoName ); - cmdSystem->AddCommand( "aviDemo", Session_AVIDemo_f, CMD_FL_SYSTEM, "writes AVIs for a demo", idCmdSystem::ArgCompletion_DemoName ); - cmdSystem->AddCommand( "compressDemo", Session_CompressDemo_f, CMD_FL_SYSTEM, "compresses a demo file", idCmdSystem::ArgCompletion_DemoName ); -#endif - - cmdSystem->AddCommand( "disconnect", Session_Disconnect_f, CMD_FL_SYSTEM, "disconnects from a game" ); - - cmdSystem->AddCommand( "demoShot", Session_DemoShot_f, CMD_FL_SYSTEM, "writes a screenshot for a demo" ); - cmdSystem->AddCommand( "testGUI", Session_TestGUI_f, CMD_FL_SYSTEM, "tests a gui" ); - -#ifndef ID_DEDICATED - cmdSystem->AddCommand( "saveGame", SaveGame_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "saves a game" ); - cmdSystem->AddCommand( "loadGame", LoadGame_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "loads a game", idCmdSystem::ArgCompletion_SaveGame ); -#endif - - cmdSystem->AddCommand( "rescanSI", Session_RescanSI_f, CMD_FL_SYSTEM, "internal - rescan serverinfo cvars and tell game" ); - -#ifdef _DEBUG - cmdSystem->AddCommand( "hitch", Session_Hitch_f, CMD_FL_SYSTEM|CMD_FL_CHEAT, "hitches the game" ); -#endif - // the same idRenderWorld will be used for all games // and demos, insuring that level specific models // will be freed diff --git a/neo/framework/Session_menu.cpp b/neo/framework/Session_menu.cpp index 28d0c5d6d..e4141c883 100644 --- a/neo/framework/Session_menu.cpp +++ b/neo/framework/Session_menu.cpp @@ -564,7 +564,7 @@ void idSessionLocal::HandleMainMenuCommands( const char *menuCommand ) { if ( icmd < args.Argc() ) { StartNewGame( args.Argv( icmd++ ) ); } else { - StartNewGame( "game/mars_city1" ); + StartNewGame( "game/dev" ); } // need to do this here to make sure com_frameTime is correct or the gui activates with a time that // is "however long map load took" time in the past diff --git a/neo/idlib/CMakeLists.txt b/neo/idlib/CMakeLists.txt index 5b13f95ef..69eaee991 100644 --- a/neo/idlib/CMakeLists.txt +++ b/neo/idlib/CMakeLists.txt @@ -44,6 +44,7 @@ set( src_idlib precompiled.cpp MapFile.cpp CmdArgs.cpp + CommandLink.cpp Token.cpp Base64.cpp Timer.cpp diff --git a/neo/idlib/Callback.h b/neo/idlib/Callback.h new file mode 100644 index 000000000..d1b55f039 --- /dev/null +++ b/neo/idlib/Callback.h @@ -0,0 +1,173 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code 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. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 BFG Edition Source Code. If not, see . + +In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ +#ifndef __CALLBACK_H__ +#define __CALLBACK_H__ + +/* +================================================================================================ +This file defines a set of template functors for generating callbacks, specifically +the OnChange handlers in the CVar system. +================================================================================================ +*/ + +/* +================================================ +idCallback +================================================ +*/ +class idCallback { +public: + virtual ~idCallback() {} + virtual void Call() = 0; + virtual idCallback * Clone() const = 0; +}; + +/* +================================================ +idCallbackStatic + +Callback class that forwards the call to a c-style function +================================================ +*/ +class idCallbackStatic : public idCallback { +public: + idCallbackStatic( void (*f)() ) { + this->f = f; + } + void Call() { + f(); + } + idCallback * Clone() const { + //idScopedGlobalHeap everythingHereGoesInTheGlobalHeap; + return new (TAG_FUNC_CALLBACK) idCallbackStatic( f ); + } +private: + void (*f)(); +}; + +/* +================================================ +idCallbackBindMem + +Callback class that forwards the call to a member function +================================================ +*/ +template< class T > +class idCallbackBindMem : public idCallback { +public: + idCallbackBindMem( T * t, void (T::*f)() ) { + this->t = t; + this->f = f; + } + void Call() { + (t->*f)(); + } + idCallback * Clone() const { + return new (TAG_FUNC_CALLBACK) idCallbackBindMem( t, f ); + } +private: + T * t; + void (T::*f)(); +}; + +/* +================================================ +idCallbackBindMemArg1 + +Callback class that forwards the call to a member function with an additional constant parameter +================================================ +*/ +template< class T, typename A1 > +class idCallbackBindMemArg1 : public idCallback { +public: + idCallbackBindMemArg1( T * t_, void (T::*f_)( A1 ), A1 a1_ ) : + t( t_ ), + f( f_ ), + a1( a1_ ) { + } + void Call() { + (t->*f)( a1 ); + } + idCallback * Clone() const { + return new (TAG_FUNC_CALLBACK) idCallbackBindMemArg1( t, f, a1 ); + } +private: + T * t; + void (T::*f)( A1 ); + A1 a1; + + // hack to get to compile on the 360 with reference arguments + // with this on the PC, the MakeCallback function fails compilation because it's returning a copy + // therefore, the Arg1 callbacks can't have arguments that are references + //DISALLOW_COPY_AND_ASSIGN( idCallbackBindMemArg1 ); +}; + +/* +================================================================================================ + + These are needed because we can't derive the type of an object from the type passed to the + constructor. If it weren't for these, we'd have to manually specify the type: + + idCallbackBindMem( this, &idFoo::MyFunction ); + becomes: + MakeCallback( this, &idFoo::MyFunction ); + +================================================================================================ +*/ + +/* +======================== +MakeCallback +======================== +*/ +ID_INLINE_EXTERN idCallbackStatic MakeCallback( void (*f)(void) ) { + return idCallbackStatic( f ); +} + +/* +======================== +MakeCallback +======================== +*/ +template < class T > +ID_INLINE_EXTERN idCallbackBindMem MakeCallback( T * t, void (T::*f)(void) ) { + return idCallbackBindMem( t, f ); +} + +/* +======================== +MakeCallback +======================== +*/ +template < class T, typename A1 > +ID_INLINE_EXTERN idCallbackBindMemArg1 MakeCallback( T * t, void (T::*f)( A1 ), A1 a1 ) { + return idCallbackBindMemArg1( t, f, a1 ); +} + +#endif // __CALLBACK_H__ + diff --git a/neo/idlib/CmdArgs.cpp b/neo/idlib/CmdArgs.cpp index 7f91afb8d..8c516ec72 100644 --- a/neo/idlib/CmdArgs.cpp +++ b/neo/idlib/CmdArgs.cpp @@ -53,6 +53,7 @@ const char *idCmdArgs::Args( int start, int end, bool escapeArgs ) const { static char cmd_args[MAX_COMMAND_STRING]; int i; + assert( argc < MAX_COMMAND_ARGS ); if ( end < 0 ) { end = argc - 1; } else if ( end >= argc ) { @@ -175,6 +176,9 @@ idCmdArgs::AppendArg ============ */ void idCmdArgs::AppendArg( const char *text ) { + if ( argc >= MAX_COMMAND_ARGS ) { + return; + } if ( !argc ) { argc = 1; argv[ 0 ] = tokenized; @@ -191,7 +195,7 @@ void idCmdArgs::AppendArg( const char *text ) { idCmdArgs::GetArgs ============ */ -const char **idCmdArgs::GetArgs( int *_argc ) { +const char * const * idCmdArgs::GetArgs( int *_argc ) { *_argc = argc; return (const char **)&argv[0]; } diff --git a/neo/idlib/CmdArgs.h b/neo/idlib/CmdArgs.h index 61a32db46..328cc2728 100644 --- a/neo/idlib/CmdArgs.h +++ b/neo/idlib/CmdArgs.h @@ -59,7 +59,7 @@ class idCmdArgs { void AppendArg( const char *text ); void Clear( void ) { argc = 0; } - const char ** GetArgs( int *argc ); + const char * const * GetArgs( int *argc ); private: static const int MAX_COMMAND_ARGS = 64; diff --git a/neo/idlib/CommandLink.cpp b/neo/idlib/CommandLink.cpp new file mode 100644 index 000000000..f2341ee06 --- /dev/null +++ b/neo/idlib/CommandLink.cpp @@ -0,0 +1,59 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code 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. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Doom 3 BFG Edition Source Code. If not, see . + +In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ +#pragma hdrstop +#include "precompiled.h" + +/* +======================== +CommandLinks + +The command system is not required for idLib, but we want to be able +to use the CONSOLE_COMMAND() macro inside idlib, so these must be here. +======================== +*/ +idCommandLink *CommandLinks( idCommandLink *cl ) { + static idCommandLink *commandLinks = NULL; + if ( cl != NULL ) { + commandLinks = cl; + } + return commandLinks; +} + + +idCommandLink *commandLinks = NULL; + +idCommandLink::idCommandLink( const char *cmdName, cmdFunction_t function, + const char *description, argCompletion_t argCompletion ) { + next = CommandLinks(); + CommandLinks( this ); + cmdName_ = cmdName; + function_ = function; + description_ = description; + argCompletion_ = argCompletion; +} +