Beispiel #1
0
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
long double ReadSignedFloat( script_t *script ) {
	token_t token;
	long double sign = 1;

	PS_ExpectAnyToken( script, &token );
	if ( !strcmp( token.string, "-" ) ) {
		sign = -1;
		PS_ExpectTokenType( script, TT_NUMBER, 0, &token );
	} //end if
	else if ( token.type != TT_NUMBER ) {
		ScriptError( script, "expected float value, found %s\n", token.string );
	} //end else if
	return sign * token.floatvalue;
} //end of the function ReadSignedFloat
Beispiel #2
0
//============================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//============================================================================
signed long int ReadSignedInt( script_t *script ) {
	token_t token;
	signed long int sign = 1;

	PS_ExpectAnyToken( script, &token );
	if ( !strcmp( token.string, "-" ) ) {
		sign = -1;
		PS_ExpectTokenType( script, TT_NUMBER, TT_INTEGER, &token );
	} //end if
	else if ( token.type != TT_NUMBER || token.subtype == TT_FLOAT ) {
		ScriptError( script, "expected integer value, found %s\n", token.string );
	} //end else if
	return sign * token.intvalue;
} //end of the function ReadSignedInt
Beispiel #3
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void AAS_ParseBSPEntities( void ) {
	script_t *script;
	token_t token;
	bsp_entity_t *ent;
	bsp_epair_t *epair;
	byte *buffer, *buftrav;
	int bufsize;

	// RF, modified this, so that it first gathers up memory requirements, then allocates a single chunk,
	// and places the strings all in there

	bspworld.ebuffer = NULL;

	script = LoadScriptMemory( bspworld.dentdata, bspworld.entdatasize, "entdata" );
	SetScriptFlags( script, SCFL_NOSTRINGWHITESPACES | SCFL_NOSTRINGESCAPECHARS ); //SCFL_PRIMITIVE);

	bufsize = 0;

	while ( PS_ReadToken( script, &token ) )
	{
		if ( strcmp( token.string, "{" ) ) {
			ScriptError( script, "invalid %s\n", token.string );
			AAS_FreeBSPEntities();
			FreeScript( script );
			return;
		} //end if
		if ( bspworld.numentities >= MAX_BSPENTITIES ) {
			botimport.Print( PRT_MESSAGE, "too many entities in BSP file\n" );
			break;
		} //end if
		while ( PS_ReadToken( script, &token ) )
		{
			if ( !strcmp( token.string, "}" ) ) {
				break;
			}
			bufsize += sizeof( bsp_epair_t );
			if ( token.type != TT_STRING ) {
				ScriptError( script, "invalid %s\n", token.string );
				AAS_FreeBSPEntities();
				FreeScript( script );
				return;
			} //end if
			StripDoubleQuotes( token.string );
			bufsize += strlen( token.string ) + 1;
			if ( !PS_ExpectTokenType( script, TT_STRING, 0, &token ) ) {
				AAS_FreeBSPEntities();
				FreeScript( script );
				return;
			} //end if
			StripDoubleQuotes( token.string );
			bufsize += strlen( token.string ) + 1;
		} //end while
		if ( strcmp( token.string, "}" ) ) {
			ScriptError( script, "missing }\n" );
			AAS_FreeBSPEntities();
			FreeScript( script );
			return;
		} //end if
	} //end while
	FreeScript( script );

	buffer = (byte *)GetClearedHunkMemory( bufsize );
	buftrav = buffer;
	bspworld.ebuffer = buffer;

	// RF, now parse the entities into memory
	// RF, NOTE: removed error checks for speed, no need to do them twice

	script = LoadScriptMemory( bspworld.dentdata, bspworld.entdatasize, "entdata" );
	SetScriptFlags( script, SCFL_NOSTRINGWHITESPACES | SCFL_NOSTRINGESCAPECHARS ); //SCFL_PRIMITIVE);

	bspworld.numentities = 1;

	while ( PS_ReadToken( script, &token ) )
	{
		ent = &bspworld.entities[bspworld.numentities];
		bspworld.numentities++;
		ent->epairs = NULL;
		while ( PS_ReadToken( script, &token ) )
		{
			if ( !strcmp( token.string, "}" ) ) {
				break;
			}
			epair = (bsp_epair_t *) buftrav; buftrav += sizeof( bsp_epair_t );
			epair->next = ent->epairs;
			ent->epairs = epair;
			StripDoubleQuotes( token.string );
			epair->key = (char *) buftrav; buftrav += ( strlen( token.string ) + 1 );
			strcpy( epair->key, token.string );
			if ( !PS_ExpectTokenType( script, TT_STRING, 0, &token ) ) {
				AAS_FreeBSPEntities();
				FreeScript( script );
				return;
			} //end if
			StripDoubleQuotes( token.string );
			epair->value = (char *) buftrav; buftrav += ( strlen( token.string ) + 1 );
			strcpy( epair->value, token.string );
		} //end while
	} //end while
	FreeScript( script );
} //end of the function AAS_ParseBSPEntities
Beispiel #4
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void AAS_ParseBSPEntities(void)
{
	script_t *script;
	token_t token;
	bsp_entity_t *ent;
	bsp_epair_t *epair;

	script = LoadScriptMemory(bspworld.dentdata, bspworld.entdatasize, "entdata");
	SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES|SCFL_NOSTRINGESCAPECHARS);//SCFL_PRIMITIVE);

	bspworld.numentities = 1;

	while(PS_ReadToken(script, &token))
	{
		if (strcmp(token.string, "{"))
		{
			ScriptError(script, "invalid %s", token.string);
			AAS_FreeBSPEntities();
			FreeScript(script);
			return;
		} //end if
		if (bspworld.numentities >= MAX_BSPENTITIES)
		{
			botimport.Print(PRT_MESSAGE, "too many entities in BSP file\n");
			break;
		} //end if
		ent = &bspworld.entities[bspworld.numentities];
		bspworld.numentities++;
		ent->epairs = NULL;
		while(PS_ReadToken(script, &token))
		{
			if (!strcmp(token.string, "}")) break;
			epair = (bsp_epair_t *) GetClearedHunkMemory(sizeof(bsp_epair_t));
			epair->next = ent->epairs;
			ent->epairs = epair;
			if (token.type != TT_STRING)
			{
				ScriptError(script, "invalid %s", token.string);
				AAS_FreeBSPEntities();
				FreeScript(script);
				return;
			} //end if
			StripDoubleQuotes(token.string);
			epair->key = (char *) GetHunkMemory(strlen(token.string) + 1);
			strcpy(epair->key, token.string);
			if (!PS_ExpectTokenType(script, TT_STRING, 0, &token))
			{
				AAS_FreeBSPEntities();
				FreeScript(script);
				return;
			} //end if
			StripDoubleQuotes(token.string);
			epair->value = (char *) GetHunkMemory(strlen(token.string) + 1);
			strcpy(epair->value, token.string);
		} //end while
		if (strcmp(token.string, "}"))
		{
			ScriptError(script, "missing }");
			AAS_FreeBSPEntities();
			FreeScript(script);
			return;
		} //end if
	} //end while
	FreeScript(script);
} //end of the function AAS_ParseBSPEntities
Beispiel #5
0
/*
=================
Q2_ParseBrush
=================
*/
void Q2_ParseBrush(script_t *script, entity_t *mapent)
{
	mapbrush_t      *b;
	int             i, j, k;
	int             mt;
	side_t          *side, *s2;
	int             planenum;
	brush_texture_t td;
	int             planepts[3][3];
	token_t         token;

	if (nummapbrushes >= MAX_MAPFILE_BRUSHES)
	{
		Error("nummapbrushes == MAX_MAPFILE_BRUSHES");
	}

	b                 = &mapbrushes[nummapbrushes];
	b->original_sides = &brushsides[nummapbrushsides];
	b->entitynum      = num_entities - 1;
	b->brushnum       = nummapbrushes - mapent->firstbrush;
	b->leafnum        = -1;

	do
	{
		if (!PS_ReadToken(script, &token))
		{
			break;
		}
		if (!strcmp(token.string, "}"))
		{
			break;
		}

		//IDBUG: mixed use of MAX_MAPFILE_? and MAX_MAP_? this could
		//			lead to out of bound indexing of the arrays
		if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES)
		{
			Error("MAX_MAPFILE_BRUSHSIDES");
		}
		side = &brushsides[nummapbrushsides];

		//read the three point plane definition
		for (i = 0; i < 3; i++)
		{
			if (i != 0)
			{
				PS_ExpectTokenString(script, "(");
			}
			for (j = 0; j < 3; j++)
			{
				PS_ExpectAnyToken(script, &token);
				planepts[i][j] = atof(token.string);
			} //end for
			PS_ExpectTokenString(script, ")");
		} //end for

		//
		//read the texturedef
		//
		PS_ExpectAnyToken(script, &token);
		strcpy(td.name, token.string);

		PS_ExpectAnyToken(script, &token);
		td.shift[0] = atol(token.string);
		PS_ExpectAnyToken(script, &token);
		td.shift[1] = atol(token.string);
		PS_ExpectAnyToken(script, &token);
		td.rotate = atol(token.string);
		PS_ExpectAnyToken(script, &token);
		td.scale[0] = atof(token.string);
		PS_ExpectAnyToken(script, &token);
		td.scale[1] = atof(token.string);

		//find default flags and values
		mt             = FindMiptex(td.name);
		td.flags       = textureref[mt].flags;
		td.value       = textureref[mt].value;
		side->contents = textureref[mt].contents;
		side->surf     = td.flags = textureref[mt].flags;

		//check if there's a number available
		if (PS_CheckTokenType(script, TT_NUMBER, 0, &token))
		{
			side->contents = token.intvalue;
			PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
			side->surf = td.flags = token.intvalue;
			PS_ExpectTokenType(script, TT_NUMBER, 0, &token);
			td.value = token.intvalue;
		}

		// translucent objects are automatically classified as detail
//		if (side->surf & (SURF_TRANS33|SURF_TRANS66) )
//			side->contents |= CONTENTS_DETAIL;
		if (side->contents & (CONTENTS_PLAYERCLIP | CONTENTS_MONSTERCLIP))
		{
			side->contents |= CONTENTS_DETAIL;
		}
		if (fulldetail)
		{
			side->contents &= ~CONTENTS_DETAIL;
		}
		if (!(side->contents & ((LAST_VISIBLE_CONTENTS - 1)
		                        | CONTENTS_PLAYERCLIP | CONTENTS_MONSTERCLIP | CONTENTS_MIST)))
		{
			side->contents |= CONTENTS_SOLID;
		}

		// hints and skips are never detail, and have no content
//		if (side->surf & (SURF_HINT|SURF_SKIP) )
//		{
//			side->contents = 0;
//			side->surf &= ~CONTENTS_DETAIL;
//		}

#ifdef ME
		//for creating AAS... this side is textured
		side->flags |= SFL_TEXTURED;
#endif //ME
		//
		// find the plane number
		//
		planenum = PlaneFromPoints(planepts[0], planepts[1], planepts[2]);
		if (planenum == -1)
		{
			Log_Print("Entity %i, Brush %i: plane with no normal\n"
			          , b->entitynum, b->brushnum);
			continue;
		}

		//
		// see if the plane has been used already
		//
		for (k = 0 ; k < b->numsides ; k++)
		{
			s2 = b->original_sides + k;
			if (s2->planenum == planenum)
			{
				Log_Print("Entity %i, Brush %i: duplicate plane\n"
				          , b->entitynum, b->brushnum);
				break;
			}
			if (s2->planenum == (planenum ^ 1))
			{
				Log_Print("Entity %i, Brush %i: mirrored plane\n"
				          , b->entitynum, b->brushnum);
				break;
			}
		}
		if (k != b->numsides)
		{
			continue;       // duplicated

		}
		//
		// keep this side
		//

		side           = b->original_sides + b->numsides;
		side->planenum = planenum;
		side->texinfo  = TexinfoForBrushTexture(&mapplanes[planenum],
		                                        &td, vec3_origin);

		// save the td off in case there is an origin brush and we
		// have to recalculate the texinfo
		side_brushtextures[nummapbrushsides] = td;

		nummapbrushsides++;
		b->numsides++;
	}
	while (1);

	// get the content for the entire brush
	b->contents = Q2_BrushContents(b);

#ifdef ME
	if (BrushExists(b))
	{
		c_squattbrushes++;
		b->numsides = 0;
		return;
	} //end if

	if (create_aas)
	{
		//create AAS brushes, and add brush bevels
		AAS_CreateMapBrushes(b, mapent, true);
		//NOTE: if we return here then duplicate plane errors occur for the non world entities
		return;
	} //end if
#endif //ME

	// allow detail brushes to be removed
	if (nodetail && (b->contents & CONTENTS_DETAIL))
	{
		b->numsides = 0;
		return;
	}

	// allow water brushes to be removed
	if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)))
	{
		b->numsides = 0;
		return;
	}

	// create windings for sides and bounds for brush
	MakeBrushWindings(b);

	// brushes that will not be visible at all will never be
	// used as bsp splitters
	if (b->contents & (CONTENTS_PLAYERCLIP | CONTENTS_MONSTERCLIP))
	{
		c_clipbrushes++;
		for (i = 0 ; i < b->numsides ; i++)
			b->original_sides[i].texinfo = TEXINFO_NODE;
	}

	//
	// origin brushes are removed, but they set
	// the rotation origin for the rest of the brushes
	// in the entity.  After the entire entity is parsed,
	// the planenums and texinfos will be adjusted for
	// the origin brush
	//
	if (b->contents & CONTENTS_ORIGIN)
	{
		char   string[32];
		vec3_t origin;

		if (num_entities == 1)
		{
			Error("Entity %i, Brush %i: origin brushes not allowed in world"
			      , b->entitynum, b->brushnum);
			return;
		}

		VectorAdd(b->mins, b->maxs, origin);
		VectorScale(origin, 0.5, origin);

		sprintf(string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]);
		SetKeyValue(&entities[b->entitynum], "origin", string);

		VectorCopy(origin, entities[b->entitynum].origin);

		// don't keep this brush
		b->numsides = 0;

		return;
	}

	AddBrushBevels(b);

	nummapbrushes++;
	mapent->numbrushes++;
}