//========================================================================== // // 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; }
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; }
static void ParseMapInfoLower (MapInfoHandler *handlers, const char *strings[], level_pwad_info_t *levelinfo, cluster_info_t *clusterinfo, DWORD flags) { int entry; MapInfoHandler *handler; byte *info; info = levelinfo ? (byte *)levelinfo : (byte *)clusterinfo; while (SC_GetString ()) { if (SC_MatchString (MapInfoTopLevel) != -1) { SC_UnGet (); break; } entry = SC_MustMatchString (strings); handler = handlers + entry; switch (handler->type) { case MITYPE_IGNORE: break; case MITYPE_EATNEXT: SC_MustGetString (); break; case MITYPE_INT: SC_MustGetNumber (); *((int *)(info + handler->data1)) = sc_Number; break; case MITYPE_FLOAT: SC_MustGetFloat (); *((float *)(info + handler->data1)) = sc_Float; break; case MITYPE_COLOR: { SC_MustGetString (); std::string string = V_GetColorStringByName (sc_String); if (string.length()) { *((DWORD *)(info + handler->data1)) = V_GetColorFromString (NULL, string.c_str()); } else { *((DWORD *)(info + handler->data1)) = V_GetColorFromString (NULL, sc_String); } } break; case MITYPE_MAPNAME: SC_MustGetString (); if (IsNum (sc_String)) { int map = atoi (sc_String); sprintf (sc_String, "MAP%02d", map); } strncpy ((char *)(info + handler->data1), sc_String, 8); break; case MITYPE_LUMPNAME: SC_MustGetString (); uppercopy ((char *)(info + handler->data1), sc_String); break; case MITYPE_SKY: SC_MustGetString (); // get texture name; uppercopy ((char *)(info + handler->data1), sc_String); SC_MustGetFloat (); // get scroll speed //if (HexenHack) //{ // *((fixed_t *)(info + handler->data2)) = sc_Number << 8; //} //else //{ // *((fixed_t *)(info + handler->data2)) = (fixed_t)(sc_Float * 65536.0f); //} break; case MITYPE_SETFLAG: flags |= handler->data1; break; case MITYPE_SCFLAGS: flags = (flags & handler->data2) | handler->data1; break; case MITYPE_CLUSTER: SC_MustGetNumber (); *((int *)(info + handler->data1)) = sc_Number; if (HexenHack) { cluster_info_t *clusterH = FindClusterInfo (sc_Number); if (clusterH) clusterH->flags |= CLUSTER_HUB; } break; case MITYPE_STRING: SC_MustGetString (); ReplaceString ((const char **)(info + handler->data1), sc_String); break; case MITYPE_CSTRING: SC_MustGetString (); strncpy ((char *)(info + handler->data1), sc_String, handler->data2); *((char *)(info + handler->data1 + handler->data2)) = '\0'; break; } } if (levelinfo) levelinfo->flags = flags; else clusterinfo->flags = flags; }
// // G_ParseMapInfo // Parses the MAPINFO lumps of all loaded WADs and generates // data for wadlevelinfos and wadclusterinfos. // void G_ParseMapInfo (void) { int lump, lastlump = 0; level_pwad_info_t defaultinfo; level_pwad_info_t *levelinfo; int levelindex; cluster_info_t *clusterinfo; int clusterindex; DWORD levelflags; while ((lump = W_FindLump ("MAPINFO", &lastlump)) != -1) { SetLevelDefaults (&defaultinfo); SC_OpenLumpNum (lump, "MAPINFO"); while (SC_GetString ()) { switch (SC_MustMatchString (MapInfoTopLevel)) { case MITL_DEFAULTMAP: SetLevelDefaults (&defaultinfo); ParseMapInfoLower (MapHandlers, MapInfoMapLevel, &defaultinfo, NULL, 0); break; case MITL_MAP: // map <MAPNAME> <Nice Name> levelflags = defaultinfo.flags; SC_MustGetString (); if (IsNum (sc_String)) { // MAPNAME is a number, assume a Hexen wad int map = atoi (sc_String); sprintf (sc_String, "MAP%02d", map); SKYFLATNAME[5] = 0; HexenHack = true; // Hexen levels are automatically nointermission // and even lighting and no auto sound sequences levelflags |= LEVEL_NOINTERMISSION | LEVEL_EVENLIGHTING | LEVEL_SNDSEQTOTALCTRL; } levelindex = FindWadLevelInfo (sc_String); if (levelindex == -1) { levelindex = numwadlevelinfos++; wadlevelinfos = (level_pwad_info_t *)Realloc (wadlevelinfos, sizeof(level_pwad_info_t)*numwadlevelinfos); } levelinfo = wadlevelinfos + levelindex; memcpy (levelinfo, &defaultinfo, sizeof(*levelinfo)); uppercopy (levelinfo->mapname, sc_String); SC_MustGetString (); ReplaceString (&levelinfo->level_name, sc_String); // Set up levelnum now so that the Teleport_NewMap specials // in hexen.wad work without modification. if (!strnicmp (levelinfo->mapname, "MAP", 3) && levelinfo->mapname[5] == 0) { int mapnum = atoi (levelinfo->mapname + 3); if (mapnum >= 1 && mapnum <= 99) levelinfo->levelnum = mapnum; } ParseMapInfoLower (MapHandlers, MapInfoMapLevel, levelinfo, NULL, levelflags); break; case MITL_CLUSTERDEF: // clusterdef <clusternum> SC_MustGetNumber (); clusterindex = FindWadClusterInfo (sc_Number); if (clusterindex == -1) { clusterindex = numwadclusterinfos++; wadclusterinfos = (cluster_info_t *)Realloc (wadclusterinfos, sizeof(cluster_info_t)*numwadclusterinfos); memset (wadclusterinfos + clusterindex, 0, sizeof(cluster_info_t)); } clusterinfo = wadclusterinfos + clusterindex; clusterinfo->cluster = sc_Number; ParseMapInfoLower (ClusterHandlers, MapInfoClusterLevel, NULL, clusterinfo, 0); break; } } SC_Close (); } }
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 GenericParse (FGenericParse *parser, const char **keywords, void *fields, const char *type, const char *name) { bool notdone = true; int keyword; int val; const TypeInfo *info; do { SC_MustGetString (); keyword = SC_MustMatchString (keywords); switch (parser[keyword].Type) { case GEN_End: notdone = false; break; case GEN_Fixed: SC_MustGetFloat (); SET_FIELD (fixed_t, (fixed_t)(FRACUNIT * sc_Float)); break; case GEN_Sound: SC_MustGetString (); val = S_FindSound (sc_String); SET_FIELD (int, val); if (val == 0) { Printf ("Unknown sound %s in %s %s\n", sc_String, type, name); } break; case GEN_Byte: SC_MustGetNumber (); SET_FIELD (byte, sc_Number); break; case GEN_Class: SC_MustGetString (); if (SC_Compare ("None")) { info = NULL; } else { info = TypeInfo::IFindType (sc_String); if (!info->IsDescendantOf (RUNTIME_CLASS(AActor))) { Printf ("%s is not an Actor (in %s %s)\n", sc_String, type, name); info = NULL; } else if (info == NULL) { Printf ("Unknown actor %s in %s %s\n", sc_String, type, name); } } SET_FIELD (const TypeInfo *, info); break; case GEN_Splash: SC_MustGetString (); val = FindSplash (sc_String); SET_FIELD (int, val); if (val == -1) { Printf ("Splash %s is not defined yet (in %s %s)\n", sc_String, type, name); } break; case GEN_Float: SC_MustGetFloat (); SET_FIELD (float, sc_Float); break; case GEN_Time: SC_MustGetFloat (); SET_FIELD (int, (int)(sc_Float * TICRATE)); break; case GEN_Bool: SET_FIELD (bool, true); break; case GEN_Int: SC_MustGetNumber (); SET_FIELD (int, sc_Number); break; case GEN_Custom: parser[keyword].u.Handler (keyword, fields); break; } } while (notdone); }
//========================================================================== // // 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; }
// // 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 (); } }