]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - common.c
added loadsize variable set by COM_LoadFile
[xonotic/darkplaces.git] / common.c
index a3baf1955ff57267f42001e484eb5fde28ea5841..56d7f5ee031376fc8aa8ac195d2aeaa703f88d82 100644 (file)
--- a/common.c
+++ b/common.c
@@ -19,6 +19,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 // common.c -- misc functions used in client and server
 
+#include <fcntl.h>
+#ifdef WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+
 #include "quakedef.h"
 
 #define NUM_SAFE_ARGVS  7
@@ -583,6 +591,16 @@ 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)
@@ -731,6 +749,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)
@@ -886,25 +914,29 @@ COM_FileBase
 */
 void COM_FileBase (char *in, char *out)
 {
-       char *s, *s2;
-       
-       s = in + strlen(in) - 1;
-       
-       while (s != in && *s != '.')
-               s--;
-       
-       // LordHavoc: EWW bug bug bug bug bug... added previously missing s2 != in (yes, could go hunting through mem for /)
-       for (s2 = s ; s2 != in && *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
        {
-               // LordHavoc: FIXME: examine this
-               s--;
-               strncpy (out,s2+1, s-s2);
-               out[s-s2] = 0;
+               while (slash < dot)
+                       *out++ = *slash++;
+               *out++ = 0;
        }
 }
 
@@ -1047,16 +1079,16 @@ being registered.
 */
 void COM_CheckRegistered (void)
 {
-       int             h;
+       QFile           *h;
        unsigned short  check[128];
        int                     i;
 
        Cvar_Set ("cmdline", com_cmdline);
 
-       COM_OpenFile("gfx/pop.lmp", &h, false);
+       COM_FOpenFile("gfx/pop.lmp", &h, false, true);
        static_registered = 0;
 
-       if (h == -1)
+       if (!h)
        {
                if (com_modified)
                        Con_Printf ("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
@@ -1071,8 +1103,8 @@ void COM_CheckRegistered (void)
                return;
        }
 
-       Sys_FileRead (h, check, sizeof(check));
-       COM_CloseFile (h);
+       Qread (h, check, sizeof(check));
+       Qclose (h);
        
        for (i=0 ; i<128 ; i++)
                if (pop[i] != (unsigned short)BigShort (check[i]))
@@ -1175,6 +1207,8 @@ void *qmalloc(unsigned int size)
        qmalloctotal_alloc += size;
        qmalloctotal_alloccount++;
        mem = malloc(size+sizeof(unsigned int));
+       if (!mem)
+               return mem;
        *mem = size;
        return (void *)(mem + 1);
 }
@@ -1182,6 +1216,8 @@ void *qmalloc(unsigned int size)
 void qfree(void *mem)
 {
        unsigned int *m;
+       if (!mem)
+               return;
        m = mem;
        m--; // back up to size
        qmalloctotal_free += *m; // size
@@ -1189,7 +1225,7 @@ void qfree(void *mem)
        free(m);
 }
 
-void GL_TextureStats_PrintTotal(void);
+extern void GL_TextureStats_PrintTotal(void);
 extern int hunk_low_used, hunk_high_used, hunk_size;
 void COM_Memstats_f(void)
 {
@@ -1321,8 +1357,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
 {
@@ -1355,6 +1393,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
@@ -1369,6 +1431,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)
        {
@@ -1382,29 +1447,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
@@ -1438,6 +1480,55 @@ void COM_CopyFile (char *netpath, char *cachepath)
        Sys_FileClose (out);    
 }
 
+/*
+===========
+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];
+
+       if (fd == -1)
+       {
+               Sys_Error ("Couldn't open %s", path);
+               return 0;
+       }
+       if (offs < 0 || len < 0)
+       {
+               // normal file
+               offs = 0;
+               len = lseek (fd, 0, SEEK_END);
+               lseek (fd, 0, SEEK_SET);
+       }
+       lseek (fd, offs, SEEK_SET);
+       if (zip)
+       {
+               read (fd, id, 2);
+               if (id[0] == 0x1f && id[1] == 0x8b)
+               {
+                       lseek (fd, offs + len - 4, SEEK_SET);
+                       read (fd, len_bytes, 4);
+                       len = ((len_bytes[3] << 24)
+                                  | (len_bytes[2] << 16)
+                                  | (len_bytes[1] << 8)
+                                  | (len_bytes[0]));
+               }
+       }
+       lseek (fd, offs, SEEK_SET);
+       com_filesize = len;
+
+#ifdef WIN32
+       setmode (fd, O_BINARY);
+#endif
+       if (zip)
+               return Qdopen (fd, "rbz");
+       else
+               return Qdopen (fd, "rb");
+}
+
 /*
 ===========
 COM_FindFile
@@ -1446,19 +1537,25 @@ Finds the file in the search path.
 Sets com_filesize and one of handle or file
 ===========
 */
-int COM_FindFile (char *filename, int *handle, FILE **file, qboolean quiet)
+int COM_FindFile (char *filename, QFile **file, qboolean quiet, qboolean zip)
 {
-       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;
+       char                    gzfilename[MAX_OSPATH];
+       int                             filenamelen;
+
+       filenamelen = strlen (filename);
+       sprintf (gzfilename, "%s.gz", filename);
 
-       if (file && handle)
-               Sys_Error ("COM_FindFile: both handle and file set");
-       if (!file && !handle)
-               Sys_Error ("COM_FindFile: neither handle or file set");
+       if (!file)
+               Sys_Error ("COM_FindFile: file not set");
                
 //
 // search through the path, one element at a time
@@ -1478,22 +1575,13 @@ int COM_FindFile (char *filename, int *handle, FILE **file, qboolean quiet)
                // look through all the pak file elements
                        pak = search->pack;
                        for (i=0 ; i<pak->numfiles ; i++)
-                               if (!strcmp (pak->files[i].name, filename))
+                               if (!strcmp (pak->files[i].name, filename)
+                                   || !strcmp (pak->files[i].name, gzfilename))
                                {       // found it!
                                        if (!quiet)
-                                               Sys_Printf ("PackFile: %s : %s\n",pak->filename, filename);
-                                       if (handle)
-                                       {
-                                               *handle = pak->handle;
-                                               Sys_FileSeek (pak->handle, pak->files[i].filepos);
-                                       }
-                                       else
-                                       {       // open a new file on the pakfile
-                                               *file = fopen (pak->filename, "rb");
-                                               if (*file)
-                                                       fseek (*file, pak->files[i].filepos, SEEK_SET);
-                                       }
-                                       com_filesize = pak->files[i].filelen;
+                                               Sys_Printf ("PackFile: %s : %s\n",pak->filename, pak->files[i].name);
+                                       // open a new file on the pakfile
+                                       *file = COM_OpenRead (pak->filename, pak->files[i].filepos, pak->files[i].filelen, zip);
                                        return com_filesize;
                                }
                }
@@ -1512,10 +1600,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] != ':'))
@@ -1532,17 +1619,11 @@ 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);
-                       com_filesize = Sys_FileOpenRead (netpath, &i);
-                       if (handle)
-                               *handle = i;
-                       else
-                       {
-                               Sys_FileClose (i);
-                               *file = fopen (netpath, "rb");
-                       }
+                       *file = COM_OpenRead (netpath, -1, -1, zip);
                        return com_filesize;
                }
                
@@ -1551,58 +1632,23 @@ int COM_FindFile (char *filename, int *handle, FILE **file, qboolean quiet)
        if (!quiet)
                Sys_Printf ("FindFile: can't find %s\n", filename);
        
-       if (handle)
-               *handle = -1;
-       else
-               *file = NULL;
+       *file = NULL;
        com_filesize = -1;
        return -1;
 }
 
 
-/*
-===========
-COM_OpenFile
-
-filename never has a leading slash, but may contain directory walks
-returns a handle and a length
-it may actually be inside a pak file
-===========
-*/
-int COM_OpenFile (char *filename, int *handle, qboolean quiet)
-{
-       return COM_FindFile (filename, handle, NULL, quiet);
-}
-
 /*
 ===========
 COM_FOpenFile
 
-If the requested file is inside a packfile, a new FILE * will be opened
+If the requested file is inside a packfile, a new QFile * will be opened
 into the file.
 ===========
 */
-int COM_FOpenFile (char *filename, FILE **file, qboolean quiet)
+int COM_FOpenFile (char *filename, QFile **file, qboolean quiet, qboolean zip)
 {
-       return COM_FindFile (filename, NULL, file, quiet);
-}
-
-/*
-============
-COM_CloseFile
-
-If it is a pak file handle, don't really close it
-============
-*/
-void COM_CloseFile (int h)
-{
-       searchpath_t    *s;
-       
-       for (s = com_searchpaths ; s ; s=s->next)
-               if (s->pack && s->pack->handle == h)
-                       return;
-                       
-       Sys_FileClose (h);
+       return COM_FindFile (filename, file, quiet, zip);
 }
 
 
@@ -1611,25 +1657,28 @@ 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;
-byte    *loadbuf;
-int             loadsize;
+cache_user_t   *loadcache;
+byte                   *loadbuf;
+int                            loadsize;
 byte *COM_LoadFile (char *path, int usehunk, qboolean quiet)
 {
-       int             h;
+       QFile             *h;
        byte    *buf;
-       char    base[32];
+       char    base[1024];
        int             len;
 
        buf = NULL;     // quiet compiler warning
+       loadsize = 0;
 
 // look for it in the filesystem or pack files
-       len = COM_OpenFile (path, &h, quiet);
-       if (h == -1)
+       len = COM_FOpenFile (path, &h, quiet, true);
+       if (!h)
                return NULL;
+
+       loadsize = len;
        
 // extract the filename base name for hunk tag
        COM_FileBase (path, base);
@@ -1638,28 +1687,33 @@ byte *COM_LoadFile (char *path, int usehunk, qboolean quiet)
        {
        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 3:
-               buf = Cache_Alloc (loadcache, len+1, base);
-               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;
-//     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);                     
-       COM_CloseFile (h);
+       Qread (h, buf, len);                     
+       Qclose (h);
 
        return buf;
 }
@@ -1675,11 +1729,13 @@ 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);
 }
+*/
 
 /*
 =================
@@ -1833,6 +1889,7 @@ void COM_InitFilesystem (void)
                        basedir[j-1] = 0;
        }
 
+#if CACHEENABLE
 //
 // -cachedir <path>
 // Overrides the system supplied cache directory (NULL or /qcache)
@@ -1850,6 +1907,7 @@ void COM_InitFilesystem (void)
                strcpy (com_cachedir, host_parms.cachedir);
        else
                com_cachedir[0] = 0;
+#endif
 
 //
 // start up with GAMENAME by default (id1)
@@ -1938,3 +1996,29 @@ 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++;
+       }
+}