CGPValue *CGPValue::Duplicate(CTextPool **textPool) { CGPValue *newValue; CGPObject *iterator; char *name; if (textPool) { name = (*textPool)->AllocText((char *)mName, true, textPool); } else { name = (char *)mName; } newValue = new CGPValue(name); iterator = mList; while(iterator) { if (textPool) { name = (*textPool)->AllocText((char *)iterator->GetName(), true, textPool); } else { name = (char *)iterator->GetName(); } newValue->AddValue(name); iterator = iterator->GetNext(); } return newValue; }
bool CGPGroup::Parse(char **dataPtr, CTextPool **textPool) { char *token; char lastToken[MAX_TOKEN_SIZE]; CGPGroup *newSubGroup; CGPValue *newPair; while(1) { token = GetToken(dataPtr, true); if (!token[0]) { // end of data - error! if (mParent) { return false; } else { break; } } else if (strcmpi(token, "}") == 0) { // ending brace for this group break; } strcpy(lastToken, token); // read ahead to see what we are doing token = GetToken(dataPtr, true, true); if (strcmpi(token, "{") == 0) { // new sub group newSubGroup = AddGroup(lastToken, textPool); newSubGroup->SetWriteable(mWriteable); if (!newSubGroup->Parse(dataPtr, textPool)) { return false; } } else if (strcmpi(token, "[") == 0) { // new pair list newPair = AddPair(lastToken, 0, textPool); if (!newPair->Parse(dataPtr, textPool)) { return false; } } else { // new pair AddPair(lastToken, token, textPool); } } return true; }
const char *CGPGroup::FindPairValue(const char *key, const char *defaultVal) { CGPValue *pair = FindPair(key); if (pair) { return pair->GetTopValue(); } return defaultVal; }
// (params should both be const, but GP1 has crap proto args) // static bool Skins_ParseThisFile(CGenericParser2 &SkinParser, /*const*/char *psSkinFileData, string &strThisModelBaseName, CGPGroup *&pFileGroup, CGPGroup *&pParseGroup_Prefs, LPCSTR psSkinFileName, G2SkinModelPrefs_t &G2SkinModelPrefs ) { bool bParseThisSkinFile = false; char *psDataPtr = psSkinFileData; if (SkinParser.Parse(&psDataPtr, true)) { pFileGroup = SkinParser.GetBaseParseGroup(); if (pFileGroup) { pParseGroup_Prefs = pFileGroup->FindSubGroup(sSKINKEYWORD_PREFS);//, true); if (pParseGroup_Prefs) { // see if our current model is amongst those that use this skin... // // look for a "models" field which says who uses this skin file... // CGPGroup *pParseGroup_ModelsUsing = pParseGroup_Prefs->FindSubGroup(sSKINKEYWORD_MODELSUSING); if (pParseGroup_ModelsUsing) { // ok, now search this subgroup for our model name... // for (CGPValue *pValue = pParseGroup_ModelsUsing->GetPairs(); pValue; pValue = pValue->GetNext()) { string str1 = pValue->GetName(); string str2 = pValue->GetTopValue(); if (str2 == strThisModelBaseName) { bParseThisSkinFile = true; //break; // do NOT stop scanning now } // record this model entry... // G2SkinModelPrefs[ psSkinFileName ][ str2 ] = 1; // any old junk, as long as we make an entry } } } } } else { ErrorBox(va("{} - Brace mismatch error in file \"%s\"!",psSkinFileName)); } return bParseThisSkinFile; }
int CGPGroup::GetNumPairs(void) { int count; CGPValue *pair; count = 0; pair = mPairs; while(pair) { count++; pair = (CGPValue *)pair->GetNext(); } return(count); }
CGPValue *CGPGroup::FindPair(const char *key) { CGPValue *pair = mPairs; while(pair) { if (strcmpi(pair->GetName(), key) == 0) { return pair; } pair = pair->GetNext(); } return 0; }
const char *CGPGroup::FindPairValue(const char *key, const char *defaultVal) { CGPValue *mPair = mPairs; while(mPair) { if (Q_strcmpi(mPair->GetName(), key) == 0) { return mPair->GetTopValue(); } mPair = (CGPValue *)mPair->GetNext(); } return defaultVal; }
void CGPGroup::Parse(char **dataPtr, CTextPool **textPool) { char *token; char lastToken[MAX_TOKEN_SIZE]; CGPGroup *newSubGroup; CGPValue *newPair; char *name, *value; while(1) { token = GetToken(dataPtr, true); if (!token[0]) { // end of data - error! break; } else if (Q_strcmpi(token, "}") == 0) { // ending brace for this group break; } strcpy(lastToken, token); // read ahead to see what we are doing token = GetToken(dataPtr, true, true); if (Q_strcmpi(token, "{") == 0) { // new sub group name = (*textPool)->AllocText(lastToken, true, textPool); newSubGroup = AddGroup(name); newSubGroup->SetWriteable(mWriteable); newSubGroup->Parse(dataPtr, textPool); } else if (Q_strcmpi(token, "[") == 0) { // new pair list name = (*textPool)->AllocText(lastToken, true, textPool); newPair = AddPair(name, 0); newPair->Parse(dataPtr, textPool); } else { // new pair name = (*textPool)->AllocText(lastToken, true, textPool); value = (*textPool)->AllocText(token, true, textPool); AddPair(name, value); } } }
bool CGPGroup::Write(CTextPool **textPool, int depth) { int i; CGPValue *mPair = mPairs; CGPGroup *mSubGroup = mSubGroups; if (depth >= 0) { for(i=0;i<depth;i++) { (*textPool)->AllocText("\t", false, textPool); } WriteText(textPool, mName); (*textPool)->AllocText("\r\n", false, textPool); for(i=0;i<depth;i++) { (*textPool)->AllocText("\t", false, textPool); } (*textPool)->AllocText("{\r\n", false, textPool); } while(mPair) { mPair->Write(textPool, depth+1); mPair = (CGPValue *)mPair->GetNext(); } while(mSubGroup) { mSubGroup->Write(textPool, depth+1); mSubGroup = (CGPGroup *)mSubGroup->GetNext(); } if (depth >= 0) { for(i=0;i<depth;i++) { (*textPool)->AllocText("\t", false, textPool); } (*textPool)->AllocText("}\r\n", false, textPool); } return true; }
//------------------------------------------------------ // ParseLength // Takes a length group and chomps out any pairs contained // in it. // // input: // the parse group to process // // return: // success of parse operation. //------------------------------------------------------ bool CPrimitiveTemplate::ParseLength( CGPGroup *grp ) { CGPValue *pairs; const char *key; const char *val; // Inside of the group, we should have a series of pairs pairs = grp->GetPairs(); while( pairs ) { // Let's get the key field key = pairs->GetName(); val = pairs->GetTopValue(); // Huge stricmp lists suxor if ( !stricmp( key, "start" )) { ParseLengthStart( val ); } else if ( !stricmp( key, "end" )) { ParseLengthEnd( val ); } else if ( !stricmp( key, "parm" ) || !stricmp( key, "parms" )) { ParseLengthParm( val ); } else if ( !stricmp( key, "flags" ) || !stricmp( key, "flag" )) { ParseLengthFlags( val ); } else { theFxHelper.Print( "Unknown key parsing a Length group: %s\n", key ); } pairs = (CGPValue *)pairs->GetNext(); } return true; }
/************************************************************************************************ * CGPGroup::FindPair * This function will search for the pair with the specified key name. Multiple keys may be * searched if you specify "||" inbetween each key name in the string. The first key to be * found (from left to right) will be returned. * * Input * key: the name of the key(s) to be searched for. * * Output / Return * the group belonging to the first key found or 0 if no group was found. * ************************************************************************************************/ CGPValue *CGPGroup::FindPair(const char *key) { CGPValue *pair; size_t length; const char *pos, *separator, *next; pos = key; while(pos[0]) { separator = strstr(pos, "||"); if (separator) { length = separator - pos; next = separator + 2; } else { length = strlen(pos); next = pos + length; } pair = mPairs; while(pair) { if (strlen(pair->GetName()) == length && Q_stricmpn(pair->GetName(), pos, length) == 0) { return pair; } pair = pair->GetNext(); } pos = next; } return 0; }
// Parse a primitive, apply defaults first, grab any base level // key pairs, then process any sub groups we may contain. //------------------------------------------------------ bool CPrimitiveTemplate::ParsePrimitive( CGPGroup *grp ) { CGPGroup *subGrp; CGPValue *pairs; const char *key; const char *val; // Lets work with the pairs first pairs = grp->GetPairs(); while( pairs ) { // the fields key = pairs->GetName(); val = pairs->GetTopValue(); // Huge stricmp lists suxor if ( !stricmp( key, "count" )) { ParseCount( val ); } else if ( !stricmp( key, "shaders" ) || !stricmp( key, "shader" )) { ParseShaders( pairs ); } else if ( !stricmp( key, "models" ) || !stricmp( key, "model" )) { ParseModels( pairs ); } else if ( !stricmp( key, "sounds" ) || !stricmp( key, "sound" )) { ParseSounds( pairs ); } else if ( !stricmp( key, "impactfx" )) { ParseImpactFxStrings( pairs ); } else if ( !stricmp( key, "deathfx" )) { ParseDeathFxStrings( pairs ); } else if ( !stricmp( key, "emitfx" )) { ParseEmitterFxStrings( pairs ); } else if ( !stricmp( key, "playfx" )) { ParsePlayFxStrings( pairs ); } else if ( !stricmp( key, "life" )) { ParseLife( val ); } else if ( !stricmp( key, "cullrange" )) { mCullRange = atoi( val ); mCullRange *= mCullRange; // Square } else if ( !stricmp( key, "delay" )) { ParseDelay( val ); } else if ( !stricmp( key, "bounce" ) || !stricmp( key, "intensity" )) // me==bad for reusing this...but it shouldn't hurt anything) { ParseElasticity( val ); } else if ( !stricmp( key, "min" )) { ParseMin( val ); } else if ( !stricmp( key, "max" )) { ParseMax( val ); } else if ( !stricmp( key, "angle" ) || !stricmp( key, "angles" )) { ParseAngle( val ); } else if ( !stricmp( key, "angleDelta" )) { ParseAngleDelta( val ); } else if ( !stricmp( key, "velocity" ) || !stricmp( key, "vel" )) { ParseVelocity( val ); } else if ( !stricmp( key, "acceleration" ) || !stricmp( key, "accel" )) { ParseAcceleration( val ); } else if ( !stricmp( key, "gravity" )) { ParseGravity( val ); } else if ( !stricmp( key, "density" )) { ParseDensity( val ); } else if ( !stricmp( key, "variance" )) { ParseVariance( val ); } else if ( !stricmp( key, "origin" )) { ParseOrigin1( val ); } else if ( !stricmp( key, "origin2" )) { ParseOrigin2( val ); } else if ( !stricmp( key, "radius" )) // part of ellipse/cylinder calcs. { ParseRadius( val ); } else if ( !stricmp( key, "height" )) // part of ellipse/cylinder calcs. { ParseHeight( val ); } else if ( !stricmp( key, "rotation" )) { ParseRotation( val ); } else if ( !Q_stricmp( key, "rotationDelta" )) { ParseRotationDelta( val ); } else if ( !stricmp( key, "flags" ) || !stricmp( key, "flag" )) { // these need to get passed on to the primitive ParseFlags( val ); } else if ( !stricmp( key, "spawnFlags" ) || !stricmp( key, "spawnFlag" )) { // these are used to spawn things in cool ways, but don't ever get passed on to prims. ParseSpawnFlags( val ); } else if ( !stricmp( key, "name" )) { if ( val ) { // just stash the descriptive name of the primitive strcpy( mName, val ); } } else { theFxHelper.Print( "Unknown key parsing an effect primitive: %s\n", key ); } pairs = (CGPValue *)pairs->GetNext(); } subGrp = grp->GetSubGroups(); // Lets chomp on the groups now while ( subGrp ) { key = subGrp->GetName(); if ( !stricmp( key, "rgb" )) { ParseRGB( subGrp ); } else if ( !stricmp( key, "alpha" )) { ParseAlpha( subGrp ); } else if ( !stricmp( key, "size" ) || !stricmp( key, "width" )) { ParseSize( subGrp ); } else if ( !stricmp( key, "size2" ) || !stricmp( key, "width2" )) { ParseSize2( subGrp ); } else if ( !stricmp( key, "length" ) || !stricmp( key, "height" )) { ParseLength( subGrp ); } else { theFxHelper.Print( "Unknown group key parsing a particle: %s\n", key ); } subGrp = (CGPGroup *)subGrp->GetNext(); } return true; }
static sboolean Music_ParseLeveldata(const char *psLevelName) { sboolean bReturn = qfalse; if (MusicData == NULL) { MusicData = new MusicData_t; } // already got this data? // if (MusicData->size() && !Q_stricmp(psLevelName,gsLevelNameForCompare.c_str())) { return qtrue; } MusicData->clear(); char sLevelName[MAX_QPATH]; Q_strncpyz(sLevelName,psLevelName,sizeof(sLevelName)); gsLevelNameForLoad = sLevelName; // harmless to init here even if we fail to parse dms.dat file gsLevelNameForCompare = sLevelName; // harmless to init here even if we fail to parse dms.dat file gsLevelNameForBossLoad = sLevelName; // harmless to init here even if we fail to parse dms.dat file char *pText = NULL; /*int iTotalBytesLoaded = */FS_ReadFile(sFILENAME_DMS, (void **)&pText ); if (pText) { char *psStrippedText = StripTrailingWhiteSpaceOnEveryLine(pText); CGenericParser2 Parser; char *psDataPtr = psStrippedText; // because ptr gets advanced, so we supply a clone that GP can alter if (Parser.Parse(&psDataPtr, true)) { CGPGroup *pFileGroup = Parser.GetBaseParseGroup(); if (pFileGroup) { CGPGroup *pgMusicFiles = pFileGroup->FindSubGroup(sKEY_MUSICFILES); if (pgMusicFiles) { CGPGroup *pgLevelMusic = pFileGroup->FindSubGroup(sKEY_LEVELMUSIC); if (pgLevelMusic) { CGPGroup *pgThisLevelMusic = NULL; // // check for new USE keyword... // int iSanityLimit = 0; sstring_t sSearchName(sLevelName); while (sSearchName.c_str()[0] && iSanityLimit < 10) { gsLevelNameForLoad = sSearchName; gsLevelNameForBossLoad = sSearchName; pgThisLevelMusic = pgLevelMusic->FindSubGroup(sSearchName.c_str()); if (pgThisLevelMusic) { CGPValue *pValue = pgThisLevelMusic->FindPair(sKEY_USES); if (pValue) { // re-search using the USE param... // sSearchName = pValue->GetTopValue(); iSanityLimit++; // Com_DPrintf("Using \"%s\"\n",sSearchName.c_str()); } else { // no new USE keyword found... // sSearchName = ""; } } else { // level entry not found... // break; } } // now go ahead and use the final music set we've decided on... // if (pgThisLevelMusic && iSanityLimit < 10) { // these are optional fields, so see which ones we find... // LPCSTR psName_Explore = NULL; LPCSTR psName_Action = NULL; LPCSTR psName_Boss = NULL; LPCSTR psName_Death = NULL; // LPCSTR psName_UseBoss = NULL; for (CGPValue *pValue = pgThisLevelMusic->GetPairs(); pValue; pValue = pValue->GetNext()) { LPCSTR psKey = pValue->GetName(); LPCSTR psValue = pValue->GetTopValue(); if (Q_stricmp(psValue,sKEY_PLACEHOLDER)) // ignore "placeholder" items { if (!Q_stricmp(psKey,sKEY_EXPLORE)) { psName_Explore = psValue; } else if (!Q_stricmp(psKey,sKEY_ACTION)) { psName_Action = psValue; } else if (!Q_stricmp(psKey,sKEY_USEBOSS)) { psName_UseBoss = psValue; } else if (!Q_stricmp(psKey,sKEY_BOSS)) { psName_Boss = psValue; } else if (!Q_stricmp(psKey,sKEY_DEATH)) { psName_Death = psValue; } } } bReturn = qtrue; // defualt to ON now, so I can turn it off if "useboss" fails if (psName_UseBoss) { CGPGroup *pgLevelMusicOfBoss = pgLevelMusic->FindSubGroup(psName_UseBoss); if (pgLevelMusicOfBoss) { CGPValue *pValueBoss = pgLevelMusicOfBoss->FindPair(sKEY_BOSS); if (pValueBoss) { psName_Boss = pValueBoss->GetTopValue(); gsLevelNameForBossLoad = psName_UseBoss; } else { MUSIC_PARSE_ERROR(va("'useboss' \"%s\" has no \"boss\" entry!\n",psName_UseBoss)); bReturn = qfalse; } } else { MUSIC_PARSE_ERROR(va("Unable to find 'useboss' entry \"%s\"\n",psName_UseBoss)); bReturn = qfalse; } } // done this way in case I want to conditionally pass any bools depending on music type... // if (bReturn && psName_Explore) { bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Explore, sKEY_EXPLORE, eBGRNDTRACK_EXPLORE); } if (bReturn && psName_Action) { bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Action, sKEY_ACTION, eBGRNDTRACK_ACTION); } if (bReturn && psName_Boss) { bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Boss, sKEY_BOSS, eBGRNDTRACK_BOSS); } if (bReturn /*&& psName_Death*/) // LAST MINUTE HACK!!, always force in some death music!!!! { //bReturn = Music_ParseMusic(Parser, MusicData, pgMusicFiles, psName_Death, sKEY_DEATH, eBGRNDTRACK_DEATH); MusicFile_t m; m.sFileNameBase = "death_music"; (*MusicData)[ sKEY_DEATH ] = m; } } else { MUSIC_PARSE_WARNING(va("Unable to find entry for \"%s\" in \"%s\"\n",sLevelName,sFILENAME_DMS)); } } else { MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\"\n",sKEY_LEVELMUSIC)); } } else { MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\"\n",sKEY_MUSICFILES)); } } else { MUSIC_PARSE_ERROR( "Error calling GP2.GetBaseParseGroup()\n" ); } } else { MUSIC_PARSE_ERROR( "Error using GP to parse file\n" ); } Z_Free(psStrippedText); FS_FreeFile( pText ); } else { MUSIC_PARSE_ERROR( "Unable to even read main file\n" ); // file name specified in error message } if (bReturn) { // sort exit points, and do some error checking... // for (MusicData_t::iterator itMusicData = MusicData->begin(); itMusicData != MusicData->end(); ++itMusicData) { LPCSTR psMusicStateType = (*itMusicData).first.c_str(); MusicFile_t &MusicFile = (*itMusicData).second; // kludge up an enum, only interested in boss or not at the moment, so... // MusicState_e eMusicState = !stricmp(psMusicStateType,"boss") ? eBGRNDTRACK_BOSS : !stricmp(psMusicStateType,"death") ? eBGRNDTRACK_DEATH : eBGRNDTRACK_EXPLORE; if (!MusicFile.MusicExitTimes.empty()) { sort(MusicFile.MusicExitTimes.begin(),MusicFile.MusicExitTimes.end()); } // check music exists... // LPCSTR psMusicFileName = Music_BuildFileName( MusicFile.sFileNameBase.c_str(), eMusicState ); if (!S_FileExists( psMusicFileName )) { MUSIC_PARSE_ERROR(va("Music file \"%s\" not found!\n",psMusicFileName)); return qfalse; // have to return, because music data destroyed now } // check all transition music pieces exist, and that entry points into new pieces after transitions also exist... // for (int iExitPoint=0; iExitPoint < MusicFile.MusicExitPoints.size(); iExitPoint++) { MusicExitPoint_t &MusicExitPoint = MusicFile.MusicExitPoints[ iExitPoint ]; LPCSTR psTransitionFileName = Music_BuildFileName( MusicExitPoint.sNextFile.c_str(), eMusicState ); if (!S_FileExists( psTransitionFileName )) { MUSIC_PARSE_ERROR(va("Transition file \"%s\" (entry \"%s\" ) not found!\n",psTransitionFileName, MusicExitPoint.sNextFile.c_str())); return qfalse; // have to return, because music data destroyed now } LPCSTR psNextMark = MusicExitPoint.sNextMark.c_str(); if (strlen(psNextMark)) // always NZ ptr { // then this must be "action" music under current rules... // assert( !strcmp(psMusicStateType, Music_BaseStateToString(eBGRNDTRACK_ACTION) ? Music_BaseStateToString(eBGRNDTRACK_ACTION):"") ); // // does this marker exist in the explore piece? // MusicData_t::iterator itExploreMusicData = MusicData->find( Music_BaseStateToString(eBGRNDTRACK_EXPLORE) ); if (itExploreMusicData != MusicData->end()) { MusicFile_t &MusicFile_Explore = (*itExploreMusicData).second; if (!MusicFile_Explore.MusicEntryTimes.count(psNextMark)) { MUSIC_PARSE_ERROR( va("Unable to find entry point \"%s\" in description for \"%s\"\n",psNextMark,MusicFile_Explore.sFileNameBase.c_str()) ); return qfalse; // have to return, because music data destroyed now } } else { MUSIC_PARSE_ERROR( va("Unable to find %s piece to match \"%s\"\n", Music_BaseStateToString(eBGRNDTRACK_EXPLORE), MusicFile.sFileNameBase.c_str() ) ); return qfalse; // have to return, because music data destroyed now } } } } } #ifdef _DEBUG /* // dump the whole thing out to prove it was read in ok... // if (bReturn) { for (MusicData_t::iterator itMusicData = MusicData->begin(); itMusicData != MusicData->end(); ++itMusicData) { LPCSTR psMusicState = (*itMusicData).first.c_str(); MusicFile_t &MusicFile = (*itMusicData).second; OutputDebugString(va("Music State: \"%s\", File: \"%s\"\n",psMusicState, MusicFile.sFileNameBase.c_str())); // entry times... // for (MusicEntryTimes_t::iterator itEntryTimes = MusicFile.MusicEntryTimes.begin(); itEntryTimes != MusicFile.MusicEntryTimes.end(); ++itEntryTimes) { LPCSTR psMarkerName = (*itEntryTimes).first.c_str(); float fEntryTime = (*itEntryTimes).second; OutputDebugString(va("Entry time for \"%s\": %f\n", psMarkerName, fEntryTime)); } // exit points... // for (int i=0; i<MusicFile.MusicExitPoints.size(); i++) { MusicExitPoint_t &MusicExitPoint = MusicFile.MusicExitPoints[i]; OutputDebugString(va("Exit point %d: sNextFile: \"%s\", sNextMark: \"%s\"\n",i,MusicExitPoint.sNextFile.c_str(),MusicExitPoint.sNextMark.c_str())); } // exit times... // for (i=0; i<MusicFile.MusicExitTimes.size(); i++) { MusicExitTime_t &MusicExitTime = MusicFile.MusicExitTimes[i]; OutputDebugString(va("Exit time %d: fTime: %f, iExitPoint: %d\n",i,MusicExitTime.fTime,MusicExitTime.iExitPoint)); } } } */ #endif return bReturn; }
static sboolean Music_ParseMusic(CGenericParser2 &Parser, MusicData_t *MusicData, CGPGroup *pgMusicFiles, LPCSTR psMusicName, LPCSTR psMusicNameKey, MusicState_e eMusicState) { sboolean bReturn = qfalse; #ifdef _XBOX Z_SetNewDeleteTemporary(true); #endif MusicFile_t MusicFile; #ifdef _XBOX Z_SetNewDeleteTemporary(false); #endif CGPGroup *pgMusicFile = pgMusicFiles->FindSubGroup(psMusicName); if (pgMusicFile) { // read subgroups... // sboolean bEntryFound = qfalse; sboolean bExitFound = qfalse; // // (read entry points first, so I can check exit points aren't too close in time) // CGPGroup *pEntryGroup = pgMusicFile->FindSubGroup(sKEY_ENTRY); if (pEntryGroup) { // read entry points... // for (CGPValue *pValue = pEntryGroup->GetPairs(); pValue; pValue = pValue->GetNext()) { LPCSTR psKey = pValue->GetName(); LPCSTR psValue = pValue->GetTopValue(); //if (!strncmp(psKey,sKEY_MARKER,strlen(sKEY_MARKER))) // for now, assume anything is a marker { MusicFile.MusicEntryTimes[psKey] = atof(psValue); bEntryFound = qtrue; // harmless to keep setting } } } for (CGPGroup *pGroup = pgMusicFile->GetSubGroups(); pGroup; pGroup = pGroup->GetNext()) { LPCSTR psGroupName = pGroup->GetName(); if (!strcmp(psGroupName,sKEY_ENTRY)) { // skip entry points, I've already read them in above // } else if (!strcmp(psGroupName,sKEY_EXIT)) { int iThisExitPointIndex = MusicFile.MusicExitPoints.size(); // must eval this first, so unaffected by push_back etc // // read this set of exit points... // MusicExitPoint_t MusicExitPoint; for (CGPValue *pValue = pGroup->GetPairs(); pValue; pValue = pValue->GetNext()) { LPCSTR psKey = pValue->GetName(); LPCSTR psValue = pValue->GetTopValue(); if (!strcmp(psKey,sKEY_NEXTFILE)) { MusicExitPoint.sNextFile = psValue; bExitFound = qtrue; // harmless to keep setting } else if (!strcmp(psKey,sKEY_NEXTMARK)) { MusicExitPoint.sNextMark = psValue; } else if (!strncmp(psKey,sKEY_TIME,strlen(sKEY_TIME))) { MusicExitTime_t MusicExitTime; MusicExitTime.fTime = atof(psValue); MusicExitTime.iExitPoint= iThisExitPointIndex; // new check, don't keep this this exit point if it's within 1.5 seconds either way of an entry point... // sboolean bTooCloseToEntryPoint = qfalse; for (MusicEntryTimes_t::iterator itEntryTimes = MusicFile.MusicEntryTimes.begin(); itEntryTimes != MusicFile.MusicEntryTimes.end(); ++itEntryTimes) { float fThisEntryTime = (*itEntryTimes).second; if (Q_fabs(fThisEntryTime - MusicExitTime.fTime) < 1.5f) { // bTooCloseToEntryPoint = qtrue; // not sure about this, ignore for now break; } } if (!bTooCloseToEntryPoint) { #ifdef _XBOX Z_SetNewDeleteTemporary(true); #endif MusicFile.MusicExitTimes.push_back(MusicExitTime); #ifdef _XBOX Z_SetNewDeleteTemporary(false); #endif } } } #ifdef _XBOX Z_SetNewDeleteTemporary(true); #endif MusicFile.MusicExitPoints.push_back(MusicExitPoint); #ifdef _XBOX Z_SetNewDeleteTemporary(false); #endif int iNumExitPoints = MusicFile.MusicExitPoints.size(); // error checking... // switch (eMusicState) { case eBGRNDTRACK_EXPLORE: if (iNumExitPoints > iMAX_EXPLORE_TRANSITIONS) { MUSIC_PARSE_ERROR( va("\"%s\" has > %d %s transitions defined!\n",psMusicName,iMAX_EXPLORE_TRANSITIONS,psMusicNameKey) ); return qfalse; } break; case eBGRNDTRACK_ACTION: if (iNumExitPoints > iMAX_ACTION_TRANSITIONS) { MUSIC_PARSE_ERROR( va("\"%s\" has > %d %s transitions defined!\n",psMusicName,iMAX_ACTION_TRANSITIONS,psMusicNameKey) ); return qfalse; } break; case eBGRNDTRACK_BOSS: case eBGRNDTRACK_DEATH: MUSIC_PARSE_ERROR( va("\"%s\" has %s transitions defined, this is not allowed!\n",psMusicName,psMusicNameKey) ); break; } } } // for now, assume everything was ok unless some obvious things are missing... // bReturn = qtrue; if (eMusicState != eBGRNDTRACK_BOSS && eMusicState != eBGRNDTRACK_DEATH) // boss & death pieces can omit entry/exit stuff { if (!bEntryFound) { MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\" in group \"%s\"\n",sKEY_ENTRY,psMusicName)); bReturn = qfalse; } if (!bExitFound) { MUSIC_PARSE_ERROR(va("Unable to find subgroup \"%s\" in group \"%s\"\n",sKEY_EXIT,psMusicName)); bReturn = qfalse; } } } else { MUSIC_PARSE_ERROR(va("Unable to find musicfiles entry \"%s\"\n",psMusicName)); } if (bReturn) { MusicFile.sFileNameBase = psMusicName; (*MusicData)[ psMusicNameKey ] = MusicFile; } return bReturn; }
void CRMLandScape::LoadMiscentDef(const char *td) { char miscentDef[MAX_QPATH]; CGenericParser2 parse; CGPGroup *basegroup, *classes, *items, *model; CGPValue *pair; Com_sprintf(miscentDef, MAX_QPATH, "ext_data/RMG/%s.miscents", Info_ValueForKey(td, "miscentDef")); Com_DPrintf("CG_Terrain: Loading and parsing miscentDef %s.....\n", Info_ValueForKey(td, "miscentDef")); if(!Com_ParseTextFile(miscentDef, parse)) { Com_sprintf(miscentDef, MAX_QPATH, "ext_data/arioche/%s.miscents", Info_ValueForKey(td, "miscentDef")); if(!Com_ParseTextFile(miscentDef, parse)) { Com_Printf("Could not open %s\n", miscentDef); return; } } // The whole file.... basegroup = parse.GetBaseParseGroup(); // The root { } struct classes = basegroup->GetSubGroups(); while(classes) { items = classes->GetSubGroups(); while(items) { if(!stricmp(items->GetName(), "miscent")) { int height, maxheight; // Height must exist - the rest are optional height = atol(items->FindPairValue("height", "0")); maxheight = atol(items->FindPairValue("maxheight", "255")); model = items->GetSubGroups(); while(model) { if(!stricmp(model->GetName(), "model")) { CRandomModel hd; // Set defaults hd.SetModel(""); hd.SetFrequency(1.0f); hd.SetMinScale(1.0f); hd.SetMaxScale(1.0f); pair = model->GetPairs(); while(pair) { if(!stricmp(pair->GetName(), "name")) { hd.SetModel(pair->GetTopValue()); } else if(!stricmp(pair->GetName(), "frequency")) { hd.SetFrequency((float)atof(pair->GetTopValue())); } else if(!stricmp(pair->GetName(), "minscale")) { hd.SetMinScale((float)atof(pair->GetTopValue())); } else if(!stricmp(pair->GetName(), "maxscale")) { hd.SetMaxScale((float)atof(pair->GetTopValue())); } pair = (CGPValue *)pair->GetNext(); } AddModel(height, maxheight, &hd); } model = (CGPGroup *)model->GetNext(); } } items = (CGPGroup *)items->GetNext(); } classes = (CGPGroup *)classes->GetNext(); } Com_ParseTextFileDestroy(parse); }
static LPCSTR Skins_Parse(string strThisSkinFileName, CGPGroup *pFileGroup, CGPGroup *pParseGroup_Prefs) { LPCSTR psError = NULL; // read any optional surface on/off blocks... // for (int iSurfaceOnOffType = 0; iSurfaceOnOffType<3; iSurfaceOnOffType++) { CGPGroup *pSurfaceParseGroup = NULL; switch (iSurfaceOnOffType) { case 0: pSurfaceParseGroup = pParseGroup_Prefs->FindSubGroup(sSKINKEYWORD_SURFACES_ON); break; case 1: pSurfaceParseGroup = pParseGroup_Prefs->FindSubGroup(sSKINKEYWORD_SURFACES_OFF); break; case 2: pSurfaceParseGroup = pParseGroup_Prefs->FindSubGroup(sSKINKEYWORD_SURFACES_OFFNOCHILDREN); break; default: assert(0); break; } if (pSurfaceParseGroup) { CGPValue *pValue = pSurfaceParseGroup->GetPairs(); while (pValue) { // string str1 = (*it).first; // junk, eg "name1" string str2 = pValue->GetTopValue(); switch (iSurfaceOnOffType) { case 0: CurrentSkinsSurfacePrefs[strThisSkinFileName].vSurfacesOn.push_back(str2); break; case 1: CurrentSkinsSurfacePrefs[strThisSkinFileName].vSurfacesOff.push_back(str2); break; case 2: CurrentSkinsSurfacePrefs[strThisSkinFileName].vSurfacesOffNoChildren.push_back(str2); break; default: assert(0); break; } pValue = pValue->GetNext(); } } } // find all the materials and add them to the skin set... // int iMaterialDeclarationIndex = 0; for (CGPGroup *pMaterialGroup = pFileGroup->GetSubGroups(); pMaterialGroup; pMaterialGroup = pMaterialGroup->GetNext(), iMaterialDeclarationIndex++) { string strKeyWord = pMaterialGroup->GetName(); if (strKeyWord == sSKINKEYWORD_MATERIAL) { string strMaterialName(pMaterialGroup->FindPairValue(sSKINKEYWORD_NAME,"")); if (strMaterialName == "") { psError = va("%s[%d] had no \"%s\" field!\n",sSKINKEYWORD_MATERIAL, iMaterialDeclarationIndex, sSKINKEYWORD_NAME); return psError; } // now iterate through the ethnic group variants of this material... // int iEthnicGroupIndex = 0; for (CGPGroup *pEthnicGroup = pMaterialGroup->GetSubGroups(); pEthnicGroup; pEthnicGroup = pEthnicGroup->GetNext(), iEthnicGroupIndex++) { strKeyWord = pEthnicGroup->GetName(); if (strKeyWord == sSKINKEYWORD_GROUP) { string strEthnicGroupName(pEthnicGroup->FindPairValue(sSKINKEYWORD_NAME,"")); if (strEthnicGroupName == "") { psError = va("%s[%d] %s[%d] had no \"%s\" field!\n",sSKINKEYWORD_MATERIAL, iMaterialDeclarationIndex, sSKINKEYWORD_GROUP, iEthnicGroupIndex, sSKINKEYWORD_NAME); return psError; } // now iterate through the shader variants for this ethnic version of this material... (is anyone reading this...?) // int iAlternateShaderIndex = 0; for (CGPValue *pValue = pEthnicGroup->GetPairs(); pValue; pValue = pValue->GetNext()) { string strField(pValue->GetName()); if (strField != sSKINKEYWORD_NAME) { // ... then it should be a shader... // string strShader(pValue->GetTopValue()); CurrentSkins[strThisSkinFileName][strEthnicGroupName][strMaterialName].push_back(strShader); } } } } } } return psError; }