*/
// 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
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)
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)
*/
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;
}
}
*/
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");
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]))
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
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)
{
// 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
{
}
}
+/*
+============
+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
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)
{
}
-/*
-============
-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
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
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
// 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;
}
}
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] != ':'))
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;
}
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);
}
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);
{
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;
}
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);
}
+*/
/*
=================
basedir[j-1] = 0;
}
+#if CACHEENABLE
//
// -cachedir <path>
// Overrides the system supplied cache directory (NULL or /qcache)
strcpy (com_cachedir, host_parms.cachedir);
else
com_cachedir[0] = 0;
+#endif
//
// start up with GAMENAME by default (id1)
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++;
+ }
+}