// // SC_MustGetFloat // void SC_MustGetFloat (void) { if (SC_GetFloat() == false) { SC_ScriptError ("Missing floating-point number (unexpected end of file)."); } }
void SC_MustGetFloat() { if (SC_GetFloat() == false) { SC_ScriptError("Missing float."); } }
void SC_MustGetString() { if (SC_GetString() == false) { SC_ScriptError("Missing string."); } }
void SC_MustGetNumber() { if (SC_GetNumber() == false) { SC_ScriptError("Missing integer."); } }
void gl_ParseSkybox() { int facecount=0; SC_MustGetString(); FSkyBox * sb = new FSkyBox; uppercopy(sb->Name, sc_String); sb->Name[8]=0; SC_MustGetStringName("{"); while (!SC_CheckString("}")) { SC_MustGetString(); if (facecount<6) { sb->faces[facecount] = TexMan[TexMan.GetTexture(sc_String, FTexture::TEX_Wall, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_Overridable)]; } facecount++; } if (facecount != 3 && facecount != 6) { SC_ScriptError("%s: Skybox definition requires either 3 or 6 faces", sb->Name); } sb->SetSize(); TexMan.AddTexture(sb); FGLTexture * gltex = FGLTexture::ValidateTexture(sb); gltex->bSkybox=true; }
BOOL SC_GetNumber (void) { char *stopper; CheckOpen (); if (SC_GetString()) { if (strcmp (sc_String, "MAXINT") == 0) { sc_Number = INT_MAX; } else { sc_Number = strtol (sc_String, &stopper, 0); if (*stopper != 0) { SC_ScriptError ("SC_GetNumber: Bad numeric constant \"%s\".", sc_String); } } sc_Float = (float)sc_Number; return true; } else { return false; } }
// // SC_MustGetNumber // void SC_MustGetNumber (void) { if (SC_GetNumber() == false) { SC_ScriptError ("Missing integer (unexpected end of file)."); } }
// // SC_MustGetString // void SC_MustGetString (void) { if (SC_GetString () == false) { SC_ScriptError ("Missing string (unexpected end of file)."); } }
//========================================================================== // // For getting a state address from the parent // No attempts have been made to add new functionality here // This is strictly for keeping compatibility with old WADs! // //========================================================================== FState *CheckState(PClass *type) { int v=0; if (SC_GetString() && !sc_Crossed) { if (SC_Compare("0")) return NULL; else if (SC_Compare("PARENT")) { FState * state = NULL; SC_MustGetString(); FActorInfo * info = type->ParentClass->ActorInfo; if (info != NULL) { state = info->FindState(FName(sc_String)); } if (SC_GetString ()) { if (SC_Compare ("+")) { SC_MustGetNumber (); v = sc_Number; } else { SC_UnGet (); } } if (state == NULL && v==0) return NULL; if (v!=0 && state==NULL) { SC_ScriptError("Attempt to get invalid state from actor %s\n", type->ParentClass->TypeName.GetChars()); return NULL; } state+=v; return state; } else SC_ScriptError("Invalid state assignment"); } return NULL; }
void SC_MustGetStringName(const char *name) { SC_MustGetString(); if (SC_Compare(name) == false) { SC_ScriptError(NULL); } }
void SC_MustGetString(void) { if (!SC_GetString()) SC_ScriptError("Missing string."); if (SC_Compare("=")) SC_GetString(); }
void SC_MustGetStringName (const char *name) { SC_MustGetString (); if (SC_Compare (name) == false) { SC_ScriptError ("Expected '%s', got '%s'.", name, sc_String); } }
// // SC_MustGetStringName // void SC_MustGetStringName (const char *name) { SC_MustGetString (); if (SC_Compare (name) == false) { const char *args[2]; args[0] = name; args[1] = sc_String; SC_ScriptError ("Expected '%s', got '%s'.", args); } }
// // SC_MustMatchString // int SC_MustMatchString (const char **strings) { int i; i = SC_MatchString (strings); if (i == -1) { SC_ScriptError (NULL); } return i; }
//========================================================================== // // DoActionSpecials // handles action specials as code pointers // //========================================================================== bool DoActionSpecials(FState & state, bool multistate, int * statecount, Baggage &bag) { int i; const ACSspecials *spec; if ((spec = is_special (sc_String, sc_StringLen)) != NULL) { int paramindex=PrepareStateParameters(&state, 6); StateParameters[paramindex]=spec->Special; // Make this consistent with all other parameter parsing if (SC_CheckToken('(')) { for (i = 0; i < 5;) { StateParameters[paramindex+i+1]=ParseExpression (false, bag.Info->Class); i++; if (!SC_CheckToken (',')) break; } SC_MustGetToken (')'); } else i=0; if (i < spec->MinArgs) { SC_ScriptError ("Too few arguments to %s", spec->name); } if (i > MAX (spec->MinArgs, spec->MaxArgs)) { SC_ScriptError ("Too many arguments to %s", spec->name); } state.Action = A_CallSpecial; return true; } return false; }
static int GetSoundOffset(char *name) { int i; for(i = 0; i < NUMSFX; i++) { if(!strcasecmp(name, S_sfx[i].tagName)) { return i; } } SC_ScriptError("GetSoundOffset: Unknown sound name\n"); return 0; }
void ParseSplash () { int splashnum; FSplashDef *splashdef; bool isnew = false; SC_MustGetString (); splashnum = (int)FindSplash (sc_String); if (splashnum < 0) { FSplashDef def; def.Name = copystring (sc_String); splashnum = (int)Splashes.Push (def); isnew = true; } splashdef = &Splashes[splashnum]; SC_MustGetString (); if (!SC_Compare ("modify") || (SC_MustGetString(), isnew)) { // Set defaults splashdef->SmallSplashSound = splashdef->NormalSplashSound = 0; splashdef->SmallSplash = splashdef->SplashBase = splashdef->SplashChunk = NULL; splashdef->ChunkXVelShift = splashdef->ChunkYVelShift = splashdef->ChunkZVelShift = 8; splashdef->ChunkBaseZVel = FRACUNIT; splashdef->SmallSplashClip = 12*FRACUNIT; splashdef->NoAlert = false; } if (!SC_Compare ("{")) { SC_ScriptError ("Expected {"); } else { GenericParse (SplashParser, SplashKeywords, splashdef, "splash", splashdef->Name); } }
void ParseTerrain () { int terrainnum; const char *name; SC_MustGetString (); terrainnum = (int)FindTerrain (sc_String); if (terrainnum < 0) { FTerrainDef def; memset (&def, 0, sizeof(def)); def.Splash = -1; def.Name = copystring (sc_String); terrainnum = (int)Terrains.Push (def); } // Set defaults SC_MustGetString (); if (!SC_Compare ("modify")) { name = Terrains[terrainnum].Name; memset (&Terrains[terrainnum], 0, sizeof(FTerrainDef)); Terrains[terrainnum].Splash = -1; Terrains[terrainnum].Name = name; } else { SC_MustGetString (); } if (SC_Compare ("{")) { GenericParse (TerrainParser, TerrainKeywords, &Terrains[terrainnum], "terrain", Terrains[terrainnum].Name); } else { SC_ScriptError ("Expected {"); } }
void SN_InitSequenceScript(void) { int i, j; int inSequence; int *tempDataStart; int *tempDataPtr; inSequence = -1; ActiveSequences = 0; for(i = 0; i < SS_MAX_SCRIPTS; i++) { SequenceData[i] = NULL; } SC_Open(SS_SCRIPT_NAME); while(SC_GetString()) { if(*sc_String == ':') { if(inSequence != -1) { SC_ScriptError("SN_InitSequenceScript: Nested Script Error"); } tempDataStart = (int *)Z_Malloc(SS_TEMPBUFFER_SIZE, PU_STATIC, NULL); memset(tempDataStart, 0, SS_TEMPBUFFER_SIZE); tempDataPtr = tempDataStart; for(i = 0; i < SS_MAX_SCRIPTS; i++) { if(SequenceData[i] == NULL) { break; } } if(i == SS_MAX_SCRIPTS) { I_Error("Number of SS Scripts >= SS_MAX_SCRIPTS"); } for(j = 0; j < SEQ_NUMSEQ; j++) { if(!strcasecmp(SequenceTranslate[j].name, sc_String+1)) { SequenceTranslate[j].scriptNum = i; inSequence = j; break; } } continue; // parse the next command } if(inSequence == -1) { continue; } if(SC_Compare(SS_STRING_PLAYUNTILDONE)) { VerifySequencePtr(tempDataStart, tempDataPtr); SC_MustGetString(); *tempDataPtr++ = SS_CMD_PLAY; *tempDataPtr++ = GetSoundOffset(sc_String); *tempDataPtr++ = SS_CMD_WAITUNTILDONE; } else if(SC_Compare(SS_STRING_PLAY)) { VerifySequencePtr(tempDataStart, tempDataPtr); SC_MustGetString(); *tempDataPtr++ = SS_CMD_PLAY; *tempDataPtr++ = GetSoundOffset(sc_String); } else if(SC_Compare(SS_STRING_PLAYTIME)) { VerifySequencePtr(tempDataStart, tempDataPtr); SC_MustGetString(); *tempDataPtr++ = SS_CMD_PLAY; *tempDataPtr++ = GetSoundOffset(sc_String); SC_MustGetNumber(); *tempDataPtr++ = SS_CMD_DELAY; *tempDataPtr++ = sc_Number; } else if(SC_Compare(SS_STRING_PLAYREPEAT)) { VerifySequencePtr(tempDataStart, tempDataPtr); SC_MustGetString(); *tempDataPtr++ = SS_CMD_PLAYREPEAT; *tempDataPtr++ = GetSoundOffset(sc_String); } else if(SC_Compare(SS_STRING_DELAY)) { VerifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_DELAY; SC_MustGetNumber(); *tempDataPtr++ = sc_Number; } else if(SC_Compare(SS_STRING_DELAYRAND)) { VerifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_DELAYRAND; SC_MustGetNumber(); *tempDataPtr++ = sc_Number; SC_MustGetNumber(); *tempDataPtr++ = sc_Number; } else if(SC_Compare(SS_STRING_VOLUME)) { VerifySequencePtr(tempDataStart, tempDataPtr); *tempDataPtr++ = SS_CMD_VOLUME; SC_MustGetNumber(); *tempDataPtr++ = sc_Number; } else if(SC_Compare(SS_STRING_END)) { int dataSize; *tempDataPtr++ = SS_CMD_END; dataSize = (tempDataPtr-tempDataStart)*sizeof(int); SequenceData[i] = (int *)Z_Malloc(dataSize, PU_STATIC, NULL); memcpy(SequenceData[i], tempDataStart, dataSize); Z_Free(tempDataStart); inSequence = -1; } else if(SC_Compare(SS_STRING_STOPSOUND)) { SC_MustGetString(); SequenceTranslate[inSequence].stopSound = GetSoundOffset(sc_String); *tempDataPtr++ = SS_CMD_STOPSOUND; } else { SC_ScriptError("SN_InitSequenceScript: Unknown commmand.\n"); } } }
void P_InitFTAnims(void) { int base; boolean ignore; boolean done; int AnimDefCount = 0; int groupNumber, picBase; int type, index; SC_Open(ANIM_SCRIPT_NAME); while(SC_GetString()) { if(AnimDefCount == MAX_ANIM_DEFS) { Con_Error("P_InitFTAnims: too many AnimDefs."); } if(SC_Compare(SCI_FLAT)) { type = ANIM_FLAT; } else if(SC_Compare(SCI_TEXTURE)) { type = ANIM_TEXTURE; } else { SC_ScriptError(NULL); } SC_MustGetString(); // Name ignore = false; if(type == ANIM_FLAT) { if(W_CheckNumForName(sc_String) == -1) { ignore = true; } else { picBase = R_FlatNumForName(sc_String); groupNumber = R_CreateAnimGroup(DD_FLAT, AGF_SMOOTH | AGF_FIRST_ONLY); } } else { // Texture if(R_CheckTextureNumForName(sc_String) == -1) { ignore = true; } else { picBase = R_TextureNumForName(sc_String); groupNumber = R_CreateAnimGroup(DD_TEXTURE, AGF_SMOOTH | AGF_FIRST_ONLY); } } done = false; while(done == false) { if(SC_GetString()) { if(SC_Compare(SCI_PIC)) { SC_MustGetNumber(); if(ignore == false) { index = picBase + sc_Number - 1; } SC_MustGetString(); if(SC_Compare(SCI_TICS)) { SC_MustGetNumber(); if(ignore == false) { R_AddToAnimGroup(groupNumber, index, sc_Number, 0); } } else if(SC_Compare(SCI_RAND)) { SC_MustGetNumber(); base = sc_Number; SC_MustGetNumber(); if(ignore == false) { R_AddToAnimGroup(groupNumber, index, base, sc_Number - base); } } else { SC_ScriptError(NULL); } } else { SC_UnGet(); done = true; } } else { done = true; } } } SC_Close(); }
static void ParseOuter () { int bracedepth = 0; bool ifskip = false; while (SC_GetString ()) { if (ifskip) { if (bracedepth > 0) { if (SC_Compare ("}")) { bracedepth--; continue; } } else if (SC_Compare ("endif")) { ifskip = false; continue; } if (SC_Compare ("{")) { bracedepth++; } else if (SC_Compare ("}")) { SC_ScriptError ("Too many left braces ('}')"); } } else { switch (SC_MustMatchString (OuterKeywords)) { case OUT_SPLASH: ParseSplash (); break; case OUT_TERRAIN: ParseTerrain (); break; case OUT_FLOOR: ParseFloor (); break; case OUT_IFDOOM: if (gameinfo.gametype != GAME_Doom) { ifskip = true; } break; case OUT_IFHERETIC: if (gameinfo.gametype != GAME_Heretic) { ifskip = true; } break; case OUT_IFHEXEN: if (gameinfo.gametype != GAME_Hexen) { ifskip = true; } break; case OUT_IFSTRIFE: if (gameinfo.gametype != GAME_Strife) { ifskip = true; } break; case OUT_ENDIF: break; } } } }
//========================================================================== // // ParseStates // parses a state block // //========================================================================== int ParseStates(FActorInfo * actor, AActor * defaults, Baggage &bag) { FString statestring; intptr_t count = 0; FState state; FState * laststate = NULL; intptr_t lastlabel = -1; int minrequiredstate = -1; SC_MustGetStringName ("{"); SC_SetEscape(false); // disable escape sequences in the state parser while (!SC_CheckString ("}") && !sc_End) { memset(&state,0,sizeof(state)); statestring = ParseStateString(); if (!statestring.CompareNoCase("GOTO")) { do_goto: statestring = ParseStateString(); if (SC_CheckString ("+")) { SC_MustGetNumber (); statestring += '+'; statestring += sc_String; } // copy the text - this must be resolved later! if (laststate != NULL) { // Following a state definition: Modify it. laststate->NextState = (FState*)copystring(statestring); } else if (lastlabel >= 0) { // Following a label: Retarget it. RetargetStates (count+1, statestring); } else { SC_ScriptError("GOTO before first state"); } } else if (!statestring.CompareNoCase("STOP")) { do_stop: if (laststate!=NULL) { laststate->NextState=(FState*)-1; } else if (lastlabel >=0) { RetargetStates (count+1, NULL); } else { SC_ScriptError("STOP before first state"); continue; } } else if (!statestring.CompareNoCase("WAIT") || !statestring.CompareNoCase("FAIL")) { if (!laststate) { SC_ScriptError("%s before first state", sc_String); continue; } laststate->NextState=(FState*)-2; } else if (!statestring.CompareNoCase("LOOP")) { if (!laststate) { SC_ScriptError("LOOP before first state"); continue; } laststate->NextState=(FState*)(lastlabel+1); } else { const char * statestrp; SC_MustGetString(); if (SC_Compare (":")) { laststate = NULL; do { lastlabel = count; AddState(statestring, (FState *) (count+1)); statestring = ParseStateString(); if (!statestring.CompareNoCase("GOTO")) { goto do_goto; } else if (!statestring.CompareNoCase("STOP")) { goto do_stop; } SC_MustGetString (); } while (SC_Compare (":")); // continue; } SC_UnGet (); if (statestring.Len() != 4) { SC_ScriptError ("Sprite names must be exactly 4 characters\n"); } memcpy(state.sprite.name, statestring, 4); state.Misc1=state.Misc2=0; state.ParameterIndex=0; SC_MustGetString(); statestring = (sc_String+1); statestrp = statestring; state.Frame=(*sc_String&223)-'A'; if ((*sc_String&223)<'A' || (*sc_String&223)>']') { SC_ScriptError ("Frames must be A-Z, [, \\, or ]"); state.Frame=0; } SC_MustGetNumber(); sc_Number++; state.Tics=sc_Number&255; state.Misc1=(sc_Number>>8)&255; if (state.Misc1) state.Frame|=SF_BIGTIC; while (SC_GetString() && !sc_Crossed) { if (SC_Compare("BRIGHT")) { state.Frame|=SF_FULLBRIGHT; continue; } if (SC_Compare("OFFSET")) { if (state.Frame&SF_BIGTIC) { SC_ScriptError("You cannot use OFFSET with a state duration larger than 254!"); } // specify a weapon offset SC_MustGetStringName("("); SC_MustGetNumber(); state.Misc1=sc_Number; SC_MustGetStringName (","); SC_MustGetNumber(); state.Misc2=sc_Number; SC_MustGetStringName(")"); continue; } // Make the action name lowercase to satisfy the gperf hashers strlwr (sc_String); int minreq=count; if (DoActionSpecials(state, !statestring.IsEmpty(), &minreq, bag)) { if (minreq>minrequiredstate) minrequiredstate=minreq; goto endofstate; } PSymbol *sym = bag.Info->Class->Symbols.FindSymbol (FName(sc_String, true), true); if (sym != NULL && sym->SymbolType == SYM_ActionFunction) { PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym); state.Action = afd->Function; if (!afd->Arguments.IsEmpty()) { const char *params = afd->Arguments.GetChars(); int numparams = (int)afd->Arguments.Len(); int v; if (!islower(*params)) { SC_MustGetStringName("("); } else { if (!SC_CheckString("(")) goto endofstate; } int paramindex = PrepareStateParameters(&state, numparams); int paramstart = paramindex; bool varargs = params[numparams - 1] == '+'; if (varargs) { StateParameters[paramindex++] = 0; } while (*params) { switch(*params) { case 'I': case 'i': // Integer SC_MustGetNumber(); v=sc_Number; break; case 'F': case 'f': // Fixed point SC_MustGetFloat(); v=fixed_t(sc_Float*FRACUNIT); break; case 'S': case 's': // Sound name SC_MustGetString(); v=S_FindSound(sc_String); break; case 'M': case 'm': // Actor name case 'T': case 't': // String SC_SetEscape(true); SC_MustGetString(); SC_SetEscape(false); v = (int)(sc_String[0] ? FName(sc_String) : NAME_None); break; case 'L': case 'l': // Jump label if (SC_CheckNumber()) { if (strlen(statestring)>0) { SC_ScriptError("You cannot use A_Jump commands with a jump index on multistate definitions\n"); } v=sc_Number; if (v<1) { SC_ScriptError("Negative jump offsets are not allowed"); } { int minreq=count+v; if (minreq>minrequiredstate) minrequiredstate=minreq; } } else { if (JumpParameters.Size()==0) JumpParameters.Push(NAME_None); v = -(int)JumpParameters.Size(); // This forces quotation marks around the state name. SC_MustGetToken(TK_StringConst); FString statestring = sc_String; // ParseStateString(); const PClass *stype=NULL; int scope = statestring.IndexOf("::"); if (scope >= 0) { FName scopename = FName(statestring, scope, false); if (scopename == NAME_Super) { // Super refers to the direct superclass scopename = actor->Class->ParentClass->TypeName; } JumpParameters.Push(scopename); statestring = statestring.Right(statestring.Len()-scope-2); stype = PClass::FindClass (scopename); if (stype == NULL) { SC_ScriptError ("%s is an unknown class.", scopename.GetChars()); } if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor))) { SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars()); } if (!stype->IsAncestorOf (actor->Class)) { SC_ScriptError ("%s is not derived from %s so cannot access its states.", actor->Class->TypeName.GetChars(), stype->TypeName.GetChars()); } } else { // No class name is stored. This allows 'virtual' jumps to // labels in subclasses. // It also means that the validity of the given state cannot // be checked here. JumpParameters.Push(NAME_None); } TArray<FName> names; MakeStateNameList(statestring, &names); if (stype != NULL) { if (!stype->ActorInfo->FindState(names.Size(), &names[0])) { SC_ScriptError("Jump to unknown state '%s' in class '%s'", statestring.GetChars(), stype->TypeName.GetChars()); } } JumpParameters.Push((ENamedName)names.Size()); for(unsigned i=0;i<names.Size();i++) { JumpParameters.Push(names[i]); } // No offsets here. The point of jumping to labels is to avoid such things! } break; case 'C': case 'c': // Color SC_MustGetString (); if (SC_Compare("none")) { v = -1; } else { int c = V_GetColor (NULL, sc_String); // 0 needs to be the default so we have to mark the color. v = MAKEARGB(1, RPART(c), GPART(c), BPART(c)); } break; case 'X': case 'x': v = ParseExpression (false, bag.Info->Class); break; case 'Y': case 'y': v = ParseExpression (true, bag.Info->Class); break; default: assert(false); v = -1; break; } StateParameters[paramindex++] = v; params++; if (varargs) { StateParameters[paramstart]++; } if (*params) { if (*params == '+') { if (SC_CheckString(")")) { goto endofstate; } params--; v = 0; StateParameters.Push(v); } else if ((islower(*params) || *params=='!') && SC_CheckString(")")) { goto endofstate; } SC_MustGetStringName (","); } } SC_MustGetStringName(")"); } else { SC_MustGetString(); if (SC_Compare("(")) { SC_ScriptError("You cannot pass parameters to '%s'\n",sc_String); } SC_UnGet(); } goto endofstate; } SC_ScriptError("Invalid state parameter %s\n", sc_String); } SC_UnGet(); endofstate: StateArray.Push(state); while (*statestrp) { int frame=((*statestrp++)&223)-'A'; if (frame<0 || frame>28) { SC_ScriptError ("Frames must be A-Z, [, \\, or ]"); frame=0; } state.Frame=(state.Frame&(SF_FULLBRIGHT|SF_BIGTIC))|frame; StateArray.Push(state); count++; } laststate=&StateArray[count]; count++; } } if (count<=minrequiredstate) { SC_ScriptError("A_Jump offset out of range in %s", actor->Class->TypeName.GetChars()); } SC_SetEscape(true); // re-enable escape sequences return count; }
void SC_MustGetNumber(void) { if (!SC_GetNumber()) SC_ScriptError("Missing integer."); }
static FState *ResolveGotoLabel (AActor *actor, const PClass *mytype, char *name) { const PClass *type=mytype; FState *state; char *namestart = name; char *label, *offset, *pt; int v; // Check for classname if ((pt = strstr (name, "::")) != NULL) { const char *classname = name; *pt = '\0'; name = pt + 2; // The classname may either be "Super" to identify this class's immediate // superclass, or it may be the name of any class that this one derives from. if (stricmp (classname, "Super") == 0) { type = type->ParentClass; actor = GetDefaultByType (type); } else { // first check whether a state of the desired name exists const PClass *stype = PClass::FindClass (classname); if (stype == NULL) { SC_ScriptError ("%s is an unknown class.", classname); } if (!stype->IsDescendantOf (RUNTIME_CLASS(AActor))) { SC_ScriptError ("%s is not an actor class, so it has no states.", stype->TypeName.GetChars()); } if (!stype->IsAncestorOf (type)) { SC_ScriptError ("%s is not derived from %s so cannot access its states.", type->TypeName.GetChars(), stype->TypeName.GetChars()); } if (type != stype) { type = stype; actor = GetDefaultByType (type); } } } label = name; // Check for offset offset = NULL; if ((pt = strchr (name, '+')) != NULL) { *pt = '\0'; offset = pt + 1; } v = offset ? strtol (offset, NULL, 0) : 0; // Get the state's address. if (type==mytype) state = FindState (actor, type, label); else state = FindStateInClass (actor, type, label); if (state != NULL) { state += v; } else if (v != 0) { SC_ScriptError ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars()); } delete[] namestart; // free the allocated string buffer return state; }
static void InitMapInfo(void) { int map; int mapMax; int mcmdValue; mapInfo_t *info; char songMulch[10]; mapMax = 1; // Put defaults into MapInfo[0] info = MapInfo; info->cluster = 0; info->warpTrans = 0; info->nextMap = 1; // Always go to map 1 if not specified info->cdTrack = 1; info->sky1Texture = R_TextureNumForName(DEFAULT_SKY_NAME); info->sky2Texture = info->sky1Texture; info->sky1ScrollDelta = 0; info->sky2ScrollDelta = 0; info->doubleSky = false; info->lightning = false; info->fadetable = W_GetNumForName(DEFAULT_FADE_TABLE); strcpy(info->name, UNKNOWN_MAP_NAME); // strcpy(info->songLump, DEFAULT_SONG_LUMP); SC_Open(MAPINFO_SCRIPT_NAME); while (SC_GetString()) { if (SC_Compare("MAP") == false) { SC_ScriptError(NULL); } SC_MustGetNumber(); if (sc_Number < 1 || sc_Number > 99) { // SC_ScriptError(NULL); } map = sc_Number; info = &MapInfo[map]; // Save song lump name strcpy(songMulch, info->songLump); // Copy defaults to current map definition memcpy(info, &MapInfo[0], sizeof(*info)); // Restore song lump name strcpy(info->songLump, songMulch); // The warp translation defaults to the map number info->warpTrans = map; // Map name must follow the number SC_MustGetString(); strcpy(info->name, sc_String); // Process optional tokens while (SC_GetString()) { if (SC_Compare("MAP")) { // Start next map definition SC_UnGet(); break; } mcmdValue = MapCmdIDs[SC_MustMatchString(MapCmdNames)]; switch (mcmdValue) { case MCMD_CLUSTER: SC_MustGetNumber(); info->cluster = sc_Number; break; case MCMD_WARPTRANS: SC_MustGetNumber(); info->warpTrans = sc_Number; break; case MCMD_NEXT: SC_MustGetNumber(); info->nextMap = sc_Number; break; case MCMD_CDTRACK: SC_MustGetNumber(); info->cdTrack = sc_Number; break; case MCMD_SKY1: SC_MustGetString(); info->sky1Texture = R_TextureNumForName(sc_String); SC_MustGetNumber(); info->sky1ScrollDelta = sc_Number << 8; break; case MCMD_SKY2: SC_MustGetString(); info->sky2Texture = R_TextureNumForName(sc_String); SC_MustGetNumber(); info->sky2ScrollDelta = sc_Number << 8; break; case MCMD_DOUBLESKY: info->doubleSky = true; break; case MCMD_LIGHTNING: info->lightning = true; break; case MCMD_FADETABLE: SC_MustGetString(); info->fadetable = W_GetNumForName(sc_String); break; case MCMD_CD_STARTTRACK: case MCMD_CD_END1TRACK: case MCMD_CD_END2TRACK: case MCMD_CD_END3TRACK: case MCMD_CD_INTERTRACK: case MCMD_CD_TITLETRACK: SC_MustGetNumber(); cd_NonLevelTracks[mcmdValue - MCMD_CD_STARTTRACK] = sc_Number; break; } } mapMax = map > mapMax ? map : mapMax; } SC_Close(); MapCount = mapMax; }
// // TextureManager::readAnimDefLump // // [RH] This uses a Hexen ANIMDEFS lump to define the animation sequences. // void TextureManager::readAnimDefLump() { int lump = -1; while ((lump = W_FindLump("ANIMDEFS", lump)) != -1) { SC_OpenLumpNum(lump, "ANIMDEFS"); while (SC_GetString()) { if (SC_Compare("flat") || SC_Compare("texture")) { anim_t anim; Texture::TextureSourceType texture_type = Texture::TEX_WALLTEXTURE; if (SC_Compare("flat")) texture_type = Texture::TEX_FLAT; SC_MustGetString(); anim.basepic = texturemanager.getHandle(sc_String, texture_type); anim.curframe = 0; anim.numframes = 0; memset(anim.speedmin, 1, anim_t::MAX_ANIM_FRAMES * sizeof(*anim.speedmin)); memset(anim.speedmax, 1, anim_t::MAX_ANIM_FRAMES * sizeof(*anim.speedmax)); while (SC_GetString()) { if (!SC_Compare("pic")) { SC_UnGet(); break; } if ((unsigned)anim.numframes == anim_t::MAX_ANIM_FRAMES) SC_ScriptError ("Animation has too many frames"); byte min = 1, max = 1; SC_MustGetNumber(); int frame = sc_Number; SC_MustGetString(); if (SC_Compare("tics")) { SC_MustGetNumber(); sc_Number = clamp(sc_Number, 0, 255); min = max = sc_Number; } else if (SC_Compare("rand")) { SC_MustGetNumber(); min = MAX(sc_Number, 0); SC_MustGetNumber(); max = MIN(sc_Number, 255); if (min > max) min = max = 1; } else { SC_ScriptError ("Must specify a duration for animation frame"); } anim.speedmin[anim.numframes] = min; anim.speedmax[anim.numframes] = max; anim.framepic[anim.numframes] = frame + anim.basepic - 1; anim.numframes++; } anim.countdown = anim.speedmin[0]; if (anim.basepic != TextureManager::NOT_FOUND_TEXTURE_HANDLE && anim.basepic != TextureManager::NO_TEXTURE_HANDLE) mAnimDefs.push_back(anim); } else if (SC_Compare ("switch")) // Don't support switchdef yet... { //P_ProcessSwitchDef (); SC_ScriptError("switchdef not supported."); } else if (SC_Compare("warp")) { SC_MustGetString(); if (SC_Compare("flat") || SC_Compare("texture")) { Texture::TextureSourceType texture_type = Texture::TEX_WALLTEXTURE; if (SC_Compare("flat")) texture_type = Texture::TEX_FLAT; SC_MustGetString(); texhandle_t texhandle = texturemanager.getHandle(sc_String, texture_type); if (texhandle == TextureManager::NOT_FOUND_TEXTURE_HANDLE || texhandle == TextureManager::NO_TEXTURE_HANDLE) continue; warp_t warp; // backup the original texture warp.original_texture = getTexture(texhandle); int width = 1 << warp.original_texture->getWidthBits(); int height = 1 << warp.original_texture->getHeightBits(); // create a new texture of the same size for the warped image warp.warped_texture = createTexture(texhandle, width, height); mWarpDefs.push_back(warp); } else { SC_ScriptError(NULL, NULL); } } } SC_Close (); } }