-/// just for debugging
-int memsearch (qbyte *start, int count, int search)
-{
- int i;
-
- for (i=0 ; i<count ; i++)
- if (start[i] == search)
- return i;
- return -1;
-}
-
-/*
-=============================================================================
-
-QUAKE FILESYSTEM
-
-=============================================================================
-*/
-
-int com_filesize;
-
-
-//
-// in memory
-//
-
-typedef struct
-{
- char name[MAX_QPATH];
- int filepos, filelen;
-} packfile_t;
-
-typedef struct pack_s
-{
- char filename[MAX_OSPATH];
- int handle;
- int numfiles;
- packfile_t *files;
- mempool_t *mempool;
- struct pack_s *next;
-} pack_t;
-
-//
-// on disk
-//
-typedef struct
-{
- char name[56];
- int filepos, filelen;
-} dpackfile_t;
-
-typedef struct
-{
- char id[4];
- int dirofs;
- int dirlen;
-} dpackheader_t;
-
-// 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];
-#endif
-char com_gamedir[MAX_OSPATH];
-
-typedef struct searchpath_s
-{
- char filename[MAX_OSPATH];
- pack_t *pack; // only one of filename / pack will be used
- struct searchpath_s *next;
-} searchpath_t;
-
-searchpath_t *com_searchpaths;
-
-/*
-============
-COM_Path_f
-
-============
-*/
-void COM_Path_f (void)
-{
- searchpath_t *s;
-
- Con_Printf ("Current search path:\n");
- for (s=com_searchpaths ; s ; s=s->next)
- {
- if (s->pack)
- {
- Con_Printf ("%s (%i files)\n", s->pack->filename, s->pack->numfiles);
- }
- else
- Con_Printf ("%s\n", s->filename);
- }
-}
-
-/*
-============
-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 == '\\')
- {
- // create the directory
- save = *ofs;
- *ofs = 0;
- Sys_mkdir (path);
- *ofs = save;
- }
- }
-}
-
-
-/*
-============
-COM_WriteFile
-
-The filename will be prefixed by the current game directory
-============
-*/
-void COM_WriteFile (char *filename, void *data, int len)
-{
- 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
-
- handle = Sys_FileOpenWrite (name);
- if (handle == -1)
- {
- Sys_Printf ("COM_WriteFile: failed on %s\n", name);
- return;
- }
-
- Con_Printf ("COM_WriteFile: %s\n", name);
- Sys_FileWrite (handle, data, len);
- Sys_FileClose (handle);
-}
-
-
-/*
-===========
-COM_CopyFile
-
-Copies a file over from the net to the local cache, creating any directories
-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);
- COM_CreatePath (cachepath); // create directories up to the cache file
- out = Sys_FileOpenWrite (cachepath);
-
- while (remaining)
- {
- if (remaining < sizeof(buf))
- count = remaining;
- else
- count = sizeof(buf);
- Sys_FileRead (in, buf, count);
- Sys_FileWrite (out, buf, count);
- remaining -= count;
- }
-
- Sys_FileClose (in);
- 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
-
-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)
-{
- 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)
- 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)
- {
- // is the element a pak file?
- if (search->pack)
- {
- // look through all the pak file elements
- pak = search->pack;
- for (i=0 ; i<pak->numfiles ; i++)
- 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, 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;
- }
- }
- 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);
- else
- sprintf (cachepath,"%s%s", com_cachedir, netpath+2);
-#else
- sprintf (cachepath,"%s%s", com_cachedir, netpath);
-#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;
-}
-
-
-/*
-===========
-COM_FOpenFile
-
-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)
-{
- return COM_FindFile (filename, file, quiet, zip);
-}
-
-
-/*
-============
-COM_LoadFile
-
-Filename are reletive to the quake directory.
-Always appends a 0 byte.
-============
-*/
-qbyte *loadbuf;
-int loadsize;
-qbyte *COM_LoadFile (char *path, qboolean quiet)
-{
- QFile *h;
- qbyte *buf;
- char base[1024];
- int len;
-
- buf = NULL; // quiet compiler warning
- loadsize = 0;
-
-// look for it in the filesystem or pack files
- 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);
-
- 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);
- Qclose (h);
-
- return buf;
-}
-
-/*
-=================
-COM_LoadPackFile
-
-Takes an explicit (not game tree related) path to a pak file.
-
-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)
-{
- dpackheader_t header;
- int i;
- int numpackfiles;
- pack_t *pack;
- int packhandle;
- // 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 (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);
-
- 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 = 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++)
- {
- strcpy (pack->files[i].name, info[i].name);
- pack->files[i].filepos = LittleLong(info[i].filepos);
- pack->files[i].filelen = LittleLong(info[i].filelen);
- }
-
- Mem_Free(info);
-
- Con_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles);
- return pack;
-}
-
-
-/*
-================
-COM_AddGameDirectory
-
-Sets com_gamedir, adds the directory to the head of the path,
-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];
-
- strcpy (com_gamedir, dir);
-
-//
-// add the directory to the search path
-//
- 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++)
- {
- sprintf (pakfile, "%s/pak%i.pak", dir, i);
- pak = COM_LoadPackFile (pakfile);
- if (!pak)
- break;
- search = Mem_Alloc(pak_mempool, sizeof(searchpath_t));
- search->pack = pak;
- search->next = com_searchpaths;
- com_searchpaths = search;
- }
-
-//
-// add the contents of the parms.txt file to the end of the command line
-//
-
-}
-
-/*
-================
-COM_InitFilesystem
-================
-*/
-void COM_InitFilesystem (void)
-{
- int i, j;
- char basedir[MAX_OSPATH];
- searchpath_t *search;
-
-//
-// -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);
-
- j = strlen (basedir);
-
- if (j > 0)
- {
- if ((basedir[j-1] == '\\') || (basedir[j-1] == '/'))
- basedir[j-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)
- {
- if (com_argv[i+1][0] == '-')
- com_cachedir[0] = 0;
- else
- strcpy (com_cachedir, com_argv[i+1]);
- }
- else if (host_parms.cachedir)
- strcpy (com_cachedir, host_parms.cachedir);
- else
- com_cachedir[0] = 0;
-#endif
-
-// start up with GAMENAME by default (id1)
- COM_AddGameDirectory (va("%s/"GAMENAME, basedir) );
-
- switch(gamemode)
- {
- case GAME_NORMAL:
- break;
- case GAME_HIPNOTIC:
- COM_AddGameDirectory (va("%s/hipnotic", basedir) );
- break;
- case GAME_ROGUE:
- COM_AddGameDirectory (va("%s/rogue", basedir) );
- break;
- case GAME_NEHAHRA:
- COM_AddGameDirectory (va("%s/nehahra", basedir) );
- break;
- case GAME_FIENDARENA:
- COM_AddGameDirectory (va("%s/fiendarena", basedir) );
- break;
- case GAME_ZYMOTIC:
- COM_AddGameDirectory (va("%s/zymotic", basedir) );
- break;
- default:
- Sys_Error("COM_InitFilesystem: unknown gamemode %i\n", gamemode);
- break;
- }
-
-//
-// -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]));
- }
-
-//
-// -path <dir or packfile> [<dir or packfile>] ...
-// Fully specifies the exact search path, overriding the generated one
-//
- i = COM_CheckParm ("-path");
- if (i)
- {
- com_modified = true;
- com_searchpaths = NULL;
- while (++i < com_argc)
- {
- if (!com_argv[i] || com_argv[i][0] == '+' || com_argv[i][0] == '-')
- break;
-
- search = Mem_Alloc(pak_mempool, sizeof(searchpath_t));
- if ( !strcmp(COM_FileExtension(com_argv[i]), "pak") )
- {
- search->pack = COM_LoadPackFile (com_argv[i]);
- if (!search->pack)
- Sys_Error ("Couldn't load packfile: %s", com_argv[i]);
- }
- else
- strcpy (search->filename, com_argv[i]);
- search->next = com_searchpaths;
- com_searchpaths = search;
- }
- }
-
-// if (COM_CheckParm ("-proghack"))
-// proghack = true;
-}
-
-int COM_FileExists(char *filename)
-{
- searchpath_t *search;
- char netpath[MAX_OSPATH];
- pack_t *pak;
- int i;
- int findtime;
-
- for (search = com_searchpaths;search;search = search->next)
- {
- if (search->pack)
- {
- pak = search->pack;
- for (i = 0;i < pak->numfiles;i++)
- if (!strcmp (pak->files[i].name, filename))
- return true;
- }
- else
- {
- sprintf (netpath, "%s/%s",search->filename, filename);
- findtime = Sys_FileTime (netpath);
- if (findtime != -1)
- return true;
- }
- }
-
- return false;
-}
-
-