]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
detect bogus texture upload attempts and print the info to console
[xonotic/darkplaces.git] / common.c
index 4258945e5145fd9fe095b4cda379dd6354dc9b2a..c6a16ee05e8df11eb81ca0a5741917b6c2481153 100644 (file)
--- a/common.c
+++ b/common.c
@@ -29,36 +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];
 
-qboolean               standard_quake = true, rogue = false, hipnotic = false, nehahra = false;
+int gamemode;
+char *gamename;
+char *gamedirname;
+char com_modname[MAX_OSPATH];
 
 /*
 
@@ -92,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<count ; i++)
-                       ((int *)dest)[i] = fill;
-       }
-       else
-               for (i=0 ; i<count ; i++)
-                       ((byte *)dest)[i] = fill;
-}
-
-void Q_memcpy (void *dest, void *src, int count)
-{
-       int             i;
-       
-       if (( ( (long)dest | (long)src | count) & 3) == 0 )
-       {
-               count>>=2;
-               for (i=0 ; i<count ; i++)
-                       ((int *)dest)[i] = ((int *)src)[i];
-       }
-       else
-               for (i=0 ; i<count ; i++)
-                       ((byte *)dest)[i] = ((byte *)src)[i];
-}
-
-int Q_memcmp (void *m1, void *m2, int count)
-{
-       while(count)
-       {
-               count--;
-               if (((byte *)m1)[count] != ((byte *)m2)[count])
-                       return -1;
-       }
-       return 0;
-}
-
-void Q_strcpy (char *dest, char *src)
-{
-       while (*src)
-       {
-               *dest++ = *src++;
-       }
-       *dest++ = 0;
-}
-
-void Q_strncpy (char *dest, char *src, int count)
-{
-       while (*src && count--)
-       {
-               *dest++ = *src++;
-       }
-       if (count)
-               *dest++ = 0;
-}
-
-int Q_strlen (char *str)
-{
-       int             count;
-       
-       count = 0;
-       while (str[count])
-               count++;
-
-       return count;
-}
-
-char *Q_strrchr(char *s, char c)
-{
-    int len = Q_strlen(s);
-    s += len;
-    while (len--)
-       if (*--s == c) return s;
-    return 0;
-}
-
-void Q_strcat (char *dest, char *src)
-{
-       dest += Q_strlen(dest);
-       Q_strcpy (dest, src);
-}
-
-int Q_strcmp (char *s1, char *s2)
-{
-       while (1)
-       {
-               if (*s1 != *s2)
-                       return -1;              // strings not equal    
-               if (!*s1)
-                       return 0;               // strings are equal
-               s1++;
-               s2++;
-       }
-       
-       return -1;
-}
-
-int Q_strncmp (char *s1, char *s2, int count)
-{
-       while (1)
-       {
-               if (!count--)
-                       return 0;
-               if (*s1 != *s2)
-                       return -1;              // strings not equal    
-               if (!*s1)
-                       return 0;               // strings are equal
-               s1++;
-               s2++;
-       }
-       
-       return -1;
-}
-*/
-int Q_strncasecmp (char *s1, char *s2, int n)
+int Q_strncasecmp (const char *s1, const char *s2, int n)
 {
        int             c1, c2;
 
@@ -223,7 +95,7 @@ int Q_strncasecmp (char *s1, char *s2, int n)
 
                if (!n--)
                        return 0;               // strings are equal until end point
-               
+
                if (c1 != c2)
                {
                        if (c1 >= 'a' && c1 <= 'z')
@@ -235,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;
-}
-*/
 
 /*
 ============================================================================
@@ -401,7 +136,7 @@ float   (*LittleFloat) (float l);
 
 short   ShortSwap (short l)
 {
-       byte    b1,b2;
+       qbyte    b1,b2;
 
        b1 = l&255;
        b2 = (l>>8)&255;
@@ -409,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;
@@ -426,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];
@@ -448,10 +187,12 @@ float FloatSwap (float f)
        return dat2.f;
 }
 
+#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG)
 float FloatNoSwap (float f)
 {
        return f;
 }
+#endif
 
 /*
 ==============================================================================
@@ -468,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;
@@ -508,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;
@@ -524,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);
@@ -540,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)
-{
-       MSG_WriteFloat(sb, f);
-}
-*/
-
-// used by client
-void MSG_WriteCoord (sizebuf_t *sb, float f)
+// used by server (always latest dpprotocol)
+void MSG_WriteDPCoord (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)
 {
@@ -581,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;
@@ -652,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;
 }
 
@@ -662,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
        {
@@ -691,56 +375,39 @@ char *MSG_ReadString (void)
                        break;
                string[l] = c;
                l++;
-       } while (l < sizeof(string)-1);
-       
+       } while (l < (int)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;
 }
@@ -748,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;
 }
 
@@ -761,87 +428,123 @@ 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 Com_HexDumpToConsole(const qbyte *data, int size)
 {
-       char    *last;
-       
-       last = pathname;
-       while (*pathname)
+       int i;
+       char text[1024];
+       char *cur, *flushpointer;
+       cur = text;
+       flushpointer = text + 512;
+       for (i = 0;i < size;i++)
+       {
+               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[(data[i] >> 4) & 15] | 0x80;
+                       *cur++ = hexchar[(data[i] >> 0) & 15] | 0x80;
+               }
+               else
+               {
+                       *cur++ = hexchar[(data[i] >> 4) & 15];
+                       *cur++ = hexchar[(data[i] >> 0) & 15];
+               }
+               if (cur >= flushpointer)
+               {
+                       *cur++ = 0;
+                       Con_Printf("%s", text);
+                       cur = text;
+               }
+       }
+       if ((i & 15) != 0)
+               *cur++ = '\n';
+       if (cur > text)
        {
-               if (*pathname=='/')
-                       last = pathname+1;
-               pathname++;
+               *cur++ = 0;
+               Con_Printf("%s", text);
        }
-       return last;
 }
 
+void SZ_HexDumpToConsole(const sizebuf_t *buf)
+{
+       Com_HexDumpToConsole(buf->data, buf->cursize);
+}
+
+
+//============================================================================
+
+
 /*
 ============
 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;
 }
 
 /*
@@ -849,10 +552,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++;
@@ -870,10 +573,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;
@@ -904,9 +606,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 .)
@@ -926,31 +628,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] == '/')
        {
@@ -958,7 +668,7 @@ skipwhite:
                        data++;
                goto skipwhite;
        }
-       
+
 
 // handle quoted strings specially
        if (c == '\"')
@@ -970,7 +680,8 @@ skipwhite:
                        if (c=='\"' || !c)
                        {
                                com_token[len] = 0;
-                               return data;
+                               *datapointer = data;
+                               return true;
                        }
                        com_token[len] = c;
                        len++;
@@ -983,7 +694,8 @@ skipwhite:
                com_token[len] = c;
                len++;
                com_token[len] = 0;
-               return data+1;
+               *datapointer = data+1;
+               return true;
        }
 
 // parse a regular word
@@ -993,12 +705,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;
 }
 
 
@@ -1010,10 +723,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 ; i<com_argc ; i++)
        {
                if (!com_argv[i])
@@ -1021,7 +734,7 @@ int COM_CheckParm (char *parm)
                if (!strcmp (parm,com_argv[i]))
                        return i;
        }
-               
+
        return 0;
 }
 
@@ -1039,26 +752,16 @@ void COM_CheckRegistered (void)
 {
        Cvar_Set ("cmdline", com_cmdline);
 
-//     static_registered = 0;
-
        if (!Sys_FileTime("gfx/pop.lmp"))
        {
                if (com_modified)
                        Con_Printf ("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
                else
                        Con_Printf ("Playing shareware version.\n");
-//#if WINDED
-//     Sys_Error ("This dedicated server requires a full registered copy of Quake");
-//#endif
-//             Con_Printf ("Playing shareware version.\n");
-//             if (com_modified)
-//                     Sys_Error ("You must have the registered version to use modified games");
                return;
        }
-       
-//     Cvar_Set ("cmdline", com_cmdline);
+
        Cvar_Set ("registered", "1");
-//     static_registered = 1;
        Con_Printf ("Playing registered version.\n");
 }
 
@@ -1071,113 +774,86 @@ void COM_Path_f (void);
 COM_InitArgv
 ================
 */
-void COM_InitArgv (int argc, char **argv)
+void COM_InitArgv (void)
 {
-       qboolean        safe;
-       int             i, j, n;
-
-// reconstitute the command line for the cmdline externally visible cvar
+       int i, j, n;
+       // reconstitute the command line for the cmdline externally visible cvar
        n = 0;
-
-       for (j=0 ; (j<MAX_NUM_ARGVS) && (j< argc) ; j++)
+       for (j = 0;(j < MAX_NUM_ARGVS) && (j < com_argc);j++)
        {
                i = 0;
-
-               while ((n < (CMDLINE_LENGTH - 1)) && argv[j][i])
-               {
-                       com_cmdline[n++] = argv[j][i++];
-               }
-
+               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;
-
-       safe = false;
-
-       for (com_argc=0 ; (com_argc<MAX_NUM_ARGVS) && (com_argc < argc) ;
-                com_argc++)
-       {
-               largv[com_argc] = argv[com_argc];
-               if (!strcmp ("-safe", argv[com_argc]))
-                       safe = true;
-       }
-
-       if (safe)
-       {
-       // force all the safe-mode switches. Note that we reserved extra space in
-       // case we need to add these, so we don't need an overflow check
-               for (i=0 ; i<NUM_SAFE_ARGVS ; i++)
-               {
-                       largv[com_argc] = safeargvs[i];
-                       com_argc++;
-               }
-       }
-
-       largv[com_argc] = argvdummy;
-       com_argv = largv;
-
-#ifdef NEHAHRA
-       nehahra = true;
-       standard_quake = false;
-#else
-       if (COM_CheckParm ("-rogue"))
-       {
-               rogue = true;
-               standard_quake = false;
-       }
-
-       if (COM_CheckParm ("-hipnotic"))
-       {
-               hipnotic = true;
-               standard_quake = false;
-       }
-
-       if (COM_CheckParm ("-nehahra"))
-       {
-               nehahra = true;
-               standard_quake = false;
-       }
-#endif
-}
-
-
-unsigned int qmalloctotal_alloc, qmalloctotal_alloccount, qmalloctotal_free, qmalloctotal_freecount;
-
-void *qmalloc(unsigned int size)
-{
-       unsigned int *mem;
-       qmalloctotal_alloc += size;
-       qmalloctotal_alloccount++;
-       mem = malloc(size+sizeof(unsigned int));
-       if (!mem)
-               return mem;
-       *mem = size;
-       return (void *)(mem + 1);
 }
 
-void qfree(void *mem)
+void COM_InitGameType (void)
 {
-       unsigned int *m;
-       if (!mem)
-               return;
-       m = mem;
-       m--; // back up to size
-       qmalloctotal_free += *m; // size
-       qmalloctotal_freecount++;
-       free(m);
-}
+       char name[MAX_OSPATH];
+       COM_StripExtension(com_argv[0], name);
+       COM_ToLowerString(name, name);
 
-extern void GL_TextureStats_PrintTotal(void);
-extern int hunk_low_used, hunk_high_used, hunk_size;
-void COM_Memstats_f(void)
-{
-       Con_Printf("%i malloc calls totalling %i bytes (%.4gMB)\n%i free calls totalling %i bytes (%.4gMB)\n%i bytes (%.4gMB) currently allocated\n", qmalloctotal_alloccount, qmalloctotal_alloc, qmalloctotal_alloc / 1048576.0, qmalloctotal_freecount, qmalloctotal_free, qmalloctotal_free / 1048576.0, qmalloctotal_alloc - qmalloctotal_free, (qmalloctotal_alloc - qmalloctotal_free) / 1048576.0);
-       GL_TextureStats_PrintTotal();
-       Con_Printf ("%i bytes (%.4gMB) of %.4gMB hunk in use\n", hunk_low_used + hunk_high_used, (hunk_low_used + hunk_high_used) / 1048576.0, hunk_size / 1048576.0);
+       if (strstr(name, "transfusion"))
+               gamemode = GAME_TRANSFUSION;
+       else if (strstr(name, "nexiuz"))
+               gamemode = GAME_NEXIUZ;
+       else if (strstr(name, "nehahra"))
+               gamemode = GAME_NEHAHRA;
+       else if (strstr(name, "hipnotic"))
+               gamemode = GAME_HIPNOTIC;
+       else if (strstr(name, "rogue"))
+               gamemode = GAME_ROGUE;
+       else
+               gamemode = GAME_NORMAL;
+
+       if (COM_CheckParm ("-transfusion"))
+               gamemode = GAME_TRANSFUSION;
+       else if (COM_CheckParm ("-nexiuz"))
+               gamemode = GAME_NEXIUZ;
+       else if (COM_CheckParm ("-nehahra"))
+               gamemode = GAME_NEHAHRA;
+       else if (COM_CheckParm ("-hipnotic"))
+               gamemode = GAME_HIPNOTIC;
+       else if (COM_CheckParm ("-rogue"))
+               gamemode = GAME_ROGUE;
+       else if (COM_CheckParm ("-quake"))
+               gamemode = GAME_NORMAL;
+
+       switch(gamemode)
+       {
+       case GAME_NORMAL:
+               gamename = "DarkPlaces-Quake";
+               gamedirname = "";
+               break;
+       case GAME_HIPNOTIC:
+               gamename = "Darkplaces-Hipnotic";
+               gamedirname = "hipnotic";
+               break;
+       case GAME_ROGUE:
+               gamename = "Darkplaces-Rogue";
+               gamedirname = "rogue";
+               break;
+       case GAME_NEHAHRA:
+               gamename = "DarkPlaces-Nehahra";
+               gamedirname = "nehahra";
+               break;
+       case GAME_NEXIUZ:
+               gamename = "Nexiuz";
+               gamedirname = "data";
+               break;
+       case GAME_TRANSFUSION:
+               gamename = "Transfusion";
+               gamedirname = "transfusion";
+               break;
+       default:
+               Sys_Error("COM_InitGameType: unknown gamemode %i\n", gamemode);
+               break;
+       }
 }
 
 
@@ -1188,12 +864,12 @@ extern void Mathlib_Init(void);
 COM_Init
 ================
 */
-void COM_Init (char *basedir)
+void COM_Init (void)
 {
 #if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG)
-       byte    swaptest[2] = {1,0};
+       qbyte swaptest[2] = {1,0};
 
-// set the byte swapping variables in a portable manner 
+// set the byte swapping variables in a portable manner
        if ( *(short *)swaptest == 1)
        {
                BigShort = ShortSwap;
@@ -1214,15 +890,18 @@ void COM_Init (char *basedir)
        }
 #endif
 
+       pak_mempool = Mem_AllocPool("paks");
+
        Cvar_RegisterVariable (&registered);
        Cvar_RegisterVariable (&cmdline);
        Cmd_AddCommand ("path", COM_Path_f);
-       Cmd_AddCommand ("memstats", COM_Memstats_f);
 
        Mathlib_Init();
 
        COM_InitFilesystem ();
        COM_CheckRegistered ();
+
+       COM_InitGameType();
 }
 
 
@@ -1235,30 +914,23 @@ varargs versions of all text functions.
 FIXME: make this buffer size safe someday
 ============
 */
-char    *va(char *format, ...)
+char *va(const char *format, ...)
 {
-       va_list         argptr;
-       static char             string[1024];
-       
+       va_list argptr;
+       // LordHavoc: now cycles through 8 buffers to avoid problems in most cases
+       static char string[8][1024], *s;
+       static int stringindex = 0;
+
+       s = string[stringindex];
+       stringindex = (stringindex + 1) & 7;
        va_start (argptr, format);
-       vsprintf (string, format,argptr);
+       vsprintf (s, format,argptr);
        va_end (argptr);
 
-       return string;  
+       return s;
 }
 
 
-/// just for debugging
-int     memsearch (byte *start, int count, int search)
-{
-       int             i;
-       
-       for (i=0 ; i<count ; i++)
-               if (start[i] == search)
-                       return i;
-       return -1;
-}
-
 /*
 =============================================================================
 
@@ -1267,7 +939,7 @@ QUAKE FILESYSTEM
 =============================================================================
 */
 
-int     com_filesize;
+int com_filesize;
 
 
 //
@@ -1276,16 +948,18 @@ int     com_filesize;
 
 typedef struct
 {
-       char    name[MAX_QPATH];
-       int             filepos, filelen;
+       char name[MAX_QPATH];
+       int filepos, filelen;
 } packfile_t;
 
 typedef struct pack_s
 {
-       char    filename[MAX_OSPATH];
-       int             handle;
-       int             numfiles;
-       packfile_t      *files;
+       char filename[MAX_OSPATH];
+       int handle;
+       int numfiles;
+       packfile_t *files;
+       mempool_t *mempool;
+       struct pack_s *next;
 } pack_t;
 
 //
@@ -1293,33 +967,36 @@ typedef struct pack_s
 //
 typedef struct
 {
-       char    name[56];
-       int             filepos, filelen;
+       char name[56];
+       int filepos, filelen;
 } dpackfile_t;
 
 typedef struct
 {
-       char    id[4];
-       int             dirofs;
-       int             dirlen;
+       char id[4];
+       int dirofs;
+       int dirlen;
 } dpackheader_t;
 
-// LordHavoc: was 2048, increased to 16384 and changed info[MAX_PACK_FILES] to a temporary malloc to avoid stack overflows
-#define MAX_FILES_IN_PACK       16384
+// LordHavoc: was 2048, increased to 65536 and changed info[MAX_PACK_FILES] to a temporary alloc
+#define MAX_FILES_IN_PACK       65536
+
+pack_t *packlist = NULL;
 
 #if CACHEENABLE
-char   com_cachedir[MAX_OSPATH];
+char com_cachedir[MAX_OSPATH];
 #endif
-char   com_gamedir[MAX_OSPATH];
+char com_gamedir[MAX_OSPATH];
 
 typedef struct searchpath_s
 {
-       char    filename[MAX_OSPATH];
-       pack_t  *pack;          // only one of filename / pack will be used
+       // only one of filename / pack will be used
+       char filename[MAX_OSPATH];
+       pack_t *pack;
        struct searchpath_s *next;
 } searchpath_t;
 
-searchpath_t    *com_searchpaths;
+searchpath_t *com_searchpaths;
 
 /*
 ============
@@ -1329,8 +1006,8 @@ COM_Path_f
 */
 void COM_Path_f (void)
 {
-       searchpath_t    *s;
-       
+       searchpath_t *s;
+
        Con_Printf ("Current search path:\n");
        for (s=com_searchpaths ; s ; s=s->next)
        {
@@ -1352,12 +1029,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);
@@ -1374,26 +1052,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;
        }
-       
-       Sys_Printf ("COM_WriteFile: %s\n", name);
+
+       Con_DPrintf ("COM_WriteFile: %s\n", name);
        Sys_FileWrite (handle, data, len);
        Sys_FileClose (handle);
+       return true;
 }
 
 
@@ -1407,17 +1087,16 @@ 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))
+               if (remaining < (int)sizeof(buf))
                        count = remaining;
                else
                        count = sizeof(buf);
@@ -1427,7 +1106,7 @@ void COM_CopyFile (char *netpath, char *cachepath)
        }
 
        Sys_FileClose (in);
-       Sys_FileClose (out);    
+       Sys_FileClose (out);
 }
 
 /*
@@ -1437,9 +1116,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)
        {
@@ -1487,35 +1165,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)
        {
@@ -1536,24 +1207,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);
@@ -1564,24 +1228,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;
@@ -1596,7 +1258,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);
 }
@@ -1610,15 +1272,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;
@@ -1629,64 +1290,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);
+
+       ((qbyte *)buf)[len] = 0;
 
-       Qread (h, buf, len);                     
+       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
@@ -1697,55 +1316,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 ; i<numpackfiles ; i++)
+       for (i = 0;i < numpackfiles;i++)
        {
-               strcpy (newfiles[i].name, info[i].name);
-               newfiles[i].filepos = LittleLong(info[i].filepos);
-               newfiles[i].filelen = LittleLong(info[i].filelen);
+               strcpy (pack->files[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;
 }
@@ -1756,45 +1374,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);
 }
 
 /*
@@ -1804,79 +1423,43 @@ COM_InitFilesystem
 */
 void COM_InitFilesystem (void)
 {
-       int             i, j;
-       char    basedir[MAX_OSPATH];
-       searchpath_t    *search;
+       int i;
+       searchpath_t *search;
 
-//
-// -basedir <path>
-// Overrides the system supplied base directory (under GAMENAME)
-//
+       strcpy(com_basedir, ".");
+
+       // -basedir <path>
+       // 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);
+               strcpy (com_basedir, com_argv[i+1]);
 
-       j = strlen (basedir);
-
-       if (j > 0)
-       {
-               if ((basedir[j-1] == '\\') || (basedir[j-1] == '/'))
-                       basedir[j-1] = 0;
-       }
+       i = strlen (com_basedir);
+       if (i > 0 && (com_basedir[i-1] == '\\' || com_basedir[i-1] == '/'))
+               com_basedir[i-1] = 0;
 
-#if CACHEENABLE
-//
-// -cachedir <path>
-// Overrides the system supplied cache directory (NULL or /qcache)
-// -cachedir - will disable caching.
-//
-       i = COM_CheckParm ("-cachedir");
-       if (i && i < com_argc-1)
+// start up with GAMENAME by default (id1)
+       strcpy(com_modname, GAMENAME);
+       COM_AddGameDirectory (va("%s/"GAMENAME, com_basedir));
+       if (gamedirname[0])
        {
-               if (com_argv[i+1][0] == '-')
-                       com_cachedir[0] = 0;
-               else
-                       strcpy (com_cachedir, com_argv[i+1]);
+               com_modified = true;
+               strcpy(com_modname, gamedirname);
+               COM_AddGameDirectory (va("%s/%s", com_basedir, gamedirname));
        }
-       else if (host_parms.cachedir)
-               strcpy (com_cachedir, host_parms.cachedir);
-       else
-               com_cachedir[0] = 0;
-#endif
 
-//
-// start up with GAMENAME by default (id1)
-//
-       COM_AddGameDirectory (va("%s/"GAMENAME, basedir) );
-
-#ifdef NEHAHRA
-       COM_AddGameDirectory (va("%s/nehahra", basedir) );
-#else
-       if (COM_CheckParm ("-rogue"))
-               COM_AddGameDirectory (va("%s/rogue", basedir) );
-       if (COM_CheckParm ("-hipnotic"))
-               COM_AddGameDirectory (va("%s/hipnotic", basedir) );
-       if (COM_CheckParm ("-nehahra"))
-               COM_AddGameDirectory (va("%s/nehahra", basedir) );
-#endif
-
-//
-// -game <gamedir>
-// Adds basedir/gamedir as an override game
-//
+       // -game <gamedir>
+       // 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 <dir or packfile> [<dir or packfile>] ...
-// Fully specifies the exact search path, overriding the generated one
-//
+       // -path <dir or packfile> [<dir or packfile>] ...
+       // Fully specifies the exact search path, overriding the generated one
        i = COM_CheckParm ("-path");
        if (i)
        {
@@ -1886,8 +1469,8 @@ 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]);
@@ -1900,18 +1483,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)
        {
@@ -1924,11 +1503,11 @@ int COM_FileExists(char *filename)
                }
                else
                {
-                       sprintf (netpath, "%s/%s",search->filename, filename);               
+                       sprintf (netpath, "%s/%s",search->filename, filename);
                        findtime = Sys_FileTime (netpath);
                        if (findtime != -1)
                                return true;
-               }               
+               }
        }
 
        return false;
@@ -1938,7 +1517,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)
        {
@@ -1949,7 +1528,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)
        {
@@ -1959,3 +1538,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;
+}