stage 3 of TimingData changes: changed external interface, enforce encapsulation more strictly
This commit is contained in:
+61
-64
@@ -267,28 +267,29 @@ void AdjustSync::AutosyncTempo()
|
||||
GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fIntercept;
|
||||
const float fScaleBPM = 1.0f/(1.0f - fSlope);
|
||||
TimingData &timing = GAMESTATE->m_pCurSong->m_SongTiming;
|
||||
vector<TimingSegment *> &bpms = timing.m_avpTimingSegments[SEGMENT_BPM];
|
||||
|
||||
const vector<TimingSegment *> &bpms = timing.GetTimingSegments(SEGMENT_BPM);
|
||||
for (unsigned i = 0; i < bpms.size(); i++)
|
||||
{
|
||||
BPMSegment *b = static_cast<BPMSegment *>(bpms[i]);
|
||||
b->SetBPM(b->GetBPM() * fScaleBPM);
|
||||
const BPMSegment *b = ToBPM( bpms[i] );
|
||||
timing.AddSegment( BPMSegment(b->GetRow(), b->GetBPM() * fScaleBPM) );
|
||||
}
|
||||
|
||||
/* We assume that the stops were measured as a number of beats.
|
||||
* Therefore, if we change the bpms, we need to make a similar
|
||||
* change to the stops. */
|
||||
vector<TimingSegment *> &stops = timing.m_avpTimingSegments[SEGMENT_STOP];
|
||||
const vector<TimingSegment *> &stops = timing.GetTimingSegments(SEGMENT_STOP);
|
||||
for (unsigned i = 0; i < stops.size(); i++)
|
||||
{
|
||||
StopSegment *s = static_cast<StopSegment *>(stops[i]);
|
||||
s->SetPause(s->GetPause() * (1.0f - fSlope));
|
||||
const StopSegment *s = ToStop( stops[i] );
|
||||
timing.AddSegment( StopSegment(s->GetRow(), s->GetPause() * (1.0f - fSlope)) );
|
||||
}
|
||||
// Do the same for delays.
|
||||
vector<TimingSegment *> &delays = timing.m_avpTimingSegments[SEGMENT_DELAY];
|
||||
const vector<TimingSegment *> &delays = timing.GetTimingSegments(SEGMENT_DELAY);
|
||||
for (unsigned i = 0; i < delays.size(); i++)
|
||||
{
|
||||
DelaySegment *s = static_cast<DelaySegment *>(delays[i]);
|
||||
s->SetPause(s->GetPause() * (1.0f - fSlope));
|
||||
const DelaySegment *s = ToDelay( delays[i] );
|
||||
timing.AddSegment( DelaySegment(s->GetRow(), s->GetPause() * (1.0f - fSlope)) );
|
||||
}
|
||||
|
||||
SCREENMAN->SystemMessage( AUTOSYNC_CORRECTION_APPLIED.GetValue() );
|
||||
@@ -336,12 +337,13 @@ void AdjustSync::GetSyncChangeTextGlobal( vector<RString> &vsAddTo )
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: needs cleanup still -- vyhd
|
||||
void AdjustSync::GetSyncChangeTextSong( vector<RString> &vsAddTo )
|
||||
{
|
||||
if( GAMESTATE->m_pCurSong.Get() )
|
||||
{
|
||||
unsigned int iOriginalSize = vsAddTo.size();
|
||||
TimingData original = s_vpTimingDataOriginal[0];
|
||||
TimingData &original = s_vpTimingDataOriginal[0];
|
||||
TimingData &testing = GAMESTATE->m_pCurSong->m_SongTiming;
|
||||
|
||||
{
|
||||
@@ -359,79 +361,74 @@ void AdjustSync::GetSyncChangeTextSong( vector<RString> &vsAddTo )
|
||||
}
|
||||
}
|
||||
|
||||
vector<TimingSegment *> &bpmTest = testing.m_avpTimingSegments[SEGMENT_BPM];
|
||||
vector<TimingSegment *> &bpmOrig = original.m_avpTimingSegments[SEGMENT_BPM];
|
||||
const vector<TimingSegment *> &bpmTest = testing.GetTimingSegments(SEGMENT_BPM);
|
||||
const vector<TimingSegment *> &bpmOrig = original.GetTimingSegments(SEGMENT_BPM);
|
||||
for( unsigned i=0; i< bpmTest.size(); i++ )
|
||||
{
|
||||
BPMSegment *bT = static_cast<BPMSegment *>(bpmTest[i]);
|
||||
BPMSegment *bO = static_cast<BPMSegment *>(bpmOrig[i]);
|
||||
float fOld = Quantize( bO->GetBPM(), 0.001f );
|
||||
float fNew = Quantize( bT->GetBPM(), 0.001f );
|
||||
float fDelta = fNew - fOld;
|
||||
float fNew = Quantize( ToBPM(bpmTest[i])->GetBPM(), 0.001f );
|
||||
float fOld = Quantize( ToBPM(bpmOrig[i])->GetBPM(), 0.001f );
|
||||
|
||||
if( fabsf(fDelta) > 0.0001f )
|
||||
if( fabsf(fNew - fOld) < 1e-4 )
|
||||
continue;
|
||||
|
||||
if ( i >= 4 )
|
||||
{
|
||||
if ( i >= 4 )
|
||||
{
|
||||
vsAddTo.push_back(ETC.GetValue());
|
||||
break;
|
||||
}
|
||||
vsAddTo.push_back( ssprintf(
|
||||
TEMPO_SEGMENT_FROM.GetValue(),
|
||||
FormatNumberAndSuffix(i+1).c_str(),
|
||||
fOld,
|
||||
fNew ) );
|
||||
vsAddTo.push_back(ETC.GetValue());
|
||||
break;
|
||||
}
|
||||
|
||||
RString s = ssprintf( TEMPO_SEGMENT_FROM.GetValue(),
|
||||
FormatNumberAndSuffix(i+1).c_str(), fOld, fNew );
|
||||
|
||||
vsAddTo.push_back( s );
|
||||
}
|
||||
|
||||
vector<TimingSegment *> &stopTest = testing.m_avpTimingSegments[SEGMENT_STOP];
|
||||
vector<TimingSegment *> &stopOrig = original.m_avpTimingSegments[SEGMENT_STOP];
|
||||
const vector<TimingSegment *> &stopTest = testing.GetTimingSegments(SEGMENT_STOP);
|
||||
const vector<TimingSegment *> &stopOrig = original.GetTimingSegments(SEGMENT_STOP);
|
||||
|
||||
for( unsigned i=0; i< stopTest.size(); i++ )
|
||||
{
|
||||
StopSegment *sT = static_cast<StopSegment *>(stopTest[i]);
|
||||
StopSegment *sO = static_cast<StopSegment *>(stopOrig[i]);
|
||||
float fOld = Quantize( sO->GetPause(), 0.001f );
|
||||
float fNew = Quantize( sT->GetPause(), 0.001f );
|
||||
float fOld = Quantize( ToStop(stopOrig[i])->GetPause(), 0.001f );
|
||||
float fNew = Quantize( ToStop(stopTest[i])->GetPause(), 0.001f );
|
||||
float fDelta = fNew - fOld;
|
||||
|
||||
if( fabsf(fDelta) > 0.0001f )
|
||||
if( fabsf(fDelta) < 1e-4 )
|
||||
continue;
|
||||
|
||||
if ( i >= 4 )
|
||||
{
|
||||
if ( i >= 4 )
|
||||
{
|
||||
vsAddTo.push_back(ETC.GetValue());
|
||||
break;
|
||||
}
|
||||
vsAddTo.push_back( ssprintf(
|
||||
CHANGED_STOP.GetValue(),
|
||||
i+1,
|
||||
fOld,
|
||||
fNew ) );
|
||||
vsAddTo.push_back(ETC.GetValue());
|
||||
break;
|
||||
}
|
||||
|
||||
RString s = ssprintf( CHANGED_STOP.GetValue(), i+1, fOld, fNew, fDelta );
|
||||
vsAddTo.push_back( s );
|
||||
}
|
||||
|
||||
vector<TimingSegment *> &delyTest = testing.m_avpTimingSegments[SEGMENT_DELAY];
|
||||
vector<TimingSegment *> &delyOrig = original.m_avpTimingSegments[SEGMENT_DELAY];
|
||||
|
||||
const vector<TimingSegment *> &delyTest = testing.GetTimingSegments(SEGMENT_DELAY);
|
||||
const vector<TimingSegment *> &delyOrig = original.GetTimingSegments(SEGMENT_DELAY);
|
||||
|
||||
for( unsigned i=0; i< delyTest.size(); i++ )
|
||||
{
|
||||
DelaySegment *sT = static_cast<DelaySegment *>(delyTest[i]);
|
||||
DelaySegment *sO = static_cast<DelaySegment *>(delyOrig[i]);
|
||||
float fOld = Quantize( sO->GetPause(), 0.001f );
|
||||
float fNew = Quantize( sT->GetPause(), 0.001f );
|
||||
if( delyTest[i] == delyOrig[i] )
|
||||
continue;
|
||||
|
||||
float fOld = Quantize( ToDelay(delyOrig[i])->GetPause(), 0.001f );
|
||||
float fNew = Quantize( ToDelay(delyTest[i])->GetPause(), 0.001f );
|
||||
float fDelta = fNew - fOld;
|
||||
|
||||
if( fabsf(fDelta) > 0.0001f )
|
||||
|
||||
if( fabsf(fDelta) < 1e-4 )
|
||||
continue;
|
||||
|
||||
if ( i >= 4 )
|
||||
{
|
||||
if ( i >= 4 )
|
||||
{
|
||||
vsAddTo.push_back(ETC.GetValue());
|
||||
break;
|
||||
}
|
||||
vsAddTo.push_back( ssprintf(
|
||||
CHANGED_STOP.GetValue(),
|
||||
i+1,
|
||||
fOld,
|
||||
fNew ) );
|
||||
vsAddTo.push_back(ETC.GetValue());
|
||||
break;
|
||||
}
|
||||
|
||||
RString s = ssprintf( CHANGED_STOP.GetValue(),
|
||||
i+1, fOld, fNew, fDelta );
|
||||
vsAddTo.push_back( s );
|
||||
}
|
||||
|
||||
if( vsAddTo.size() > iOriginalSize && s_fAverageError > 0.0f )
|
||||
|
||||
+3
-3
@@ -421,8 +421,8 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac
|
||||
const TimingData &timing = m_pSong->m_SongTiming;
|
||||
|
||||
// change BG every time signature change or 4 measures
|
||||
const vector<TimingSegment *> &tSigs = timing.m_avpTimingSegments[SEGMENT_TIME_SIG];
|
||||
|
||||
const vector<TimingSegment *> &tSigs = timing.GetTimingSegments(SEGMENT_TIME_SIG);
|
||||
|
||||
for (unsigned i = 0; i < tSigs.size(); i++)
|
||||
{
|
||||
TimeSignatureSegment *ts = static_cast<TimeSignatureSegment *>(tSigs[i]);
|
||||
@@ -448,7 +448,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac
|
||||
}
|
||||
|
||||
// change BG every BPM change that is at the beginning of a measure
|
||||
const vector<TimingSegment *> &bpms = timing.m_avpTimingSegments[SEGMENT_BPM];
|
||||
const vector<TimingSegment *> &bpms = timing.GetTimingSegments(SEGMENT_BPM);
|
||||
for( unsigned i=0; i<bpms.size(); i++ )
|
||||
{
|
||||
bool bAtBeginningOfMeasure = false;
|
||||
|
||||
@@ -60,8 +60,8 @@ struct MusicPlaying
|
||||
RageSound *m_Music;
|
||||
MusicPlaying( RageSound *Music )
|
||||
{
|
||||
m_Timing.AddSegment( SEGMENT_BPM, new BPMSegment(0,120) );
|
||||
m_NewTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0,120) );
|
||||
m_Timing.AddSegment( BPMSegment(0,120) );
|
||||
m_NewTiming.AddSegment( BPMSegment(0,120) );
|
||||
m_bHasTiming = false;
|
||||
m_bTimingDelayed = false;
|
||||
m_bApplyMusicRate = false;
|
||||
|
||||
+32
-28
@@ -822,16 +822,20 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
const TimingData *pTiming = &m_pPlayerState->GetDisplayedTiming();
|
||||
const vector<TimingSegment *> *segs = pTiming->m_avpTimingSegments;
|
||||
const vector<TimingSegment*>* segs[NUM_TimingSegmentType];
|
||||
|
||||
FOREACH_TimingSegmentType( tst )
|
||||
segs[tst] = &(pTiming->GetTimingSegments(tst));
|
||||
|
||||
unsigned i = 0;
|
||||
// Draw beat bars
|
||||
if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && pTiming != NULL )
|
||||
{
|
||||
const vector<TimingSegment *> &tSigs = segs[SEGMENT_TIME_SIG];
|
||||
const vector<TimingSegment *> &tSigs = *segs[SEGMENT_TIME_SIG];
|
||||
int iMeasureIndex = 0;
|
||||
for (i = 0; i < tSigs.size(); i++)
|
||||
{
|
||||
TimeSignatureSegment *ts = static_cast<TimeSignatureSegment *>(tSigs[i]);
|
||||
const TimeSignatureSegment *ts = ToTimeSignature(tSigs[i]);
|
||||
int iSegmentEndRow = (i + 1 == tSigs.size()) ? iLastRowToDraw : tSigs[i+1]->GetRow();
|
||||
|
||||
// beat bars every 16th note
|
||||
@@ -874,9 +878,9 @@ void NoteField::DrawPrimitives()
|
||||
// Scroll text
|
||||
if( GAMESTATE->m_bIsUsingStepTiming )
|
||||
{
|
||||
for (i = 0; i < segs[SEGMENT_SCROLL].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_SCROLL]->size(); i++)
|
||||
{
|
||||
ScrollSegment *seg = static_cast<ScrollSegment *>(segs[SEGMENT_SCROLL][i]);
|
||||
ScrollSegment *seg = ToScroll( segs[SEGMENT_SCROLL]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -887,9 +891,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// BPM text
|
||||
for (i = 0; i < segs[SEGMENT_BPM].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_BPM]->size(); i++)
|
||||
{
|
||||
BPMSegment *seg = static_cast<BPMSegment *>(segs[SEGMENT_BPM][i]);
|
||||
const BPMSegment *seg = ToBPM( segs[SEGMENT_BPM]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -899,9 +903,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Freeze text
|
||||
for (i = 0; i < segs[SEGMENT_STOP].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_STOP]->size(); i++)
|
||||
{
|
||||
StopSegment *seg = static_cast<StopSegment *>(segs[SEGMENT_STOP][i]);
|
||||
const StopSegment *seg = ToStop( segs[SEGMENT_STOP]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -911,9 +915,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Delay text
|
||||
for (i = 0; i < segs[SEGMENT_DELAY].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_DELAY]->size(); i++)
|
||||
{
|
||||
DelaySegment *seg = static_cast<DelaySegment *>(segs[SEGMENT_DELAY][i]);
|
||||
const DelaySegment *seg = ToDelay( segs[SEGMENT_DELAY]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -923,9 +927,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Warp text
|
||||
for (i = 0; i < segs[SEGMENT_WARP].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_WARP]->size(); i++)
|
||||
{
|
||||
WarpSegment *seg = static_cast<WarpSegment *>(segs[SEGMENT_WARP][i]);
|
||||
const WarpSegment *seg = ToWarp( segs[SEGMENT_WARP]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -935,9 +939,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Time Signature text
|
||||
for (i = 0; i < segs[SEGMENT_TIME_SIG].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_TIME_SIG]->size(); i++)
|
||||
{
|
||||
TimeSignatureSegment *seg = static_cast<TimeSignatureSegment *>(segs[SEGMENT_TIME_SIG][i]);
|
||||
const TimeSignatureSegment *seg = ToTimeSignature( segs[SEGMENT_TIME_SIG]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -947,9 +951,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Tickcount text
|
||||
for (i = 0; i < segs[SEGMENT_TICKCOUNT].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_TICKCOUNT]->size(); i++)
|
||||
{
|
||||
TickcountSegment *seg = static_cast<TickcountSegment *>(segs[SEGMENT_TICKCOUNT][i]);
|
||||
const TickcountSegment *seg = ToTickcount( segs[SEGMENT_TICKCOUNT]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -957,11 +961,11 @@ void NoteField::DrawPrimitives()
|
||||
DrawTickcountText( fBeat, seg->GetTicks() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Combo text
|
||||
for (i = 0; i < segs[SEGMENT_COMBO].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_COMBO]->size(); i++)
|
||||
{
|
||||
ComboSegment *seg = static_cast<ComboSegment *>(segs[SEGMENT_COMBO][i]);
|
||||
const ComboSegment *seg = ToCombo( segs[SEGMENT_COMBO]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -971,9 +975,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Label text
|
||||
for (i = 0; i < segs[SEGMENT_LABEL].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_LABEL]->size(); i++)
|
||||
{
|
||||
LabelSegment *seg = static_cast<LabelSegment *>(segs[SEGMENT_LABEL][i]);
|
||||
const LabelSegment *seg = ToLabel( segs[SEGMENT_LABEL]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -983,9 +987,9 @@ void NoteField::DrawPrimitives()
|
||||
}
|
||||
|
||||
// Speed text
|
||||
for (i = 0; i < segs[SEGMENT_SPEED].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_SPEED]->size(); i++)
|
||||
{
|
||||
SpeedSegment *seg = static_cast<SpeedSegment *>(segs[SEGMENT_SPEED][i]);
|
||||
const SpeedSegment *seg = ToSpeed( segs[SEGMENT_SPEED]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -994,11 +998,11 @@ void NoteField::DrawPrimitives()
|
||||
seg->GetDelay(), seg->GetUnit() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fake text
|
||||
for (i = 0; i < segs[SEGMENT_FAKE].size(); i++)
|
||||
for (i = 0; i < segs[SEGMENT_FAKE]->size(); i++)
|
||||
{
|
||||
FakeSegment *seg = static_cast<FakeSegment *>(segs[SEGMENT_FAKE][i]);
|
||||
const FakeSegment *seg = ToFake( segs[SEGMENT_FAKE]->at(i) );
|
||||
if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw )
|
||||
{
|
||||
float fBeat = seg->GetBeat();
|
||||
@@ -1088,7 +1092,7 @@ void NoteField::DrawPrimitives()
|
||||
ASSERT( iter[j] == GAMESTATE->m_pCurSong->GetBackgroundChanges(j).end() );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if( IS_ON_SCREEN(fLowestBeat) )
|
||||
{
|
||||
vector<RString> vsBGChanges;
|
||||
|
||||
+13
-22
@@ -585,24 +585,20 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
|
||||
else if( sValueName.EqualsNoCase("BPM") )
|
||||
{
|
||||
const float fBPM = StringToFloat( sParams[1] );
|
||||
|
||||
if( PREFSMAN->m_bQuirksMode )
|
||||
|
||||
if( unlikely(fBPM <= 0.0f && !PREFSMAN->m_bQuirksMode) )
|
||||
{
|
||||
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, fBPM) );
|
||||
LOG->UserLog("Song file", sPath, "has an invalid BPM change at beat %f, BPM %f.",
|
||||
0.0f, fBPM );
|
||||
}
|
||||
else{
|
||||
if( fBPM > 0.0f )
|
||||
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, fBPM) );
|
||||
else
|
||||
LOG->UserLog("Song file",
|
||||
sPath,
|
||||
"has an invalid BPM change at beat %f, BPM %f.",
|
||||
0.0f, fBPM );
|
||||
else
|
||||
{
|
||||
out.m_SongTiming.AddSegment( BPMSegment(0, fBPM) );
|
||||
}
|
||||
}
|
||||
else if( sValueName.EqualsNoCase("DISPLAYBPM") )
|
||||
{
|
||||
// #DISPLAYBPM:[xxx..xxx]|[xxx]|[*];
|
||||
// #DISPLAYBPM:[xxx..xxx]|[xxx]|[*];
|
||||
int iMin, iMax;
|
||||
/* We can't parse this as a float with sscanf, since '.' is a valid
|
||||
* character in a float. (We could do it with a regex, but it's not
|
||||
@@ -626,7 +622,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
|
||||
|
||||
else if( sValueName.EqualsNoCase("GAP") )
|
||||
// the units of GAP is 1/1000 second
|
||||
out.m_SongTiming.m_fBeat0OffsetInSeconds = -StringToInt( sParams[1] ) / 1000.0f;
|
||||
out.m_SongTiming.m_fBeat0OffsetInSeconds = -StringToInt(sParams[1]) / 1000.0f;
|
||||
|
||||
else if( sValueName.EqualsNoCase("SAMPLESTART") )
|
||||
out.m_fMusicSampleStartSeconds = ParseBrokenDWITimestamp(sParams[1], sParams[2], sParams[3]);
|
||||
@@ -650,8 +646,8 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
|
||||
}
|
||||
int iFreezeRow = BeatToNoteRow( StringToFloat(arrayFreezeValues[0]) / 4.0f );
|
||||
float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ) / 1000.0f;
|
||||
|
||||
out.m_SongTiming.AddSegment( SEGMENT_STOP, new StopSegment(iFreezeRow, fFreezeSeconds) );
|
||||
|
||||
out.m_SongTiming.AddSegment( StopSegment(iFreezeRow, fFreezeSeconds) );
|
||||
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", fFreezeBeat, fFreezeSeconds );
|
||||
}
|
||||
}
|
||||
@@ -670,19 +666,14 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set<RString> &Bla
|
||||
LOG->UserLog( "Song file", sPath, "has an invalid CHANGEBPM: '%s'.", arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int iStartIndex = BeatToNoteRow( StringToFloat(arrayBPMChangeValues[0]) / 4.0f );
|
||||
float fBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
BPMSegment * bs = new BPMSegment( iStartIndex, fBPM );
|
||||
out.m_SongTiming.AddSegment( SEGMENT_BPM, bs );
|
||||
}
|
||||
out.m_SongTiming.AddSegment( BPMSegment(iStartIndex, fBPM) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog( "Song file", sPath, "has an invalid BPM change at beat %f, BPM %f.",
|
||||
NoteRowToBeat(iStartIndex), fBPM );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
-8
@@ -15,13 +15,9 @@ void NotesLoaderJson::GetApplicableFiles( const RString &sPath, vector<RString>
|
||||
GetDirListing( sPath + RString("*.json"), out );
|
||||
}
|
||||
|
||||
static void Deserialize(TimingSegment &seg_, const Json::Value &root)
|
||||
static void Deserialize( TimingSegment *seg, const Json::Value &root )
|
||||
{
|
||||
TimingSegment *seg = &seg_;
|
||||
|
||||
float fBeat = root["Beat"].asDouble();
|
||||
seg->SetBeat(fBeat);
|
||||
switch (seg->GetType())
|
||||
switch( seg->GetType() )
|
||||
{
|
||||
case SEGMENT_BPM:
|
||||
{
|
||||
@@ -39,10 +35,33 @@ static void Deserialize(TimingSegment &seg_, const Json::Value &root)
|
||||
}
|
||||
}
|
||||
|
||||
static void Deserialize(BPMSegment &seg, const Json::Value &root)
|
||||
{
|
||||
Deserialize( static_cast<TimingSegment*>(&seg), root );
|
||||
}
|
||||
|
||||
static void Deserialize(StopSegment &seg, const Json::Value &root)
|
||||
{
|
||||
Deserialize( static_cast<TimingSegment*>(&seg), root );
|
||||
}
|
||||
|
||||
static void Deserialize(TimingData &td, const Json::Value &root)
|
||||
{
|
||||
JsonUtil::DeserializeVectorPointers( td.m_avpTimingSegments[SEGMENT_BPM], Deserialize, root["BpmSegments"] );
|
||||
JsonUtil::DeserializeVectorPointers( td.m_avpTimingSegments[SEGMENT_STOP], Deserialize, root["StopSegments"] );
|
||||
vector<BPMSegment*> vBPMs;
|
||||
vector<StopSegment*> vStops;
|
||||
JsonUtil::DeserializeVectorPointers( vBPMs, Deserialize, root["BpmSegments"] );
|
||||
JsonUtil::DeserializeVectorPointers( vStops, Deserialize, root["StopSegments"] );
|
||||
|
||||
for( unsigned i = 0; i < vBPMs.size(); ++i )
|
||||
{
|
||||
td.AddSegment( *vBPMs[i] );
|
||||
delete vBPMs[i];
|
||||
}
|
||||
for( unsigned i = 0; i < vStops.size(); ++i )
|
||||
{
|
||||
td.AddSegment( *vStops[i] );
|
||||
delete vStops[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void Deserialize(LyricSegment &o, const Json::Value &root)
|
||||
|
||||
+16
-14
@@ -17,7 +17,7 @@ static void HandleBunki( TimingData &timing, const float fEarlyBPM,
|
||||
const float beat = (fPos + fGap) * BeatsPerSecond;
|
||||
LOG->Trace( "BPM %f, BPS %f, BPMPos %f, beat %f",
|
||||
fEarlyBPM, BeatsPerSecond, fPos, beat );
|
||||
timing.AddSegment( SEGMENT_BPM, new BPMSegment(BeatToNoteRow(beat), fCurBPM) );
|
||||
timing.AddSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) );
|
||||
}
|
||||
|
||||
static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool bKIUCompliant )
|
||||
@@ -59,7 +59,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool
|
||||
else if( sValueName=="BPM" )
|
||||
{
|
||||
BPM1 = StringToFloat(sParams[1]);
|
||||
stepsTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, BPM1) );
|
||||
stepsTiming.AddSegment( BPMSegment(0, BPM1) );
|
||||
}
|
||||
else if( sValueName=="BPM2" )
|
||||
{
|
||||
@@ -136,7 +136,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool
|
||||
LOG->UserLog( "Song file", sPath, "has an invalid tick count: %d.", iTickCount );
|
||||
return false;
|
||||
}
|
||||
stepsTiming.AddSegment( SEGMENT_TICKCOUNT, new TickcountSegment(0, iTickCount));
|
||||
stepsTiming.AddSegment( TickcountSegment(0, iTickCount));
|
||||
}
|
||||
|
||||
else if( sValueName=="DIFFICULTY" )
|
||||
@@ -332,7 +332,7 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool
|
||||
// be 0. if the tickcount is non a stepmania standard then it will be adapted, a scroll
|
||||
// segment will then be added based on approximations. -DaisuMaster
|
||||
// eh better do it considering the tickcount (high tickcounts)
|
||||
|
||||
|
||||
// I'm making some experiments, please spare me...
|
||||
//continue;
|
||||
|
||||
@@ -367,7 +367,8 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool
|
||||
else if (BeginsWith(sRowString, "|M") || BeginsWith(sRowString, "|C"))
|
||||
{
|
||||
// multipliers/combo
|
||||
stepsTiming.SetHitComboAtBeat( fCurBeat, static_cast<int>(numTemp) );
|
||||
ComboSegment seg( BeatToNoteRow(fCurBeat), int(numTemp) );
|
||||
stepsTiming.AddSegment( seg );
|
||||
}
|
||||
else if (BeginsWith(sRowString, "|S"))
|
||||
{
|
||||
@@ -380,7 +381,8 @@ static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool
|
||||
else if (BeginsWith(sRowString, "|X"))
|
||||
{
|
||||
// scroll segments
|
||||
stepsTiming.SetScrollAtBeat( fCurBeat, numTemp );
|
||||
ScrollSegment seg = ScrollSegment( BeatToNoteRow(fCurBeat), numTemp );
|
||||
stepsTiming.AddSegment( seg );
|
||||
//return true;
|
||||
}
|
||||
|
||||
@@ -511,12 +513,12 @@ static void ProcessTickcounts( const RString & value, int & ticks, TimingData &
|
||||
* and stops. It will be called again in LoadFromKSFFile for the
|
||||
* actual steps. */
|
||||
ticks = StringToInt( value );
|
||||
ticks = ticks > 0 ? ticks : 4;
|
||||
// add a tickcount for those using the [Player]
|
||||
// CheckpointsUseTimeSignatures metric. -aj
|
||||
// It's not with timesigs now -DaisuMaster
|
||||
TickcountSegment * tcs = new TickcountSegment(0, ticks > ROWS_PER_BEAT ? ROWS_PER_BEAT : ticks);
|
||||
timing.AddSegment( SEGMENT_TICKCOUNT, tcs );
|
||||
CLAMP( ticks, 0, ROWS_PER_BEAT );
|
||||
|
||||
if( ticks == 0 )
|
||||
ticks = TickcountSegment::DEFAULT_TICK_COUNT;
|
||||
|
||||
timing.AddSegment( TickcountSegment(0, ticks) );
|
||||
}
|
||||
|
||||
static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant )
|
||||
@@ -557,7 +559,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
else if( sValueName=="BPM" )
|
||||
{
|
||||
BPM1 = StringToFloat(sParams[1]);
|
||||
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, BPM1) );
|
||||
out.m_SongTiming.AddSegment( BPMSegment(0, BPM1) );
|
||||
}
|
||||
else if( sValueName=="BPM2" )
|
||||
{
|
||||
@@ -584,7 +586,7 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant
|
||||
SMGap1 = -StringToFloat( sParams[1] )/100;
|
||||
out.m_SongTiming.m_fBeat0OffsetInSeconds = SMGap1;
|
||||
}
|
||||
// This is currently required for more accurate KIU BPM changes.
|
||||
// This is currently required for more accurate KIU BPM changes.
|
||||
else if( sValueName=="STARTTIME2" )
|
||||
{
|
||||
bKIUCompliant = true;
|
||||
|
||||
+7
-12
@@ -592,7 +592,7 @@ static void ReadGlobalTags( const RString &sPath, const NameToData_t &mapNameToD
|
||||
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
out.m_SongTiming.AddSegment( SEGMENT_BPM, new BPMSegment(0, fBPM) );
|
||||
out.m_SongTiming.AddSegment( BPMSegment(0, fBPM) );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(0), fBPM );
|
||||
}
|
||||
else
|
||||
@@ -697,9 +697,8 @@ static void ReadGlobalTags( const RString &sPath, const NameToData_t &mapNameToD
|
||||
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
BPMSegment * newSeg = new BPMSegment( BeatToNoteRow(fBeat), fBPM );
|
||||
out.m_SongTiming.AddSegment( SEGMENT_BPM, newSeg );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, newSeg->GetBPM() );
|
||||
out.m_SongTiming.AddSegment( BPMSegment(BeatToNoteRow(fBeat), fBPM) );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, fBPM );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -724,9 +723,8 @@ static void ReadGlobalTags( const RString &sPath, const NameToData_t &mapNameToD
|
||||
float fBeats = StringToFloat( sBeats ) / 48.0f;
|
||||
float fFreezeSecs = fBeats / fBPS;
|
||||
|
||||
StopSegment * newSeg = new StopSegment( BeatToNoteRow(fBeat), fFreezeSecs );
|
||||
out.m_SongTiming.AddSegment( SEGMENT_STOP, newSeg );
|
||||
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg->GetPause() );
|
||||
out.m_SongTiming.AddSegment( StopSegment(BeatToNoteRow(fBeat), fFreezeSecs) );
|
||||
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, fFreezeSecs );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -753,12 +751,9 @@ static void ReadGlobalTags( const RString &sPath, const NameToData_t &mapNameToD
|
||||
|
||||
if( fBPM > 0.0f )
|
||||
{
|
||||
BPMSegment * newSeg = new BPMSegment( iStepIndex, fBPM );
|
||||
out.m_SongTiming.AddSegment( SEGMENT_BPM, newSeg );
|
||||
out.m_SongTiming.AddSegment( BPMSegment(iStepIndex, fBPM) );
|
||||
LOG->Trace("Inserting new BPM change at beat %f, BPM %f",
|
||||
newSeg->GetBeat(),
|
||||
newSeg->GetBPM() );
|
||||
|
||||
NoteRowToBeat(iStepIndex), fBPM );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+65
-86
@@ -227,12 +227,12 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString line, const int rowsP
|
||||
arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
bNotEmpty = true;
|
||||
|
||||
|
||||
const float fBeat = RowToBeat( arrayBPMChangeValues[0], rowsPerBeat );
|
||||
const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] );
|
||||
|
||||
|
||||
if( fNewBPM < 0.0f )
|
||||
{
|
||||
negBeat = fBeat;
|
||||
@@ -244,9 +244,8 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString line, const int rowsP
|
||||
if( negBPM < 0 )
|
||||
{
|
||||
float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat);
|
||||
out.AddSegment(SEGMENT_WARP,
|
||||
new WarpSegment(BeatToNoteRow(negBeat), endBeat - negBeat));
|
||||
|
||||
out.AddSegment( WarpSegment(BeatToNoteRow(negBeat), endBeat - negBeat) );
|
||||
|
||||
negBeat = -1;
|
||||
negBPM = 1;
|
||||
}
|
||||
@@ -260,18 +259,16 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString line, const int rowsP
|
||||
// add in a warp.
|
||||
if( highspeedBeat > 0 )
|
||||
{
|
||||
out.AddSegment(SEGMENT_WARP,
|
||||
new WarpSegment(BeatToNoteRow(highspeedBeat), fBeat - highspeedBeat) );
|
||||
out.AddSegment( WarpSegment(BeatToNoteRow(highspeedBeat), fBeat - highspeedBeat) );
|
||||
highspeedBeat = -1;
|
||||
}
|
||||
{
|
||||
out.AddSegment(SEGMENT_BPM,
|
||||
new BPMSegment(BeatToNoteRow(fBeat), fNewBPM));
|
||||
out.AddSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return bNotEmpty;
|
||||
}
|
||||
|
||||
@@ -283,7 +280,7 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows
|
||||
// Prepare variables for negative stop conversion.
|
||||
float negBeat = -1;
|
||||
float negPause = 0;
|
||||
|
||||
|
||||
for( unsigned f=0; f<arrayFreezeExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayFreezeValues;
|
||||
@@ -296,26 +293,26 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows
|
||||
arrayFreezeExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const float fFreezeBeat = RowToBeat( arrayFreezeValues[0], rowsPerBeat );
|
||||
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 oldBPM = out.GetBPMAtRow(BeatToNoteRow(negBeat));
|
||||
float fSecondsPerBeat = 60 / oldBPM;
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
|
||||
if( negBeat + fSkipBeats > fFreezeBeat )
|
||||
fSkipBeats = fFreezeBeat - negBeat;
|
||||
|
||||
out.AddSegment(SEGMENT_WARP, new WarpSegment(BeatToNoteRow(negBeat), fSkipBeats));
|
||||
|
||||
|
||||
out.AddSegment( WarpSegment(BeatToNoteRow(negBeat), fSkipBeats));
|
||||
|
||||
negBeat = -1;
|
||||
negPause = 0;
|
||||
}
|
||||
|
||||
|
||||
if( fFreezeSeconds < 0.0f )
|
||||
{
|
||||
negBeat = fFreezeBeat;
|
||||
@@ -323,20 +320,18 @@ void SMLoader::ProcessStops( TimingData &out, const RString line, const int rows
|
||||
}
|
||||
else if( fFreezeSeconds > 0.0f )
|
||||
{
|
||||
out.AddSegment(SEGMENT_STOP,
|
||||
new StopSegment(BeatToNoteRow(fFreezeBeat), fFreezeSeconds));
|
||||
out.AddSegment( StopSegment(BeatToNoteRow(fFreezeBeat), fFreezeSeconds) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Process the prior stop if there was one.
|
||||
if( negPause > 0 )
|
||||
{
|
||||
BPMSegment * oldBPM = out.GetBPMSegmentAtBeat(negBeat);
|
||||
float fSecondsPerBeat = 60 / oldBPM->GetBPM();
|
||||
float oldBPM = out.GetBPMAtBeat(negBeat);
|
||||
float fSecondsPerBeat = 60 / oldBPM;
|
||||
float fSkipBeats = negPause / fSecondsPerBeat;
|
||||
|
||||
out.AddSegment(SEGMENT_WARP, new WarpSegment(BeatToNoteRow(negBeat), fSkipBeats));
|
||||
|
||||
out.AddSegment( WarpSegment(BeatToNoteRow(negBeat), fSkipBeats) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +339,7 @@ void SMLoader::ProcessDelays( TimingData &out, const RString line, const int row
|
||||
{
|
||||
vector<RString> arrayDelayExpressions;
|
||||
split( line, ",", arrayDelayExpressions );
|
||||
|
||||
|
||||
for( unsigned f=0; f<arrayDelayExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayDelayValues;
|
||||
@@ -357,17 +352,12 @@ void SMLoader::ProcessDelays( TimingData &out, const RString line, const int row
|
||||
arrayDelayExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
const float fFreezeBeat = RowToBeat( arrayDelayValues[0], rowsPerBeat );
|
||||
const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] );
|
||||
|
||||
DelaySegment * new_seg = new DelaySegment(BeatToNoteRow(fFreezeBeat),
|
||||
fFreezeSeconds);
|
||||
|
||||
// LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
|
||||
|
||||
if(fFreezeSeconds > 0.0f)
|
||||
out.AddSegment( SEGMENT_DELAY, new_seg );
|
||||
out.AddSegment( DelaySegment(BeatToNoteRow(fFreezeBeat), fFreezeSeconds) );
|
||||
else
|
||||
LOG->UserLog(
|
||||
"Song file",
|
||||
@@ -397,11 +387,8 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const
|
||||
}
|
||||
|
||||
const float fBeat = RowToBeat( vs2[0], rowsPerBeat );
|
||||
|
||||
TimeSignatureSegment * seg =
|
||||
new TimeSignatureSegment( BeatToNoteRow(fBeat),
|
||||
StringToInt( vs2[1] ),
|
||||
StringToInt( vs2[2] ));
|
||||
const int iNumerator = StringToInt( vs2[1] );
|
||||
const int iDenominator = StringToInt( vs2[2] );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
@@ -411,26 +398,26 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const
|
||||
fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg->GetNum() < 1 )
|
||||
|
||||
if( iNumerator < 1 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
this->GetSongTitle(),
|
||||
"has an invalid time signature change with beat %f, iNumerator %i.",
|
||||
fBeat, seg->GetNum() );
|
||||
fBeat, iNumerator );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg->GetDen() < 1 )
|
||||
|
||||
if( iDenominator < 1 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
this->GetSongTitle(),
|
||||
"has an invalid time signature change with beat %f, iDenominator %i.",
|
||||
fBeat, seg->GetDen() );
|
||||
fBeat, iDenominator );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddSegment( SEGMENT_TIME_SIG, seg );
|
||||
|
||||
out.AddSegment( TimeSignatureSegment(BeatToNoteRow(fBeat), iNumerator, iDenominator) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,7 +425,7 @@ void SMLoader::ProcessTickcounts( TimingData &out, const RString line, const int
|
||||
{
|
||||
vector<RString> arrayTickcountExpressions;
|
||||
split( line, ",", arrayTickcountExpressions );
|
||||
|
||||
|
||||
for( unsigned f=0; f<arrayTickcountExpressions.size(); f++ )
|
||||
{
|
||||
vector<RString> arrayTickcountValues;
|
||||
@@ -451,12 +438,11 @@ void SMLoader::ProcessTickcounts( TimingData &out, const RString line, const int
|
||||
arrayTickcountExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const float fTickcountBeat = RowToBeat( arrayTickcountValues[0], rowsPerBeat );
|
||||
int iTicks = clamp(atoi( arrayTickcountValues[1] ), 0, ROWS_PER_BEAT);
|
||||
|
||||
out.AddSegment( SEGMENT_TICKCOUNT,
|
||||
new TickcountSegment(BeatToNoteRow(fTickcountBeat), iTicks) );
|
||||
|
||||
out.AddSegment( TickcountSegment(BeatToNoteRow(fTickcountBeat), iTicks) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -464,22 +450,22 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row
|
||||
{
|
||||
vector<RString> vs1;
|
||||
split( line, ",", vs1 );
|
||||
|
||||
|
||||
FOREACH_CONST( RString, vs1, s1 )
|
||||
{
|
||||
vector<RString> vs2;
|
||||
split( *s1, "=", vs2 );
|
||||
|
||||
|
||||
if( vs2[0] == 0 && vs2.size() == 2 ) // First one always seems to have 2.
|
||||
{
|
||||
vs2.push_back("0");
|
||||
}
|
||||
|
||||
|
||||
if( vs2.size() == 3 ) // use beats by default.
|
||||
{
|
||||
vs2.push_back("0");
|
||||
}
|
||||
|
||||
|
||||
if( vs2.size() < 4 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
@@ -488,39 +474,35 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row
|
||||
static_cast<int>(vs2.size()) );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const float fBeat = RowToBeat( vs2[0], rowsPerBeat );
|
||||
|
||||
SpeedSegment * seg = new SpeedSegment( BeatToNoteRow(fBeat),
|
||||
StringToFloat( vs2[1] ),
|
||||
StringToFloat( vs2[2] ));
|
||||
const float fRatio = StringToFloat( vs2[1] );
|
||||
const float fDelay = StringToFloat( vs2[2] );
|
||||
|
||||
// XXX: ugly...
|
||||
int iUnit = StringToInt(vs2[3]);
|
||||
SpeedSegment::BaseUnit unit = (iUnit == 0) ?
|
||||
SpeedSegment::UNIT_BEATS : SpeedSegment::UNIT_SECONDS;
|
||||
|
||||
seg->SetUnit( unit );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
this->GetSongTitle(),
|
||||
"has an speed change with beat %f.",
|
||||
"has an speed change with beat %f.",
|
||||
fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg->GetDelay() < 0 )
|
||||
|
||||
if( fDelay < 0 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
this->GetSongTitle(),
|
||||
"has an speed change with beat %f, length %f.",
|
||||
fBeat, seg->GetDelay() );
|
||||
fBeat, fDelay );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddSegment( SEGMENT_SPEED, seg );
|
||||
|
||||
out.AddSegment( SpeedSegment(BeatToNoteRow(fBeat), fRatio, fDelay, unit) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,7 +510,7 @@ void SMLoader::ProcessFakes( TimingData &out, const RString line, const int rows
|
||||
{
|
||||
vector<RString> arrayFakeExpressions;
|
||||
split( line, ",", arrayFakeExpressions );
|
||||
|
||||
|
||||
for( unsigned b=0; b<arrayFakeExpressions.size(); b++ )
|
||||
{
|
||||
vector<RString> arrayFakeValues;
|
||||
@@ -541,12 +523,12 @@ void SMLoader::ProcessFakes( TimingData &out, const RString line, const int rows
|
||||
arrayFakeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const float fBeat = RowToBeat( arrayFakeValues[0], rowsPerBeat );
|
||||
const float fNewBeat = StringToFloat( arrayFakeValues[1] );
|
||||
|
||||
|
||||
if(fNewBeat > 0)
|
||||
out.AddSegment( SEGMENT_FAKE, new FakeSegment(BeatToNoteRow(fBeat), fNewBeat) );
|
||||
out.AddSegment( FakeSegment(BeatToNoteRow(fBeat), fNewBeat) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
@@ -777,28 +759,27 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache
|
||||
{
|
||||
ProcessBPMs(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="STOPS" || sValueName=="FREEZES" )
|
||||
{
|
||||
ProcessStops(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="DELAYS" )
|
||||
{
|
||||
ProcessDelays(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="TIMESIGNATURES" )
|
||||
{
|
||||
ProcessTimeSignatures(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="TICKCOUNTS" )
|
||||
{
|
||||
ProcessTickcounts(out.m_SongTiming, sParams[1]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
else if( sValueName=="INSTRUMENTTRACK" )
|
||||
{
|
||||
ProcessInstrumentTracks( out, sParams[1] );
|
||||
@@ -931,10 +912,9 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache
|
||||
else
|
||||
LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", sValueName.c_str() );
|
||||
}
|
||||
|
||||
|
||||
// Ensure all warps from negative time changes are in order.
|
||||
vector<TimingSegment *> &warps = out.m_SongTiming.m_avpTimingSegments[SEGMENT_WARP];
|
||||
sort(warps.begin(), warps.end());
|
||||
out.m_SongTiming.SortSegments( SEGMENT_WARP );
|
||||
TidyUpData( out, bFromCache );
|
||||
return true;
|
||||
}
|
||||
@@ -1105,7 +1085,6 @@ void SMLoader::TidyUpData( Song &song, bool bFromCache )
|
||||
if( !IsAFile( song.GetBackgroundPath() ) )
|
||||
break;
|
||||
|
||||
|
||||
bg.push_back( BackgroundChange(lastBeat,song.m_sBackgroundFile) );
|
||||
} while(0);
|
||||
}
|
||||
|
||||
+39
-45
@@ -38,8 +38,7 @@ void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, con
|
||||
const int iMisses = (size == 2 || size == 4 ?
|
||||
iCombos :
|
||||
StringToInt(arrayMultiplierValues[2]));
|
||||
out.AddSegment(SEGMENT_COMBO,
|
||||
new ComboSegment( BeatToNoteRow(fComboBeat), iCombos, iMisses ));
|
||||
out.AddSegment( ComboSegment(BeatToNoteRow(fComboBeat), iCombos, iMisses) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,31 +61,26 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam )
|
||||
continue;
|
||||
}
|
||||
const float fBeat = StringToFloat( vs2[0] );
|
||||
|
||||
TimeSignatureSegment * seg = new TimeSignatureSegment(
|
||||
BeatToNoteRow(fBeat),
|
||||
StringToInt(vs2[1]),
|
||||
4 );
|
||||
const int iNumerator = StringToInt( vs2[1] );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
this->GetSongTitle(),
|
||||
this->GetSongTitle(),
|
||||
"has an invalid time signature change with beat %f.",
|
||||
fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg->GetNum() < 1 )
|
||||
if( iNumerator < 1 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
this->GetSongTitle(),
|
||||
"has an invalid time signature change with beat %f, iNumerator %i.",
|
||||
fBeat, seg->GetNum() );
|
||||
fBeat, iNumerator );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddSegment( SEGMENT_TIME_SIG, seg );
|
||||
|
||||
out.AddSegment( TimeSignatureSegment(BeatToNoteRow(fBeat), iNumerator) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,19 +110,19 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro
|
||||
static_cast<int>(vs2.size()) );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const float fBeat = RowToBeat( vs2[0], rowsPerBeat );
|
||||
|
||||
|
||||
RString backup = vs2[2];
|
||||
Trim(vs2[2], "s");
|
||||
Trim(vs2[2], "S");
|
||||
|
||||
|
||||
const float fRatio = StringToFloat( vs2[1] );
|
||||
const float fDelay = StringToFloat( vs2[2] );
|
||||
|
||||
SpeedSegment::BaseUnit unit = ((backup != vs2[2]) ?
|
||||
SpeedSegment::UNIT_SECONDS : SpeedSegment::UNIT_BEATS);
|
||||
|
||||
SpeedSegment * seg = new SpeedSegment( BeatToNoteRow(fBeat),
|
||||
StringToFloat( vs2[1] ), StringToFloat(vs2[2]), unit);
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
@@ -138,17 +132,17 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro
|
||||
fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( seg->GetDelay() < 0 )
|
||||
|
||||
if( fDelay < 0 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
this->GetSongTitle(),
|
||||
"has an speed change with beat %f, length %f.",
|
||||
fBeat, seg->GetDelay() );
|
||||
fBeat, fDelay );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddSegment( SEGMENT_SPEED, seg );
|
||||
|
||||
out.AddSegment( SpeedSegment(BeatToNoteRow(fBeat), fRatio, fDelay, unit) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +342,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
|
||||
{
|
||||
vector<RString> aFGChangeExpressions;
|
||||
split( sParams[1], ",", aFGChangeExpressions );
|
||||
|
||||
|
||||
for( unsigned b=0; b<aFGChangeExpressions.size(); b++ )
|
||||
{
|
||||
BackgroundChange change;
|
||||
@@ -356,82 +350,82 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
|
||||
out.AddForegroundChange( change );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="OFFSET" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
timing.m_fBeat0OffsetInSeconds = StringToFloat( sParams[1] );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="BPMS" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
ProcessBPMs( timing, sParams[1], iRowsPerBeat );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="STOPS" || sValueName=="FREEZES" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
ProcessStops( timing, sParams[1], iRowsPerBeat );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="DELAYS" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
ProcessDelays( timing, sParams[1], iRowsPerBeat );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="TICKCOUNT" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
ProcessTickcounts( timing, sParams[1], iRowsPerBeat );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="SPEED" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
RString tmp = sParams[1];
|
||||
Trim( tmp );
|
||||
ProcessSpeeds( timing, tmp, iRowsPerBeat );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="MULTIPLIER" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
ProcessMultipliers( timing, iRowsPerBeat, sParams[1] );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="FAKES" )
|
||||
{
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
TimingData &timing = (state == SMA_GETTING_STEP_INFO
|
||||
? pNewNotes->m_Timing : out.m_SongTiming);
|
||||
ProcessFakes( timing, sParams[1], iRowsPerBeat );
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="METERTYPE" )
|
||||
{
|
||||
; // We don't use this...yet.
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="KEYSOUNDS" )
|
||||
{
|
||||
split( sParams[1], ",", out.m_vsKeysoundFile );
|
||||
}
|
||||
|
||||
|
||||
// Attacks loaded from file
|
||||
else if( sValueName=="ATTACKS" )
|
||||
{
|
||||
ProcessAttackString(out.m_sAttackString, sParams);
|
||||
ProcessAttacks(out.m_Attacks, sParams);
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="NOTES" || sValueName=="NOTES2" )
|
||||
{
|
||||
if( iNumParams < 7 )
|
||||
@@ -442,7 +436,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
|
||||
iNumParams );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
LoadFromTokens(
|
||||
sParams[1],
|
||||
sParams[2],
|
||||
|
||||
+11
-12
@@ -37,10 +37,10 @@ void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float
|
||||
// Early versions were absolute in beats. They should be relative.
|
||||
if( ( fVersion < VERSION_SPLIT_TIMING && fNewBeat > fBeat ) )
|
||||
{
|
||||
out.AddSegment( SEGMENT_WARP, new WarpSegment(BeatToNoteRow(fBeat), fNewBeat - fBeat) );
|
||||
out.AddSegment( WarpSegment(BeatToNoteRow(fBeat), fNewBeat - fBeat) );
|
||||
}
|
||||
else if( fNewBeat > 0 )
|
||||
out.AddSegment( SEGMENT_WARP, new WarpSegment(BeatToNoteRow(fBeat), fNewBeat) );
|
||||
out.AddSegment( WarpSegment(BeatToNoteRow(fBeat), fNewBeat) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
@@ -73,7 +73,7 @@ void SSCLoader::ProcessLabels( TimingData &out, const RString sParam )
|
||||
RString sLabel = arrayLabelValues[1];
|
||||
TrimRight(sLabel);
|
||||
if( fBeat >= 0.0f )
|
||||
out.AddSegment( SEGMENT_LABEL, new LabelSegment(BeatToNoteRow(fBeat), sLabel) );
|
||||
out.AddSegment( LabelSegment(BeatToNoteRow(fBeat), sLabel) );
|
||||
else
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
@@ -106,7 +106,7 @@ void SSCLoader::ProcessCombos( TimingData &out, const RString line, const int ro
|
||||
const float fComboBeat = StringToFloat( arrayComboValues[0] );
|
||||
const int iCombos = StringToInt( arrayComboValues[1] );
|
||||
const int iMisses = (size == 2 ? iCombos : StringToInt(arrayComboValues[2]));
|
||||
out.AddSegment( SEGMENT_COMBO, new ComboSegment( BeatToNoteRow(fComboBeat), iCombos, iMisses ) );
|
||||
out.AddSegment( ComboSegment( BeatToNoteRow(fComboBeat), iCombos, iMisses ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,11 +128,10 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
|
||||
static_cast<int>(vs2.size()) );
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
const float fBeat = StringToFloat( vs2[0] );
|
||||
|
||||
ScrollSegment * seg = new ScrollSegment(BeatToNoteRow(fBeat), StringToFloat( vs2[1] ) );
|
||||
|
||||
const float fRatio = StringToFloat( vs2[1] );
|
||||
|
||||
if( fBeat < 0 )
|
||||
{
|
||||
LOG->UserLog("Song file",
|
||||
@@ -141,8 +140,8 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam )
|
||||
fBeat );
|
||||
continue;
|
||||
}
|
||||
|
||||
out.AddSegment( SEGMENT_SCROLL, seg );
|
||||
|
||||
out.AddSegment( ScrollSegment(BeatToNoteRow(fBeat), fRatio) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,7 +740,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
|
||||
ProcessAttacks(pNewNotes->m_Attacks, sParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="OFFSET" )
|
||||
{
|
||||
if (out.m_fVersion >= VERSION_SPLIT_TIMING)
|
||||
@@ -750,7 +749,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach
|
||||
bHasOwnTiming = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
else if( sValueName=="DISPLAYBPM" )
|
||||
{
|
||||
// #DISPLAYBPM:[xxx][xxx:xxx]|[*];
|
||||
|
||||
@@ -353,9 +353,8 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out )
|
||||
/* Write transliterations, if we have them, since DWI doesn't support UTF-8. */
|
||||
f.PutLine( ssprintf("#TITLE:%s;", DwiEscape(out.GetTranslitFullTitle()).c_str()) );
|
||||
f.PutLine( ssprintf("#ARTIST:%s;", DwiEscape(out.GetTranslitArtist()).c_str()) );
|
||||
|
||||
const vector<TimingSegment *> &bpms = out.m_SongTiming.m_avpTimingSegments[SEGMENT_BPM];
|
||||
|
||||
|
||||
const vector<TimingSegment *> &bpms = out.m_SongTiming.GetTimingSegments(SEGMENT_BPM);
|
||||
ASSERT_M(bpms[0]->GetRow() == 0,
|
||||
ssprintf("The first BPM Segment must be defined at row 0, not %d!", bpms[0]->GetRow()) );
|
||||
f.PutLine( ssprintf("#FILE:%s;", DwiEscape(out.m_sMusicFile).c_str()) );
|
||||
@@ -382,7 +381,7 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out )
|
||||
}
|
||||
|
||||
// TODO: Also check for delays, add them as stops minus one row?
|
||||
const vector<TimingSegment *> &stops = out.m_SongTiming.m_avpTimingSegments[SEGMENT_STOP];
|
||||
const vector<TimingSegment *> &stops = out.m_SongTiming.GetTimingSegments(SEGMENT_STOP);
|
||||
if( !stops.empty() )
|
||||
{
|
||||
f.Write( "#FREEZE:" );
|
||||
|
||||
@@ -24,8 +24,8 @@ static void Serialize(const TimingSegment &seg, Json::Value &root)
|
||||
|
||||
static void Serialize(const TimingData &td, Json::Value &root)
|
||||
{
|
||||
JsonUtil::SerializeVectorPointers( td.m_avpTimingSegments[SEGMENT_BPM], Serialize, root["BpmSegments"] );
|
||||
JsonUtil::SerializeVectorPointers( td.m_avpTimingSegments[SEGMENT_STOP], Serialize, root["StopSegments"] );
|
||||
JsonUtil::SerializeVectorPointers( td.GetTimingSegments(SEGMENT_BPM), Serialize, root["BpmSegments"] );
|
||||
JsonUtil::SerializeVectorPointers( td.GetTimingSegments(SEGMENT_STOP), Serialize, root["StopSegments"] );
|
||||
}
|
||||
|
||||
static void Serialize(const LyricSegment &o, Json::Value &root)
|
||||
|
||||
+20
-21
@@ -75,18 +75,18 @@ static void WriteGlobalTags( RageFile &f, Song &out )
|
||||
|
||||
|
||||
f.Write( "#BPMS:" );
|
||||
vector<TimingSegment *> &bpms = timing.m_avpTimingSegments[SEGMENT_BPM];
|
||||
const vector<TimingSegment *> &bpms = timing.GetTimingSegments(SEGMENT_BPM);
|
||||
for( unsigned i=0; i<bpms.size(); i++ )
|
||||
{
|
||||
const BPMSegment *bs = static_cast<BPMSegment *>(bpms[i]);
|
||||
const BPMSegment *bs = ToBPM(bpms[i]);
|
||||
|
||||
f.PutLine( ssprintf( "%.3f=%.3f", bs->GetBeat(), bs->GetBPM() ) );
|
||||
if( i != bpms.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
vector<TimingSegment *> &warps = timing.m_avpTimingSegments[SEGMENT_WARP];
|
||||
|
||||
const vector<TimingSegment *> &warps = timing.GetTimingSegments(SEGMENT_WARP);
|
||||
unsigned wSize = warps.size();
|
||||
if( wSize > 0 )
|
||||
{
|
||||
@@ -96,34 +96,33 @@ static void WriteGlobalTags( RageFile &f, Song &out )
|
||||
int iRow = ws->GetRow();
|
||||
float fBPS = 60 / out.m_SongTiming.GetBPMAtRow(iRow);
|
||||
float fSkip = fBPS * ws->GetLength();
|
||||
out.m_SongTiming.AddSegment(SEGMENT_STOP,
|
||||
new StopSegment(iRow, -fSkip) );
|
||||
out.m_SongTiming.AddSegment( StopSegment(iRow, -fSkip) );
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make Delays into Stops that start one row before.
|
||||
vector<TimingSegment *> &stops = timing.m_avpTimingSegments[SEGMENT_STOP];
|
||||
vector<TimingSegment *> &delays = timing.m_avpTimingSegments[SEGMENT_DELAY];
|
||||
|
||||
const vector<TimingSegment *> &stops = timing.GetTimingSegments(SEGMENT_STOP);
|
||||
const vector<TimingSegment *> &delays = timing.GetTimingSegments(SEGMENT_DELAY);
|
||||
|
||||
map<float, float> allPauses;
|
||||
for( unsigned i=0; i<stops.size(); i++ )
|
||||
{
|
||||
const StopSegment *fs = static_cast<StopSegment *>(stops[i]);
|
||||
allPauses.insert(pair<float, float>(fs->GetBeat(),
|
||||
fs->GetPause()));
|
||||
const StopSegment *fs = ToStop( stops[i] );
|
||||
|
||||
allPauses.insert(pair<float, float>(fs->GetBeat(), fs->GetPause()));
|
||||
|
||||
// erase stops with negative length
|
||||
if( fs->GetPause() < 0 )
|
||||
{
|
||||
stops.erase(stops.begin()+i,stops.begin()+i+1 );
|
||||
i--;
|
||||
}
|
||||
timing.AddSegment( StopSegment(fs->GetRow(), 0) );
|
||||
}
|
||||
// Delays can't be negative: thus, no effect.
|
||||
FOREACH(TimingSegment *, delays, ss)
|
||||
FOREACH_CONST(TimingSegment *, delays, ss)
|
||||
{
|
||||
allPauses.insert(pair<float, float>(NoteRowToBeat((*ss)->GetRow() - 1),
|
||||
static_cast<DelaySegment *>(*ss)->GetPause()));
|
||||
float fBeat = NoteRowToBeat( (*ss)->GetRow()-1 );
|
||||
float fPause = ToDelay(*ss)->GetPause();
|
||||
allPauses.insert( pair<float,float>(fBeat, fPause) );
|
||||
}
|
||||
|
||||
|
||||
f.Write( "#STOPS:" );
|
||||
vector<RString> stopLines;
|
||||
FOREACHM(float, float, allPauses, ap)
|
||||
@@ -133,7 +132,7 @@ static void WriteGlobalTags( RageFile &f, Song &out )
|
||||
f.PutLine(join(",\n", stopLines));
|
||||
|
||||
f.PutLine( ";" );
|
||||
|
||||
|
||||
FOREACH_BackgroundLayer( b )
|
||||
{
|
||||
if( b==0 )
|
||||
|
||||
+36
-36
@@ -60,115 +60,115 @@ struct TimingTagWriter {
|
||||
|
||||
};
|
||||
|
||||
static void GetTimingTags( vector<RString> &lines, TimingData timing, bool bIsSong = false )
|
||||
static void GetTimingTags( vector<RString> &lines, const TimingData &timing, bool bIsSong = false )
|
||||
{
|
||||
TimingTagWriter w ( &lines );
|
||||
|
||||
timing.TidyUpData();
|
||||
|
||||
// timing.TidyUpData(); // UGLY: done via const_cast. do we really -need- this here?
|
||||
unsigned i = 0;
|
||||
|
||||
w.Init( "BPMS" );
|
||||
vector<TimingSegment *> &bpms = timing.m_avpTimingSegments[SEGMENT_BPM];
|
||||
const vector<TimingSegment *> &bpms = timing.GetTimingSegments(SEGMENT_BPM);
|
||||
for (; i < bpms.size(); i++)
|
||||
{
|
||||
BPMSegment *bs = static_cast<BPMSegment *>(bpms[i]);
|
||||
const BPMSegment *bs = ToBPM( bpms[i] );
|
||||
w.Write( bs->GetRow(), bs->GetBPM() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
|
||||
w.Init( "STOPS" );
|
||||
vector<TimingSegment *> &stops = timing.m_avpTimingSegments[SEGMENT_STOP];
|
||||
const vector<TimingSegment *> &stops = timing.GetTimingSegments(SEGMENT_STOP);
|
||||
for (i = 0; i < stops.size(); i++)
|
||||
{
|
||||
StopSegment *ss = static_cast<StopSegment *>(stops[i]);
|
||||
const StopSegment *ss = ToStop( stops[i] );
|
||||
w.Write( ss->GetRow(), ss->GetPause() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
|
||||
w.Init( "DELAYS" );
|
||||
vector<TimingSegment *> &delays = timing.m_avpTimingSegments[SEGMENT_DELAY];
|
||||
const vector<TimingSegment *> &delays = timing.GetTimingSegments(SEGMENT_DELAY);
|
||||
for (i = 0; i < delays.size(); i++)
|
||||
{
|
||||
DelaySegment *ss = static_cast<DelaySegment *>(delays[i]);
|
||||
const DelaySegment *ss = ToDelay( delays[i] );
|
||||
w.Write( ss->GetRow(), ss->GetPause() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
|
||||
w.Init( "WARPS" );
|
||||
vector<TimingSegment *> &warps = timing.m_avpTimingSegments[SEGMENT_WARP];
|
||||
const vector<TimingSegment *> &warps = timing.GetTimingSegments(SEGMENT_WARP);
|
||||
for (i = 0; i < warps.size(); i++)
|
||||
{
|
||||
WarpSegment *ws = static_cast<WarpSegment *>(warps[i]);
|
||||
const WarpSegment *ws = ToWarp( warps[i] );
|
||||
w.Write( ws->GetRow(), ws->GetLength() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
vector<TimingSegment *> &tSigs = timing.m_avpTimingSegments[SEGMENT_TIME_SIG];
|
||||
|
||||
const vector<TimingSegment *> &tSigs = timing.GetTimingSegments(SEGMENT_TIME_SIG);
|
||||
ASSERT( !tSigs.empty() );
|
||||
w.Init( "TIMESIGNATURES" );
|
||||
for (i = 0; i < tSigs.size(); i++)
|
||||
{
|
||||
TimeSignatureSegment *ts = static_cast<TimeSignatureSegment *>(tSigs[i]);
|
||||
const TimeSignatureSegment *ts = ToTimeSignature( tSigs[i] );
|
||||
w.Write( ts->GetRow(), ts->GetNum(), ts->GetDen() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
vector<TimingSegment *> &ticks = timing.m_avpTimingSegments[SEGMENT_TICKCOUNT];
|
||||
const vector<TimingSegment *> &ticks = timing.GetTimingSegments(SEGMENT_TICKCOUNT);
|
||||
ASSERT( !ticks.empty() );
|
||||
w.Init( "TICKCOUNTS" );
|
||||
for (i = 0; i < ticks.size(); i++)
|
||||
{
|
||||
TickcountSegment *ts = static_cast<TickcountSegment *>(ticks[i]);
|
||||
const TickcountSegment *ts = ToTickcount( ticks[i] );
|
||||
w.Write( ts->GetRow(), ts->GetTicks() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
vector<TimingSegment *> &combos = timing.m_avpTimingSegments[SEGMENT_COMBO];
|
||||
|
||||
const vector<TimingSegment *> &combos = timing.GetTimingSegments(SEGMENT_COMBO);
|
||||
ASSERT( !combos.empty() );
|
||||
w.Init( "COMBOS" );
|
||||
for (i = 0; i < combos.size(); i++)
|
||||
{
|
||||
ComboSegment *cs = static_cast<ComboSegment *>(combos[i]);
|
||||
const ComboSegment *cs = ToCombo( combos[i] );
|
||||
if (cs->GetCombo() == cs->GetMissCombo())
|
||||
w.Write( cs->GetRow(), cs->GetCombo() );
|
||||
else
|
||||
w.Write( cs->GetRow(), cs->GetCombo(), cs->GetMissCombo() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
|
||||
// Song Timing should only have the initial value.
|
||||
vector<TimingSegment *> &speeds = timing.m_avpTimingSegments[SEGMENT_SPEED];
|
||||
const vector<TimingSegment *> &speeds = timing.GetTimingSegments(SEGMENT_SPEED);
|
||||
w.Init( "SPEEDS" );
|
||||
for (i = 0; i < speeds.size(); i++)
|
||||
{
|
||||
SpeedSegment *ss = static_cast<SpeedSegment *>(speeds[i]);
|
||||
SpeedSegment *ss = ToSpeed( speeds[i] );
|
||||
w.Write( ss->GetRow(), ss->GetRatio(), ss->GetDelay(), ss->GetUnit() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
|
||||
w.Init( "SCROLLS" );
|
||||
vector<TimingSegment *> &scrolls = timing.m_avpTimingSegments[SEGMENT_SCROLL];
|
||||
const vector<TimingSegment *> &scrolls = timing.GetTimingSegments(SEGMENT_SCROLL);
|
||||
for (i = 0; i < scrolls.size(); i++)
|
||||
{
|
||||
ScrollSegment *ss = static_cast<ScrollSegment *>(scrolls[i]);
|
||||
ScrollSegment *ss = ToScroll( scrolls[i] );
|
||||
w.Write( ss->GetRow(), ss->GetRatio() );
|
||||
}
|
||||
w.Finish();
|
||||
|
||||
|
||||
if( !bIsSong )
|
||||
{
|
||||
vector<TimingSegment *> &fakes = timing.m_avpTimingSegments[SEGMENT_FAKE];
|
||||
{
|
||||
const vector<TimingSegment *> &fakes = timing.GetTimingSegments(SEGMENT_FAKE);
|
||||
w.Init( "FAKES" );
|
||||
for (i = 0; i < fakes.size(); i++)
|
||||
{
|
||||
FakeSegment *fs = static_cast<FakeSegment *>(fakes[i]);
|
||||
FakeSegment *fs = ToFake( fakes[i] );
|
||||
w.Write( fs->GetRow(), fs->GetLength() );
|
||||
}
|
||||
w.Finish();
|
||||
}
|
||||
|
||||
|
||||
w.Init( "LABELS" );
|
||||
vector<TimingSegment *> &labels = timing.m_avpTimingSegments[SEGMENT_LABEL];
|
||||
const vector<TimingSegment *> &labels = timing.GetTimingSegments(SEGMENT_LABEL);
|
||||
for (i = 0; i < labels.size(); i++)
|
||||
{
|
||||
LabelSegment *ls = static_cast<LabelSegment *>(labels[i]);
|
||||
@@ -344,7 +344,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
|
||||
lines.push_back( ssprintf( "#RADARVALUES:%s;", join(",",asRadarValues).c_str() ) );
|
||||
|
||||
lines.push_back( ssprintf( "#CREDIT:%s;", SmEscape(in.GetCredit()).c_str() ) );
|
||||
|
||||
|
||||
// XXX: Is there a better way to write this?
|
||||
if (const_cast<TimingData &>(song.m_SongTiming) != in.m_Timing)
|
||||
{
|
||||
@@ -353,7 +353,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
|
||||
}
|
||||
if (song.GetAttackString() != in.GetAttackString())
|
||||
lines.push_back( ssprintf("#ATTACKS:%s;", in.GetAttackString().c_str()));
|
||||
|
||||
|
||||
switch( in.GetDisplayBPM() )
|
||||
{
|
||||
case DISPLAY_BPM_ACTUAL:
|
||||
|
||||
+6
-7
@@ -752,24 +752,23 @@ void Player::SendComboMessages( int iOldCombo, int iOldMissCombo )
|
||||
}
|
||||
|
||||
static void GenerateCacheDataStructure(PlayerState *pPlayerState, NoteData ¬es) {
|
||||
|
||||
|
||||
pPlayerState->m_CacheDisplayedBeat.clear();
|
||||
|
||||
const vector<TimingSegment *> *segs = pPlayerState->GetDisplayedTiming().m_avpTimingSegments;
|
||||
|
||||
|
||||
const vector<TimingSegment*> vScrolls = pPlayerState->GetDisplayedTiming().GetTimingSegments( SEGMENT_SCROLL );
|
||||
|
||||
float displayedBeat = 0.0f;
|
||||
float lastRealBeat = 0.0f;
|
||||
float lastRatio = 1.0f;
|
||||
for ( unsigned i = 0; i < segs[SEGMENT_SCROLL].size(); i++ )
|
||||
for ( unsigned i = 0; i < vScrolls.size(); i++ )
|
||||
{
|
||||
ScrollSegment *seg = static_cast<ScrollSegment *>(segs[SEGMENT_SCROLL][i]);
|
||||
ScrollSegment *seg = ToScroll( vScrolls[i] );
|
||||
displayedBeat += ( seg->GetBeat() - lastRealBeat ) * lastRatio;
|
||||
lastRealBeat = seg->GetBeat();
|
||||
lastRatio = seg->GetRatio();
|
||||
CacheDisplayedBeat c = { seg->GetBeat(), displayedBeat, seg->GetRatio() };
|
||||
pPlayerState->m_CacheDisplayedBeat.push_back( c );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Player::Update( float fDeltaTime )
|
||||
|
||||
+72
-108
@@ -1864,7 +1864,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
else
|
||||
fDelta *= 40;
|
||||
}
|
||||
|
||||
|
||||
float fNewBPM = fBPM + fDelta;
|
||||
GetAppropriateTiming().SetBPMAtBeat( GetBeat(), fNewBPM );
|
||||
(fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play();
|
||||
@@ -1893,19 +1893,21 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
fDelta *= 40;
|
||||
}
|
||||
unsigned i;
|
||||
vector<TimingSegment *> &stops = GetAppropriateTiming().m_avpTimingSegments[SEGMENT_STOP];
|
||||
for( i=0; i<stops.size(); i++ )
|
||||
{
|
||||
if( stops[i]->GetRow() == GetRow() )
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// is there a StopSegment on the current row?
|
||||
const StopSegment *seg = GetAppropriateTiming().GetStopSegmentAtRow( GetRow() );
|
||||
|
||||
// a stop already exists here; change its value by the delta
|
||||
if( seg->GetRow() == GetRow() )
|
||||
{
|
||||
float fSeconds = seg->GetPause() + fDelta;
|
||||
GetAppropriateTiming().AddSegment
|
||||
if( i == stops.size() ) // there is no StopSegment at the current beat
|
||||
{
|
||||
// create a new StopSegment
|
||||
if( fDelta > 0 )
|
||||
GetAppropriateTiming().AddSegment(SEGMENT_STOP,
|
||||
new StopSegment( GetRow(), fDelta) );
|
||||
GetAppropriateTiming().AddSegment( StopSegment(GetRow(), fDelta) );
|
||||
}
|
||||
else // StopSegment being modified is m_SongTiming.m_StopSegments[i]
|
||||
{
|
||||
@@ -1914,6 +1916,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB )
|
||||
if( s->GetPause() <= 0 )
|
||||
stops.erase( stops.begin()+i, stops.begin()+i+1);
|
||||
}
|
||||
#endif
|
||||
(fDelta>0 ? m_soundValueIncrease : m_soundValueDecrease).Play();
|
||||
SetDirty( true );
|
||||
}
|
||||
@@ -2962,59 +2965,67 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
else if( SM == SM_BackFromBPMChange && !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
float fBPM = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
|
||||
if( fBPM > 0 )
|
||||
GetAppropriateTiming().SetBPMAtBeat( GetBeat(), fBPM );
|
||||
GetAppropriateTiming().AddSegment( BPMSegment(GetRow(), fBPM) );
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromStopChange && !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
float fStop = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
|
||||
if( fStop >= 0 )
|
||||
GetAppropriateTiming().SetStopAtBeat( GetBeat(), fStop );
|
||||
GetAppropriateTiming().AddSegment( StopSegment(GetRow(), fStop) );
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromDelayChange && !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
float fDelay = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
|
||||
if( fDelay >= 0 )
|
||||
GetAppropriateTiming().SetDelayAtBeat( GetBeat(), fDelay );
|
||||
GetAppropriateTiming().AddSegment( DelaySegment(GetRow(), fDelay) );
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromTimeSignatureChange && !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
int iNum, iDen;
|
||||
|
||||
if( sscanf( ScreenTextEntry::s_sLastAnswer.c_str(), " %d / %d ", &iNum, &iDen ) == 2 )
|
||||
{
|
||||
GetAppropriateTiming().SetTimeSignatureAtBeat( GetBeat(), iNum, iDen );
|
||||
}
|
||||
GetAppropriateTiming().AddSegment( TimeSignatureSegment(GetRow(), iNum, iDen) );
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
else if ( SM == SM_BackFromTickcountChange && !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
int iTick = StringToInt( ScreenTextEntry::s_sLastAnswer );
|
||||
|
||||
if ( iTick >= 0 && iTick <= ROWS_PER_BEAT )
|
||||
{
|
||||
GetAppropriateTiming().SetTickcountAtBeat( GetBeat(), iTick );
|
||||
}
|
||||
GetAppropriateTiming().AddSegment( TickcountSegment( GetRow(), iTick) );
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
else if ( SM == SM_BackFromComboChange && !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
int iCombo, iMiss;
|
||||
|
||||
if (sscanf(ScreenTextEntry::s_sLastAnswer.c_str(), " %d / %d ", &iCombo, &iMiss) == 2)
|
||||
{
|
||||
GetAppropriateTiming().SetComboAtBeat( GetBeat(), iCombo, iMiss );
|
||||
}
|
||||
GetAppropriateTiming().AddSegment( ComboSegment(GetRow(), iCombo, iMiss) );
|
||||
|
||||
SetDirty( true );
|
||||
}
|
||||
else if ( SM == SM_BackFromLabelChange && !ScreenTextEntry::s_bCancelledLast )
|
||||
{
|
||||
RString sLabel = ScreenTextEntry::s_sLastAnswer;
|
||||
|
||||
if ( !GetAppropriateTiming().DoesLabelExist(sLabel) )
|
||||
{
|
||||
// XXX: these should be in the NotesWriters where they're needed.
|
||||
sLabel.Replace("=", "_");
|
||||
sLabel.Replace(",", "_");
|
||||
GetAppropriateTiming().SetLabelAtBeat( GetBeat(), sLabel );
|
||||
GetAppropriateTiming().AddSegment( LabelSegment(GetRow(), sLabel) );
|
||||
SetDirty( true );
|
||||
}
|
||||
}
|
||||
@@ -3074,7 +3085,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
float fFake = StringToFloat( ScreenTextEntry::s_sLastAnswer );
|
||||
if( fFake >= 0 ) // allow 0 to kill a warp.
|
||||
{
|
||||
GetAppropriateTiming().SetFakeAtBeat( GetBeat(), fFake );
|
||||
GetAppropriateTiming().AddSegment( FakeSegment(GetRow(), fFake) );
|
||||
SetDirty( true );
|
||||
}
|
||||
}
|
||||
@@ -3472,12 +3483,13 @@ static void ChangeArtistTranslit( const RString &sNew )
|
||||
|
||||
static void ChangeBeat0Offset( const RString &sNew )
|
||||
{
|
||||
TimingData &timing = (GAMESTATE->m_bIsUsingStepTiming ?
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing :
|
||||
TimingData &timing = (GAMESTATE->m_bIsUsingStepTiming ?
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1]->m_Timing :
|
||||
GAMESTATE->m_pCurSong->m_SongTiming);
|
||||
float old = timing.m_fBeat0OffsetInSeconds;
|
||||
timing.m_fBeat0OffsetInSeconds = StringToFloat( sNew );
|
||||
timing.m_fBeat0OffsetInSeconds = StringToFloat(sNew);
|
||||
float delta = timing.m_fBeat0OffsetInSeconds - old;
|
||||
|
||||
if (GAMESTATE->m_bIsUsingStepTiming)
|
||||
{
|
||||
GAMESTATE->m_pCurSteps[PLAYER_1]->m_Attacks.UpdateStartTimes(delta);
|
||||
@@ -3578,14 +3590,19 @@ void ScreenEdit::DisplayTimingMenu()
|
||||
float fBeat = GetBeat();
|
||||
TimingData &pTime = GetAppropriateTiming();
|
||||
bool bHasSpeedOnThisRow = pTime.GetSpeedSegmentAtBeat( fBeat )->GetBeat() == fBeat;
|
||||
|
||||
|
||||
g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.6f", pTime.m_fBeat0OffsetInSeconds) );
|
||||
g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.6f", pTime.GetBPMAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( ssprintf("%.6f", pTime.GetStopAtBeat( fBeat ) ) ) ;
|
||||
g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( ssprintf("%.6f", pTime.GetDelayAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[time_signature].SetOneUnthemedChoice(ssprintf("%d / %d",
|
||||
pTime.GetTimeSignatureNumeratorAtBeat( fBeat ),
|
||||
pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) );
|
||||
|
||||
g_TimingDataInformation.rows[time_signature].SetOneUnthemedChoice(
|
||||
ssprintf( "%d / %d",
|
||||
pTime.GetTimeSignatureSegmentAtBeat(fBeat)->GetNum(),
|
||||
pTime.GetTimeSignatureSegmentAtBeat(fBeat)->GetDen()
|
||||
)
|
||||
);
|
||||
|
||||
g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtBeat( fBeat ).c_str() );
|
||||
g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d / %d",
|
||||
@@ -3594,16 +3611,16 @@ void ScreenEdit::DisplayTimingMenu()
|
||||
g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( ssprintf("%.6f", pTime.GetWarpAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[speed_percent].SetOneUnthemedChoice( bHasSpeedOnThisRow ? ssprintf("%.6f", pTime.GetSpeedPercentAtBeat( fBeat ) ) : "---" );
|
||||
g_TimingDataInformation.rows[speed_wait].SetOneUnthemedChoice( bHasSpeedOnThisRow ? ssprintf("%.6f", pTime.GetSpeedWaitAtBeat( fBeat ) ) : "---" );
|
||||
|
||||
|
||||
RString starting = ( pTime.GetSpeedModeAtBeat( fBeat ) == 1 ? "Seconds" : "Beats" );
|
||||
g_TimingDataInformation.rows[speed_mode].SetOneUnthemedChoice( starting.c_str() );
|
||||
|
||||
|
||||
g_TimingDataInformation.rows[scroll].SetOneUnthemedChoice( ssprintf("%.6f", pTime.GetScrollAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[fake].SetOneUnthemedChoice( ssprintf("%.6f", pTime.GetFakeAtBeat( fBeat ) ) );
|
||||
|
||||
|
||||
g_TimingDataInformation.rows[speed_wait].bEnabled = bHasSpeedOnThisRow;
|
||||
g_TimingDataInformation.rows[speed_mode].bEnabled = bHasSpeedOnThisRow;
|
||||
|
||||
|
||||
EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation );
|
||||
}
|
||||
|
||||
@@ -4167,9 +4184,9 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector<int> &iAn
|
||||
}
|
||||
case convert_to_fake:
|
||||
{
|
||||
float startBeat = NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker);
|
||||
float lengthBeat = NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) - startBeat;
|
||||
GetAppropriateTiming().SetFakeAtBeat(startBeat,lengthBeat);
|
||||
int startRow = m_NoteFieldEdit.m_iBeginMarker;
|
||||
float lengthBeat = NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) - NoteRowToBeat(startRow);
|
||||
GetAppropriateTiming().AddSegment( FakeSegment(startRow,lengthBeat) );
|
||||
SetDirty(true);
|
||||
break;
|
||||
}
|
||||
@@ -4279,7 +4296,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
switch( c )
|
||||
{
|
||||
DEFAULT_FAIL( c );
|
||||
|
||||
|
||||
case paste_at_current_beat:
|
||||
case paste_at_begin_marker:
|
||||
{
|
||||
@@ -4302,82 +4319,28 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
break;
|
||||
case paste_partial_timing_at_beat:
|
||||
{
|
||||
#if 0
|
||||
int firstRow = BeatToNoteRow(GetAppropriatePosition().m_fSongBeat);
|
||||
FOREACH_ENUM(TimingSegmentType, tst)
|
||||
|
||||
FOREACH_TimingSegmentType( tst )
|
||||
{
|
||||
/* TODO: Maybe wipe out the already there timing data first?
|
||||
* We need to identify the max row within the timing data first. */
|
||||
for (unsigned i = 0; i < this->clipboardTiming.m_avpTimingSegments[tst].size(); i++)
|
||||
const vector<TimingSegment*> &vSegs = clipboardTiming.GetTimingSegments(tst);
|
||||
|
||||
/* TODO: this is an exact dupe of TimingData::CopyRange... */
|
||||
for (unsigned i = 0; i < vSegs.size(); i++)
|
||||
{
|
||||
// TODO: This REALLY needs improving.
|
||||
TimingSegment * org = this->clipboardTiming.m_avpTimingSegments[tst][i];
|
||||
TimingSegment * cpy;
|
||||
|
||||
switch (tst)
|
||||
{
|
||||
case SEGMENT_BPM:
|
||||
{
|
||||
cpy = new BPMSegment(*(static_cast<BPMSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_STOP:
|
||||
{
|
||||
cpy = new StopSegment(*(static_cast<StopSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_DELAY:
|
||||
{
|
||||
cpy = new DelaySegment(*(static_cast<DelaySegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_TIME_SIG:
|
||||
{
|
||||
cpy = new TimeSignatureSegment(*(static_cast<TimeSignatureSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_WARP:
|
||||
{
|
||||
cpy = new WarpSegment(*(static_cast<WarpSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_LABEL:
|
||||
{
|
||||
cpy = new LabelSegment(*(static_cast<LabelSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_TICKCOUNT:
|
||||
{
|
||||
cpy = new TickcountSegment(*(static_cast<TickcountSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_COMBO:
|
||||
{
|
||||
cpy = new ComboSegment(*(static_cast<ComboSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_SPEED:
|
||||
{
|
||||
cpy = new SpeedSegment(*(static_cast<SpeedSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_SCROLL:
|
||||
{
|
||||
cpy = new ScrollSegment(*(static_cast<ScrollSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
case SEGMENT_FAKE:
|
||||
{
|
||||
cpy = new FakeSegment(*(static_cast<FakeSegment *>(org)));
|
||||
break;
|
||||
}
|
||||
default: FAIL_M(ssprintf("An unknown timing segment type %d can't be copied over!", tst));
|
||||
}
|
||||
int oldRow = cpy->GetRow();
|
||||
const TimingSegment *seg = vSegs[i];
|
||||
TimingSegment *cpy = seg->Copy();
|
||||
|
||||
int oldRow = cpy->GetRow() + firstRow;
|
||||
int newRow = oldRow + firstRow;
|
||||
cpy->SetRow(newRow);
|
||||
GetAppropriateTiming().AddSegment(tst, cpy);
|
||||
GetAppropriateTiming().AddSegment( cpy );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case insert_and_shift:
|
||||
@@ -4410,9 +4373,9 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
TimingData &timing = GetAppropriateTiming();
|
||||
float pause = timing.GetDelayAtRow(GetRow());
|
||||
timing.SetDelayAtRow(GetRow(), 0);
|
||||
|
||||
|
||||
float pauseBeats = pause * timing.GetBPMAtBeat(GetBeat()) / 60;
|
||||
|
||||
|
||||
NoteDataUtil::InsertRows(m_NoteDataEdit, GetRow(), BeatToNoteRow(pauseBeats));
|
||||
timing.InsertRows(GetRow(), BeatToNoteRow(pauseBeats));
|
||||
break;
|
||||
@@ -4991,7 +4954,8 @@ void ScreenEdit::CheckNumberOfNotesAndUndo()
|
||||
if( EDIT_MODE.GetValue() != EditMode_Home )
|
||||
return;
|
||||
|
||||
const TimeSignatureSegment * curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat );
|
||||
const float fBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat;
|
||||
const TimeSignatureSegment * curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( fBeat );
|
||||
int rowsPerMeasure = curTime->GetDen() * curTime->GetNum();
|
||||
|
||||
for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure )
|
||||
|
||||
+276
-713
File diff suppressed because it is too large
Load Diff
+176
-524
@@ -10,16 +10,29 @@ struct lua_State;
|
||||
/** @brief Compare a TimingData segment's properties with one another. */
|
||||
#define COMPARE(x) if(this->x!=other.x) return false;
|
||||
|
||||
|
||||
/* convenience functions to handle static casting */
|
||||
template<class T> T* ToDerived( TimingSegment *t, TimingSegmentType tst )
|
||||
template<class T>
|
||||
inline T ToDerived( const TimingSegment *t, TimingSegmentType tst )
|
||||
{
|
||||
ASSERT( t->GetType() == tst ); // type checking
|
||||
return static_cast<T*>( t );
|
||||
ASSERT_M( t && tst == t->GetType(),
|
||||
ssprintf("type mismatch (expected %s, got %s)",
|
||||
TimingSegmentTypeToString(tst).c_str(),
|
||||
TimingSegmentTypeToString(t->GetType()).c_str() ) );
|
||||
|
||||
return static_cast<T>( t );
|
||||
}
|
||||
|
||||
#define TimingSegmentToXWithName(Seg, SegName, SegType) \
|
||||
inline Seg* To##SegName( TimingSegment *t ) { return ToDerived<Seg>(t, SegType); }
|
||||
inline const Seg* To##SegName( const TimingSegment *t ) \
|
||||
{ \
|
||||
ASSERT( t->GetType() == SegType ); \
|
||||
return static_cast<const Seg*>( t ); \
|
||||
} \
|
||||
inline Seg* To##SegName( TimingSegment *t ) \
|
||||
{ \
|
||||
ASSERT( t->GetType() == SegType ); \
|
||||
return static_cast<Seg*>( t ); \
|
||||
}
|
||||
|
||||
#define TimingSegmentToX(Seg, SegType) \
|
||||
TimingSegmentToXWithName(Seg##Segment, Seg, SEGMENT_##SegType)
|
||||
@@ -46,10 +59,25 @@ TimingSegmentToX( Fake, FAKE );
|
||||
class TimingData
|
||||
{
|
||||
public:
|
||||
void AddSegment(TimingSegmentType tst, TimingSegment * seg);
|
||||
/**
|
||||
* @brief Sets up initial timing data with a defined offset.
|
||||
* @param fOffset the offset from the 0th beat. */
|
||||
TimingData( float fOffset = 0 );
|
||||
~TimingData();
|
||||
|
||||
unsigned GetSegmentIndexAtRow(TimingSegmentType tst, int row) const;
|
||||
unsigned GetSegmentIndexAtBeat(TimingSegmentType tst, float beat) const
|
||||
TimingData( const TimingData& rhs ) : m_sFile(rhs.m_sFile),
|
||||
m_fBeat0OffsetInSeconds(rhs.m_fBeat0OffsetInSeconds)
|
||||
{
|
||||
const vector<TimingSegment*>* avpSegs = rhs.m_avpTimingSegments;
|
||||
|
||||
// deep-copy the TimingSegment pointers
|
||||
FOREACH_TimingSegmentType( tst )
|
||||
for( unsigned i = 0; i < avpSegs[tst].size(); ++i )
|
||||
m_avpTimingSegments[tst].push_back( avpSegs[tst][i]->Copy() );
|
||||
}
|
||||
|
||||
int GetSegmentIndexAtRow(TimingSegmentType tst, int row) const;
|
||||
int GetSegmentIndexAtBeat(TimingSegmentType tst, float beat) const
|
||||
{
|
||||
return GetSegmentIndexAtRow( tst, BeatToNoteRow(beat) );
|
||||
}
|
||||
@@ -68,12 +96,6 @@ public:
|
||||
|
||||
bool empty() const;
|
||||
|
||||
/**
|
||||
* @brief Sets up initial timing data with a defined offset.
|
||||
* @param fOffset the offset from the 0th beat. */
|
||||
TimingData(float fOffset = 0);
|
||||
~TimingData();
|
||||
|
||||
TimingData CopyRange(int startRow, int endRow) const;
|
||||
/**
|
||||
* @brief Gets the actual BPM of the song,
|
||||
@@ -85,30 +107,6 @@ public:
|
||||
* @param highest the highest allowed max BPM.
|
||||
*/
|
||||
void GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut, float highest = FLT_MAX ) const;
|
||||
/**
|
||||
* @brief Retrieve the BPM at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the BPM.
|
||||
*/
|
||||
float GetBPMAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the BPM at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the BPM.
|
||||
*/
|
||||
float GetBPMAtBeat( float fBeat ) const { return GetBPMAtRow( BeatToNoteRow(fBeat)); }
|
||||
/**
|
||||
* @brief Set the row to have the new BPM.
|
||||
* @param iNoteRow the row to have the new BPM.
|
||||
* @param fBPM the BPM.
|
||||
*/
|
||||
void SetBPMAtRow( int iNoteRow, float fBPM );
|
||||
/**
|
||||
* @brief Set the beat to have the new BPM.
|
||||
* @param fBeat the beat to have the new BPM.
|
||||
* @param fBPM the BPM.
|
||||
*/
|
||||
void SetBPMAtBeat( float fBeat, float fBPM ) { SetBPMAtRow( BeatToNoteRow(fBeat), fBPM ); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the TimingSegment at the specified row.
|
||||
@@ -116,6 +114,7 @@ public:
|
||||
* @param tst the TimingSegmentType requested.
|
||||
* @return the segment in question.
|
||||
*/
|
||||
const TimingSegment* GetSegmentAtRow( int iNoteRow, TimingSegmentType tst ) const;
|
||||
TimingSegment* GetSegmentAtRow( int iNoteRow, TimingSegmentType tst );
|
||||
|
||||
/**
|
||||
@@ -124,511 +123,176 @@ public:
|
||||
* @param tst the TimingSegmentType requested.
|
||||
* @return the segment in question.
|
||||
*/
|
||||
TimingSegment* GetSegmentAtBeat( float fBeat, TimingSegmentType tst )
|
||||
const TimingSegment* GetSegmentAtBeat( float fBeat, TimingSegmentType tst ) const
|
||||
{
|
||||
return GetSegmentAtRow( BeatToNoteRow(fBeat), tst );
|
||||
}
|
||||
TimingSegment* GetSegmentAtBeat( float fBeat, TimingSegmentType tst )
|
||||
{
|
||||
return const_cast<TimingSegment*>( GetSegmentAtBeat(fBeat, tst) );
|
||||
}
|
||||
|
||||
void SetTimingSegmentAtRow( TimingSegment *seg, int iNoteRow );
|
||||
|
||||
|
||||
/* XXX: convenience shortcuts. We should get rid of these later. */
|
||||
#define GetAndSetSegmentWithName(Seg, SegName, SegType) \
|
||||
#define DefineSegmentWithName(Seg, SegName, SegType) \
|
||||
const Seg* Get##Seg##AtRow( int iNoteRow ) const \
|
||||
{ \
|
||||
const TimingSegment *t = GetSegmentAtRow( iNoteRow, SegType ); \
|
||||
return To##SegName( t ); \
|
||||
} \
|
||||
Seg* Get##Seg##AtRow( int iNoteRow ) \
|
||||
{ \
|
||||
TimingSegment *t = GetSegmentAtRow( iNoteRow, SegType ); \
|
||||
return To##SegName( t ); \
|
||||
return const_cast<Seg*> (((const TimingData*)this)->Get##Seg##AtRow(iNoteRow) ); \
|
||||
} \
|
||||
const Seg* Get##Seg##AtBeat( float fBeat ) const \
|
||||
{ \
|
||||
return Get##Seg##AtRow( BeatToNoteRow(fBeat) ); \
|
||||
} \
|
||||
Seg* Get##Seg##AtBeat( float fBeat ) \
|
||||
{ \
|
||||
TimingSegment *t = GetSegmentAtBeat( fBeat, SegType ); \
|
||||
return To##SegName( t ); \
|
||||
return const_cast<Seg*> (((const TimingData*)this)->Get##Seg##AtBeat(fBeat) ); \
|
||||
} \
|
||||
void Set##SegName##AtRow( Seg &seg, int iNoteRow ) \
|
||||
void AddSegment( const Seg &seg ) \
|
||||
{ \
|
||||
SetTimingSegmentAtRow( &seg, iNoteRow ); \
|
||||
AddSegment( &seg ); \
|
||||
}
|
||||
|
||||
// "XXX: this comment (and quote mark) exists so nano won't
|
||||
// display the rest of this file as one giant string
|
||||
|
||||
// (TimeSignature,TIME_SIG) -> (TimeSignatureSegment,SEGMENT_TIME_SIG)
|
||||
#define GetAndSetSegment(Seg, SegType ) \
|
||||
GetAndSetSegmentWithName( Seg##Segment, Seg, SEGMENT_##SegType )
|
||||
#define DefineSegment(Seg, SegType ) \
|
||||
DefineSegmentWithName( Seg##Segment, Seg, SEGMENT_##SegType )
|
||||
|
||||
GetAndSetSegment( BPM, BPM );
|
||||
GetAndSetSegment( Stop, STOP );
|
||||
GetAndSetSegment( Delay, DELAY );
|
||||
GetAndSetSegment( Warp, WARP );
|
||||
GetAndSetSegment( Label, LABEL );
|
||||
GetAndSetSegment( Tickcount, TICKCOUNT );
|
||||
GetAndSetSegment( Combo, COMBO );
|
||||
GetAndSetSegment( Speed, SPEED );
|
||||
GetAndSetSegment( Scroll, SCROLL );
|
||||
GetAndSetSegment( Fake, FAKE );
|
||||
GetAndSetSegment( TimeSignature, TIME_SIG );
|
||||
DefineSegment( BPM, BPM );
|
||||
DefineSegment( Stop, STOP );
|
||||
DefineSegment( Delay, DELAY );
|
||||
DefineSegment( Warp, WARP );
|
||||
DefineSegment( Label, LABEL );
|
||||
DefineSegment( Tickcount, TICKCOUNT );
|
||||
DefineSegment( Combo, COMBO );
|
||||
DefineSegment( Speed, SPEED );
|
||||
DefineSegment( Scroll, SCROLL );
|
||||
DefineSegment( Fake, FAKE );
|
||||
DefineSegment( TimeSignature, TIME_SIG );
|
||||
|
||||
#undef GetAndSetSegmentWithName
|
||||
#undef GetAndSetSegment
|
||||
#undef DefineSegmentWithName
|
||||
#undef DefineSegment
|
||||
|
||||
/* convenience aliases (Set functions are deprecated) */
|
||||
float GetBPMAtRow( int iNoteRow ) const { return GetBPMSegmentAtRow(iNoteRow)->GetBPM(); }
|
||||
float GetBPMAtBeat( float fBeat ) const { return GetBPMAtRow( BeatToNoteRow(fBeat) ); }
|
||||
void SetBPMAtRow( int iNoteRow, float fBPM ) { AddSegment( BPMSegment(iNoteRow, fBPM) ); }
|
||||
void SetBPMAtBeat( float fBeat, float fBPM ) { SetBPMAtRow( BeatToNoteRow(fBeat), fBPM ); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the stop time at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the stop time.
|
||||
*/
|
||||
float GetStopAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the stop time at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the stop time.
|
||||
*/
|
||||
float GetStopAtRow( int iNoteRow ) const { return GetStopSegmentAtRow(iNoteRow)->GetPause(); }
|
||||
float GetStopAtBeat( float fBeat ) const { return GetStopAtRow( BeatToNoteRow(fBeat) ); }
|
||||
void SetStopAtRow( int iNoteRow, float fSeconds ) { AddSegment( StopSegment(iNoteRow, fSeconds) ); }
|
||||
void SetStopAtBeat( float fBeat, float fSeconds ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds ); }
|
||||
|
||||
/**
|
||||
* @brief Set the row to have the new stop time.
|
||||
* @param iNoteRow the row to have the new stop time.
|
||||
* @param fSeconds the new stop time.
|
||||
*/
|
||||
void SetStopAtRow( int iNoteRow, float fSeconds );
|
||||
/**
|
||||
* @brief Set the beat to have the new stop time.
|
||||
* @param fBeat to have the new stop time.
|
||||
* @param fSeconds the new stop time.
|
||||
*/
|
||||
void SetStopAtBeat( float fBeat, float fSeconds ) { SetStopAtRow( BeatToNoteRow(fBeat), fSeconds); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the delay time at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the delay time.
|
||||
*/
|
||||
float GetDelayAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the delay time at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the delay time.
|
||||
*/
|
||||
float GetDelayAtRow( int iNoteRow ) const { return GetDelaySegmentAtRow(iNoteRow)->GetPause(); }
|
||||
float GetDelayAtBeat( float fBeat ) const { return GetDelayAtRow( BeatToNoteRow(fBeat) ); }
|
||||
void SetDelayAtRow( int iNoteRow, float fSeconds ) { AddSegment( DelaySegment(iNoteRow, fSeconds) ); }
|
||||
void SetDelayAtBeat( float fBeat, float fSeconds ) { SetDelayAtRow( BeatToNoteRow(fBeat), fSeconds ); }
|
||||
|
||||
/**
|
||||
* @brief Set the row to have the new delay time.
|
||||
*
|
||||
* This function was added specifically for sm-ssc.
|
||||
* @param iNoteRow the row to have the new delay time.
|
||||
* @param fSeconds the new delay time.
|
||||
*/
|
||||
void SetDelayAtRow( int iNoteRow, float fSeconds );
|
||||
/**
|
||||
* @brief Set the beat to have the new delay time.
|
||||
*
|
||||
* This function was added specifically for sm-ssc.
|
||||
* @param fBeat the beat to have the new delay time.
|
||||
* @param fSeconds the new delay time.
|
||||
*/
|
||||
void SetDelayAtBeat( float fBeat, float fSeconds ) { SetDelayAtRow( BeatToNoteRow(fBeat), fSeconds); }
|
||||
void SetTimeSignatureAtRow( int iNoteRow, int iNum, int iDen )
|
||||
{
|
||||
AddSegment( TimeSignatureSegment(iNoteRow, iNum, iDen) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieve the Time Signature's numerator at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the numerator.
|
||||
*/
|
||||
int GetTimeSignatureNumeratorAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the Time Signature's numerator at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the numerator.
|
||||
*/
|
||||
int GetTimeSignatureNumeratorAtBeat( float fBeat ) { return GetTimeSignatureNumeratorAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Retrieve the Time Signature's denominator at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the denominator.
|
||||
*/
|
||||
int GetTimeSignatureDenominatorAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the Time Signature's denominator at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the denominator.
|
||||
*/
|
||||
int GetTimeSignatureDenominatorAtBeat( float fBeat ) { return GetTimeSignatureDenominatorAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Time Signature.
|
||||
* @param iNoteRow the row to have the new Time Signature.
|
||||
* @param iNumerator the numerator.
|
||||
* @param iDenominator the denominator.
|
||||
*/
|
||||
void SetTimeSignatureAtRow( int iNoteRow, int iNumerator, int iDenominator );
|
||||
/**
|
||||
* @brief Set the beat to have the new Time Signature.
|
||||
* @param fBeat the beat to have the new Time Signature.
|
||||
* @param iNumerator the numerator.
|
||||
* @param iDenominator the denominator.
|
||||
*/
|
||||
void SetTimeSignatureAtBeat( float fBeat, int iNumerator, int iDenominator ) { SetTimeSignatureAtRow( BeatToNoteRow(fBeat), iNumerator, iDenominator ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Time Signature numerator.
|
||||
* @param iNoteRow the row to have the new Time Signature numerator.
|
||||
* @param iNumerator the numerator.
|
||||
*/
|
||||
void SetTimeSignatureNumeratorAtRow( int iNoteRow, int iNumerator );
|
||||
/**
|
||||
* @brief Set the beat to have the new Time Signature numerator.
|
||||
* @param fBeat the beat to have the new Time Signature numerator.
|
||||
* @param iNumerator the numerator.
|
||||
*/
|
||||
void SetTimeSignatureNumeratorAtBeat( float fBeat, int iNumerator ) { SetTimeSignatureNumeratorAtRow( BeatToNoteRow(fBeat), iNumerator); }
|
||||
/**
|
||||
* @brief Set the row to have the new Time Signature denominator.
|
||||
* @param iNoteRow the row to have the new Time Signature denominator.
|
||||
* @param iDenominator the denominator.
|
||||
*/
|
||||
void SetTimeSignatureDenominatorAtRow( int iNoteRow, int iDenominator );
|
||||
/**
|
||||
* @brief Set the beat to have the new Time Signature denominator.
|
||||
* @param fBeat the beat to have the new Time Signature denominator.
|
||||
* @param iDenominator the denominator.
|
||||
*/
|
||||
void SetTimeSignatureDenominatorAtBeat( float fBeat, int iDenominator ) { SetTimeSignatureDenominatorAtRow( BeatToNoteRow(fBeat), iDenominator); }
|
||||
void SetTimeSignatureAtBeat( float fBeat, int iNum, int iDen )
|
||||
{
|
||||
SetTimeSignatureAtRow( BeatToNoteRow(fBeat), iNum, iDen );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine the beat to warp to.
|
||||
* @param iRow The row you start on.
|
||||
* @return the beat you warp to.
|
||||
*/
|
||||
float GetWarpAtRow( int iRow ) const;
|
||||
/**
|
||||
* @brief Determine the beat to warp to.
|
||||
* @param fBeat The beat you start on.
|
||||
* @return the beat you warp to.
|
||||
*/
|
||||
float GetWarpAtBeat( float fBeat ) const { return GetWarpAtRow( BeatToNoteRow( fBeat ) ); }
|
||||
/**
|
||||
* @brief Set the beat to warp to given a starting row.
|
||||
* @param iRow The row to start on.
|
||||
* @param fNew The destination beat.
|
||||
*/
|
||||
void SetWarpAtRow( int iRow, float fNew );
|
||||
/**
|
||||
* @brief Set the beat to warp to given a starting beat.
|
||||
* @param fBeat The beat to start on.
|
||||
* @param fNew The destination beat.
|
||||
*/
|
||||
void SetWarpAtBeat( float fBeat, float fNew ) { SetWarpAtRow( BeatToNoteRow( fBeat ), fNew ); }
|
||||
float GetWarpAtRow( int iNoteRow ) const { return GetWarpSegmentAtRow(iNoteRow)->GetLength(); }
|
||||
float GetWarpAtBeat( float fBeat ) const { return GetWarpAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/* Note: fLength is in beats, not rows */
|
||||
void SetWarpAtRow( int iRow, float fLength ) { AddSegment( WarpSegment(iRow, fLength) ); }
|
||||
void SetWarpAtBeat( float fBeat, float fLength ) { AddSegment( WarpSegment(BeatToNoteRow(fBeat), fLength) ); }
|
||||
|
||||
/**
|
||||
* @brief Checks if the row is inside a warp.
|
||||
* @param iRow the row to focus on.
|
||||
* @return true if the row is inside a warp, false otherwise.
|
||||
*/
|
||||
bool IsWarpAtRow( int iRow ) const;
|
||||
/**
|
||||
* @brief Checks if the beat is inside a warp.
|
||||
* @param fBeat the beat to focus on.
|
||||
* @return true if the row is inside a warp, false otherwise.
|
||||
*/
|
||||
bool IsWarpAtBeat( float fBeat ) const { return IsWarpAtRow( BeatToNoteRow( fBeat ) ); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the Tickcount at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the Tickcount.
|
||||
*/
|
||||
int GetTickcountAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the Tickcount at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the Tickcount.
|
||||
*/
|
||||
int GetTickcountAtRow( int iNoteRow ) const { return GetTickcountSegmentAtRow(iNoteRow)->GetTicks(); }
|
||||
int GetTickcountAtBeat( float fBeat ) const { return GetTickcountAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Set the row to have the new tickcount.
|
||||
* @param iNoteRow the row to have the new tickcount.
|
||||
* @param iTicks the tickcount.
|
||||
*/
|
||||
void SetTickcountAtRow( int iNoteRow, int iTicks );
|
||||
/**
|
||||
* @brief Set the beat to have the new tickcount.
|
||||
* @param fBeat the beat to have the new tickcount.
|
||||
* @param iTicks the tickcount.
|
||||
*/
|
||||
void SetTickcountAtRow( int iNoteRow, int iTicks ) { AddSegment( TickcountSegment(iNoteRow, iTicks) ); }
|
||||
void SetTickcountAtBeat( float fBeat, int iTicks ) { SetTickcountAtRow( BeatToNoteRow( fBeat ), iTicks ); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the Combo at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the Combo.
|
||||
*/
|
||||
int GetComboAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the Combo at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the Combo.
|
||||
*/
|
||||
int GetComboAtRow( int iNoteRow ) const { return GetComboSegmentAtRow(iNoteRow)->GetCombo(); }
|
||||
int GetComboAtBeat( float fBeat ) const { return GetComboAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Retrieve the Miss Combo at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the Miss Combo.
|
||||
*/
|
||||
int GetMissComboAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the Miss Combo at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the Miss Combo.
|
||||
*/
|
||||
int GetMissComboAtRow( int iNoteRow ) const { return GetComboSegmentAtRow(iNoteRow)->GetMissCombo(); }
|
||||
int GetMissComboAtBeat( float fBeat ) const { return GetMissComboAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Combo.
|
||||
* @param iNoteRow the row to have the new Combo.
|
||||
* @param iCombo the Combo.
|
||||
*/
|
||||
void SetComboAtRow( int iNoteRow, int iCombo );
|
||||
/**
|
||||
* @brief Set the beat to have the new Combo.
|
||||
* @param fBeat the beat to have the new Combo.
|
||||
* @param iCombo the Combo.
|
||||
*/
|
||||
void SetComboAtBeat( float fBeat, int iCombo ) { SetComboAtRow( BeatToNoteRow( fBeat ), iCombo ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Combo and Miss Combo.
|
||||
* @param iNoteRow the row to have the new Combo and Miss Combo.
|
||||
* @param iCombo the Combo.
|
||||
* @param iMiss the Miss Combo.
|
||||
*/
|
||||
void SetComboAtRow( int iNoteRow, int iCombo, int iMiss );
|
||||
/**
|
||||
* @brief Set the beat to have the new Combo and Miss Combo.
|
||||
* @param fBeat the beat to have the new Combo and Miss Combo.
|
||||
* @param iCombo the Combo.
|
||||
* @param iMiss the Miss Combo.
|
||||
*/
|
||||
void SetComboAtBeat( float fBeat, int iCombo, int iMiss ) { SetComboAtRow( BeatToNoteRow( fBeat ), iCombo, iMiss ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Combo.
|
||||
* @param iNoteRow the row to have the new Combo.
|
||||
* @param iCombo the Combo.
|
||||
*/
|
||||
void SetHitComboAtRow( int iNoteRow, int iCombo );
|
||||
/**
|
||||
* @brief Set the beat to have the new Combo.
|
||||
* @param fBeat the beat to have the new Combo.
|
||||
* @param iCombo the Combo.
|
||||
*/
|
||||
void SetHitComboAtBeat( float fBeat, int iCombo ) { SetHitComboAtRow( BeatToNoteRow( fBeat ), iCombo ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Miss Combo.
|
||||
* @param iNoteRow the row to have the new Miss Combo.
|
||||
* @param iCombo the Miss Combo.
|
||||
*/
|
||||
void SetMissComboAtRow( int iNoteRow, int iCombo );
|
||||
/**
|
||||
* @brief Set the beat to have the new Miss Combo.
|
||||
* @param fBeat the beat to have the new Miss Combo.
|
||||
* @param iCombo the Miss Combo.
|
||||
*/
|
||||
void SetMissComboAtBeat( float fBeat, int iCombo ) { SetMissComboAtRow( BeatToNoteRow( fBeat ), iCombo ); }
|
||||
|
||||
/**
|
||||
* @brief Retrieve the Label at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the Label.
|
||||
*/
|
||||
RString GetLabelAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the Label at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the Label.
|
||||
*/
|
||||
RString GetLabelAtBeat( float fBeat ) const { return GetLabelAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Label.
|
||||
* @param iNoteRow the row to have the new Label.
|
||||
* @param sLabel the Label.
|
||||
*/
|
||||
void SetLabelAtRow( int iNoteRow, const RString sLabel );
|
||||
/**
|
||||
* @brief Set the beat to have the new Label.
|
||||
* @param fBeat the beat to have the new Label.
|
||||
* @param sLabel the Label.
|
||||
*/
|
||||
const RString& GetLabelAtRow( int iNoteRow ) const { return GetLabelSegmentAtRow(iNoteRow)->GetLabel(); }
|
||||
const RString& GetLabelAtBeat( float fBeat ) const { return GetLabelAtRow( BeatToNoteRow(fBeat) ); }
|
||||
void SetLabelAtRow( int iNoteRow, const RString& sLabel ) { AddSegment( LabelSegment(iNoteRow,sLabel) ); }
|
||||
void SetLabelAtBeat( float fBeat, const RString sLabel ) { SetLabelAtRow( BeatToNoteRow( fBeat ), sLabel ); }
|
||||
bool DoesLabelExist( const RString& sLabel ) const;
|
||||
|
||||
/**
|
||||
* @brief Determine if the requisite label already exists.
|
||||
* @param sLabel the label to check.
|
||||
* @return true if it exists, false otherwise. */
|
||||
bool DoesLabelExist( RString sLabel ) const;
|
||||
/**
|
||||
* @brief Retrieve the Speed's percent at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the percent.
|
||||
*/
|
||||
float GetSpeedPercentAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the Speed's percent at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the percent.
|
||||
*/
|
||||
float GetSpeedPercentAtRow( int iNoteRow ) { return GetSpeedSegmentAtRow(iNoteRow)->GetRatio(); }
|
||||
float GetSpeedPercentAtBeat( float fBeat ) { return GetSpeedPercentAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Retrieve the Speed's wait at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the wait.
|
||||
*/
|
||||
float GetSpeedWaitAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the Speed's wait at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the wait.
|
||||
*/
|
||||
|
||||
float GetSpeedWaitAtRow( int iNoteRow ) { return GetSpeedSegmentAtRow(iNoteRow)->GetDelay(); }
|
||||
float GetSpeedWaitAtBeat( float fBeat ) { return GetSpeedWaitAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Retrieve the Speed's mode at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the mode.
|
||||
*/
|
||||
SpeedSegment::BaseUnit GetSpeedModeAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the Speed's mode at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the mode.
|
||||
*/
|
||||
|
||||
// XXX: is there any point to having specific unit types?
|
||||
SpeedSegment::BaseUnit GetSpeedModeAtRow( int iNoteRow ) const { return GetSpeedSegmentAtRow(iNoteRow)->GetUnit(); }
|
||||
SpeedSegment::BaseUnit GetSpeedModeAtBeat( float fBeat ) { return GetSpeedModeAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Speed.
|
||||
* @param iNoteRow the row to have the new Speed.
|
||||
* @param fPercent the percent.
|
||||
* @param fWait the wait.
|
||||
* @param usMode the mode.
|
||||
*/
|
||||
void SetSpeedAtRow( int iNoteRow, float fPercent, float fWait, SpeedSegment::BaseUnit unit );
|
||||
/**
|
||||
* @brief Set the beat to have the new Speed.
|
||||
* @param fBeat the beat to have the new Speed.
|
||||
* @param fPercent the percent.
|
||||
* @param fWait the wait.
|
||||
* @param usMode the mode.
|
||||
*/
|
||||
void SetSpeedAtBeat( float fBeat, float fPercent, float fWait, SpeedSegment::BaseUnit unit ) { SetSpeedAtRow( BeatToNoteRow(fBeat), fPercent, fWait, unit ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Speed percent.
|
||||
* @param iNoteRow the row to have the new Speed percent.
|
||||
* @param fPercent the percent.
|
||||
*/
|
||||
void SetSpeedPercentAtRow( int iNoteRow, float fPercent );
|
||||
/**
|
||||
* @brief Set the beat to have the new Speed percent.
|
||||
* @param fBeat the beat to have the new Speed percent.
|
||||
* @param fPercent the percent.
|
||||
*/
|
||||
|
||||
void SetSpeedAtRow( int iNoteRow, float fPercent, float fWait, SpeedSegment::BaseUnit unit )
|
||||
{
|
||||
AddSegment( SpeedSegment(iNoteRow, fPercent, fWait, unit) );
|
||||
}
|
||||
|
||||
void SetSpeedAtBeat( float fBeat, float fPercent, float fWait, SpeedSegment::BaseUnit unit )
|
||||
{
|
||||
SetSpeedAtRow( BeatToNoteRow(fBeat), fPercent, fWait, unit );
|
||||
}
|
||||
|
||||
void SetSpeedPercentAtRow( int iNoteRow, float fPercent )
|
||||
{
|
||||
const SpeedSegment* seg = GetSpeedSegmentAtRow(iNoteRow);
|
||||
SetSpeedAtRow( iNoteRow, fPercent, seg->GetDelay(), seg->GetUnit() );
|
||||
}
|
||||
|
||||
void SetSpeedWaitAtRow( int iNoteRow, float fWait )
|
||||
{
|
||||
const SpeedSegment* seg = GetSpeedSegmentAtRow(iNoteRow);
|
||||
SetSpeedAtRow( iNoteRow, seg->GetRatio(), fWait, seg->GetUnit() );
|
||||
}
|
||||
|
||||
void SetSpeedModeAtRow( int iNoteRow, SpeedSegment::BaseUnit unit )
|
||||
{
|
||||
const SpeedSegment* seg = GetSpeedSegmentAtRow(iNoteRow);
|
||||
SetSpeedAtRow( iNoteRow, seg->GetRatio(), seg->GetDelay(), unit );
|
||||
}
|
||||
|
||||
void SetSpeedPercentAtBeat( float fBeat, float fPercent ) { SetSpeedPercentAtRow( BeatToNoteRow(fBeat), fPercent); }
|
||||
/**
|
||||
* @brief Set the row to have the new Speed wait.
|
||||
* @param iNoteRow the row to have the new Speed wait.
|
||||
* @param fWait the wait.
|
||||
*/
|
||||
void SetSpeedWaitAtRow( int iNoteRow, float fWait );
|
||||
/**
|
||||
* @brief Set the beat to have the new Speed wait.
|
||||
* @param fBeat the beat to have the new Speed wait.
|
||||
* @param fWait the wait.
|
||||
*/
|
||||
void SetSpeedWaitAtBeat( float fBeat, float fWait ) { SetSpeedWaitAtRow( BeatToNoteRow(fBeat), fWait); }
|
||||
/**
|
||||
* @brief Set the row to have the new Speed mode.
|
||||
* @param iNoteRow the row to have the new Speed mode.
|
||||
* @param usMode the mode.
|
||||
*/
|
||||
void SetSpeedModeAtRow( int iNoteRow, SpeedSegment::BaseUnit unit );
|
||||
/**
|
||||
* @brief Set the beat to have the new Speed mode.
|
||||
* @param fBeat the beat to have the new Speed mode.
|
||||
* @param usMode the mode.
|
||||
*/
|
||||
void SetSpeedModeAtBeat( float fBeat, SpeedSegment::BaseUnit unit ) { SetSpeedModeAtRow( BeatToNoteRow(fBeat), unit); }
|
||||
|
||||
float GetDisplayedSpeedPercent( float fBeat, float fMusicSeconds ) const;
|
||||
|
||||
/**
|
||||
* @brief Retrieve the scrolling factor at the given row.
|
||||
* @param iNoteRow the row in question.
|
||||
* @return the percent.
|
||||
*/
|
||||
float GetScrollAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the scrolling factor at the given beat.
|
||||
* @param fBeat the beat in question.
|
||||
* @return the percent.
|
||||
*/
|
||||
|
||||
float GetScrollAtRow( int iNoteRow ) const { return GetScrollSegmentAtRow(iNoteRow)->GetRatio(); }
|
||||
float GetScrollAtBeat( float fBeat ) { return GetScrollAtRow( BeatToNoteRow(fBeat) ); }
|
||||
|
||||
/**
|
||||
* @brief Set the row to have the new Scrolling factor.
|
||||
* @param iNoteRow the row to have the new Speed.
|
||||
* @param fPercent the scrolling factor.
|
||||
*/
|
||||
void SetScrollAtRow( int iNoteRow, float fPercent );
|
||||
/**
|
||||
* @brief Set the row to have the new Scrolling factor.
|
||||
* @param iNoteRow the row to have the new Speed.
|
||||
* @param fPercent the scrolling factor.
|
||||
*/
|
||||
void SetScrollAtRow( int iNoteRow, float fPercent ) { AddSegment( ScrollSegment(iNoteRow, fPercent) ); }
|
||||
void SetScrollAtBeat( float fBeat, float fPercent ) { SetScrollAtRow( BeatToNoteRow(fBeat), fPercent ); }
|
||||
|
||||
/**
|
||||
* @brief Determine when the fakes end.
|
||||
* @param iRow The row you start on.
|
||||
* @return the time when the fakes end.
|
||||
*/
|
||||
float GetFakeAtRow( int iRow ) const;
|
||||
/**
|
||||
* @brief Determine when the fakes end.
|
||||
* @param fBeat The beat you start on.
|
||||
* @return the time when the fakes end.
|
||||
*/
|
||||
float GetFakeAtRow( int iRow ) const { return GetFakeSegmentAtRow(iRow)->GetLength(); }
|
||||
float GetFakeAtBeat( float fBeat ) const { return GetFakeAtRow( BeatToNoteRow( fBeat ) ); }
|
||||
/**
|
||||
* @brief Set the beat to indicate when the FakeSegment ends.
|
||||
* @param iRow The row to start on.
|
||||
* @param fNew The destination beat.
|
||||
*/
|
||||
void SetFakeAtRow( int iRow, float fNew );
|
||||
/**
|
||||
* @brief Set the beat to indicate when the FakeSegment ends.
|
||||
* @param fBeat The beat to start on.
|
||||
* @param fNew The destination beat.
|
||||
*/
|
||||
void SetFakeAtBeat( float fBeat, float fNew ) { SetFakeAtRow( BeatToNoteRow( fBeat ), fNew ); }
|
||||
|
||||
/**
|
||||
* @brief Checks if the row is inside a fake.
|
||||
* @param iRow the row to focus on.
|
||||
* @return true if the row is inside a fake, false otherwise.
|
||||
*/
|
||||
bool IsWarpAtRow( int iRow ) const;
|
||||
bool IsWarpAtBeat( float fBeat ) const { return IsWarpAtRow( BeatToNoteRow( fBeat ) ); }
|
||||
bool IsFakeAtRow( int iRow ) const;
|
||||
/**
|
||||
* @brief Checks if the beat is inside a fake.
|
||||
* @param fBeat the beat to focus on.
|
||||
* @return true if the row is inside a fake, false otherwise.
|
||||
*/
|
||||
bool IsFakeAtBeat( float fBeat ) const { return IsFakeAtRow( BeatToNoteRow( fBeat ) ); }
|
||||
|
||||
|
||||
/**
|
||||
* @brief Determine if this notes on this row can be judged.
|
||||
* @param row the row to focus on.
|
||||
* @return true if the row can be judged, false otherwise. */
|
||||
bool IsJudgableAtRow( int row ) const
|
||||
{
|
||||
return !(IsWarpAtRow(row) || IsFakeAtRow(row));
|
||||
}
|
||||
/**
|
||||
* @brief Determine if this notes on this beat can be judged.
|
||||
* @param beat the beat to focus on.
|
||||
* @return true if the row can be judged, false otherwise. */
|
||||
bool IsJudgableAtRow( int row ) const { return !IsWarpAtRow(row) && !IsFakeAtRow(row); }
|
||||
bool IsJudgableAtBeat( float beat ) const { return IsJudgableAtRow( BeatToNoteRow( beat ) ); }
|
||||
|
||||
|
||||
|
||||
|
||||
void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor );
|
||||
|
||||
|
||||
void NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, int &iBeatIndexOut, int &iRowsRemainder ) const;
|
||||
|
||||
void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut, bool &bDelayOut, int &iWarpBeginOut, float &fWarpLengthOut ) const;
|
||||
@@ -653,38 +317,16 @@ public:
|
||||
}
|
||||
float GetElapsedTimeFromBeatNoOffset( float fBeat ) const;
|
||||
float GetDisplayedBeat( float fBeat ) const;
|
||||
/**
|
||||
* @brief View the TimingData to see if a song changes its BPM at any point.
|
||||
* @return true if there is at least one change, false otherwise.
|
||||
*/
|
||||
bool HasBpmChanges() const;
|
||||
/**
|
||||
* @brief View the TimingData to see if there is at least one stop at any point.
|
||||
* @return true if there is at least one stop, false otherwise.
|
||||
*/
|
||||
bool HasStops() const;
|
||||
/**
|
||||
* @brief View the TimingData to see if there is at least one delay at any point.
|
||||
* @return true if there is at least one delay, false otherwise.
|
||||
*/
|
||||
bool HasDelays() const;
|
||||
/**
|
||||
* @brief View the TimingData to see if there is at least one warp at any point.
|
||||
* @return true if there is at least one warp, false otherwise.
|
||||
*/
|
||||
bool HasWarps() const;
|
||||
/**
|
||||
* @brief View the TimingData to see if there is at least one fake segment involved.
|
||||
* @return true if there is at least one fake segment, false otherwise. */
|
||||
bool HasFakes() const;
|
||||
/**
|
||||
* @brief View the TimingData to see if a song changes its speed scrolling at any point.
|
||||
* @return true if there is at least one change, false otherwise. */
|
||||
|
||||
bool HasBpmChanges() const { return GetTimingSegments(SEGMENT_BPM).size() > 1; }
|
||||
bool HasStops() const { return !GetTimingSegments(SEGMENT_STOP).empty(); }
|
||||
bool HasDelays() const { return !GetTimingSegments(SEGMENT_DELAY).empty(); }
|
||||
bool HasWarps() const { return !GetTimingSegments(SEGMENT_WARP).empty(); }
|
||||
bool HasFakes() const { return !GetTimingSegments(SEGMENT_FAKE).empty(); }
|
||||
|
||||
bool HasSpeedChanges() const;
|
||||
/**
|
||||
* @brief View the TimingData to see if a song changes its speed scrolling at any point.
|
||||
* @return true if there is at least one change, false otherwise. */
|
||||
bool HasScrollChanges() const;
|
||||
|
||||
/**
|
||||
* @brief Compare two sets of timing data to see if they are equal.
|
||||
* @param other the other TimingData.
|
||||
@@ -720,6 +362,13 @@ public:
|
||||
void InsertRows( int iStartRow, int iRowsToAdd );
|
||||
void DeleteRows( int iStartRow, int iRowsToDelete );
|
||||
|
||||
void SortSegments( TimingSegmentType tst );
|
||||
|
||||
const vector<TimingSegment*> &GetTimingSegments( TimingSegmentType tst ) const
|
||||
{
|
||||
return m_avpTimingSegments[tst];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tidy up the timing data, e.g. provide default BPMs, labels, tickcounts.
|
||||
*/
|
||||
@@ -727,6 +376,7 @@ public:
|
||||
|
||||
// Lua
|
||||
void PushSelf( lua_State *L );
|
||||
|
||||
/**
|
||||
* @brief The file of the song/steps that use this TimingData.
|
||||
*
|
||||
@@ -734,15 +384,17 @@ public:
|
||||
*/
|
||||
RString m_sFile;
|
||||
|
||||
// All of the following vectors must be sorted before gameplay.
|
||||
vector<TimingSegment *> m_avpTimingSegments[NUM_TimingSegmentType];
|
||||
|
||||
/**
|
||||
* @brief The initial offset of a song.
|
||||
*/
|
||||
/** @brief The initial offset of a song. */
|
||||
float m_fBeat0OffsetInSeconds;
|
||||
|
||||
// XXX: this breaks encapsulation. get rid of it ASAP
|
||||
vector<RString> ToVectorString(TimingSegmentType tst, int dec = 6) const;
|
||||
protected:
|
||||
// don't call this directly; use the derived-type overloads.
|
||||
void AddSegment( const TimingSegment *seg );
|
||||
|
||||
// All of the following vectors must be sorted before gameplay.
|
||||
vector<TimingSegment *> m_avpTimingSegments[NUM_TimingSegmentType];
|
||||
};
|
||||
|
||||
#undef COMPARE
|
||||
@@ -751,7 +403,7 @@ public:
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @author Chris Danford, Glenn Maynard (c) 2001-2004
|
||||
* @author Chris Danford, Glenn Maynard (c) 2001-2004
|
||||
* @section LICENSE
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -24,6 +24,99 @@ void TimingSegment::Scale( int start, int length, int newLength )
|
||||
SetRow( ScalePosition( start, length, newLength, this->GetRow() ) );
|
||||
}
|
||||
|
||||
void TimingSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\tTimingSegment(%d [%f])", GetRow(), GetBeat() );
|
||||
}
|
||||
|
||||
void BPMSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %f)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetBPM()
|
||||
);
|
||||
}
|
||||
|
||||
void StopSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %f)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetPause()
|
||||
);
|
||||
}
|
||||
|
||||
void DelaySegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %f)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetPause()
|
||||
);
|
||||
}
|
||||
|
||||
void TimeSignatureSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %d/%d)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetNum(), GetDen()
|
||||
);
|
||||
}
|
||||
|
||||
void WarpSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %d [%f])",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetLengthRows(), GetLengthBeats()
|
||||
);
|
||||
}
|
||||
|
||||
void LabelSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %s)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetLabel().c_str()
|
||||
);
|
||||
}
|
||||
|
||||
void TickcountSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %d)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetTicks()
|
||||
);
|
||||
}
|
||||
|
||||
void ComboSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %d, %d)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetCombo(), GetMissCombo()
|
||||
);
|
||||
}
|
||||
|
||||
void SpeedSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %f, %f, %d)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetRatio(), GetDelay(), GetUnit()
|
||||
);
|
||||
}
|
||||
|
||||
void ScrollSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %f)",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetRatio()
|
||||
);
|
||||
}
|
||||
|
||||
void FakeSegment::DebugPrint() const
|
||||
{
|
||||
LOG->Trace( "\t%s(%d [%f], %d [%f])",
|
||||
TimingSegmentTypeToString(GetType()).c_str(),
|
||||
GetRow(), GetBeat(), GetLengthRows(), GetLengthBeats()
|
||||
);
|
||||
}
|
||||
|
||||
RString FakeSegment::ToString(int dec) const
|
||||
{
|
||||
RString str = "%.0" + IntToString(dec)
|
||||
|
||||
+288
-9
@@ -20,26 +20,48 @@ enum TimingSegmentType
|
||||
TimingSegmentType_Invalid,
|
||||
};
|
||||
|
||||
// XXX: dumb names
|
||||
enum SegmentEffectType
|
||||
{
|
||||
SegmentEffectType_Row, // takes effect on a single row
|
||||
SegmentEffectType_Range, // takes effect for a definite amount of rows
|
||||
SegmentEffectType_Indefinite, // takes effect until the next segment of its type
|
||||
NUM_SegmentEffectType,
|
||||
SegmentEffectType_Invalid,
|
||||
};
|
||||
|
||||
#define FOREACH_TimingSegmentType(tst) FOREACH_ENUM(TimingSegmentType, tst)
|
||||
|
||||
const RString& TimingSegmentTypeToString( TimingSegmentType tst );
|
||||
|
||||
const int ROW_INVALID = -1;
|
||||
|
||||
#define COMPARE(x) if( this->x!=other.x ) return false
|
||||
#define COMPARE_FLOAT(x) if( fabsf(this->x - other.x) > EPSILON ) return false
|
||||
|
||||
/**
|
||||
* @brief The base timing segment for make glorious benefit wolfman
|
||||
* XXX: this should be an abstract class.
|
||||
*/
|
||||
struct TimingSegment
|
||||
{
|
||||
virtual TimingSegmentType GetType() const
|
||||
{
|
||||
return TimingSegmentType_Invalid;
|
||||
}
|
||||
virtual TimingSegmentType GetType() const { return TimingSegmentType_Invalid; }
|
||||
virtual SegmentEffectType GetEffectType() const { return SegmentEffectType_Invalid; }
|
||||
virtual TimingSegment* Copy() const = 0;
|
||||
|
||||
virtual bool IsNotable() const = 0;
|
||||
virtual void DebugPrint() const;
|
||||
|
||||
// don't allow base TimingSegments to be instantiated directly
|
||||
TimingSegment( int iRow = ROW_INVALID ) : m_iStartRow(iRow) { }
|
||||
TimingSegment( float fBeat ) : m_iStartRow(ToNoteRow(fBeat)) { }
|
||||
|
||||
TimingSegment(const TimingSegment &other) :
|
||||
m_iStartRow( other.GetRow() ) { }
|
||||
|
||||
// for our purposes, two floats within this level of error are equal
|
||||
static const double EPSILON = 1e-4f;
|
||||
|
||||
virtual ~TimingSegment() { }
|
||||
|
||||
/**
|
||||
@@ -66,14 +88,17 @@ struct TimingSegment
|
||||
return GetRow() < other.GetRow();
|
||||
}
|
||||
|
||||
// overloads should not call this base version; derived classes
|
||||
// should only compare contents, and this compares position.
|
||||
virtual bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
return GetRow() == other.GetRow();
|
||||
}
|
||||
|
||||
virtual bool operator!=( const TimingSegment &other ) const
|
||||
{
|
||||
return !operator==(other);
|
||||
return !this->operator==(other);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -95,6 +120,12 @@ private:
|
||||
struct FakeSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_FAKE; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Range; }
|
||||
|
||||
TimingSegment* Copy() const { return new FakeSegment(*this); }
|
||||
|
||||
bool IsNotable() const { return m_iLengthRows > 0; }
|
||||
void DebugPrint() const;
|
||||
|
||||
FakeSegment() : TimingSegment(), m_iLengthRows(-1) { }
|
||||
|
||||
@@ -118,6 +149,23 @@ struct FakeSegment : public TimingSegment
|
||||
void Scale( int start, int length, int newLength );
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const FakeSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE( m_iLengthRows );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const FakeSegment&>(other) );
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief The number of rows the FakeSegment is alive for. */
|
||||
int m_iLengthRows;
|
||||
@@ -133,6 +181,11 @@ private:
|
||||
struct WarpSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_WARP; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Range; }
|
||||
TimingSegment* Copy() const { return new WarpSegment(*this); }
|
||||
|
||||
bool IsNotable() const { return m_iLengthRows > 0; }
|
||||
void DebugPrint() const;
|
||||
|
||||
WarpSegment() : TimingSegment(), m_iLengthRows(0) { }
|
||||
|
||||
@@ -154,8 +207,24 @@ struct WarpSegment : public TimingSegment
|
||||
void SetLength( float fBeats ) { m_iLengthRows = ToNoteRow(fBeats); }
|
||||
|
||||
void Scale( int start, int length, int newLength );
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const WarpSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE( m_iLengthRows );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const WarpSegment&>(other) );
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief The number of rows the WarpSegment will warp past. */
|
||||
int m_iLengthRows;
|
||||
@@ -170,12 +239,19 @@ private:
|
||||
* represent how many ticks can be counted in one beat.
|
||||
*/
|
||||
|
||||
/** @brief The default amount of ticks per beat. */
|
||||
const unsigned DEFAULT_TICK_COUNT = 4;
|
||||
|
||||
struct TickcountSegment : public TimingSegment
|
||||
{
|
||||
/** @brief The default amount of ticks per beat. */
|
||||
static const unsigned DEFAULT_TICK_COUNT = 4;
|
||||
|
||||
TimingSegmentType GetType() const { return SEGMENT_TICKCOUNT; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Indefinite; }
|
||||
|
||||
bool IsNotable() const { return true; } // indefinite segments are always true
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new TickcountSegment(*this); }
|
||||
|
||||
TickcountSegment( int iStartRow = ROW_INVALID, int iTicks = DEFAULT_TICK_COUNT ) :
|
||||
TimingSegment(iStartRow), m_iTicksPerBeat(iTicks) { }
|
||||
@@ -188,6 +264,22 @@ struct TickcountSegment : public TimingSegment
|
||||
void SetTicks( int iTicks ) { m_iTicksPerBeat = iTicks; }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const TickcountSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE( m_iTicksPerBeat );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const TickcountSegment&>(other) );
|
||||
}
|
||||
private:
|
||||
/** @brief The amount of hold checkpoints counted per beat */
|
||||
int m_iTicksPerBeat;
|
||||
@@ -202,6 +294,12 @@ private:
|
||||
struct ComboSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_COMBO; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Indefinite; }
|
||||
|
||||
bool IsNotable() const { return true; } // indefinite segments are always true
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new ComboSegment(*this); }
|
||||
|
||||
ComboSegment( int iStartRow = ROW_INVALID, int iCombo = 1, int iMissCombo = 1 ) :
|
||||
TimingSegment(iStartRow), m_iCombo(iCombo),
|
||||
@@ -219,6 +317,23 @@ struct ComboSegment : public TimingSegment
|
||||
void SetMissCombo( int iCombo ) { m_iMissCombo = iCombo; }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const ComboSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE( m_iCombo );
|
||||
COMPARE( m_iMissCombo );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const ComboSegment&>(other) );
|
||||
}
|
||||
private:
|
||||
/** @brief The amount the combo increases at this point. */
|
||||
int m_iCombo;
|
||||
@@ -237,6 +352,12 @@ private:
|
||||
struct LabelSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_LABEL; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Indefinite; }
|
||||
|
||||
bool IsNotable() const { return true; } // indefinite segments are always true
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new LabelSegment(*this); }
|
||||
|
||||
LabelSegment( int iStartRow = ROW_INVALID, const RString& sLabel = RString() ) :
|
||||
TimingSegment(iStartRow), m_sLabel(sLabel) { }
|
||||
@@ -249,6 +370,22 @@ struct LabelSegment : public TimingSegment
|
||||
void SetLabel( const RString& sLabel ) { m_sLabel.assign(sLabel); }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const LabelSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE( m_sLabel );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const LabelSegment&>(other) );
|
||||
}
|
||||
private:
|
||||
/** @brief The label/section name for this point. */
|
||||
RString m_sLabel;
|
||||
@@ -260,6 +397,12 @@ private:
|
||||
struct BPMSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_BPM; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Indefinite; }
|
||||
|
||||
bool IsNotable() const { return true; } // indefinite segments are always true
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new BPMSegment(*this); }
|
||||
|
||||
// note that this takes a BPM, not a BPS (compatibility)
|
||||
BPMSegment( int iStartRow = ROW_INVALID, float fBPM = 0.0f ) :
|
||||
@@ -276,6 +419,23 @@ struct BPMSegment : public TimingSegment
|
||||
void SetBPM( float fBPM ) { m_fBPS = fBPM / 60.0f; }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const BPMSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE_FLOAT( m_fBPS );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const BPMSegment&>(other) );
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief The number of beats per second within this BPMSegment. */
|
||||
float m_fBPS;
|
||||
@@ -291,6 +451,12 @@ private:
|
||||
struct TimeSignatureSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_TIME_SIG; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Indefinite; }
|
||||
|
||||
bool IsNotable() const { return true; } // indefinite segments are always true
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new TimeSignatureSegment(*this); }
|
||||
|
||||
TimeSignatureSegment( int iStartRow = ROW_INVALID,
|
||||
int iNum = 4, int iDenom = 4 ) :
|
||||
@@ -308,6 +474,8 @@ struct TimeSignatureSegment : public TimingSegment
|
||||
int GetDen() const { return m_iDenominator; }
|
||||
void SetDen( int den ) { m_iDenominator = den; }
|
||||
|
||||
void Set( int num, int den ) { m_iNumerator = num; m_iDenominator = den; }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
/**
|
||||
@@ -325,6 +493,23 @@ struct TimeSignatureSegment : public TimingSegment
|
||||
return BeatToNoteRow(1) * 4 * m_iNumerator / m_iDenominator;
|
||||
}
|
||||
|
||||
bool operator==( const TimeSignatureSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE( m_iNumerator );
|
||||
COMPARE( m_iDenominator );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const TimeSignatureSegment&>(other) );
|
||||
}
|
||||
|
||||
private:
|
||||
int m_iNumerator, m_iDenominator;
|
||||
};
|
||||
@@ -342,6 +527,12 @@ private:
|
||||
struct SpeedSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_SPEED; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Indefinite; }
|
||||
|
||||
bool IsNotable() const { return true; } // indefinite segments are always true
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new SpeedSegment(*this); }
|
||||
|
||||
/** @brief The type of unit used for segment scaling. */
|
||||
enum BaseUnit { UNIT_BEATS, UNIT_SECONDS };
|
||||
@@ -369,6 +560,25 @@ struct SpeedSegment : public TimingSegment
|
||||
void Scale( int start, int length, int newLength );
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const SpeedSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE_FLOAT( m_fRatio );
|
||||
COMPARE_FLOAT( m_fDelay );
|
||||
COMPARE( m_Unit );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const SpeedSegment&>(other) );
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief The percentage by which the Player's BPM is multiplied. */
|
||||
float m_fRatio;
|
||||
@@ -393,6 +603,12 @@ private:
|
||||
struct ScrollSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_SCROLL; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Indefinite; }
|
||||
|
||||
bool IsNotable() const { return true; } // indefinite segments are always true
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new ScrollSegment(*this); }
|
||||
|
||||
ScrollSegment( int iStartRow = ROW_INVALID, float fRatio = 1.0f ) :
|
||||
TimingSegment(iStartRow), m_fRatio(fRatio) { }
|
||||
@@ -405,6 +621,23 @@ struct ScrollSegment : public TimingSegment
|
||||
void SetRatio( float fRatio ) { m_fRatio = fRatio; }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const ScrollSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE_FLOAT( m_fRatio );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const ScrollSegment&>(other) );
|
||||
}
|
||||
|
||||
private:
|
||||
/** @brief The percentage by which the chart's scroll rate is multiplied. */
|
||||
float m_fRatio;
|
||||
@@ -416,6 +649,12 @@ private:
|
||||
struct StopSegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_STOP; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Row; }
|
||||
|
||||
bool IsNotable() const { return m_fSeconds > 0; }
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new StopSegment(*this); }
|
||||
|
||||
StopSegment( int iStartRow = ROW_INVALID, float fSeconds = 0.0f ) :
|
||||
TimingSegment(iStartRow), m_fSeconds(fSeconds) { }
|
||||
@@ -428,6 +667,22 @@ struct StopSegment : public TimingSegment
|
||||
void SetPause( float fSeconds ) { m_fSeconds = fSeconds; }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const StopSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE_FLOAT( m_fSeconds );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const StopSegment&>(other) );
|
||||
}
|
||||
private:
|
||||
/** @brief The number of seconds to pause at the segment's row. */
|
||||
float m_fSeconds;
|
||||
@@ -439,8 +694,14 @@ private:
|
||||
struct DelaySegment : public TimingSegment
|
||||
{
|
||||
TimingSegmentType GetType() const { return SEGMENT_DELAY; }
|
||||
SegmentEffectType GetEffectType() const { return SegmentEffectType_Row; }
|
||||
|
||||
DelaySegment( int iStartRow, float fSeconds ) :
|
||||
bool IsNotable() const { return m_fSeconds > 0; }
|
||||
void DebugPrint() const;
|
||||
|
||||
TimingSegment* Copy() const { return new DelaySegment(*this); }
|
||||
|
||||
DelaySegment( int iStartRow = ROW_INVALID, float fSeconds = 0 ) :
|
||||
TimingSegment(iStartRow), m_fSeconds(fSeconds) { }
|
||||
|
||||
DelaySegment( const DelaySegment &other ) :
|
||||
@@ -451,11 +712,29 @@ struct DelaySegment : public TimingSegment
|
||||
void SetPause( float fSeconds ) { m_fSeconds = fSeconds; }
|
||||
|
||||
RString ToString( int dec ) const;
|
||||
|
||||
bool operator==( const DelaySegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
COMPARE_FLOAT( m_fSeconds );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==( const TimingSegment &other ) const
|
||||
{
|
||||
LOG->Trace( __PRETTY_FUNCTION__ );
|
||||
if( GetType() != other.GetType() )
|
||||
return false;
|
||||
|
||||
return operator==( static_cast<const DelaySegment&>(other) );
|
||||
}
|
||||
private:
|
||||
/** @brief The number of seconds to pause at the segment's row. */
|
||||
float m_fSeconds;
|
||||
};
|
||||
|
||||
#undef COMPARE
|
||||
#undef COMPARE_FLOAT
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user