⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 quake1 dos源代码最新版本
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
============
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 + -