📄 common.c
字号:
/*
============
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);
handle = Sys_FileOpenWrite (name);
if (handle == -1)
{
Sys_Printf ("COM_WriteFile: failed on %s\n", name);
return;
}
Sys_Printf ("COM_WriteFile: %s\n", name);
Sys_FileWrite (handle, data, len);
Sys_FileClose (handle);
}
/*
============
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
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_FindFile
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, searchpath_t **foundpath) // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
{
searchpath_t *search;
char netpath[MAX_OSPATH];
char cachepath[MAX_OSPATH];
pack_t *pak;
int i;
int findtime, cachetime;
if (file && handle)
Sys_Error ("COM_FindFile: both handle and file set");
if (!file && !handle)
Sys_Error ("COM_FindFile: neither handle or file 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))
{ // found it!
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);
}
// 2001-09-12 Returning from which searchpath a file was loaded by Maddes start
if ( foundpath )
{
*foundpath = search;
}
// 2001-09-12 Returning from which searchpath a file was loaded by Maddes end
com_filesize = pak->files[i].filelen;
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;
// see if the file needs to be updated in the cache
if (!com_cachedir[0])
strcpy (cachepath, netpath);
else
{
#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);
}
Sys_Printf ("FindFile: %s\n",netpath);
com_filesize = Sys_FileOpenRead (netpath, &i);
if (handle)
*handle = i;
else
{
Sys_FileClose (i);
*file = fopen (netpath, "rb");
}
// 2001-09-12 Returning from which searchpath a file was loaded by Maddes start
if ( foundpath )
{
*foundpath = search;
}
// 2001-09-12 Returning from which searchpath a file was loaded by Maddes end
return com_filesize;
}
}
Sys_Printf ("FindFile: can't find %s\n", filename);
if (handle)
*handle = -1;
else
*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, searchpath_t **foundpath) // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
{
return COM_FindFile (filename, handle, NULL, foundpath); // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
}
/*
===========
COM_FOpenFile
If the requested file is inside a packfile, a new FILE * will be opened
into the file.
===========
*/
int COM_FOpenFile (char *filename, FILE **file, searchpath_t **foundpath) // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
{
return COM_FindFile (filename, NULL, file, foundpath); // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
}
/*
============
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);
}
/*
============
COM_LoadFile
Filename are reletive to the quake directory.
always appends a 0 byte.
============
*/
cache_user_t *loadcache;
byte *loadbuf;
int loadsize;
// 2001-09-12 Returning information about loaded file by Maddes start
//byte *COM_LoadFile (char *path, int usehunk)
loadedfile_t *COM_LoadFile (char *path, int usehunk)
// 2001-09-12 Returning information about loaded file by Maddes end
{
int h;
byte *buf;
char base[32];
int len;
// 2001-09-12 Returning information about loaded file by Maddes start
int bufsize;
loadedfile_t *fileinfo;
searchpath_t *foundpath; // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
// 2001-09-12 Returning information about loaded file by Maddes end
buf = NULL; // quiet compiler warning
// look for it in the filesystem or pack files
len = COM_OpenFile (path, &h, &foundpath); // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
if (h == -1)
return NULL;
bufsize = ((len+1+3)&~3) + sizeof(struct loadedfile_s); // 2001-09-12 Returning information about loaded file by Maddes
// extract the filename base name for hunk tag
// 2001-12-28 Use full filename for hunk allocation by Maddes start
// COM_FileBase (path, base);
strncpy(base, COM_SkipPath(path), sizeof(base));
base[sizeof(base)-1] = 0;
// 2001-12-28 Use full filename for hunk allocation by Maddes end
if (usehunk == 1)
// 2001-09-12 Returning information about loaded file by Maddes start
// buf = Hunk_AllocName (len+1, base);
buf = Hunk_AllocName (bufsize, base);
// 2001-09-12 Returning information about loaded file by Maddes end
else if (usehunk == 2)
// 2001-09-12 Returning information about loaded file by Maddes start
// buf = Hunk_TempAlloc (len+1);
buf = Hunk_TempAlloc (bufsize);
// 2001-09-12 Returning information about loaded file by Maddes end
else if (usehunk == 0)
// 2001-09-12 Returning information about loaded file by Maddes start
// buf = Z_Malloc (mainzone, len+1); // 2001-09-20 Enhanced zone handling by Maddes
buf = Z_Malloc (mainzone, bufsize); // 2001-09-20 Enhanced zone handling by Maddes
// 2001-09-12 Returning information about loaded file by Maddes end
else if (usehunk == 3)
// 2001-09-12 Returning information about loaded file by Maddes start
// buf = Cache_Alloc (loadcache, len+1, base);
buf = Cache_Alloc (loadcache, bufsize, base);
// 2001-09-12 Returning information about loaded file by Maddes end
else if (usehunk == 4)
{
// 2001-09-12 Returning information about loaded file by Maddes start
/*
if (len+1 > loadsize)
buf = Hunk_TempAlloc (len+1);
*/
if (bufsize > loadsize)
buf = Hunk_TempAlloc (bufsize);
// 2001-09-12 Returning information about loaded file by Maddes end
else
buf = loadbuf;
}
else
Sys_Error ("COM_LoadFile: bad usehunk");
if (!buf)
Sys_Error ("COM_LoadFile: not enough space for %s", path);
((byte *)buf)[len] = 0;
// 2001-09-12 Returning information about loaded file by Maddes start
fileinfo = (loadedfile_t *)(buf + ((len+1+3)&~3));
fileinfo->data = buf;
fileinfo->filelen = len;
fileinfo->path = foundpath; // 2001-09-12 Returning from which searchpath a file was loaded by Maddes
// 2001-09-12 Returning information about loaded file by Maddes end
Draw_BeginDisc ();
Sys_FileRead (h, buf, len);
COM_CloseFile (h);
Draw_EndDisc ();
// 2001-09-12 Returning information about loaded file by Maddes start
// return buf;
return fileinfo;
// 2001-09-12 Returning information about loaded file by Maddes end
}
// 2001-09-12 Returning information about loaded file by Maddes start
//byte *COM_LoadHunkFile (char *path)
loadedfile_t *COM_LoadHunkFile (char *path)
// 2001-09-12 Returning information about loaded file by Maddes end
{
return COM_LoadFile (path, 1);
}
// 2001-09-12 Returning information about loaded file by Maddes start
//byte *COM_LoadTempFile (char *path)
loadedfile_t *COM_LoadTempFile (char *path)
// 2001-09-12 Returning information about loaded file by Maddes end
{
return COM_LoadFile (path, 2);
}
// 2001-09-12 Returning information about loaded file by Maddes start
//void COM_LoadCacheFile (char *path, struct cache_user_s *cu)
loadedfile_t *COM_LoadCacheFile (char *path, struct cache_user_s *cu)
// 2001-09-12 Returning information about loaded file by Maddes end
{
loadcache = cu;
return COM_LoadFile (path, 3); // 2001-09-12 Returning information about loaded file by Maddes
}
// uses temp hunk if larger than bufsize
// 2001-09-12 Returning information about loaded file by Maddes start
//byte *COM_LoadStackFile (char *path, void *buffer, int bufsize)
loadedfile_t *COM_LoadStackFile (char *path, void *buffer, int bufsize)
// 2001-09-12 Returning information about loaded file by Maddes end
{
// byte *buf; // 2001-09-12 Returning information about loaded file by Maddes
loadbuf = (byte *)buffer;
loadsize = bufsize;
// 2001-09-12 Returning information about loaded file by Maddes start
/*
buf = COM_LoadFile (path, 4);
return buf;
*/
return COM_LoadFile (path, 4);
// 2001-09-12 Returning information about loaded file by Maddes end
}
/*
=================
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;
packfile_t *newfiles;
int numpackfiles;
pack_t *pack;
int packhandle;
dpackfile_t info[MAX_FILES_IN_PACK];
unsigned short crc;
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')
Sys_Error ("%s is not a packfile", packfile);
header.dirofs = LittleLong (header.dirofs);
header.dirlen = LittleLong (header.dirlen);
numpackfiles = header.dirlen / sizeof(dpackfile_t);
if (numpackfiles > MAX_FILES_IN_PACK)
Sys_Error ("%s has %i files", packfile, numpackfiles);
if (numpackfiles != PAK0_COUNT)
com_modified = true; // not the original file
newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "packfile");
Sys_FileSeek (packhandle, header.dirofs);
Sys_FileRead (packhandle, (void *)info, header.dirlen);
// crc the directory to check for modifications
CRC_Init (&crc);
for (i=0 ; i<header.dirlen ; i++)
CRC_ProcessByte (&crc, ((byte *)info)[i]);
if (crc != PAK0_CRC)
com_modified = true;
// parse the directory
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);
}
pack = Hunk_Alloc (sizeof (pack_t));
strcpy (pack->filename, packfile);
pack->handle = packhandle;
pack->numfiles = numpackfiles;
pack->files = newfiles;
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 = Hunk_Alloc (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 = Hunk_Alloc (sizeof(searchpath_t));
strcpy (search->filename, dir); // 2001-09-12 Finding the last searchpath of a directory by Maddes
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;
}
//
// -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;
//
// start up with GAMENAME by default (id1)
//
COM_AddGameDirectory (va("%s/"GAMENAME, basedir) );
if (COM_CheckParm ("-rogue"))
COM_AddGameDirectory (va("%s/rogue", basedir) );
if (COM_CheckParm ("-hipnotic"))
COM_AddGameDirectory (va("%s/hipnotic", basedir) );
// 1999-12-23 Multiple "-data" parameters by Maddes start
//
// -data <datadir>
// Adds datadirs similar to "-game"
//
i = 1;
// 2000-07-30 DJGPP compiler warning fix by Norberto Alfredo Bensa start
// while(i = COM_CheckParmOffset ("-data", i))
while((i = COM_CheckParmOffset ("-data", i)))
// 2000-07-30 DJGPP compiler warning fix by Norberto Alfredo Bensa end
{
if (i && i < com_argc-1)
{
com_modified = true;
COM_AddGameDirectory (va("%s/%s", basedir, com_argv[i+1]));
}
i++;
}
// 1999-12-23 Multiple "-data" parameters by Maddes end
//
// -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 = Hunk_Alloc (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;
}
// 2001-09-12 Finding the last searchpath of a directory start
/*
============
COM_GetDirSearchPath
Find the last searchpath entry of the same directory of the given searchpath
============
*/
searchpath_t *COM_GetDirSearchPath(searchpath_t *startsearch)
{
searchpath_t *search, *lastsearch;
lastsearch = startsearch;
while ( (search = lastsearch->next) )
{
if (strcmp(search->filename, startsearch->filename)) // different directories, then stop here
{
break;
}
lastsearch = search;
}
return lastsearch;
}
// 2001-09-12 Finding the last searchpath of a directory end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -