X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=common.c;h=ab5fc3195cda1864e69ccb49143cf26b2e8f1b5e;hb=9e3db0fc7835fee2178c2ce677fcc98d8fda449f;hp=63d6a2d9a2f8e2235e8d02901ed00eae059209e4;hpb=5e50ce0968fe5404bc5872337ed882f2505dcc9c;p=xonotic%2Fdarkplaces.git diff --git a/common.c b/common.c index 63d6a2d9..ab5fc319 100644 --- a/common.c +++ b/common.c @@ -27,20 +27,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -cvar_t registered = {0, "registered","0"}; -cvar_t cmdline = {0, "cmdline","0"}; +cvar_t registered = {0, "registered","0", "indicates if this is running registered quake (whether gfx/pop.lmp was found)"}; +cvar_t cmdline = {0, "cmdline","0", "contains commandline the engine was launched with"}; -extern qboolean fs_modified; // set true if using non-id files - -char com_token[1024]; +char com_token[MAX_INPUTLINE]; int com_argc; const char **com_argv; -// LordHavoc: made commandline 1024 characters instead of 256 -#define CMDLINE_LENGTH 1024 -char com_cmdline[CMDLINE_LENGTH]; - -int gamemode; +gamemode_t gamemode; const char *gamename; const char *gamedirname1; const char *gamedirname2; @@ -59,7 +53,7 @@ char com_modname[MAX_OSPATH] = ""; short ShortSwap (short l) { - qbyte b1,b2; + unsigned char b1,b2; b1 = l&255; b2 = (l>>8)&255; @@ -69,7 +63,7 @@ short ShortSwap (short l) int LongSwap (int l) { - qbyte b1,b2,b3,b4; + unsigned char b1,b2,b3,b4; b1 = l&255; b2 = (l>>8)&255; @@ -84,7 +78,7 @@ float FloatSwap (float f) union { float f; - qbyte b[4]; + unsigned char b[4]; } dat1, dat2; @@ -99,22 +93,22 @@ float FloatSwap (float f) // Extract integers from buffers -unsigned int BuffBigLong (const qbyte *buffer) +unsigned int BuffBigLong (const unsigned char *buffer) { return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; } -unsigned short BuffBigShort (const qbyte *buffer) +unsigned short BuffBigShort (const unsigned char *buffer) { return (buffer[0] << 8) | buffer[1]; } -unsigned int BuffLittleLong (const qbyte *buffer) +unsigned int BuffLittleLong (const unsigned char *buffer) { return (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0]; } -unsigned short BuffLittleShort (const qbyte *buffer) +unsigned short BuffLittleShort (const unsigned char *buffer) { return (buffer[1] << 8) | buffer[0]; } @@ -171,7 +165,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 unsigned char *data, size_t size) { unsigned short crc = CRC_INIT_VALUE; while (size--) @@ -179,6 +173,65 @@ unsigned short CRC_Block(qbyte *data, int size) return crc ^ CRC_XOR_VALUE; } +// QuakeWorld +static unsigned char chktbl[1024 + 4] = +{ + 0x78,0xd2,0x94,0xe3,0x41,0xec,0xd6,0xd5,0xcb,0xfc,0xdb,0x8a,0x4b,0xcc,0x85,0x01, + 0x23,0xd2,0xe5,0xf2,0x29,0xa7,0x45,0x94,0x4a,0x62,0xe3,0xa5,0x6f,0x3f,0xe1,0x7a, + 0x64,0xed,0x5c,0x99,0x29,0x87,0xa8,0x78,0x59,0x0d,0xaa,0x0f,0x25,0x0a,0x5c,0x58, + 0xfb,0x00,0xa7,0xa8,0x8a,0x1d,0x86,0x80,0xc5,0x1f,0xd2,0x28,0x69,0x71,0x58,0xc3, + 0x51,0x90,0xe1,0xf8,0x6a,0xf3,0x8f,0xb0,0x68,0xdf,0x95,0x40,0x5c,0xe4,0x24,0x6b, + 0x29,0x19,0x71,0x3f,0x42,0x63,0x6c,0x48,0xe7,0xad,0xa8,0x4b,0x91,0x8f,0x42,0x36, + 0x34,0xe7,0x32,0x55,0x59,0x2d,0x36,0x38,0x38,0x59,0x9b,0x08,0x16,0x4d,0x8d,0xf8, + 0x0a,0xa4,0x52,0x01,0xbb,0x52,0xa9,0xfd,0x40,0x18,0x97,0x37,0xff,0xc9,0x82,0x27, + 0xb2,0x64,0x60,0xce,0x00,0xd9,0x04,0xf0,0x9e,0x99,0xbd,0xce,0x8f,0x90,0x4a,0xdd, + 0xe1,0xec,0x19,0x14,0xb1,0xfb,0xca,0x1e,0x98,0x0f,0xd4,0xcb,0x80,0xd6,0x05,0x63, + 0xfd,0xa0,0x74,0xa6,0x86,0xf6,0x19,0x98,0x76,0x27,0x68,0xf7,0xe9,0x09,0x9a,0xf2, + 0x2e,0x42,0xe1,0xbe,0x64,0x48,0x2a,0x74,0x30,0xbb,0x07,0xcc,0x1f,0xd4,0x91,0x9d, + 0xac,0x55,0x53,0x25,0xb9,0x64,0xf7,0x58,0x4c,0x34,0x16,0xbc,0xf6,0x12,0x2b,0x65, + 0x68,0x25,0x2e,0x29,0x1f,0xbb,0xb9,0xee,0x6d,0x0c,0x8e,0xbb,0xd2,0x5f,0x1d,0x8f, + 0xc1,0x39,0xf9,0x8d,0xc0,0x39,0x75,0xcf,0x25,0x17,0xbe,0x96,0xaf,0x98,0x9f,0x5f, + 0x65,0x15,0xc4,0x62,0xf8,0x55,0xfc,0xab,0x54,0xcf,0xdc,0x14,0x06,0xc8,0xfc,0x42, + 0xd3,0xf0,0xad,0x10,0x08,0xcd,0xd4,0x11,0xbb,0xca,0x67,0xc6,0x48,0x5f,0x9d,0x59, + 0xe3,0xe8,0x53,0x67,0x27,0x2d,0x34,0x9e,0x9e,0x24,0x29,0xdb,0x69,0x99,0x86,0xf9, + 0x20,0xb5,0xbb,0x5b,0xb0,0xf9,0xc3,0x67,0xad,0x1c,0x9c,0xf7,0xcc,0xef,0xce,0x69, + 0xe0,0x26,0x8f,0x79,0xbd,0xca,0x10,0x17,0xda,0xa9,0x88,0x57,0x9b,0x15,0x24,0xba, + 0x84,0xd0,0xeb,0x4d,0x14,0xf5,0xfc,0xe6,0x51,0x6c,0x6f,0x64,0x6b,0x73,0xec,0x85, + 0xf1,0x6f,0xe1,0x67,0x25,0x10,0x77,0x32,0x9e,0x85,0x6e,0x69,0xb1,0x83,0x00,0xe4, + 0x13,0xa4,0x45,0x34,0x3b,0x40,0xff,0x41,0x82,0x89,0x79,0x57,0xfd,0xd2,0x8e,0xe8, + 0xfc,0x1d,0x19,0x21,0x12,0x00,0xd7,0x66,0xe5,0xc7,0x10,0x1d,0xcb,0x75,0xe8,0xfa, + 0xb6,0xee,0x7b,0x2f,0x1a,0x25,0x24,0xb9,0x9f,0x1d,0x78,0xfb,0x84,0xd0,0x17,0x05, + 0x71,0xb3,0xc8,0x18,0xff,0x62,0xee,0xed,0x53,0xab,0x78,0xd3,0x65,0x2d,0xbb,0xc7, + 0xc1,0xe7,0x70,0xa2,0x43,0x2c,0x7c,0xc7,0x16,0x04,0xd2,0x45,0xd5,0x6b,0x6c,0x7a, + 0x5e,0xa1,0x50,0x2e,0x31,0x5b,0xcc,0xe8,0x65,0x8b,0x16,0x85,0xbf,0x82,0x83,0xfb, + 0xde,0x9f,0x36,0x48,0x32,0x79,0xd6,0x9b,0xfb,0x52,0x45,0xbf,0x43,0xf7,0x0b,0x0b, + 0x19,0x19,0x31,0xc3,0x85,0xec,0x1d,0x8c,0x20,0xf0,0x3a,0xfa,0x80,0x4d,0x2c,0x7d, + 0xac,0x60,0x09,0xc0,0x40,0xee,0xb9,0xeb,0x13,0x5b,0xe8,0x2b,0xb1,0x20,0xf0,0xce, + 0x4c,0xbd,0xc6,0x04,0x86,0x70,0xc6,0x33,0xc3,0x15,0x0f,0x65,0x19,0xfd,0xc2,0xd3, + + // map checksum goes here + 0x00,0x00,0x00,0x00 +}; + +// QuakeWorld +unsigned char COM_BlockSequenceCRCByteQW(unsigned char *base, int length, int sequence) +{ + unsigned char *p; + unsigned char chkb[60 + 4]; + + p = chktbl + (sequence % (sizeof(chktbl) - 8)); + + if (length > 60) + length = 60; + memcpy(chkb, base, length); + + chkb[length] = (sequence & 0xff) ^ p[0]; + chkb[length+1] = p[1]; + chkb[length+2] = ((sequence>>8) & 0xff) ^ p[2]; + chkb[length+3] = p[3]; + + return CRC_Block(chkb, length + 4) & 0xff; +} /* ============================================================================== @@ -195,7 +248,7 @@ Handles byte ordering and avoids alignment errors void MSG_WriteChar (sizebuf_t *sb, int c) { - qbyte *buf; + unsigned char *buf; buf = SZ_GetSpace (sb, 1); buf[0] = c; @@ -203,7 +256,7 @@ void MSG_WriteChar (sizebuf_t *sb, int c) void MSG_WriteByte (sizebuf_t *sb, int c) { - qbyte *buf; + unsigned char *buf; buf = SZ_GetSpace (sb, 1); buf[0] = c; @@ -211,7 +264,7 @@ void MSG_WriteByte (sizebuf_t *sb, int c) void MSG_WriteShort (sizebuf_t *sb, int c) { - qbyte *buf; + unsigned char *buf; buf = SZ_GetSpace (sb, 2); buf[0] = c&0xff; @@ -220,7 +273,7 @@ void MSG_WriteShort (sizebuf_t *sb, int c) void MSG_WriteLong (sizebuf_t *sb, int c) { - qbyte *buf; + unsigned char *buf; buf = SZ_GetSpace (sb, 4); buf[0] = c&0xff; @@ -241,15 +294,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, (unsigned char *)&dat.l, 4); } void MSG_WriteString (sizebuf_t *sb, const char *s) { - if (!s) - SZ_Write (sb, "", 1); + if (!s || !*s) + MSG_WriteChar (sb, 0); else - SZ_Write (sb, s, strlen(s)+1); + SZ_Write (sb, (unsigned char *)s, (int)strlen(s)+1); +} + +void MSG_WriteUnterminatedString (sizebuf_t *sb, const char *s) +{ + if (s && *s) + SZ_Write (sb, (unsigned char *)s, (int)strlen(s)); } void MSG_WriteCoord13i (sizebuf_t *sb, float f) @@ -273,19 +332,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 || protocol == PROTOCOL_NEHAHRAMOVIE) + if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_QUAKEWORLD) MSG_WriteCoord13i (sb, f); - else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6) + 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); @@ -314,12 +373,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 || protocol == PROTOCOL_DARKPLACES6) - 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 || protocol == PROTOCOL_QUAKEWORLD) MSG_WriteAngle8i (sb, f); + else + MSG_WriteAngle16i (sb, f); } // @@ -414,9 +473,9 @@ float MSG_ReadBigFloat (void) char *MSG_ReadString (void) { - static char string[2048]; + static char string[MAX_INPUTLINE]; int l,c; - for (l = 0;l < (int) sizeof(string) - 1 && (c = MSG_ReadChar()) != -1 && c != 0;l++) + for (l = 0;l < (int) sizeof(string) - 1 && (c = MSG_ReadByte()) != -1 && c != 0;l++) string[l] = c; string[l] = 0; return string; @@ -425,7 +484,7 @@ char *MSG_ReadString (void) int MSG_ReadBytes (int numbytes, unsigned char *out) { int l, c; - for (l = 0;l < numbytes && (c = MSG_ReadChar()) != -1;l++) + for (l = 0;l < numbytes && (c = MSG_ReadByte()) != -1;l++) out[l] = c; return l; } @@ -445,19 +504,19 @@ float MSG_ReadCoord32f (void) return MSG_ReadLittleFloat(); } -float MSG_ReadCoord (int protocol) +float MSG_ReadCoord (protocolversion_t protocol) { - if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_NEHAHRAMOVIE) + if (protocol == PROTOCOL_QUAKE || protocol == PROTOCOL_QUAKEDP || protocol == PROTOCOL_NEHAHRAMOVIE || protocol == PROTOCOL_QUAKEWORLD) return MSG_ReadCoord13i(); - else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6) + 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); @@ -480,52 +539,33 @@ float MSG_ReadAngle32f (void) return MSG_ReadFloat (); } -float MSG_ReadAngle (int protocol) +float MSG_ReadAngle (protocolversion_t protocol) { - if (protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6) - 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 || protocol == PROTOCOL_QUAKEWORLD) 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) +unsigned char *SZ_GetSpace (sizebuf_t *buf, int length) { - void *data; + unsigned char *data; if (buf->cursize + length > buf->maxsize) { if (!buf->allowoverflow) - Host_Error ("SZ_GetSpace: overflow without allowoverflow set\n"); + Host_Error ("SZ_GetSpace: overflow without allowoverflow set"); if (length > buf->maxsize) - Host_Error ("SZ_GetSpace: %i is > full buffer size\n", length); + Host_Error ("SZ_GetSpace: %i is > full buffer size", length); buf->overflowed = true; Con_Print("SZ_GetSpace: overflow\n"); @@ -538,7 +578,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 unsigned char *data, int length) { memcpy (SZ_GetSpace(buf,length),data,length); } @@ -548,12 +588,12 @@ void SZ_Write (sizebuf_t *buf, const void *data, int length) // all of darkplaces. static char *hexchar = "0123456789ABCDEF"; -void Com_HexDumpToConsole(const qbyte *data, int size) +void Com_HexDumpToConsole(const unsigned char *data, int size) { int i, j, n; char text[1024]; char *cur, *flushpointer; - const qbyte *d; + const unsigned char *d; cur = text; flushpointer = text + 512; for (i = 0;i < size;) @@ -589,7 +629,13 @@ void Com_HexDumpToConsole(const qbyte *data, int size) { if (j < n) { - if (d[j] >= ' ' && d[j] <= 127) + // color change prefix character has to be treated specially + if (d[j] == STRING_COLOR_TAG) + { + *cur++ = STRING_COLOR_TAG; + *cur++ = STRING_COLOR_TAG; + } + else if (d[j] >= ' ') *cur++ = d[j]; else *cur++ = '.'; @@ -627,6 +673,7 @@ Parse a token out of a string int COM_ParseToken(const char **datapointer, int returnnewline) { int len; + int c; const char *data = *datapointer; len = 0; @@ -679,15 +726,34 @@ skipwhite: // 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; + c = *data; + if (*data == '\\') + { + if (data[1] == '"') + { + data++; + c = *data; + } + else if (data[1] == '\'') + { + data++; + c = *data; + } + else if (data[1] == 'n') + { + data++; + c = '\n'; + } + else if (data[1] == '\\') + data++; + } + com_token[len++] = c; } com_token[len] = 0; *datapointer = data+1; @@ -698,15 +764,34 @@ skipwhite: // 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; + c = *data; + if (*data == '\\') + { + if (data[1] == '"') + { + data++; + c = *data; + } + else if (data[1] == '\'') + { + data++; + c = *data; + } + else if (data[1] == 'n') + { + data++; + c = '\n'; + } + else if (data[1] == '\\') + data++; + } + com_token[len++] = c; } com_token[len] = 0; *datapointer = data+1; @@ -739,7 +824,28 @@ skipwhite: *datapointer = NULL; return false; } - com_token[len++] = *data; + c = *data; + if (*data == '\\') + { + if (data[1] == '"') + { + data++; + c = *data; + } + else if (data[1] == '\'') + { + data++; + c = *data; + } + else if (data[1] == 'n') + { + data++; + c = '\n'; + } + else if (data[1] == '\\') + data++; + } + com_token[len++] = c; } com_token[len] = 0; *datapointer = data; @@ -802,7 +908,22 @@ skipwhite: } com_token[len] = 0; *datapointer = data+1; - return true; + } + else if (*data == '\'') + { + // quoted string + for (data++;*data != '\'';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; } else { @@ -819,8 +940,9 @@ skipwhite: } com_token[len] = 0; *datapointer = data; - return true; } + + return true; } @@ -847,74 +969,11 @@ int COM_CheckParm (const char *parm) return 0; } -/* -================ -COM_CheckRegistered - -Looks for the pop.txt file and verifies it. -Sets the "registered" cvar. -Immediately exits out if an alternate game was attempted to be started without -being registered. -================ -*/ -void COM_CheckRegistered (void) -{ - Cvar_Set ("cmdline", com_cmdline); - - if (!FS_FileExists("gfx/pop.lmp")) - { - if (fs_modified) - Con_Print("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n"); - else - Con_Print("Playing shareware version.\n"); - return; - } - - Cvar_Set ("registered", "1"); - Con_Print("Playing registered version.\n"); -} - - -/* -================ -COM_InitArgv -================ -*/ -void COM_InitArgv (void) -{ - int i, j, n; - // reconstitute the command line for the cmdline externally visible cvar - n = 0; - for (j = 0;(j < MAX_NUM_ARGVS) && (j < com_argc);j++) - { - i = 0; - if (strstr(com_argv[j], " ")) - { - // arg contains whitespace, store quotes around it - com_cmdline[n++] = '\"'; - while ((n < (CMDLINE_LENGTH - 1)) && com_argv[j][i]) - com_cmdline[n++] = com_argv[j][i++]; - com_cmdline[n++] = '\"'; - } - else - { - while ((n < (CMDLINE_LENGTH - 1)) && com_argv[j][i]) - com_cmdline[n++] = com_argv[j][i++]; - } - if (n < (CMDLINE_LENGTH - 1)) - com_cmdline[n++] = ' '; - else - break; - } - com_cmdline[n] = 0; -} - - //=========================================================================== // Game mods -typedef struct +typedef struct gamemode_info_s { const char* prog_name; const char* cmdline; @@ -957,10 +1016,7 @@ static const gamemode_info_t gamemode_info [] = { "battlemech", "-battlemech", "Battlemech", "base", NULL, "battlemech", "battlemech" }, // GAME_ZYMOTIC // COMMANDLINEOPTION: Game: -zymotic runs the singleplayer game Zymotic -{ "zymotic", "-zymotic", "Zymotic", "data", NULL, "zymotic", "zymotic" }, -// GAME_FNIGGIUM -// COMMANDLINEOPTION: Game: -fniggium runs the post apocalyptic melee RPG Fniggium -{ "fniggium", "-fniggium", "Fniggium", "data", NULL, "fniggium", "fniggium" }, +{ "zymotic", "-zymotic", "Zymotic", "basezym", NULL, "zymotic", "zymotic" }, // GAME_SETHERAL // COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral { "setheral", "-setheral", "Setheral", "data", NULL, "setheral", "setheral" }, @@ -975,13 +1031,25 @@ static const gamemode_info_t gamemode_info [] = { "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", NULL, "openquartz", "darkplaces"}, +{ "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", "id1", "prydon", "prydon", "darkplaces"}, +{ "prydon", "-prydon", "PrydonGate", "id1", "prydon", "prydon", "darkplaces" }, // GAME_NETHERWORLD -// COMMANDLINEOPTION: Game: -netherworld runs the game Netherworld: Dark Masters -{ "netherworld", "-netherworld", "Dark Masters", "id1", "netherworld", "nw", "darkplaces"}, +// 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" }, +// GAME_DARSANA +// COMMANDLINEOPTION: Game: -darsana runs the game Darsana +{ "darsana", "-darsana", "Darsana", "ddata", NULL, "darsana", "darsana" }, +// GAME_CONTAGIONTHEORY +// COMMANDLINEOPTION: Game: -contagiontheory runs the game Contagion Theory +{ "contagiontheory", "-contagiontheory", "Contagion Theory", "ctdata", NULL, "ct", "contagiontheory" }, }; void COM_InitGameType (void) @@ -997,7 +1065,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; } @@ -1005,7 +1073,7 @@ 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; } @@ -1017,35 +1085,44 @@ void COM_InitGameType (void) } -extern void Mathlib_Init(void); -extern void FS_Init (void); - /* ================ COM_Init ================ */ -void COM_Init (void) +void COM_Init_Commands (void) { + int i, j, n; + char com_cmdline[MAX_INPUTLINE]; + Cvar_RegisterVariable (®istered); Cvar_RegisterVariable (&cmdline); - Mathlib_Init(); - - FS_Init (); - COM_CheckRegistered (); -} - -extern void FS_Shutdown (void); - -/* -================ -COM_Shutdown -================ -*/ -void COM_Shutdown (void) -{ - FS_Shutdown (); + // reconstitute the command line for the cmdline externally visible cvar + n = 0; + for (j = 0;(j < MAX_NUM_ARGVS) && (j < com_argc);j++) + { + i = 0; + if (strstr(com_argv[j], " ")) + { + // arg contains whitespace, store quotes around it + com_cmdline[n++] = '\"'; + while ((n < ((int)sizeof(com_cmdline) - 1)) && com_argv[j][i]) + com_cmdline[n++] = com_argv[j][i++]; + com_cmdline[n++] = '\"'; + } + else + { + while ((n < ((int)sizeof(com_cmdline) - 1)) && com_argv[j][i]) + com_cmdline[n++] = com_argv[j][i++]; + } + if (n < ((int)sizeof(com_cmdline) - 1)) + com_cmdline[n++] = ' '; + else + break; + } + com_cmdline[n] = 0; + Cvar_Set ("cmdline", com_cmdline); } /* @@ -1067,13 +1144,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) @@ -1126,7 +1244,7 @@ int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *t l = *text; commentprefixlength = 0; if (commentprefix) - commentprefixlength = strlen(commentprefix); + commentprefixlength = (int)strlen(commentprefix); while (*l && *l != '\n' && *l != '\r') { if (*l > ' ') @@ -1183,8 +1301,8 @@ int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *t // written by Elric, thanks Elric! char *SearchInfostring(const char *infostring, const char *key) { - static char value [256]; - char crt_key [256]; + static char value [MAX_INPUTLINE]; + char crt_key [MAX_INPUTLINE]; size_t value_ind, key_ind; char c; @@ -1242,6 +1360,139 @@ char *SearchInfostring(const char *infostring, const char *key) } } +void InfoString_GetValue(const char *buffer, const char *key, char *value, size_t valuelength) +{ + int pos = 0, j; + size_t keylength; + if (!key) + key = ""; + if (!value) + value = ""; + keylength = strlen(key); + if (valuelength < 1 || !value) + { + Con_Printf("InfoString_GetValue: no room in value\n"); + return; + } + value[0] = 0; + if (strchr(key, '\\')) + { + Con_Printf("InfoString_GetValue: key name \"%s\" contains \\ which is not possible in an infostring\n", key); + return; + } + if (strchr(key, '\"')) + { + Con_Printf("InfoString_SetValue: key name \"%s\" contains \" which is not allowed in an infostring\n", key); + return; + } + if (!key[0]) + { + Con_Printf("InfoString_GetValue: can not look up a key with no name\n"); + return; + } + while (buffer[pos] == '\\') + { + if (!memcmp(buffer + pos+1, key, keylength)) + { + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + pos++; + for (j = 0;buffer[pos+j] && buffer[pos+j] != '\\' && j < (int)valuelength - 1;j++) + value[j] = buffer[pos+j]; + value[j] = 0; + return; + } + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + } + // if we reach this point the key was not found +} + +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)) + break; + for (pos++;buffer[pos] && buffer[pos] != '\\';pos++); + for (pos++;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] == '\\') + { + for (pos2++;buffer[pos2] && buffer[pos2] != '\\';pos2++); + for (pos2++;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 && value[0]) + { + // set the key/value and append the remaining text + char tempbuffer[4096]; + strlcpy(tempbuffer, buffer + pos2, sizeof(tempbuffer)); + sprintf(buffer + 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[2048]; + char value[2048]; + 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