//============================================================================ // // 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
//============================================================================ // // 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
//=========================================================================== // // 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
//=========================================================================== // // 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
/* ================= 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++; }