Represent TimingData values (except for "seconds") in fixed-point.
Maybe we should stop calling note indexes "rows" and "indexes", and just call them "beats"; if they're stored as an integer, they're in fixed-point. Things like "note rows per second" are a lot less intuitive than just calling them "beats per second".
This commit is contained in:
@@ -308,19 +308,21 @@ void Background::LoadFromRandom( float fFirstBeat, float fLastBeat, const Timing
|
||||
}
|
||||
|
||||
// change BG every BPM change that is at the beginning of a measure
|
||||
int iStartIndex = BeatToNoteRow(fFirstBeat);
|
||||
int iEndIndex = BeatToNoteRow(fLastBeat);
|
||||
for( unsigned i=0; i<timing.m_BPMSegments.size(); i++ )
|
||||
{
|
||||
const BPMSegment& bpmseg = timing.m_BPMSegments[i];
|
||||
|
||||
if( fmodf(bpmseg.m_fStartBeat, (float)BEATS_PER_MEASURE) != 0 )
|
||||
if( bpmseg.m_iStartIndex % BeatToNoteRow((float) BEATS_PER_MEASURE) != 0 )
|
||||
continue; // skip
|
||||
|
||||
if( bpmseg.m_fStartBeat < fFirstBeat || bpmseg.m_fStartBeat > fLastBeat )
|
||||
if( bpmseg.m_iStartIndex < iStartIndex || bpmseg.m_iStartIndex > iEndIndex )
|
||||
continue; // skip
|
||||
|
||||
CString sBGName = CreateRandomBGA();
|
||||
if( sBGName != "" )
|
||||
m_aBGChanges.push_back( BackgroundChange(bpmseg.m_fStartBeat,sBGName) );
|
||||
m_aBGChanges.push_back( BackgroundChange(NoteRowToBeat(bpmseg.m_iStartIndex),sBGName) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -485,9 +485,9 @@ void NoteField::DrawPrimitives()
|
||||
vector<BPMSegment> &aBPMSegments = GAMESTATE->m_pCurSong->m_Timing.m_BPMSegments;
|
||||
for( unsigned i=0; i<aBPMSegments.size(); i++ )
|
||||
{
|
||||
if(aBPMSegments[i].m_fStartBeat >= fFirstBeatToDraw &&
|
||||
aBPMSegments[i].m_fStartBeat <= fLastBeatToDraw)
|
||||
DrawBPMText( aBPMSegments[i].m_fStartBeat, aBPMSegments[i].m_fBPM );
|
||||
if(aBPMSegments[i].m_iStartIndex >= iFirstIndexToDraw &&
|
||||
aBPMSegments[i].m_iStartIndex <= iLastIndexToDraw)
|
||||
DrawBPMText( NoteRowToBeat(aBPMSegments[i].m_iStartIndex), aBPMSegments[i].GetBPM() );
|
||||
}
|
||||
//
|
||||
// Freeze text
|
||||
@@ -495,9 +495,9 @@ void NoteField::DrawPrimitives()
|
||||
vector<StopSegment> &aStopSegments = GAMESTATE->m_pCurSong->m_Timing.m_StopSegments;
|
||||
for( unsigned i=0; i<aStopSegments.size(); i++ )
|
||||
{
|
||||
if(aStopSegments[i].m_fStartBeat >= fFirstBeatToDraw &&
|
||||
aStopSegments[i].m_fStartBeat <= fLastBeatToDraw)
|
||||
DrawFreezeText( aStopSegments[i].m_fStartBeat, aStopSegments[i].m_fStopSeconds );
|
||||
if(aStopSegments[i].m_iStartRow >= iFirstIndexToDraw &&
|
||||
aStopSegments[i].m_iStartRow <= iLastIndexToDraw)
|
||||
DrawFreezeText( NoteRowToBeat(aStopSegments[i].m_iStartRow), NoteRowToBeat(aStopSegments[i].m_iStartRow) );
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "song.h"
|
||||
#include "Steps.h"
|
||||
#include "RageUtil_CharConversions.h"
|
||||
#include "NoteTypes.h"
|
||||
|
||||
/* BMS encoding: tap-hold
|
||||
4&8panel: Player1 Player2
|
||||
@@ -602,10 +603,10 @@ void BMSLoader::ReadGlobalTags( const NameToData_t &mapNameToData, Song &out )
|
||||
|
||||
if( GetTagFromMap( mapNameToData, "#bpm", sData ) )
|
||||
{
|
||||
BPMSegment newSeg( 0, strtof(sData, NULL) );
|
||||
BPMSegment newSeg( 0, BeatToNoteRow(strtof(sData, NULL)) );
|
||||
out.AddBPMSegment( newSeg );
|
||||
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.m_fStartBeat, newSeg.m_fBPM );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartIndex), newSeg.GetBPM() );
|
||||
}
|
||||
|
||||
NameToData_t::const_iterator it;
|
||||
@@ -691,9 +692,11 @@ void BMSLoader::ReadGlobalTags( const NameToData_t &mapNameToData, Song &out )
|
||||
{
|
||||
float fBPM = strtof( sBPM, NULL );
|
||||
|
||||
BPMSegment newSeg( fBeat, fBPM );
|
||||
BPMSegment newSeg;
|
||||
newSeg.m_iStartIndex = BeatToNoteRow(fBeat);
|
||||
newSeg.SetBPM( fBPM );
|
||||
out.AddBPMSegment( newSeg );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.m_fStartBeat, newSeg.m_fBPM );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", fBeat, newSeg.GetBPM() );
|
||||
}
|
||||
else
|
||||
LOG->Warn( "Couldn't find tag '%s' in '%s'.", sTagToLookFor.c_str(), m_sDir.c_str() );
|
||||
@@ -710,9 +713,9 @@ void BMSLoader::ReadGlobalTags( const NameToData_t &mapNameToData, Song &out )
|
||||
float fBeats = strtof(sBeats,NULL) / 48.0f;
|
||||
float fFreezeSecs = fBeats / fBPS;
|
||||
|
||||
StopSegment newSeg( fBeat, fFreezeSecs );
|
||||
StopSegment newSeg( BeatToNoteRow(fBeat), fFreezeSecs );
|
||||
out.AddStopSegment( newSeg );
|
||||
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", newSeg.m_fStartBeat, newSeg.m_fStopSeconds );
|
||||
LOG->Trace( "Inserting new Freeze at beat %f, secs %f", fBeat, newSeg.m_fStopSeconds );
|
||||
}
|
||||
else
|
||||
LOG->Warn( "Couldn't find tag '%s' in '%s'.", sTagToLookFor.c_str(), m_sDir.c_str() );
|
||||
@@ -735,9 +738,11 @@ void BMSLoader::ReadGlobalTags( const NameToData_t &mapNameToData, Song &out )
|
||||
{
|
||||
float fBPM = strtof( sBPM, NULL );
|
||||
|
||||
BPMSegment newSeg( NoteRowToBeat(iStepIndex), fBPM );
|
||||
BPMSegment newSeg;
|
||||
newSeg.m_iStartIndex = iStepIndex;
|
||||
newSeg.SetBPM( fBPM );
|
||||
out.AddBPMSegment( newSeg );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.m_fStartBeat, newSeg.m_fBPM );
|
||||
LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartIndex), newSeg.GetBPM() );
|
||||
}
|
||||
else
|
||||
LOG->Warn( "Couldn't find tag '%s' in '%s'.", sTagToLookFor.c_str(), m_sDir.c_str() );
|
||||
@@ -834,9 +839,9 @@ void BMSLoader::SetTimeSigAdjustments( const MeasureToTimeSig_t &sigs, Song *pOu
|
||||
* adjustment and the BPM adjustment together, everything remains consistent.
|
||||
* Adjust m_TimeSigAdjustments first, or fAdjustmentEndBeat will be wrong. */
|
||||
m_TimeSigAdjustments[iMeasure] = 1.0f / fFactor;
|
||||
float fAdjustmentStartBeat = NoteRowToBeat( GetMeasureStartRow( sigs, iMeasure ) );
|
||||
float fAdjustmentEndBeat = NoteRowToBeat( GetMeasureStartRow( sigs, iMeasure+1 ) );
|
||||
pOut->m_Timing.MultiplyBPMInBeatRange( fAdjustmentStartBeat, fAdjustmentEndBeat, 1.0f / fFactor );
|
||||
int iAdjustmentStartRow = GetMeasureStartRow( sigs, iMeasure );
|
||||
int iAdjustmentEndRow = GetMeasureStartRow( sigs, iMeasure+1 );
|
||||
pOut->m_Timing.MultiplyBPMInBeatRange( iAdjustmentStartRow, iAdjustmentEndRow, 1.0f / fFactor );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -375,7 +375,7 @@ bool DWILoader::LoadFromDWIFile( CString sPath, Song &out )
|
||||
out.m_sCDTitleFile = sParams[1];
|
||||
|
||||
else if( 0==stricmp(sValueName,"BPM") )
|
||||
out.AddBPMSegment( BPMSegment(0, strtof(sParams[1], NULL)) );
|
||||
out.AddBPMSegment( BPMSegment(0, BeatToNoteRow(strtof(sParams[1], NULL))) );
|
||||
|
||||
else if( 0==stricmp(sValueName,"DISPLAYBPM") )
|
||||
{
|
||||
@@ -425,11 +425,10 @@ bool DWILoader::LoadFromDWIFile( CString sPath, Song &out )
|
||||
LOG->Warn( "Invalid FREEZE in '%s': '%s'", m_sLoadingFile.c_str(), arrayFreezeExpressions[f].c_str() );
|
||||
continue;
|
||||
}
|
||||
float fIndex = strtof( arrayFreezeValues[0],NULL ) * ROWS_PER_BEAT / 4.0f;
|
||||
float fFreezeBeat = NoteRowToBeat( fIndex );
|
||||
int iFreezeRow = BeatToNoteRow( strtof( arrayFreezeValues[0],NULL ) / 4.0f );
|
||||
float fFreezeSeconds = strtof( arrayFreezeValues[1], NULL ) / 1000.0f;
|
||||
|
||||
out.AddStopSegment( StopSegment(fFreezeBeat, fFreezeSeconds) );
|
||||
out.AddStopSegment( StopSegment(iFreezeRow, fFreezeSeconds) );
|
||||
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", fFreezeBeat, fFreezeSeconds );
|
||||
}
|
||||
}
|
||||
@@ -448,11 +447,11 @@ bool DWILoader::LoadFromDWIFile( CString sPath, Song &out )
|
||||
LOG->Warn( "Invalid CHANGEBPM in '%s': '%s'", m_sLoadingFile.c_str(), arrayBPMChangeExpressions[b].c_str() );
|
||||
continue;
|
||||
}
|
||||
float fIndex = strtof( arrayBPMChangeValues[0], NULL ) * ROWS_PER_BEAT / 4.0f;
|
||||
float fBeat = NoteRowToBeat( fIndex );
|
||||
float fNewBPM = strtof( arrayBPMChangeValues[1], NULL );
|
||||
|
||||
out.AddBPMSegment( BPMSegment(fBeat, fNewBPM) );
|
||||
BPMSegment bs;
|
||||
bs.m_iStartIndex = BeatToNoteRow( strtof( arrayBPMChangeValues[0],NULL ) / 4.0f );
|
||||
bs.SetBPM( strtof( arrayBPMChangeValues[1], NULL ) );
|
||||
out.AddBPMSegment( bs );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "RageUtil.h"
|
||||
#include "SongManager.h"
|
||||
#include "RageFileManager.h"
|
||||
#include "NoteTypes.h"
|
||||
|
||||
#define MAX_EDIT_SIZE_BYTES 20*1024 // 20 KB
|
||||
|
||||
@@ -110,7 +111,7 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
const float fFreezeSeconds = strtof( arrayFreezeValues[1], NULL );
|
||||
|
||||
StopSegment new_seg;
|
||||
new_seg.m_fStartBeat = fFreezeBeat;
|
||||
new_seg.m_iStartRow = BeatToNoteRow(fFreezeBeat);
|
||||
new_seg.m_fStopSeconds = fFreezeSeconds;
|
||||
|
||||
// LOG->Trace( "Adding a freeze segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds );
|
||||
@@ -141,8 +142,8 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
|
||||
const float fNewBPM = strtof( arrayBPMChangeValues[1], NULL );
|
||||
|
||||
BPMSegment new_seg;
|
||||
new_seg.m_fStartBeat = fBeat;
|
||||
new_seg.m_fBPM = fNewBPM;
|
||||
new_seg.m_iStartIndex = BeatToNoteRow(fBeat);
|
||||
new_seg.SetBPM( fNewBPM );
|
||||
|
||||
out.AddBPMSegment( new_seg );
|
||||
}
|
||||
|
||||
@@ -350,9 +350,9 @@ bool NotesWriterDWI::Write( CString sPath, const Song &out )
|
||||
/* Write transliterations, if we have them, since DWI doesn't support UTF-8. */
|
||||
f.PutLine( ssprintf("#TITLE:%s;", out.GetFullTranslitTitle().c_str()) );
|
||||
f.PutLine( ssprintf("#ARTIST:%s;", out.GetTranslitArtist().c_str()) );
|
||||
ASSERT( out.m_Timing.m_BPMSegments[0].m_fStartBeat == 0 );
|
||||
ASSERT( out.m_Timing.m_BPMSegments[0].m_iStartIndex == 0 );
|
||||
f.PutLine( ssprintf("#FILE:%s;", out.m_sMusicFile.c_str()) );
|
||||
f.PutLine( ssprintf("#BPM:%.3f;", out.m_Timing.m_BPMSegments[0].m_fBPM) );
|
||||
f.PutLine( ssprintf("#BPM:%.3f;", out.m_Timing.m_BPMSegments[0].GetBPM()) );
|
||||
f.PutLine( ssprintf("#GAP:%d;", int(-roundf( out.m_Timing.m_fBeat0OffsetInSeconds*1000 ))) );
|
||||
f.PutLine( ssprintf("#SAMPLESTART:%.3f;", out.m_fMusicSampleStartSeconds) );
|
||||
f.PutLine( ssprintf("#SAMPLELENGTH:%.3f;", out.m_fMusicSampleLengthSeconds) );
|
||||
@@ -381,7 +381,7 @@ bool NotesWriterDWI::Write( CString sPath, const Song &out )
|
||||
for( unsigned i=0; i<out.m_Timing.m_StopSegments.size(); i++ )
|
||||
{
|
||||
const StopSegment &fs = out.m_Timing.m_StopSegments[i];
|
||||
f.Write( ssprintf("%.3f=%.3f", BeatToNoteRow( fs.m_fStartBeat ) * 4.0f / ROWS_PER_BEAT,
|
||||
f.Write( ssprintf("%.3f=%.3f", fs.m_iStartRow * 4.0f / ROWS_PER_BEAT,
|
||||
roundf(fs.m_fStopSeconds*1000)) );
|
||||
if( i != out.m_Timing.m_StopSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
@@ -395,7 +395,7 @@ bool NotesWriterDWI::Write( CString sPath, const Song &out )
|
||||
for( unsigned i=1; i<out.m_Timing.m_BPMSegments.size(); i++ )
|
||||
{
|
||||
const BPMSegment &bs = out.m_Timing.m_BPMSegments[i];
|
||||
f.Write( ssprintf("%.3f=%.3f", BeatToNoteRow( bs.m_fStartBeat ) * 4.0f / ROWS_PER_BEAT, bs.m_fBPM ) );
|
||||
f.Write( ssprintf("%.3f=%.3f", bs.m_iStartIndex * 4.0f / ROWS_PER_BEAT, bs.GetBPM() ) );
|
||||
if( i != out.m_Timing.m_BPMSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "RageFile.h"
|
||||
#include "RageFileManager.h"
|
||||
#include "song.h"
|
||||
#include "NoteTypes.h"
|
||||
#include <cstring>
|
||||
#include <cerrno>
|
||||
|
||||
@@ -62,7 +63,7 @@ void NotesWriterSM::WriteGlobalTags( RageFile &f, const Song &out )
|
||||
{
|
||||
const BPMSegment &bs = out.m_Timing.m_BPMSegments[i];
|
||||
|
||||
f.Write( ssprintf( "%.3f=%.3f", bs.m_fStartBeat, bs.m_fBPM ) );
|
||||
f.Write( ssprintf( "%.3f=%.3f", NoteRowToBeat(bs.m_iStartIndex), bs.GetBPM() ) );
|
||||
if( i != out.m_Timing.m_BPMSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
@@ -73,7 +74,7 @@ void NotesWriterSM::WriteGlobalTags( RageFile &f, const Song &out )
|
||||
{
|
||||
const StopSegment &fs = out.m_Timing.m_StopSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.3f=%.3f", fs.m_fStartBeat, fs.m_fStopSeconds ) );
|
||||
f.PutLine( ssprintf( "%.3f=%.3f", NoteRowToBeat(fs.m_iStartRow), fs.m_fStopSeconds ) );
|
||||
if( i != out.m_Timing.m_StopSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
|
||||
@@ -1190,7 +1190,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
||||
unsigned i;
|
||||
for( i=0; i<m_pSong->m_Timing.m_StopSegments.size(); i++ )
|
||||
{
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat )
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) )
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1198,7 +1198,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
||||
{
|
||||
// create a new StopSegment
|
||||
if( fStopDelta > 0 )
|
||||
m_pSong->AddStopSegment( StopSegment(GAMESTATE->m_fSongBeat, fStopDelta) );
|
||||
m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(GAMESTATE->m_fSongBeat), fStopDelta) );
|
||||
}
|
||||
else // StopSegment being modified is m_Timing.m_StopSegments[i]
|
||||
{
|
||||
@@ -1801,7 +1801,8 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, int* iAnswers )
|
||||
unsigned i;
|
||||
for( i=0; i<m_pSong->m_Timing.m_StopSegments.size(); i++ )
|
||||
{
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat )
|
||||
// XXX
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) )
|
||||
break;
|
||||
}
|
||||
if ( i == m_pSong->m_Timing.m_StopSegments.size() )
|
||||
@@ -2071,7 +2072,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
||||
float fDeltaBeats = fNewClipboardBeats - fOldClipboardBeats;
|
||||
float fNewClipboardEndBeat = m_NoteFieldEdit.m_fBeginMarker + fNewClipboardBeats;
|
||||
NoteDataUtil::ShiftRows( m_NoteDataEdit, BeatToNoteRow(m_NoteFieldEdit.m_fBeginMarker), BeatToNoteRow(fDeltaBeats) );
|
||||
m_pSong->m_Timing.ScaleRegion( fScale, m_NoteFieldEdit.m_fBeginMarker, m_NoteFieldEdit.m_fEndMarker );
|
||||
m_pSong->m_Timing.ScaleRegion( fScale, BeatToNoteRow(m_NoteFieldEdit.m_fBeginMarker), BeatToNoteRow(m_NoteFieldEdit.m_fEndMarker) );
|
||||
|
||||
HandleAreaMenuChoice( paste_at_begin_marker, NULL );
|
||||
|
||||
@@ -2199,10 +2200,10 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
||||
NoteDataUtil::ShiftRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(-1) );
|
||||
break;
|
||||
case shift_pauses_forward:
|
||||
m_pSong->m_Timing.ShiftRows( GAMESTATE->m_fSongBeat, 1 );
|
||||
m_pSong->m_Timing.ShiftRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(+1) );
|
||||
break;
|
||||
case shift_pauses_backward:
|
||||
m_pSong->m_Timing.ShiftRows( GAMESTATE->m_fSongBeat, -1 );
|
||||
m_pSong->m_Timing.ShiftRows( BeatToNoteRow(GAMESTATE->m_fSongBeat), BeatToNoteRow(-1) );
|
||||
break;
|
||||
// MD 11/02/03 - Converting selected region to a pause of the same length.
|
||||
case convert_beat_to_pause:
|
||||
@@ -2218,26 +2219,26 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
||||
BeatToNoteRow(m_NoteFieldEdit.m_fBeginMarker) + 1,
|
||||
BeatToNoteRow(-m_NoteFieldEdit.m_fEndMarker+m_NoteFieldEdit.m_fBeginMarker)
|
||||
);
|
||||
m_pSong->m_Timing.ShiftRows( m_NoteFieldEdit.m_fBeginMarker + 0.003f,
|
||||
(-m_NoteFieldEdit.m_fEndMarker+m_NoteFieldEdit.m_fBeginMarker)
|
||||
m_pSong->m_Timing.ShiftRows( BeatToNoteRow(m_NoteFieldEdit.m_fBeginMarker) + 1,
|
||||
BeatToNoteRow(-m_NoteFieldEdit.m_fEndMarker+m_NoteFieldEdit.m_fBeginMarker)
|
||||
);
|
||||
unsigned i;
|
||||
for( i=0; i<m_pSong->m_Timing.m_StopSegments.size(); i++ )
|
||||
{
|
||||
float fStart = m_pSong->m_Timing.GetElapsedTimeFromBeat(m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat);
|
||||
float fStart = m_pSong->m_Timing.GetElapsedTimeFromBeat(NoteRowToBeat(m_pSong->m_Timing.m_StopSegments[i].m_iStartRow));
|
||||
float fEnd = fStart + m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds;
|
||||
if( fStart > fMarkerEnd || fEnd < fMarkerStart )
|
||||
continue;
|
||||
else {
|
||||
if (fStart > fMarkerStart)
|
||||
m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat = m_NoteFieldEdit.m_fBeginMarker;
|
||||
if( fStart > fMarkerStart )
|
||||
m_pSong->m_Timing.m_StopSegments[i].m_iStartRow = BeatToNoteRow(m_NoteFieldEdit.m_fBeginMarker);
|
||||
m_pSong->m_Timing.m_StopSegments[i].m_fStopSeconds = fStopLength;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i == m_pSong->m_Timing.m_StopSegments.size() ) // there is no BPMSegment at the current beat
|
||||
m_pSong->AddStopSegment( StopSegment(m_NoteFieldEdit.m_fBeginMarker, fStopLength) );
|
||||
m_pSong->AddStopSegment( StopSegment(BeatToNoteRow(m_NoteFieldEdit.m_fBeginMarker), fStopLength) );
|
||||
m_NoteFieldEdit.m_fEndMarker = -1;
|
||||
break;
|
||||
}
|
||||
@@ -2255,7 +2256,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
||||
unsigned i;
|
||||
for( i=0; i<m_pSong->m_Timing.m_StopSegments.size(); i++ )
|
||||
{
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_fStartBeat == GAMESTATE->m_fSongBeat )
|
||||
if( m_pSong->m_Timing.m_StopSegments[i].m_iStartRow == BeatToNoteRow(GAMESTATE->m_fSongBeat) )
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2271,7 +2272,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, int* iAnswers )
|
||||
// don't move the step from where it is, just move everything later
|
||||
m_NoteDataEdit.ConvertHoldNotesTo2sAnd3s();
|
||||
NoteDataUtil::ShiftRows( m_NoteDataEdit, BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopLength) );
|
||||
m_pSong->m_Timing.ShiftRows( GAMESTATE->m_fSongBeat + 0.003f, fStopLength );
|
||||
m_pSong->m_Timing.ShiftRows( BeatToNoteRow(GAMESTATE->m_fSongBeat) + 1, BeatToNoteRow(fStopLength) );
|
||||
m_NoteDataEdit.Convert2sAnd3sToHoldNotes();
|
||||
|
||||
}
|
||||
|
||||
@@ -1829,9 +1829,9 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
|
||||
fOffsetDelta *= 10;
|
||||
BPMSegment& seg = GAMESTATE->m_pCurSong->GetBPMSegmentAtBeat( GAMESTATE->m_fSongBeat );
|
||||
|
||||
seg.m_fBPM += fOffsetDelta;
|
||||
seg.m_iBPS += BeatToNoteRow(fOffsetDelta);
|
||||
|
||||
m_textDebug.SetText( ssprintf("Cur BPM = %.2f", seg.m_fBPM) );
|
||||
m_textDebug.SetText( ssprintf("Cur BPM = %.2f", seg.GetBPM()) );
|
||||
m_textDebug.StopTweening();
|
||||
m_textDebug.SetDiffuse( RageColor(1,1,1,1) );
|
||||
m_textDebug.BeginTweening( 3 ); // sleep
|
||||
|
||||
@@ -524,8 +524,8 @@ void Song::TidyUpData()
|
||||
}
|
||||
|
||||
/* Make sure the first BPM segment starts at beat 0. */
|
||||
if( m_Timing.m_BPMSegments[0].m_fStartBeat != 0 )
|
||||
m_Timing.m_BPMSegments[0].m_fStartBeat = 0;
|
||||
if( m_Timing.m_BPMSegments[0].m_iStartIndex != 0 )
|
||||
m_Timing.m_BPMSegments[0].m_iStartIndex = 0;
|
||||
|
||||
|
||||
if( m_fMusicSampleStartSeconds == -1 ||
|
||||
|
||||
+107
-62
@@ -3,6 +3,17 @@
|
||||
#include "PrefsManager.h"
|
||||
#include "RageUtil.h"
|
||||
#include "RageLog.h"
|
||||
#include "NoteTypes.h"
|
||||
|
||||
void BPMSegment::SetBPM( float f )
|
||||
{
|
||||
m_iBPS = BeatToNoteRow( f / 60.0f );
|
||||
}
|
||||
|
||||
float BPMSegment::GetBPM() const
|
||||
{
|
||||
return NoteRowToBeat(m_iBPS * 60);
|
||||
}
|
||||
|
||||
TimingData::TimingData()
|
||||
{
|
||||
@@ -11,7 +22,7 @@ TimingData::TimingData()
|
||||
|
||||
static int CompareBPMSegments(const BPMSegment &seg1, const BPMSegment &seg2)
|
||||
{
|
||||
return seg1.m_fStartBeat < seg2.m_fStartBeat;
|
||||
return seg1.m_iStartIndex < seg2.m_iStartIndex;
|
||||
}
|
||||
|
||||
void SortBPMSegmentsArray( vector<BPMSegment> &arrayBPMSegments )
|
||||
@@ -21,7 +32,7 @@ void SortBPMSegmentsArray( vector<BPMSegment> &arrayBPMSegments )
|
||||
|
||||
static int CompareStopSegments(const StopSegment &seg1, const StopSegment &seg2)
|
||||
{
|
||||
return seg1.m_fStartBeat < seg2.m_fStartBeat;
|
||||
return seg1.m_iStartRow < seg2.m_iStartRow;
|
||||
}
|
||||
|
||||
void SortStopSegmentsArray( vector<StopSegment> &arrayStopSegments )
|
||||
@@ -31,14 +42,16 @@ void SortStopSegmentsArray( vector<StopSegment> &arrayStopSegments )
|
||||
|
||||
void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
|
||||
{
|
||||
fMaxBPMOut = 0;
|
||||
fMinBPMOut = 100000; // inf
|
||||
int iMinBPS = MAX_NOTE_ROW;
|
||||
int iMaxBPS = 0;
|
||||
for( unsigned i=0; i<m_BPMSegments.size(); i++ )
|
||||
{
|
||||
const BPMSegment &seg = m_BPMSegments[i];
|
||||
fMaxBPMOut = max( seg.m_fBPM, fMaxBPMOut );
|
||||
fMinBPMOut = min( seg.m_fBPM, fMinBPMOut );
|
||||
iMaxBPS = max( seg.m_iBPS, iMaxBPS );
|
||||
iMinBPS = min( seg.m_iBPS, iMinBPS );
|
||||
}
|
||||
fMinBPMOut = NoteRowToBeat( iMinBPS );
|
||||
fMaxBPMOut = NoteRowToBeat( iMaxBPS );
|
||||
}
|
||||
|
||||
|
||||
@@ -57,41 +70,43 @@ void TimingData::AddStopSegment( const StopSegment &seg )
|
||||
/* Change an existing BPM segment, merge identical segments together or insert a new one. */
|
||||
void TimingData::SetBPMAtBeat( float fBeat, float fBPM )
|
||||
{
|
||||
int iNoteRow = BeatToNoteRow( fBeat );
|
||||
int iBPS = BeatToNoteRow( fBPM ) / 60;
|
||||
unsigned i;
|
||||
for( i=0; i<m_BPMSegments.size(); i++ )
|
||||
if( m_BPMSegments[i].m_fStartBeat >= fBeat )
|
||||
if( m_BPMSegments[i].m_iStartIndex >= iNoteRow )
|
||||
break;
|
||||
|
||||
if( i == m_BPMSegments.size() ||
|
||||
fabsf(m_BPMSegments[i].m_fStartBeat-fBeat) > 0.001f )
|
||||
if( i == m_BPMSegments.size() || m_BPMSegments[i].m_iStartIndex == iNoteRow )
|
||||
{
|
||||
// There is no BPMSegment at the specified beat. If the BPM being set differs
|
||||
// from the last BPMSegment's BPM, create a new BPMSegment.
|
||||
if( i == 0 || fabsf(m_BPMSegments[i-1].m_fBPM - fBPM) > 0.009f )
|
||||
AddBPMSegment( BPMSegment(fBeat, fBPM) );
|
||||
if( i == 0 || m_BPMSegments[i-1].m_iBPS != iBPS )
|
||||
AddBPMSegment( BPMSegment(iNoteRow, iBPS) );
|
||||
}
|
||||
else // BPMSegment being modified is m_BPMSegments[i]
|
||||
{
|
||||
if( i > 0 && fabsf(m_BPMSegments[i-1].m_fBPM - fBPM) < 0.009f )
|
||||
if( i > 0 && m_BPMSegments[i-1].m_iBPS == iBPS )
|
||||
m_BPMSegments.erase( m_BPMSegments.begin()+i,
|
||||
m_BPMSegments.begin()+i+1);
|
||||
else
|
||||
m_BPMSegments[i].m_fBPM = fBPM;
|
||||
m_BPMSegments[i].m_iBPS = iBPS;
|
||||
}
|
||||
}
|
||||
|
||||
void TimingData::SetStopAtBeat( float fBeat, float fSeconds )
|
||||
{
|
||||
int iRow = BeatToNoteRow( fBeat );
|
||||
unsigned i;
|
||||
for( i=0; i<m_StopSegments.size(); i++ )
|
||||
if( m_StopSegments[i].m_fStartBeat == fBeat )
|
||||
if( m_StopSegments[i].m_iStartRow == iRow )
|
||||
break;
|
||||
|
||||
if( i == m_StopSegments.size() ) // there is no BPMSegment at the current beat
|
||||
{
|
||||
// create a new StopSegment
|
||||
if( fSeconds > 0 )
|
||||
AddStopSegment( StopSegment(fBeat, fSeconds) );
|
||||
AddStopSegment( StopSegment(iRow, fSeconds) );
|
||||
}
|
||||
else // StopSegment being modified is m_StopSegments[i]
|
||||
{
|
||||
@@ -103,37 +118,60 @@ void TimingData::SetStopAtBeat( float fBeat, float fSeconds )
|
||||
}
|
||||
|
||||
/* Multiply the BPM in the range [fStartBeat,fEndBeat) by fFactor. */
|
||||
void TimingData::MultiplyBPMInBeatRange( float fStartBeat, float fEndBeat, float fFactor )
|
||||
void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor )
|
||||
{
|
||||
/* Record the BPM at fEndBeat, so we can make sure it doesn't change. */
|
||||
float fEndBPM = GetBPMAtBeat( fEndBeat );
|
||||
|
||||
/* Set the first beat. */
|
||||
SetBPMAtBeat( fStartBeat, GetBPMAtBeat(fStartBeat) * fFactor );
|
||||
|
||||
/* Change all other BPM segments in this range. */
|
||||
for( unsigned i=0; i<m_BPMSegments.size(); i++ )
|
||||
if( m_BPMSegments[i].m_fStartBeat > fStartBeat && m_BPMSegments[i].m_fStartBeat < fEndBeat )
|
||||
m_BPMSegments[i].m_fBPM *= fFactor;
|
||||
{
|
||||
const int iStartIndexThisSegment = m_BPMSegments[i].m_iStartIndex;
|
||||
const bool bIsLastBPMSegment = i==m_BPMSegments.size()-1;
|
||||
const int iStartIndexNextSegment = bIsLastBPMSegment ? 40000/*inf*/ : m_BPMSegments[i+1].m_iStartIndex;
|
||||
|
||||
/* Don't change the BPM at the end of the range. */
|
||||
SetBPMAtBeat( fEndBeat, fEndBPM );
|
||||
if( iStartIndexThisSegment <= iStartIndex && iStartIndexNextSegment <= iStartIndex )
|
||||
continue;
|
||||
|
||||
/* If this BPM segment crosses the beginning of the range, split it into two. */
|
||||
if( iStartIndexThisSegment < iStartIndex && iStartIndexNextSegment > iStartIndex )
|
||||
{
|
||||
BPMSegment b = m_BPMSegments[i];
|
||||
b.m_iStartIndex = iStartIndexNextSegment;
|
||||
m_BPMSegments.insert( m_BPMSegments.begin()+i+1, b );
|
||||
|
||||
/* Don't apply the BPM change to the first half of the segment we just split,
|
||||
* since it lies outside the range. */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If this BPM segment crosses the end of the range, split it into two. */
|
||||
if( iStartIndexThisSegment < iEndIndex && iStartIndexNextSegment > iEndIndex )
|
||||
{
|
||||
BPMSegment b = m_BPMSegments[i];
|
||||
b.m_iStartIndex = iEndIndex;
|
||||
m_BPMSegments.insert( m_BPMSegments.begin()+i+1, b );
|
||||
}
|
||||
else if( iStartIndexNextSegment > iEndIndex )
|
||||
continue;
|
||||
|
||||
m_BPMSegments[i].m_iBPS = lrintf( m_BPMSegments[i].m_iBPS * fFactor );
|
||||
}
|
||||
}
|
||||
|
||||
float TimingData::GetBPMAtBeat( float fBeat ) const
|
||||
{
|
||||
int iIndex = BeatToNoteRow( fBeat );
|
||||
unsigned i;
|
||||
for( i=0; i<m_BPMSegments.size()-1; i++ )
|
||||
if( m_BPMSegments[i+1].m_fStartBeat > fBeat )
|
||||
if( m_BPMSegments[i+1].m_iStartIndex > iIndex )
|
||||
break;
|
||||
return m_BPMSegments[i].m_fBPM;
|
||||
return m_BPMSegments[i].GetBPM();
|
||||
}
|
||||
|
||||
BPMSegment& TimingData::GetBPMSegmentAtBeat( float fBeat )
|
||||
{
|
||||
int iIndex = BeatToNoteRow( fBeat );
|
||||
unsigned i;
|
||||
for( i=0; i<m_BPMSegments.size()-1; i++ )
|
||||
if( m_BPMSegments[i+1].m_fStartBeat > fBeat )
|
||||
if( m_BPMSegments[i+1].m_iStartIndex > iIndex )
|
||||
break;
|
||||
return m_BPMSegments[i];
|
||||
}
|
||||
@@ -150,21 +188,25 @@ void TimingData::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatO
|
||||
|
||||
for( unsigned i=0; i<m_BPMSegments.size(); i++ ) // foreach BPMSegment
|
||||
{
|
||||
const float fStartBeatThisSegment = m_BPMSegments[i].m_fStartBeat;
|
||||
const int iStartRowThisSegment = m_BPMSegments[i].m_iStartIndex;
|
||||
const float fStartBeatThisSegment = NoteRowToBeat( iStartRowThisSegment );
|
||||
const bool bIsFirstBPMSegment = i==0;
|
||||
const bool bIsLastBPMSegment = i==m_BPMSegments.size()-1;
|
||||
const float fStartBeatNextSegment = bIsLastBPMSegment ? 40000/*inf*/ : m_BPMSegments[i+1].m_fStartBeat;
|
||||
const float fBPS = m_BPMSegments[i].m_fBPM / 60.0f;
|
||||
const int iStartRowNextSegment = bIsLastBPMSegment ? MAX_NOTE_ROW : m_BPMSegments[i+1].m_iStartIndex;
|
||||
const float fStartBeatNextSegment = NoteRowToBeat( iStartRowNextSegment );
|
||||
const int iBPS = m_BPMSegments[i].m_iBPS;
|
||||
const float fBPS = NoteRowToBeat( iBPS );
|
||||
|
||||
for( unsigned j=0; j<m_StopSegments.size(); j++ ) // foreach freeze
|
||||
{
|
||||
if( !bIsFirstBPMSegment && fStartBeatThisSegment >= m_StopSegments[j].m_fStartBeat )
|
||||
if( !bIsFirstBPMSegment && iStartRowThisSegment >= m_StopSegments[j].m_iStartRow )
|
||||
continue;
|
||||
if( !bIsLastBPMSegment && m_StopSegments[j].m_fStartBeat > fStartBeatNextSegment )
|
||||
if( !bIsLastBPMSegment && m_StopSegments[j].m_iStartRow > iStartRowNextSegment )
|
||||
continue;
|
||||
|
||||
// this freeze lies within this BPMSegment
|
||||
const float fBeatsSinceStartOfSegment = m_StopSegments[j].m_fStartBeat - fStartBeatThisSegment;
|
||||
const int iRowsBeatsSinceStartOfSegment = m_StopSegments[j].m_iStartRow - iStartRowThisSegment;
|
||||
const float fBeatsSinceStartOfSegment = NoteRowToBeat(iRowsBeatsSinceStartOfSegment);
|
||||
const float fFreezeStartSecond = fBeatsSinceStartOfSegment / fBPS;
|
||||
|
||||
if( fFreezeStartSecond >= fElapsedTime )
|
||||
@@ -176,7 +218,7 @@ void TimingData::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatO
|
||||
if( fFreezeStartSecond >= fElapsedTime )
|
||||
{
|
||||
/* The time lies within the stop. */
|
||||
fBeatOut = m_StopSegments[j].m_fStartBeat;
|
||||
fBeatOut = NoteRowToBeat(m_StopSegments[j].m_iStartRow);
|
||||
fBPSOut = fBPS;
|
||||
bFreezeOut = true;
|
||||
return;
|
||||
@@ -206,10 +248,11 @@ float TimingData::GetElapsedTimeFromBeat( float fBeat ) const
|
||||
fElapsedTime -= PREFSMAN->m_fGlobalOffsetSeconds;
|
||||
fElapsedTime -= m_fBeat0OffsetInSeconds;
|
||||
|
||||
int iRow = BeatToNoteRow(fBeat);
|
||||
for( unsigned j=0; j<m_StopSegments.size(); j++ ) // foreach freeze
|
||||
{
|
||||
/* The exact beat of a stop comes before the stop, not after, so use >=, not >. */
|
||||
if( m_StopSegments[j].m_fStartBeat >= fBeat )
|
||||
if( m_StopSegments[j].m_iStartRow >= iRow )
|
||||
break;
|
||||
fElapsedTime += m_StopSegments[j].m_fStopSeconds;
|
||||
}
|
||||
@@ -217,7 +260,7 @@ float TimingData::GetElapsedTimeFromBeat( float fBeat ) const
|
||||
for( unsigned i=0; i<m_BPMSegments.size(); i++ ) // foreach BPMSegment
|
||||
{
|
||||
const bool bIsLastBPMSegment = i==m_BPMSegments.size()-1;
|
||||
const float fBPS = m_BPMSegments[i].m_fBPM / 60.0f;
|
||||
const float fBPS = NoteRowToBeat( m_BPMSegments[i].m_iBPS );
|
||||
|
||||
if( bIsLastBPMSegment )
|
||||
{
|
||||
@@ -225,8 +268,10 @@ float TimingData::GetElapsedTimeFromBeat( float fBeat ) const
|
||||
}
|
||||
else
|
||||
{
|
||||
const float fStartBeatThisSegment = m_BPMSegments[i].m_fStartBeat;
|
||||
const float fStartBeatNextSegment = m_BPMSegments[i+1].m_fStartBeat;
|
||||
const int iStartIndexThisSegment = m_BPMSegments[i].m_iStartIndex;
|
||||
const float fStartBeatThisSegment = NoteRowToBeat( iStartIndexThisSegment );
|
||||
const int iStartIndexNextSegment = m_BPMSegments[i+1].m_iStartIndex;
|
||||
const float fStartBeatNextSegment = NoteRowToBeat( iStartIndexNextSegment );
|
||||
const float fBeatsInThisSegment = fStartBeatNextSegment - fStartBeatThisSegment;
|
||||
fElapsedTime += min(fBeat, fBeatsInThisSegment) / fBPS;
|
||||
fBeat -= fBeatsInThisSegment;
|
||||
@@ -239,58 +284,58 @@ float TimingData::GetElapsedTimeFromBeat( float fBeat ) const
|
||||
return fElapsedTime;
|
||||
}
|
||||
|
||||
void TimingData::ScaleRegion( float fScale, float fStartBeat, float fEndBeat )
|
||||
void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex )
|
||||
{
|
||||
ASSERT( fScale > 0 );
|
||||
ASSERT( fStartBeat >= 0 );
|
||||
ASSERT( fStartBeat < fEndBeat );
|
||||
ASSERT( iStartIndex >= 0 );
|
||||
ASSERT( iStartIndex < iEndIndex );
|
||||
|
||||
unsigned ix = 0;
|
||||
|
||||
for ( ix = 0; ix < m_BPMSegments.size(); ix++ )
|
||||
{
|
||||
const float fSegStart = m_BPMSegments[ix].m_fStartBeat;
|
||||
if( fSegStart < fStartBeat )
|
||||
const int iSegStart = m_BPMSegments[ix].m_iStartIndex;
|
||||
if( iSegStart < iStartIndex )
|
||||
continue;
|
||||
else if( fSegStart > fEndBeat )
|
||||
m_BPMSegments[ix].m_fStartBeat += (fEndBeat - fStartBeat) * (fScale - 1);
|
||||
else if( iSegStart > iEndIndex )
|
||||
m_BPMSegments[ix].m_iStartIndex += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) );
|
||||
else
|
||||
m_BPMSegments[ix].m_fStartBeat = (fSegStart - fStartBeat) * fScale + fStartBeat;
|
||||
m_BPMSegments[ix].m_iStartIndex = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex;
|
||||
}
|
||||
|
||||
for( ix = 0; ix < m_StopSegments.size(); ix++ )
|
||||
{
|
||||
const float fSegStart = m_StopSegments[ix].m_fStartBeat;
|
||||
if( fSegStart < fStartBeat )
|
||||
const int iSegStartRow = m_StopSegments[ix].m_iStartRow;
|
||||
if( iSegStartRow < iStartIndex )
|
||||
continue;
|
||||
else if( fSegStart > fEndBeat )
|
||||
m_StopSegments[ix].m_fStartBeat += (fEndBeat - fStartBeat) * (fScale - 1);
|
||||
else if( iSegStartRow > iEndIndex )
|
||||
m_StopSegments[ix].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1));
|
||||
else
|
||||
m_StopSegments[ix].m_fStartBeat = (fSegStart - fStartBeat) * fScale + fStartBeat;
|
||||
m_StopSegments[ix].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex;
|
||||
}
|
||||
}
|
||||
|
||||
void TimingData::ShiftRows( float fStartBeat, float fBeatsToShift )
|
||||
void TimingData::ShiftRows( int iStartRow, int iRowsToShift )
|
||||
{
|
||||
unsigned ix = 0;
|
||||
|
||||
for( ix = 0; ix < m_BPMSegments.size(); ix++ )
|
||||
{
|
||||
float &fSegStart = m_BPMSegments[ix].m_fStartBeat;
|
||||
if( fSegStart < fStartBeat )
|
||||
int &iSegStart = m_BPMSegments[ix].m_iStartIndex;
|
||||
if( iSegStart < iStartRow )
|
||||
continue;
|
||||
|
||||
fSegStart += fBeatsToShift;
|
||||
fSegStart = max( fSegStart, fStartBeat );
|
||||
iSegStart += iRowsToShift;
|
||||
iSegStart = max( iSegStart, iStartRow );
|
||||
}
|
||||
|
||||
for( ix = 0; ix < m_StopSegments.size(); ix++ )
|
||||
{
|
||||
float &fSegStart = m_StopSegments[ix].m_fStartBeat;
|
||||
if( fSegStart < fStartBeat )
|
||||
int &iSegStartRow = m_StopSegments[ix].m_iStartRow;
|
||||
if( iSegStartRow < iStartRow )
|
||||
continue;
|
||||
fSegStart += fBeatsToShift;
|
||||
fSegStart = max( fSegStart, fStartBeat );
|
||||
iSegStartRow += iRowsToShift;
|
||||
iSegStartRow = max( iSegStartRow, iStartRow );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-10
@@ -3,19 +3,24 @@
|
||||
#ifndef TIMING_DATA_H
|
||||
#define TIMING_DATA_H
|
||||
|
||||
#include "NoteTypes.h"
|
||||
|
||||
struct BPMSegment
|
||||
{
|
||||
BPMSegment() { m_fStartBeat = m_fBPM = -1; };
|
||||
BPMSegment( float s, float b ) { m_fStartBeat = s; m_fBPM = b; };
|
||||
float m_fStartBeat;
|
||||
float m_fBPM;
|
||||
BPMSegment() { m_iStartIndex = -1; m_iBPS = -1; }
|
||||
BPMSegment( int s, int b ) { m_iStartIndex = s; m_iBPS = b; }
|
||||
int m_iStartIndex;
|
||||
int m_iBPS; /* rows per second */
|
||||
|
||||
void SetBPM( float f );
|
||||
float GetBPM() const;
|
||||
};
|
||||
|
||||
struct StopSegment
|
||||
{
|
||||
StopSegment() { m_fStartBeat = m_fStopSeconds = -1; };
|
||||
StopSegment( float s, float f ) { m_fStartBeat = s; m_fStopSeconds = f; };
|
||||
float m_fStartBeat;
|
||||
StopSegment() { m_fStopSeconds = -1; m_iStartRow = -1; }
|
||||
StopSegment( int s, float f ) { m_iStartRow = s; m_fStopSeconds = f; }
|
||||
int m_iStartRow;
|
||||
float m_fStopSeconds;
|
||||
};
|
||||
|
||||
@@ -28,7 +33,7 @@ public:
|
||||
float GetBPMAtBeat( float fBeat ) const;
|
||||
void SetBPMAtBeat( float fBeat, float fBPM );
|
||||
void SetStopAtBeat( float fBeat, float fSeconds );
|
||||
void MultiplyBPMInBeatRange( float fStartBeat, float fEndBeat, float fFactor );
|
||||
void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor );
|
||||
void AddBPMSegment( const BPMSegment &seg );
|
||||
void AddStopSegment( const StopSegment &seg );
|
||||
BPMSegment& GetBPMSegmentAtBeat( float fBeat );
|
||||
@@ -54,8 +59,8 @@ public:
|
||||
// of the range that was deleted (say if rows 1680-1728 are deleted, and
|
||||
// a BPM change or a stop occurs at row 1704, we'll move it to row
|
||||
// 1680).
|
||||
void ScaleRegion( float fScale = 1, float fStartBeat = 0, float fEndBeat = 99999 );
|
||||
void ShiftRows( float fStartBeat, float fBeatsToShift );
|
||||
void ScaleRegion( float fScale = 1, int iStartRow = 0, int iEndRow = MAX_NOTE_ROW );
|
||||
void ShiftRows( int iStartRow, int iRowsToShift );
|
||||
|
||||
CString m_sFile; // informational only
|
||||
vector<BPMSegment> m_BPMSegments; // this must be sorted before gameplay
|
||||
|
||||
Reference in New Issue
Block a user