static void ParseFloor (FScanner &sc) { FTextureID picnum; int terrain; bool opt = sc.CheckString("optional"); sc.MustGetString (); picnum = TexMan.CheckForTexture (sc.String, FTexture::TEX_Flat, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny); if (!picnum.Exists()) { if (!opt) { Printf("Unknown flat %s\n", sc.String); } sc.MustGetString(); return; } sc.MustGetString (); terrain = P_FindTerrain (sc.String); if (terrain == -1) { Printf ("Unknown terrain %s\n", sc.String); terrain = 0; } TerrainTypes.Set(picnum.GetIndex(), terrain); }
static TArray<FString> PSR_ReadBaseInstalls(FScanner &sc) { TArray<FString> result; // Get a list of possible install directories. while(sc.GetToken()) { if(sc.TokenType == '}') break; sc.TokenMustBe(TK_StringConst); FString key(sc.String); if(key.Left(18).CompareNoCase("BaseInstallFolder_") == 0) { sc.MustGetToken(TK_StringConst); result.Push(FString(sc.String) + "/steamapps/common"); } else { if(sc.CheckToken('{')) PSR_FindEndBlock(sc); else sc.MustGetToken(TK_StringConst); } } return result; }
bool FIntermissionActionWiper::ParseKey(FScanner &sc) { struct WipeType { const char *Name; gamestate_t Type; } const FT[] = { { "Crossfade", GS_FORCEWIPEFADE }, { "Melt", GS_FORCEWIPEMELT }, { "Burn", GS_FORCEWIPEBURN }, { "Default", GS_FORCEWIPE }, { NULL, GS_FORCEWIPE } }; if (sc.Compare("WipeType")) { sc.MustGetToken('='); sc.MustGetToken(TK_Identifier); int v = sc.MatchString(&FT[0].Name, sizeof(FT[0])); if (v != -1) mWipeType = FT[v].Type; return true; } else return Super::ParseKey(sc); }
static void AddOneKey(Keygroup *keygroup, PClassActor *mi, FScanner &sc) { if (mi) { // Any inventory item can be used to unlock a door if (mi->IsDescendantOf(RUNTIME_CLASS(AInventory))) { OneKey k = {mi,1}; keygroup->anykeylist.Push (k); //... but only keys get key numbers! if (mi->IsDescendantOf(RUNTIME_CLASS(AKey))) { if (!ignorekey && static_cast<AKey*>(GetDefaultByType(mi))->KeyNumber == 0) { static_cast<AKey*>(GetDefaultByType(mi))->KeyNumber=++currentnumber; } } } else { sc.ScriptError("'%s' is not an inventory item", sc.String); } } else { sc.ScriptError("Unknown item '%s'", sc.String); } }
static TArray<FString> ParseSteamRegistry(const char* path) { TArray<FString> dirs; // Read registry data FScanner sc; if (sc.OpenFile(path)) { sc.SetCMode(true); // Find the SteamApps listing if (PSR_FindAndEnterBlock(sc, "InstallConfigStore")) { if (PSR_FindAndEnterBlock(sc, "Software")) { if (PSR_FindAndEnterBlock(sc, "Valve")) { if (PSR_FindAndEnterBlock(sc, "Steam")) { dirs = PSR_ReadBaseInstalls(sc); } PSR_FindEndBlock(sc); } PSR_FindEndBlock(sc); } PSR_FindEndBlock(sc); } } return dirs; }
static void ParseOptionSettings(FScanner &sc) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) { sc.MustGetString(); if (sc.Compare("else")) { SkipSubBlock(sc); } else if (sc.Compare("ifgame")) { if (!CheckSkipGameBlock(sc)) { // recursively parse sub-block ParseOptionSettings(sc); } } else if (sc.Compare("Linespacing")) { sc.MustGetNumber(); OptionSettings.mLinespacing = sc.Number; } else if (sc.Compare("LabelOffset")) { sc.MustGetNumber(); // ignored } else { sc.ScriptError("Unknown keyword '%s'", sc.String); } } }
void ParseFunctionDef(FScanner &sc, PClassActor *cls, FName funcname, TArray<PType *> &rets, DWORD funcflags) { assert(cls != NULL); const AFuncDesc *afd; TArray<PType *> args; TArray<DWORD> argflags; afd = FindFunction(funcname); if (afd == NULL) { sc.ScriptMessage ("The function '%s' has not been exported from the executable.", funcname.GetChars()); FScriptPosition::ErrorCounter++; } sc.MustGetToken('('); SetImplicitArgs(&args, &argflags, cls, funcflags); ParseArgListDef(sc, cls, args, argflags); if (afd != NULL) { PFunction *sym = new PFunction(funcname); sym->AddVariant(NewPrototype(rets, args), argflags, *(afd->VMPointer)); sym->Flags = funcflags; if (cls->Symbols.AddSymbol(sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in class '%s'.", funcname.GetChars(), cls->TypeName.GetChars()); FScriptPosition::ErrorCounter++; } } }
void FTeam::ParseTeamInfo () { int iLump, iLastLump = 0; Teams.Clear(); while ((iLump = Wads.FindLump ("TEAMINFO", &iLastLump)) != -1) { FScanner Scan (iLump); while (Scan.GetString ()) { if (Scan.Compare ("ClearTeams")) ClearTeams (); else if (Scan.Compare ("Team")) ParseTeamDefinition (Scan); else Scan.ScriptError ("ParseTeamInfo: Unknown team command '%s'.\n", Scan.String); } } if (Teams.Size () < 2) I_FatalError ("ParseTeamInfo: At least two teams must be defined in TEAMINFO."); else if (Teams.Size () > (unsigned)TEAM_MAXIMUM) I_FatalError ("ParseTeamInfo: Too many teams defined. (Maximum: %d)", TEAM_MAXIMUM); }
//========================================================================== // // Processes a flag. Also used by olddecorations.cpp // //========================================================================== void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *part2, int mod) { FFlagDef *fd; if ( (fd = FindFlag (bag.Info, part1, part2)) ) { AActor *defaults = (AActor*)bag.Info->Defaults; if (fd->structoffset == -1) // this is a deprecated flag that has been changed into a real property { HandleDeprecatedFlags(defaults, bag.Info, mod=='+', fd->flagbit); } else { ModActorFlag(defaults, fd, mod == '+'); } } else { if (part2 == NULL) { sc.ScriptMessage("\"%s\" is an unknown flag\n", part1); } else { sc.ScriptMessage("\"%s.%s\" is an unknown flag\n", part1, part2); } FScriptPosition::ErrorCounter++; } }
static FString ParseMultiString(FScanner &scanner, int error) { FString build; if (scanner.CheckToken(TK_Identifier)) { if (!stricmp(scanner.String, "clear")) { return "-"; } else { scanner.ScriptError("Either 'clear' or string constant expected"); } } do { scanner.MustGetToken(TK_StringConst); if (build.Len() > 0) build += "\n"; build += scanner.String; } while (scanner.CheckToken(',')); return build; }
void FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, int usetype, bool missing) { int type; FTextureID framenum; DWORD min, max; type = FAnimDef::ANIM_Forward; framenum = ParseFramenum (sc, picnum, usetype, missing); ParseTime (sc, min, max); if (framenum == picnum || !picnum.Exists()) { return; // Animation is only one frame or does not exist } if (framenum < picnum) { type = FAnimDef::ANIM_Backward; Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals; swapvalues (framenum, picnum); } if (sc.GetString()) { if (sc.Compare ("Oscillate")) { type = type == FAnimDef::ANIM_Forward ? FAnimDef::ANIM_OscillateUp : FAnimDef::ANIM_OscillateDown; } else { sc.UnGet (); } } AddSimpleAnim (picnum, framenum - picnum + 1, type, min, max - min); }
void SetReplacement(FScanner &sc, FActorInfo *info, FName replaceName) { // Check for "replaces" if (replaceName != NAME_None) { // Get actor name const PClass *replacee = PClass::FindClass (replaceName); if (replacee == NULL) { sc.ScriptMessage("Replaced type '%s' not found for %s", replaceName.GetChars(), info->Class->TypeName.GetChars()); return; } else if (replacee->ActorInfo == NULL) { sc.ScriptMessage("Replaced type '%s' for %s is not an actor", replaceName.GetChars(), info->Class->TypeName.GetChars()); return; } if (replacee != NULL) { replacee->ActorInfo->Replacement = info; info->Replacee = replacee->ActorInfo; } } }
void SBarInfo::ParseMugShotBlock(FScanner &sc, FMugShotState &state) { sc.MustGetToken('{'); while(!sc.CheckToken('}')) { FMugShotFrame frame; bool multiframe = false; if(sc.CheckToken('{')) multiframe = true; do { sc.MustGetToken(TK_Identifier); if(strlen(sc.String) > 5) sc.ScriptError("MugShot frames cannot exceed 5 characters."); frame.Graphic.Push(sc.String); } while(multiframe && sc.CheckToken(',')); if(multiframe) sc.MustGetToken('}'); bool negative = sc.CheckToken('-'); sc.MustGetToken(TK_IntConst); frame.Delay = (negative ? -1 : 1)*sc.Number; sc.MustGetToken(';'); state.Frames.Push(frame); } }
void P_ParseAnimatedDoor(FScanner &sc) { const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; FDoorAnimation anim; TArray<FTextureID> frames; bool error = false; FTextureID v; sc.MustGetString(); anim.BaseTexture = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); if (!anim.BaseTexture.Exists()) { error = true; } while (sc.GetString ()) { if (sc.Compare ("opensound")) { sc.MustGetString (); anim.OpenSound = sc.String; } else if (sc.Compare ("closesound")) { sc.MustGetString (); anim.CloseSound = sc.String; } else if (sc.Compare ("pic")) { sc.MustGetString (); if (IsNum (sc.String)) { v = anim.BaseTexture + (atoi(sc.String) - 1); } else { v = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); if (!v.Exists() && anim.BaseTexture.Exists() && !error) { sc.ScriptError ("Unknown texture %s", sc.String); } frames.Push (v); } } else { sc.UnGet (); break; } } if (!error) { anim.TextureFrames = new FTextureID[frames.Size()]; memcpy (anim.TextureFrames, &frames[0], sizeof(FTextureID) * frames.Size()); anim.NumTextureFrames = frames.Size(); DoorAnimations.Push (anim); } }
//========================================================================== // // Reads an actor definition // //========================================================================== static void ParseActor(FScanner &sc) { PClassActor *info = NULL; Baggage bag; info = ParseActorHeader(sc, &bag); sc.MustGetToken('{'); while (sc.MustGetAnyToken(), sc.TokenType != '}') { switch (sc.TokenType) { case TK_Action: ParseActionDef (sc, info); break; case TK_Const: ParseConstant (sc, &info->Symbols, info); break; case TK_Enum: ParseEnum (sc, &info->Symbols, info); break; case TK_Native: ParseNativeFunction (sc, info); break; case TK_Var: ParseUserVariable (sc, &info->Symbols, info); break; case TK_Identifier: ParseActorProperty(sc, bag); break; case TK_States: if (bag.StateSet) { sc.ScriptMessage("'%s' contains multiple state declarations", bag.Info->TypeName.GetChars()); FScriptPosition::ErrorCounter++; } ParseStates(sc, bag.Info, (AActor *)bag.Info->Defaults, bag); bag.StateSet = true; break; case '+': case '-': ParseActorFlag(sc, bag, sc.TokenType); break; default: sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->TypeName.GetChars()); break; } } FinishActor(sc, info, bag); sc.SetCMode (false); }
static void ParseDamage (FScanner &sc, int keyword, void *fields) { FTerrainDef *def = (FTerrainDef *)fields; sc.MustGetString (); // Lava is synonymous with Fire here! if (sc.Compare("Lava")) def->DamageMOD=NAME_Fire; else def->DamageMOD=sc.String; }
static int ParseLumpName(FScanner &scanner, char *buffer) { scanner.MustGetToken(TK_StringConst); if (strlen(scanner.String) > 8) { scanner.ScriptError("String too long. Maximum size is 8 characters."); return 0; } uppercopy(buffer, scanner.String); return 1; }
static void SkipSubBlock(FScanner &sc) { sc.MustGetStringName("{"); int depth = 1; while (depth > 0) { sc.MustGetString(); if (sc.Compare("{")) depth++; if (sc.Compare("}")) depth--; } }
static int ParseMapEntry(FScanner &scanner, UMapEntry *val) { scanner.MustGetToken(TK_Identifier); val->MapName = scanner.String; scanner.MustGetToken('{'); while(!scanner.CheckToken('}')) { ParseStandardProperty(scanner, val); } return 1; }
//========================================================================== // // Parses a flag name // //========================================================================== static void ParseActorFlag (FScanner &sc, Baggage &bag, int mod) { sc.MustGetString (); FString part1 = sc.String; const char *part2 = NULL; if (sc.CheckString (".")) { sc.MustGetString (); part2 = sc.String; } HandleActorFlag(sc, bag, part1, part2, mod); }
int SBarInfo::getSignedInteger(FScanner &sc) { if(sc.CheckToken('-')) { sc.MustGetToken(TK_IntConst); return -sc.Number; } else { sc.MustGetToken(TK_IntConst); return sc.Number; } }
EColorRange GetTranslation(FScanner &sc) { if (!sc.CheckToken(TK_Null)) sc.MustGetToken(TK_Identifier); EColorRange returnVal = CR_UNTRANSLATED; FString namedTranslation; //we must send in "[translation]" const BYTE *trans_ptr; namedTranslation.Format("[%s]", sc.String); trans_ptr = (const BYTE *)(&namedTranslation[0]); if((returnVal = V_ParseFontColor(trans_ptr, CR_UNTRANSLATED, CR_UNTRANSLATED)) == CR_UNDEFINED) { sc.ScriptError("Missing definition for color %s.", sc.String); } return returnVal; }
static void ParseActionDef (FScanner &sc, PClassActor *cls) { unsigned int error = 0; FName funcname; TArray<PType *> rets; if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) { sc.ScriptMessage ("Action functions can only be imported by internal class and actor definitions!"); FScriptPosition::ErrorCounter++; } sc.MustGetToken(TK_Native); // check for a return value do { if (sc.CheckToken(TK_Int) || sc.CheckToken(TK_Bool)) { rets.Push(TypeSInt32); } else if (sc.CheckToken(TK_State)) { rets.Push(TypeState); } else if (sc.CheckToken(TK_Float)) { rets.Push(TypeFloat64); } } while (sc.CheckToken(',')); sc.MustGetToken(TK_Identifier); funcname = sc.String; ParseFunctionDef(sc, cls, funcname, rets, VARF_Method | VARF_Action); }
void MapLoader::InitED() { FString filename = Level->info->EDName; FScanner sc; if (filename.IsEmpty()) return; int lump = Wads.CheckNumForFullName(filename, true, ns_global); if (lump == -1) return; sc.OpenLumpNum(lump); sc.SetCMode(true); while (sc.GetString()) { if (sc.Compare("linedef")) { parseEDLinedef(sc, EDLines); } else if (sc.Compare("mapthing")) { parseMapthing(sc, EDThings); } else if (sc.Compare("sector")) { parseSector(sc, EDSectors); } else { sc.ScriptError("Unknown keyword '%s'", sc.String); } } }
static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClass *cls) { int currvalue = 0; sc.MustGetToken('{'); while (!sc.CheckToken('}')) { sc.MustGetToken(TK_Identifier); FName symname = sc.String; if (sc.CheckToken('=')) { FxExpression *expr = ParseExpression (sc, cls); currvalue = expr->EvalExpression(NULL).GetInt(); delete expr; } PSymbolConst *sym = new PSymbolConst(symname); sym->ValueType = VAL_Int; sym->Value = currvalue; if (symt->AddSymbol (sym) == NULL) { delete sym; sc.ScriptMessage ("'%s' is already defined in '%s'.", symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); FScriptPosition::ErrorCounter++; } // This allows a comma after the last value but doesn't enforce it. if (sc.CheckToken('}')) break; sc.MustGetToken(','); currvalue++; } sc.MustGetToken(';'); }
static void PSR_FindEndBlock(FScanner &sc) { int depth = 1; do { if(sc.CheckToken('}')) --depth; else if(sc.CheckToken('{')) ++depth; else sc.MustGetAnyToken(); } while(depth); }
static void ParseNativeFunction(FScanner &sc, PClassActor *cls) { TArray<PType *> rets(1); if (sc.LumpNum == -1 || Wads.GetLumpFile(sc.LumpNum) > 0) { sc.ScriptMessage ("functions can only be declared by native actors!"); FScriptPosition::ErrorCounter++; } // Read the type and make sure it's int or float. sc.MustGetAnyToken(); switch (sc.TokenType) { case TK_Int: case TK_Bool: rets.Push(TypeSInt32); break; case TK_Float: rets.Push(TypeFloat64); break; case TK_Angle_t: rets.Push(TypeAngle); break; case TK_Fixed_t: rets.Push(TypeFixed); break; case TK_State: rets.Push(TypeState); break; case TK_Identifier: rets.Push(NewPointer(RUNTIME_CLASS(DObject))); // Todo: Object type sc.ScriptError("Object type variables not implemented yet!"); break; default: sc.ScriptError("Invalid return type %s", sc.String); return; } sc.MustGetToken(TK_Identifier); ParseFunctionDef(sc, cls, sc.String, rets, VARF_Method); }
//========================================================================== // // Reads an actor definition // //========================================================================== static void ParseActor(FScanner &sc) { FActorInfo * info=NULL; Baggage bag; info = ParseActorHeader(sc, &bag); sc.MustGetToken('{'); while (sc.MustGetAnyToken(), sc.TokenType != '}') { switch (sc.TokenType) { case TK_Action: ParseActionDef (sc, info->Class); break; case TK_Const: ParseConstant (sc, &info->Class->Symbols, info->Class); break; case TK_Enum: ParseEnum (sc, &info->Class->Symbols, info->Class); break; case TK_Native: ParseNativeVariable (sc, &info->Class->Symbols, info->Class); break; case TK_Var: ParseUserVariable (sc, &info->Class->Symbols, info->Class); break; case TK_Identifier: ParseActorProperty(sc, bag); break; case '+': case '-': ParseActorFlag(sc, bag, sc.TokenType); break; default: sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->Class->TypeName.GetChars()); break; } } FinishActor(sc, info, bag); sc.SetCMode (false); }
static void ParseListMenu(FScanner &sc) { sc.MustGetString(); FListMenuDescriptor *desc = new FListMenuDescriptor; desc->mType = MDESC_ListMenu; desc->mMenuName = sc.String; desc->mSelectedItem = -1; desc->mAutoselect = -1; desc->mSelectOfsX = DefaultListMenuSettings.mSelectOfsX; desc->mSelectOfsY = DefaultListMenuSettings.mSelectOfsY; desc->mSelector = DefaultListMenuSettings.mSelector; desc->mDisplayTop = DefaultListMenuSettings.mDisplayTop; desc->mXpos = DefaultListMenuSettings.mXpos; desc->mYpos = DefaultListMenuSettings.mYpos; desc->mLinespacing = DefaultListMenuSettings.mLinespacing; desc->mNetgameMessage = DefaultListMenuSettings.mNetgameMessage; desc->mFont = DefaultListMenuSettings.mFont; desc->mFontColor = DefaultListMenuSettings.mFontColor; desc->mFontColor2 = DefaultListMenuSettings.mFontColor2; desc->mClass = NULL; desc->mRedirect = NULL; desc->mWLeft = 0; desc->mWRight = 0; desc->mCenter = false; ParseListMenuBody(sc, desc); bool scratch = ReplaceMenu(sc, desc); if (scratch) delete desc; }
//========================================================================== // // This is only here so any shader definition for ZDoomGL can be skipped // There is no functionality for this stuff! // //========================================================================== bool gl_ParseShader(FScanner &sc) { int ShaderDepth = 0; if (sc.GetString()) { char *tmp; tmp = strstr(sc.String, "{"); while (tmp) { ShaderDepth++; tmp++; tmp = strstr(tmp, "{"); } tmp = strstr(sc.String, "}"); while (tmp) { ShaderDepth--; tmp++; tmp = strstr(tmp, "}"); } if (ShaderDepth == 0) return true; } return false; }