diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 2a9c87adb9..034f74752e 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -384,6 +384,30 @@ void SetRadarValues(StepsTagInfo& info) info.ssc_format= true; } +void SetTechCounts(StepsTagInfo& info) +{ + if (info.from_cache || info.for_load_edit) + { + std::vector values; + split((*info.params)[1], ",", values, true); + std::size_t cats_per_player= values.size() / NUM_PlayerNumber; + TechCounts v[NUM_PLAYERS]; + FOREACH_PlayerNumber(pn) + { + for(std::size_t i= 0; i < cats_per_player; ++i) + { + v[pn][i]= StringToFloat(values[pn * cats_per_player + i]); + } + } + info.steps->SetCachedTechCounts(v); + } + else + { + // just recalc at time. + } + info.ssc_format= true; +} + void SetMeasureInfo(StepsTagInfo& info) { if (info.from_cache || info.for_load_edit) @@ -406,6 +430,15 @@ void SetMeasureInfo(StepsTagInfo& info) info.ssc_format= true; } +void SetGrooveStatsHash(StepsTagInfo& info) +{ + if (info.from_cache || info.for_load_edit) + { + RString value = (*info.params)[1]; + info.steps->SetCachedGrooveStatsHash(value); + } + info.ssc_format = true; +} void SetCredit(StepsTagInfo& info) { @@ -647,8 +680,9 @@ struct ssc_parser_helper_t steps_tag_handlers["SCROLLS"]= &SetStepsScrolls; steps_tag_handlers["FAKES"]= &SetStepsFakes; steps_tag_handlers["LABELS"]= &SetStepsLabels; + steps_tag_handlers["TECHCOUNTS"] = &SetTechCounts; steps_tag_handlers["MEASUREINFO"] = &SetMeasureInfo; - + /* If this is called, the chart does not use the same attacks * as the Song's timing. No other changes are required. */ steps_tag_handlers["ATTACKS"]= &SetStepsAttacks; diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index 2ede6aacbd..cc648bdbdd 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -34,6 +34,8 @@ const float VERSION_CHART_NAME_TAG = 0.74f; const float VERSION_CACHE_SWITCH_TAG = 0.77f; /** @brief The version where note count was added as a radar category. */ const float VERSION_RADAR_NOTECOUNT = 0.83f; +/** @brief The version where tech stats, measure stats, and GrooveStats key were added. */ +const float VERSION_TECH_STATS = 0.84f; /** * @brief The SSCLoader handles all of the parsing needed for .ssc files. diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 5b0fd3a4aa..3f5ffdea14 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -428,6 +428,18 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa } if (bSavingCache) { + lines.push_back( ssprintf( "// step cache tags:" ) ); + std::vector asTechCounts; + FOREACH_PlayerNumber( pn ) + { + const TechCounts &ts = in.GetTechCounts(pn); + FOREACH_ENUM( TechCountsCategory, tc ) + { + asTechCounts.push_back(ssprintf("%.6f", ts[tc])); + } + } + lines.push_back(ssprintf("#TECHCOUNTS:%s;", join(",", asTechCounts).c_str())); + std::vector asMeasureInfo; FOREACH_PlayerNumber( pn ) { @@ -435,8 +447,14 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa asMeasureInfo.push_back(ms.ToString()); } lines.push_back(ssprintf("#MEASUREINFO:%s;", join("|", asMeasureInfo).c_str())); + + // MV: #STEPFILENAME has to be at the end of the cache tags, + // because it's used in SSCLoader::LoadFromSimfile to determine when + // to switch the state back to GETTING_SONG_INFO, which means any tags + // after it will be ignored. lines.push_back(ssprintf("#STEPFILENAME:%s;", in.GetFilename().c_str())); + lines.push_back( ssprintf( "// end step cache tags" ) ); } else { diff --git a/src/Song.cpp b/src/Song.cpp index 9a29fd2e3e..e36cee21a6 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -51,7 +51,7 @@ * @brief The internal version of the cache for StepMania. * * Increment this value to invalidate the current cache. */ -const int FILE_CACHE_VERSION = 227; +const int FILE_CACHE_VERSION = 232; /** @brief How long does a song sample last by default? */ const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;