From fb858dd64bafeab8773f309662afd6a4cd735a47 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 12 Nov 2019 16:08:41 -0800 Subject: [PATCH] So you don't like macros? (cherry picked from commit 5fd6561d464d53521343dd4abae6b08e42719885) --- src/d_netcmd.c | 134 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 89 insertions(+), 45 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b7dc097e..3de734cc 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2479,16 +2479,49 @@ void D_PickVote(void) SendNetXCmd(XD_PICKVOTE, &buf, 2); } -/* -Easy macro; declare parm_*id* and define acceptableargc; put in the parameter -to match as a string as *name*. Set *argn* to the number of extra arguments -following the parameter. parm_*id* is filled with the index of the parameter -found and acceptableargc is incremented to match the macro parameters. -Returned is whether the parameter was found. -*/ -#define CHECKPARM( id, name, argn ) \ -( (( parm_ ## id = COM_CheckParm(name) )) &&\ - ( acceptableargc += 1 + argn ) ) +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 *user_options, + const char ***option_names, + int *option_num_arguments +) +{ + int arguments_used; + + int i; + const char **pp; + const char *name; + size_t n; + + arguments_used = 0; + + 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]; + } + } + while (( name = *++pp )) ; + } + + return arguments_used; +} + // // Warp to map code. // Called either from map console command, or idclev cheat. @@ -2497,13 +2530,42 @@ Returned is whether the parameter was found. // static void Command_Map_f(void) { - size_t acceptableargc; - size_t parm_force; - size_t parm_gametype; - size_t parm_encore; + const char *force_option_names[] = + { + "-force", + "-f", + 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 user_options [NUM_MAP_COMMAND_OPTIONS] = {0}; + const char *arg_gametype; - /* debug? */ - size_t parm_noresetplayers; boolean newresetplayers; boolean mustmodifygame; @@ -2527,33 +2589,15 @@ static void Command_Map_f(void) return; } - acceptableargc = 2;/* map name */ + /* map name + options */ + acceptableargc = 2 + CheckOptions(NUM_MAP_COMMAND_OPTIONS, + user_options, option_names, option_num_arguments); - (void) - ( - CHECKPARM (force, "-force", 0) || - CHECKPARM (force, "-f", 0) - ); - (void) - ( - CHECKPARM (gametype, "-gametype", 1) || - CHECKPARM (gametype, "-g", 1) || - CHECKPARM (gametype, "-gt", 1) - ); - (void) - ( - CHECKPARM (encore, "-encore", 0) || - CHECKPARM (encore, "-en", 0) || - CHECKPARM (encore, "-e", 0) - ); - - (void)CHECKPARM (noresetplayers, "-noresetplayers", 0); - - newresetplayers = !parm_noresetplayers; + newresetplayers = !user_options[MAP_COMMAND_NORESETPLAYERS_OPTION]; mustmodifygame = !( netgame || multiplayer || majormods ); - if (mustmodifygame && !parm_force) + if (mustmodifygame && !user_options[MAP_COMMAND_FORCE_OPTION]) { /* May want to be more descriptive? */ CONS_Printf(M_GetText("Sorry, level change disabled in single player.\n")); @@ -2566,7 +2610,7 @@ static void Command_Map_f(void) return; } - if (parm_gametype && !multiplayer) + if (user_options[MAP_COMMAND_GAMETYPE_OPTION] && !multiplayer) { CONS_Printf(M_GetText("You can't switch gametypes in single player!\n")); return; @@ -2633,16 +2677,16 @@ static void Command_Map_f(void) realmapname = G_BuildMapTitle(newmapnum); } - if (mustmodifygame && parm_force) + if (mustmodifygame && user_options[MAP_COMMAND_FORCE_OPTION]) { G_SetGameModified(false, true); } // new gametype value // use current one by default - if (parm_gametype) + if (user_options[MAP_COMMAND_GAMETYPE_OPTION]) { - arg_gametype = COM_Argv(parm_gametype + 1); + arg_gametype = COM_Argv(user_options[MAP_COMMAND_GAMETYPE_OPTION] + 1); for (i = 0; gametype_cons_t[i].strvalue; i++) if (!strcasecmp(gametype_cons_t[i].strvalue, arg_gametype)) @@ -2672,8 +2716,8 @@ static void Command_Map_f(void) newresetplayers = false; // if not forcing and gametypes is the same // don't use a gametype the map doesn't support - if (cv_debug || parm_force || cv_skipmapcheck.value) - ; // The player wants us to trek on anyway. Do so. + if (cv_debug || user_options[MAP_COMMAND_FORCE_OPTION] || cv_skipmapcheck.value) + fromlevelselect = false; // The player wants us to trek on anyway. Do so. // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer else {