diff --git a/Docs/Changelog_SSCformat.txt b/Docs/Changelog_SSCformat.txt index 205aac7c06..4aa7024de4 100644 --- a/Docs/Changelog_SSCformat.txt +++ b/Docs/Changelog_SSCformat.txt @@ -9,6 +9,9 @@ change to JSON, but it is unsure if this will be done. Implement .ssc at your own risk. ________________________________________________________________________________ +[v0.57] - Wolfman2000 +* Implement #LABELS tag for easier Editor work/Rock Band section mimicry. + [v0.56] - Wolfman2000 * Implement #WARPS tag to replace negative bpm/stop gimmicks. diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 1868dfd19d..5d2c9ce188 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -514,6 +514,34 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach } } } + + 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] ); + const RString sLabel = arrayLabelValues[1]; + if( fBeat > 0.0f ) + out.m_Timing.AddLabelSegment( LabelSegment(fBeat, sLabel) ); + else + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Label at beat %f called %s.", fBeat, sLabel.c_str() ); + } + + } + } else if( sValueName=="TIMESIGNATURES" ) { @@ -763,180 +791,28 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach { 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 ); - pNewNotes->m_Timing.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 ); - pNewNotes->m_Timing.AddStopSegment( new_seg ); - } - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid stop at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } - } - */ + // copy from above when it's time. } 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) - pNewNotes->m_Timing.AddStopSegment( new_seg ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } - */ + // copy from above when it's time. } 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; - } - - pNewNotes->m_Timing.AddTimeSignatureSegment( seg ); - } - */ + // copy from above when it's time. } 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 ); - pNewNotes->m_Timing.AddTickcountSegment( new_seg ); - } - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid tickcount at beat %f, ticks %d.", fTickcountBeat, iTicks ); - } - } - */ + // copy from above when it's time. } 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 ); - pNewNotes->m_Timing.AddComboSegment( new_seg ); - } - */ + // copy from above when it's time. + } + else if( sValueName=="WARPS" || sValueName=="LABELS" ) + { + // copy from above when it's time. } else if( sValueName=="ATTACKS" ) { diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 36c170b475..71e57ef042 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -194,6 +194,17 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) } f.PutLine( ";" ); + f.Write( "#LABELS:" ); + for( unsigned i=0; i asBPMValues; - for( unsigned i=0; i asStopValues; - for( unsigned i=0; i asDelayValues; - for( unsigned i=0; i asWarpValues; - for( unsigned i=0; i asTimeSigValues; - FOREACH_CONST( TimeSignatureSegment, in.m_Timing.m_vTimeSignatureSegments, iter ) - { - asTimeSigValues.push_back( ssprintf( "%.6f=%d=%d", NoteRowToBeat(iter->m_iStartRow), iter->m_iNumerator, iter->m_iDenominator ) ); - vector::const_iterator iter2 = iter; - iter2++; - } - lines.push_back( ssprintf( "#TIMESIGNATURES:%s;", join("\n,", asTimeSigValues).c_str() ) ); - - ASSERT( !in.m_Timing.m_TickcountSegments.empty() ); - vector asTickValues; - for( unsigned i=0; i asComboValues; - for( unsigned i=0; i