Mission accomplished: #COMBOS tag in sm-ssc.
This tag will not show up on saved SM files. Let's not mess with that format any more than needed.
This commit is contained in:
@@ -9,6 +9,9 @@ change to JSON, but it is unsure if this will be done.
|
||||
Implement .ssc at your own risk.
|
||||
________________________________________________________________________________
|
||||
|
||||
[v0.55] - Wolfman2000
|
||||
* Add #COMBOS tag to the Song and Steps (does nothing here).
|
||||
|
||||
[v0.54] - Wolfman2000
|
||||
* Add #ATTACKS tag to the Notedata sections. Right now it does nothing.
|
||||
|
||||
|
||||
@@ -13,6 +13,10 @@ _____________________________________________________________________________
|
||||
sm-ssc v1.2.3 | 201103??
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
20110305
|
||||
--------
|
||||
* Added #COMBOS tag to the .ssc format. [Wolfman2000]
|
||||
|
||||
20110302
|
||||
--------
|
||||
* [ScreenGameplaySyncMachine] Allow themers to use either .ssc or .sm files. [AJ]
|
||||
|
||||
@@ -842,6 +842,7 @@ Edit time signature=Edit time signature (not working yet)
|
||||
Edit time signature (top)=Edit time signature (beats per measure)
|
||||
Edit time signature (bottom)=Edit time signature (single beat note value)
|
||||
Edit tickcount=Edit tickcount
|
||||
Edit combo=Edit combo
|
||||
Editor options=Options
|
||||
EditorShowBGChangesPlay=Show Backgrounds
|
||||
Effect=Effect
|
||||
@@ -1207,6 +1208,7 @@ Enter a new Delay value.=Enter a new Delay value.
|
||||
Enter a new Time Signature numerator value.=Enter the number of beats per measure.
|
||||
Enter a new Time Signature denominator value.=Enter the note value that represents one beat.
|
||||
Enter a new Tickcount value.=Enter a new Tickcount value.
|
||||
Enter a new Combo value.=Enter a new Combo value.
|
||||
Enter a new artist transliteration.=Enter a new artist transliteration.
|
||||
Enter a new artist.=Enter a new artist.
|
||||
Enter a new genre.=Enter a new genre.
|
||||
|
||||
@@ -956,18 +956,21 @@ StopColor=color("0.8,0.8,0,1")
|
||||
DelayColor=color("0,0.8,0.8,1")
|
||||
TimeSignatureColor=color("1,0.55,0,1")
|
||||
TickcountColor=color("0,1,0,1")
|
||||
ComboColor=color("0.55,1,0,1")
|
||||
#
|
||||
BPMIsLeftSide=true
|
||||
StopIsLeftSide=true
|
||||
DelayIsLeftSide=true
|
||||
TimeSignatureIsLeftSide=true
|
||||
TickcountIsLeftSide=false
|
||||
ComboIsLeftSide=false
|
||||
#
|
||||
BPMOffsetX=60
|
||||
StopOffsetX=10
|
||||
DelayOffsetX=10
|
||||
TimeSignatureOffsetX=30
|
||||
TickcountOffsetX=10
|
||||
ComboOffsetX=30
|
||||
|
||||
[PlayerStageStats]
|
||||
# Original CVS Grading
|
||||
|
||||
@@ -424,16 +424,19 @@ static ThemeMetric<RageColor> STOP_COLOR ( "NoteField", "StopColor" );
|
||||
static ThemeMetric<RageColor> DELAY_COLOR ( "NoteField", "DelayColor" );
|
||||
static ThemeMetric<RageColor> TIME_SIGNATURE_COLOR ( "NoteField", "TimeSignatureColor" );
|
||||
static ThemeMetric<RageColor> TICKCOUNT_COLOR ( "NoteField", "TickcountColor" );
|
||||
static ThemeMetric<RageColor> COMBO_COLOR ( "NoteField", "ComboColor" );
|
||||
static ThemeMetric<bool> BPM_IS_LEFT_SIDE ( "NoteField", "BPMIsLeftSide" );
|
||||
static ThemeMetric<bool> STOP_IS_LEFT_SIDE ( "NoteField", "StopIsLeftSide" );
|
||||
static ThemeMetric<bool> DELAY_IS_LEFT_SIDE ( "NoteField", "DelayIsLeftSide" );
|
||||
static ThemeMetric<bool> TIME_SIGNATURE_IS_LEFT_SIDE ( "NoteField", "TimeSignatureIsLeftSide" );
|
||||
static ThemeMetric<bool> TICKCOUNT_IS_LEFT_SIDE ( "NoteField", "TickcountIsLeftSide" );
|
||||
static ThemeMetric<bool> COMBO_IS_LEFT_SIDE ( "NoteField", "ComboIsLeftSide" );
|
||||
static ThemeMetric<float> BPM_OFFSETX ( "NoteField", "BPMOffsetX" );
|
||||
static ThemeMetric<float> STOP_OFFSETX ( "NoteField", "StopOffsetX" );
|
||||
static ThemeMetric<float> DELAY_OFFSETX ( "NoteField", "DelayOffsetX" );
|
||||
static ThemeMetric<float> TIME_SIGNATURE_OFFSETX ( "NoteField", "TimeSignatureOffsetX" );
|
||||
static ThemeMetric<float> TICKCOUNT_OFFSETX ( "NoteField", "TickcountOffsetX" );
|
||||
static ThemeMetric<float> COMBO_OFFSETX ( "NoteField", "ComboOffsetX" );
|
||||
|
||||
void NoteField::DrawBPMText( const float fBeat, const float fBPM )
|
||||
{
|
||||
@@ -512,6 +515,23 @@ void NoteField::DrawTickcountText( const float fBeat, int iTicks )
|
||||
m_textMeasureNumber.Draw();
|
||||
}
|
||||
|
||||
void NoteField::DrawComboText( const float fBeat, int iCombo )
|
||||
{
|
||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
|
||||
const float fYPos = ArrowEffects::GetYPos( m_pPlayerState, 0, fYOffset, m_fYReverseOffsetPixels );
|
||||
const float fZoom = ArrowEffects::GetZoom( m_pPlayerState );
|
||||
const float xBase = GetWidth()/2.f;
|
||||
const float xOffset = COMBO_OFFSETX * fZoom;
|
||||
|
||||
m_textMeasureNumber.SetZoom( fZoom );
|
||||
m_textMeasureNumber.SetHorizAlign( COMBO_IS_LEFT_SIDE ? align_right : align_left );
|
||||
m_textMeasureNumber.SetDiffuse( COMBO_COLOR );
|
||||
m_textMeasureNumber.SetGlow( RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f) );
|
||||
m_textMeasureNumber.SetText( ssprintf("%d", iCombo) );
|
||||
m_textMeasureNumber.SetXY( (COMBO_IS_LEFT_SIDE ? -xBase - xOffset : xBase + xOffset), fYPos );
|
||||
m_textMeasureNumber.Draw();
|
||||
}
|
||||
|
||||
void NoteField::DrawAttackText( const float fBeat, const Attack &attack )
|
||||
{
|
||||
const float fYOffset = ArrowEffects::GetYOffset( m_pPlayerState, 0, fBeat );
|
||||
@@ -776,6 +796,19 @@ void NoteField::DrawPrimitives()
|
||||
DrawTickcountText( fBeat, tTickcountSegments[i].m_iTicks );
|
||||
}
|
||||
}
|
||||
|
||||
// Combo text
|
||||
const vector<ComboSegment> &tComboSegments = GAMESTATE->m_pCurSong->m_Timing.m_ComboSegments;
|
||||
for( unsigned i=0; i<tComboSegments.size(); i++ )
|
||||
{
|
||||
if( tComboSegments[i].m_iStartRow >= iFirstRowToDraw &&
|
||||
tComboSegments[i].m_iStartRow <= iLastRowToDraw)
|
||||
{
|
||||
float fBeat = NoteRowToBeat(tComboSegments[i].m_iStartRow);
|
||||
if( IS_ON_SCREEN(fBeat) )
|
||||
DrawComboText( fBeat, tComboSegments[i].m_iCombo );
|
||||
}
|
||||
}
|
||||
|
||||
// todo: add warp text -aj
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ protected:
|
||||
void DrawFreezeText( const float fBeat, const float fBPM, const float bDelay );
|
||||
void DrawTimeSignatureText( const float fBeat, int iNumerator, int iDenominator );
|
||||
void DrawTickcountText( const float fBeat, int iTicks );
|
||||
void DrawComboText( const float fBeat, int iCombo );
|
||||
void DrawAttackText( const float fBeat, const Attack &attack );
|
||||
void DrawBGChangeText( const float fBeat, const RString sNewBGName );
|
||||
float GetWidth() const;
|
||||
|
||||
@@ -565,7 +565,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
}
|
||||
|
||||
else if( sValueName=="COMBOS" )
|
||||
{/*
|
||||
{
|
||||
vector<RString> arrayComboExpressions;
|
||||
split( sParams[1], ",", arrayComboExpressions );
|
||||
|
||||
@@ -584,7 +584,6 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach
|
||||
ComboSegment new_seg( BeatToNoteRow( fComboBeat ), iCombos );
|
||||
out.m_Timing.AddComboSegment( new_seg );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/* The following are cache tags. Never fill their values
|
||||
|
||||
@@ -181,19 +181,19 @@ static void WriteGlobalTags( RageFile &f, const Song &out )
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
|
||||
/*
|
||||
|
||||
ASSERT( !out.m_Timing.m_ComboSegments.empty() );
|
||||
f.Write( "#COMBOS:" );
|
||||
for( unsigned i=0; i<out.m_Timing.m_ComboSegments.size(); i++ )
|
||||
{
|
||||
const ComboSegment &cs = out.m_Timing.m_ComboSegments[i];
|
||||
|
||||
f.PutLine( ssprintf( "%.6f=%d", NoteRowToBeat(cs.m_iStartRow), cs.m_iComboFactor ) );
|
||||
f.PutLine( ssprintf( "%.6f=%d", NoteRowToBeat(cs.m_iStartRow), cs.m_iCombo ) );
|
||||
if( i != out.m_Timing.m_ComboSegments.size()-1 )
|
||||
f.Write( "," );
|
||||
}
|
||||
f.PutLine( ";" );
|
||||
*/
|
||||
|
||||
FOREACH_BackgroundLayer( b )
|
||||
{
|
||||
if( b==0 )
|
||||
@@ -302,7 +302,7 @@ static RString GetSSCNoteData( const Song &song, const Steps &in, bool bSavingCa
|
||||
lines.push_back( "#TIMESIGNATURES:;" );
|
||||
lines.push_back( "#TICKCOUNTS:;" );
|
||||
lines.push_back( "#ATTACKS:;" );
|
||||
// lines.push_back( "#COMBOS:;" );
|
||||
lines.push_back( "#COMBOS:;" );
|
||||
|
||||
/*
|
||||
vector<RString> asBPMValues;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "Game.h"
|
||||
#include "Style.h"
|
||||
#include "Song.h"
|
||||
#include "TimingData.h"
|
||||
#include "NoteDataWithScoring.h"
|
||||
|
||||
|
||||
@@ -577,7 +578,7 @@ void ScoreKeeperNormal::HandleHoldCheckpointScore( const NoteData &nd, int iRow,
|
||||
}
|
||||
|
||||
HandleTapNoteScoreInternal( iNumHoldsMissedThisRow == 0? TNS_CheckpointHit:TNS_CheckpointMiss, TNS_CheckpointHit );
|
||||
HandleComboInternal( iNumHoldsHeldThisRow, 0, iNumHoldsMissedThisRow );
|
||||
HandleComboInternal( iNumHoldsHeldThisRow, 0, iNumHoldsMissedThisRow, iRow );
|
||||
}
|
||||
|
||||
void ScoreKeeperNormal::HandleTapNoteScoreInternal( TapNoteScore tns, TapNoteScore maximum )
|
||||
@@ -593,7 +594,7 @@ void ScoreKeeperNormal::HandleTapNoteScoreInternal( TapNoteScore tns, TapNoteSco
|
||||
m_pPlayerStageStats->m_iCurPossibleDancePoints += TapNoteScoreToDancePoints( maximum );
|
||||
}
|
||||
|
||||
void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumHitMaintainCombo, int iNumBreakCombo )
|
||||
void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumHitMaintainCombo, int iNumBreakCombo, int iRow )
|
||||
{
|
||||
// Regular combo
|
||||
if( m_ComboIsPerRow )
|
||||
@@ -610,7 +611,9 @@ void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumH
|
||||
|
||||
if( iNumBreakCombo == 0 )
|
||||
{
|
||||
m_pPlayerStageStats->m_iCurCombo += iNumHitContinueCombo;
|
||||
TimingData td = GAMESTATE->m_pCurSong->m_Timing;
|
||||
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo );
|
||||
m_pPlayerStageStats->m_iCurCombo += iNumHitContinueCombo * multiplier;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -619,7 +622,7 @@ void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumH
|
||||
}
|
||||
}
|
||||
|
||||
void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsInRow )
|
||||
void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsInRow, int iRow )
|
||||
{
|
||||
if( m_ComboIsPerRow )
|
||||
{
|
||||
@@ -628,7 +631,9 @@ void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsIn
|
||||
if ( tns >= m_MinScoreToContinueCombo )
|
||||
{
|
||||
m_pPlayerStageStats->m_iCurMissCombo = 0;
|
||||
m_pPlayerStageStats->m_iCurCombo += iNumTapsInRow;
|
||||
TimingData td = GAMESTATE->m_pCurSong->m_Timing;
|
||||
int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo );
|
||||
m_pPlayerStageStats->m_iCurCombo += iNumTapsInRow * multiplier;
|
||||
}
|
||||
else if ( tns < m_MinScoreToMaintainCombo )
|
||||
{
|
||||
@@ -673,14 +678,14 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow )
|
||||
|
||||
TapNoteScore scoreOfLastTap = NoteDataWithScoring::LastTapNoteWithResult( nd, iRow ).result.tns;
|
||||
HandleTapNoteScoreInternal( scoreOfLastTap, TNS_W1 );
|
||||
|
||||
|
||||
if ( GAMESTATE->GetCurrentGame()->m_bCountNotesSeparately )
|
||||
{
|
||||
HandleComboInternal( iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo );
|
||||
HandleComboInternal( iNumHitContinueCombo, iNumHitMaintainCombo, iNumBreakCombo, iRow );
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleRowComboInternal( scoreOfLastTap, iNumTapsInRow ); //This should work?
|
||||
HandleRowComboInternal( scoreOfLastTap, iNumTapsInRow, iRow ); //This should work?
|
||||
}
|
||||
|
||||
if( m_pPlayerState->m_PlayerNumber != PLAYER_INVALID )
|
||||
|
||||
@@ -114,8 +114,8 @@ public:
|
||||
|
||||
private:
|
||||
void HandleTapNoteScoreInternal( TapNoteScore tns, TapNoteScore maximum );
|
||||
void HandleComboInternal( int iNumHitContinueCombo, int iNumHitMaintainCombo, int iNumBreakCombo );
|
||||
void HandleRowComboInternal( TapNoteScore tns, int iNumTapsInRow );
|
||||
void HandleComboInternal( int iNumHitContinueCombo, int iNumHitMaintainCombo, int iNumBreakCombo, int iRow = -1 );
|
||||
void HandleRowComboInternal( TapNoteScore tns, int iNumTapsInRow, int iRow = -1 );
|
||||
void GetRowCounts( const NoteData &nd, int iRow, int &iNumHitContinueCombo, int &iNumHitMaintainCombo, int &iNumBreakCombo );
|
||||
|
||||
};
|
||||
|
||||
+22
-1
@@ -78,6 +78,7 @@ AutoScreenMessage( SM_BackFromDelayChange );
|
||||
AutoScreenMessage( SM_BackFromTimeSignatureNumeratorChange );
|
||||
AutoScreenMessage( SM_BackFromTimeSignatureDenominatorChange );
|
||||
AutoScreenMessage( SM_BackFromTickcountChange );
|
||||
AutoScreenMessage( SM_BackFromComboChange );
|
||||
AutoScreenMessage( SM_DoSaveAndExit );
|
||||
AutoScreenMessage( SM_DoExit );
|
||||
AutoScreenMessage( SM_SaveSuccessful );
|
||||
@@ -578,7 +579,8 @@ static MenuDef g_TimingDataInformation(
|
||||
MenuRowDef( ScreenEdit::delay, "Edit delay", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::time_signature_numerator, "Edit time signature (top)", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::time_signature_denominator, "Edit time signature (bottom)", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL )
|
||||
MenuRowDef( ScreenEdit::tickcount, "Edit tickcount", true, EditMode_Full, true, true, 0, NULL ),
|
||||
MenuRowDef( ScreenEdit::combo, "Edit combo", true, EditMode_Full, true, true, 0, NULL )
|
||||
);
|
||||
|
||||
enum { song_bganimation, song_movie, song_bitmap, global_bganimation, global_movie, global_movie_song_group, global_movie_song_group_and_genre, dynamic_random, baked_random, none };
|
||||
@@ -2651,6 +2653,15 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM )
|
||||
}
|
||||
SetDirty( true );
|
||||
}
|
||||
else if ( SM == SM_BackFromComboChange )
|
||||
{
|
||||
int iCombo = atoi( ScreenTextEntry::s_sLastAnswer );
|
||||
if ( iCombo >= 0 )
|
||||
{
|
||||
m_pSong->m_Timing.SetComboAtBeat( GAMESTATE->m_fSongBeat, iCombo );
|
||||
}
|
||||
SetDirty( true );
|
||||
}
|
||||
else if( SM == SM_BackFromBGChange )
|
||||
{
|
||||
HandleBGChangeChoice( (BGChangeChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers );
|
||||
@@ -3169,6 +3180,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector<int> &iAns
|
||||
g_TimingDataInformation.rows[time_signature_numerator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureNumeratorAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[time_signature_denominator].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTimeSignatureDenominatorAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtBeat( fBeat ) ) );
|
||||
g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d", pTime.GetComboAtBeat( fBeat ) ) );
|
||||
|
||||
EditMiniMenu( &g_TimingDataInformation, SM_BackFromTimingDataInformation );
|
||||
}
|
||||
@@ -3620,6 +3632,7 @@ static LocalizedString ENTER_DELAY_VALUE ( "ScreenEdit", "Enter a new Delay va
|
||||
static LocalizedString ENTER_TIME_SIGNATURE_NUMERATOR_VALUE ( "ScreenEdit", "Enter a new Time Signature numerator value." );
|
||||
static LocalizedString ENTER_TIME_SIGNATURE_DENOMINATOR_VALUE ( "ScreenEdit", "Enter a new Time Signature denominator value." );
|
||||
static LocalizedString ENTER_TICKCOUNT_VALUE ( "ScreenEdit", "Enter a new Tickcount value." );
|
||||
static LocalizedString ENTER_COMBO_VALUE ( "ScreenEdit", "Enter a new Combo value." );
|
||||
void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector<int> &iAnswers )
|
||||
{
|
||||
switch( c )
|
||||
@@ -3676,6 +3689,14 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
|
||||
2
|
||||
);
|
||||
break;
|
||||
case combo:
|
||||
ScreenTextEntry::TextEntry(
|
||||
SM_BackFromComboChange,
|
||||
ENTER_COMBO_VALUE,
|
||||
ssprintf( "%d", m_pSong->m_Timing.GetComboAtBeat( GAMESTATE->m_fSongBeat ) ),
|
||||
4
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -448,6 +448,7 @@ public:
|
||||
time_signature_numerator,
|
||||
time_signature_denominator,
|
||||
tickcount,
|
||||
combo,
|
||||
NUM_TIMING_DATA_INFORMATION_CHOICES
|
||||
};
|
||||
|
||||
|
||||
+10
-1
@@ -41,7 +41,7 @@
|
||||
* @brief The internal version of the cache for StepMania.
|
||||
*
|
||||
* Increment this value to invalidate the current cache. */
|
||||
const int FILE_CACHE_VERSION = 165;
|
||||
const int FILE_CACHE_VERSION = 166;
|
||||
|
||||
/** @brief How long does a song sample last by default? */
|
||||
const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f;
|
||||
@@ -782,6 +782,15 @@ void Song::TidyUpData()
|
||||
seg.m_iTicks = 2;
|
||||
m_Timing.m_TickcountSegments.push_back( seg );
|
||||
}
|
||||
|
||||
// Have a default combo segment of one just in case.
|
||||
if( m_Timing.m_ComboSegments.empty() )
|
||||
{
|
||||
ComboSegment seg;
|
||||
seg.m_iStartRow = 0;
|
||||
seg.m_iCombo = 1;
|
||||
m_Timing.m_ComboSegments.push_back( seg );
|
||||
}
|
||||
}
|
||||
|
||||
void Song::TranslateTitles()
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ struct lua_State;
|
||||
struct BackgroundChange;
|
||||
|
||||
/** @brief The version of the .ssc file format. */
|
||||
const static float STEPFILE_VERSION_NUMBER = 0.54f;
|
||||
const static float STEPFILE_VERSION_NUMBER = 0.55f;
|
||||
|
||||
/** @brief How many edits for this song can each profile have? */
|
||||
const int MAX_EDITS_PER_SONG_PER_PROFILE = 5;
|
||||
|
||||
@@ -52,6 +52,11 @@ void TimingData::AddTickcountSegment( const TickcountSegment &seg )
|
||||
m_TickcountSegments.insert( upper_bound(m_TickcountSegments.begin(), m_TickcountSegments.end(), seg), seg );
|
||||
}
|
||||
|
||||
void TimingData::AddComboSegment( const ComboSegment &seg )
|
||||
{
|
||||
m_ComboSegments.insert( upper_bound(m_ComboSegments.begin(), m_ComboSegments.end(), seg), seg );
|
||||
}
|
||||
|
||||
/* Change an existing BPM segment, merge identical segments together or insert a new one. */
|
||||
void TimingData::SetBPMAtRow( int iNoteRow, float fBPM )
|
||||
{
|
||||
@@ -176,6 +181,27 @@ void TimingData::SetTickcountAtRow( int iRow, int iTicks )
|
||||
}
|
||||
}
|
||||
|
||||
void TimingData::SetComboAtRow( int iRow, int iCombo )
|
||||
{
|
||||
unsigned i;
|
||||
for( i=0; i<m_ComboSegments.size(); i++ )
|
||||
if( m_ComboSegments[i].m_iStartRow >= iRow )
|
||||
break;
|
||||
|
||||
if( i == m_ComboSegments.size() || m_ComboSegments[i].m_iStartRow != iRow )
|
||||
{
|
||||
if( i == 0 || m_ComboSegments[i-1].m_iCombo != iCombo )
|
||||
AddComboSegment( ComboSegment(iRow, iCombo ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( i > 0 && m_ComboSegments[i-1].m_iCombo == iCombo )
|
||||
m_ComboSegments.erase( m_ComboSegments.begin()+i, m_ComboSegments.begin()+i+1 );
|
||||
else
|
||||
m_ComboSegments[i].m_iCombo = iCombo;
|
||||
}
|
||||
}
|
||||
|
||||
float TimingData::GetStopAtRow( int iNoteRow, bool bDelay ) const
|
||||
{
|
||||
for( unsigned i=0; i<m_StopSegments.size(); i++ )
|
||||
@@ -199,6 +225,11 @@ float TimingData::GetDelayAtRow( int iRow ) const
|
||||
return GetStopAtRow( iRow, true );
|
||||
}
|
||||
|
||||
int TimingData::GetComboAtRow( int iNoteRow ) const
|
||||
{
|
||||
return m_ComboSegments[GetComboSegmentIndexAtRow( iNoteRow )].m_iCombo;
|
||||
}
|
||||
|
||||
int TimingData::GetWarpToRow( int iWarpBeginRow ) const
|
||||
{
|
||||
for( unsigned i=0; i<m_WarpSegments.size(); i++ )
|
||||
@@ -309,6 +340,18 @@ int TimingData::GetTimeSignatureDenominatorAtRow( int iRow )
|
||||
return GetTimeSignatureSegmentAtRow( iRow ).m_iDenominator;
|
||||
}
|
||||
|
||||
int TimingData::GetComboSegmentIndexAtRow( int iRow ) const
|
||||
{
|
||||
unsigned i;
|
||||
for( i=0; i<m_ComboSegments.size()-1; i++ )
|
||||
{
|
||||
const ComboSegment& s = m_ComboSegments[i+1];
|
||||
if( s.m_iStartRow > iRow )
|
||||
break;
|
||||
}
|
||||
return (int)i;
|
||||
}
|
||||
|
||||
BPMSegment& TimingData::GetBPMSegmentAtRow( int iNoteRow )
|
||||
{
|
||||
static BPMSegment empty;
|
||||
@@ -319,6 +362,15 @@ BPMSegment& TimingData::GetBPMSegmentAtRow( int iNoteRow )
|
||||
return m_BPMSegments[i];
|
||||
}
|
||||
|
||||
ComboSegment& TimingData::GetComboSegmentAtRow( int iRow )
|
||||
{
|
||||
unsigned i;
|
||||
for( i=0; i<m_ComboSegments.size()-1; i++ )
|
||||
if( m_ComboSegments[i+1].m_iStartRow > iRow )
|
||||
break;
|
||||
return m_ComboSegments[i];
|
||||
}
|
||||
|
||||
StopSegment& TimingData::GetStopSegmentAtRow( int iNoteRow, bool bDelay )
|
||||
{
|
||||
static StopSegment empty;
|
||||
@@ -487,16 +539,19 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float
|
||||
vector<WarpSegment> vWS = m_WarpSegments;
|
||||
vector<TimeSignatureSegment> vTSS = m_vTimeSignatureSegments;
|
||||
vector<TickcountSegment> vTS = m_TickcountSegments;
|
||||
vector<ComboSegment> vCS = m_ComboSegments;
|
||||
sort( vBPMS.begin(), vBPMS.end() );
|
||||
sort( vSS.begin(), vSS.end() );
|
||||
sort( vWS.begin(), vWS.end() );
|
||||
sort( vTSS.begin(), vTSS.end() );
|
||||
sort( vTS.begin(), vTS.end() );
|
||||
sort( vCS.begin(), vCS.end() );
|
||||
ASSERT_M( vBPMS == m_BPMSegments, "The BPM segments were not sorted!" );
|
||||
ASSERT_M( vSS == m_StopSegments, "The Stop segments were not sorted!" );
|
||||
ASSERT_M( vWS == m_WarpSegments, "The Warp segments were not sorted!" );
|
||||
ASSERT_M( vTSS == m_vTimeSignatureSegments, "The Time Signature segments were not sorted!" );
|
||||
ASSERT_M( vTS == m_TickcountSegments, "The Tickcount segments were not sorted!" );
|
||||
ASSERT_M( vCS == m_ComboSegments, "The Combo segments were not sorted!" );
|
||||
FAIL_M( ssprintf("Failed to find the appropriate segment for elapsed time %f.", fTime) );
|
||||
}
|
||||
|
||||
@@ -619,6 +674,14 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd )
|
||||
continue;
|
||||
tick.m_iStartRow += iRowsToAdd;
|
||||
}
|
||||
|
||||
for( unsigned i = 0; i < m_ComboSegments.size(); i++ )
|
||||
{
|
||||
ComboSegment &comb = m_ComboSegments[i];
|
||||
if( comb.m_iStartRow < iStartRow )
|
||||
continue;
|
||||
comb.m_iStartRow += iRowsToAdd;
|
||||
}
|
||||
|
||||
if( iStartRow == 0 )
|
||||
{
|
||||
@@ -720,6 +783,26 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete )
|
||||
// After deleted region:
|
||||
tick.m_iStartRow -= iRowsToDelete;
|
||||
}
|
||||
|
||||
for( unsigned i = 0; i < m_ComboSegments.size(); i++ )
|
||||
{
|
||||
ComboSegment &comb = m_ComboSegments[i];
|
||||
|
||||
// Before deleted region:
|
||||
if( comb.m_iStartRow < iStartRow )
|
||||
continue;
|
||||
|
||||
// Inside deleted region:
|
||||
if( comb.m_iStartRow < iStartRow+iRowsToDelete )
|
||||
{
|
||||
m_ComboSegments.erase( m_ComboSegments.begin()+i, m_ComboSegments.begin()+i+1 );
|
||||
--i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// After deleted region:
|
||||
comb.m_iStartRow -= iRowsToDelete;
|
||||
}
|
||||
|
||||
this->SetBPMAtRow( iStartRow, fNewBPM );
|
||||
}
|
||||
|
||||
+137
-1
@@ -478,6 +478,82 @@ struct TickcountSegment
|
||||
*/
|
||||
bool operator>=( const TickcountSegment &other ) const { return !operator<(other); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Identifies when a chart is to have a different combo multiplier value.
|
||||
*
|
||||
* Admitedly, this would primarily be used for mission mode style charts. However,
|
||||
* it can have its place during normal gameplay.
|
||||
*/
|
||||
struct ComboSegment
|
||||
{
|
||||
/**
|
||||
* @brief Creates a simple Combo Segment with default values.
|
||||
*
|
||||
* It is best to override the values as soon as possible.
|
||||
*/
|
||||
ComboSegment() : m_iStartRow(-1), m_iCombo(1) { }
|
||||
/**
|
||||
* @brief Creates a Combo Segment with the specified starting row and combo factor.
|
||||
* @param s the starting row of this segment.
|
||||
* @param t the amount the combo increases on a succesful hit.
|
||||
*/
|
||||
ComboSegment( int s, int t ){ m_iStartRow = max( 0, s ); m_iCombo = max( 1, t ); }
|
||||
/**
|
||||
* @brief The row in which the ComboSegment activates.
|
||||
*/
|
||||
int m_iStartRow;
|
||||
/**
|
||||
* @brief The amount the combo increases at this point.
|
||||
*/
|
||||
int m_iCombo;
|
||||
|
||||
/**
|
||||
* @brief Compares two ComboSegments to see if they are equal to each other.
|
||||
* @param other the other ComboSegment to compare to.
|
||||
* @return the equality of the two segments.
|
||||
*/
|
||||
bool operator==( const ComboSegment &other ) const
|
||||
{
|
||||
COMPARE( m_iStartRow );
|
||||
COMPARE( m_iCombo );
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @brief Compares two ComboSegments to see if they are not equal to each other.
|
||||
* @param other the other ComboSegment to compare to.
|
||||
* @return the inequality of the two segments.
|
||||
*/
|
||||
bool operator!=( const ComboSegment &other ) const { return !operator==(other); }
|
||||
/**
|
||||
* @brief Compares two ComboSegments to see if one is less than the other.
|
||||
* @param other the other ComboSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is less than the second.
|
||||
*/
|
||||
bool operator<( const ComboSegment &other ) const { return m_iStartRow < other.m_iStartRow; }
|
||||
/**
|
||||
* @brief Compares two ComboSegments to see if one is less than or equal to the other.
|
||||
* @param other the other ComboSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is less or equal to than the second.
|
||||
*/
|
||||
bool operator<=( const ComboSegment &other ) const
|
||||
{
|
||||
return ( operator<(other) || operator==(other) );
|
||||
}
|
||||
/**
|
||||
* @brief Compares two ComboSegments to see if one is greater than the other.
|
||||
* @param other the other ComboSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is greater than the second.
|
||||
*/
|
||||
bool operator>( const ComboSegment &other ) const { return !operator<=(other); }
|
||||
/**
|
||||
* @brief Compares two ComboSegments to see if one is greater than or equal to the other.
|
||||
* @param other the other ComboSegment to compare to.
|
||||
* @return the truth/falsehood of if the first is greater than or equal to the second.
|
||||
*/
|
||||
bool operator>=( const ComboSegment &other ) const { return !operator<(other); }
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Holds data for translating beats<->seconds.
|
||||
*/
|
||||
@@ -872,6 +948,60 @@ public:
|
||||
*/
|
||||
void AddTickcountSegment( const TickcountSegment &seg );
|
||||
|
||||
/**
|
||||
* @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 GetComboAtBeat( float fBeat ) const { return GetComboAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Set the row to have the new Combo.
|
||||
* @param iNoteRow the row to have the new Combo.
|
||||
* @param iTicks 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 iTicks the Combo.
|
||||
*/
|
||||
void SetComboAtBeat( float fBeat, int iCombo ) { SetComboAtRow( BeatToNoteRow( fBeat ), iCombo ); }
|
||||
/**
|
||||
* @brief Retrieve the ComboSegment at the specified row.
|
||||
* @param iNoteRow the row that has a ComboSegment.
|
||||
* @return the ComboSegment in question.
|
||||
*/
|
||||
ComboSegment& GetComboSegmentAtRow( int iNoteRow );
|
||||
/**
|
||||
* @brief Retrieve the ComboSegment at the specified beat.
|
||||
* @param fBeat the beat that has a ComboSegment.
|
||||
* @return the ComboSegment in question.
|
||||
*/
|
||||
ComboSegment& GetComboSegmentAtBeat( float fBeat ) { return GetComboSegmentAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Retrieve the index of the ComboSegments at the specified row.
|
||||
* @param iNoteRow the row that has a ComboSegment.
|
||||
* @return the ComboSegment's index in question.
|
||||
*/
|
||||
int GetComboSegmentIndexAtRow( int iNoteRow ) const;
|
||||
/**
|
||||
* @brief Retrieve the index of the ComboSegments at the specified beat.
|
||||
* @param fBeat the beat that has a ComboSegment.
|
||||
* @return the ComboSegment's index in question.
|
||||
*/
|
||||
int GetComboSegmentIndexAtBeat( float fBeat ) const { return GetComboSegmentIndexAtRow( BeatToNoteRow(fBeat) ); }
|
||||
/**
|
||||
* @brief Add the ComboSegment to the TimingData.
|
||||
* @param seg the new ComboSegment.
|
||||
*/
|
||||
void AddComboSegment( const ComboSegment &seg );
|
||||
|
||||
void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor );
|
||||
|
||||
void NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, int &iBeatIndexOut, int &iRowsRemainder ) const;
|
||||
@@ -936,6 +1066,9 @@ public:
|
||||
COMPARE( m_TickcountSegments.size() );
|
||||
for( unsigned i=0; i<m_TickcountSegments.size(); i++ )
|
||||
COMPARE( m_TickcountSegments[i] );
|
||||
COMPARE( m_ComboSegments.size() );
|
||||
for( unsigned i=0; i<m_ComboSegments.size(); i++ )
|
||||
COMPARE( m_ComboSegments[i] );
|
||||
COMPARE( m_fBeat0OffsetInSeconds );
|
||||
return true;
|
||||
}
|
||||
@@ -979,6 +1112,10 @@ public:
|
||||
* @brief The collection of TickcountSegments.
|
||||
*/
|
||||
vector<TickcountSegment> m_TickcountSegments;
|
||||
/**
|
||||
* @brief The collection of ComboSegments.
|
||||
*/
|
||||
vector<ComboSegment> m_ComboSegments;
|
||||
/**
|
||||
* @brief The initial offset of a song.
|
||||
*/
|
||||
@@ -999,7 +1136,6 @@ public:
|
||||
/**
|
||||
* @file
|
||||
* @author Chris Danford, Glenn Maynard (c) 2001-2004
|
||||
*
|
||||
* @section LICENSE
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user