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

📄 w_wad.c

📁 使用Doom引擎开发的著名游戏《毁灭巫师》的源代码。
💻 C
字号:
//**************************************************************************//**//** w_wad.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: w_wad.c,v $//** $Revision: 1.6 $//** $Date: 95/10/06 20:56:47 $//** $Author: cjr $//**//**************************************************************************// HEADER FILES ------------------------------------------------------------#ifdef NeXT#include <libc.h>#include <ctype.h>#else#include <malloc.h>#include <io.h>#include <fcntl.h>#include <sys/stat.h>#endif#include "h2def.h"// MACROS ------------------------------------------------------------------#ifdef NeXT// NeXT doesn't need a binary flag in open call#define O_BINARY 0#define strcmpi strcasecmp#endif// TYPES -------------------------------------------------------------------typedef struct{	char identification[4];	int numlumps;	int infotableofs;} wadinfo_t;typedef struct{	int filepos;	int size;	char name[8];} filelump_t;// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------// EXTERNAL DATA DECLARATIONS ----------------------------------------------// PUBLIC DATA DEFINITIONS -------------------------------------------------lumpinfo_t *lumpinfo;int numlumps;void **lumpcache;// PRIVATE DATA DEFINITIONS ------------------------------------------------static lumpinfo_t *PrimaryLumpInfo;static int PrimaryNumLumps;static void **PrimaryLumpCache;static lumpinfo_t *AuxiliaryLumpInfo;static int AuxiliaryNumLumps;static void **AuxiliaryLumpCache;static int AuxiliaryHandle = 0;boolean AuxiliaryOpened = false;// CODE --------------------------------------------------------------------#ifdef NeXT//==========================================================================//// strupr////==========================================================================void strupr(char *s){    while(*s)	*s++ = toupper(*s);}//==========================================================================//// filelength////==========================================================================int filelength(int handle){    struct stat fileinfo;    if(fstat(handle, &fileinfo) == -1)	{		I_Error("Error fstating");	}    return fileinfo.st_size;}#endif//==========================================================================//// W_AddFile//// Files with a .wad extension are wadlink files with multiple lumps,// other files are single lumps with the base filename for the lump name.////==========================================================================void W_AddFile(char *filename){	wadinfo_t header;	lumpinfo_t *lump_p;	unsigned i;	int handle, length;	int startlump;	filelump_t *fileinfo, singleinfo;	filelump_t *freeFileInfo;	if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)	{ // Didn't find file		return;	}	startlump = numlumps;	if(strcmpi(filename+strlen(filename)-3, "wad"))	{ // Single lump file		fileinfo = &singleinfo;		freeFileInfo = NULL;		singleinfo.filepos = 0;		singleinfo.size = LONG(filelength(handle));		M_ExtractFileBase(filename, singleinfo.name);		numlumps++;	}	else	{ // WAD file		read(handle, &header, sizeof(header));		if(strncmp(header.identification, "IWAD", 4))		{			if(strncmp(header.identification, "PWAD", 4))			{ // Bad file id				I_Error("Wad file %s doesn't have IWAD or PWAD id\n",					filename);			}		}		header.numlumps = LONG(header.numlumps);		header.infotableofs = LONG(header.infotableofs);		length = header.numlumps*sizeof(filelump_t);//		fileinfo = alloca(length);		if(!(fileinfo = malloc(length)))		{			I_Error("W_AddFile:  fileinfo malloc failed\n");		}		freeFileInfo = fileinfo;		lseek(handle, header.infotableofs, SEEK_SET);		read(handle, fileinfo, length);		numlumps += header.numlumps;	}	// Fill in lumpinfo	lumpinfo = realloc(lumpinfo, numlumps*sizeof(lumpinfo_t));	if(!lumpinfo)	{		I_Error("Couldn't realloc lumpinfo");	}	lump_p = &lumpinfo[startlump];	for(i = startlump; i < numlumps; i++, lump_p++, fileinfo++)	{		lump_p->handle = handle;		lump_p->position = LONG(fileinfo->filepos);		lump_p->size = LONG(fileinfo->size);		strncpy(lump_p->name, fileinfo->name, 8);	}	if(freeFileInfo)	{		free(freeFileInfo);	}}//==========================================================================//// W_InitMultipleFiles//// Pass a null terminated list of files to use.  All files are optional,// but at least one file must be found.  Lump names can appear multiple// times.  The name searcher looks backwards, so a later file can// override an earlier one.////==========================================================================void W_InitMultipleFiles(char **filenames){	int size;	// Open all the files, load headers, and count lumps	numlumps = 0;	lumpinfo = malloc(1); // Will be realloced as lumps are added	for(; *filenames; filenames++)	{		W_AddFile(*filenames);	}	if(!numlumps)	{		I_Error("W_InitMultipleFiles: no files found");	}	// Set up caching	size = numlumps*sizeof(*lumpcache);	lumpcache = malloc(size);	if(!lumpcache)	{		I_Error("Couldn't allocate lumpcache");	}	memset(lumpcache, 0, size);	PrimaryLumpInfo = lumpinfo;	PrimaryLumpCache = lumpcache;	PrimaryNumLumps = numlumps;}//==========================================================================//// W_InitFile//// Initialize the primary from a single file.////==========================================================================void W_InitFile(char *filename){	char *names[2];	names[0] = filename;	names[1] = NULL;	W_InitMultipleFiles(names);}//==========================================================================//// W_OpenAuxiliary////==========================================================================void W_OpenAuxiliary(char *filename){	int i;	int size;	wadinfo_t header;	int handle;	int length;	filelump_t *fileinfo;	filelump_t *sourceLump;	lumpinfo_t *destLump;	if(AuxiliaryOpened)	{		W_CloseAuxiliary();	}	if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)	{		I_Error("W_OpenAuxiliary: %s not found.", filename);		return;	}	AuxiliaryHandle = handle;	read(handle, &header, sizeof(header));	if(strncmp(header.identification, "IWAD", 4))	{		if(strncmp(header.identification, "PWAD", 4))		{ // Bad file id			I_Error("Wad file %s doesn't have IWAD or PWAD id\n",				filename);		}	}	header.numlumps = LONG(header.numlumps);	header.infotableofs = LONG(header.infotableofs);	length = header.numlumps*sizeof(filelump_t);	fileinfo = Z_Malloc(length, PU_STATIC, 0);	lseek(handle, header.infotableofs, SEEK_SET);	read(handle, fileinfo, length);	numlumps = header.numlumps;	// Init the auxiliary lumpinfo array	lumpinfo = Z_Malloc(numlumps*sizeof(lumpinfo_t), PU_STATIC, 0);	sourceLump = fileinfo;	destLump = lumpinfo;	for(i = 0; i < numlumps; i++, destLump++, sourceLump++)	{		destLump->handle = handle;		destLump->position = LONG(sourceLump->filepos);		destLump->size = LONG(sourceLump->size);		strncpy(destLump->name, sourceLump->name, 8);	}	Z_Free(fileinfo);	// Allocate the auxiliary lumpcache array	size = numlumps*sizeof(*lumpcache);	lumpcache = Z_Malloc(size, PU_STATIC, 0);	memset(lumpcache, 0, size);	AuxiliaryLumpInfo = lumpinfo;	AuxiliaryLumpCache = lumpcache;	AuxiliaryNumLumps = numlumps;	AuxiliaryOpened = true;}//==========================================================================//// W_CloseAuxiliary////==========================================================================void W_CloseAuxiliary(void){	int i;	if(AuxiliaryOpened)	{		W_UseAuxiliary();		for(i = 0; i < numlumps; i++)		{			if(lumpcache[i])			{				Z_Free(lumpcache[i]);			}		}		Z_Free(AuxiliaryLumpInfo);		Z_Free(AuxiliaryLumpCache);		W_CloseAuxiliaryFile();		AuxiliaryOpened = false;	}	W_UsePrimary();}//==========================================================================//// W_CloseAuxiliaryFile//// WARNING: W_CloseAuxiliary() must be called before any further// auxiliary lump processing.////==========================================================================void W_CloseAuxiliaryFile(void){	if(AuxiliaryHandle)	{		close(AuxiliaryHandle);		AuxiliaryHandle = 0;	}}//==========================================================================//// W_UsePrimary////==========================================================================void W_UsePrimary(void){	lumpinfo = PrimaryLumpInfo;	numlumps = PrimaryNumLumps;	lumpcache = PrimaryLumpCache;}//==========================================================================//// W_UseAuxiliary////==========================================================================void W_UseAuxiliary(void){	if(AuxiliaryOpened == false)	{		I_Error("W_UseAuxiliary: WAD not opened.");	}	lumpinfo = AuxiliaryLumpInfo;	numlumps = AuxiliaryNumLumps;	lumpcache = AuxiliaryLumpCache;}//==========================================================================//// W_NumLumps////==========================================================================int	W_NumLumps(void){	return numlumps;}//==========================================================================//// W_CheckNumForName//// Returns -1 if name not found.////==========================================================================int W_CheckNumForName(char *name){	char name8[9];	int v1, v2;	lumpinfo_t *lump_p;	// Make the name into two integers for easy compares	strncpy(name8, name, 8);	name8[8] = 0; // in case the name was a full 8 chars	strupr(name8); // case insensitive	v1 = *(int *)name8;	v2 = *(int *)&name8[4];	// Scan backwards so patch lump files take precedence	lump_p = lumpinfo+numlumps;	while(lump_p-- != lumpinfo)	{		if(*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)		{			return lump_p-lumpinfo;		}	}	return -1;}//==========================================================================//// W_GetNumForName//// Calls W_CheckNumForName, but bombs out if not found.////==========================================================================int	W_GetNumForName (char *name){	int	i;	i = W_CheckNumForName(name);	if(i != -1)	{		return i;	}	I_Error("W_GetNumForName: %s not found!", name);	return -1;}//==========================================================================//// W_LumpLength//// Returns the buffer size needed to load the given lump.////==========================================================================int W_LumpLength(int lump){	if(lump >= numlumps)	{		I_Error("W_LumpLength: %i >= numlumps", lump);	}	return lumpinfo[lump].size;}//==========================================================================//// W_ReadLump//// Loads the lump into the given buffer, which must be >= W_LumpLength().////==========================================================================void W_ReadLump(int lump, void *dest){	int c;	lumpinfo_t *l;	if(lump >= numlumps)	{		I_Error("W_ReadLump: %i >= numlumps", lump);	}	l = lumpinfo+lump;	//I_BeginRead();	lseek(l->handle, l->position, SEEK_SET);	c = read(l->handle, dest, l->size);	if(c < l->size)	{		I_Error("W_ReadLump: only read %i of %i on lump %i",			c, l->size, lump);	}	//I_EndRead();}//==========================================================================//// W_CacheLumpNum////==========================================================================void *W_CacheLumpNum(int lump, int tag){	byte *ptr;	if((unsigned)lump >= numlumps)	{		I_Error("W_CacheLumpNum: %i >= numlumps", lump);	}	if(!lumpcache[lump])	{ // Need to read the lump in		ptr = Z_Malloc(W_LumpLength(lump), tag, &lumpcache[lump]);		W_ReadLump(lump, lumpcache[lump]);	}	else	{		Z_ChangeTag(lumpcache[lump], tag);	}	return lumpcache[lump];}//==========================================================================//// W_CacheLumpName////==========================================================================void *W_CacheLumpName(char *name, int tag){	return W_CacheLumpNum(W_GetNumForName(name), tag);}//==========================================================================//// W_Profile////==========================================================================// Ripped out for Heretic/*int	info[2500][10];int	profilecount;void W_Profile (void){	int		i;	memblock_t	*block;	void	*ptr;	char	ch;	FILE	*f;	int		j;	char	name[9];			for (i=0 ; i<numlumps ; i++)	{			ptr = lumpcache[i];		if (!ptr)		{			ch = ' ';			continue;		}		else		{			block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));			if (block->tag < PU_PURGELEVEL)				ch = 'S';			else				ch = 'P';		}		info[i][profilecount] = ch;	}	profilecount++;		f = fopen ("waddump.txt","w");	name[8] = 0;	for (i=0 ; i<numlumps ; i++)	{		memcpy (name,lumpinfo[i].name,8);		for (j=0 ; j<8 ; j++)			if (!name[j])				break;		for ( ; j<8 ; j++)			name[j] = ' ';		fprintf (f,"%s ",name);		for (j=0 ; j<profilecount ; j++)			fprintf (f,"    %c",info[i][j]);		fprintf (f,"\n");	}	fclose (f);}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -