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 || protocol == PROTOCOL_NEHAHRAMOVIE)
277 MSG_WriteCoord13i (sb, f);
278 else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6)
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 || protocol == PROTOCOL_DARKPLACES6)
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 == PROTOCOL_NEHAHRAMOVIE)
449 return MSG_ReadCoord13i();
450 else if (protocol == PROTOCOL_DARKPLACES1 || protocol == PROTOCOL_DARKPLACES5 || protocol == PROTOCOL_DARKPLACES6)
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 || protocol == PROTOCOL_DARKPLACES6)
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 == '\'')
689 for (data++;*data != '\'';data++)
691 if (*data == '\\' && data[1] == '\'' )
693 if (!*data || len >= (int)sizeof(com_token) - 1)
699 com_token[len++] = *data;
702 *datapointer = data+1;
705 else if (*data == '\n' || *data == '{' || *data == '}' || *data == ')' || *data == '(' || *data == ']' || *data == '[' || *data == '\'' || *data == ':' || *data == ',' || *data == ';')
708 com_token[len++] = *data++;
716 for (;*data > ' ' && *data != '{' && *data != '}' && *data != ')' && *data != '(' && *data != ']' && *data != '[' && *data != '\'' && *data != ':' && *data != ',' && *data != ';' && *data != '\'' && *data != '"';data++)
718 if (len >= (int)sizeof(com_token) - 1)
724 com_token[len++] = *data;
734 COM_ParseTokenConsole
736 Parse a token out of a string, behaving like the qwcl console
739 int COM_ParseTokenConsole(const char **datapointer)
742 const char *data = *datapointer;
755 for (;*data <= ' ';data++)
765 if (*data == '/' && data[1] == '/')
768 while (*data && *data != '\n')
772 else if (*data == '\"')
775 for (data++;*data != '\"';data++)
777 if (!*data || len >= (int)sizeof(com_token) - 1)
783 com_token[len++] = *data;
786 *datapointer = data+1;
792 for (;*data > ' ';data++)
794 if (len >= (int)sizeof(com_token) - 1)
800 com_token[len++] = *data;
813 Returns the position (1 to argc-1) in the program's argument list
814 where the given parameter apears, or 0 if not present
817 int COM_CheckParm (const char *parm)
821 for (i=1 ; i<com_argc ; i++)
824 continue; // NEXTSTEP sometimes clears appkit vars.
825 if (!strcmp (parm,com_argv[i]))
836 Looks for the pop.txt file and verifies it.
837 Sets the "registered" cvar.
838 Immediately exits out if an alternate game was attempted to be started without
842 void COM_CheckRegistered (void)
844 Cvar_Set ("cmdline", com_cmdline);
846 if (!FS_FileExists("gfx/pop.lmp"))
849 Con_Print("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
851 Con_Print("Playing shareware version.\n");
855 Cvar_Set ("registered", "1");
856 Con_Print("Playing registered version.\n");
865 void COM_InitArgv (void)
868 // reconstitute the command line for the cmdline externally visible cvar
870 for (j = 0;(j < MAX_NUM_ARGVS) && (j < com_argc);j++)
873 if (strstr(com_argv[j], " "))
875 // arg contains whitespace, store quotes around it
876 com_cmdline[n++] = '\"';
877 while ((n < (CMDLINE_LENGTH - 1)) && com_argv[j][i])
878 com_cmdline[n++] = com_argv[j][i++];
879 com_cmdline[n++] = '\"';
883 while ((n < (CMDLINE_LENGTH - 1)) && com_argv[j][i])
884 com_cmdline[n++] = com_argv[j][i++];
886 if (n < (CMDLINE_LENGTH - 1))
887 com_cmdline[n++] = ' ';
895 //===========================================================================
901 const char* prog_name;
903 const char* gamename;
904 const char* gamedirname;
905 const char* gamescreenshotname;
908 static const gamemode_info_t gamemode_info [] =
909 {// prog_name cmdline gamename gamedirname gamescreenshotname
912 // COMMANDLINEOPTION: Game: -quake runs the game Quake (default)
913 { "", "-quake", "DarkPlaces-Quake", "", "dp" },
915 // COMMANDLINEOPTION: Game: -hipnotic runs Quake mission pack 1: The Scourge of Armagon
916 { "hipnotic", "-hipnotic", "Darkplaces-Hipnotic", "hipnotic", "dp" },
918 // COMMANDLINEOPTION: Game: -rogue runs Quake mission pack 2: The Dissolution of Eternity
919 { "rogue", "-rogue", "Darkplaces-Rogue", "rogue", "dp" },
921 // COMMANDLINEOPTION: Game: -nehahra runs The Seal of Nehahra movie and game
922 { "nehahra", "-nehahra", "DarkPlaces-Nehahra", "nehahra", "dp" },
924 // COMMANDLINEOPTION: Game: -nexuiz runs the multiplayer game Nexuiz
925 { "nexuiz", "-nexuiz", "Nexuiz", "data", "nexuiz" },
927 // COMMANDLINEOPTION: Game: -transfusion runs Transfusion (the recreation of Blood in Quake)
928 { "transfusion", "-transfusion", "Transfusion", "basetf", "transfusion" },
930 // COMMANDLINEOPTION: Game: -goodvsbad2 runs the psychadelic RTS FPS game Good Vs Bad 2
931 { "gvb2", "-goodvsbad2", "GoodVs.Bad2", "rts", "gvb2" },
933 // COMMANDLINEOPTION: Game: -teu runs The Evil Unleashed (this option is obsolete as they are not using darkplaces)
934 { "teu", "-teu", "TheEvilUnleashed", "baseteu", "teu" },
936 // COMMANDLINEOPTION: Game: -battlemech runs the multiplayer topdown deathmatch game BattleMech
937 { "battlemech", "-battlemech", "Battlemech", "base", "battlemech" },
939 // COMMANDLINEOPTION: Game: -zymotic runs the singleplayer game Zymotic
940 { "zymotic", "-zymotic", "Zymotic", "data", "zymotic" },
942 // COMMANDLINEOPTION: Game: -fniggium runs the post apocalyptic melee RPG Fniggium
943 { "fniggium", "-fniggium", "Fniggium", "data", "fniggium" },
945 // COMMANDLINEOPTION: Game: -setheral runs the multiplayer game Setheral
946 { "setheral", "-setheral", "Setheral", "data", "setheral" },
948 // COMMANDLINEOPTION: Game: -som runs the multiplayer game Son Of Man
949 { "som", "-som", "Son of Man", "sonofman", "som" },
951 // COMMANDLINEOPTION: Game: -tenebrae runs the graphics test mod known as Tenebrae (some features not implemented)
952 { "tenebrae", "-tenebrae", "DarkPlaces-Tenebrae", "tenebrae", "dp" },
954 // COMMANDLINEOPTION: Game: -neoteric runs the game Neoteric
955 { "neoteric", "-neoteric", "Neoteric", "neobase", "neo" },
957 // COMMANDLINEOPTION: Game: -openquartz runs the game OpenQuartz, a standalone GPL replacement of the quake content
958 { "openquartz", "-openquartz", "OpenQuartz", "id1", "openquartz"},
960 // COMMANDLINEOPTION: Game: -prydon runs the topdown point and click action-RPG Prydon Gate
961 { "prydon", "-prydon", "PrydonGate", "prydon", "prydon"},
963 // COMMANDLINEOPTION: Game: -netherworld runs the game Netherworld: Dark Masters
964 { "netherworld", "-netherworld", "Dark Masters", "netherworld", "nw"},
967 void COM_InitGameType (void)
969 char name [MAX_OSPATH];
972 FS_StripExtension (com_argv[0], name, sizeof (name));
973 COM_ToLowerString (name, name, sizeof (name));
975 // Check the binary name; default to GAME_NORMAL (0)
976 gamemode = GAME_NORMAL;
977 for (i = 1; i < sizeof (gamemode_info) / sizeof (gamemode_info[0]); i++)
978 if (strstr (name, gamemode_info[i].prog_name))
984 // Look for a command-line option
985 for (i = 0; i < sizeof (gamemode_info) / sizeof (gamemode_info[0]); i++)
986 if (COM_CheckParm (gamemode_info[i].cmdline))
992 gamename = gamemode_info[gamemode].gamename;
993 gamedirname = gamemode_info[gamemode].gamedirname;
994 gamescreenshotname = gamemode_info[gamemode].gamescreenshotname;
998 extern void Mathlib_Init(void);
999 extern void FS_Init (void);
1006 void COM_Init (void)
1008 Cvar_RegisterVariable (®istered);
1009 Cvar_RegisterVariable (&cmdline);
1014 COM_CheckRegistered ();
1017 extern void FS_Shutdown (void);
1024 void COM_Shutdown (void)
1033 does a varargs printf into a temp buffer, so I don't need to have
1034 varargs versions of all text functions.
1035 FIXME: make this buffer size safe someday
1038 char *va(const char *format, ...)
1041 // LordHavoc: now cycles through 8 buffers to avoid problems in most cases
1042 static char string[8][1024], *s;
1043 static int stringindex = 0;
1045 s = string[stringindex];
1046 stringindex = (stringindex + 1) & 7;
1047 va_start (argptr, format);
1048 vsnprintf (s, sizeof (string[0]), format,argptr);
1055 //======================================
1057 void COM_ToLowerString (const char *in, char *out, size_t size_out)
1062 while (*in && size_out > 1)
1064 if (*in >= 'A' && *in <= 'Z')
1065 *out++ = *in++ + 'a' - 'A';
1073 void COM_ToUpperString (const char *in, char *out, size_t size_out)
1078 while (*in && size_out > 1)
1080 if (*in >= 'a' && *in <= 'z')
1081 *out++ = *in++ + 'A' - 'a';
1089 int COM_StringBeginsWith(const char *s, const char *match)
1091 for (;*s && *match;s++, match++)
1097 int COM_ReadAndTokenizeLine(const char **text, char **argv, int maxargc, char *tokenbuf, int tokenbufsize, const char *commentprefix)
1099 int argc, commentprefixlength;
1103 tokenbufend = tokenbuf + tokenbufsize;
1105 commentprefixlength = 0;
1107 commentprefixlength = strlen(commentprefix);
1108 while (*l && *l != '\n')
1112 if (commentprefixlength && !strncmp(l, commentprefix, commentprefixlength))
1114 while (*l && *l != '\n')
1118 if (argc >= maxargc)
1120 argv[argc++] = tokenbuf;
1124 while (*l && *l != '"')
1126 if (tokenbuf >= tokenbufend)
1137 if (tokenbuf >= tokenbufend)
1142 if (tokenbuf >= tokenbufend)
1155 // written by Elric, thanks Elric!
1156 char *SearchInfostring(const char *infostring, const char *key)
1158 static char value [256];
1160 size_t value_ind, key_ind;
1163 if (*infostring++ != '\\')
1178 if (c == '\\' || key_ind == sizeof (crt_key) - 1)
1180 crt_key[key_ind] = '\0';
1184 crt_key[key_ind++] = c;
1187 // If it's the key we are looking for, save it in "value"
1188 if (!strcmp(crt_key, key))
1194 if (c == '\0' || c == '\\' || value_ind == sizeof (value) - 1)
1196 value[value_ind] = '\0';
1200 value[value_ind++] = c;
1204 // Else, skip the value
1218 //========================================================
1219 // strlcat and strlcpy, from OpenBSD
1222 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
1224 * Permission to use, copy, modify, and distribute this software for any
1225 * purpose with or without fee is hereby granted, provided that the above
1226 * copyright notice and this permission notice appear in all copies.
1228 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1229 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1230 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1231 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1232 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1233 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1234 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1237 /* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */
1238 /* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */
1241 #ifndef HAVE_STRLCAT
1243 strlcat(char *dst, const char *src, size_t siz)
1245 register char *d = dst;
1246 register const char *s = src;
1247 register size_t n = siz;
1250 /* Find the end of dst and adjust bytes left but don't go past end */
1251 while (n-- != 0 && *d != '\0')
1257 return(dlen + strlen(s));
1258 while (*s != '\0') {
1267 return(dlen + (s - src)); /* count does not include NUL */
1269 #endif // #ifndef HAVE_STRLCAT
1272 #ifndef HAVE_STRLCPY
1274 strlcpy(char *dst, const char *src, size_t siz)
1276 register char *d = dst;
1277 register const char *s = src;
1278 register size_t n = siz;
1280 /* Copy as many bytes as will fit */
1281 if (n != 0 && --n != 0) {
1283 if ((*d++ = *s++) == 0)
1288 /* Not enough room in dst, add NUL and traverse rest of src */
1291 *d = '\0'; /* NUL-terminate dst */
1296 return(s - src - 1); /* count does not include NUL */
1299 #endif // #ifndef HAVE_STRLCPY