From f629f06c34a84806360ae8f0c26a3e2e4d500ee0 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 9 May 2011 22:42:46 -0400 Subject: [PATCH] [splittiming] Abstract functionality for later. I don't want to repeat code for Steps. --- src/NotesLoaderSM.cpp | 476 +++++++++++++++++++++-------------------- src/NotesLoaderSM.h | 7 + src/NotesLoaderSSC.cpp | 319 ++++++++------------------- src/NotesLoaderSSC.h | 5 + 4 files changed, 343 insertions(+), 464 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 3ee9994332..3fa6432713 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -103,6 +103,244 @@ bool SMLoader::LoadTimingFromFile( const RString &fn, TimingData &out ) return true; } +void SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) +{ + vector arrayBPMChangeExpressions; + split( sParam, ",", arrayBPMChangeExpressions ); + + // prepare storage variables for negative BPMs -> Warps. + float negBeat = -1; + float negBPM = 1; + float highspeedBeat = -1; + + for( unsigned b=0; b arrayBPMChangeValues; + split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); + // XXX: Hard to tell which file caused this. + if( arrayBPMChangeValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #BPMs value \"%s\" (must have exactly one '='), ignored.", + arrayBPMChangeExpressions[b].c_str() ); + continue; + } + + const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); + const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); + + if( fNewBPM < 0.0f ) + { + out.m_bHasNegativeBpms = true; + negBeat = fBeat; + negBPM = fNewBPM; + } + else if( fNewBPM > 0.0f ) + { + // add in a warp. + if( negBPM < 0 ) + { + float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat); + WarpSegment new_seg(negBeat, endBeat); + out.AddWarpSegment( new_seg ); + + negBeat = -1; + negBPM = 1; + } + // too fast. make it a warp. + if( fNewBPM > FAST_BPM_WARP ) + { + highspeedBeat = fBeat; + } + else + { + // add in a warp. + if( highspeedBeat > 0 ) + { + WarpSegment new_seg(highspeedBeat, fBeat); + out.AddWarpSegment( new_seg ); + highspeedBeat = -1; + } + { + BPMSegment new_seg; + new_seg.m_iStartRow = BeatToNoteRow(fBeat); + new_seg.SetBPM( fNewBPM ); + out.AddBPMSegment( new_seg ); + } + } + } + } +} + +void SMLoader::ProcessStops( TimingData &out, const RString sParam ) +{ + vector arrayFreezeExpressions; + split( sParam, ",", arrayFreezeExpressions ); + + // Prepare variables for negative stop conversion. + float negBeat = -1; + float negPause = 0; + + for( unsigned f=0; f arrayFreezeValues; + split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); + if( arrayFreezeValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.", + arrayFreezeExpressions[f].c_str() ); + continue; + } + + const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] ); + const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); + + // Process the prior stop. + if( negPause > 0 ) + { + BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); + float fSecondsPerBeat = 60 / oldBPM.GetBPM(); + float fSkipBeats = negPause / fSecondsPerBeat; + + if( negBeat + fSkipBeats > fFreezeBeat ) + fSkipBeats = fFreezeBeat - negBeat; + + WarpSegment ws( negBeat, negBeat + fSkipBeats); + out.AddWarpSegment( ws ); + + negBeat = -1; + negPause = 0; + } + + if( fFreezeSeconds < 0.0f ) + { + negBeat = fFreezeBeat; + negPause = -fFreezeSeconds; + } + else if( fFreezeSeconds > 0.0f ) + { + StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); + out.AddStopSegment( ss ); + } + + } + + // Process the prior stop if there was one. + if( negPause > 0 ) + { + BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); + float fSecondsPerBeat = 60 / oldBPM.GetBPM(); + float fSkipBeats = negPause / fSecondsPerBeat; + + WarpSegment ws( negBeat, negBeat + fSkipBeats); + out.AddWarpSegment( ws ); + } +} + +void SMLoader::ProcessDelays( TimingData &out, const RString sParam ) +{ + vector arrayDelayExpressions; + split( sParam, ",", arrayDelayExpressions ); + + for( unsigned f=0; f arrayDelayValues; + split( arrayDelayExpressions[f], "=", arrayDelayValues ); + if( arrayDelayValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #DELAYS value \"%s\" (must have exactly one '='), ignored.", + arrayDelayExpressions[f].c_str() ); + continue; + } + + const float fFreezeBeat = StringToFloat( arrayDelayValues[0] ); + const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); + + StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true ); + // XXX: Remove Negatives Bug? + new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat); + new_seg.m_fStopSeconds = fFreezeSeconds; + + // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); + + if(fFreezeSeconds > 0.0f) + out.AddStopSegment( new_seg ); + else + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); + } +} + +void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) +{ + vector vs1; + split( sParam, ",", vs1 ); + + FOREACH_CONST( RString, vs1, s1 ) + { + vector vs2; + split( *s1, "=", vs2 ); + + if( vs2.size() < 3 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() ); + continue; + } + + const float fBeat = StringToFloat( vs2[0] ); + + TimeSignatureSegment seg; + seg.m_iStartRow = BeatToNoteRow(fBeat); + seg.m_iNumerator = atoi( vs2[1] ); + seg.m_iDenominator = atoi( vs2[2] ); + + if( fBeat < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat ); + continue; + } + + if( seg.m_iNumerator < 1 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); + continue; + } + + if( seg.m_iDenominator < 1 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator ); + continue; + } + + out.AddTimeSignatureSegment( seg ); + } +} + +void SMLoader::ProcessTickcounts( TimingData &out, const RString sParam ) +{ + vector arrayTickcountExpressions; + split( sParam, ",", arrayTickcountExpressions ); + + for( unsigned f=0; f arrayTickcountValues; + split( arrayTickcountExpressions[f], "=", arrayTickcountValues ); + if( arrayTickcountValues.size() != 2 ) + { + // XXX: Hard to tell which file caused this. + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #TICKCOUNTS value \"%s\" (must have exactly one '='), ignored.", + arrayTickcountExpressions[f].c_str() ); + continue; + } + + const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] ); + int iTicks = clamp(atoi( arrayTickcountValues[1] ), 0, ROWS_PER_BEAT); + + TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks ); + out.AddTickcountSegment( new_seg ); + } +} + void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out ) { out.m_fBeat0OffsetInSeconds = 0; @@ -123,255 +361,27 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out ) } else if( sValueName=="BPMS" ) { - vector arrayBPMChangeExpressions; - split( sParams[1], ",", arrayBPMChangeExpressions ); - - // prepare storage variables for negative BPMs -> Warps. - float negBeat = -1; - float negBPM = 1; - float highspeedBeat = -1; - - for( unsigned b=0; b arrayBPMChangeValues; - split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); - // XXX: Hard to tell which file caused this. - if( arrayBPMChangeValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() ); - continue; - } - - const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); - const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); - - if( fNewBPM < 0.0f ) - { - out.m_bHasNegativeBpms = true; - negBeat = fBeat; - negBPM = fNewBPM; - } - else if( fNewBPM > 0.0f ) - { - // add in a warp. - if( negBPM < 0 ) - { - float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat); - WarpSegment new_seg(negBeat, endBeat); - out.AddWarpSegment( new_seg ); - - negBeat = -1; - negBPM = 1; - } - // too fast. make it a warp. - if( fNewBPM > FAST_BPM_WARP ) - { - highspeedBeat = fBeat; - } - else - { - // add in a warp. - if( highspeedBeat > 0 ) - { - WarpSegment new_seg(highspeedBeat, fBeat); - out.AddWarpSegment( new_seg ); - highspeedBeat = -1; - } - { - BPMSegment new_seg; - new_seg.m_iStartRow = BeatToNoteRow(fBeat); - new_seg.SetBPM( fNewBPM ); - out.AddBPMSegment( new_seg ); - } - } - } - } + ProcessBPMs(out, sParams[1]); } else if( sValueName=="STOPS" || sValueName=="FREEZES" ) { - vector arrayFreezeExpressions; - split( sParams[1], ",", arrayFreezeExpressions ); - - // Prepare variables for negative stop conversion. - float negBeat = -1; - float negPause = 0; - - for( unsigned f=0; f arrayFreezeValues; - split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); - if( arrayFreezeValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayFreezeExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] ); - const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); - - // Process the prior stop. - if( negPause > 0 ) - { - BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); - float fSecondsPerBeat = 60 / oldBPM.GetBPM(); - float fSkipBeats = negPause / fSecondsPerBeat; - - if( negBeat + fSkipBeats > fFreezeBeat ) - fSkipBeats = fFreezeBeat - negBeat; - - WarpSegment ws( negBeat, negBeat + fSkipBeats); - out.AddWarpSegment( ws ); - - negBeat = -1; - negPause = 0; - } - - if( fFreezeSeconds < 0.0f ) - { - negBeat = fFreezeBeat; - negPause = -fFreezeSeconds; - } - else if( fFreezeSeconds > 0.0f ) - { - StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); - out.AddStopSegment( ss ); - } - - } - - // Process the prior stop if there was one. - if( negPause > 0 ) - { - BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); - float fSecondsPerBeat = 60 / oldBPM.GetBPM(); - float fSkipBeats = negPause / fSecondsPerBeat; - - WarpSegment ws( negBeat, negBeat + fSkipBeats); - out.AddWarpSegment( ws ); - } + ProcessStops(out, sParams[1]); } else if( sValueName=="DELAYS" ) { - vector arrayDelayExpressions; - split( sParams[1], ",", arrayDelayExpressions ); - - for( unsigned f=0; f arrayDelayValues; - split( arrayDelayExpressions[f], "=", arrayDelayValues ); - if( arrayDelayValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayDelayExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = StringToFloat( arrayDelayValues[0] ); - const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); - - StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true ); - // XXX: Remove Negatives Bug? - new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat); - new_seg.m_fStopSeconds = fFreezeSeconds; - - // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); - - if(fFreezeSeconds > 0.0f) - out.AddStopSegment( new_seg ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } + ProcessDelays(out, sParams[1]); } else if( sValueName=="TIMESIGNATURES" ) { - vector vs1; - split( sParams[1], ",", vs1 ); - - FOREACH_CONST( RString, vs1, s1 ) - { - vector vs2; - split( *s1, "=", vs2 ); - - if( vs2.size() < 3 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() ); - continue; - } - - const float fBeat = StringToFloat( vs2[0] ); - - TimeSignatureSegment seg; - seg.m_iStartRow = BeatToNoteRow(fBeat); - seg.m_iNumerator = atoi( vs2[1] ); - seg.m_iDenominator = atoi( vs2[2] ); - - if( fBeat < 0 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat ); - continue; - } - - if( seg.m_iNumerator < 1 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); - continue; - } - - if( seg.m_iDenominator < 1 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator ); - continue; - } - - out.AddTimeSignatureSegment( seg ); - } + ProcessTimeSignatures(out, sParams[1]); } else if( sValueName=="TICKCOUNTS" ) { - vector arrayTickcountExpressions; - split( sParams[1], ",", arrayTickcountExpressions ); - - for( unsigned f=0; f arrayTickcountValues; - split( arrayTickcountExpressions[f], "=", arrayTickcountValues ); - if( arrayTickcountValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayTickcountExpressions[f].c_str() ); - continue; - } - - const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] ); - int iTicks = atoi( arrayTickcountValues[1] ); - // you're lazy, let SM do the work for you... -DaisuMaster - if( iTicks < 1) iTicks = 1; - if( iTicks > ROWS_PER_BEAT ) iTicks = ROWS_PER_BEAT; - - TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks ); - out.AddTickcountSegment( new_seg ); - - if(iTicks >= 1 && iTicks <= ROWS_PER_BEAT ) // Constants - { - // LOG->Trace( "Adding a tickcount segment: beat: %f, ticks = %d", fTickcountBeat, iTicks ); - //out.AddTickcountSegment( new_seg ); - } - else - { - //LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid tickcount at beat %f, ticks %d.", fTickcountBeat, iTicks ); - //LOG->UserLog( "Song file", "(UNKNOWN)", "Clamping tickcount value to %d at beat %f.", iTicks, fTickcountBeat); - //etc - } - } + ProcessTickcounts(out, sParams[1]); } // Ensure all of the warps are handled right. sort(out.m_WarpSegments.begin(), out.m_WarpSegments.end()); diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index db1e938528..d61c7b19ff 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -25,6 +25,13 @@ namespace SMLoader bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ); + + + void ProcessBPMs( TimingData &, const RString ); + void ProcessStops( TimingData &, const RString ); + void ProcessDelays( TimingData &, const RString ); + void ProcessTimeSignatures( TimingData &, const RString ); + void ProcessTickcounts( TimingData &, const RString ); } #endif diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index b242781117..51c8b83f66 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -112,6 +112,86 @@ bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) return LoadFromSSCFile( sPath + aFileNames[0], out ); } +void SSCLoader::ProcessWarps( TimingData &out, const RString sParam ) +{ + vector arrayWarpExpressions; + split( sParam, ",", arrayWarpExpressions ); + + for( unsigned b=0; b arrayWarpValues; + split( arrayWarpExpressions[b], "=", arrayWarpValues ); + // XXX: Hard to tell which file caused this. + if( arrayWarpValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #WARPS value \"%s\" (must have exactly one '='), ignored.", + arrayWarpExpressions[b].c_str() ); + continue; + } + + const float fBeat = StringToFloat( arrayWarpValues[0] ); + const float fNewBeat = StringToFloat( arrayWarpValues[1] ); + + if(fNewBeat > fBeat) + out.AddWarpSegment( WarpSegment(fBeat, fNewBeat) ); + else + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat ); + } + } +} + +void SSCLoader::ProcessLabels( TimingData &out, const RString sParam ) +{ + vector arrayLabelExpressions; + split( sParam, ",", arrayLabelExpressions ); + + for( unsigned b=0; b arrayLabelValues; + split( arrayLabelExpressions[b], "=", arrayLabelValues ); + if( arrayLabelValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #LABELS value \"%s\" (must have exactly one '='), ignored.", + arrayLabelExpressions[b].c_str() ); + continue; + } + + const float fBeat = StringToFloat( arrayLabelValues[0] ); + RString sLabel = arrayLabelValues[1]; + TrimRight(sLabel); + if( fBeat >= 0.0f ) + out.AddLabelSegment( LabelSegment(fBeat, sLabel) ); + else + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() ); + } + + } +} + +void SSCLoader::ProcessCombos( TimingData &out, const RString sParam ) +{ + vector arrayComboExpressions; + split( sParam, ",", arrayComboExpressions ); + + for( unsigned f=0; f arrayComboValues; + split( arrayComboExpressions[f], "=", arrayComboValues ); + if( arrayComboValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #COMBOS value \"%s\" (must have exactly one '='), ignored.", + arrayComboExpressions[f].c_str() ); + continue; + } + const float fComboBeat = StringToFloat( arrayComboValues[0] ); + const int iCombos = atoi( arrayComboValues[1] ); + ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos ); + out.AddComboSegment( new_seg ); + } +} + bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache ) { LOG->Trace( "Song::LoadFromSSCFile(%s)", sPath.c_str() ); @@ -390,264 +470,41 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach * if the steps do not have their own timing. */ else if( sValueName=="STOPS" ) { - vector arrayFreezeExpressions; - split( sParams[1], ",", arrayFreezeExpressions ); - - for( unsigned f=0; f arrayFreezeValues; - split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); - if( arrayFreezeValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayFreezeExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] ); - const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); - StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); - - if(fFreezeSeconds > 0.0f) - { - // LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); - out.m_SongTiming.AddStopSegment( new_seg ); - } - else - { - // negative stops (hi JS!) -aj - if( PREFSMAN->m_bQuirksMode ) - { - // LOG->Trace( "Adding a negative freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); - out.m_SongTiming.AddStopSegment( new_seg ); - } - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } - } + SMLoader::ProcessStops(out.m_SongTiming, sParams[1]); } else if( sValueName=="DELAYS" ) { - vector arrayDelayExpressions; - split( sParams[1], ",", arrayDelayExpressions ); - - for( unsigned f=0; f arrayDelayValues; - split( arrayDelayExpressions[f], "=", arrayDelayValues ); - if( arrayDelayValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayDelayExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = StringToFloat( arrayDelayValues[0] ); - const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); - - StopSegment new_seg( BeatToNoteRow(fFreezeBeat), fFreezeSeconds, true ); - - // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); - - if(fFreezeSeconds > 0.0f) - out.m_SongTiming.AddStopSegment( new_seg ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } + SMLoader::ProcessDelays(out.m_SongTiming, sParams[1]); } else if( sValueName=="BPMS" ) { - vector arrayBPMChangeExpressions; - split( sParams[1], ",", arrayBPMChangeExpressions ); - - for( unsigned b=0; b arrayBPMChangeValues; - split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); - // XXX: Hard to tell which file caused this. - if( arrayBPMChangeValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayBPMChangeExpressions[b].c_str() ); - continue; - } - - const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); - const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); - - if(fNewBPM > 0.0f) - out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); - else - { - out.m_SongTiming.m_bHasNegativeBpms = true; - // only add Negative BPMs in quirks mode -aj - if( PREFSMAN->m_bQuirksMode ) - out.m_SongTiming.AddBPMSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid BPM change at beat %f, BPM %f.", fBeat, fNewBPM ); - } - } + SMLoader::ProcessBPMs(out.m_SongTiming, sParams[1]); } else if( sValueName=="WARPS" ) { - vector arrayWarpExpressions; - split( sParams[1], ",", arrayWarpExpressions ); - - for( unsigned b=0; b arrayWarpValues; - split( arrayWarpExpressions[b], "=", arrayWarpValues ); - // XXX: Hard to tell which file caused this. - if( arrayWarpValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayWarpExpressions[b].c_str() ); - continue; - } - - const float fBeat = StringToFloat( arrayWarpValues[0] ); - const float fNewBeat = StringToFloat( arrayWarpValues[1] ); - - if(fNewBeat > fBeat) - out.m_SongTiming.AddWarpSegment( WarpSegment(fBeat, fNewBeat) ); - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Warp at beat %f, BPM %f.", fBeat, fNewBeat ); - } - } + ProcessWarps( out.m_SongTiming, sParams[1] ); } else if( sValueName=="LABELS" ) { - vector arrayLabelExpressions; - split( sParams[1], ",", arrayLabelExpressions ); - - for( unsigned b=0; b arrayLabelValues; - split( arrayLabelExpressions[b], "=", arrayLabelValues ); - if( arrayLabelValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayLabelExpressions[b].c_str() ); - continue; - } - - const float fBeat = StringToFloat( arrayLabelValues[0] ); - RString sLabel = arrayLabelValues[1]; - TrimRight(sLabel); - if( fBeat >= 0.0f ) - out.m_SongTiming.AddLabelSegment( LabelSegment(fBeat, sLabel) ); - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() ); - } - - } + ProcessLabels( out.m_SongTiming, sParams[1] ); } else if( sValueName=="TIMESIGNATURES" ) { - vector vs1; - split( sParams[1], ",", vs1 ); - - FOREACH_CONST( RString, vs1, s1 ) - { - vector vs2; - split( *s1, "=", vs2 ); - - if( vs2.size() < 3 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with %i values.", (int)vs2.size() ); - continue; - } - - const float fBeat = StringToFloat( vs2[0] ); - - TimeSignatureSegment seg; - seg.m_iStartRow = BeatToNoteRow(fBeat); - seg.m_iNumerator = atoi( vs2[1] ); - seg.m_iDenominator = atoi( vs2[2] ); - - if( fBeat < 0 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f.", fBeat ); - continue; - } - - if( seg.m_iNumerator < 1 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); - continue; - } - - if( seg.m_iDenominator < 1 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator ); - continue; - } - - out.m_SongTiming.AddTimeSignatureSegment( seg ); - } + SMLoader::ProcessTimeSignatures(out.m_SongTiming, sParams[1]); } else if( sValueName=="TICKCOUNTS" ) { - vector arrayTickcountExpressions; - split( sParams[1], ",", arrayTickcountExpressions ); - - for( unsigned f=0; f arrayTickcountValues; - split( arrayTickcountExpressions[f], "=", arrayTickcountValues ); - if( arrayTickcountValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayTickcountExpressions[f].c_str() ); - continue; - } - - const float fTickcountBeat = StringToFloat( arrayTickcountValues[0] ); - const int iTicks = atoi( arrayTickcountValues[1] ); - TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks ); - - if(iTicks >= 1 && iTicks <= ROWS_PER_BEAT ) // Constants - { - // LOG->Trace( "Adding a tickcount segment: beat: %f, ticks = %d", fTickcountBeat, iTicks ); - out.m_SongTiming.AddTickcountSegment( new_seg ); - } - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid tickcount at beat %f, ticks %d.", fTickcountBeat, iTicks ); - } - } + SMLoader::ProcessTickcounts(out.m_SongTiming, sParams[1]); } else if( sValueName=="COMBOS" ) { - vector arrayComboExpressions; - split( sParams[1], ",", arrayComboExpressions ); - - for( unsigned f=0; f arrayComboValues; - split( arrayComboExpressions[f], "=", arrayComboValues ); - if( arrayComboValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #%s value \"%s\" (must have exactly one '='), ignored.", - sValueName.c_str(), arrayComboExpressions[f].c_str() ); - continue; - } - const float fComboBeat = StringToFloat( arrayComboValues[0] ); - const int iCombos = atoi( arrayComboValues[1] ); - ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos ); - out.m_SongTiming.AddComboSegment( new_seg ); - } + ProcessCombos( out.m_SongTiming, sParams[1] ); } /* The following are cache tags. Never fill their values diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index ff44a23cb5..53c9d5c72b 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -75,6 +75,11 @@ namespace SSCLoader * @param bFromCache a flag to determine if this song is loaded from a cache file. */ void TidyUpData( Song &song, bool bFromCache ); + + + void ProcessWarps( TimingData &, const RString ); + void ProcessLabels( TimingData &, const RString ); + void ProcessCombos( TimingData &, const RString ); } #endif /**