Optimizations from LJ and generic functions

This commit is contained in:
James R 2019-11-13 14:26:28 -08:00
parent c9aad2d186
commit 359d8a2c25
3 changed files with 70 additions and 110 deletions

View File

@ -345,6 +345,40 @@ size_t COM_CheckParm(const char *check)
return 0; return 0;
} }
/** \brief COM_CheckParm, but checks only the start of each argument.
* E.g. checking for "-no" would match "-noerror" too.
*/
size_t COM_CheckPartialParm(const char *check)
{
int len;
size_t i;
len = strlen(check);
for (i = 1; i < com_argc; i++)
{
if (strncasecmp(check, com_argv[i], len) == 0)
return i;
}
return 0;
}
/** Find the first argument that starts with a hyphen (-).
* \return The index of the argument, or 0
* if there are no such arguments.
*/
size_t COM_FirstOption(void)
{
size_t i;
for (i = 1; i < com_argc; i++)
{
if (com_argv[i][0] == '-')/* options start with a hyphen */
return i;
}
return 0;
}
/** Parses a string into command-line tokens. /** Parses a string into command-line tokens.
* *
* \param ptext A null-terminated string. Does not need to be * \param ptext A null-terminated string. Does not need to be

View File

@ -29,6 +29,8 @@ size_t COM_Argc(void);
const char *COM_Argv(size_t arg); // if argv > argc, returns empty string const char *COM_Argv(size_t arg); // if argv > argc, returns empty string
char *COM_Args(void); char *COM_Args(void);
size_t COM_CheckParm(const char *check); // like M_CheckParm :) size_t COM_CheckParm(const char *check); // like M_CheckParm :)
size_t COM_CheckPartialParm(const char *check);
size_t COM_FirstOption(void);
// match existing command or NULL // match existing command or NULL
const char *COM_CompleteCommand(const char *partial, INT32 skips); const char *COM_CompleteCommand(const char *partial, INT32 skips);

View File

@ -1719,56 +1719,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
} }
} }
enum
{
MAP_COMMAND_FORCE_OPTION,
MAP_COMMAND_GAMETYPE_OPTION,
MAP_COMMAND_NORESETPLAYERS_OPTION,
NUM_MAP_COMMAND_OPTIONS
};
static size_t CheckOptions(
int num_options,
size_t *first_argumentp,
size_t *user_options,
const char ***option_names,
int *option_num_arguments
)
{
int arguments_used;
size_t first_argument;
int i;
const char **pp;
const char *name;
size_t n;
arguments_used = 0;
first_argument = COM_Argc();
for (i = 0; i < num_options; ++i)
{
pp = option_names[i];
name = *pp;
do
{
if (( n = COM_CheckParm(name) ))
{
user_options[i] = n;
arguments_used += 1 + option_num_arguments[i];
if (n < first_argument)
first_argument = n;
}
}
while (( name = *++pp )) ;
}
(*first_argumentp) = first_argument;
return arguments_used;
}
static char * static char *
ConcatCommandArgv (int start, int end) ConcatCommandArgv (int start, int end)
{ {
@ -1812,43 +1762,10 @@ ConcatCommandArgv (int start, int end)
// //
static void Command_Map_f(void) static void Command_Map_f(void)
{ {
const char *force_option_names[] = size_t first_option;
{ size_t option_force;
"-force", size_t option_gametype;
"-f", const char *gametypename;
NULL
};
const char *gametype_option_names[] =
{
"-gametype",
"-g",
"-gt",
NULL
};
const char *noresetplayers_option_names[] =
{
"-noresetplayers",
NULL
};
const char **option_names[] =
{
force_option_names,
gametype_option_names,
noresetplayers_option_names,
};
int option_num_arguments[] =
{
0,/* -force */
1,/* -gametype */
0,/* -noresetplayers */
};
size_t acceptableargc;/* (this includes the command name itself!) */
size_t first_argument;
size_t user_options [NUM_MAP_COMMAND_OPTIONS] = {0};
const char *arg_gametype;
boolean newresetplayers; boolean newresetplayers;
boolean mustmodifygame; boolean mustmodifygame;
@ -1871,18 +1788,15 @@ static void Command_Map_f(void)
return; return;
} }
/* map name + options */ option_force = COM_CheckPartialParm("-f");
acceptableargc = 2 + CheckOptions(NUM_MAP_COMMAND_OPTIONS, option_gametype = COM_CheckPartialParm("-g");
&first_argument, newresetplayers = ! COM_CheckParm("-noresetplayers");
user_options, option_names, option_num_arguments);
newresetplayers = !user_options[MAP_COMMAND_NORESETPLAYERS_OPTION];
mustmodifygame = mustmodifygame =
!( netgame || multiplayer ) && !( netgame || multiplayer ) &&
(!modifiedgame || savemoddata ); (!modifiedgame || savemoddata );
if (mustmodifygame && !user_options[MAP_COMMAND_FORCE_OPTION]) if (mustmodifygame && !option_force)
{ {
/* May want to be more descriptive? */ /* May want to be more descriptive? */
CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n"));
@ -1895,26 +1809,37 @@ static void Command_Map_f(void)
return; return;
} }
if (user_options[MAP_COMMAND_GAMETYPE_OPTION] && !multiplayer) if (option_gametype)
{ {
CONS_Printf(M_GetText("You can't switch gametypes in single player!\n")); if (!multiplayer)
return; {
CONS_Printf(M_GetText(
"You can't switch gametypes in single player!\n"));
return;
}
else if (COM_Argc() < option_gametype + 2)/* no argument after? */
{
CONS_Alert(CONS_ERROR,
"No gametype name follows parameter '%s'.\n",
COM_Argv(option_gametype));
return;
}
} }
/* If the first argument is an option, you fucked up. */ if (!( first_option = COM_FirstOption() ))
if (COM_Argc() < acceptableargc || first_argument == 1) first_option = COM_Argc();
if (first_option < 2)
{ {
/* I'm going over the fucking lines and I DON'T CAREEEEE */ /* I'm going over the fucking lines and I DON'T CAREEEEE */
CONS_Printf("map <name / [MAP]code / number> [-gametype <type>] [-force]:\n"); CONS_Printf("map <name / [MAP]code / number> [-gametype <type>] [-force]:\n");
CONS_Printf(M_GetText( CONS_Printf(M_GetText(
"Warp to a map, by its name, two character code, with optional \"MAP\" prefix, or by its number (though why would you).\n" "Warp to a map, by its name, two character code, with optional \"MAP\" prefix, or by its number (though why would you).\n"
"All parameters are case-insensitive.\n" "All parameters are case-insensitive and may be abbreviated.\n"));
"* \"-force\" may be shortened to \"-f\".\n"
"* \"-gametype\" may be shortened to \"-g\" or \"-gt\".\n"));
return; return;
} }
mapname = ConcatCommandArgv(1, first_argument); mapname = ConcatCommandArgv(1, first_option);
mapnamelen = strlen(mapname); mapnamelen = strlen(mapname);
if (mapnamelen == 2)/* maybe two digit code */ if (mapnamelen == 2)/* maybe two digit code */
@ -1965,22 +1890,22 @@ static void Command_Map_f(void)
realmapname = G_BuildMapTitle(newmapnum); realmapname = G_BuildMapTitle(newmapnum);
} }
if (mustmodifygame && user_options[MAP_COMMAND_FORCE_OPTION]) if (mustmodifygame && option_force)
{ {
G_SetGameModified(false); G_SetGameModified(false);
} }
// new gametype value // new gametype value
// use current one by default // use current one by default
if (user_options[MAP_COMMAND_GAMETYPE_OPTION]) if (option_gametype)
{ {
arg_gametype = COM_Argv(user_options[MAP_COMMAND_GAMETYPE_OPTION] + 1); gametypename = COM_Argv(option_gametype + 1);
newgametype = G_GetGametypeByName(arg_gametype); newgametype = G_GetGametypeByName(gametypename);
if (newgametype == -1) // reached end of the list with no match if (newgametype == -1) // reached end of the list with no match
{ {
d = atoi(arg_gametype); d = atoi(gametypename);
// assume they gave us a gametype number, which is okay too // assume they gave us a gametype number, which is okay too
if (d >= 0 && d < NUMGAMETYPES) if (d >= 0 && d < NUMGAMETYPES)
newgametype = d; newgametype = d;
@ -1988,7 +1913,7 @@ static void Command_Map_f(void)
} }
// don't use a gametype the map doesn't support // don't use a gametype the map doesn't support
if (cv_debug || user_options[MAP_COMMAND_FORCE_OPTION] || cv_skipmapcheck.value) if (cv_debug || option_force || cv_skipmapcheck.value)
fromlevelselect = false; // The player wants us to trek on anyway. Do so. fromlevelselect = false; // The player wants us to trek on anyway. Do so.
// G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer
else else
@ -2043,7 +1968,6 @@ static void Command_Map_f(void)
Z_Free(realmapname); Z_Free(realmapname);
} }
#undef CHECKPARM
/** Receives a map command and changes the map. /** Receives a map command and changes the map.
* *