Replace #MEASUREINFO with two separate tags, #NPSPERMEASURE and #NOTESPERMEASURE. Stop storing MeasureInfo objects on Steps, and just directly store NpsPerMeasure, NotesPerMeasure, and peakNPS.
This commit is contained in:
@@ -4,11 +4,6 @@
|
||||
#include "GameConstantsAndTypes.h"
|
||||
#include "NoteData.h"
|
||||
|
||||
/** This is a container for per-measure stats of a stepchart.
|
||||
This data is calculated and saved to the song cache files as the #MEASUREINFO tag.
|
||||
This data is provided to the theme via lua functions in Steps.cpp and Trail.cpp,
|
||||
*/
|
||||
|
||||
struct MeasureInfo
|
||||
{
|
||||
int measureCount;
|
||||
|
||||
+40
-6
@@ -408,19 +408,52 @@ void SetTechCounts(StepsTagInfo& info)
|
||||
info.ssc_format= true;
|
||||
}
|
||||
|
||||
void SetMeasureInfo(StepsTagInfo& info)
|
||||
void SetNpsPerMeasure(StepsTagInfo& info)
|
||||
{
|
||||
if (info.from_cache || info.for_load_edit)
|
||||
{
|
||||
std::vector<RString> values;
|
||||
split((*info.params)[1], "|", values, true);
|
||||
split((*info.params)[1], ",", values, true);
|
||||
std::size_t measures_per_player = values.size() / NUM_PlayerNumber;
|
||||
std::vector<std::vector<float>> npsPerMeasure;
|
||||
npsPerMeasure.resize(NUM_PLAYERS);
|
||||
|
||||
MeasureInfo v[NUM_PLAYERS];
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
v[pn].FromString(values[pn]);
|
||||
npsPerMeasure[pn].resize(measures_per_player, 0);
|
||||
for(std::size_t i= 0; i < measures_per_player; ++i)
|
||||
{
|
||||
npsPerMeasure[pn][i]= StringToFloat(values[pn * measures_per_player + i]);
|
||||
}
|
||||
}
|
||||
info.steps->SetCachedMeasureInfo(v);
|
||||
info.steps->SetCachedNpsPerMeasure(npsPerMeasure);
|
||||
}
|
||||
else
|
||||
{
|
||||
// just recalc at time.
|
||||
}
|
||||
info.ssc_format= true;
|
||||
}
|
||||
|
||||
void SetNotesPerMeasure(StepsTagInfo& info)
|
||||
{
|
||||
if (info.from_cache || info.for_load_edit)
|
||||
{
|
||||
std::vector<RString> values;
|
||||
split((*info.params)[1], ",", values, true);
|
||||
std::size_t measures_per_player = values.size() / NUM_PlayerNumber;
|
||||
std::vector<std::vector<int>> notesPerMeasure;
|
||||
notesPerMeasure.resize(NUM_PLAYERS);
|
||||
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
notesPerMeasure[pn].resize(measures_per_player, 0);
|
||||
for(std::size_t i= 0; i < measures_per_player; ++i)
|
||||
{
|
||||
notesPerMeasure[pn][i]= StringToInt(values[pn * measures_per_player + i]);
|
||||
}
|
||||
}
|
||||
info.steps->SetCachedNotesPerMeasure(notesPerMeasure);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -670,7 +703,8 @@ struct ssc_parser_helper_t
|
||||
steps_tag_handlers["FAKES"]= &SetStepsFakes;
|
||||
steps_tag_handlers["LABELS"]= &SetStepsLabels;
|
||||
steps_tag_handlers["TECHCOUNTS"] = &SetTechCounts;
|
||||
steps_tag_handlers["MEASUREINFO"] = &SetMeasureInfo;
|
||||
steps_tag_handlers["NPSPERMEASURE"] = &SetNpsPerMeasure;
|
||||
steps_tag_handlers["NOTESPERMEASURE"] = &SetNotesPerMeasure;
|
||||
|
||||
/* If this is called, the chart does not use the same attacks
|
||||
* as the Song's timing. No other changes are required. */
|
||||
|
||||
+22
-7
@@ -439,16 +439,31 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
|
||||
}
|
||||
}
|
||||
lines.push_back(ssprintf("#TECHCOUNTS:%s;", join(",", asTechCounts).c_str()));
|
||||
|
||||
std::vector<RString> asMeasureInfo;
|
||||
FOREACH_PlayerNumber( pn )
|
||||
|
||||
std::vector<RString> asNpsPerMeasure;
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
const MeasureInfo &ms = in.GetMeasureInfo(pn);
|
||||
asMeasureInfo.push_back(ms.ToString());
|
||||
const std::vector<float> &npsPerMeasure = in.GetNpsPerMeasure(pn);
|
||||
for(unsigned i = 0; i < npsPerMeasure.size(); i++)
|
||||
{
|
||||
asNpsPerMeasure.push_back(ssprintf("%.3f", npsPerMeasure[i]));
|
||||
}
|
||||
}
|
||||
RString allMeasureInfo = "#MEASUREINFO:" + join("|", asMeasureInfo) + ";";
|
||||
lines.push_back(allMeasureInfo);
|
||||
|
||||
lines.push_back( ssprintf( "#NPSPERMEASURE:%s;", join(",",asNpsPerMeasure).c_str() ) );
|
||||
|
||||
std::vector<RString> asNotesPerMeasure;
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
const std::vector<int> ¬esPerMeasure = in.GetNotesPerMeasure(pn);
|
||||
for(unsigned i = 0; i < notesPerMeasure.size(); i++)
|
||||
{
|
||||
asNotesPerMeasure.push_back(ssprintf("%d", notesPerMeasure[i]));
|
||||
}
|
||||
}
|
||||
|
||||
lines.push_back( ssprintf( "#NOTESPERMEASURE:%s;", join(",",asNotesPerMeasure).c_str() ) );
|
||||
|
||||
// NOTE(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
|
||||
|
||||
+1
-1
@@ -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 = 228;
|
||||
const int FILE_CACHE_VERSION = 229;
|
||||
|
||||
/** @brief How long does a song sample last by default? */
|
||||
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
|
||||
|
||||
+70
-21
@@ -59,9 +59,16 @@ Steps::Steps(Song *song): m_StepsType(StepsType_Invalid), m_pSong(song),
|
||||
m_Difficulty(Difficulty_Invalid), m_iMeter(0),
|
||||
m_bAreCachedRadarValuesJustLoaded(false),
|
||||
m_bAreCachedTechCountsValuesJustLoaded(false),
|
||||
m_bAreCachedMeasureInfoJustLoaded(false),
|
||||
m_AreCachedNpsPerMeasureJustLoaded(false),
|
||||
m_AreCachedNotesPerMeasureJustLoaded(false),
|
||||
m_sCredit(""), displayBPMType(DISPLAY_BPM_ACTUAL),
|
||||
specifiedBPMMin(0), specifiedBPMMax(0) {}
|
||||
specifiedBPMMin(0), specifiedBPMMax(0) {
|
||||
m_CachedNpsPerMeasure.resize(NUM_PLAYERS);
|
||||
m_CachedNotesPerMeasure.resize(NUM_PLAYERS);
|
||||
FOREACH_PlayerNumber(pn) {
|
||||
m_PeakNps[pn] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Steps::~Steps()
|
||||
{
|
||||
@@ -411,17 +418,19 @@ void Steps::CalculateMeasureInfo()
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_bAreCachedMeasureInfoJustLoaded )
|
||||
if( m_AreCachedNpsPerMeasureJustLoaded )
|
||||
{
|
||||
m_bAreCachedMeasureInfoJustLoaded = false;
|
||||
m_AreCachedNpsPerMeasureJustLoaded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
NoteData tempNoteData;
|
||||
this->GetNoteData( tempNoteData );
|
||||
|
||||
MeasureInfo measureInfo[NUM_PLAYERS];
|
||||
|
||||
FOREACH_PlayerNumber(pn)
|
||||
m_CachedMeasureInfo[pn]
|
||||
measureInfo[pn]
|
||||
.Zero();
|
||||
|
||||
GAMESTATE->SetProcessedTimingData(this->GetTimingData());
|
||||
@@ -432,7 +441,7 @@ void Steps::CalculateMeasureInfo()
|
||||
NoteDataUtil::SplitCompositeNoteData( tempNoteData, vParts );
|
||||
for( std::size_t pn = 0; pn < std::min(vParts.size(), std::size_t(NUM_PLAYERS)); ++pn )
|
||||
{
|
||||
MeasureInfo::CalculateMeasureInfo(vParts[pn], m_CachedMeasureInfo[pn]);
|
||||
MeasureInfo::CalculateMeasureInfo(vParts[pn], measureInfo[pn]);
|
||||
}
|
||||
}
|
||||
else if (GAMEMAN->GetStepsTypeInfo(this->m_StepsType).m_StepsTypeCategory == StepsTypeCategory_Couple)
|
||||
@@ -441,16 +450,25 @@ void Steps::CalculateMeasureInfo()
|
||||
// XXX: Assumption that couple will always have an even number of notes.
|
||||
const int tracks = tempNoteData.GetNumTracks() / 2;
|
||||
p1.SetNumTracks(tracks);
|
||||
MeasureInfo::CalculateMeasureInfo(tempNoteData, m_CachedMeasureInfo[PLAYER_1]);
|
||||
MeasureInfo::CalculateMeasureInfo(tempNoteData, measureInfo[PLAYER_1]);
|
||||
NoteDataUtil::ShiftTracks(tempNoteData, tracks);
|
||||
tempNoteData.SetNumTracks(tracks);
|
||||
MeasureInfo::CalculateMeasureInfo(tempNoteData, m_CachedMeasureInfo[PLAYER_2]);
|
||||
MeasureInfo::CalculateMeasureInfo(tempNoteData, measureInfo[PLAYER_2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
MeasureInfo::CalculateMeasureInfo(tempNoteData, m_CachedMeasureInfo[0]);
|
||||
std::fill_n( m_CachedMeasureInfo + 1, NUM_PLAYERS-1, m_CachedMeasureInfo[0] );
|
||||
MeasureInfo::CalculateMeasureInfo(tempNoteData, measureInfo[0]);
|
||||
std::fill_n( measureInfo + 1, NUM_PLAYERS-1, measureInfo[0] );
|
||||
}
|
||||
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
m_CachedNpsPerMeasure[pn].assign(measureInfo[pn].npsPerMeasure.begin(), measureInfo[pn].npsPerMeasure.end());
|
||||
|
||||
m_CachedNotesPerMeasure[pn].assign(measureInfo[pn].notesPerMeasure.begin(), measureInfo[pn].notesPerMeasure.end());
|
||||
m_PeakNps[pn] = measureInfo[pn].peakNps;
|
||||
}
|
||||
|
||||
GAMESTATE->SetProcessedTimingData(nullptr);
|
||||
}
|
||||
|
||||
@@ -604,7 +622,11 @@ void Steps::DeAutogen( bool bCopyNoteData )
|
||||
m_iMeter = Real()->m_iMeter;
|
||||
std::copy( Real()->m_CachedRadarValues, Real()->m_CachedRadarValues + NUM_PLAYERS, m_CachedRadarValues );
|
||||
std::copy( Real()->m_CachedTechCounts, Real()->m_CachedTechCounts + NUM_PLAYERS, m_CachedTechCounts );
|
||||
std::copy( Real()->m_CachedMeasureInfo, Real()->m_CachedMeasureInfo + NUM_PLAYERS, m_CachedMeasureInfo );
|
||||
|
||||
m_CachedNpsPerMeasure.assign(Real()->m_CachedNpsPerMeasure.begin(), Real()->m_CachedNpsPerMeasure.end());
|
||||
m_CachedNotesPerMeasure.assign(Real()->m_CachedNotesPerMeasure.begin(), Real()->m_CachedNotesPerMeasure.end());
|
||||
|
||||
|
||||
m_sCredit = Real()->m_sCredit;
|
||||
parent = nullptr;
|
||||
|
||||
@@ -740,11 +762,40 @@ void Steps::SetCachedTechCounts( const TechCounts ts[NUM_PLAYERS] )
|
||||
m_bAreCachedTechCountsValuesJustLoaded = true;
|
||||
}
|
||||
|
||||
void Steps::SetCachedMeasureInfo(const MeasureInfo ms[NUM_PLAYERS])
|
||||
void Steps::SetCachedNpsPerMeasure(std::vector<std::vector<float>>& npsPerMeasure)
|
||||
{
|
||||
DeAutogen();
|
||||
std::copy(ms, ms + NUM_PLAYERS, m_CachedMeasureInfo);
|
||||
m_bAreCachedMeasureInfoJustLoaded = true;
|
||||
if(npsPerMeasure.size() != NUM_PLAYERS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
m_CachedNpsPerMeasure[pn].assign(npsPerMeasure[pn].begin(), npsPerMeasure[pn].end());
|
||||
std::vector<float>::iterator peakNps = std::max_element(npsPerMeasure[pn].begin(), npsPerMeasure[pn].end());
|
||||
if(peakNps != npsPerMeasure[pn].end())
|
||||
{
|
||||
m_PeakNps[pn] = *peakNps;
|
||||
}
|
||||
}
|
||||
m_AreCachedNpsPerMeasureJustLoaded = true;
|
||||
}
|
||||
|
||||
void Steps::SetCachedNotesPerMeasure(std::vector<std::vector<int>>& notesPerMeasure)
|
||||
{
|
||||
DeAutogen();
|
||||
|
||||
if(notesPerMeasure.size() != NUM_PLAYERS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FOREACH_PlayerNumber(pn)
|
||||
{
|
||||
m_CachedNotesPerMeasure[pn].assign(notesPerMeasure[pn].begin(), notesPerMeasure[pn].end());
|
||||
}
|
||||
m_AreCachedNotesPerMeasureJustLoaded = true;
|
||||
}
|
||||
|
||||
RString Steps::GenerateChartKey()
|
||||
@@ -900,8 +951,8 @@ public:
|
||||
if (!lua_isnil(L, 1)) {
|
||||
pn = Enum::Check<PlayerNumber>(L, 1);
|
||||
}
|
||||
MeasureInfo &ts = const_cast<MeasureInfo &>(p->GetMeasureInfo(pn));
|
||||
LuaHelpers::CreateTableFromArray(ts.npsPerMeasure, L);
|
||||
std::vector<float> &ts = const_cast<std::vector<float> &>(p->GetNpsPerMeasure(pn));
|
||||
LuaHelpers::CreateTableFromArray(ts, L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -911,9 +962,8 @@ public:
|
||||
if (!lua_isnil(L, 1)) {
|
||||
pn = Enum::Check<PlayerNumber>(L, 1);
|
||||
}
|
||||
MeasureInfo &ts = const_cast<MeasureInfo &>(p->GetMeasureInfo(pn));
|
||||
LuaHelpers::CreateTableFromArray(ts.notesPerMeasure, L);
|
||||
|
||||
std::vector<int> &ts = const_cast<std::vector<int> &>(p->GetNotesPerMeasure(pn));
|
||||
LuaHelpers::CreateTableFromArray(ts, L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -923,8 +973,7 @@ public:
|
||||
if (!lua_isnil(L, 1)) {
|
||||
pn = Enum::Check<PlayerNumber>(L, 1);
|
||||
}
|
||||
MeasureInfo &ts = const_cast<MeasureInfo &>(p->GetMeasureInfo(pn));
|
||||
lua_pushnumber(L, ts.peakNps);
|
||||
lua_pushnumber(L, p->GetPeakNps(pn));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
+17
-5
@@ -145,7 +145,8 @@ public:
|
||||
void SetMeter( int meter );
|
||||
void SetCachedRadarValues( const RadarValues v[NUM_PLAYERS] );
|
||||
void SetCachedTechCounts(const TechCounts ts[NUM_PLAYERS]);
|
||||
void SetCachedMeasureInfo(const MeasureInfo ms[NUM_PLAYERS]);
|
||||
void SetCachedNpsPerMeasure(std::vector<std::vector<float>>& npsPerMeasure);
|
||||
void SetCachedNotesPerMeasure(std::vector<std::vector<int>>& notesPerMeasure);
|
||||
float PredictMeter() const;
|
||||
|
||||
unsigned GetHash() const;
|
||||
@@ -178,7 +179,10 @@ public:
|
||||
const TechCounts &GetTechCounts(PlayerNumber pn) const { return Real()->m_CachedTechCounts[pn]; }
|
||||
|
||||
void CalculateMeasureInfo();
|
||||
const MeasureInfo &GetMeasureInfo(PlayerNumber pn) const { return Real()->m_CachedMeasureInfo[pn]; }
|
||||
|
||||
const std::vector<float> &GetNpsPerMeasure(PlayerNumber pn) const { return Real()->m_CachedNpsPerMeasure[pn]; }
|
||||
const std::vector<int> &GetNotesPerMeasure(PlayerNumber pn) const { return Real()->m_CachedNotesPerMeasure[pn]; }
|
||||
float GetPeakNps(PlayerNumber pn) const { return Real()->m_PeakNps[pn]; }
|
||||
|
||||
/**
|
||||
* @brief The TimingData used by the Steps.
|
||||
@@ -276,9 +280,17 @@ private:
|
||||
/** @brief The tech stats used for each player */
|
||||
mutable TechCounts m_CachedTechCounts[NUM_PLAYERS];
|
||||
bool m_bAreCachedTechCountsValuesJustLoaded;
|
||||
|
||||
mutable MeasureInfo m_CachedMeasureInfo[NUM_PLAYERS];
|
||||
bool m_bAreCachedMeasureInfoJustLoaded;
|
||||
|
||||
std::vector<std::vector<float>> m_CachedNpsPerMeasure;
|
||||
bool m_AreCachedNpsPerMeasureJustLoaded;
|
||||
|
||||
std::vector<std::vector<int>> m_CachedNotesPerMeasure;
|
||||
bool m_AreCachedNotesPerMeasureJustLoaded;
|
||||
|
||||
float m_PeakNps[NUM_PLAYERS];
|
||||
|
||||
|
||||
|
||||
|
||||
/** @brief The name of the person who created the Steps. */
|
||||
RString m_sCredit;
|
||||
|
||||
Reference in New Issue
Block a user