]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
***map loader generates portals for the map*** (can you tell this is a big deal? :)
[xonotic/darkplaces.git] / common.c
index 2c9c8cc11c07c6d42eba517bb339d6b651abeaca..717317266bc30d01a24820ecc312126c369539b7 100644 (file)
--- a/common.c
+++ b/common.c
@@ -583,22 +583,33 @@ 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)
 {
        if (dpprotocol)
                MSG_WriteFloat(sb, f);
        else
-               MSG_WriteShort (sb, (int)(f*8));
+               MSG_WriteShort (sb, (int)(f*8.0f + 0.5f));
 }
 
 void MSG_WritePreciseAngle (sizebuf_t *sb, float f)
 {
-       MSG_WriteShort (sb, (int) (f*65536.0f/360) & 65535);
+       MSG_WriteShort (sb, (int)(f*(65536.0f/360.0f) + 0.5f) & 65535);
 }
 
+// LordHavoc: round to nearest value, rather than rounding down, fixes crosshair problem
 void MSG_WriteAngle (sizebuf_t *sb, float f)
 {
-       MSG_WriteByte (sb, ((int)f*256/360) & 255);
+       MSG_WriteByte (sb, (int)(f*(256.0f/360.0f) + 0.5f) & 255);
 }
 
 //
@@ -730,6 +741,16 @@ char *MSG_ReadString (void)
        return string;
 }
 
+// used by server (always dpprotocol)
+// moved to common.h as #define
+/*
+float MSG_ReadFloatCoord (void)
+{
+       return MSG_ReadFloat();
+}
+*/
+
+// used by client
 float MSG_ReadCoord (void)
 {
        if (dpprotocol)
@@ -788,7 +809,7 @@ void *SZ_GetSpace (sizebuf_t *buf, int length)
        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: 512k (quake original default was 48k)");
+                       Host_Error ("SZ_GetSpace: overflow without allowoverflow set - use -zone on the commandline for more zone memory, default: 128k (quake original default was 48k)");
                
                if (length > buf->maxsize)
                        Host_Error ("SZ_GetSpace: %i is > full buffer size", length);
@@ -885,23 +906,29 @@ COM_FileBase
 */
 void COM_FileBase (char *in, char *out)
 {
-       char *s, *s2;
-       
-       s = in + strlen(in) - 1;
-       
-       while (s != in && *s != '.')
-               s--;
-       
-       for (s2 = s ; *s2 && *s2 != '/' ; s2--)
-       ;
-       
-       if (s-s2 < 2)
+       char *slash, *dot;
+       char *s;
+
+       slash = in;
+       dot = NULL;
+       s = in;
+       while(*s)
+       {
+               if (*s == '/')
+                       slash = s + 1;
+               if (*s == '.')
+                       dot = s;
+               s++;
+       }
+       if (dot == NULL)
+               dot = s;
+       if (dot - slash < 2)
                strcpy (out,"?model?");
        else
        {
-               s--;
-               strncpy (out,s2+1, s-s2);
-               out[s-s2] = 0;
+               while (slash < dot)
+                       *out++ = *slash++;
+               *out++ = 0;
        }
 }
 
@@ -1164,6 +1191,42 @@ void COM_InitArgv (int argc, char **argv)
 }
 
 
+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)
+{
+       unsigned int *m;
+       if (!mem)
+               return;
+       m = mem;
+       m--; // back up to size
+       qmalloctotal_free += *m; // size
+       qmalloctotal_freecount++;
+       free(m);
+}
+
+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);
+}
+
+
 /*
 ================
 COM_Init
@@ -1198,6 +1261,7 @@ void COM_Init (char *basedir)
        Cvar_RegisterVariable (&registered);
        Cvar_RegisterVariable (&cmdline);
        Cmd_AddCommand ("path", COM_Path_f);
+       Cmd_AddCommand ("memstats", COM_Memstats_f);
 
        COM_InitFilesystem ();
        COM_CheckRegistered ();
@@ -1285,8 +1349,10 @@ typedef struct
 // 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
 
-char    com_cachedir[MAX_OSPATH];
-char    com_gamedir[MAX_OSPATH];
+#if CACHEENABLE
+char   com_cachedir[MAX_OSPATH];
+#endif
+char   com_gamedir[MAX_OSPATH];
 
 typedef struct searchpath_s
 {
@@ -1319,6 +1385,30 @@ void COM_Path_f (void)
        }
 }
 
+/*
+============
+COM_CreatePath
+
+LordHavoc: Previously only used for CopyFile, now also used for COM_WriteFile.
+============
+*/
+void    COM_CreatePath (char *path)
+{
+       char    *ofs, save;
+       
+       for (ofs = path+1 ; *ofs ; ofs++)
+       {
+               if (*ofs == '/' || *ofs == '\\' || *ofs == ':')
+               {       // create the directory
+                       save = *ofs;
+                       *ofs = 0;
+                       Sys_mkdir (path);
+                       *ofs = save;
+               }
+       }
+}
+
+
 /*
 ============
 COM_WriteFile
@@ -1333,6 +1423,9 @@ void COM_WriteFile (char *filename, void *data, int len)
        
        sprintf (name, "%s/%s", com_gamedir, filename);
 
+       // LordHavoc: added this
+       COM_CreatePath (name); // create directories up to the file
+
        handle = Sys_FileOpenWrite (name);
        if (handle == -1)
        {
@@ -1346,29 +1439,6 @@ void COM_WriteFile (char *filename, void *data, int len)
 }
 
 
-/*
-============
-COM_CreatePath
-
-Only used for CopyFile
-============
-*/
-void    COM_CreatePath (char *path)
-{
-       char    *ofs;
-       
-       for (ofs = path+1 ; *ofs ; ofs++)
-       {
-               if (*ofs == '/')
-               {       // create the directory
-                       *ofs = 0;
-                       Sys_mkdir (path);
-                       *ofs = '/';
-               }
-       }
-}
-
-
 /*
 ===========
 COM_CopyFile
@@ -1412,12 +1482,15 @@ Sets com_filesize and one of handle or file
 */
 int COM_FindFile (char *filename, int *handle, FILE **file, qboolean quiet)
 {
-       searchpath_t    *search;
-       char            netpath[MAX_OSPATH];
-       char            cachepath[MAX_OSPATH];
-       pack_t          *pak;
-       int                     i;
-       int                     findtime, cachetime;
+       searchpath_t    *search;
+       char                    netpath[MAX_OSPATH];
+#if CACHEENABLE
+       char                    cachepath[MAX_OSPATH];
+       int                             cachetime;
+#endif
+       pack_t                  *pak;
+       int                             i;
+       int                             findtime;
 
        if (file && handle)
                Sys_Error ("COM_FindFile: both handle and file set");
@@ -1476,10 +1549,9 @@ int COM_FindFile (char *filename, int *handle, FILE **file, qboolean quiet)
                        if (findtime == -1)
                                continue;
                                
-               // see if the file needs to be updated in the cache
-                       if (!com_cachedir[0])
-                               strcpy (cachepath, netpath);
-                       else
+#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] != ':'))
@@ -1496,6 +1568,7 @@ int COM_FindFile (char *filename, int *handle, FILE **file, qboolean quiet)
                                        COM_CopyFile (netpath, cachepath);
                                strcpy (netpath, cachepath);
                        }       
+#endif
 
                        if (!quiet)
                                Sys_Printf ("FindFile: %s\n",netpath);
@@ -1575,7 +1648,7 @@ void COM_CloseFile (int h)
 COM_LoadFile
 
 Filename are reletive to the quake directory.
-Allways appends a 0 byte.
+Always appends a 0 byte.
 ============
 */
 cache_user_t *loadcache;
@@ -1585,7 +1658,7 @@ byte *COM_LoadFile (char *path, int usehunk, qboolean quiet)
 {
        int             h;
        byte    *buf;
-       char    base[32];
+       char    base[1024];
        int             len;
 
        buf = NULL;     // quiet compiler warning
@@ -1598,29 +1671,33 @@ byte *COM_LoadFile (char *path, int usehunk, qboolean quiet)
 // extract the filename base name for hunk tag
        COM_FileBase (path, base);
        
-       if (usehunk == 1)
-               buf = Hunk_AllocName (len+1, base);
-       else if (usehunk == 2)
-               buf = Hunk_TempAlloc (len+1);
-       else if (usehunk == 0)
-               buf = Z_Malloc (len+1);
-       else if (usehunk == 3)
-               buf = Cache_Alloc (loadcache, len+1, base);
-       else if (usehunk == 4)
+       switch (usehunk)
        {
-               if (len+1 > loadsize)
-                       buf = Hunk_TempAlloc (len+1);
-               else
-                       buf = loadbuf;
-       }
-       else if (usehunk == 5)
-               buf = malloc (len+1);
-       else
+       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;
+       }
 
-       if (!buf)
-               Sys_Error ("COM_LoadFile: not enough space for %s", path);
-               
        ((byte *)buf)[len] = 0;
 
        Sys_FileRead (h, buf, len);                     
@@ -1634,11 +1711,6 @@ byte *COM_LoadHunkFile (char *path, qboolean quiet)
        return COM_LoadFile (path, 1, quiet);
 }
 
-byte *COM_LoadTempFile (char *path, qboolean quiet)
-{
-       return COM_LoadFile (path, 2, quiet);
-}
-
 // LordHavoc: returns malloc'd memory
 byte *COM_LoadMallocFile (char *path, qboolean quiet)
 {
@@ -1651,18 +1723,6 @@ void COM_LoadCacheFile (char *path, struct cache_user_s *cu, qboolean quiet)
        COM_LoadFile (path, 3, quiet);
 }
 
-// uses temp hunk if larger than bufsize
-byte *COM_LoadStackFile (char *path, void *buffer, int bufsize, qboolean quiet)
-{
-       byte    *buf;
-       
-       loadbuf = (byte *)buffer;
-       loadsize = bufsize;
-       buf = COM_LoadFile (path, 4, quiet);
-       
-       return buf;
-}
-
 /*
 =================
 COM_LoadPackFile
@@ -1705,9 +1765,9 @@ pack_t *COM_LoadPackFile (char *packfile)
        if (numpackfiles != PAK0_COUNT)
                com_modified = true;    // not the original file
 
-       newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "packfile");
+       newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "pack file-table");
 
-       info = malloc(sizeof(*info)*MAX_FILES_IN_PACK);
+       info = qmalloc(sizeof(*info)*MAX_FILES_IN_PACK);
        Sys_FileSeek (packhandle, header.dirofs);
        Sys_FileRead (packhandle, (void *)info, header.dirlen);
 
@@ -1727,9 +1787,9 @@ pack_t *COM_LoadPackFile (char *packfile)
                newfiles[i].filepos = LittleLong(info[i].filepos);
                newfiles[i].filelen = LittleLong(info[i].filelen);
        }
-       free(info);
+       qfree(info);
 
-       pack = Hunk_Alloc (sizeof (pack_t));
+       pack = Hunk_AllocName (sizeof (pack_t), packfile);
        strcpy (pack->filename, packfile);
        pack->handle = packhandle;
        pack->numfiles = numpackfiles;
@@ -1760,7 +1820,7 @@ void COM_AddGameDirectory (char *dir)
 //
 // add the directory to the search path
 //
-       search = Hunk_Alloc (sizeof(searchpath_t));
+       search = Hunk_AllocName (sizeof(searchpath_t), "pack info");
        strcpy (search->filename, dir);
        search->next = com_searchpaths;
        com_searchpaths = search;
@@ -1774,10 +1834,10 @@ void COM_AddGameDirectory (char *dir)
                pak = COM_LoadPackFile (pakfile);
                if (!pak)
                        break;
-               search = Hunk_Alloc (sizeof(searchpath_t));
+               search = Hunk_AllocName (sizeof(searchpath_t), "pack info");
                search->pack = pak;
                search->next = com_searchpaths;
-               com_searchpaths = search;               
+               com_searchpaths = search;
        }
 
 //
@@ -1815,6 +1875,7 @@ void COM_InitFilesystem (void)
                        basedir[j-1] = 0;
        }
 
+#if CACHEENABLE
 //
 // -cachedir <path>
 // Overrides the system supplied cache directory (NULL or /qcache)
@@ -1832,6 +1893,7 @@ void COM_InitFilesystem (void)
                strcpy (com_cachedir, host_parms.cachedir);
        else
                com_cachedir[0] = 0;
+#endif
 
 //
 // start up with GAMENAME by default (id1)
@@ -1862,7 +1924,7 @@ void COM_InitFilesystem (void)
 
 //
 // -path <dir or packfile> [<dir or packfile>] ...
-// Fully specifies the exact serach path, overriding the generated one
+// Fully specifies the exact search path, overriding the generated one
 //
        i = COM_CheckParm ("-path");
        if (i)
@@ -1874,7 +1936,7 @@ void COM_InitFilesystem (void)
                        if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-')
                                break;
                        
-                       search = Hunk_Alloc (sizeof(searchpath_t));
+                       search = Hunk_AllocName (sizeof(searchpath_t), "pack info");
                        if ( !strcmp(COM_FileExtension(com_argv[i]), "pak") )
                        {
                                search->pack = COM_LoadPackFile (com_argv[i]);
@@ -1921,3 +1983,28 @@ int COM_FileExists(char *filename)
        return false;
 }
 
+
+//======================================
+// LordHavoc: added these because they are useful
+
+void COM_ToLowerString(char *in, char *out)
+{
+       while (*in)
+       {
+               if (*in >= 'A' && *in <= 'Z')
+                       *out++ = *in++ + 'a' - 'A';
+               else
+                       *out++ = *in++;
+       }
+}
+
+void COM_ToUpperString(char *in, char *out)
+{
+       while (*in)
+       {
+               if (*in >= 'a' && *in <= 'z')
+                       *out++ = *in++ + 'A' - 'a';
+               else
+                       *out++ = *in++;
+       }
+}