Ejemplo n.º 1
0
Archivo: map.c Proyecto: kellyrm/Q1
/*
================
LoadMapFile
================
*/
void LoadMapFile (char *filename)
{
	char *buf;

	Message (MSGVERBOSE, "------ LoadMapFile ------");

	LoadFile (filename, (void **)&buf);

	StartTokenParsing (buf);

	num_entities = 0;

	while (ParseEntity ())
	{
	}

	FreeOther (buf);

	if (num_entities == 0)
		Message(MSGERR, "No entities in map");

	if (PlayerStarts == 0)
		Message (MSGWARNCRIT, "No info_player_start entity in level");

	if (strlen(MapTitle) != 0)
		Message (MSGALWAYS, "Title: \"%s\"", MapTitle);

	Message (MSGVERBOSE, "%6i faces", nummapfaces);
	Message (MSGVERBOSE, "%6i brushes", nummapbrushes);
	Message (MSGVERBOSE, "%6i entities", num_entities);
	Message (MSGVERBOSE, "%6i miptex", nummiptex);
	Message (MSGVERBOSE, "%6i texinfo", numtexinfo);
}
Ejemplo n.º 2
0
Archivo: map.c Proyecto: kellyrm/Q1
static void DropBrush (mbrush_t	*b)
{
	mface_t	*f, *f2;

	for (f = b->faces; f != NULL; f = f2)
	{
		f2 = f->next;
		FreeOther (f);
	}

	b->faces = NULL;
}
Ejemplo n.º 3
0
HSDrawOtherData* HSDrawData::AllocOther(HSDrawOtherData* pData,BOOL bForce /*= FALSE*/)
{
	FreeOther();

	if( m_pHSExternAlloc )
	{
		if( bForce || pData )
		{
			m_pOtherData = (HSDrawOtherData*)(*m_pHSExternAlloc)
				( (long)pData,HSDrawOtherDataType );
		}
	}

	return m_pOtherData;
}
Ejemplo n.º 4
0
Archivo: map.c Proyecto: kellyrm/Q1
void 	SetKeyValue (entity_t *ent, char *key, char *value)
{
	epair_t	*ep;

	for (ep=ent->epairs ; ep ; ep=ep->next)
		if (!strcmp (ep->key, key) )
		{
			FreeOther (ep->value);
			ep->value = copystring(value);
			return;
		}
	ep = AllocOther (sizeof(*ep));
	ep->next = ent->epairs;
	ent->epairs = ep;
	ep->key = copystring(key);
	ep->value = copystring(value);
}
Ejemplo n.º 5
0
Archivo: map.c Proyecto: kellyrm/Q1
/*
================
ParseEntity
================
*/
qboolean ParseEntity (void)
{
	epair_t	   *ep;
	entity_t   *world;
	mbrush_t   *b, *next;
	int	   Line, i;
	char	   *Classname;
	static int WorldSpawns = 0;

	if (!GetToken (true))
		return false;

	Line = scriptline;

	if (strcmp (token, "{") )
		Message (MSGERR, "Invalid entity format, { not found on line %d", Line);

	ExtendArray(entities, num_entities);
	mapent = &entities[num_entities];
	mapent->Line = Line;
	num_entities++;

	do
	{
		if (!GetToken (true))
			Message (MSGERR, "ParseEntity: EOF without closing brace");
		if (!strcmp (token, "}") )
			break;
		if (!strcmp (token, "{") )
			ParseBrush ();
		else
			ParseEpair ();
	} while (1);

	Classname = ValueForKey(mapent, "classname");

	if (strlen(Classname) == 0)
		Message (MSGERR, "No classname in entity on line %d", Line); // Missing classname

	if (!stricmp(Classname, "worldspawn"))
	{
		if (++WorldSpawns > 1)
			Message (MSGERR, "Multiple world entities on line %d", Line); // Multiple worlds

		if (!options.onlyents && !mapent->brushes)
			Message (MSGERR, "No world brushes on line %d", Line); // No world brushes

		// Get map title
		strcpy(MapTitle, ValueForKey(mapent, "message"));

		// Translate into simplified Quake character set
		for (i = 0; MapTitle[i] != '\0'; ++i)
		{
			MapTitle[i] &= 0x7F; // Ignore colour bit

			if (MapTitle[i] >= 0x12 && MapTitle[i] <= 0x1B)
				MapTitle[i] += 0x1E; // Extra 0-9 area
			else if (MapTitle[i] == 0x10)
				MapTitle[i] = '['; // Extra bracket
			else if (MapTitle[i] == 0x11)
				MapTitle[i] = ']'; // Extra bracket

			if (!isprint(MapTitle[i] & 0xFF))
				MapTitle[i] = ' ';
		}
	}
	else if (options.noents && strnicmp(Classname, "info_player_", 12))
	{
		// Only world and players allowed; drop entity
		
		for (ep = mapent->epairs; ep; ep = ep->next)
			FreeOther (ep->value);

		memset (mapent, 0, sizeof(entity_t));

		--num_entities;
		
		return true;
	}
	else if (options.group && !stricmp(Classname, "func_group"))
	{
		// Move entity brushes into world
		world = &entities[0];

		for (b = mapent->brushes; b; b = next)
		{
			next = b->next;
			b->next = world->brushes;
			world->brushes = b;
		}
		
		for (ep = mapent->epairs; ep; ep = ep->next)
			FreeOther (ep->value);

		memset (mapent, 0, sizeof(entity_t));

		--num_entities;
		
		return true;
	}

	if (num_entities == 1 && WorldSpawns == 0)
		Message (MSGERR, "World is not first entity on line %d", Line); // World is not first entity

	GetVectorForKey (mapent, "origin", mapent->origin);
	return true;
}
Ejemplo n.º 6
0
Archivo: map.c Proyecto: kellyrm/Q1
/*
=================
ParseBrush
=================
*/
void ParseBrush (void)
{
	mbrush_t  *b;
	mface_t	  *f, *f2;
	vec3_t	  planepts[3];
	vec3_t	  t1, t2, t3, VAxis[2];
	int	  i, j, Faces;
	texinfo_t tx;
	vec_t	  d;
	vec_t	  shift[2], rotate, scale[2];
	qboolean  ok, Valve220;

        ExtendArray(mapbrushes, nummapbrushes);
	b = &mapbrushes[nummapbrushes];
	b->Line = scriptline;

	ok = GetToken (true);

	while (ok)
	{
		txcommand = 0;
		if (!strcmp (token, "}") )
		{
			if (!options.onlyents)
			{
				if (InvalidBrush(b, &Faces))
				{
					// Too few faces in brush or not closed; drop it
					DropBrush (b);
					nummapfaces -= Faces;
					// Note: texinfo array is not corrected here
					return;
				}
			}

			if (options.SortFace)
				SortFaces(b);

			break;
		}

	// read the three point plane definition
		for (i=0 ; i<3 ; i++)
		{
			if (i != 0)
				GetToken (true);
			if (strcmp (token, "(") )
				Message (MSGERR, "Invalid brush plane format on line %d", scriptline);

			for (j=0 ; j<3 ; j++)
			{
				GetToken (false);
				planepts[i][j] = atof(token);	// AR: atof
			}

			GetToken (false);
			if (strcmp (token, ")") )
				Message (MSGERR, "Invalid brush plane format on line %d", scriptline);

		}

	// read the texturedef
		memset (&tx, 0, sizeof(tx));
		GetToken (false);

		if (options.Q2Map)
			Q2ToQ1Tex (token);

		// Check texture name length
		if (strlen(token) > sizeof(char16) - 1)
			Message (MSGERR, "Texture name \"%s\" too long on line %d", token, scriptline);

		if (options.SolidMap && num_entities == 1 && token[0] == '*' ||
		    options.noents && num_entities > 1)
		{
			// No liquid worldbrushes or only worldbrushes allowed; drop brush
			DropBrush (b);

			while (GetToken(true) && strcmp(token, "}"))
				;

			return;
		}

		Valve220 = false;

		tx.miptex = FindMiptex (token);
		GetToken (false);
		
		if (!strcmp (token, "["))
		{
			// Valve 220 map import
			Valve220 = true;
			GetValveTex (VAxis[0]);
		}

		shift[0] = atoi(token);
		GetToken (false);
		
		if (Valve220)
		{
			// Skip ]
			GetToken (false);
			GetValveTex (VAxis[1]);
		}

		shift[1] = atoi(token);
		GetToken (false);

		if (Valve220)
			GetToken (false); // Skip ]

		rotate = atoi(token);
		GetToken (false);
		scale[0] = atof(token);
		GetToken (false);
		scale[1] = atof(token);

		if (options.Q2Map)
		{
			// Skip extra Q2 style face info
			GetToken (false);
			GetToken (false);
			GetToken (false);
		}

		ok = GetToken (true); // Note : scriptline normally gets advanced here

		// if the three points are all on a previous plane, it is a
		// duplicate plane
		for (f2 = b->faces ; f2 ; f2=f2->next)
		{
			for (i=0 ; i<3 ; i++)
			{
				d = DotProduct(planepts[i],f2->plane.normal) - f2->plane.dist;
				if (d < -ON_EPSILON || d > ON_EPSILON)
					break;
			}
			if (i==3)
				break;
		}
		if (f2)
		{
			Message (MSGWARN, "Brush with duplicate plane on line %d", scriptline - 1);
			continue;
		}

		f = AllocOther(sizeof(mface_t));

	// convert to a vector / dist plane
		for (j=0 ; j<3 ; j++)
		{
			t1[j] = planepts[0][j] - planepts[1][j];
			t2[j] = planepts[2][j] - planepts[1][j];
			t3[j] = planepts[1][j];
		}

		CrossProduct(t1,t2, f->plane.normal);
		if (VectorCompare (f->plane.normal, vec3_origin))
		{
			Message (MSGWARN, "Brush plane with no normal on line %d", scriptline - 1);
			FreeOther (f);
			continue;
		}
		VectorNormalize (f->plane.normal);
		f->plane.dist = DotProduct (t3, f->plane.normal);

		f->next = b->faces;
		b->faces = f;

		if (txcommand=='1' || txcommand=='2')
		{		// from QuArK, the texture vectors are given directly from the three points
			vec3_t	TexPt[2];
			int		k;
			vec_t	dot22, dot23, dot33, mdet, aa, bb, dd;

			k = txcommand-'0';
			for (j=0; j<3; j++)
				TexPt[1][j] = (planepts[k][j] - planepts[0][j]) * ScaleCorrection;
			k = 3-k;
			for (j=0; j<3; j++)
				TexPt[0][j] = (planepts[k][j] - planepts[0][j]) * ScaleCorrection;

			dot22 = DotProduct (TexPt[0], TexPt[0]);
			dot23 = DotProduct (TexPt[0], TexPt[1]);
			dot33 = DotProduct (TexPt[1], TexPt[1]);
			mdet = dot22*dot33-dot23*dot23;
			if (mdet<1E-6 && mdet>-1E-6)
			{
				aa = bb = dd = 0;
				Message (MSGWARN, "Degenerate QuArK-style brush texture on line %d", scriptline - 1);
			}
			else
			{
				mdet = 1.0/mdet;
      			aa = dot33*mdet;
      			bb = -dot23*mdet;
				//cc = -dot23*mdet;     // cc = bb
				dd = dot22*mdet;
			}

			for (j=0; j<3; j++)
			{
				tx.vecs[0][j] = aa * TexPt[0][j] + bb * TexPt[1][j];
				tx.vecs[1][j] = -(/*cc*/ bb * TexPt[0][j] + dd * TexPt[1][j]);
			}

			tx.vecs[0][3] = -DotProduct(tx.vecs[0], planepts[0]);
			tx.vecs[1][3] = -DotProduct(tx.vecs[1], planepts[0]);
		}
		else if (Valve220)
		{
			// Valve 220 texturedef
			vec3_t vec;
			vec_t  tscale;

			// Prevent division by zero
			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

			// FIXME: If origin brushes are in use, this is where to fix their tex alignment!!!
			for (i = 0; i < 2; ++i)
			{
				tscale = 1 / scale[i];
				VectorScale(VAxis[i], tscale, vec);
				
				for (j = 0; j < 3; ++j)
					tx.vecs[i][j] = (float)vec[j];
				
				tx.vecs[i][3] = (float)shift[i] + DotProduct(vec3_origin, vec);
			}
		}
		else
	//
	// fake proper texture vectors from QuakeEd style
	//
		{
			vec3_t	vecs[2];
			int		sv, tv;
			vec_t	ang, sinv, cosv;
			vec_t	ns, nt;

			TextureAxisFromPlane(&f->plane, vecs[0], vecs[1]);

			if (!scale[0])
				scale[0] = 1;
			if (!scale[1])
				scale[1] = 1;

		// rotate axis
			if (rotate == 0)
				{ sinv = 0 ; cosv = 1; }
			else if (rotate == 90)
				{ sinv = 1 ; cosv = 0; }
			else if (rotate == 180)
				{ sinv = 0 ; cosv = -1; }
			else if (rotate == 270)
				{ sinv = -1 ; cosv = 0; }
			else
			{
				ang = rotate / 180 * Q_PI;
				sinv = sin(ang);
				cosv = cos(ang);
			}

			if (vecs[0][0])
				sv = 0;
			else if (vecs[0][1])
				sv = 1;
			else
				sv = 2;

			if (vecs[1][0])
				tv = 0;
			else if (vecs[1][1])
				tv = 1;
			else
				tv = 2;

			for (i=0 ; i<2 ; i++)
			{
				ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
				nt = sinv * vecs[i][sv] +  cosv * vecs[i][tv];
				vecs[i][sv] = ns;
				vecs[i][tv] = nt;
			}

			for (i=0 ; i<2 ; i++)
				for (j=0 ; j<3 ; j++)
					tx.vecs[i][j] = vecs[i][j] / scale[i];

			tx.vecs[0][3] = shift[0];
			tx.vecs[1][3] = shift[1];
		}

	// unique the texinfo
		f->texinfo = FindTexinfo (&tx);
		nummapfaces++;
	};

	nummapbrushes++;
	b->next = mapent->brushes;
	mapent->brushes = b;
}