Ejemplo n.º 1
0
Archivo: map.c Proyecto: kellyrm/Q1
/*
===============
FindTexinfo

Returns a global texinfo number
===============
*/
int	FindTexinfo (texinfo_t *t)
{
	int			i, j;
	texinfo_t	*tex;

// set the special flag
	if (miptex[t->miptex][0] == '*' ||
	    !options.SolidMap && !Q_strncasecmp (miptex[t->miptex], "sky",3) )
		t->flags |= TEX_SPECIAL;


	tex = texinfo;
	for (i=0 ; i<numtexinfo;i++, tex++)
	{
		if (t->miptex != tex->miptex)
			continue;
		if (t->flags != tex->flags)
			continue;

		for (j=0 ; j<8 ; j++)
			if (t->vecs[0][j] != tex->vecs[0][j])
				break;
		if (j != 8)
			continue;

		return i;
	}

// allocate a new texture
	ExtendArray(texinfo, i);
	texinfo[i] = *t;
	numtexinfo++;

	return i;
}
Ejemplo n.º 2
0
Archivo: map.c Proyecto: kellyrm/Q1
int FindMiptex (char *name)
{
	int		i;

	for (i=0 ; i<nummiptex ; i++)
	{
		if (!Q_strncasecmp(name, miptex[i], sizeof(char16)))
			return i;
	}
        ExtendArray(miptex, i);
	CleanupName (name, miptex[i]);
	nummiptex++;
	return i;
}
Ejemplo n.º 3
0
Archivo: brush.c Proyecto: kellyrm/Q1
/*
===============
FindPlane

Returns a global plane number and the side that will be the front
===============
*/
int	FindPlane (plane_t *dplane, int *side)
{
	int			i;
	plane_t		*dp, pl;
	vec_t		dot;

	dot = VectorLength(dplane->normal);
	if (dot < 1.0 - ANGLEEPSILON || dot > 1.0 + ANGLEEPSILON)
		Message (MSGERR, "FindPlane: Normalization error");

	pl = *dplane;
	NormalizePlane (&pl);
	if (DotProduct(pl.normal, dplane->normal) > 0)
		*side = 0;
	else
		*side = 1;

	dp = planes;
	for (i=0 ; i<numbrushplanes;i++, dp++)
	{
		dot = DotProduct (dp->normal, pl.normal);
		if (dot > 1.0 - ANGLEEPSILON
		&& fabs(dp->dist - pl.dist) < DISTEPSILON )
		{	// regular match
			return i;
		}
	}

        if (validfacesactive)
                ExtendArray(validfaces, numbrushplanes);
	ExtendArray(planes, numbrushplanes);
	planes[numbrushplanes] = pl;

	numbrushplanes++;

	return numbrushplanes-1;
}
Ejemplo n.º 4
0
Archivo: tkOption.c Proyecto: das/tcltk
static void
ExtendStacks(
    ElArray *arrayPtr,		/* Array of elements to copy onto stacks. */
    int leaf)			/* If zero, then don't copy exact leaf
				 * elements. */
{
    register int count;
    register Element *elPtr;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (elPtr = arrayPtr->els, count = arrayPtr->numUsed;
	    count > 0; elPtr++, count--) {
	if (!(elPtr->flags & (NODE|WILDCARD)) && !leaf) {
	    continue;
	}
	tsdPtr->stacks[elPtr->flags] =
		ExtendArray(tsdPtr->stacks[elPtr->flags], elPtr);
    }
}
Ejemplo n.º 5
0
Archivo: tkOption.c Proyecto: aosm/tcl
void
Tk_AddOption(
    Tk_Window tkwin,		/* Window token; option will be associated
				 * with main window for this window. */
    CONST char *name,		/* Multi-element name of option. */
    CONST char *value,		/* String value for option. */
    int priority)		/* Overall priority level to use for this
				 * option, such as TK_USER_DEFAULT_PRIO or
				 * TK_INTERACTIVE_PRIO. Must be between 0 and
				 * TK_MAX_PRIO. */
{
    TkWindow *winPtr = ((TkWindow *) tkwin)->mainPtr->winPtr;
    register ElArray **arrayPtrPtr;
    register Element *elPtr;
    Element newEl;
    register CONST char *p;
    CONST char *field;
    int count, firstField;
    ptrdiff_t length;
#define TMP_SIZE 100
    char tmp[TMP_SIZE+1];
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (winPtr->mainPtr->optionRootPtr == NULL) {
	OptionInit(winPtr->mainPtr);
    }
    tsdPtr->cachedWindow = NULL;/* Invalidate the cache. */

    /*
     * Compute the priority for the new element, including both the overall
     * level and the serial number (to disambiguate with the level).
     */

    if (priority < 0) {
	priority = 0;
    } else if (priority > TK_MAX_PRIO) {
	priority = TK_MAX_PRIO;
    }
    newEl.priority = (priority << 24) + tsdPtr->serial;
    tsdPtr->serial++;

    /*
     * Parse the option one field at a time.
     */

    arrayPtrPtr = &(((TkWindow *) tkwin)->mainPtr->optionRootPtr);
    p = name;
    for (firstField = 1; ; firstField = 0) {
	/*
	 * Scan the next field from the name and convert it to a Tk_Uid. Must
	 * copy the field before calling Tk_Uid, so that a terminating NULL
	 * may be added without modifying the source string.
	 */

	if (*p == '*') {
	    newEl.flags = WILDCARD;
	    p++;
	} else {
	    newEl.flags = 0;
	}
	field = p;
	while ((*p != 0) && (*p != '.') && (*p != '*')) {
	    p++;
	}
	length = p - field;
	if (length > TMP_SIZE) {
	    length = TMP_SIZE;
	}
	strncpy(tmp, field, (size_t) length);
	tmp[length] = 0;
	newEl.nameUid = Tk_GetUid(tmp);
	if (isupper(UCHAR(*field))) {
	    newEl.flags |= CLASS;
	}

	if (*p != 0) {
	    /*
	     * New element will be a node. If this option can't possibly apply
	     * to this main window, then just skip it. Otherwise, add it to
	     * the parent, if it isn't already there, and descend into it.
	     */

	    newEl.flags |= NODE;
	    if (firstField && !(newEl.flags & WILDCARD)
		    && (newEl.nameUid != winPtr->nameUid)
		    && (newEl.nameUid != winPtr->classUid)) {
		return;
	    }
	    for (elPtr = (*arrayPtrPtr)->els, count = (*arrayPtrPtr)->numUsed;
		    ; elPtr++, count--) {
		if (count == 0) {
		    newEl.child.arrayPtr = NewArray(5);
		    *arrayPtrPtr = ExtendArray(*arrayPtrPtr, &newEl);
		    arrayPtrPtr = &((*arrayPtrPtr)
			    ->nextToUse[-1].child.arrayPtr);
		    break;
		}
		if ((elPtr->nameUid == newEl.nameUid)
			&& (elPtr->flags == newEl.flags)) {
		    arrayPtrPtr = &(elPtr->child.arrayPtr);
		    break;
		}
	    }
	    if (*p == '.') {
		p++;
	    }
	} else {
	    /*
	     * New element is a leaf. Add it to the parent, if it isn't
	     * already there. If it exists already, keep whichever value has
	     * highest priority.
	     */

	    newEl.child.valueUid = Tk_GetUid(value);
	    for (elPtr = (*arrayPtrPtr)->els, count = (*arrayPtrPtr)->numUsed;
		    ; elPtr++, count--) {
		if (count == 0) {
		    *arrayPtrPtr = ExtendArray(*arrayPtrPtr, &newEl);
		    return;
		}
		if ((elPtr->nameUid == newEl.nameUid)
			&& (elPtr->flags == newEl.flags)) {
		    if (elPtr->priority < newEl.priority) {
			elPtr->priority = newEl.priority;
			elPtr->child.valueUid = newEl.child.valueUid;
		    }
		    return;
		}
	    }
	}
    }
}
Ejemplo n.º 6
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.º 7
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;
}