NotesLoaderBMS: Fix loading BPM changes by putting all of them in a map first and then finally add the BPM segments.

As the BMS loader sorts the definitions by measure and channel, they are not sorted by time, so there are cases that this can happen:

#00103:7F
#00203:007F0000
#00208:01
#BPM01 63.5

In this case, the segment in the second line is parsed before the third line, and because of the BPM is the same as the segment before it (the first line), no BPM changes will be added, the segment in the third line will then set the BPM of the rest of the song, which is wrong. To fix this the BPM needs to be sorted.
This commit is contained in:
Thai Pangsakulyanont
2011-06-13 10:54:18 +07:00
parent bc074180da
commit 5cd05670ab
+8 -2
View File
@@ -548,6 +548,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
{
map<RString, int> mapIdToKeysoundIndex;
map<int, float> mapNoteRowToBPM;
MeasureToTimeSig_t sigAdjustments;
LOG->Trace( "Steps::LoadFromBMSFile( '%s' )", sPath.c_str() );
@@ -622,7 +623,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
case BMS_TRACK_BPM:
if( iVal > 0 )
{
out.m_Timing.SetBPMAtBeat( fBeat, (float) iVal );
mapNoteRowToBPM[ BeatToNoteRow(fBeat) ] = iVal;
LOG->Trace( "Inserting new BPM change at beat %f, BPM %i", fBeat, iVal );
}
else
@@ -639,7 +640,7 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
if( GetTagFromMap( mapNameToData, sTagToLookFor, sBPM ) )
{
float fBPM = StringToFloat( sBPM );
out.m_Timing.SetBPMAtBeat( fBeat, fBPM );
mapNoteRowToBPM[ BeatToNoteRow(fBeat) ] = fBPM;
}
else
{
@@ -676,6 +677,11 @@ static bool LoadFromBMSFile( const RString &sPath, const NameToData_t &mapNameTo
}
}
for( map<int, float>::iterator it = mapNoteRowToBPM.begin(); it != mapNoteRowToBPM.end(); it ++ )
{
out.m_Timing.SetBPMAtRow( it->first, it->second );
}
// Now that we're done reading BPMs, factor out weird time signatures.
SetTimeSigAdjustments( mapMeasureToTimeSig, outSong, sigAdjustments );