X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=common.c;h=0f413b2ddde0cc493ed19b662cfde10571388041;hp=7a042874f45cdb453f6ffd182c0d2207cd6d0551;hb=d73510b7f24213b76b1611909adc9e39d77215d2;hpb=45982a9894c5bff60ff494a0f82865ec267d52f7 diff --git a/common.c b/common.c index 7a042874..0f413b2d 100644 --- a/common.c +++ b/common.c @@ -29,37 +29,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -#define NUM_SAFE_ARGVS 7 - -static char *largv[MAX_NUM_ARGVS + NUM_SAFE_ARGVS + 1]; -static char *argvdummy = " "; - -static char *safeargvs[NUM_SAFE_ARGVS] = - {"-stdvid", "-nolan", "-nosound", "-nocdaudio", "-nojoy", "-nomouse", "-dibonly"}; - cvar_t registered = {0, "registered","0"}; cvar_t cmdline = {0, "cmdline","0"}; -qboolean com_modified; // set true if using non-id files - -//qboolean proghack; +mempool_t *pak_mempool; -//int static_registered = 1; // only for startup check, then set - -qboolean msg_suppress_1 = 0; +qboolean com_modified; // set true if using non-id files void COM_InitFilesystem (void); -char com_token[1024]; -int com_argc; -char **com_argv; +char com_token[1024]; +char com_basedir[MAX_OSPATH]; +int com_argc; +const char **com_argv; // LordHavoc: made commandline 1024 characters instead of 256 #define CMDLINE_LENGTH 1024 -char com_cmdline[CMDLINE_LENGTH]; +char com_cmdline[CMDLINE_LENGTH]; int gamemode; char *gamename; +char *gamedirname; +char com_modname[MAX_OSPATH]; /* @@ -93,127 +84,7 @@ The file "parms.txt" will be read out of the game directory and appended to the ============================================================================ */ -/* -void Q_memset (void *dest, int fill, int count) -{ - int i; - - if ( (((long)dest | count) & 3) == 0) - { - count >>= 2; - fill = fill | (fill<<8) | (fill<<16) | (fill<<24); - for (i=0 ; i>=2; - for (i=0 ; i= 'a' && c1 <= 'z') @@ -236,152 +107,15 @@ int Q_strncasecmp (char *s1, char *s2, int n) } if (!c1) return 0; // strings are equal -// s1++; -// s2++; } - + return -1; } -int Q_strcasecmp (char *s1, char *s2) +int Q_strcasecmp (const char *s1, const char *s2) { return Q_strncasecmp (s1, s2, 99999); } -/* -int Q_atoi (char *str) -{ - int val; - int sign; - int c; - - if (*str == '-') - { - sign = -1; - str++; - } - else - sign = 1; - - val = 0; - -// -// check for hex -// - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) - { - str += 2; - while (1) - { - c = *str++; - if (c >= '0' && c <= '9') - val = (val<<4) + c - '0'; - else if (c >= 'a' && c <= 'f') - val = (val<<4) + c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - val = (val<<4) + c - 'A' + 10; - else - return val*sign; - } - } - -// -// check for character -// - if (str[0] == '\'') - { - return sign * str[1]; - } - -// -// assume decimal -// - while (1) - { - c = *str++; - if (c <'0' || c > '9') - return val*sign; - val = val*10 + c - '0'; - } - - return 0; -} - - -float Q_atof (char *str) -{ - double val; - int sign; - int c; - int decimal, total; - - if (*str == '-') - { - sign = -1; - str++; - } - else - sign = 1; - - val = 0; - -// -// check for hex -// - if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) - { - str += 2; - while (1) - { - c = *str++; - if (c >= '0' && c <= '9') - val = (val*16) + c - '0'; - else if (c >= 'a' && c <= 'f') - val = (val*16) + c - 'a' + 10; - else if (c >= 'A' && c <= 'F') - val = (val*16) + c - 'A' + 10; - else - return val*sign; - } - } - -// -// check for character -// - if (str[0] == '\'') - { - return sign * str[1]; - } - -// -// assume decimal -// - decimal = -1; - total = 0; - while (1) - { - c = *str++; - if (c == '.') - { - decimal = total; - continue; - } - if (c <'0' || c > '9') - break; - val = val*10 + c - '0'; - total++; - } - - if (decimal == -1) - return val*sign; - while (total > decimal) - { - val /= 10; - total--; - } - - return val*sign; -} -*/ /* ============================================================================ @@ -402,7 +136,7 @@ float (*LittleFloat) (float l); short ShortSwap (short l) { - byte b1,b2; + qbyte b1,b2; b1 = l&255; b2 = (l>>8)&255; @@ -410,14 +144,16 @@ short ShortSwap (short l) return (b1<<8) + b2; } +#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG) short ShortNoSwap (short l) { return l; } +#endif int LongSwap (int l) { - byte b1,b2,b3,b4; + qbyte b1,b2,b3,b4; b1 = l&255; b2 = (l>>8)&255; @@ -427,20 +163,22 @@ int LongSwap (int l) return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; } +#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG) int LongNoSwap (int l) { return l; } +#endif float FloatSwap (float f) { union { float f; - byte b[4]; + qbyte b[4]; } dat1, dat2; - - + + dat1.f = f; dat2.b[0] = dat1.b[3]; dat2.b[1] = dat1.b[2]; @@ -449,10 +187,12 @@ float FloatSwap (float f) return dat2.f; } +#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG) float FloatNoSwap (float f) { return f; } +#endif /* ============================================================================== @@ -469,38 +209,23 @@ Handles byte ordering and avoids alignment errors void MSG_WriteChar (sizebuf_t *sb, int c) { - byte *buf; + qbyte *buf; -//#ifdef PARANOID -// if (c < -128 || c > 127) -// Sys_Error ("MSG_WriteChar: range error"); -//#endif - buf = SZ_GetSpace (sb, 1); buf[0] = c; } void MSG_WriteByte (sizebuf_t *sb, int c) { - byte *buf; + qbyte *buf; -//#ifdef PARANOID -// if (c < 0 || c > 255) -// Sys_Error ("MSG_WriteByte: range error"); -//#endif - buf = SZ_GetSpace (sb, 1); buf[0] = c; } void MSG_WriteShort (sizebuf_t *sb, int c) { - byte *buf; - -//#ifdef PARANOID -// if (c < ((short)0x8000) || c > (short)0x7fff) -// Sys_Error ("MSG_WriteShort: range error"); -//#endif + qbyte *buf; buf = SZ_GetSpace (sb, 2); buf[0] = c&0xff; @@ -509,8 +234,8 @@ void MSG_WriteShort (sizebuf_t *sb, int c) void MSG_WriteLong (sizebuf_t *sb, int c) { - byte *buf; - + qbyte *buf; + buf = SZ_GetSpace (sb, 4); buf[0] = c&0xff; buf[1] = (c>>8)&0xff; @@ -525,15 +250,15 @@ void MSG_WriteFloat (sizebuf_t *sb, float f) float f; int l; } dat; - - + + dat.f = f; dat.l = LittleLong (dat.l); - + SZ_Write (sb, &dat.l, 4); } -void MSG_WriteString (sizebuf_t *sb, char *s) +void MSG_WriteString (sizebuf_t *sb, const char *s) { if (!s) SZ_Write (sb, "", 1); @@ -541,40 +266,37 @@ void MSG_WriteString (sizebuf_t *sb, char *s) SZ_Write (sb, s, strlen(s)+1); } -// used by server (always dpprotocol) -// moved to common.h as #define -/* -void MSG_WriteFloatCoord (sizebuf_t *sb, float f) +// used by server (always latest dpprotocol) +void MSG_WriteDPCoord (sizebuf_t *sb, float f) { - MSG_WriteFloat(sb, f); -} -*/ - -// used by client -void MSG_WriteCoord (sizebuf_t *sb, float f) -{ - if (dpprotocol) - MSG_WriteFloat(sb, f); + if (f >= 0) + MSG_WriteShort (sb, (int)(f + 0.5f)); else - MSG_WriteShort (sb, (int)(f*8.0f + 0.5f)); + MSG_WriteShort (sb, (int)(f - 0.5f)); } void MSG_WritePreciseAngle (sizebuf_t *sb, float f) { - MSG_WriteShort (sb, (int)(f*(65536.0f/360.0f) + 0.5f) & 65535); + if (f >= 0) + MSG_WriteShort (sb, (int)(f*(65536.0f/360.0f) + 0.5f) & 65535); + else + MSG_WriteShort (sb, (int)(f*(65536.0f/360.0f) - 0.5f) & 65535); } -// LordHavoc: round to nearest value, rather than rounding down, fixes crosshair problem +// LordHavoc: round to nearest value, rather than rounding toward zero, fixes crosshair problem void MSG_WriteAngle (sizebuf_t *sb, float f) { - MSG_WriteByte (sb, (int)(f*(256.0f/360.0f) + 0.5f) & 255); + if (f >= 0) + MSG_WriteByte (sb, (int)(f*(256.0f/360.0f) + 0.5f) & 255); + else + MSG_WriteByte (sb, (int)(f*(256.0f/360.0f) - 0.5f) & 255); } // // reading functions // -int msg_readcount; -qboolean msg_badread; +int msg_readcount; +qboolean msg_badread; void MSG_BeginReading (void) { @@ -582,67 +304,28 @@ void MSG_BeginReading (void) msg_badread = false; } -/* -// returns -1 and sets msg_badread if no more characters are available -int MSG_ReadChar (void) -{ - int c; - - // LordHavoc: minor optimization - if (msg_readcount >= net_message.cursize) -// if (msg_readcount+1 > net_message.cursize) - { - msg_badread = true; - return -1; - } - - c = (signed char)net_message.data[msg_readcount]; - msg_readcount++; - - return c; -} - -int MSG_ReadByte (void) -{ - int c; - - // LordHavoc: minor optimization - if (msg_readcount >= net_message.cursize) -// if (msg_readcount+1 > net_message.cursize) - { - msg_badread = true; - return -1; - } - - c = (unsigned char)net_message.data[msg_readcount]; - msg_readcount++; - - return c; -} -*/ - int MSG_ReadShort (void) { - int c; - + int c; + if (msg_readcount+2 > net_message.cursize) { msg_badread = true; return -1; } - + c = (short)(net_message.data[msg_readcount] + (net_message.data[msg_readcount+1]<<8)); - + msg_readcount += 2; - + return c; } int MSG_ReadLong (void) { - int c; - + int c; + if (msg_readcount+4 > net_message.cursize) { msg_badread = true; @@ -653,9 +336,9 @@ int MSG_ReadLong (void) + (net_message.data[msg_readcount+1]<<8) + (net_message.data[msg_readcount+2]<<16) + (net_message.data[msg_readcount+3]<<24); - + msg_readcount += 4; - + return c; } @@ -663,27 +346,27 @@ float MSG_ReadFloat (void) { union { - byte b[4]; - float f; - int l; + qbyte b[4]; + float f; + int l; } dat; - + dat.b[0] = net_message.data[msg_readcount]; dat.b[1] = net_message.data[msg_readcount+1]; dat.b[2] = net_message.data[msg_readcount+2]; dat.b[3] = net_message.data[msg_readcount+3]; msg_readcount += 4; - + dat.l = LittleLong (dat.l); - return dat.f; + return dat.f; } char *MSG_ReadString (void) { - static char string[2048]; - int l,c; - + static char string[2048]; + int l,c; + l = 0; do { @@ -693,55 +376,38 @@ char *MSG_ReadString (void) string[l] = c; l++; } while (l < sizeof(string)-1); - + string[l] = 0; - + return string; } -// used by server (always dpprotocol) -// moved to common.h as #define -/* -float MSG_ReadFloatCoord (void) +// used by server (always latest dpprotocol) +float MSG_ReadDPCoord (void) { - return MSG_ReadFloat(); + return (signed short) MSG_ReadShort(); } -*/ // used by client float MSG_ReadCoord (void) { - if (dpprotocol) + if (dpprotocol == DPPROTOCOL_VERSION2 || dpprotocol == DPPROTOCOL_VERSION3) + return (signed short) MSG_ReadShort(); + else if (dpprotocol == DPPROTOCOL_VERSION1) return MSG_ReadFloat(); else return MSG_ReadShort() * (1.0f/8.0f); } -/* -float MSG_ReadCoord (void) -{ - return MSG_ReadShort() * (1.0f/8.0f); -} - -float MSG_ReadAngle (void) -{ - return MSG_ReadChar() * (360.0f/256.0f); -} - -float MSG_ReadPreciseAngle (void) -{ - return MSG_ReadShort() * (360.0f/65536); -} -*/ - //=========================================================================== -void SZ_Alloc (sizebuf_t *buf, int startsize) +void SZ_Alloc (sizebuf_t *buf, int startsize, const char *name) { if (startsize < 256) startsize = 256; - buf->data = Hunk_AllocName (startsize, "sizebuf"); + buf->mempool = Mem_AllocPool(name); + buf->data = Mem_Alloc(buf->mempool, startsize); buf->maxsize = startsize; buf->cursize = 0; } @@ -749,9 +415,9 @@ void SZ_Alloc (sizebuf_t *buf, int startsize) void SZ_Free (sizebuf_t *buf) { -// Z_Free (buf->data); -// buf->data = NULL; -// buf->maxsize = 0; + Mem_FreePool(&buf->mempool); + buf->data = NULL; + buf->maxsize = 0; buf->cursize = 0; } @@ -762,87 +428,118 @@ void SZ_Clear (sizebuf_t *buf) void *SZ_GetSpace (sizebuf_t *buf, int length) { - void *data; - + void *data; + if (buf->cursize + length > buf->maxsize) { if (!buf->allowoverflow) - Host_Error ("SZ_GetSpace: overflow without allowoverflow set - use -zone on the commandline for more zone memory, default: 128k (quake original default was 48k)"); - + Host_Error ("SZ_GetSpace: overflow without allowoverflow set\n"); + if (length > buf->maxsize) - Host_Error ("SZ_GetSpace: %i is > full buffer size", length); - + Host_Error ("SZ_GetSpace: %i is > full buffer size\n", length); + buf->overflowed = true; - Con_Printf ("SZ_GetSpace: overflow"); - SZ_Clear (buf); + Con_Printf ("SZ_GetSpace: overflow\n"); + SZ_Clear (buf); } data = buf->data + buf->cursize; buf->cursize += length; - + return data; } -void SZ_Write (sizebuf_t *buf, void *data, int length) +void SZ_Write (sizebuf_t *buf, const void *data, int length) { - memcpy (SZ_GetSpace(buf,length),data,length); + memcpy (SZ_GetSpace(buf,length),data,length); } -void SZ_Print (sizebuf_t *buf, char *data) +void SZ_Print (sizebuf_t *buf, const char *data) { - int len; - + int len; len = strlen(data)+1; // byte * cast to keep VC++ happy if (buf->data[buf->cursize-1]) - memcpy ((byte *)SZ_GetSpace(buf, len),data,len); // no trailing 0 + memcpy ((qbyte *)SZ_GetSpace(buf, len),data,len); // no trailing 0 else - memcpy ((byte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0 + memcpy ((qbyte *)SZ_GetSpace(buf, len-1)-1,data,len); // write over trailing 0 } - -//============================================================================ - - -/* -============ -COM_SkipPath -============ -*/ -char *COM_SkipPath (char *pathname) +static char *hexchar = "0123456789ABCDEF"; +void SZ_HexDumpToConsole(const sizebuf_t *buf) { - char *last; - - last = pathname; - while (*pathname) + int i; + char text[1024]; + char *cur, *flushpointer; + cur = text; + flushpointer = text + 512; + for (i = 0;i < buf->cursize;i++) { - if (*pathname=='/') - last = pathname+1; - pathname++; + if ((i & 15) == 0) + { + *cur++ = hexchar[(i >> 12) & 15]; + *cur++ = hexchar[(i >> 8) & 15]; + *cur++ = hexchar[(i >> 4) & 15]; + *cur++ = hexchar[(i >> 0) & 15]; + *cur++ = ':'; + *cur++ = ' '; + } + else if ((i & 15) == 15) + *cur++ = '\n'; + else + *cur++ = ' '; + if (i & 1) + { + *cur++ = hexchar[(buf->data[i] >> 4) & 15] | 0x80; + *cur++ = hexchar[(buf->data[i] >> 0) & 15] | 0x80; + } + else + { + *cur++ = hexchar[(buf->data[i] >> 4) & 15]; + *cur++ = hexchar[(buf->data[i] >> 0) & 15]; + } + if (cur >= flushpointer) + { + *cur++ = 0; + Con_Printf("%s", text); + cur = text; + } + } + if ((i & 15) != 0) + *cur++ = '\n'; + if (cur > text) + { + *cur++ = 0; + Con_Printf("%s", text); } - return last; } + +//============================================================================ + + /* ============ COM_StripExtension ============ */ // LordHavoc: replacement for severely broken COM_StripExtension that was used in original quake. -void COM_StripExtension (char *in, char *out) +void COM_StripExtension (const char *in, char *out) { char *last = NULL; while (*in) { if (*in == '.') - last = in; - if ((*in == '/') || (*in == '\\') || (*in == ':')) + last = out; + else if (*in == '/' || *in == '\\' || *in == ':') last = NULL; *out++ = *in++; } if (last) *last = 0; + else + *out = 0; } /* @@ -850,10 +547,10 @@ void COM_StripExtension (char *in, char *out) COM_FileExtension ============ */ -char *COM_FileExtension (char *in) +char *COM_FileExtension (const char *in) { static char exten[8]; - int i; + int i; while (*in && *in != '.') in++; @@ -871,10 +568,9 @@ char *COM_FileExtension (char *in) COM_FileBase ============ */ -void COM_FileBase (char *in, char *out) +void COM_FileBase (const char *in, char *out) { - char *slash, *dot; - char *s; + const char *slash, *dot, *s; slash = in; dot = NULL; @@ -905,9 +601,9 @@ void COM_FileBase (char *in, char *out) COM_DefaultExtension ================== */ -void COM_DefaultExtension (char *path, char *extension) +void COM_DefaultExtension (char *path, const char *extension) { - char *src; + const char *src; // // if path doesn't have a .EXT, append extension // (extension should include the .) @@ -927,31 +623,39 @@ void COM_DefaultExtension (char *path, char *extension) /* ============== -COM_Parse +COM_ParseToken Parse a token out of a string ============== */ -char *COM_Parse (char *data) +int COM_ParseToken (const char **datapointer) { - int c; - int len; - + int c; + int len; + const char *data = *datapointer; + len = 0; com_token[0] = 0; - + if (!data) - return NULL; - + { + *datapointer = NULL; + return false; + } + // skip whitespace skipwhite: - while ( (c = *data) <= ' ') + while ((c = *data) <= ' ') { if (c == 0) - return NULL; // end of file; + { + // end of file + *datapointer = NULL; + return false; + } data++; } - + // skip // comments if (c=='/' && data[1] == '/') { @@ -959,7 +663,7 @@ skipwhite: data++; goto skipwhite; } - + // handle quoted strings specially if (c == '\"') @@ -971,7 +675,8 @@ skipwhite: if (c=='\"' || !c) { com_token[len] = 0; - return data; + *datapointer = data; + return true; } com_token[len] = c; len++; @@ -984,7 +689,8 @@ skipwhite: com_token[len] = c; len++; com_token[len] = 0; - return data+1; + *datapointer = data+1; + return true; } // parse a regular word @@ -994,12 +700,13 @@ skipwhite: data++; len++; c = *data; - if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') + if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':') break; } while (c>32); - + com_token[len] = 0; - return data; + *datapointer = data; + return true; } @@ -1011,10 +718,10 @@ Returns the position (1 to argc-1) in the program's argument list where the given parameter apears, or 0 if not present ================ */ -int COM_CheckParm (char *parm) +int COM_CheckParm (const char *parm) { - int i; - + int i; + for (i=1 ; inext) { @@ -1373,12 +1016,13 @@ LordHavoc: Previously only used for CopyFile, now also used for COM_WriteFile. */ void COM_CreatePath (char *path) { - char *ofs, save; + char *ofs, save; for (ofs = path+1 ; *ofs ; ofs++) { - if (*ofs == '/' || *ofs == '\\' || *ofs == ':') - { // create the directory + if (*ofs == '/' || *ofs == '\\') + { + // create the directory save = *ofs; *ofs = 0; Sys_mkdir (path); @@ -1395,26 +1039,28 @@ COM_WriteFile The filename will be prefixed by the current game directory ============ */ -void COM_WriteFile (char *filename, void *data, int len) +qboolean COM_WriteFile (const char *filename, void *data, int len) { - int handle; - char name[MAX_OSPATH]; + int handle; + char name[MAX_OSPATH]; sprintf (name, "%s/%s", com_gamedir, filename); // LordHavoc: added this - COM_CreatePath (name); // create directories up to the file + // create directories up to the file + COM_CreatePath (name); handle = Sys_FileOpenWrite (name); if (handle == -1) { - Sys_Printf ("COM_WriteFile: failed on %s\n", name); - return; + Con_Printf ("COM_WriteFile: failed on %s\n", name); + return false; } - Con_Printf ("COM_WriteFile: %s\n", name); + Con_DPrintf ("COM_WriteFile: %s\n", name); Sys_FileWrite (handle, data, len); Sys_FileClose (handle); + return true; } @@ -1428,14 +1074,13 @@ needed. This is for the convenience of developers using ISDN from home. */ void COM_CopyFile (char *netpath, char *cachepath) { - int in, out; - int remaining, count; - char buf[4096]; - - remaining = Sys_FileOpenRead (netpath, &in); + int in, out, remaining, count; + char buf[4096]; + + remaining = Sys_FileOpenRead (netpath, &in); COM_CreatePath (cachepath); // create directories up to the cache file out = Sys_FileOpenWrite (cachepath); - + while (remaining) { if (remaining < sizeof(buf)) @@ -1448,7 +1093,7 @@ void COM_CopyFile (char *netpath, char *cachepath) } Sys_FileClose (in); - Sys_FileClose (out); + Sys_FileClose (out); } /* @@ -1458,9 +1103,8 @@ COM_OpenRead */ QFile * COM_OpenRead (const char *path, int offs, int len, qboolean zip) { - int fd = open (path, O_RDONLY); - unsigned char id[2]; - unsigned char len_bytes[4]; + int fd = open (path, O_RDONLY); + unsigned char id[2], len_bytes[4]; if (fd == -1) { @@ -1508,35 +1152,28 @@ Finds the file in the search path. Sets com_filesize and one of handle or file =========== */ -int COM_FindFile (char *filename, QFile **file, qboolean quiet, qboolean zip) +int COM_FindFile (const char *filename, QFile **file, qboolean quiet, qboolean zip) { - searchpath_t *search; - char netpath[MAX_OSPATH]; + searchpath_t *search; + char netpath[MAX_OSPATH]; #if CACHEENABLE - char cachepath[MAX_OSPATH]; - int cachetime; + char cachepath[MAX_OSPATH]; + int cachetime; #endif - pack_t *pak; - int i; - int findtime; - char gzfilename[MAX_OSPATH]; - int filenamelen; + pack_t *pak; + int i, findtime, filenamelen; + char gzfilename[MAX_OSPATH]; filenamelen = strlen (filename); sprintf (gzfilename, "%s.gz", filename); if (!file) Sys_Error ("COM_FindFile: file not set"); - + // // search through the path, one element at a time // search = com_searchpaths; -// if (proghack) -// { // gross hack to use quake 1 progs with quake 2 maps -// if (!strcmp(filename, "progs.dat")) -// search = search->next; -// } for ( ; search ; search = search->next) { @@ -1557,24 +1194,17 @@ int COM_FindFile (char *filename, QFile **file, qboolean quiet, qboolean zip) } } else - { - // check a file in the directory tree -// if (!static_registered) -// { // if not a registered version, don't ever go beyond base -// if ( strchr (filename, '/') || strchr (filename,'\\')) -// continue; -// } - + { sprintf (netpath, "%s/%s",search->filename, filename); - + findtime = Sys_FileTime (netpath); if (findtime == -1) continue; - + #if CACHEENABLE // see if the file needs to be updated in the cache if (com_cachedir[0]) - { + { #if defined(_WIN32) if ((strlen(netpath) < 2) || (netpath[1] != ':')) sprintf (cachepath,"%s%s", com_cachedir, netpath); @@ -1585,24 +1215,22 @@ int COM_FindFile (char *filename, QFile **file, qboolean quiet, qboolean zip) #endif cachetime = Sys_FileTime (cachepath); - + if (cachetime < findtime) COM_CopyFile (netpath, cachepath); strcpy (netpath, cachepath); - } + } #endif - if (!quiet) Sys_Printf ("FindFile: %s\n",netpath); *file = COM_OpenRead (netpath, -1, -1, zip); return com_filesize; } - } - + if (!quiet) Sys_Printf ("FindFile: can't find %s\n", filename); - + *file = NULL; com_filesize = -1; return -1; @@ -1617,7 +1245,7 @@ If the requested file is inside a packfile, a new QFile * will be opened into the file. =========== */ -int COM_FOpenFile (char *filename, QFile **file, qboolean quiet, qboolean zip) +int COM_FOpenFile (const char *filename, QFile **file, qboolean quiet, qboolean zip) { return COM_FindFile (filename, file, quiet, zip); } @@ -1631,15 +1259,14 @@ Filename are reletive to the quake directory. Always appends a 0 byte. ============ */ -cache_user_t *loadcache; -byte *loadbuf; -int loadsize; -byte *COM_LoadFile (char *path, int usehunk, qboolean quiet) +qbyte *loadbuf; +int loadsize; +qbyte *COM_LoadFile (const char *path, qboolean quiet) { - QFile *h; - byte *buf; - char base[1024]; - int len; + QFile *h; + qbyte *buf; + char base[1024]; + int len; buf = NULL; // quiet compiler warning loadsize = 0; @@ -1650,64 +1277,22 @@ byte *COM_LoadFile (char *path, int usehunk, qboolean quiet) return NULL; loadsize = len; - + // extract the filename base name for hunk tag COM_FileBase (path, base); - - switch (usehunk) - { - case 1: - buf = Hunk_AllocName (len+1, va("%s (file)", path)); - if (!buf) - Sys_Error ("COM_LoadFile: not enough hunk space for %s (size %i)", path, len); - break; -// case 0: -// buf = Z_Malloc (len+1); -// if (!buf) -// Sys_Error ("COM_LoadFile: not enough zone space for %s (size %i)", path, len); -// break; -// case 3: -// buf = Cache_Alloc (loadcache, len+1, base); -// if (!buf) -// Sys_Error ("COM_LoadFile: not enough cache space for %s (size %i)", path, len); -// break; - case 5: - buf = qmalloc (len+1); - if (!buf) - Sys_Error ("COM_LoadFile: not enough available memory for %s (size %i)", path, len); - break; - default: - Sys_Error ("COM_LoadFile: bad usehunk"); - break; - } - ((byte *)buf)[len] = 0; + buf = Mem_Alloc(tempmempool, len+1); + if (!buf) + Sys_Error ("COM_LoadFile: not enough available memory for %s (size %i)", path, len); - Qread (h, buf, len); + ((qbyte *)buf)[len] = 0; + + Qread (h, buf, len); Qclose (h); return buf; } -byte *COM_LoadHunkFile (char *path, qboolean quiet) -{ - return COM_LoadFile (path, 1, quiet); -} - -// LordHavoc: returns malloc'd memory -byte *COM_LoadMallocFile (char *path, qboolean quiet) -{ - return COM_LoadFile (path, 5, quiet); -} - -/* -void COM_LoadCacheFile (char *path, struct cache_user_s *cu, qboolean quiet) -{ - loadcache = cu; - COM_LoadFile (path, 3, quiet); -} -*/ - /* ================= COM_LoadPackFile @@ -1718,55 +1303,54 @@ Loads the header and directory, adding the files at the beginning of the list so they override previous pack files. ================= */ -pack_t *COM_LoadPackFile (char *packfile) +pack_t *COM_LoadPackFile (const char *packfile) { - dpackheader_t header; - int i; - packfile_t *newfiles; - int numpackfiles; - pack_t *pack; - int packhandle; - // LordHavoc: changed from stack array to temporary malloc, allowing huge pack directories - dpackfile_t *info; + dpackheader_t header; + int i, numpackfiles, packhandle; + pack_t *pack; + // LordHavoc: changed from stack array to temporary alloc, allowing huge pack directories + dpackfile_t *info; if (Sys_FileOpenRead (packfile, &packhandle) == -1) - { -// Con_Printf ("Couldn't open %s\n", packfile); return NULL; - } + Sys_FileRead (packhandle, (void *)&header, sizeof(header)); - if (header.id[0] != 'P' || header.id[1] != 'A' - || header.id[2] != 'C' || header.id[3] != 'K') + if (memcmp(header.id, "PACK", 4)) Sys_Error ("%s is not a packfile", packfile); header.dirofs = LittleLong (header.dirofs); header.dirlen = LittleLong (header.dirlen); + if (header.dirlen % sizeof(dpackfile_t)) + Sys_Error ("%s has an invalid directory size", packfile); + numpackfiles = header.dirlen / sizeof(dpackfile_t); if (numpackfiles > MAX_FILES_IN_PACK) Sys_Error ("%s has %i files", packfile, numpackfiles); - newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "pack file-table"); + pack = Mem_Alloc(pak_mempool, sizeof (pack_t)); + strcpy (pack->filename, packfile); + pack->handle = packhandle; + pack->numfiles = numpackfiles; + pack->mempool = Mem_AllocPool(packfile); + pack->files = Mem_Alloc(pack->mempool, numpackfiles * sizeof(packfile_t)); + pack->next = packlist; + packlist = pack; - info = qmalloc(sizeof(*info)*MAX_FILES_IN_PACK); + info = Mem_Alloc(tempmempool, sizeof(*info) * numpackfiles); Sys_FileSeek (packhandle, header.dirofs); Sys_FileRead (packhandle, (void *)info, header.dirlen); // parse the directory - for (i=0 ; ifiles[i].name, info[i].name); + pack->files[i].filepos = LittleLong(info[i].filepos); + pack->files[i].filelen = LittleLong(info[i].filelen); } - qfree(info); - pack = Hunk_AllocName (sizeof (pack_t), packfile); - strcpy (pack->filename, packfile); - pack->handle = packhandle; - pack->numfiles = numpackfiles; - pack->files = newfiles; - + Mem_Free(info); + Con_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles); return pack; } @@ -1777,45 +1361,46 @@ pack_t *COM_LoadPackFile (char *packfile) COM_AddGameDirectory Sets com_gamedir, adds the directory to the head of the path, -then loads and adds pak1.pak pak2.pak ... +then loads and adds pak1.pak pak2.pak ... ================ */ void COM_AddGameDirectory (char *dir) { - int i; - searchpath_t *search; - pack_t *pak; - char pakfile[MAX_OSPATH]; + stringlist_t *list, *current; + searchpath_t *search; + pack_t *pak; + char pakfile[MAX_OSPATH]; strcpy (com_gamedir, dir); // // add the directory to the search path // - search = Hunk_AllocName (sizeof(searchpath_t), "pack info"); + search = Mem_Alloc(pak_mempool, sizeof(searchpath_t)); strcpy (search->filename, dir); search->next = com_searchpaths; com_searchpaths = search; -// -// add any pak files in the format pak0.pak pak1.pak, ... -// - for (i=0 ; ; i++) + // add any paks in the directory + list = listdirectory(dir); + for (current = list;current;current = current->next) { - sprintf (pakfile, "%s/pak%i.pak", dir, i); - pak = COM_LoadPackFile (pakfile); - if (!pak) - break; - search = Hunk_AllocName (sizeof(searchpath_t), "pack info"); - search->pack = pak; - search->next = com_searchpaths; - com_searchpaths = search; + if (matchpattern(current->text, "*.pak", true)) + { + sprintf (pakfile, "%s/%s", dir, current->text); + pak = COM_LoadPackFile (pakfile); + if (pak) + { + search = Mem_Alloc(pak_mempool, sizeof(searchpath_t)); + search->pack = pak; + search->next = com_searchpaths; + com_searchpaths = search; + } + else + Con_Printf("unable to load pak \"%s\"\n", pakfile); + } } - -// -// add the contents of the parms.txt file to the end of the command line -// - + freedirectory(list); } /* @@ -1825,90 +1410,43 @@ COM_InitFilesystem */ void COM_InitFilesystem (void) { - int i, j; - char basedir[MAX_OSPATH]; - searchpath_t *search; + int i; + searchpath_t *search; -// -// -basedir -// Overrides the system supplied base directory (under GAMENAME) -// + strcpy(com_basedir, "."); + + // -basedir + // Overrides the system supplied base directory (under GAMENAME) i = COM_CheckParm ("-basedir"); if (i && i < com_argc-1) - strcpy (basedir, com_argv[i+1]); - else - strcpy (basedir, host_parms.basedir); - - j = strlen (basedir); - - if (j > 0) - { - if ((basedir[j-1] == '\\') || (basedir[j-1] == '/')) - basedir[j-1] = 0; - } + strcpy (com_basedir, com_argv[i+1]); -#if CACHEENABLE -// -// -cachedir -// Overrides the system supplied cache directory (NULL or /qcache) -// -cachedir - will disable caching. -// - i = COM_CheckParm ("-cachedir"); - if (i && i < com_argc-1) - { - if (com_argv[i+1][0] == '-') - com_cachedir[0] = 0; - else - strcpy (com_cachedir, com_argv[i+1]); - } - else if (host_parms.cachedir) - strcpy (com_cachedir, host_parms.cachedir); - else - com_cachedir[0] = 0; -#endif + i = strlen (com_basedir); + if (i > 0 && (com_basedir[i-1] == '\\' || com_basedir[i-1] == '/')) + com_basedir[i-1] = 0; // start up with GAMENAME by default (id1) - COM_AddGameDirectory (va("%s/"GAMENAME, basedir) ); - - switch(gamemode) + strcpy(com_modname, GAMENAME); + COM_AddGameDirectory (va("%s/"GAMENAME, com_basedir)); + if (gamedirname[0]) { - case GAME_NORMAL: - break; - case GAME_HIPNOTIC: - COM_AddGameDirectory (va("%s/hipnotic", basedir) ); - break; - case GAME_ROGUE: - COM_AddGameDirectory (va("%s/rogue", basedir) ); - break; - case GAME_NEHAHRA: - COM_AddGameDirectory (va("%s/nehahra", basedir) ); - break; - case GAME_FIENDARENA: - COM_AddGameDirectory (va("%s/fiendarena", basedir) ); - break; - case GAME_ZYMOTIC: - COM_AddGameDirectory (va("%s/zymotic", basedir) ); - break; - default: - Sys_Error("COM_InitFilesystem: unknown gamemode %i\n", gamemode); - break; + com_modified = true; + strcpy(com_modname, gamedirname); + COM_AddGameDirectory (va("%s/%s", com_basedir, gamedirname)); } -// -// -game -// Adds basedir/gamedir as an override game -// + // -game + // Adds basedir/gamedir as an override game i = COM_CheckParm ("-game"); if (i && i < com_argc-1) { com_modified = true; - COM_AddGameDirectory (va("%s/%s", basedir, com_argv[i+1])); + strcpy(com_modname, com_argv[i+1]); + COM_AddGameDirectory (va("%s/%s", com_basedir, com_argv[i+1])); } -// -// -path [] ... -// Fully specifies the exact search path, overriding the generated one -// + // -path [] ... + // Fully specifies the exact search path, overriding the generated one i = COM_CheckParm ("-path"); if (i) { @@ -1919,7 +1457,7 @@ void COM_InitFilesystem (void) if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-') break; - search = Hunk_AllocName (sizeof(searchpath_t), "pack info"); + search = Mem_Alloc(pak_mempool, sizeof(searchpath_t)); if ( !strcmp(COM_FileExtension(com_argv[i]), "pak") ) { search->pack = COM_LoadPackFile (com_argv[i]); @@ -1932,18 +1470,14 @@ void COM_InitFilesystem (void) com_searchpaths = search; } } - -// if (COM_CheckParm ("-proghack")) -// proghack = true; } -int COM_FileExists(char *filename) +int COM_FileExists(const char *filename) { - searchpath_t *search; - char netpath[MAX_OSPATH]; - pack_t *pak; - int i; - int findtime; + searchpath_t *search; + char netpath[MAX_OSPATH]; + pack_t *pak; + int i, findtime; for (search = com_searchpaths;search;search = search->next) { @@ -1960,7 +1494,7 @@ int COM_FileExists(char *filename) findtime = Sys_FileTime (netpath); if (findtime != -1) return true; - } + } } return false; @@ -1970,7 +1504,7 @@ int COM_FileExists(char *filename) //====================================== // LordHavoc: added these because they are useful -void COM_ToLowerString(char *in, char *out) +void COM_ToLowerString(const char *in, char *out) { while (*in) { @@ -1981,7 +1515,7 @@ void COM_ToLowerString(char *in, char *out) } } -void COM_ToUpperString(char *in, char *out) +void COM_ToUpperString(const char *in, char *out) { while (*in) { @@ -1991,3 +1525,11 @@ void COM_ToUpperString(char *in, char *out) *out++ = *in++; } } + +int COM_StringBeginsWith(const char *s, const char *match) +{ + for (;*s && *match;s++, match++) + if (*s != *match) + return false; + return true; +}