From 718a6305f45952306ce213bfdb84abaef8efac1a Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Wed, 21 Aug 2002 03:04:39 +0000 Subject: [PATCH] Flatten song parsing code a bit. (Gah--that makes patches look really big, when most of the lines are really just changing indentation.) More minor const fixes in Notes. Handle #DIFFICULTY in KSF. Fix spurious warnings about KSF keys. Clean up KSF parsing slightly. --- stepmania/src/Notes.cpp | 166 +++++++++---------- stepmania/src/Song.cpp | 351 ++++++++++++++++++++-------------------- 2 files changed, 260 insertions(+), 257 deletions(-) diff --git a/stepmania/src/Notes.cpp b/stepmania/src/Notes.cpp index 43e34a5b4c..e26ffe4231 100644 --- a/stepmania/src/Notes.cpp +++ b/stepmania/src/Notes.cpp @@ -742,6 +742,7 @@ bool Notes::LoadFromKSFFile( const CString &sPath ) throw RageException( "Error opening file '%s'.", sPath ); int iTickCount = -1; // this is the value we read for TICKCOUNT + CString iStep; // this is the value we read for STEP for( int i=0; iWarn( "TICKCOUNT not found; defaulting to %i", sPath, iTickCount ); + } + + NoteData notedata; // read it into here + + CStringArray asRows; + iStep.TrimLeft(); + split( iStep, "\n", asRows, true ); + + int iHoldStartRow[13]; + for( int t=0; t<13; t++ ) + iHoldStartRow[t] = -1; + + for( int r=0; rWarn( "In KSF file '%s', STEP was read before TICKCOUNT", sPath ); - iTickCount = 2; + if( iHoldStartRow[t] == -1 ) + iHoldStartRow[t] = r; + else + ; // ignore middle of hold } - - NoteData notedata; // read it into here - - CStringArray asRows; - sParams[1].TrimLeft(); - split( sParams[1], "\n", asRows, true ); - - int iHoldStartRow[13]; - for( int t=0; t<13; t++ ) - iHoldStartRow[t] = -1; - - for( int r=0; rTrace( "Unexpected value named '%s'", sValueName ); } + CString sDir, sFName, sExt; + splitrelpath( sPath, sDir, sFName, sExt ); + sFName.MakeLower(); + + m_sDescription = sFName; + if( sFName.Find("crazy")!=-1 ) + { + m_DifficultyClass = CLASS_HARD; + if(!m_iMeter) m_iMeter = 8; + } + else if( sFName.Find("hard")!=-1 ) + { + m_DifficultyClass = CLASS_MEDIUM; + if(!m_iMeter) m_iMeter = 5; + } + else if( sFName.Find("easy")!=-1 ) + { + m_DifficultyClass = CLASS_EASY; + if(!m_iMeter) m_iMeter = 2; + } + else + { + m_DifficultyClass = CLASS_MEDIUM; + if(!m_iMeter) m_iMeter = 5; + } + + if( sFName.Find("double") != -1 ) + { + notedata.m_iNumTracks = 10; + m_NotesType = NOTES_TYPE_PUMP_DOUBLE; + } + else + { + notedata.m_iNumTracks = 5; + m_NotesType = NOTES_TYPE_PUMP_SINGLE; + } + + m_sSMNoteData = notedata.GetSMNoteDataString(); + return true; } diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index d577e0a4d2..5bc8151b1e 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -73,8 +73,8 @@ void SortStopSegmentsArray( CArray &arrayStopSegments int CompareAnimationSegments(const void *arg1, const void *arg2) { // arg1 and arg2 are of type Step** - AnimationSegment* seg1 = (AnimationSegment*)arg1; - AnimationSegment* seg2 = (AnimationSegment*)arg2; + const AnimationSegment* seg1 = (const AnimationSegment*)arg1; + const AnimationSegment* seg2 = (const AnimationSegment*)arg2; float score1 = seg1->m_fStartBeat; float score2 = seg2->m_fStartBeat; @@ -469,187 +469,187 @@ bool Song::LoadFromBMSDir( CString sDir ) // valuename, sNoteData, iMeasureNo, iBMSTrackNo, iNumNotesInThisMeasure ); for( int j=0; j 10 ) // some BPMs's play the music again at the end. Why? Who knows... + break; + float fBPS; + fBPS = m_BPMSegments[0].m_fBPM/60.0f; + m_fBeat0OffsetInSeconds = fBeatOffset / fBPS; + //LOG->Trace( "Found offset to be index %d, beat %f", iStepIndex, NoteRowToBeat(iStepIndex) ); + } + break; + case 3: // bpm change + { + BPMSegment newSeg( NoteRowToBeat(iStepIndex), (float)arrayNotes[j] ); + AddBPMSegment( newSeg ); + LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.m_fStartBeat, newSeg.m_fBPM ); + } + break; + + // Let me just take a moment to express how frustrated I am with the new, + // poorly-designed changes to the BMS format. + // + // + // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhh!!!!!!!!!!!!!!! + // + // Thank you. + + case 8: // indirect bpm + { + // This is a very inefficient way to parse, but it doesn't matter much + // because this is only parsed on the first run after the song is installed. + CString sTagToLookFor = ssprintf( "#BPM%02x", arrayNotes[j] ); + float fBPM = -1; + + + // open the song file again and and look for this tag's value + CStdioFile file; + if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) ) { - float fBeatOffset = fBeatOffset = NoteRowToBeat( (float)iStepIndex ); - if( fBeatOffset > 10 ) // some BPMs's play the music again at the end. Why? Who knows... - break; - float fBPS; - fBPS = m_BPMSegments[0].m_fBPM/60.0f; - m_fBeat0OffsetInSeconds = fBeatOffset / fBPS; - //LOG->Trace( "Found offset to be index %d, beat %f", iStepIndex, NoteRowToBeat(iStepIndex) ); + throw RageException( "Failed to open %s.", sPath ); + return false; } - break; - case 3: // bpm change + + CString line; + while( file.ReadString(line) ) // foreach line { - BPMSegment newSeg( NoteRowToBeat(iStepIndex), (float)arrayNotes[j] ); + CString value_name; // fill these in + CString value_data; + + // BMS value names can be separated by a space or a colon. + int iIndexOfFirstColon = line.Find( ":" ); + int iIndexOfFirstSpace = line.Find( " " ); + + if( iIndexOfFirstColon == -1 ) + iIndexOfFirstColon = 10000; + if( iIndexOfFirstSpace == -1 ) + iIndexOfFirstSpace = 10000; + + int iIndexOfSeparator = min( iIndexOfFirstSpace, iIndexOfFirstColon ); + + if( iIndexOfSeparator != 10000 ) + { + value_name = line.Mid( 0, iIndexOfSeparator ); + value_data = line; // the rest + value_data.Delete(0,iIndexOfSeparator+1); + } + else // no separator + { + value_name = line; + } + + if( 0==stricmp(value_name, sTagToLookFor) ) + { + fBPM = (float)atof( value_data ); + break; + } + } + + if( fBPM == -1 ) // we didn't find the line we were looking for + { + LOG->Trace( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, sPath ); + } + else + { + BPMSegment newSeg( NoteRowToBeat(iStepIndex), fBPM ); AddBPMSegment( newSeg ); LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.m_fStartBeat, newSeg.m_fBPM ); } - break; - // Let me just take a moment to express how frustrated I am with the new, - // poorly-designed changes to the BMS format. - // - // - // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhhhhhhhhhhhhhhhhhhhhhh!!!!!!!!!!!!!!! - // - // Thank you. - - case 8: // indirect bpm - { - // This is a very inefficient way to parse, but it doesn't matter much - // because this is only parsed on the first run after the song is installed. - CString sTagToLookFor = ssprintf( "#BPM%02x", arrayNotes[j] ); - float fBPM = -1; - - - // open the song file again and and look for this tag's value - CStdioFile file; - if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) ) - { - throw RageException( "Failed to open %s.", sPath ); - return false; - } - - CString line; - while( file.ReadString(line) ) // foreach line - { - CString value_name; // fill these in - CString value_data; - - // BMS value names can be separated by a space or a colon. - int iIndexOfFirstColon = line.Find( ":" ); - int iIndexOfFirstSpace = line.Find( " " ); - - if( iIndexOfFirstColon == -1 ) - iIndexOfFirstColon = 10000; - if( iIndexOfFirstSpace == -1 ) - iIndexOfFirstSpace = 10000; - - int iIndexOfSeparator = min( iIndexOfFirstSpace, iIndexOfFirstColon ); - - if( iIndexOfSeparator != 10000 ) - { - value_name = line.Mid( 0, iIndexOfSeparator ); - value_data = line; // the rest - value_data.Delete(0,iIndexOfSeparator+1); - } - else // no separator - { - value_name = line; - } - - if( 0==stricmp(value_name, sTagToLookFor) ) - { - fBPM = (float)atof( value_data ); - break; - } - } - - if( fBPM == -1 ) // we didn't find the line we were looking for - { - LOG->Trace( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, sPath ); - } - else - { - BPMSegment newSeg( NoteRowToBeat(iStepIndex), fBPM ); - AddBPMSegment( newSeg ); - LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.m_fStartBeat, newSeg.m_fBPM ); - } - - file.Close(); - } - break; - case 9: // stop - { - // This is a very inefficient way to parse, but it doesn't - // matter much because this is only parsed on the first run after the song is installed. - CString sTagToLookFor = ssprintf( "#STOP%02x", arrayNotes[j] ); - float fFreezeStartBeat = NoteRowToBeat(iStepIndex); - float fFreezeSecs = -1; - - - // open the song file again and and look for this tag's value - CStdioFile file; - if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) ) - throw RageException( "Failed to open %s.", sPath ); - - CString line; - while( file.ReadString(line) ) // foreach line - { - CString value_name; // fill these in - CString value_data; - - // BMS value names can be separated by a space or a colon. - int iIndexOfFirstColon = line.Find( ":" ); - int iIndexOfFirstSpace = line.Find( " " ); - - if( iIndexOfFirstColon == -1 ) - iIndexOfFirstColon = 10000; - if( iIndexOfFirstSpace == -1 ) - iIndexOfFirstSpace = 10000; - - int iIndexOfSeparator = min( iIndexOfFirstSpace, iIndexOfFirstColon ); - - if( iIndexOfSeparator != 10000 ) - { - value_name = line.Mid( 0, iIndexOfSeparator ); - value_data = line; // the rest - value_data.Delete(0,iIndexOfSeparator+1); - } - else // no separator - { - value_name = line; - } - - if( 0==stricmp(value_name, sTagToLookFor) ) - { - // find the BPM at the time of this freeze - float fBPM = -1; - for( int i=0; i fFreezeStartBeat ) - { - fBPM = m_BPMSegments[i].m_fBPM; - break; - } - } - // the BPM segment of this beat is the last BPM segment - if( fBPM == -1 ) - fBPM = m_BPMSegments[m_BPMSegments.GetSize()-1].m_fBPM; - - fFreezeSecs = (float)atof(value_data)/(fBPM*0.81f); // I have no idea what units these are in, so I experimented until finding this factor. - break; - } - } - - if( fFreezeSecs == -1 ) // we didn't find the line we were looking for - { - LOG->Trace( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, sPath ); - } - else - { - StopSegment newSeg( fFreezeStartBeat, fFreezeSecs ); - AddStopSegment( newSeg ); - LOG->Trace( "Inserting new Freeze at beat %f, secs %f", newSeg.m_fStartBeat, newSeg.m_fStopSeconds ); - } - - file.Close(); - } - break; + file.Close(); } + break; + case 9: // stop + { + // This is a very inefficient way to parse, but it doesn't + // matter much because this is only parsed on the first run after the song is installed. + CString sTagToLookFor = ssprintf( "#STOP%02x", arrayNotes[j] ); + float fFreezeStartBeat = NoteRowToBeat(iStepIndex); + float fFreezeSecs = -1; + + + // open the song file again and and look for this tag's value + CStdioFile file; + if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) ) + throw RageException( "Failed to open %s.", sPath ); + + CString line; + while( file.ReadString(line) ) // foreach line + { + CString value_name; // fill these in + CString value_data; + + // BMS value names can be separated by a space or a colon. + int iIndexOfFirstColon = line.Find( ":" ); + int iIndexOfFirstSpace = line.Find( " " ); + + if( iIndexOfFirstColon == -1 ) + iIndexOfFirstColon = 10000; + if( iIndexOfFirstSpace == -1 ) + iIndexOfFirstSpace = 10000; + + int iIndexOfSeparator = min( iIndexOfFirstSpace, iIndexOfFirstColon ); + + if( iIndexOfSeparator != 10000 ) + { + value_name = line.Mid( 0, iIndexOfSeparator ); + value_data = line; // the rest + value_data.Delete(0,iIndexOfSeparator+1); + } + else // no separator + { + value_name = line; + } + + if( 0==stricmp(value_name, sTagToLookFor) ) + { + // find the BPM at the time of this freeze + float fBPM = -1; + for( int i=0; i fFreezeStartBeat ) + { + fBPM = m_BPMSegments[i].m_fBPM; + break; + } + } + // the BPM segment of this beat is the last BPM segment + if( fBPM == -1 ) + fBPM = m_BPMSegments[m_BPMSegments.GetSize()-1].m_fBPM; + + fFreezeSecs = (float)atof(value_data)/(fBPM*0.81f); // I have no idea what units these are in, so I experimented until finding this factor. + break; + } + } + + if( fFreezeSecs == -1 ) // we didn't find the line we were looking for + { + LOG->Trace( "WARNING: Couldn't find tag '%s' in '%s'.", sTagToLookFor, sPath ); + } + else + { + StopSegment newSeg( fFreezeStartBeat, fFreezeSecs ); + AddStopSegment( newSeg ); + LOG->Trace( "Inserting new Freeze at beat %f, secs %f", newSeg.m_fStartBeat, newSeg.m_fStopSeconds ); + } + + file.Close(); + } + break; } } } @@ -1013,7 +1013,10 @@ bool Song::LoadFromKSFDir( CString sDir ) else if( 0==stricmp(sValueName,"STARTTIME") ) m_fBeat0OffsetInSeconds = -(float)atof(sParams[1])/100; - + else if( 0==stricmp(sValueName,"TICKCOUNT") || + 0==stricmp(sValueName,"STEP") || + 0==stricmp(sValueName,"DIFFICULTY")) + ; /* Handled in Notes::LoadFromKSFFile; don't warn. */ else LOG->Trace( "Unexpected value named '%s'", sValueName ); }