2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 // common.c -- misc functions used in client and server
30 cvar_t registered = {0, "registered","0"};
31 cvar_t cmdline = {0, "cmdline","0"};
33 extern qboolean fs_modified; // set true if using non-id files
37 const char **com_argv;
39 // LordHavoc: made commandline 1024 characters instead of 256
40 #define CMDLINE_LENGTH 1024
41 char com_cmdline[CMDLINE_LENGTH];
45 const char *gamedirname;
46 const char *gamescreenshotname;
47 char com_modname[MAX_OSPATH] = "";
51 ============================================================================
55 ============================================================================
58 short ShortSwap (short l)
77 return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4;
80 float FloatSwap (float f)
90 dat2.b[0] = dat1.b[3];
91 dat2.b[1] = dat1.b[2];
92 dat2.b[2] = dat1.b[1];
93 dat2.b[3] = dat1.b[0];
98 // Extract integers from buffers
100 unsigned int BuffBigLong (const qbyte *buffer)
102 return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
105 unsigned short BuffBigShort (const qbyte *buffer)
107 return (buffer[0] << 8) | buffer[1];
110 unsigned int BuffLittleLong (const qbyte *buffer)
112 return (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] << 8) | buffer[0];
115 unsigned short BuffLittleShort (const qbyte *buffer)
117 return (buffer[1] << 8) | buffer[0];
122 ============================================================================
126 ============================================================================
129 // this is a 16 bit, non-reflected CRC using the polynomial 0x1021
130 // and the initial and final xor values shown below... in other words, the
131 // CCITT standard CRC used by XMODEM
133 #define CRC_INIT_VALUE 0xffff
134 #define CRC_XOR_VALUE 0x0000
136 static unsigned short crctable[256] =
138 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
139 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
140 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
141 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
142 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
143 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
144 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
145 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
146 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
147 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
148 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
149 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
150 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
151 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
152 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
153 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
154 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
155 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
156 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
157 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
158 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
159 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
160 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
161 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
162 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
163 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
164 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
165 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
166 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
167 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
168 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
169 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
172 unsigned short CRC_Block(qbyte *data, int size)
174 unsigned short crc = CRC_INIT_VALUE;
176 crc = (crc << 8) ^ crctable[(crc >> 8) ^ (*data++)];
177 return crc ^ CRC_XOR_VALUE;
182 ==============================================================================
186 Handles byte ordering and avoids alignment errors
187 ==============================================================================
194 void MSG_WriteChar (sizebuf_t *sb, int c)
198 buf = SZ_GetSpace (sb, 1);
202 void MSG_WriteByte (sizebuf_t *sb, int c)
206 buf = SZ_GetSpace (sb, 1);
210 void MSG_WriteShort (sizebuf_t *sb, int c)
214 buf = SZ_GetSpace (sb, 2);
219 void MSG_WriteLong (sizebuf_t *sb, int c)
223 buf = SZ_GetSpace (sb, 4);
225 buf[1] = (c>>8)&0xff;
226 buf[2] = (c>>16)&0xff;
230 void MSG_WriteFloat (sizebuf_t *sb, float f)
240 dat.l = LittleLong (dat.l);
242 SZ_Write (sb, &dat.l, 4);
245 void MSG_WriteString (sizebuf_t *sb, const char *s)
248 SZ_Write (sb, "", 1);
250 SZ_Write (sb, s, strlen(s)+1);
253 void MSG_WriteCoord13i (sizebuf_t *sb, float f)
256 MSG_WriteShort (sb, (int)(f * 8.0 + 0.5));
258 MSG_WriteShort (sb, (int)(f * 8.0 - 0.5));
261 void MSG_WriteCoord16i (sizebuf_t *sb, float f)
264 MSG_WriteShort (sb, (int)(f + 0.5));
266 MSG_WriteShort (sb, (int)(f - 0.5));
269 void MSG_WriteCoord32f (sizebuf_t *sb, float f)
271 MSG_WriteFloat (sb, f);
274 void MSG_WriteCoord (sizebuf_t *sb, float f, int protocol)
276 if (protocol == PROTOCOL_QUAKE)
277 MSG_WriteCoord13i (sb, f);
278 else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5)
279 MSG_WriteCoord32f (sb, f);
280 else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
281 MSG_WriteCoord16i (sb, f);
283 Host_Error("MSG_WriteCoord: unknown protocol\n");
286 void MSG_WriteVector (sizebuf_t *sb, float *v, int protocol)
288 MSG_WriteCoord (sb, v[0], protocol);
289 MSG_WriteCoord (sb, v[1], protocol);
290 MSG_WriteCoord (sb, v[2], protocol);
293 // LordHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
294 void MSG_WriteAngle8i (sizebuf_t *sb, float f)
297 MSG_WriteByte (sb, (int)(f*(256.0/360.0) + 0.5) & 255);
299 MSG_WriteByte (sb, (int)(f*(256.0/360.0) - 0.5) & 255);
302 void MSG_WriteAngle16i (sizebuf_t *sb, float f)
305 MSG_WriteShort (sb, (int)(f*(65536.0/360.0) + 0.5) & 65535);
307 MSG_WriteShort (sb, (int)(f*(65536.0/360.0) - 0.5) & 65535);
310 void MSG_WriteAngle32f (sizebuf_t *sb, float f)
312 MSG_WriteFloat (sb, f);
315 void MSG_WriteAngle (sizebuf_t *sb, float f, int protocol)
317 if (protocol == PROTOCOL_DARKPLACES5)
318 MSG_WriteAngle16i (sb, f);
320 MSG_WriteAngle8i (sb, f);
327 qboolean msg_badread;
329 void MSG_BeginReading (void)
335 int MSG_ReadLittleShort (void)
337 if (msg_readcount+2 > net_message.cursize)
343 return (short)(net_message.data[msg_readcount-2] | (net_message.data[msg_readcount-1]<<8));
346 int MSG_ReadBigShort (void)
348 if (msg_readcount+2 > net_message.cursize)
354 return (short)((net_message.data[msg_readcount-2]<<8) + net_message.data[msg_readcount-1]);
357 int MSG_ReadLittleLong (void)
359 if (msg_readcount+4 > net_message.cursize)
365 return net_message.data[msg_readcount-4] | (net_message.data[msg_readcount-3]<<8) | (net_message.data[msg_readcount-2]<<16) | (net_message.data[msg_readcount-1]<<24);
368 int MSG_ReadBigLong (void)
370 if (msg_readcount+4 > net_message.cursize)
376 return (net_message.data[msg_readcount-4]<<24) + (net_message.data[msg_readcount-3]<<16) + (net_message.data[msg_readcount-2]<<8) + net_message.data[msg_readcount-1];
379 float MSG_ReadLittleFloat (void)
386 if (msg_readcount+4 > net_message.cursize)
392 dat.l = net_message.data[msg_readcount-4] | (net_message.data[msg_readcount-3]<<8) | (net_message.data[msg_readcount-2]<<16) | (net_message.data[msg_readcount-1]<<24);
396 float MSG_ReadBigFloat (void)
403 if (msg_readcount+4 > net_message.cursize)
409 dat.l = (net_message.data[msg_readcount-4]<<24) | (net_message.data[msg_readcount-3]<<16) | (net_message.data[msg_readcount-2]<<8) | net_message.data[msg_readcount-1];
413 char *MSG_ReadString (void)
415 static char string[2048];
417 for (l = 0;l < (int) sizeof(string) - 1 && (c = MSG_ReadChar()) != -1 && c != 0;l++)
423 int MSG_ReadBytes (int numbytes, unsigned char *out)
426 for (l = 0;l < numbytes && (c = MSG_ReadChar()) != -1;l++)
431 float MSG_ReadCoord13i (void)
433 return MSG_ReadLittleShort() * (1.0/8.0);
436 float MSG_ReadCoord16i (void)
438 return (signed short) MSG_ReadLittleShort();
441 float MSG_ReadCoord32f (void)
443 return MSG_ReadLittleFloat();
446 float MSG_ReadCoord (int protocol)
448 if (protocol == PROTOCOL_QUAKE || protocol == 250)
449 return MSG_ReadCoord13i();
450 else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5)
451 return MSG_ReadCoord32f();
452 else if (protocol == PROTOCOL_DARKPLACES2 || protocol == PROTOCOL_DARKPLACES3 || protocol == PROTOCOL_DARKPLACES4)
453 return MSG_ReadCoord16i();
454 Host_Error("MSG_ReadCoord: unknown protocol\n");
458 void MSG_ReadVector (float *v, int protocol)
460 v[0] = MSG_ReadCoord(protocol);
461 v[1] = MSG_ReadCoord(protocol);
462 v[2] = MSG_ReadCoord(protocol);
465 // LordHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem
466 float MSG_ReadAngle8i (void)
468 return (signed char) MSG_ReadByte () * (360.0/256.0);
471 float MSG_ReadAngle16i (void)
473 return (signed short)MSG_ReadShort () * (360.0/65536.0);
476 float MSG_ReadAngle32f (void)
478 return MSG_ReadFloat ();
481 float MSG_ReadAngle (int protocol)
483 if (protocol == PROTOCOL_DARKPLACES5)
484 return MSG_ReadAngle16i ();
486 return MSG_ReadAngle8i ();
490 //===========================================================================
492 void SZ_Alloc (sizebuf_t *buf, int startsize, const char *name)
496 buf->mempool = Mem_AllocPool(name, 0, NULL);
497 buf->data = Mem_Alloc(buf->mempool, startsize);
498 buf->maxsize = startsize;
503 void SZ_Free (sizebuf_t *buf)
505 Mem_FreePool(&buf->mempool);
511 void SZ_Clear (sizebuf_t *buf)
516 void *SZ_GetSpace (sizebuf_t *buf, int length)
520 if (buf->cursize + length > buf->maxsize)
522 if (!buf->allowoverflow)
523 Host_Error ("SZ_GetSpace: overflow without allowoverflow set\n");
525 if (length > buf->maxsize)
526 Host_Error ("SZ_GetSpace: %i is > full buffer size\n", length);
528 buf->overflowed = true;
529 Con_Print("SZ_GetSpace: overflow\n");
533 data = buf->data + buf->cursize;
534 buf->cursize += length;
539 void SZ_Write (sizebuf_t *buf, const void *data, int length)
541 memcpy (SZ_GetSpace(buf,length),data,length);
544 // LordHavoc: thanks to Fuh for bringing the pure evil of SZ_Print to my
545 // attention, it has been eradicated from here, its only (former) use in
546 // all of darkplaces.
548 static char *hexchar = "0123456789ABCDEF";
549 void Com_HexDumpToConsole(const qbyte *data, int size)
553 char *cur, *flushpointer;
556 flushpointer = text + 512;
557 for (i = 0;i < size;)
564 *cur++ = hexchar[(i >> 12) & 15];
565 *cur++ = hexchar[(i >> 8) & 15];
566 *cur++ = hexchar[(i >> 4) & 15];
567 *cur++ = hexchar[(i >> 0) & 15];
570 for (j = 0;j < 16;j++)
574 *cur++ = hexchar[(d[j] >> 4) & 15];
575 *cur++ = hexchar[(d[j] >> 0) & 15];
586 for (j = 0;j < 16;j++)
590 if (d[j] >= ' ' && d[j] <= 127)
600 if (cur >= flushpointer || i >= size)
609 void SZ_HexDumpToConsole(const sizebuf_t *buf)
611 Com_HexDumpToConsole(buf->data, buf->cursize);
615 //============================================================================
622 Parse a token out of a string
625 int COM_ParseToken(const char **datapointer, int returnnewline)
628 const char *data = *datapointer;
641 for (;*data <= ' ' && (*data != '\n' || !returnnewline);data++)
651 if (data[0] == '/' && data[1] == '/')
654 while (*data && *data != '\n')
658 else if (data[0] == '/' && data[1] == '*')
662 while (*data && (data[0] != '*' || data[1] != '/'))
667 else if (*data == '\"')
670 for (data++;*data != '\"';data++)
672 if (*data == '\\' && data[1] == '"' )
674 if (!*data || len >= (int)sizeof(com_token) - 1)
680 com_token[len++] = *data;
683 *datapointer = data+1;
686 else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == '\'' || *data == ':' || *data == ',' || *data == ';')
689 com_token[len++] = *data++;
697 for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != '\'' && *data != ':' && *data != ',' && *data != ';';data++)
699 if (len >= (int)sizeof(com_token) - 1)
705 com_token[len++] = *data;
715 COM_ParseTokenConsole
717 Parse a token out of a string, behaving like the qwcl console
720 int COM_ParseTokenConsole(const char **datapointer)
723 const char *data = *datapointer;
736 for (;*data <= ' ';data++)
746 if (*data == '/' && data[1] == '/')
749 while (*data && *data != '\n')
753 else if (*data == '\"')
756 for (data++;*data != '\"';data++)
758 if (!*data || len >= (int)sizeof(com_token) - 1)
764 com_token[len++] = *data;
767 *datapointer = data+1;
773 for (;*data > ' ';data++)
775 if (len >= (int)sizeof(com_token) - 1)
781 com_token[len++] = *data;
794 Returns the position (1 to argc-1) in the program's argument list
795 where the given parameter apears, or 0 if not present
798 int COM_CheckParm (const char *parm)
802 for (i=1 ; i<com_argc ; i++)
805 continue; // NEXTSTEP sometimes clears appkit vars.
806 if (!strcmp (parm,com_argv[i]))
817 Looks for the pop.txt file and verifies it.
818 Sets the "registered" cvar.
819 Immediately exits out if an alternate game was attempted to be started without
823 void COM_CheckRegistered (void)
825 Cvar_Set ("cmdline", com_cmdline);
827 if (!FS_FileExists("gfx/pop.lmp"))
830 Con_Print("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
832 Con_Print("Playing shareware version.\n");
836 Cvar_Set ("registered", "1");
837 Con_Print("Playing registered version.\n");
846 void COM_InitArgv (void)
849 // reconstitute the command line for the cmdline externally visible cvar
851 for (j = 0;(j < MAX_NUM_ARGVS) && (j < com_argc);j++)
854 if (strstr(com_argv[j], " "))
856 // arg contains whitespace, store quotes around it
857 com_cmdline[n++] = '\"';
858 while ((n < (CMDLINE_LENGTH - 1)) && com_argv[j][i])
859 com_cmdline[n++] = com_argv[j][i++];
860 com_cmdline[n++] = '\"';
864 while ((n < (CMDLINE_LENGTH - 1)) && com_argv[j][i])
865 com_cmdline[n++] = com_argv[j][i++];
867 if (n < (CMDLINE_LENGTH - 1))
868 com_cmdline[n++] = ' ';
876 //===========================================================================
882 const char* prog_name;
884 const char* gamename;
885 const char* gamedirname;
886 const char* gamescreenshotname;
889 static const gamemode_info_t gamemode_info [] =
890 {// prog_name cmdline gamename gamedirname gamescreenshotname
893 // COMMANDLINEOPTION: Game: -quake runs the game Quake (default)
894 { "", "-quake", "DarkPlaces-Quake", "", "dp" },
896 // COMMANDLINEOPTION: Game: -hipnotic runs Quake mission pack 1: The Scourge of Armagon
897 { "hipnotic", "-hipnotic", "Darkplaces-Hipnotic", "hipnotic", "dp" },
899 // COMMANDLINEOPTION: Game: -rogue runs Quake mission pack 2: The Dissolution of Eternity
900 { "rogue", "-rogue", "Darkplaces-Rogue", "rogue", "dp" },
902 // COMMANDLINEOPTION: Game: -nehahra runs The Seal of Nehahra movie and game
903 { "nehahra", "-nehahra", "DarkPlaces-Nehahra", "nehahra", "dp" },
905 // COMMANDLINEOPTION: Game: -nexuiz runs the multiplayer game Nexuiz
906 { "nexuiz", "-nexuiz", "Nexuiz", "data", "nexuiz" },
908 // COMMANDLINEOPTION: Game: -transfusion runs Transfusion (the recreation of Blood in Quake)
909 { "transfusion", "-transfusion", "Transfusion", "basetf", "transfusion" },
911 // COMMANDLINEOPTION: Game: -goodvsbad2 runs the psychadelic RTS FPS game Good Vs Bad 2
912 { "gvb2", "-goodvsbad2", "GoodVs.Bad2", "rts", "gvb2" },
914 // COMMANDLINEOPTION: Game: -teu runs The Evil Unleashed (this option is obsolete as they are not using darkplaces)
915 { "teu", "-teu", "TheEvilUnleashed", "baseteu", "teu" },
917 // COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech
918 { "battlemech", "-battlemech", "Battlemech", "base", "battlemech" },
920 // COMMANDLINEOPTION: Game: -zymotic runs the singleplayer game Zymotic
921 { "zymotic", "-zymotic", "Zymotic", "data", "zymotic" },
923 // COMMANDLINEOPTION: Game: -fniggium runs the post apocalyptic melee RPG Fniggium
924 { "fniggium", "-fniggium", "Fniggium", "data", "fniggium" },
926 // COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral
927 { "setheral", "-setheral", "Setheral", "data", "setheral" },
929 // COMMANDLINEOPTION: Game: -som runs the multiplayer game Son Of Man
930 { "som", "-som", "Son of Man", "sonofman", "som" },
932 // COMMANDLINEOPTION: Game: -tenebrae runs the graphics test mod known as Tenebrae (some features not implemented)
933 { "tenebrae", "-tenebrae", "DarkPlaces-Tenebrae", "tenebrae", "dp" },
935 // COMMANDLINEOPTION: Game: -neoteric runs the game Neoteric
936 { "neoteric", "-neoteric", "Neoteric", "neobase", "neo" },
938 // COMMANDLINEOPTION: Game: -openquartz runs the game OpenQuartz, a standalone GPL replacement of the quake content
939 { "openquartz", "-openquartz", "OpenQuartz", "id1", "openquartz"},
941 // COMMANDLINEOPTION: Game: -prydon runs the topdown point and click action-RPG Prydon Gate
942 { "prydon", "-prydon", "PrydonGate", "prydon", "prydon"},
944 // COMMANDLINEOPTION: Game: -netherworld runs the game Netherworld: Dark Masters
945 { "netherworld", "-netherworld", "Dark Masters", "netherworld", "nw"},
948 void COM_InitGameType (void)
950 char name [MAX_OSPATH];
953 FS_StripExtension (com_argv[0], name, sizeof (name));
954 COM_ToLowerString (name, name, sizeof (name));
956 // Check the binary name; default to GAME_NORMAL (0)
957 gamemode = GAME_NORMAL;
958 for (i = 1; i < sizeof (gamemode_info) / sizeof (gamemode_info[0]); i++)
959 if (strstr (name, gamemode_info[i].prog_name))
965 // Look for a command-line option
966 for (i = 0; i < sizeof (gamemode_info) / sizeof (gamemode_info[0]); i++)
967 if (COM_CheckParm (gamemode_info[i].cmdline))
973 gamename = gamemode_info[gamemode].gamename;
974 gamedirname = gamemode_info[gamemode].gamedirname;
975 gamescreenshotname = gamemode_info[gamemode].gamescreenshotname;
979 extern void Mathlib_Init(void);
980 extern void FS_Init (void);
989 Cvar_RegisterVariable (®istered);
990 Cvar_RegisterVariable (&cmdline);
996 COM_CheckRegistered ();
1004 does a varargs printf into a temp buffer, so I don't need to have
1005 varargs versions of all text functions.
1006 FIXME: make this buffer size safe someday
1009 char *va(const char *format, ...)
1012 // LordHavoc: now cycles through 8 buffers to avoid problems in most cases
1013 static char string[8][1024], *s;
1014 static int stringindex = 0;
1016 s = string[stringindex];
1017 stringindex = (stringindex + 1) & 7;
1018 va_start (argptr, format);
1019 vsnprintf (s, sizeof (string[0]), format,argptr);
1026 //======================================
1028 void COM_ToLowerString (const char *in, char *out, size_t size_out)
1033 while (*in && size_out > 1)
1035 if (*in >= 'A' && *in <= 'Z')
1036 *out++ = *in++ + 'a' - 'A';
1044 void COM_ToUpperString (const char *in, char *out, size_t size_out)
1049 while (*in && size_out > 1)
1051 if (*in >= 'a' && *in <= 'z')
1052 *out++ = *in++ + 'A' - 'a';
1060 int COM_StringBeginsWith(const char *s, const char *match)
1062 for (;*s && *match;s++, match++)
1068 int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *tokenbuf, int tokenbufsize, const char *commentprefix)
1070 int argc, commentprefixlength;
1074 tokenbufend = tokenbuf + tokenbufsize;
1076 commentprefixlength = 0;
1078 commentprefixlength = strlen(commentprefix);
1079 while (*l && *l != '\n')
1083 if (commentprefixlength && !strncmp(l, commentprefix, commentprefixlength))
1085 while (*l && *l != '\n')
1089 if (argc >= maxargc)
1091 argv[argc++] = tokenbuf;
1095 while (*l && *l != '"')
1097 if (tokenbuf >= tokenbufend)
1108 if (tokenbuf >= tokenbufend)
1113 if (tokenbuf >= tokenbufend)
1126 // written by Elric, thanks Elric!
1127 char *SearchInfostring(const char *infostring, const char *key)
1129 static char value [256];
1131 size_t value_ind, key_ind;
1134 if (*infostring++ != '\\')
1149 if (c == '\\' || key_ind == sizeof (crt_key) - 1)
1151 crt_key[key_ind] = '\0';
1155 crt_key[key_ind++] = c;
1158 // If it's the key we are looking for, save it in "value"
1159 if (!strcmp(crt_key, key))
1165 if (c == '\0' || c == '\\' || value_ind == sizeof (value) - 1)
1167 value[value_ind] = '\0';
1171 value[value_ind++] = c;
1175 // Else, skip the value
1189 //========================================================
1190 // strlcat and strlcpy, from OpenBSD
1193 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
1195 * Permission to use, copy, modify, and distribute this software for any
1196 * purpose with or without fee is hereby granted, provided that the above
1197 * copyright notice and this permission notice appear in all copies.
1199 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1200 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1201 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1202 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1203 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1204 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1205 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1208 /* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */
1209 /* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */
1212 #ifndef HAVE_STRLCAT
1214 strlcat(char *dst, const char *src, size_t siz)
1216 register char *d = dst;
1217 register const char *s = src;
1218 register size_t n = siz;
1221 /* Find the end of dst and adjust bytes left but don't go past end */
1222 while (n-- != 0 && *d != '\0')
1228 return(dlen + strlen(s));
1229 while (*s != '\0') {
1238 return(dlen + (s - src)); /* count does not include NUL */
1240 #endif // #ifndef HAVE_STRLCAT
1243 #ifndef HAVE_STRLCPY
1245 strlcpy(char *dst, const char *src, size_t siz)
1247 register char *d = dst;
1248 register const char *s = src;
1249 register size_t n = siz;
1251 /* Copy as many bytes as will fit */
1252 if (n != 0 && --n != 0) {
1254 if ((*d++ = *s++) == 0)
1259 /* Not enough room in dst, add NUL and traverse rest of src */
1262 *d = '\0'; /* NUL-terminate dst */
1267 return(s - src - 1); /* count does not include NUL */
1270 #endif // #ifndef HAVE_STRLCPY