]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
common: Move filematch headers to new filematch.h
[xonotic/darkplaces.git] / common.c
index 40713e22e2e57804a0974954074cb1d9c3d3c47a..8db1f27025ab61c545583f0f2cba1821ab41ff6d 100644 (file)
--- a/common.c
+++ b/common.c
@@ -1,5 +1,6 @@
 /*
 Copyright (C) 1996-1997 Id Software, Inc.
+Copyright (C) 2000-2020 DarkPlaces contributors
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
@@ -28,19 +29,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "quakedef.h"
 #include "utf8lib.h"
 
-cvar_t registered = {CVAR_CLIENT | CVAR_SERVER, "registered","0", "indicates if this is running registered quake (whether gfx/pop.lmp was found)"};
-cvar_t cmdline = {CVAR_CLIENT | CVAR_SERVER, "cmdline","0", "contains commandline the engine was launched with"};
+cvar_t registered = {CF_CLIENT | CF_SERVER, "registered","0", "indicates if this is running registered quake (whether gfx/pop.lmp was found)"};
+cvar_t cmdline = {CF_CLIENT | CF_SERVER, "cmdline","0", "contains commandline the engine was launched with"};
 
-char com_token[MAX_INPUTLINE];
+// FIXME: Find a better place for these.
+cvar_t cl_playermodel = {CF_CLIENT | CF_SERVER | CF_USERINFO | CF_ARCHIVE, "playermodel", "", "current player model in Nexuiz/Xonotic"};
+cvar_t cl_playerskin = {CF_CLIENT | CF_SERVER | CF_USERINFO | CF_ARCHIVE, "playerskin", "", "current player skin in Nexuiz/Xonotic"};
 
-gamemode_t gamemode;
-const char *gamename;
-const char *gamenetworkfiltername; // same as gamename currently but with _ in place of spaces so that "getservers" packets parse correctly (this also means the 
-const char *gamedirname1;
-const char *gamedirname2;
-const char *gamescreenshotname;
-const char *gameuserdirname;
-char com_modname[MAX_OSPATH] = "";
+char com_token[MAX_INPUTLINE];
 
 //===========================================================================
 
@@ -185,7 +181,7 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo
        //     If it fits, append it. Continue.
        //     If it doesn't fit, output current line, advance to next line. Append the word. This is a continuation. Continue.
 
-       qboolean isContinuation = false;
+       qbool isContinuation = false;
        float spaceWidth;
        const char *startOfLine = string;
        const char *cursor = string;
@@ -263,7 +259,7 @@ int COM_Wordwrap(const char *string, size_t length, float continuationWidth, flo
        return result;
 
 /*
-       qboolean isContinuation = false;
+       qbool isContinuation = false;
        float currentWordSpace = 0;
        const char *currentWord = 0;
        float minReserve = 0;
@@ -462,7 +458,7 @@ COM_ParseToken_Simple
 Parse a token out of a string
 ==============
 */
-int COM_ParseToken_Simple(const char **datapointer, qboolean returnnewline, qboolean parsebackslash, qboolean parsecomments)
+int COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments)
 {
        int len;
        int c;
@@ -575,7 +571,7 @@ COM_ParseToken_QuakeC
 Parse a token out of a string
 ==============
 */
-int COM_ParseToken_QuakeC(const char **datapointer, qboolean returnnewline)
+int COM_ParseToken_QuakeC(const char **datapointer, qbool returnnewline)
 {
        int len;
        int c;
@@ -689,7 +685,7 @@ COM_ParseToken_VM_Tokenize
 Parse a token out of a string
 ==============
 */
-int COM_ParseToken_VM_Tokenize(const char **datapointer, qboolean returnnewline)
+int COM_ParseToken_VM_Tokenize(const char **datapointer, qbool returnnewline)
 {
        int len;
        int c;
@@ -865,204 +861,34 @@ skipwhite:
        return true;
 }
 
-
 /*
-================
-COM_CheckParm
+===============
+Com_CalcRoll
 
-Returns the position (1 to argc-1) in the program's argument list
-where the given parameter apears, or 0 if not present
-================
+Used by view and sv_user
+===============
 */
-int COM_CheckParm (const char *parm)
-{
-       int i;
-
-       for (i=1 ; i<sys.argc ; i++)
-       {
-               if (!sys.argv[i])
-                       continue;               // NEXTSTEP sometimes clears appkit vars.
-               if (!strcmp (parm,sys.argv[i]))
-                       return i;
-       }
-
-       return 0;
-}
-
-//===========================================================================
-
-// Game mods
-
-gamemode_t com_startupgamemode;
-gamemode_t com_startupgamegroup;
-
-typedef struct gamemode_info_s
-{
-       gamemode_t mode; // this gamemode
-       gamemode_t group; // different games with same group can switch automatically when gamedirs change
-       const char* prog_name; // not null
-       const char* cmdline; // not null
-       const char* gamename; // not null
-       const char*     gamenetworkfiltername; // not null
-       const char* gamedirname1; // not null
-       const char* gamedirname2; // null
-       const char* gamescreenshotname; // not nul
-       const char* gameuserdirname; // not null
-} gamemode_info_t;
-
-static const gamemode_info_t gamemode_info [GAME_COUNT] =
-{// game                                               basegame                                        prog_name                               cmdline                                         gamename                                        gamenetworkfilername            basegame        modgame                 screenshot                      userdir                                    // commandline option
-{ GAME_NORMAL,                                 GAME_NORMAL,                            "",                                             "-quake",                                       "DarkPlaces-Quake",                     "DarkPlaces-Quake",                     "id1",          NULL,                   "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -quake runs the game Quake (default)
-{ GAME_HIPNOTIC,                               GAME_NORMAL,                            "hipnotic",                             "-hipnotic",                            "Darkplaces-Hipnotic",          "Darkplaces-Hipnotic",          "id1",          "hipnotic",             "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -hipnotic runs Quake mission pack 1: The Scourge of Armagon
-{ GAME_ROGUE,                                  GAME_NORMAL,                            "rogue",                                "-rogue",                                       "Darkplaces-Rogue",                     "Darkplaces-Rogue",                     "id1",          "rogue",                "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -rogue runs Quake mission pack 2: The Dissolution of Eternity
-{ GAME_NEHAHRA,                                        GAME_NORMAL,                            "nehahra",                              "-nehahra",                                     "DarkPlaces-Nehahra",           "DarkPlaces-Nehahra",           "id1",          "nehahra",              "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -nehahra runs The Seal of Nehahra movie and game
-{ GAME_QUOTH,                                  GAME_NORMAL,                            "quoth",                                "-quoth",                                       "Darkplaces-Quoth",                     "Darkplaces-Quoth",                     "id1",          "quoth",                "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -quoth runs the Quoth mod for playing community maps made for it
-{ GAME_NEXUIZ,                                 GAME_NEXUIZ,                            "nexuiz",                               "-nexuiz",                                      "Nexuiz",                                       "Nexuiz",                                       "data",         NULL,                   "nexuiz",                       "nexuiz"                                }, // COMMANDLINEOPTION: Game: -nexuiz runs the multiplayer game Nexuiz
-{ GAME_XONOTIC,                                        GAME_XONOTIC,                           "xonotic",                              "-xonotic",                                     "Xonotic",                                      "Xonotic",                                      "data",         NULL,                   "xonotic",                      "xonotic"                               }, // COMMANDLINEOPTION: Game: -xonotic runs the multiplayer game Xonotic
-{ GAME_TRANSFUSION,                            GAME_TRANSFUSION,                       "transfusion",                  "-transfusion",                         "Transfusion",                          "Transfusion",                          "basetf",       NULL,                   "transfusion",          "transfusion"                   }, // COMMANDLINEOPTION: Game: -transfusion runs Transfusion (the recreation of Blood in Quake)
-{ GAME_GOODVSBAD2,                             GAME_GOODVSBAD2,                        "gvb2",                                 "-goodvsbad2",                          "GoodVs.Bad2",                          "GoodVs.Bad2",                          "rts",          NULL,                   "gvb2",                         "gvb2"                                  }, // COMMANDLINEOPTION: Game: -goodvsbad2 runs the psychadelic RTS FPS game Good Vs Bad 2
-{ GAME_TEU,                                            GAME_TEU,                                       "teu",                                  "-teu",                                         "TheEvilUnleashed",                     "TheEvilUnleashed",                     "baseteu",      NULL,                   "teu",                          "teu"                                   }, // COMMANDLINEOPTION: Game: -teu runs The Evil Unleashed (this option is obsolete as they are not using darkplaces)
-{ GAME_BATTLEMECH,                             GAME_BATTLEMECH,                        "battlemech",                   "-battlemech",                          "Battlemech",                           "Battlemech",                           "base",         NULL,                   "battlemech",           "battlemech"                    }, // COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech
-{ GAME_ZYMOTIC,                                        GAME_ZYMOTIC,                           "zymotic",                              "-zymotic",                                     "Zymotic",                                      "Zymotic",                                      "basezym",      NULL,                   "zymotic",                      "zymotic"                               }, // COMMANDLINEOPTION: Game: -zymotic runs the singleplayer game Zymotic
-{ GAME_SETHERAL,                               GAME_SETHERAL,                          "setheral",                             "-setheral",                            "Setheral",                                     "Setheral",                                     "data",         NULL,                   "setheral",                     "setheral"                              }, // COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral
-{ GAME_TENEBRAE,                               GAME_NORMAL,                            "tenebrae",                             "-tenebrae",                            "DarkPlaces-Tenebrae",          "DarkPlaces-Tenebrae",          "id1",          "tenebrae",             "dp",                           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -tenebrae runs the graphics test mod known as Tenebrae (some features not implemented)
-{ GAME_NEOTERIC,                               GAME_NORMAL,                            "neoteric",                             "-neoteric",                            "Neoteric",                                     "Neoteric",                                     "id1",          "neobase",              "neo",                          "darkplaces"                    }, // COMMANDLINEOPTION: Game: -neoteric runs the game Neoteric
-{ GAME_OPENQUARTZ,                             GAME_NORMAL,                            "openquartz",                   "-openquartz",                          "OpenQuartz",                           "OpenQuartz",                           "id1",          NULL,                   "openquartz",           "darkplaces"                    }, // COMMANDLINEOPTION: Game: -openquartz runs the game OpenQuartz, a standalone GPL replacement of the quake content
-{ GAME_PRYDON,                                 GAME_NORMAL,                            "prydon",                               "-prydon",                                      "PrydonGate",                           "PrydonGate",                           "id1",          "prydon",               "prydon",                       "darkplaces"                    }, // COMMANDLINEOPTION: Game: -prydon runs the topdown point and click action-RPG Prydon Gate
-{ GAME_DELUXEQUAKE,                            GAME_DELUXEQUAKE,                       "dq",                                   "-dq",                                          "Deluxe Quake",                         "Deluxe_Quake",                         "basedq",       "extradq",              "basedq",                       "dq"                                    }, // COMMANDLINEOPTION: Game: -dq runs the game Deluxe Quake
-{ GAME_THEHUNTED,                              GAME_THEHUNTED,                         "thehunted",                    "-thehunted",                           "The Hunted",                           "The_Hunted",                           "thdata",       NULL,                   "th",                           "thehunted"                             }, // COMMANDLINEOPTION: Game: -thehunted runs the game The Hunted
-{ GAME_DEFEATINDETAIL2,                        GAME_DEFEATINDETAIL2,           "did2",                                 "-did2",                                        "Defeat In Detail 2",           "Defeat_In_Detail_2",           "data",         NULL,                   "did2_",                        "did2"                                  }, // COMMANDLINEOPTION: Game: -did2 runs the game Defeat In Detail 2
-{ GAME_DARSANA,                                        GAME_DARSANA,                           "darsana",                              "-darsana",                                     "Darsana",                                      "Darsana",                                      "ddata",        NULL,                   "darsana",                      "darsana"                               }, // COMMANDLINEOPTION: Game: -darsana runs the game Darsana
-{ GAME_CONTAGIONTHEORY,                        GAME_CONTAGIONTHEORY,           "contagiontheory",              "-contagiontheory",                     "Contagion Theory",                     "Contagion_Theory",                     "ctdata",       NULL,                   "ct",                           "contagiontheory"               }, // COMMANDLINEOPTION: Game: -contagiontheory runs the game Contagion Theory
-{ GAME_EDU2P,                                  GAME_EDU2P,                                     "edu2p",                                "-edu2p",                                       "EDU2 Prototype",                       "EDU2_Prototype",                       "id1",          "edu2",                 "edu2_p",                       "edu2prototype"                 }, // COMMANDLINEOPTION: Game: -edu2p runs the game Edu2 prototype
-{ GAME_PROPHECY,                               GAME_PROPHECY,                          "prophecy",                             "-prophecy",                            "Prophecy",                                     "Prophecy",                                     "gamedata",     NULL,                   "phcy",                         "prophecy"                              }, // COMMANDLINEOPTION: Game: -prophecy runs the game Prophecy
-{ GAME_BLOODOMNICIDE,                  GAME_BLOODOMNICIDE,                     "omnicide",                             "-omnicide",                            "Blood Omnicide",                       "Blood_Omnicide",                       "kain",         NULL,                   "omnicide",                     "omnicide"                              }, // COMMANDLINEOPTION: Game: -omnicide runs the game Blood Omnicide
-{ GAME_STEELSTORM,                             GAME_STEELSTORM,                        "steelstorm",                   "-steelstorm",                          "Steel-Storm",                          "Steel-Storm",                          "gamedata",     NULL,                   "ss",                           "steelstorm"                    }, // COMMANDLINEOPTION: Game: -steelstorm runs the game Steel Storm
-{ GAME_STEELSTORM2,                            GAME_STEELSTORM2,                       "steelstorm2",                  "-steelstorm2",                         "Steel Storm 2",                        "Steel_Storm_2",                        "gamedata",     NULL,                   "ss2",                          "steelstorm2"                   }, // COMMANDLINEOPTION: Game: -steelstorm2 runs the game Steel Storm 2
-{ GAME_SSAMMO,                                 GAME_SSAMMO,                            "steelstorm-ammo",              "-steelstormammo",                      "Steel Storm A.M.M.O.",         "Steel_Storm_A.M.M.O.",         "gamedata", NULL,                       "ssammo",                       "steelstorm-ammo"               }, // COMMANDLINEOPTION: Game: -steelstormammo runs the game Steel Storm A.M.M.O.
-{ GAME_STEELSTORMREVENANTS,            GAME_STEELSTORMREVENANTS,       "steelstorm-revenants", "-steelstormrev",                       "Steel Storm: Revenants",       "Steel_Storm_Revenants",        "base", NULL,                           "ssrev",                        "steelstorm-revenants"  }, // COMMANDLINEOPTION: Game: -steelstormrev runs the game Steel Storm: Revenants
-{ GAME_TOMESOFMEPHISTOPHELES,  GAME_TOMESOFMEPHISTOPHELES,     "tomesofmephistopheles","-tomesofmephistopheles",       "Tomes of Mephistopheles",      "Tomes_of_Mephistopheles",      "gamedata",     NULL,                   "tom",                          "tomesofmephistopheles" }, // COMMANDLINEOPTION: Game: -tomesofmephistopheles runs the game Tomes of Mephistopheles
-{ GAME_STRAPBOMB,                              GAME_STRAPBOMB,                         "strapbomb",                    "-strapbomb",                           "Strap-on-bomb Car",            "Strap-on-bomb_Car",            "id1",          NULL,                   "strap",                        "strapbomb"                             }, // COMMANDLINEOPTION: Game: -strapbomb runs the game Strap-on-bomb Car
-{ GAME_MOONHELM,                               GAME_MOONHELM,                          "moonhelm",                             "-moonhelm",                            "MoonHelm",                                     "MoonHelm",                                     "data",         NULL,                   "mh",                           "moonhelm"                              }, // COMMANDLINEOPTION: Game: -moonhelm runs the game MoonHelm
-{ GAME_VORETOURNAMENT,                 GAME_VORETOURNAMENT,            "voretournament",               "-voretournament",                      "Vore Tournament",                      "Vore_Tournament",                      "data",         NULL,                   "voretournament",       "voretournament"                }, // COMMANDLINEOPTION: Game: -voretournament runs the multiplayer game Vore Tournament
-};
-
-static void COM_SetGameType(int index);
-void COM_InitGameType (void)
-{
-       char name [MAX_OSPATH];
-       int i;
-       int index = 0;
-
-#ifdef FORCEGAME
-       COM_ToLowerString(FORCEGAME, name, sizeof (name));
-#else
-       // check executable filename for keywords, but do it SMARTLY - only check the last path element
-       FS_StripExtension(FS_FileWithoutPath(sys.argv[0]), name, sizeof (name));
-       COM_ToLowerString(name, name, sizeof (name));
-#endif
-       for (i = 1;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
-               if (gamemode_info[i].prog_name && gamemode_info[i].prog_name[0] && strstr (name, gamemode_info[i].prog_name))
-                       index = i;
-
-       // check commandline options for keywords
-       for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
-               if (COM_CheckParm (gamemode_info[i].cmdline))
-                       index = i;
-
-       com_startupgamemode = gamemode_info[index].mode;
-       com_startupgamegroup = gamemode_info[index].group;
-       COM_SetGameType(index);
-}
-
-void COM_ChangeGameTypeForGameDirs(void)
+float Com_CalcRoll (const vec3_t angles, const vec3_t velocity, const vec_t angleval, const vec_t velocityval)
 {
-       int i;
-       int index = -1;
-       // this will not not change the gamegroup
-       // first check if a base game (single gamedir) matches
-       for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
-       {
-               if (gamemode_info[i].group == com_startupgamegroup && !(gamemode_info[i].gamedirname2 && gamemode_info[i].gamedirname2[0]))
-               {
-                       index = i;
-                       break;
-               }
-       }
-       // now that we have a base game, see if there is a matching derivative game (two gamedirs)
-       if (fs_numgamedirs)
-       {
-               for (i = 0;i < (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0]));i++)
-               {
-                       if (gamemode_info[i].group == com_startupgamegroup && (gamemode_info[i].gamedirname2 && gamemode_info[i].gamedirname2[0]) && !strcasecmp(fs_gamedirs[0], gamemode_info[i].gamedirname2))
-                       {
-                               index = i;
-                               break;
-                       }
-               }
-       }
-       // we now have a good guess at which game this is meant to be...
-       if (index >= 0 && gamemode != gamemode_info[index].mode)
-               COM_SetGameType(index);
-}
+       vec3_t  forward, right, up;
+       float   sign;
+       float   side;
 
-static void COM_SetGameType(int index)
-{
-       static char gamenetworkfilternamebuffer[64];
-       int i, t;
-       if (index < 0 || index >= (int)(sizeof (gamemode_info) / sizeof (gamemode_info[0])))
-               index = 0;
-       gamemode = gamemode_info[index].mode;
-       gamename = gamemode_info[index].gamename;
-       gamenetworkfiltername = gamemode_info[index].gamenetworkfiltername;
-       gamedirname1 = gamemode_info[index].gamedirname1;
-       gamedirname2 = gamemode_info[index].gamedirname2;
-       gamescreenshotname = gamemode_info[index].gamescreenshotname;
-       gameuserdirname = gamemode_info[index].gameuserdirname;
-
-       if (gamemode == com_startupgamemode)
-       {
-               if((t = COM_CheckParm("-customgamename")) && t + 1 < sys.argc)
-                       gamename = gamenetworkfiltername = sys.argv[t+1];
-               if((t = COM_CheckParm("-customgamenetworkfiltername")) && t + 1 < sys.argc)
-                       gamenetworkfiltername = sys.argv[t+1];
-               if((t = COM_CheckParm("-customgamedirname1")) && t + 1 < sys.argc)
-                       gamedirname1 = sys.argv[t+1];
-               if((t = COM_CheckParm("-customgamedirname2")) && t + 1 < sys.argc)
-                       gamedirname2 = *sys.argv[t+1] ? sys.argv[t+1] : NULL;
-               if((t = COM_CheckParm("-customgamescreenshotname")) && t + 1 < sys.argc)
-                       gamescreenshotname = sys.argv[t+1];
-               if((t = COM_CheckParm("-customgameuserdirname")) && t + 1 < sys.argc)
-                       gameuserdirname = sys.argv[t+1];
-       }
+       AngleVectors (angles, forward, right, up);
+       side = DotProduct (velocity, right);
+       sign = side < 0 ? -1 : 1;
+       side = fabs(side);
 
-       if (gamedirname2 && gamedirname2[0])
-               Con_Printf("Game is %s using base gamedirs %s %s", gamename, gamedirname1, gamedirname2);
+       if (side < velocityval)
+               side = side * angleval / velocityval;
        else
-               Con_Printf("Game is %s using base gamedir %s", gamename, gamedirname1);
-       for (i = 0;i < fs_numgamedirs;i++)
-       {
-               if (i == 0)
-                       Con_Printf(", with mod gamedirs");
-               Con_Printf(" %s", fs_gamedirs[i]);
-       }
-       Con_Printf("\n");
+               side = angleval;
 
-       if (strchr(gamenetworkfiltername, ' '))
-       {
-               char *s;
-               // if there are spaces in the game's network filter name it would
-               // cause parse errors in getservers in dpmaster, so we need to replace
-               // them with _ characters
-               strlcpy(gamenetworkfilternamebuffer, gamenetworkfiltername, sizeof(gamenetworkfilternamebuffer));
-               while ((s = strchr(gamenetworkfilternamebuffer, ' ')) != NULL)
-                       *s = '_';
-               gamenetworkfiltername = gamenetworkfilternamebuffer;
-       }
+       return side*sign;
 
-       Con_Printf("gamename for server filtering: %s\n", gamenetworkfiltername);
 }
 
+//===========================================================================
 
 /*
 ================
@@ -1076,6 +902,10 @@ void COM_Init_Commands (void)
 
        Cvar_RegisterVariable (&registered);
        Cvar_RegisterVariable (&cmdline);
+       Cvar_RegisterVariable(&cl_playermodel);
+       Cvar_RegisterVirtual(&cl_playermodel, "_cl_playermodel");
+       Cvar_RegisterVariable(&cl_playerskin);
+       Cvar_RegisterVirtual(&cl_playerskin, "_cl_playerskin");
 
        // reconstitute the command line for the cmdline externally visible cvar
        n = 0;
@@ -1334,7 +1164,7 @@ all characters until the zero terminator.
 ============
 */
 size_t
-COM_StringLengthNoColors(const char *s, size_t size_s, qboolean *valid)
+COM_StringLengthNoColors(const char *s, size_t size_s, qbool *valid)
 {
        const char *end = size_s ? (s + size_s) : NULL;
        size_t len = 0;
@@ -1407,8 +1237,8 @@ For size_in, specify the maximum number of characters from in to use, or 0 to us
 all characters until the zero terminator.
 ============
 */
-qboolean
-COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qboolean escape_carets)
+qbool
+COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qbool escape_carets)
 {
 #define APPEND(ch) do { if(--size_out) { *out++ = (ch); } else { *out++ = 0; return false; } } while(0)
        const char *end = size_in ? (in + size_in) : NULL;
@@ -1470,153 +1300,11 @@ COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out,
 #undef APPEND
 }
 
-char *InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength)
-{
-       int pos = 0, j;
-       size_t keylength;
-       if (!key)
-               key = "";
-       keylength = strlen(key);
-       if (valuelength < 1 || !value)
-       {
-               Con_Printf("InfoString_GetValue: no room in value\n");
-               return NULL;
-       }
-       value[0] = 0;
-       if (strchr(key, '\\'))
-       {
-               Con_Printf("InfoString_GetValue: key name \"%s\" contains \\ which is not possible in an infostring\n", key);
-               return NULL;
-       }
-       if (strchr(key, '\"'))
-       {
-               Con_Printf("InfoString_SetValue: key name \"%s\" contains \" which is not allowed in an infostring\n", key);
-               return NULL;
-       }
-       if (!key[0])
-       {
-               Con_Printf("InfoString_GetValue: can not look up a key with no name\n");
-               return NULL;
-       }
-       while (buffer[pos] == '\\')
-       {
-               if (!memcmp(buffer + pos+1, key, keylength) &&
-                               (buffer[pos+1 + keylength] == 0 ||
-                                buffer[pos+1 + keylength] == '\\'))
-               {
-                       pos += 1 + (int)keylength;           // Skip \key
-                       if (buffer[pos] == '\\') pos++; // Skip \ before value.
-                       for (j = 0;buffer[pos+j] && buffer[pos+j] != '\\' && j < (int)valuelength - 1;j++)
-                               value[j] = buffer[pos+j];
-                       value[j] = 0;
-                       return value;
-               }
-               if (buffer[pos] == '\\') pos++; // Skip \ before value.
-               for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
-               if (buffer[pos] == '\\') pos++; // Skip \ before value.
-               for (pos++;buffer[pos] && buffer[pos] != '\\';pos++);
-       }
-       // if we reach this point the key was not found
-       return NULL;
-}
-
-void InfoString_SetValue(char *buffer, size_t bufferlength, const char *key, const char *value)
-{
-       int pos = 0, pos2;
-       size_t keylength;
-       if (!key)
-               key = "";
-       if (!value)
-               value = "";
-       keylength = strlen(key);
-       if (strchr(key, '\\') || strchr(value, '\\'))
-       {
-               Con_Printf("InfoString_SetValue: \"%s\" \"%s\" contains \\ which is not possible to store in an infostring\n", key, value);
-               return;
-       }
-       if (strchr(key, '\"') || strchr(value, '\"'))
-       {
-               Con_Printf("InfoString_SetValue: \"%s\" \"%s\" contains \" which is not allowed in an infostring\n", key, value);
-               return;
-       }
-       if (!key[0])
-       {
-               Con_Printf("InfoString_SetValue: can not set a key with no name\n");
-               return;
-       }
-       while (buffer[pos] == '\\')
-       {
-               if (!memcmp(buffer + pos+1, key, keylength) &&
-                               (buffer[pos+1 + keylength] == 0 ||
-                                buffer[pos+1 + keylength] == '\\'))
-                       break;
-               if (buffer[pos] == '\\') pos++; // Skip \ before value.
-               for (;buffer[pos] && buffer[pos] != '\\';pos++);
-               if (buffer[pos] == '\\') pos++; // Skip \ before value.
-               for (;buffer[pos] && buffer[pos] != '\\';pos++);
-       }
-       // if we found the key, find the end of it because we will be replacing it
-       pos2 = pos;
-       if (buffer[pos] == '\\')
-       {
-               pos2 += 1 + (int)keylength;  // Skip \key
-               if (buffer[pos2] == '\\') pos2++; // Skip \ before value.
-               for (;buffer[pos2] && buffer[pos2] != '\\';pos2++);
-       }
-       if (bufferlength <= pos + 1 + strlen(key) + 1 + strlen(value) + strlen(buffer + pos2))
-       {
-               Con_Printf("InfoString_SetValue: no room for \"%s\" \"%s\" in infostring\n", key, value);
-               return;
-       }
-       if (value[0])
-       {
-               // set the key/value and append the remaining text
-               char tempbuffer[MAX_INPUTLINE];
-               strlcpy(tempbuffer, buffer + pos2, sizeof(tempbuffer));
-               dpsnprintf(buffer + pos, bufferlength - pos, "\\%s\\%s%s", key, value, tempbuffer);
-       }
-       else
-       {
-               // just remove the key from the text
-               strlcpy(buffer + pos, buffer + pos2, bufferlength - pos);
-       }
-}
-
-void InfoString_Print(char *buffer)
-{
-       int i;
-       char key[MAX_INPUTLINE];
-       char value[MAX_INPUTLINE];
-       while (*buffer)
-       {
-               if (*buffer != '\\')
-               {
-                       Con_Printf("InfoString_Print: corrupt string\n");
-                       return;
-               }
-               for (buffer++, i = 0;*buffer && *buffer != '\\';buffer++)
-                       if (i < (int)sizeof(key)-1)
-                               key[i++] = *buffer;
-               key[i] = 0;
-               if (*buffer != '\\')
-               {
-                       Con_Printf("InfoString_Print: corrupt string\n");
-                       return;
-               }
-               for (buffer++, i = 0;*buffer && *buffer != '\\';buffer++)
-                       if (i < (int)sizeof(value)-1)
-                               value[i++] = *buffer;
-               value[i] = 0;
-               // empty value is an error case
-               Con_Printf("%20s %s\n", key, value[0] ? value : "NO VALUE");
-       }
-}
-
 //========================================================
 // strlcat and strlcpy, from OpenBSD
 
 /*
- * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1998, 2015 Todd C. Miller <millert@openbsd.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1631,66 +1319,65 @@ void InfoString_Print(char *buffer)
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-/*     $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $    */
-/*     $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $     */
+/*     $OpenBSD: strlcat.c,v 1.19 2019/01/25 00:19:25 millert Exp $    */
+/*     $OpenBSD: strlcpy.c,v 1.16 2019/01/25 00:19:25 millert Exp $    */
 
 
 #ifndef HAVE_STRLCAT
 size_t
-strlcat(char *dst, const char *src, size_t siz)
+strlcat(char *dst, const char *src, size_t dsize)
 {
-       register char *d = dst;
-       register const char *s = src;
-       register size_t n = siz;
+       const char *odst = dst;
+       const char *osrc = src;
+       size_t n = dsize;
        size_t dlen;
 
-       /* Find the end of dst and adjust bytes left but don't go past end */
-       while (n-- != 0 && *d != '\0')
-               d++;
-       dlen = d - dst;
-       n = siz - dlen;
-
-       if (n == 0)
-               return(dlen + strlen(s));
-       while (*s != '\0') {
-               if (n != 1) {
-                       *d++ = *s;
+       /* Find the end of dst and adjust bytes left but don't go past end. */
+       while (n-- != 0 && *dst != '\0')
+               dst++;
+       dlen = dst - odst;
+       n = dsize - dlen;
+
+       if (n-- == 0)
+               return(dlen + strlen(src));
+       while (*src != '\0') {
+               if (n != 0) {
+                       *dst++ = *src;
                        n--;
                }
-               s++;
+               src++;
        }
-       *d = '\0';
+       *dst = '\0';
 
-       return(dlen + (s - src));       /* count does not include NUL */
+       return(dlen + (src - osrc));    /* count does not include NUL */
 }
 #endif  // #ifndef HAVE_STRLCAT
 
 
 #ifndef HAVE_STRLCPY
 size_t
-strlcpy(char *dst, const char *src, size_t siz)
+strlcpy(char *dst, const char *src, size_t dsize)
 {
-       register char *d = dst;
-       register const char *s = src;
-       register size_t n = siz;
-
-       /* Copy as many bytes as will fit */
-       if (n != 0 && --n != 0) {
-               do {
-                       if ((*d++ = *s++) == 0)
+       const char *osrc = src;
+       size_t nleft = dsize;
+
+       /* Copy as many bytes as will fit. */
+       if (nleft != 0) {
+               while (--nleft != 0) {
+                       if ((*dst++ = *src++) == '\0')
                                break;
-               } while (--n != 0);
+               }
        }
 
-       /* Not enough room in dst, add NUL and traverse rest of src */
-       if (n == 0) {
-               if (siz != 0)
-                       *d = '\0';              /* NUL-terminate dst */
-               while (*s++)
+       /* Not enough room in dst, add NUL and traverse rest of src. */
+       if (nleft == 0) {
+               if (dsize != 0)
+                       *dst = '\0';            /* NUL-terminate dst */
+               while (*src++)
                        ;
        }
 
-       return(s - src - 1);    /* count does not include NUL */
+       return(src - osrc - 1); /* count does not include NUL */
 }
 
 #endif  // #ifndef HAVE_STRLCPY