void RageFileManager::GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDirs, bool bReturnPathToo ) { LockMut( *g_Mutex ); NormalizePath( sPath ); for( unsigned i = 0; i < g_Drivers.size(); ++i ) { LoadedDriver &ld = g_Drivers[i]; const CString p = ld.GetPath( sPath ); if( p.size() == 0 ) continue; const unsigned OldStart = AddTo.size(); g_Drivers[i].driver->GetDirListing( p, AddTo, bOnlyDirs, bReturnPathToo ); /* If returning the path, prepend the mountpoint name to the files this driver returned. */ if( bReturnPathToo ) for( unsigned j = OldStart; j < AddTo.size(); ++j ) AddTo[j] = ld.MountPoint + AddTo[j]; } /* More than one driver might return the same file. Remove duplicates (case- * insensitively). */ sort( AddTo.begin(), AddTo.end(), ilt ); CStringArray::iterator it = unique( AddTo.begin(), AddTo.end(), ieq ); AddTo.erase(it, AddTo.end()); }
void AnnouncerManager::GetAnnouncerNames( CStringArray& AddTo ) { GetDirListing( ANNOUNCERS_DIR+"*", AddTo, true ); // strip out the folder called "CVS" and EMPTY_ANNOUNCER_NAME for( int i=AddTo.size()-1; i>=0; i-- ) if( !stricmp( AddTo[i], "cvs" ) ) AddTo.erase(AddTo.begin()+i, AddTo.begin()+i+1 ); for( int i=AddTo.size()-1; i>=0; i-- ) if( !stricmp( AddTo[i], EMPTY_ANNOUNCER_NAME ) ) AddTo.erase(AddTo.begin()+i, AddTo.begin()+i+1 ); }
bool RandomSample::LoadSoundDir( CString sDir, int iMaxToLoad ) { if( sDir == "" ) return true; #if 0 /* (don't want to do this just yet) */ /* If this is actually a directory, add a backslash to the filename, * so we'll look for eg. themes\Default\sounds\sDir\*.mp3. Otherwise, * don't, so we'll look for all of the files starting with sDir, * eg. themes\Default\sounds\sDir*.mp3. */ if(IsADirectory(sDir) && sDir[sDir.GetLength()-1] != "/" ) sDir += "/"; #else // make sure there's a slash at the end of this path if( sDir.Right(1) != "/" ) sDir += "/"; #endif CStringArray arraySoundFiles; GetDirListing( sDir + "*.mp3", arraySoundFiles ); GetDirListing( sDir + "*.ogg", arraySoundFiles ); GetDirListing( sDir + "*.wav", arraySoundFiles ); random_shuffle( arraySoundFiles.begin(), arraySoundFiles.end() ); arraySoundFiles.resize( min( arraySoundFiles.size(), (unsigned)iMaxToLoad ) ); for( unsigned i=0; i<arraySoundFiles.size(); i++ ) LoadSound( sDir + arraySoundFiles[i] ); return true; }
//---------------------------------------- void wxBratTools::CStringArrayToWxArray(CStringArray& from, wxArrayString& to) { CStringArray::iterator it; for (it = from.begin() ; it != from.end() ; it++) { to.Add((*it).c_str()); } }
void RageFileManager::MountInitialFilesystems() { /* Add file search paths, higher priority first. */ #if defined(XBOX) RageFileManager::Mount( "dir", "D:\\", "" ); #elif defined(LINUX) /* Absolute paths. This is rarely used, eg. by Alsa9Buf::GetSoundCardDebugInfo(). * All paths that start with a slash (eg. "/proc") should use this, so put it * first. */ RageFileManager::Mount( "dir", "/", "/" ); /* We can almost do this, to have machine profiles be system-global to eg. share * scores. It would need to handle permissions properly. */ /* RageFileManager::Mount( "dir", "/var/lib/games/stepmania", "Data/Profiles" ); */ // CString Home = getenv( "HOME" ) + "/" + PRODUCT_NAME; /* * Next: path to write general mutable user data. If the above path fails (eg. * wrong permissions, doesn't exist), machine memcard data will also go in here. * XXX: It seems silly to have two ~ directories. If we're going to create a * directory on our own, it seems like it should be a dot directory, but it * seems wrong to put lots of data (eg. music) in one. Hmm. */ /* XXX: create */ /* RageFileManager::Mount( "dir", Home + "." PRODUCT_NAME, "Data" ); */ /* Next, search ~/StepMania. This is where users can put music, themes, etc. */ /* RageFileManager::Mount( "dir", Home + PRODUCT_NAME, "" ); */ /* Search for a directory with "Songs" in it. Be careful: the CWD is likely to * be ~, and it's possible that some users will have a ~/Songs/ directory that * has nothing to do with us, so check the initial directory last. */ CString Root = ""; struct stat st; if( Root == "" && !stat( DirOfExecutable + "/Songs", &st ) && st.st_mode&S_IFDIR ) Root = DirOfExecutable; if( Root == "" && !stat( InitialWorkingDirectory + "/Songs", &st ) && st.st_mode&S_IFDIR ) Root = InitialWorkingDirectory; if( Root == "" ) RageException::Throw( "Couldn't find \"Songs\"" ); RageFileManager::Mount( "dir", Root, "" ); #elif defined(_WINDOWS) /* All Windows data goes in the directory one level above the executable. */ CHECKPOINT_M( ssprintf( "DOE \"%s\"", DirOfExecutable.c_str()) ); CStringArray parts; split( DirOfExecutable, "/", parts ); CHECKPOINT_M( ssprintf( "... %i parts", parts.size()) ); ASSERT_M( parts.size() > 1, ssprintf("Strange DirOfExecutable: %s", DirOfExecutable.c_str()) ); CString Dir = join( "/", parts.begin(), parts.end()-1 ); RageFileManager::Mount( "dir", Dir, "" ); #else /* Paths relative to the CWD: */ RageFileManager::Mount( "dir", ".", "" ); #endif }
void KSFLoader::LoadTags( const CString &str, Song &out ) { /* str is either a #TITLE or a directory component. Fill in missing information. * str is either "title", "artist - title", or "artist - title - difficulty". */ CStringArray asBits; split( str, " - ", asBits, false ); /* Ignore the difficulty, since we get that elsewhere. */ if( asBits.size() == 3 && (!stricmp(asBits[2], "double") || !stricmp(asBits[2], "easy") || !stricmp(asBits[2], "normal") || !stricmp(asBits[2], "hard") || !stricmp(asBits[2], "crazy")) ) { asBits.erase(asBits.begin()+2, asBits.begin()+3); } CString title, artist; if( asBits.size() == 2 ) { artist = asBits[0]; title = asBits[1]; } else { title = asBits[0]; } /* Convert, if possible. Most KSFs are in Korean encodings (CP942/EUC-KR). */ if( !ConvertString( title, "korean" ) ) title = ""; if( !ConvertString( artist, "korean" ) ) artist = ""; if( out.m_sMainTitle == "" ) out.m_sMainTitle = title; if( out.m_sArtist == "" ) out.m_sArtist = artist; }
float HHMMSSToSeconds( const CString &sHHMMSS ) { CStringArray arrayBits; split( sHHMMSS, ":", arrayBits, false ); while( arrayBits.size() < 3 ) arrayBits.insert(arrayBits.begin(), "0" ); // pad missing bits float fSeconds = 0; fSeconds += atoi( arrayBits[0] ) * 60 * 60; fSeconds += atoi( arrayBits[1] ) * 60; fSeconds += strtof( arrayBits[2], NULL ); return fSeconds; }
//---------------------------------------- void CExternalFilesAvisoGrid::CheckVariables() { CStringArray varNames; CStringArray::iterator index; m_file.GetVariables(varNames); for (index=varNames.begin(); index != varNames.end(); index++) { if (*index == CExternalFilesAvisoGrid::m_INTERNAL_LAT_DIM_NAME) continue; if (*index == CExternalFilesAvisoGrid::m_INTERNAL_LON_DIM_NAME) continue; if (*index == CExternalFilesAvisoGrid::m_INTERNAL_DEPTH_DIM_NAME) continue; if (*index == CExternalFilesAvisoGrid::m_LATLONMIN_NAME) continue; if (*index == CExternalFilesAvisoGrid::m_LATLONSTEP_NAME) continue; if (*index == CExternalFilesAvisoGrid::m_INTERNAL_LATLON_DIM_NAME) continue; AddVar(*index); } }
//---------------------------------------- void CPlot::GetInfo() { CUnit unitXRead; CUnit unitYRead; string unitXStr; string unitYStr; bool assignYUnit = true; bool assignYTitle = true; bool assignXUnit = true; bool assignXTitle = true; CObArray allInternalFiles(false); GetAllInternalFiles(allInternalFiles); int32_t nrFiles = allInternalFiles.size(); //int32_t iField = 0; int32_t nrFields = m_fields.size(); CObArray::iterator itField; CObArray::iterator itFile; CStringArray plotFieldNames; for (itField = m_fields.begin() ; itField != m_fields.end() ; itField++) { CPlotField* field = CPlotField::GetPlotField(*itField); string fieldName = (const char *)(field->m_name); plotFieldNames.InsertUnique(fieldName); if ((field->m_xyProps != NULL) && (m_title.IsEmpty()) ) { m_title = field->m_xyProps->GetTitle(); } for (itFile = field->m_internalFiles.begin() ; itFile != field->m_internalFiles.end() ; itFile++) { CInternalFiles* yfx = CPlot::GetInternalFiles(*itFile); //----------------------------------- // Get plot Title --> title of the first file //----------------------------------- if (m_title.IsEmpty()) { m_title = yfx->GetTitle("").c_str(); } //----------------------------------- // Get and control unit of X axis //----------------------------------- string varXName; GetAxisX(yfx, NULL, NULL, &varXName); unitXRead = yfx->GetUnit(varXName); if (assignXUnit) { m_unitX = unitXRead; unitXStr = m_unitX.AsString(); m_unitXLabel = "\nUnit:\t" + wxString(m_unitX.GetText().c_str()); assignXUnit = false; } else { string unitXReadStr = unitXRead.AsString(); if (m_unitX.IsCompatible(unitXRead) == false) { string msg = CTools::Format("CPlot::CkeckUnits - In group field number %d, X field unit are not in the same way (not compatible)" "- Expected unit '%s' and found '%s' for axis X - File name is '%s'", m_groupNumber, unitXStr.c_str(), unitXReadStr.c_str(), yfx->GetName().c_str()); CException e(msg, BRATHL_INCONSISTENCY_ERROR); CTrace::Tracer("%s", e.what()); throw (e); } if (unitXStr.compare(unitXReadStr) != 0) { m_unitXConv = true; } } //----------------------------------- // Get title of X axis //----------------------------------- string titleX; if (m_titleX.IsEmpty()) { titleX = yfx->GetTitle(varXName); if (titleX.empty()) { titleX = varXName; } } if (assignXTitle) { m_titleX += titleX.c_str() + m_unitXLabel; assignXTitle = false; } //-------------------------------------------------------- // Get and control unit of Y axis --> unit of each field //--------------------------------------------------------- unitYRead = yfx->GetUnit(fieldName); if ( assignYUnit ) { m_unitY = unitYRead; unitYStr = m_unitY.AsString(); m_unitYLabel = "\nUnit:\t" + wxString(m_unitY.GetText().c_str()); assignYUnit = false; } else { string unitYReadStr = unitYRead.AsString(); if (m_unitY.IsCompatible(unitYRead) == false) { string msg = CTools::Format("CXYPlotData::Create - In group field number %d, Y field unit are not in the same way (not compatible)" "- Expected unit '%s' and found '%s' for axis Y - Field name is '%s' - File name is '%s'", m_groupNumber, unitYStr.c_str(), unitYReadStr.c_str(), fieldName.c_str(), yfx->GetName().c_str()); CException e(msg, BRATHL_INCONSISTENCY_ERROR); CTrace::Tracer("%s", e.what()); throw (e); } if (unitYStr.compare(unitYReadStr) != 0) { m_unitYConv = true; } } //----------------------------------- // Get title of Y axis (as possible) //----------------------------------- string titleY; if ((nrFields == 1) && (nrFiles <= 1)) { if (m_titleY.IsEmpty()) { titleY = yfx->GetTitle(fieldName); if (titleY.empty()) { titleY = fieldName; } } } if (assignYTitle) { m_titleY += titleY.c_str() + m_unitYLabel; assignYTitle = false; } } // end for (itFile = ... } // end for (itField = ... //CTrace::GetInstance()->SetTraceLevel(5); //plotFieldNames.Dump(*(CTrace::GetInstance()->GetDumpContext())); if (plotFieldNames.size() > 0) { for (itFile = allInternalFiles.begin() ; itFile != allInternalFiles.end() ; itFile++) { CInternalFiles* yfx = CPlot::GetInternalFiles(*itFile); if (yfx == NULL) { continue; } CStringArray complement; yfx->GetComplementVars(plotFieldNames, complement); CStringArray::iterator itStringArray; for (itStringArray = complement.begin() ; itStringArray != complement.end(); itStringArray++) { CNetCDFVarDef* v1Def = yfx->GetNetCDFVarDef(plotFieldNames.at(0)); CNetCDFVarDef* v2Def = yfx->GetNetCDFVarDef(*itStringArray); if ((v1Def == NULL) || (v2Def == NULL)) { continue; } if (yfx->GetFile()->HaveEqualDimNames(plotFieldNames.at(0), *itStringArray)) { m_nonPlotFieldNames.InsertUnique(*itStringArray); } } //complement.Dump(*(CTrace::GetInstance()->GetDumpContext())); } //m_nonPlotFieldNames.Dump(*(CTrace::GetInstance()->GetDumpContext())); } /* for (iFile = 0 ; iFile < nrFiles ; iFile++) { CInternalFilesYFX* yfx = GetInternalFilesYFX(allInternalFiles.at(iFile)); //----------------------------------- // Get plot Title --> title of the first file //----------------------------------- if (m_title.IsEmpty()) { m_title = yfx->GetTitle("").c_str(); } //----------------------------------- // Get and control unit of X axis //----------------------------------- string varXName; GetAxisX(yfx, NULL, NULL, &varXName); unitXRead = yfx->GetUnit(varXName); //-------------------------------------------------------- // Get and control unit of Y axis --> unit of each field //--------------------------------------------------------- //int32_t iField = 0; int32_t nrFields = m_fields.size(); CObArray::iterator itField; for (itField = m_fields.begin() ; itField != m_fields.end() ; itField++) { if (assignXUnit) { m_unitX = unitXRead; unitXStr = m_unitX.AsString(); m_unitXLabel = "\nUnit:\t" + wxString(m_unitX.GetText().c_str()); assignXUnit = false; } else { string unitXReadStr = unitXRead.AsString(); if (m_unitX.IsCompatible(unitXRead) == false) { string msg = CTools::Format("CPlot::CkeckUnits - In group field number %d, X field unit are not in the same way (not compatible)" "- Expected unit '%s' and found '%s' for axis X - File name is '%s'", m_groupNumber, unitXStr.c_str(), unitXReadStr.c_str(), yfx->GetName().c_str()); CException e(msg, BRATHL_INCONSISTENCY_ERROR); CTrace::Tracer(e.what()); throw (e); } if (unitXStr.compare(unitXReadStr) != 0) { m_unitXConv = true; } } //----------------------------------- // Get title of X axis //----------------------------------- string titleX; if (m_titleX.IsEmpty()) { titleX = yfx->GetTitle(varXName); if (titleX.empty()) { titleX = varXName; } } //if (iFile == 0) if (assignXTitle) { m_titleX += titleX.c_str() + m_unitXLabel; assignXTitle = false; } CPlotField* field = CPlotField::GetPlotField(*itField); string fieldName = field->m_name.c_str(); unitYRead = yfx->GetUnit(fieldName); if ( assignYUnit ) { m_unitY = unitYRead; unitYStr = m_unitY.AsString(); m_unitYLabel = "\nUnit:\t" + wxString(m_unitY.GetText().c_str()); assignYUnit = false; } else { string unitYReadStr = unitYRead.AsString(); if (m_unitY.IsCompatible(unitYRead) == false) { string msg = CTools::Format("CXYPlotData::Create - In group field number %d, Y field unit are not in the same way (not compatible)" "- Expected unit '%s' and found '%s' for axis Y - Field name is '%s' - File name is '%s'", m_groupNumber, unitYStr.c_str(), unitYReadStr.c_str(), fieldName.c_str(), yfx->GetName().c_str()); CException e(msg, BRATHL_INCONSISTENCY_ERROR); CTrace::Tracer(e.what()); throw (e); } if (unitYStr.compare(unitYReadStr) != 0) { m_unitYConv = true; } } //----------------------------------- // Get title of Y axis (as possible) //----------------------------------- string titleY; if ((nrFields == 1) && (nrFiles <= 1)) { if (m_titleY.IsEmpty()) { titleY = yfx->GetTitle(fieldName); if (titleY.empty()) { titleY = fieldName; } } } if (assignYTitle) { m_titleY += titleY.c_str() + m_unitYLabel; assignYTitle = false; } } } */ }
//---------------------------------------- void CPlot::GetAxisX(CInternalFiles* yfx, ExpressionValueDimensions* dimVal, CExpressionValue* varX, string* varXName) { if (!m_forcedVarXName.empty()) { if (varXName != NULL) { *varXName = m_forcedVarXName.c_str(); } GetForcedAxisX(yfx, dimVal, varX); return; } CStringArray axisNames; CStringArray::iterator is; //ExpressionValueDimensions dimVal; yfx->GetAxisVars(axisNames); if (axisNames.size() != 1) { string msg = CTools::Format("CPlot::GetAxisX - wrong number of axis in file '%s' : %ld" "Correct number is 1", yfx->GetName().c_str(), (long)axisNames.size()); CException e(msg, BRATHL_INCONSISTENCY_ERROR); CTrace::Tracer("%s", e.what()); throw (e); } for (is = axisNames.begin(); is != axisNames.end(); is++) { // Get dim if (dimVal != NULL) { yfx->GetVarDims(*is, *dimVal); if ( (dimVal->size() <= 0) || (dimVal->size() > 2) ) { string msg = CTools::Format("CPlot::GetAxisX - '%s' axis -> number of dimensions must be 1 or 2 - Found : %ld", (*is).c_str(), (long)dimVal->size()); CException e(msg, BRATHL_INCONSISTENCY_ERROR); CTrace::Tracer("%s", e.what()); throw (e); } } // Get values if (varX != NULL) { /* string wantedUnit; NetCDFVarKind varKind = yfx->GetVarKind(*is); if (varKind == Longitude) { wantedUnit = CLatLonPoint::m_DEFAULT_UNIT_LONGITUDE; } else if (varKind == Latitude) { wantedUnit = CLatLonPoint::m_DEFAULT_UNIT_LATITUDE; } else { CUnit unitX = yfx->GetUnit(*varXName); wantedUnit = unitX.GetText(); } yfx->ReadVar(*is, *varX, wantedUnit); */ yfx->ReadVar(*is, *varX, yfx->GetUnit(*is).GetText()); } // Get name if (varXName != NULL) { *varXName = (*is); } } }
void PaneDisplay::SetContent( PaneContents c ) { CString str = "?"; // fill this in float val = 0; // fill this in const Song *pSong = GAMESTATE->m_pCurSong; const Steps *pSteps = GAMESTATE->m_pCurSteps[m_PlayerNumber]; const Course *pCourse = GAMESTATE->m_pCurCourse; const Trail *pTrail = GAMESTATE->m_pCurTrail[m_PlayerNumber]; const Profile *pProfile = PROFILEMAN->GetProfile( m_PlayerNumber ); bool bIsEdit = pSteps && pSteps->GetDifficulty() == DIFFICULTY_EDIT; if( (g_Contents[c].req&NEED_NOTES) && !pSteps ) goto done; if( (g_Contents[c].req&NEED_COURSE) && !pTrail ) goto done; if( (g_Contents[c].req&NEED_PROFILE) && !pProfile ) { str = "N/A"; goto done; } { RadarValues rv; if( g_Contents[c].req&NEED_NOTES ) rv = pSteps->GetRadarValues(); else if( g_Contents[c].req&NEED_COURSE ) rv = pTrail->GetRadarValues(); switch( c ) { case COURSE_NUM_STEPS: case SONG_NUM_STEPS: val = rv[RADAR_NUM_TAPS_AND_HOLDS]; break; case COURSE_JUMPS: case SONG_JUMPS: val = rv[RADAR_NUM_JUMPS]; break; case COURSE_HOLDS: case SONG_HOLDS: val = rv[RADAR_NUM_HOLDS]; break; case COURSE_MINES: case SONG_MINES: val = rv[RADAR_NUM_MINES]; break; case COURSE_HANDS: case SONG_HANDS: val = rv[RADAR_NUM_HANDS]; break; case SONG_DIFFICULTY_RADAR_STREAM: val = rv[RADAR_STREAM]; break; case SONG_DIFFICULTY_RADAR_VOLTAGE: val = rv[RADAR_VOLTAGE]; break; case SONG_DIFFICULTY_RADAR_AIR: val = rv[RADAR_AIR]; break; case SONG_DIFFICULTY_RADAR_FREEZE: val = rv[RADAR_FREEZE]; break; case SONG_DIFFICULTY_RADAR_CHAOS: val = rv[RADAR_CHAOS]; break; case SONG_PROFILE_HIGH_SCORE: val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetStepsHighScoreList(pSong,pSteps).GetTopScore().fPercentDP; break; case SONG_PROFILE_NUM_PLAYS: val = (float) PROFILEMAN->GetProfile(m_PlayerNumber)->GetStepsNumTimesPlayed(pSong,pSteps); break; case SONG_MACHINE_HIGH_NAME: /* set val for color */ case SONG_MACHINE_HIGH_SCORE: CHECKPOINT; if( bIsEdit ) goto done; // no machine scores for edits val = 100.0f * PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSong,pSteps).GetTopScore().fPercentDP; break; case SONG_MACHINE_RANK: { const vector<Song*> best = SONGMAN->GetBestSongs( PROFILE_SLOT_MACHINE ); val = (float) FindIndex( best.begin(), best.end(), pSong ); val += 1; break; } case SONG_PROFILE_RANK: { const vector<Song*> best = SONGMAN->GetBestSongs( PlayerMemCard(m_PlayerNumber) ); val = (float) FindIndex( best.begin(), best.end(), pSong ); val += 1; break; } case COURSE_MACHINE_HIGH_NAME: /* set val for color */ case COURSE_MACHINE_HIGH_SCORE: val = 100.0f * PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,pTrail).GetTopScore().fPercentDP; break; case COURSE_MACHINE_NUM_PLAYS: val = (float) PROFILEMAN->GetMachineProfile()->GetCourseNumTimesPlayed( pCourse ); break; case COURSE_MACHINE_RANK: { const vector<Course*> best = SONGMAN->GetBestCourses( PROFILE_SLOT_MACHINE ); val = (float) FindIndex( best.begin(), best.end(), pCourse ); val += 1; } break; case COURSE_PROFILE_HIGH_SCORE: val = 100.0f * PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseHighScoreList(pCourse,pTrail).GetTopScore().fPercentDP; break; case COURSE_PROFILE_NUM_PLAYS: val = (float) PROFILEMAN->GetProfile(m_PlayerNumber)->GetCourseNumTimesPlayed( pCourse ); break; case COURSE_PROFILE_RANK: const vector<Course*> best = SONGMAN->GetBestCourses( PlayerMemCard(m_PlayerNumber) ); val = (float) FindIndex( best.begin(), best.end(), pCourse ); val += 1; break; }; if( val == RADAR_VAL_UNKNOWN ) goto done; /* Scale, round, clamp, etc. for floats: */ switch( c ) { case SONG_DIFFICULTY_RADAR_STREAM: case SONG_DIFFICULTY_RADAR_VOLTAGE: case SONG_DIFFICULTY_RADAR_AIR: case SONG_DIFFICULTY_RADAR_FREEZE: case SONG_DIFFICULTY_RADAR_CHAOS: val = roundf( SCALE( val, 0, 1, 0, 10 ) ); val = clamp( val, 0, 10 ); str = ssprintf( "%.0f", val ); break; } switch( c ) { case SONG_MACHINE_HIGH_NAME: str = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSong,pSteps).GetTopScore().sName; break; case COURSE_MACHINE_HIGH_NAME: str = PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,pTrail).GetTopScore().sName; break; case SONG_MACHINE_HIGH_SCORE: case COURSE_MACHINE_HIGH_SCORE: case SONG_PROFILE_HIGH_SCORE: case COURSE_PROFILE_HIGH_SCORE: str = ssprintf( "%.2f%%", val ); break; case SONG_NUM_STEPS: case SONG_JUMPS: case SONG_HOLDS: case SONG_MINES: case SONG_HANDS: case COURSE_NUM_STEPS: case COURSE_JUMPS: case COURSE_HOLDS: case COURSE_MINES: case COURSE_HANDS: case SONG_MACHINE_NUM_PLAYS: case COURSE_MACHINE_NUM_PLAYS: case SONG_PROFILE_NUM_PLAYS: case COURSE_PROFILE_NUM_PLAYS: case SONG_MACHINE_RANK: case COURSE_MACHINE_RANK: case SONG_PROFILE_RANK: case COURSE_PROFILE_RANK: str = ssprintf( "%.0f", val ); } } done: m_textContents[c].SetText( str ); const int num = NUM_ITEM_COLORS( g_Contents[c].name ); for( int p = 0; p < num; ++p ) { const CString metric = ITEM_COLOR(g_Contents[c].name, p); CStringArray spec; split( metric, ";", spec ); if( spec.size() < 2 ) RageException::Throw( "Metric '%s' malformed", metric.c_str() ); const float n = strtof( spec[0], NULL ); if( val >= n ) continue; spec.erase( spec.begin(), spec.begin()+1 ); m_textContents[c].Command( join(";", spec) ); break; } }