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

📄 map.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 3 页
字号:
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean WriteOriginBrush(FILE *fp, vec3_t origin)
{
	vec3_t normal;
	float dist;
	int i, s;
	winding_t *w;

	if (fprintf(fp, " {\n") < 0) return false;
	//
	for (i = 0; i < 3; i++)
	{
		for (s = -1; s <= 1; s += 2)
		{
			//
			VectorClear(normal);
			normal[i] = s;
			dist = origin[i] * s + 16;
			//
			w = BaseWindingForPlane(normal, dist);
			//three non-colinear points to define the plane
			if (fprintf(fp,"  ( %5i %5i %5i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]) < 0) return false;
			if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]) < 0) return false;
			if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]) < 0) return false;
			//free the winding
			FreeWinding(w);
			//write origin texture:
			// CONTENTS_ORIGIN = 16777216
			// SURF_NODRAW = 128
			if (loadedmaptype == MAPTYPE_SIN)
			{
				if (fprintf(fp, "generic/misc/origin 0 0 0 1 1") < 0) return false;
			} //end if
			else if (loadedmaptype == MAPTYPE_HALFLIFE)
			{
				if (fprintf(fp, "origin 0 0 0 1 1") < 0) return false;
			} //end if
			else
			{
				if (fprintf(fp, "e1u1/origin 0 0 0 1 1") < 0) return false;
			} //end else
			//Quake2 extra brush side info
			if (loadedmaptype == MAPTYPE_QUAKE2)
			{
				//if (fprintf(fp, " 16777216 128 0") < 0) return false;
			} //end if
			if (fprintf(fp, "\n") < 0) return false;
		} //end for
	} //end for
	if (fprintf(fp, " }\n") < 0) return false;
	c_writtenbrushes++;
	return true;
} //end of the function WriteOriginBrush
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
mapbrush_t *GetAreaPortalBrush(entity_t *mapent)
{
	int portalnum, bn;
	mapbrush_t *brush;

	//the area portal number
	portalnum = mapent->areaportalnum;
	//find the area portal brush in the world brushes
	for (bn = 0; bn < nummapbrushes && portalnum; bn++)
	{
		brush = &mapbrushes[bn];
		//must be in world entity
		if (brush->entitynum == 0)
		{
			if (brush->contents & CONTENTS_AREAPORTAL)
			{
				portalnum--;
			} //end if
		} //end if
	} //end for
	if (bn < nummapbrushes)
	{
		return brush;
	} //end if
	else
	{
		Log_Print("area portal %d brush not found\n", mapent->areaportalnum);
		return NULL;
	} //end else
} //end of the function GetAreaPortalBrush
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean WriteMapFileSafe(FILE *fp)
{
	char key[1024], value[1024];
	int i, bn, entitybrushes;
	epair_t *ep;
	mapbrush_t *brush;
	entity_t *mapent;
	//vec3_t vec_origin = {0, 0, 0};

	//
	if (fprintf(fp,"//=====================================================\n"
			"//\n"
			"// map file created with BSPC "BSPC_VERSION"\n"
			"//\n"
			"// BSPC is designed to decompile material in which you own the copyright\n"
			"// or have obtained permission to decompile from the copyright owner. Unless\n"
			"// you own the copyright or have permission to decompile from the copyright\n"
			"// owner, you may be violating copyright law and be subject to payment of\n"
			"// damages and other remedies. If you are uncertain about your rights, contact\n"
			"// your legal advisor.\n"
			"//\n") < 0) return false;
	if (loadedmaptype == MAPTYPE_SIN)
	{
		if (fprintf(fp,
						"// generic/misc/red is used for unknown textures\n") < 0) return false;
	} //end if
	if (fprintf(fp,"//\n"
						"//=====================================================\n") < 0) return false;
	//write out all the entities
	for (i = 0; i < num_entities; i++)
	{
		mapent = &entities[i];
		if (!mapent->epairs)
		{
			continue;
		} //end if
		if (fprintf(fp, "{\n") < 0) return false;
		//
		if (loadedmaptype == MAPTYPE_QUAKE3)
		{
			if (!stricmp(ValueForKey(mapent, "classname"), "light"))
			{
				SetKeyValue(mapent, "light", "10000");
			} //end if
		} //end if
		//write epairs
		for (ep = mapent->epairs; ep; ep = ep->next)
		{
			strcpy(key, ep->key);
			StripTrailing (key);
			strcpy(value, ep->value);
			StripTrailing(value);
			//
			if (loadedmaptype == MAPTYPE_QUAKE2 ||
					loadedmaptype == MAPTYPE_SIN)
			{
				//don't write an origin for BSP models
				if (mapent->modelnum >= 0 && !strcmp(key, "origin")) continue;
			} //end if
			//don't write BSP model numbers
			if (mapent->modelnum >= 0 && !strcmp(key, "model") && value[0] == '*') continue;
			//
			if (fprintf(fp, " \"%s\" \"%s\"\n", key, value) < 0) return false;
		} //end for
		//
		if (ValueForKey(mapent, "origin")) GetVectorForKey(mapent, "origin", mapent->origin);
		else mapent->origin[0] = mapent->origin[1] = mapent->origin[2] = 0;
		//if this is an area portal entity
		if (!strcmp("func_areaportal", ValueForKey(mapent, "classname")))
		{
			brush = GetAreaPortalBrush(mapent);
			if (!brush) return false;
			if (!WriteMapBrush(fp, brush, mapent->origin)) return false;
		} //end if
		else
		{
			entitybrushes = false;
			//write brushes
			for (bn = 0; bn < nummapbrushes; bn++)
			{
				brush = &mapbrushes[bn];
				//if the brush is part of this entity
				if (brush->entitynum == i)
				{
					//don't write out area portal brushes in the world
					if (!((brush->contents & CONTENTS_AREAPORTAL) && brush->entitynum == 0))
					{
						/*
						if (!strcmp("func_door_rotating", ValueForKey(mapent, "classname")))
						{
							AAS_PositionFuncRotatingBrush(mapent, brush);
							if (!WriteMapBrush(fp, brush, vec_origin)) return false;
						} //end if
						else //*/
						{
							if (!WriteMapBrush(fp, brush, mapent->origin)) return false;
						} //end else
						entitybrushes = true;
					} //end if
				} //end if
			} //end for
			//if the entity had brushes
			if (entitybrushes)
			{
				//if the entity has an origin set
				if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
				{
					if (!WriteOriginBrush(fp, mapent->origin)) return false;
				} //end if
			} //end if
		} //end else
		if (fprintf(fp, "}\n") < 0) return false;
	} //end for
	if (fprintf(fp, "//total of %d brushes\n", c_writtenbrushes) < 0) return false;
	return true;
} //end of the function WriteMapFileSafe
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void WriteMapFile(char *filename)
{
	FILE *fp;
	double start_time;

	c_writtenbrushes = 0;
	//the time started
	start_time = I_FloatTime();
	//
	Log_Print("writing %s\n", filename);
	fp = fopen(filename, "wb");
	if (!fp)
	{
		Log_Print("can't open %s\n", filename);
		return;
	} //end if
	if (!WriteMapFileSafe(fp))
	{
		fclose(fp);
		Log_Print("error writing map file %s\n", filename);
		return;
	} //end if
	fclose(fp);
	//display creation time
	Log_Print("written %d brushes\n", c_writtenbrushes);
	Log_Print("map file written in %5.0f seconds\n", I_FloatTime() - start_time);
} //end of the function WriteMapFile
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void PrintMapInfo(void)
{
	Log_Print("\n");
	Log_Print("%6i brushes\n", nummapbrushes);
	Log_Print("%6i brush sides\n", nummapbrushsides);
//	Log_Print("%6i clipbrushes\n", c_clipbrushes);
//	Log_Print("%6i total sides\n", nummapbrushsides);
//	Log_Print("%6i boxbevels\n", c_boxbevels);
//	Log_Print("%6i edgebevels\n", c_edgebevels);
//	Log_Print("%6i entities\n", num_entities);
//	Log_Print("%6i planes\n", nummapplanes);
//	Log_Print("%6i areaportals\n", c_areaportals);
//	Log_Print("%6i squatt brushes\n", c_squattbrushes);
//	Log_Print("size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n", map_mins[0],map_mins[1],map_mins[2],
//		map_maxs[0],map_maxs[1],map_maxs[2]);
} //end of the function PrintMapInfo
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void ResetMapLoading(void)
{
	int i;
	epair_t *ep, *nextep;

	Q2_ResetMapLoading();
	Sin_ResetMapLoading();

	//free all map brush side windings
	for (i = 0; i < nummapbrushsides; i++)
	{
		if (brushsides[i].winding)
		{
			FreeWinding(brushsides[i].winding);
		} //end for
	} //end for

	//reset regular stuff
	nummapbrushes = 0;
	memset(mapbrushes, 0, MAX_MAPFILE_BRUSHES * sizeof(mapbrush_t));
	//
	nummapbrushsides = 0;
	memset(brushsides, 0, MAX_MAPFILE_BRUSHSIDES * sizeof(side_t));
	memset(side_brushtextures, 0, MAX_MAPFILE_BRUSHSIDES * sizeof(brush_texture_t));
	//
	nummapplanes = 0;
	memset(mapplanes, 0, MAX_MAPFILE_PLANES * sizeof(plane_t));
	//
	memset(planehash, 0, PLANE_HASHES * sizeof(plane_t *));
	//
	memset(map_texinfo, 0, MAX_MAPFILE_TEXINFO * sizeof(map_texinfo_t));
	map_numtexinfo = 0;
	//
	VectorClear(map_mins);
	VectorClear(map_maxs);
	//
	c_boxbevels = 0;
	c_edgebevels = 0;
	c_areaportals = 0;
	c_clipbrushes = 0;
	c_writtenbrushes = 0;
	//clear the entities
	for (i = 0; i < num_entities; i++)
	{
		for (ep = entities[i].epairs; ep; ep = nextep)
		{
			nextep = ep->next;
			FreeMemory(ep->key);
			FreeMemory(ep->value);
			FreeMemory(ep);
		} //end for
	} //end for
	num_entities = 0;
	memset(entities, 0, MAX_MAP_ENTITIES * sizeof(entity_t));
} //end of the function ResetMapLoading
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
#ifndef Q1_BSPVERSION
#define Q1_BSPVERSION	29
#endif
#ifndef HL_BSPVERSION
#define HL_BSPVERSION	30
#endif

#define Q2_BSPHEADER				(('P'<<24)+('S'<<16)+('B'<<8)+'I')	//IBSP
#define Q2_BSPVERSION	38

#define SINGAME_BSPHEADER		(('P'<<24)+('S'<<16)+('B'<<8)+'R')	//RBSP
#define SINGAME_BSPVERSION		1

#define SIN_BSPHEADER			(('P'<<24)+('S'<<16)+('B'<<8)+'I')	//IBSP
#define SIN_BSPVERSION	41

typedef struct
{
	int ident;
	int version;
} idheader_t;

int LoadMapFromBSP(struct quakefile_s *qf)
{
	idheader_t idheader;

	if (ReadQuakeFile(qf, &idheader, 0, sizeof(idheader_t)) != sizeof(idheader_t))
	{
		return false;
	} //end if

	idheader.ident = LittleLong(idheader.ident);
	idheader.version = LittleLong(idheader.version);
	//Quake3 BSP file
	if (idheader.ident == Q3_BSP_IDENT && idheader.version == Q3_BSP_VERSION)
	{
		ResetMapLoading();
		Q3_LoadMapFromBSP(qf);
		Q3_FreeMaxBSP();
	} //end if
	//Quake2 BSP file
	else if (idheader.ident == Q2_BSPHEADER && idheader.version == Q2_BSPVERSION)
	{
		ResetMapLoading();
		Q2_AllocMaxBSP();
		Q2_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
		Q2_FreeMaxBSP();
	} //endif
	//Sin BSP file
	else if ((idheader.ident == SIN_BSPHEADER && idheader.version == SIN_BSPVERSION) ||
				//the dorks gave the same format another ident and verions
				(idheader.ident == SINGAME_BSPHEADER && idheader.version == SINGAME_BSPVERSION))
	{
		ResetMapLoading();
		Sin_AllocMaxBSP();
		Sin_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
		Sin_FreeMaxBSP();
	} //end if
	//the Quake1 bsp files don't have a ident only a version
	else if (idheader.ident == Q1_BSPVERSION)
	{
		ResetMapLoading();
		Q1_AllocMaxBSP();
		Q1_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
		Q1_FreeMaxBSP();
	} //end if
	//Half-Life also only uses a version number
	else if (idheader.ident == HL_BSPVERSION)
	{
		ResetMapLoading();
		HL_AllocMaxBSP();
		HL_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
		HL_FreeMaxBSP();
	} //end if
	else
	{
		Error("unknown BSP format %c%c%c%c, version %d\n",
										(idheader.ident & 0xFF),
										((idheader.ident >> 8) & 0xFF),
										((idheader.ident >> 16) & 0xFF),
										((idheader.ident >> 24) & 0xFF), idheader.version);
		return false;
	} //end if
	//
	return true;
} //end of the function LoadMapFromBSP

⌨️ 快捷键说明

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