]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
made darkplaces compile successfully with g++ to test for errors C doesn't care about...
[xonotic/darkplaces.git] / common.c
index 6f8065a6a48b577ea5b6a1ec023e10d72a899724..334a31b12cabefc969afc63bce09700400d02a36 100644 (file)
--- a/common.c
+++ b/common.c
@@ -40,10 +40,12 @@ const char **com_argv;
 #define CMDLINE_LENGTH 1024
 char com_cmdline[CMDLINE_LENGTH];
 
-int gamemode;
+gamemode_t gamemode;
 const char *gamename;
-const char *gamedirname;
+const char *gamedirname1;
+const char *gamedirname2;
 const char *gamescreenshotname;
+const char *gameuserdirname;
 char com_modname[MAX_OSPATH] = "";
 
 
@@ -169,7 +171,7 @@ static unsigned short crctable[256] =
        0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
 };
 
-unsigned short CRC_Block(qbyte *data, int size)
+unsigned short CRC_Block(const qbyte *data, size_t size)
 {
        unsigned short crc = CRC_INIT_VALUE;
        while (size--)
@@ -239,15 +241,21 @@ void MSG_WriteFloat (sizebuf_t *sb, float f)
        dat.f = f;
        dat.l = LittleLong (dat.l);
 
-       SZ_Write (sb, &dat.l, 4);
+       SZ_Write (sb, (qbyte *)&dat.l, 4);
 }
 
 void MSG_WriteString (sizebuf_t *sb, const char *s)
 {
        if (!s)
-               SZ_Write (sb, "", 1);
+               SZ_Write (sb, (qbyte *)"", 1);
        else
-               SZ_Write (sb, s, strlen(s)+1);
+               SZ_Write (sb, (qbyte *)s, (int)strlen(s)+1);
+}
+
+void MSG_WriteUnterminatedString (sizebuf_t *sb, const char *s)
+{
+       if (s)
+               SZ_Write (sb, (qbyte *)s, (int)strlen(s));
 }
 
 void MSG_WriteCoord13i (sizebuf_t *sb, float f)
@@ -271,19 +279,19 @@ void MSG_WriteCoord32f (sizebuf_t *sb, float f)
        MSG_WriteFloat (sb, f);
 }
 
-void MSG_WriteCoord (sizebuf_t *sb, float f, int protocol)
+void MSG_WriteCoord (sizebuf_t *sb, float f, protocolversion_t protocol)
 {
-       if (protocol == PROTOCOL_QUAKE)
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE)
                MSG_WriteCoord13i (sb, f);
-       else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5)
+       else if (protocol == PROTOCOL_DARKPLACES1)
                MSG_WriteCoord32f (sb, f);
        else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
                MSG_WriteCoord16i (sb, f);
        else
-               Host_Error("MSG_WriteCoord: unknown protocol\n");
+               MSG_WriteCoord32f (sb, f);
 }
 
-void MSG_WriteVector (sizebuf_t *sb, float *v, int protocol)
+void MSG_WriteVector (sizebuf_t *sb, float *v, protocolversion_t protocol)
 {
        MSG_WriteCoord (sb, v[0], protocol);
        MSG_WriteCoord (sb, v[1], protocol);
@@ -312,12 +320,12 @@ void MSG_WriteAngle32f (sizebuf_t *sb, float f)
        MSG_WriteFloat (sb, f);
 }
 
-void MSG_WriteAngle (sizebuf_t *sb, float f, int protocol)
+void MSG_WriteAngle (sizebuf_t *sb, float f, protocolversion_t protocol)
 {
-       if (protocol == PROTOCOL_DARKPLACES5)
-               MSG_WriteAngle16i (sb, f);
-       else
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
                MSG_WriteAngle8i (sb, f);
+       else
+               MSG_WriteAngle16i (sb, f);
 }
 
 //
@@ -443,19 +451,19 @@ float MSG_ReadCoord32f (void)
        return MSG_ReadLittleFloat();
 }
 
-float MSG_ReadCoord (int protocol)
+float MSG_ReadCoord (protocolversion_t protocol)
 {
-       if (protocol == PROTOCOL_QUAKE || protocol == 250)
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE)
                return MSG_ReadCoord13i();
-       else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5)
+       else if (protocol == PROTOCOL_DARKPLACES1)
                return MSG_ReadCoord32f();
        else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
                return MSG_ReadCoord16i();
-       Host_Error("MSG_ReadCoord: unknown protocol\n");
-       return 0;
+       else
+               return MSG_ReadCoord32f();
 }
 
-void MSG_ReadVector (float *v, int protocol)
+void MSG_ReadVector (float *v, protocolversion_t protocol)
 {
        v[0] = MSG_ReadCoord(protocol);
        v[1] = MSG_ReadCoord(protocol);
@@ -478,44 +486,25 @@ float MSG_ReadAngle32f (void)
        return MSG_ReadFloat ();
 }
 
-float MSG_ReadAngle (int protocol)
+float MSG_ReadAngle (protocolversion_t protocol)
 {
-       if (protocol == PROTOCOL_DARKPLACES5)
-               return MSG_ReadAngle16i ();
-       else
+       if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
                return MSG_ReadAngle8i ();
+       else
+               return MSG_ReadAngle16i ();
 }
 
 
 //===========================================================================
 
-void SZ_Alloc (sizebuf_t *buf, int startsize, const char *name)
-{
-       if (startsize < 256)
-               startsize = 256;
-       buf->mempool = Mem_AllocPool(name, 0, NULL);
-       buf->data = Mem_Alloc(buf->mempool, startsize);
-       buf->maxsize = startsize;
-       buf->cursize = 0;
-}
-
-
-void SZ_Free (sizebuf_t *buf)
-{
-       Mem_FreePool(&buf->mempool);
-       buf->data = NULL;
-       buf->maxsize = 0;
-       buf->cursize = 0;
-}
-
 void SZ_Clear (sizebuf_t *buf)
 {
        buf->cursize = 0;
 }
 
-void *SZ_GetSpace (sizebuf_t *buf, int length)
+qbyte *SZ_GetSpace (sizebuf_t *buf, int length)
 {
-       void *data;
+       qbyte *data;
 
        if (buf->cursize + length > buf->maxsize)
        {
@@ -536,7 +525,7 @@ void *SZ_GetSpace (sizebuf_t *buf, int length)
        return data;
 }
 
-void SZ_Write (sizebuf_t *buf, const void *data, int length)
+void SZ_Write (sizebuf_t *buf, const qbyte *data, int length)
 {
        memcpy (SZ_GetSpace(buf,length),data,length);
 }
@@ -638,7 +627,11 @@ int COM_ParseToken(const char **datapointer, int returnnewline)
 
 // skip whitespace
 skipwhite:
-       for (;*data <= ' ' && (*data != '\n' || !returnnewline);data++)
+       // line endings:
+       // UNIX: \n
+       // Mac: \r
+       // Windows: \r\n
+       for (;*data <= ' ' && ((*data != '\n' && *data != '\r') || !returnnewline);data++)
        {
                if (*data == 0)
                {
@@ -648,10 +641,14 @@ skipwhite:
                }
        }
 
+       // handle Windows line ending
+       if (data[0] == '\r' && data[1] == '\n')
+               data++;
+
        if (data[0] == '/' && data[1] == '/')
        {
                // comment
-               while (*data && *data != '\n')
+               while (*data && *data != '\n' && *data != '\r')
                        data++;
                goto skipwhite;
        }
@@ -683,6 +680,33 @@ skipwhite:
                *datapointer = data+1;
                return true;
        }
+       else if (*data == '\'')
+       {
+               // quoted string
+               for (data++;*data != '\'';data++)
+               {
+                       if (*data == '\\' && data[1] == '\'' )
+                               data++;
+                       if (!*data || len >= (int)sizeof(com_token) - 1)
+                       {
+                               com_token[0] = 0;
+                               *datapointer = NULL;
+                               return false;
+                       }
+                       com_token[len++] = *data;
+               }
+               com_token[len] = 0;
+               *datapointer = data+1;
+               return true;
+       }
+       else if (*data == '\r')
+       {
+               // translate Mac line ending to UNIX
+               com_token[len++] = '\n';
+               com_token[len] = 0;
+               *datapointer = data;
+               return true;
+       }
        else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == '\'' || *data == ':' || *data == ',' || *data == ';')
        {
                // single character
@@ -694,7 +718,7 @@ skipwhite:
        else
        {
                // regular word
-               for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != '\'' && *data != ':' && *data != ',' && *data != ';';data++)
+               for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != '\'' && *data != ':' && *data != ',' && *data != ';' && *data != '\'' && *data != '"';data++)
                {
                        if (len >= (int)sizeof(com_token) - 1)
                        {
@@ -746,7 +770,7 @@ skipwhite:
        if (*data == '/' && data[1] == '/')
        {
                // comment
-               while (*data && *data != '\n')
+               while (*data && *data != '\n' && *data != '\r')
                        data++;
                goto skipwhite;
        }
@@ -765,7 +789,6 @@ skipwhite:
                }
                com_token[len] = 0;
                *datapointer = data+1;
-               return true;
        }
        else
        {
@@ -782,8 +805,9 @@ skipwhite:
                }
                com_token[len] = 0;
                *datapointer = data;
-               return true;
        }
+
+       return true;
 }
 
 
@@ -824,7 +848,7 @@ void COM_CheckRegistered (void)
 {
        Cvar_Set ("cmdline", com_cmdline);
 
-       if (!FS_FileExists("gfx/pop.lmp"))
+       if (gamemode == GAME_NORMAL && !FS_FileExists("gfx/pop.lmp"))
        {
                if (fs_modified)
                        Con_Print("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
@@ -882,8 +906,10 @@ typedef struct
        const char* prog_name;
        const char* cmdline;
        const char* gamename;
-       const char* gamedirname;
+       const char* gamedirname1;
+       const char* gamedirname2;
        const char* gamescreenshotname;
+       const char* gameuserdirname;
 } gamemode_info_t;
 
 static const gamemode_info_t gamemode_info [] =
@@ -891,58 +917,64 @@ static const gamemode_info_t gamemode_info [] =
 
 // GAME_NORMAL
 // COMMANDLINEOPTION: Game: -quake runs the game Quake (default)
-{ "",                          "-quake",               "DarkPlaces-Quake",             "",                     "dp" },
+{ "",                          "-quake",               "DarkPlaces-Quake",             "id1",          NULL,                   "dp",                   "darkplaces" },
 // GAME_HIPNOTIC
 // COMMANDLINEOPTION: Game: -hipnotic runs Quake mission pack 1: The Scourge of Armagon
-{ "hipnotic",          "-hipnotic",    "Darkplaces-Hipnotic",  "hipnotic",     "dp" },
+{ "hipnotic",          "-hipnotic",    "Darkplaces-Hipnotic",  "id1",          "hipnotic",             "dp",                   "darkplaces" },
 // GAME_ROGUE
 // COMMANDLINEOPTION: Game: -rogue runs Quake mission pack 2: The Dissolution of Eternity
-{ "rogue",                     "-rogue",               "Darkplaces-Rogue",             "rogue",        "dp" },
+{ "rogue",                     "-rogue",               "Darkplaces-Rogue",             "id1",          "rogue",                "dp",                   "darkplaces" },
 // GAME_NEHAHRA
 // COMMANDLINEOPTION: Game: -nehahra runs The Seal of Nehahra movie and game
-{ "nehahra",           "-nehahra",             "DarkPlaces-Nehahra",   "nehahra",      "dp" },
+{ "nehahra",           "-nehahra",             "DarkPlaces-Nehahra",   "id1",          "nehahra",              "dp",                   "darkplaces" },
 // GAME_NEXUIZ
 // COMMANDLINEOPTION: Game: -nexuiz runs the multiplayer game Nexuiz
-{ "nexuiz",                    "-nexuiz",              "Nexuiz",                               "data",         "nexuiz" },
+{ "nexuiz",                    "-nexuiz",              "Nexuiz",                               "data",         NULL,                   "nexuiz",               "nexuiz" },
 // GAME_TRANSFUSION
 // COMMANDLINEOPTION: Game: -transfusion runs Transfusion (the recreation of Blood in Quake)
-{ "transfusion",       "-transfusion", "Transfusion",                  "basetf",       "transfusion" },
+{ "transfusion",       "-transfusion", "Transfusion",                  "basetf",       NULL,                   "transfusion",  "transfusion" },
 // GAME_GOODVSBAD2
 // COMMANDLINEOPTION: Game: -goodvsbad2 runs the psychadelic RTS FPS game Good Vs Bad 2
-{ "gvb2",                      "-goodvsbad2",  "GoodVs.Bad2",                  "rts",          "gvb2" },
+{ "gvb2",                      "-goodvsbad2",  "GoodVs.Bad2",                  "rts",          NULL,                   "gvb2",                 "gvb2" },
 // GAME_TEU
 // COMMANDLINEOPTION: Game: -teu runs The Evil Unleashed (this option is obsolete as they are not using darkplaces)
-{ "teu",                       "-teu",                 "TheEvilUnleashed",             "baseteu",      "teu" },
+{ "teu",                       "-teu",                 "TheEvilUnleashed",             "baseteu",      NULL,                   "teu",                  "teu" },
 // GAME_BATTLEMECH
-// COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech 
-{ "battlemech",                "-battlemech",  "Battlemech",                   "base",         "battlemech" },
+// COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech
+{ "battlemech",                "-battlemech",  "Battlemech",                   "base",         NULL,                   "battlemech",   "battlemech" },
 // GAME_ZYMOTIC
 // COMMANDLINEOPTION: Game: -zymotic runs the singleplayer game Zymotic
-{ "zymotic",           "-zymotic",             "Zymotic",                              "data",         "zymotic" },
+{ "zymotic",           "-zymotic",             "Zymotic",                              "basezym",              NULL,                   "zymotic",              "zymotic" },
 // GAME_FNIGGIUM
-// COMMANDLINEOPTION: Game: -fniggium runs the post apocalyptic melee RPG Fniggium 
-{ "fniggium",          "-fniggium",    "Fniggium",                             "data",         "fniggium" },
+// COMMANDLINEOPTION: Game: -fniggium runs the post apocalyptic melee RPG Fniggium
+{ "fniggium",          "-fniggium",    "Fniggium",                             "data",         NULL,                   "fniggium",             "fniggium" },
 // GAME_SETHERAL
-// COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral 
-{ "setheral",          "-setheral",    "Setheral",                             "data",         "setheral" },
+// COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral
+{ "setheral",          "-setheral",    "Setheral",                             "data",         NULL,                   "setheral",             "setheral" },
 // GAME_SOM
-// COMMANDLINEOPTION: Game: -som runs the multiplayer game Son Of Man 
-{ "som",                       "-som",                 "Son of Man",                   "sonofman",     "som" },
+// COMMANDLINEOPTION: Game: -som runs the multiplayer game Son Of Man
+{ "som",                       "-som",                 "Son of Man",                   "id1",          "sonofman",             "som",                  "darkplaces" },
 // GAME_TENEBRAE
 // COMMANDLINEOPTION: Game: -tenebrae runs the graphics test mod known as Tenebrae (some features not implemented)
-{ "tenebrae",          "-tenebrae",    "DarkPlaces-Tenebrae",  "tenebrae",     "dp" },
+{ "tenebrae",          "-tenebrae",    "DarkPlaces-Tenebrae",  "id1",          "tenebrae",             "dp",                   "darkplaces" },
 // GAME_NEOTERIC
 // COMMANDLINEOPTION: Game: -neoteric runs the game Neoteric
-{ "neoteric",          "-neoteric",    "Neoteric",                             "neobase",      "neo" },
+{ "neoteric",          "-neoteric",    "Neoteric",                             "id1",          "neobase",              "neo",                  "darkplaces" },
 // GAME_OPENQUARTZ
 // COMMANDLINEOPTION: Game: -openquartz runs the game OpenQuartz, a standalone GPL replacement of the quake content
-{ "openquartz",                "-openquartz",  "OpenQuartz",                   "id1",          "openquartz"},
+{ "openquartz",                "-openquartz",  "OpenQuartz",                   "id1",          NULL,                   "openquartz",   "darkplaces" },
 // GAME_PRYDON
 // COMMANDLINEOPTION: Game: -prydon runs the topdown point and click action-RPG Prydon Gate
-{ "prydon",                    "-prydon",              "PrydonGate",                   "prydon",       "prydon"},
+{ "prydon",                    "-prydon",              "PrydonGate",                   "id1",          "prydon",               "prydon",               "darkplaces" },
 // GAME_NETHERWORLD
-// COMMANDLINEOPTION: Game: -netherworld runs the game Netherworld: Dark Masters
-{ "netherworld",       "-netherworld", "Dark Masters",                 "netherworld",  "nw"},
+// COMMANDLINEOPTION: Game: -netherworld runs the game Netherworld: Dark Master
+{ "netherworld",       "-netherworld", "Netherworld: Dark Master",     "id1",          "netherworld",  "nw",                   "darkplaces" },
+// GAME_THEHUNTED
+// COMMANDLINEOPTION: Game: -thehunted runs the game The Hunted
+{ "thehunted",         "-thehunted",   "The Hunted",                   "thdata",       NULL,                   "th",                   "thehunted" },
+// GAME_DEFEATINDETAIL2
+// COMMANDLINEOPTION: Game: -did2 runs the game Defeat In Detail 2
+{ "did2",                      "-did2",                "Defeat In Detail 2",   "data",         NULL,                   "did2_",                "did2" },
 };
 
 void COM_InitGameType (void)
@@ -958,7 +990,7 @@ void COM_InitGameType (void)
        for (i = 1; i < sizeof (gamemode_info) / sizeof (gamemode_info[0]); i++)
                if (strstr (name, gamemode_info[i].prog_name))
                {
-                       gamemode = i;
+                       gamemode = (gamemode_t)i;
                        break;
                }
 
@@ -966,37 +998,29 @@ void COM_InitGameType (void)
        for (i = 0; i < sizeof (gamemode_info) / sizeof (gamemode_info[0]); i++)
                if (COM_CheckParm (gamemode_info[i].cmdline))
                {
-                       gamemode = i;
+                       gamemode = (gamemode_t)i;
                        break;
                }
 
        gamename = gamemode_info[gamemode].gamename;
-       gamedirname = gamemode_info[gamemode].gamedirname;
+       gamedirname1 = gamemode_info[gamemode].gamedirname1;
+       gamedirname2 = gamemode_info[gamemode].gamedirname2;
        gamescreenshotname = gamemode_info[gamemode].gamescreenshotname;
+       gameuserdirname = gamemode_info[gamemode].gameuserdirname;
 }
 
 
-extern void Mathlib_Init(void);
-extern void FS_Init (void);
-
 /*
 ================
 COM_Init
 ================
 */
-void COM_Init (void)
+void COM_Init_Commands (void)
 {
        Cvar_RegisterVariable (&registered);
        Cvar_RegisterVariable (&cmdline);
-
-       Mathlib_Init();
-
-       FS_Init ();
-       Log_Init ();
-       COM_CheckRegistered ();
 }
 
-
 /*
 ============
 va
@@ -1016,13 +1040,54 @@ char *va(const char *format, ...)
        s = string[stringindex];
        stringindex = (stringindex + 1) & 7;
        va_start (argptr, format);
-       vsnprintf (s, sizeof (string[0]), format,argptr);
+       dpvsnprintf (s, sizeof (string[0]), format,argptr);
        va_end (argptr);
 
        return s;
 }
 
 
+//======================================
+
+// snprintf and vsnprintf are NOT portable. Use their DP counterparts instead
+
+#undef snprintf
+#undef vsnprintf
+
+#ifdef WIN32
+# define snprintf _snprintf
+# define vsnprintf _vsnprintf
+#endif
+
+
+int dpsnprintf (char *buffer, size_t buffersize, const char *format, ...)
+{
+       va_list args;
+       int result;
+
+       va_start (args, format);
+       result = dpvsnprintf (buffer, buffersize, format, args);
+       va_end (args);
+
+       return result;
+}
+
+
+int dpvsnprintf (char *buffer, size_t buffersize, const char *format, va_list args)
+{
+       int result;
+
+       result = vsnprintf (buffer, buffersize, format, args);
+       if (result < 0 || (size_t)result >= buffersize)
+       {
+               buffer[buffersize - 1] = '\0';
+               return -1;
+       }
+
+       return result;
+}
+
+
 //======================================
 
 void COM_ToLowerString (const char *in, char *out, size_t size_out)
@@ -1075,14 +1140,14 @@ int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *t
        l = *text;
        commentprefixlength = 0;
        if (commentprefix)
-               commentprefixlength = strlen(commentprefix);
-       while (*l && *l != '\n')
+               commentprefixlength = (int)strlen(commentprefix);
+       while (*l && *l != '\n' && *l != '\r')
        {
                if (*l > ' ')
                {
                        if (commentprefixlength && !strncmp(l, commentprefix, commentprefixlength))
                        {
-                               while (*l && *l != '\n')
+                               while (*l && *l != '\n' && *l != '\r')
                                        l++;
                                break;
                        }
@@ -1117,6 +1182,12 @@ int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *t
                else
                        l++;
        }
+       // line endings:
+       // UNIX: \n
+       // Mac: \r
+       // Windows: \r\n
+       if (*l == '\r')
+               l++;
        if (*l == '\n')
                l++;
        *text = l;