[warps] allow stops inside warps and convert high bpm to warps

+ sometimes there are delays/stops in high BPM sections,
  they have to be handled inside a warp to be able to convert
  it easily.
+ on the stopped / delayed rows with warps, judging become
  enabled for that row.

Issues:

+ the bpm threshould is hardcoded (right now it's 400000.0).
  someone change it please.
+ slight off-sync from conversion. haven't figured out how to
  work around it yet.
This commit is contained in:
Thai Pangsakulyanont
2011-03-26 22:07:24 +07:00
parent bfd7e9c914
commit ac336215bd
4 changed files with 73 additions and 60 deletions
-15
View File
@@ -961,21 +961,6 @@ void GameState::UpdateSongPosition( float fPositionSeconds, const TimingData &ti
// "Crash reason : -243478.890625 -48695.773438"
ASSERT_M( m_fSongBeat > -2000, ssprintf("Song beat %f at %f seconds", m_fSongBeat, fPositionSeconds) );
//if( m_iWarpBeginRow != -1 || m_iWarpEndRow == -1 )
/*
if( m_iWarpBeginRow != -1 && m_fWarpDestination > 0.0f )
{
float fWarpLength = m_fWarpDestination-NoteRowToBeat(m_iWarpBeginRow);
// There is a warp in this section.
LOG->Trace("warp at row %i lasts for %f beats, jumps to row %i",
m_iWarpBeginRow,
fWarpLength,
BeatToNoteRow(m_fWarpDestination));
fPositionSeconds += (fWarpLength * m_fCurBPS);
}
*/
m_fMusicSeconds = fPositionSeconds;
m_fLightSongBeat = timing.GetBeatFromElapsedTime( fPositionSeconds + g_fLightsAheadSeconds );
+22 -4
View File
@@ -122,6 +122,7 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
// prepare storage variables for negative BPMs -> Warps.
float negBeat = -1;
float negBPM = 1;
float highspeedBeat = -1;
for( unsigned b=0; b<arrayBPMChangeExpressions.size(); b++ )
{
@@ -157,11 +158,28 @@ void SMLoader::LoadTimingFromSMFile( const MsdFile &msd, TimingData &out )
negBeat = -1;
negBPM = 1;
}
// too fast. make it a warp.
if( fNewBPM > 400000.0 )
{
BPMSegment new_seg;
new_seg.m_iStartRow = BeatToNoteRow(fBeat);
new_seg.SetBPM( fNewBPM );
out.AddBPMSegment( new_seg );
highspeedBeat = fBeat;
}
else
{
// add in a warp.
if( highspeedBeat > 0 )
{
WarpSegment new_seg;
new_seg.m_iStartRow = BeatToNoteRow(highspeedBeat);
new_seg.m_fEndBeat = fBeat;
out.AddWarpSegment( new_seg );
highspeedBeat = -1;
}
{
BPMSegment new_seg;
new_seg.m_iStartRow = BeatToNoteRow(fBeat);
new_seg.SetBPM( fNewBPM );
out.AddBPMSegment( new_seg );
}
}
}
}
+3 -5
View File
@@ -2561,7 +2561,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds )
continue;
// Ignore all notes that are skipped via WARPS.
if( iter.Row() >= GAMESTATE->m_iWarpBeginRow && iter.Row() < BeatToNoteRow(GAMESTATE->m_fWarpDestination) )
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iter.Row() ) )
continue;
if( tn.type == TapNote::mine )
@@ -2931,8 +2931,7 @@ void Player::HandleTapRowScore( unsigned row )
#endif
// more warp hackery. -aj
if( row >= (unsigned)GAMESTATE->m_iWarpBeginRow &&
row < (unsigned)(BeatToNoteRow(GAMESTATE->m_fWarpDestination)) )
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( row ) )
return;
if( GAMESTATE->m_bDemonstrationOrJukebox )
@@ -3036,8 +3035,7 @@ void Player::HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumH
#endif
// more warp hackery. -aj
if( iRow >= GAMESTATE->m_iWarpBeginRow &&
iRow < BeatToNoteRow(GAMESTATE->m_fWarpDestination) )
if( GAMESTATE->m_pCurSong->m_Timing.IsWarpAtRow( iRow ) )
return;
// don't accumulate combo if AutoPlay is on.
+48 -36
View File
@@ -348,7 +348,19 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const
int i = GetWarpSegmentIndexAtRow( iNoteRow );
const WarpSegment& s = m_WarpSegments[i];
return s.m_iStartRow <= iNoteRow && iNoteRow < BeatToNoteRow(s.m_fEndBeat);
if( s.m_iStartRow <= iNoteRow && iNoteRow < BeatToNoteRow(s.m_fEndBeat) )
{
if( m_StopSegments.empty() )
{
return true;
}
if( GetStopAtRow(iNoteRow) != 0.0f )
{
return false;
}
return true;
}
return false;
}
int TimingData::GetTimeSignatureSegmentIndexAtRow( int iRow ) const
@@ -499,11 +511,6 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
iEventRow = BeatToNoteRow(fWarpDestination);
iEventType = FOUND_WARP_DESTINATION;
}
if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow )
{
iEventRow = itWS->m_iStartRow;
iEventType = FOUND_WARP;
}
if( itBPMS != m_BPMSegments.end() && itBPMS->m_iStartRow < iEventRow )
{
iEventRow = itBPMS->m_iStartRow;
@@ -514,6 +521,11 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
iEventRow = itSS->m_iStartRow;
iEventType = FOUND_STOP;
}
if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow )
{
iEventRow = itWS->m_iStartRow;
iEventType = FOUND_WARP;
}
if( iEventType == NOT_FOUND )
{
break;
@@ -530,22 +542,12 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
case FOUND_WARP_DESTINATION:
bIsWarping = false;
break;
case FOUND_WARP:
bIsWarping = true;
if( itWS->m_fEndBeat > fWarpDestination )
{
fWarpDestination = itWS->m_fEndBeat;
}
iWarpBeginOut = iEventRow;
fWarpDestinationOut = fWarpDestination;
itWS ++;
break;
case FOUND_BPM_CHANGE:
fBPS = itBPMS->m_fBPS;
itBPMS ++;
break;
case FOUND_STOP: // TODO: update for Delays.
fTimeToNextEvent = bIsWarping ? 0 : itSS->m_fStopSeconds;
fTimeToNextEvent = itSS->m_fStopSeconds;
fNextEventTime = fLastTime + fTimeToNextEvent;
const bool bIsDelay = itSS->m_bDelay;
if ( fElapsedTime < fNextEventTime )
@@ -559,6 +561,16 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
fLastTime = fNextEventTime;
itSS ++;
break;
case FOUND_WARP:
bIsWarping = true;
if( itWS->m_fEndBeat > fWarpDestination )
{
fWarpDestination = itWS->m_fEndBeat;
}
iWarpBeginOut = iEventRow;
fWarpDestinationOut = fWarpDestination;
itWS ++;
break;
}
iLastRow = iEventRow;
}
@@ -599,17 +611,12 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const
iEventRow = BeatToNoteRow(fWarpDestination);
iEventType = FOUND_WARP_DESTINATION;
}
if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow )
{
iEventRow = itWS->m_iStartRow;
iEventType = FOUND_WARP;
}
if( itBPMS != m_BPMSegments.end() && itBPMS->m_iStartRow < iEventRow )
{
iEventRow = itBPMS->m_iStartRow;
iEventType = FOUND_BPM_CHANGE;
}
if( itSS != m_StopSegments.end() && itSS->m_bDelay && itSS->m_iStartRow < iEventRow )
if( itSS != m_StopSegments.end() && itSS->m_bDelay && itSS->m_iStartRow < iEventRow ) // delays (come before marker)
{
iEventRow = itSS->m_iStartRow;
iEventType = FOUND_STOP;
@@ -619,11 +626,16 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const
iEventRow = BeatToNoteRow(fBeat);
iEventType = FOUND_MARKER;
}
if( itSS != m_StopSegments.end() && !itSS->m_bDelay && itSS->m_iStartRow < iEventRow )
if( itSS != m_StopSegments.end() && !itSS->m_bDelay && itSS->m_iStartRow < iEventRow ) // stops (come after marker)
{
iEventRow = itSS->m_iStartRow;
iEventType = FOUND_STOP;
}
if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow )
{
iEventRow = itWS->m_iStartRow;
iEventType = FOUND_WARP;
}
float fTimeToNextEvent = bIsWarping ? 0 : NoteRowToBeat( iEventRow - iLastRow ) / fBPS;
float fNextEventTime = fLastTime + fTimeToNextEvent;
fLastTime = fNextEventTime;
@@ -632,6 +644,18 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const
case FOUND_WARP_DESTINATION:
bIsWarping = false;
break;
case FOUND_BPM_CHANGE:
fBPS = itBPMS->m_fBPS;
itBPMS ++;
break;
case FOUND_STOP:
fTimeToNextEvent = itSS->m_fStopSeconds;
fNextEventTime = fLastTime + fTimeToNextEvent;
fLastTime = fNextEventTime;
itSS ++;
break;
case FOUND_MARKER:
return fLastTime;
case FOUND_WARP:
bIsWarping = true;
if( itWS->m_fEndBeat > fWarpDestination )
@@ -640,18 +664,6 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const
}
itWS ++;
break;
case FOUND_BPM_CHANGE:
fBPS = itBPMS->m_fBPS;
itBPMS ++;
break;
case FOUND_STOP:
fTimeToNextEvent = bIsWarping ? 0 : itSS->m_fStopSeconds;
fNextEventTime = fLastTime + fTimeToNextEvent;
fLastTime = fNextEventTime;
itSS ++;
break;
case FOUND_MARKER:
return fLastTime;
}
iLastRow = iEventRow;
}