From 7c2cefc19025a54b6abd92bdda9f470a7c28eafe Mon Sep 17 00:00:00 2001 From: Colby Klein Date: Tue, 7 Jun 2011 18:23:17 -0700 Subject: [PATCH 01/44] Silence warning --- src/NoteTypes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NoteTypes.h b/src/NoteTypes.h index 3d99c63252..cd00810e0a 100644 --- a/src/NoteTypes.h +++ b/src/NoteTypes.h @@ -164,7 +164,7 @@ struct TapNote { if (type_ > TapNote::fake ) { - LOG->Trace(ssprintf("Invalid tap note type %d (most likely) due to random vanish issues. Assume it doesn't need judging.", type_ ) ); + LOG->Trace("Invalid tap note type %d (most likely) due to random vanish issues. Assume it doesn't need judging.", (int)type_ ); type = TapNote::empty; } } From 4b11968abcdb57d1735bf29f18f005f134ca9bd4 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 7 Jun 2011 23:43:07 -0400 Subject: [PATCH 02/44] Make it more obvious about the T key. Guess not everyone reads changelogs or F1. --- Themes/_fallback/Languages/en.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 1884302235..63c9701cc0 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1257,7 +1257,7 @@ Enter a new min BPM.=Enter the minimum displayed BPM. Enter a new max BPM.=Enter the maximum displayed BPM. More than %d notes per measure is not allowed. This change has been reverted.=More than %d notes per measure is not allowed. This change has been reverted. No backgrounds available=No backgrounds available -EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nEnter:\n Area Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n +EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nT key:\n Switch Timing\nEnter:\n Area Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n PlayRecordHelpText=Press START to end Save successful.=Save successful. Saved as SM and DWI.=Saved as SM and DWI. From 5216d6be45cb8ccb7f91ae0b4770248cbe899829 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 13:03:07 -0400 Subject: [PATCH 03/44] Simplify checks for unjudgable rows. This way, we can add more segments later and now have to change the logic in many places. --- src/GameplayAssist.cpp | 2 +- src/Player.cpp | 14 +++++++------- src/TimingData.h | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/GameplayAssist.cpp b/src/GameplayAssist.cpp index 4ecd6be014..e42920f15c 100644 --- a/src/GameplayAssist.cpp +++ b/src/GameplayAssist.cpp @@ -47,7 +47,7 @@ void GameplayAssist::PlayTicks( const NoteData &nd, const PlayerState *ps ) if( nd.IsThereATapOrHoldHeadAtRow( r ) ) iClapRow = r; - if( iClapRow != -1 && !timing.IsWarpAtRow( iClapRow ) && !timing.IsFakeAtRow( iClapRow ) ) + if( iClapRow != -1 && timing.IsJudgableAtRow(iClapRow)) { const float fTickBeat = NoteRowToBeat( iClapRow ); const float fTickSecond = timing.GetElapsedTimeFromBeatNoOffset( fTickBeat ); diff --git a/src/Player.cpp b/src/Player.cpp index 6179b16d83..569a9080df 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1538,7 +1538,7 @@ int Player::GetClosestNoteDirectional( int col, int iStartRow, int iEndRow, bool // Is this the row we want? do { const TapNote &tn = begin->second; - if( m_Timing->IsWarpAtRow( begin->first ) || m_Timing->IsFakeAtRow( begin->first ) ) + if (!m_Timing->IsJudgableAtRow( begin->first )) break; if( tn.type == TapNote::empty ) break; @@ -1594,7 +1594,7 @@ int Player::GetClosestNonEmptyRowDirectional( int iStartRow, int iEndRow, bool b ++iter; continue; } - if( m_Timing->IsWarpAtRow( iter.Row() ) || m_Timing->IsFakeAtRow( iter.Row() ) ) + if (!m_Timing->IsJudgableAtRow(iter.Row())) { ++iter; continue; @@ -2118,7 +2118,7 @@ void Player::StepStrumHopo( int col, int row, const RageTimer &tm, bool bHeld, b // Stepped too close to mine? if( !bRelease && ( REQUIRE_STEP_ON_MINES == !bHeld ) && fSecondsFromExact <= GetWindowSeconds(TW_Mine) && - !m_Timing->IsWarpAtRow(iSongRow) && !m_Timing->IsFakeAtRow(iSongRow)) + m_Timing->IsJudgableAtRow(iSongRow)) score = TNS_HitMine; break; @@ -2616,7 +2616,7 @@ void Player::UpdateTapNotesMissedOlderThan( float fMissIfOlderThanSeconds ) continue; // Ignore all notes in WarpSegments or FakeSegments. - if( m_Timing->IsWarpAtRow( iter.Row() ) || m_Timing->IsFakeAtRow( iter.Row() ) ) + if (!m_Timing->IsJudgableAtRow(iter.Row())) continue; if( tn.type == TapNote::mine ) @@ -2651,7 +2651,7 @@ void Player::UpdateJudgedRows() int iRow = iter.Row(); // Do not judge arrows in WarpSegments or FakeSegments - if( m_Timing->IsWarpAtRow(iRow) || m_Timing->IsFakeAtRow(iRow) ) + if (!m_Timing->IsJudgableAtRow(iRow)) continue; if( iLastSeenRow != iRow ) @@ -2990,7 +2990,7 @@ void Player::HandleTapRowScore( unsigned row ) #endif // Do not score rows in WarpSegments or FakeSegments - if( m_Timing->IsWarpAtRow( row ) || m_Timing->IsFakeAtRow( row ) ) + if (!m_Timing->IsJudgableAtRow(row)) return; if( GAMESTATE->m_bDemonstrationOrJukebox ) @@ -3094,7 +3094,7 @@ void Player::HandleHoldCheckpoint( int iRow, int iNumHoldsHeldThisRow, int iNumH #endif // WarpSegments and FakeSegments aren't judged in any way. - if( m_Timing->IsWarpAtRow( iRow ) || m_Timing->IsFakeAtRow( iRow ) ) + if (!m_Timing->IsJudgableAtRow(iRow)) return; // don't accumulate combo if AutoPlay is on. diff --git a/src/TimingData.h b/src/TimingData.h index e81fc078e7..fda617ee4c 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -845,6 +845,20 @@ public: */ void AddFakeSegment( const FakeSegment &seg ); + /** + * @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 IsJudgableAtBeat( float beat ) const { return IsJudgableAtRow( BeatToNoteRow( beat ) ); } + void MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float fFactor ); From d0821262d1c30d43e83cf968150fa7f5f1a30123 Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Wed, 8 Jun 2011 12:38:36 -0500 Subject: [PATCH 04/44] add @waiei's changes to SuperNova2 scoring: http://twitpic.com/57wqss --- Themes/_fallback/Scripts/04 Scoring.lua | 40 +++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/Themes/_fallback/Scripts/04 Scoring.lua b/Themes/_fallback/Scripts/04 Scoring.lua index 27a1d6155a..75b5733f1a 100644 --- a/Themes/_fallback/Scripts/04 Scoring.lua +++ b/Themes/_fallback/Scripts/04 Scoring.lua @@ -148,23 +148,39 @@ end; r['DDR SuperNOVA 2'] = function(params, pss) local multLookup = { - ['TapNoteScore_W1'] = 1, - ['TapNoteScore_W2'] = 1, - ['TapNoteScore_W3'] = 0.5 + ['TapNoteScore_W1'] = 10, + ['TapNoteScore_W2'] = 10, + ['TapNoteScore_W3'] = 5 }; setmetatable(multLookup, ZeroIfNotFound); local radarValues = GetDirectRadar(params.Player); - local totalItems = GetTotalItems(radarValues); - local base = 100000 / totalItems; - local hold = base * (params.HoldNoteScore == 'HoldNoteScore_Held' and 1 or 0); - local maxScore = (base * multLookup['TapNoteScore_W1']) + hold; - pss:SetCurMaxScore(pss:GetCurMaxScore() + (math.round(maxScore) * 10)); - local preW1 = base * multLookup[params.TapNoteScore]; - local buildScore = (preW1 - (IsW1Allowed(params.TapNoteScore) and 10 or 0)) + hold; - pss:SetScore(pss:GetScore() + (math.round(buildScore) * 10)); + local numLifts = radarValues:GetCategory('RadarCategory_Lifts') + local numFakes = radarValues:GetCategory('RadarCategory_Fakes') + local totalItems = GetTotalItems(radarValues) - (numLifts + numFakes); + + -- handle freezes + local maxAdd = 0 + if params.HoldNoteScore == 'HoldNoteScore_Held' then + maxAdd = 10 + else + if params.HoldNoteScore == 'HoldNoteScore_LetGo' then + maxAdd = 0 + else + maxAdd = multLookup[params.TapNoteScore] + if params.TapNoteScore == 'TapNoteScore_W2' then + pss:SetCurMaxScore( pss:GetCurMaxScore() + 1000000 ) + end + end + end + pss:SetCurMaxScore(pss:GetCurMaxScore() + maxAdd); + + local scoreDiv = pss:GetCurMaxScore() % 1000000 + local w2 = math.floor( pss:GetCurMaxScore()/1000000 ) + + pss:SetScore( math.floor( 1000*(scoreDiv/totalItems) * (1000 - (w2*100)) ) ); end; ----------------------------------------------------------- ---Radar Master (doesn't work in 1.2.1, disabled) +--Radar Master (doesn't work in sm-ssc 1.2.1, disabled) --don't try to "fix it up", either. you *cannot* make it work in 1.2.1. ----------------------------------------------------------- r['[SSC] Radar Master'] = function(params, pss) From 9ac07e1e2eb18dd8f3e0d6b8917068e3974d0660 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 14:43:59 -0400 Subject: [PATCH 05/44] Prepare for a place to process timing data. Hopefully what I'm thinking of won't cause too much slowdown. --- src/GameState.cpp | 11 +++++++++++ src/GameState.h | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/GameState.cpp b/src/GameState.cpp index a720dcbd89..9b030ff98d 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -106,6 +106,7 @@ static Preference g_Premium( "Premium", Premium_Off ); Preference GameState::m_bAutoJoin( "AutoJoin", false ); GameState::GameState() : + processedTiming( NULL ), m_pCurGame( Message_CurrentGameChanged ), m_pCurStyle( Message_CurrentStyleChanged ), m_PlayMode( Message_PlayModeChanged ), @@ -200,6 +201,16 @@ void GameState::SetMasterPlayerNumber(const PlayerNumber p) this->masterPlayerNumber = p; } +TimingData * GameState::GetProcessedTimingData() const +{ + return this->processedTiming; +} + +void GameState::SetProcessedTimingData(TimingData t) +{ + this->processedTiming = &t; +} + void GameState::ApplyGameCommand( const RString &sCommand, PlayerNumber pn ) { GameCommand m; diff --git a/src/GameState.h b/src/GameState.h index 79618aa711..463cc8c2ca 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -37,6 +37,8 @@ class GameState { /** @brief The player number used with Styles where one player controls both sides. */ PlayerNumber masterPlayerNumber; + /** @brief The TimingData that is used for processing certain functions. */ + TimingData * processedTiming; public: /** @brief Set up the GameState with initial values. */ GameState(); @@ -149,6 +151,16 @@ public: * @brief Set the master player number. * @param p the master player number. */ void SetMasterPlayerNumber(const PlayerNumber p); + + /** + * @brief Retrieve the present timing data being processed. + * @return the timing data pointer. */ + TimingData * GetProcessedTimingData() const; + + /** + * @brief Set the timing data to be used with processing. + * @param t the timing data. */ + void SetProcessedTimingData(TimingData t); bool IsCourseMode() const; bool IsBattleMode() const; // not Rave From fec932e153f234209004065533e1cbfb3cbdc1ff Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 15:02:54 -0400 Subject: [PATCH 06/44] More prep work for better radar calculations. --- src/GameState.cpp | 4 ++-- src/GameState.h | 2 +- src/ScoreKeeperNormal.cpp | 2 ++ src/ScreenGameplay.cpp | 4 +++- src/Steps.cpp | 3 +++ src/Trail.cpp | 3 +++ 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/GameState.cpp b/src/GameState.cpp index 9b030ff98d..825d051fda 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -206,9 +206,9 @@ TimingData * GameState::GetProcessedTimingData() const return this->processedTiming; } -void GameState::SetProcessedTimingData(TimingData t) +void GameState::SetProcessedTimingData(TimingData * t) { - this->processedTiming = &t; + this->processedTiming = t; } void GameState::ApplyGameCommand( const RString &sCommand, PlayerNumber pn ) diff --git a/src/GameState.h b/src/GameState.h index 463cc8c2ca..0b2463f3c7 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -160,7 +160,7 @@ public: /** * @brief Set the timing data to be used with processing. * @param t the timing data. */ - void SetProcessedTimingData(TimingData t); + void SetProcessedTimingData(TimingData * t); bool IsCourseMode() const; bool IsBattleMode() const; // not Rave diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index ce3874aa5a..e3872b8c83 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -120,6 +120,7 @@ void ScoreKeeperNormal::Load( * forced and not chosen by the user. */ NoteDataUtil::TransformNoteData( nd, aa, pSteps->m_StepsType, pSong ); RadarValues rvPre; + GAMESTATE->SetProcessedTimingData(&pSteps->m_Timing); NoteDataUtil::CalculateRadarValues( nd, pSong->m_fMusicLengthSeconds, rvPre ); /* Apply user transforms to find out how the notes will really look. @@ -132,6 +133,7 @@ void ScoreKeeperNormal::Load( NoteDataUtil::TransformNoteData( nd, m_pPlayerState->m_PlayerOptions.GetStage(), pSteps->m_StepsType ); RadarValues rvPost; NoteDataUtil::CalculateRadarValues( nd, pSong->m_fMusicLengthSeconds, rvPost ); + GAMESTATE->SetProcessedTimingData(NULL); iTotalPossibleDancePoints += this->GetPossibleDancePoints( rvPre, rvPost ); iTotalPossibleGradePoints += this->GetPossibleGradePoints( rvPre, rvPost ); diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index c4a6ccaeca..e29d45fa63 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -2294,10 +2294,12 @@ void ScreenGameplay::SaveStats() RadarValues rv; PlayerStageStats &pss = *pi->GetPlayerStageStats(); const NoteData &nd = pi->m_pPlayer->GetNoteData(); + PlayerNumber pn = pi->m_pn; + GAMESTATE->SetProcessedTimingData(&GAMESTATE->m_pCurSteps[pn]->m_Timing); NoteDataUtil::CalculateRadarValues( nd, fMusicLen, rv ); pss.m_radarPossible += rv; - + GAMESTATE->SetProcessedTimingData(NULL); NoteDataWithScoring::GetActualRadarValues( nd, pss, fMusicLen, rv ); pss.m_radarActual += rv; } diff --git a/src/Steps.cpp b/src/Steps.cpp index c1a79064f5..c09ebe49a6 100644 --- a/src/Steps.cpp +++ b/src/Steps.cpp @@ -14,6 +14,7 @@ #include "global.h" #include "Steps.h" #include "StepsUtil.h" +#include "GameState.h" #include "Song.h" #include "RageUtil.h" #include "RageLog.h" @@ -192,6 +193,7 @@ void Steps::CalculateRadarValues( float fMusicLengthSeconds ) FOREACH_PlayerNumber( pn ) m_CachedRadarValues[pn].Zero(); + GAMESTATE->SetProcessedTimingData(&this->m_Timing); if( tempNoteData.IsComposite() ) { vector vParts; @@ -205,6 +207,7 @@ void Steps::CalculateRadarValues( float fMusicLengthSeconds ) NoteDataUtil::CalculateRadarValues( tempNoteData, fMusicLengthSeconds, m_CachedRadarValues[0] ); fill_n( m_CachedRadarValues + 1, NUM_PLAYERS-1, m_CachedRadarValues[0] ); } + GAMESTATE->SetProcessedTimingData(NULL); } void Steps::Decompress() const diff --git a/src/Trail.cpp b/src/Trail.cpp index 073d266c93..25ece2abd3 100644 --- a/src/Trail.cpp +++ b/src/Trail.cpp @@ -1,6 +1,7 @@ #include "global.h" #include "Trail.h" #include "Foreach.h" +#include "GameState.h" #include "Steps.h" #include "Song.h" #include "PlayerOptions.h" @@ -116,6 +117,7 @@ const RadarValues &Trail::GetRadarValues() const NoteData nd; pSteps->GetNoteData( nd ); RadarValues rv_orig; + GAMESTATE->SetProcessedTimingData(const_cast(&pSteps->m_Timing)); NoteDataUtil::CalculateRadarValues( nd, e->pSong->m_fMusicLengthSeconds, rv_orig ); PlayerOptions po; po.FromString( e->Modifiers ); @@ -124,6 +126,7 @@ const RadarValues &Trail::GetRadarValues() const NoteDataUtil::TransformNoteData( nd, e->Attacks, pSteps->m_StepsType, e->pSong ); RadarValues transformed_rv; NoteDataUtil::CalculateRadarValues( nd, e->pSong->m_fMusicLengthSeconds, transformed_rv ); + GAMESTATE->SetProcessedTimingData(NULL); rv += transformed_rv; } else From 06efa5c726f46f2ade36bafe39678d44c866fd66 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 15:33:40 -0400 Subject: [PATCH 07/44] Simple solutions are smart. --- src/TimingData.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/TimingData.h b/src/TimingData.h index fda617ee4c..58999a23e9 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -851,7 +851,9 @@ public: * @return true if the row can be judged, false otherwise. */ bool IsJudgableAtRow( int row ) const { - return !(IsWarpAtRow(row) && IsFakeAtRow(row)); + if (IsWarpAtRow(row)) return false; + if (IsFakeAtRow(row)) return false; + return true; } /** * @brief Determine if this notes on this beat can be judged. From 90e563cbce1ce1381cb3400a32150859acb54b4b Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Wed, 8 Jun 2011 14:36:24 -0500 Subject: [PATCH 08/44] add @waiei's hybrid scoring and fix up supernova 2 scoring --- Themes/_fallback/Scripts/03 ThemePrefs.lua | 2 +- Themes/_fallback/Scripts/04 Scoring.lua | 61 +++++++++++++++++++--- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/Themes/_fallback/Scripts/03 ThemePrefs.lua b/Themes/_fallback/Scripts/03 ThemePrefs.lua index dfa9e3e695..90d7d73a19 100644 --- a/Themes/_fallback/Scripts/03 ThemePrefs.lua +++ b/Themes/_fallback/Scripts/03 ThemePrefs.lua @@ -150,7 +150,7 @@ function InitUserPrefs() end; function UserPrefScoringMode() - local baseChoices = { 'DDR 1stMIX', 'DDR 4thMIX', 'DDR Extreme', 'DDR SuperNOVA', 'DDR SuperNOVA 2', 'MIGS' }; --'[SSC] Radar Master' + local baseChoices = { 'DDR 1stMIX', 'DDR 4thMIX', 'DDR Extreme', 'DDR SuperNOVA', 'DDR SuperNOVA 2', 'MIGS', 'HYBRID' }; --'[SSC] Radar Master' local t = { Name = "UserPrefScoringMode"; LayoutType = "ShowAllInRow"; diff --git a/Themes/_fallback/Scripts/04 Scoring.lua b/Themes/_fallback/Scripts/04 Scoring.lua index 75b5733f1a..fd579db996 100644 --- a/Themes/_fallback/Scripts/04 Scoring.lua +++ b/Themes/_fallback/Scripts/04 Scoring.lua @@ -122,6 +122,48 @@ r['DDR Extreme'] = function(params, pss) Shared.CurrentStep[pn] = 0; -- Reset for the next song. end; end; + +----------------------------------------------------------- +--HYBRID Scoring +----------------------------------------------------------- +r['HYBRID'] = function(params, pss) + local multLookup = + { + ['TapNoteScore_W1'] = 10, + ['TapNoteScore_W2'] = 9, + ['TapNoteScore_W3'] = 5 + }; + setmetatable(multLookup, ZeroIfNotFound); + local radarValues = GetDirectRadar(params.Player); + local totalItems = GetTotalItems(radarValues) + - radarValues:GetValue('RadarCategory_Lifts'); + -- 1+2+3+...+totalItems の値 + local sTotal = (totalItems+1)*totalItems/2; + -- [en] Score for one song + -- [ja] 1つあたりのスコア + local sOne = math.floor(100000000/sTotal); + -- [ja] 端数は最後の1ステップで加算するのでその値を取得 + local sLast = 100000000-(sOne*sTotal); + -- [ja] 現在何個目の譜面か + pss:SetCurMaxScore(pss:GetCurMaxScore()+1); + -- [en] current score + -- [ja] 今回のスコア + local vScore = sOne*(pss:GetCurMaxScore()); + if (params.HoldNoteScore == 'HoldNoteScore_Held') then + vScore = vScore; + else + if (params.HoldNoteScore == 'HoldNoteScore_LetGo') then + vScore = 0; + else + vScore = vScore*multLookup[params.TapNoteScore]/10; + end; + end; + if ((vScore > 0) and (pss:GetCurMaxScore() == totalItems)) then + vScore = vScore+sLast; + end; + pss:SetScore(pss:GetScore()+vScore); +end; + ----------------------------------------------------------- --DDR SuperNOVA(-esque) scoring ----------------------------------------------------------- @@ -158,7 +200,7 @@ r['DDR SuperNOVA 2'] = function(params, pss) local numFakes = radarValues:GetCategory('RadarCategory_Fakes') local totalItems = GetTotalItems(radarValues) - (numLifts + numFakes); - -- handle freezes + -- handle holds local maxAdd = 0 if params.HoldNoteScore == 'HoldNoteScore_Held' then maxAdd = 10 @@ -167,21 +209,28 @@ r['DDR SuperNOVA 2'] = function(params, pss) maxAdd = 0 else maxAdd = multLookup[params.TapNoteScore] - if params.TapNoteScore == 'TapNoteScore_W2' then + if params.TapNoteScore == 'TapNoteScore_W2' or 'TapNoteScore_W3' then + -- [ja] 超最終手段 pss:SetCurMaxScore( pss:GetCurMaxScore() + 1000000 ) end end end pss:SetCurMaxScore(pss:GetCurMaxScore() + maxAdd); - local scoreDiv = pss:GetCurMaxScore() % 1000000 - local w2 = math.floor( pss:GetCurMaxScore()/1000000 ) + --[[ + [ja] パフェ数取得 この方法で取得するとロングノートの場合2つカウントされる そのため使えない + pss:GetTapNoteScores('TapNoteScore_W2') + 仕方がないのでパフェ数を 1000000 単位で GetCurMaxScore に記録 + その後、情報を分解して取り出す + --]] - pss:SetScore( math.floor( 1000*(scoreDiv/totalItems) * (1000 - (w2*100)) ) ); + local vScore = pss:GetCurMaxScore() % 1000000 + local vSub = math.floor( pss:GetCurMaxScore()/1000000 ) + pss:SetScore( math.floor(10000*vScore/totalItems) * 10 - (vSub*10) ); end; ----------------------------------------------------------- --Radar Master (doesn't work in sm-ssc 1.2.1, disabled) ---don't try to "fix it up", either. you *cannot* make it work in 1.2.1. +--todo: get this working with StepMania 5 ----------------------------------------------------------- r['[SSC] Radar Master'] = function(params, pss) local masterTable = { From fc9f07158a0eaa8b1714e5e8b0177d188018ac86 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 16:14:11 -0400 Subject: [PATCH 09/44] 99% fix scoring with warps and fakes. Now all charts can seek 100%. This does force yet another cache reload. Hopefully it won't slow first loads too much. --- Docs/Changelog_sm5.txt | 6 ++++++ src/NoteData.cpp | 29 +++++++++++++++++++++-------- src/NoteDataUtil.cpp | 5 +++++ src/ScoreKeeperNormal.cpp | 4 ++++ src/ScreenEdit.cpp | 5 +++++ src/ScreenGameplay.cpp | 2 +- src/Song.cpp | 2 +- 7 files changed, 43 insertions(+), 10 deletions(-) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index e9ccf1cc69..0739778269 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,6 +8,12 @@ ________________________________________________________________________________ StepMania 5.0 Preview 2 | 20110??? -------------------------------------------------------------------------------- +2011/06/08 +---------- +* Any notes in a fake segment or warp segment are completely ignored for + scoring purposes. Now you can get 100% on your warping goodness! + [Wolfman2000] + 2011/06/06 ---------- * [PlayerOptions] Removed the ScoreDisplay mod choices. Use lua to make your diff --git a/src/NoteData.cpp b/src/NoteData.cpp index eac5bc42b4..50265d5b65 100644 --- a/src/NoteData.cpp +++ b/src/NoteData.cpp @@ -9,6 +9,7 @@ #include "RageUtil.h" #include "RageLog.h" #include "XmlFile.h" +#include "GameState.h" // blame radar calculations. #include "Foreach.h" #include "RageUtil_AutoPtr.h" @@ -467,7 +468,8 @@ int NoteData::GetNumTapNotes( int iStartIndex, int iEndIndex ) const { const TapNote &tn = GetTapNote(t, r); if( tn.type != TapNote::empty && tn.type != TapNote::mine - && tn.type != TapNote::lift && tn.type != TapNote::fake ) + && tn.type != TapNote::lift && tn.type != TapNote::fake + && GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(r) ) iNumNotes++; } } @@ -485,7 +487,7 @@ int NoteData::GetNumRowsWithTap( int iStartIndex, int iEndIndex ) const { int iNumNotes = 0; FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( *this, r, iStartIndex, iEndIndex ) - if( IsThereATapAtRow(r) ) + if( IsThereATapAtRow(r) && GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(r) ) iNumNotes++; return iNumNotes; @@ -498,7 +500,8 @@ int NoteData::GetNumMines( int iStartIndex, int iEndIndex ) const for( int t=0; tGetProcessedTimingData()->IsJudgableAtRow(r)) iNumMines++; } @@ -509,7 +512,7 @@ int NoteData::GetNumRowsWithTapOrHoldHead( int iStartIndex, int iEndIndex ) cons { int iNumNotes = 0; FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( *this, r, iStartIndex, iEndIndex ) - if( IsThereATapOrHoldHeadAtRow(r) ) + if( IsThereATapOrHoldHeadAtRow(r) && GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(r) ) iNumNotes++; return iNumNotes; @@ -560,7 +563,8 @@ int NoteData::GetNumRowsWithSimultaneousPresses( int iMinSimultaneousPresses, in { if( !RowNeedsAtLeastSimultaneousPresses(iMinSimultaneousPresses,r) ) continue; - + if (!GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(r)) + continue; iNum++; } @@ -576,7 +580,10 @@ int NoteData::GetNumRowsWithSimultaneousTaps( int iMinTaps, int iStartIndex, int for( int t=0; tGetProcessedTimingData()->IsJudgableAtRow(r)) iNumNotesThisIndex++; } if( iNumNotesThisIndex >= iMinTaps ) @@ -598,6 +605,8 @@ int NoteData::GetNumHoldNotes( int iStartIndex, int iEndIndex ) const if( lBegin->second.type != TapNote::hold_head || lBegin->second.subType != TapNote::hold_head_hold ) continue; + if (!GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(lBegin->first)) + continue; iNumHolds++; } } @@ -616,6 +625,8 @@ int NoteData::GetNumRolls( int iStartIndex, int iEndIndex ) const if( lBegin->second.type != TapNote::hold_head || lBegin->second.subType != TapNote::hold_head_roll ) continue; + if (!GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(lBegin->first)) + continue; iNumRolls++; } } @@ -629,7 +640,8 @@ int NoteData::GetNumLifts( int iStartIndex, int iEndIndex ) const for( int t=0; tGetProcessedTimingData()->IsJudgableAtRow(r)) iNumLifts++; } @@ -643,7 +655,8 @@ int NoteData::GetNumFakes( int iStartIndex, int iEndIndex ) const for( int t=0; tGetProcessedTimingData()->IsJudgableAtRow(r)) iNumFakes++; } diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index ccb9faf2b4..7ecbbe46ac 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -799,6 +799,11 @@ RadarStats CalculateRadarStatsFast( const NoteData &in, RadarStats &out ) { FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE( in, t, r, 0, MAX_NOTE_ROW ) { + /* This function deals strictly with taps, jumps, hands, and quads. + * As such, all rows in here have to be judgable. */ + if (!GAMESTATE->GetProcessedTimingData()->IsJudgableAtRow(r)) + continue; + const TapNote &tn = in.GetTapNote(t, r); switch( tn.type ) { diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index e3872b8c83..d5b3494a5f 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -219,6 +219,8 @@ void ScoreKeeperNormal::OnNextSong( int iSongInCourseIndex, const Steps* pSteps, ASSERT( m_iMaxPossiblePoints >= 0 ); m_iMaxScoreSoFar += m_iMaxPossiblePoints; + GAMESTATE->SetProcessedTimingData(const_cast(&pSteps->m_Timing)); + m_iNumTapsAndHolds = pNoteData->GetNumRowsWithTapOrHoldHead() + pNoteData->GetNumHoldNotes() + pNoteData->GetNumRolls(); @@ -232,6 +234,8 @@ void ScoreKeeperNormal::OnNextSong( int iSongInCourseIndex, const Steps* pSteps, ASSERT( m_iPointBonus >= 0 ); m_iTapNotesHit = 0; + + GAMESTATE->SetProcessedTimingData(NULL); } static int GetScore(int p, int Z, int S, int n) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index c6905545f4..ac98d5c18e 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1152,6 +1152,9 @@ void ScreenEdit::UpdateTextInfo() sText += ssprintf( TAP_NOTE_TYPE_FORMAT.GetValue(), TAP_NOTE_TYPE.GetValue().c_str(), TapNoteTypeToString( m_selectedTap.type ).c_str() ); break; } + + GAMESTATE->SetProcessedTimingData(&m_pSteps->m_Timing); + sText += ssprintf( NUM_STEPS_FORMAT.GetValue(), TAP_STEPS.GetValue().c_str(), m_NoteDataEdit.GetNumTapNotes() ); sText += ssprintf( NUM_JUMPS_FORMAT.GetValue(), JUMPS.GetValue().c_str(), m_NoteDataEdit.GetNumJumps() ); sText += ssprintf( NUM_HANDS_FORMAT.GetValue(), HANDS.GetValue().c_str(), m_NoteDataEdit.GetNumHands() ); @@ -1182,6 +1185,8 @@ void ScreenEdit::UpdateTextInfo() } m_textInfo.SetText( sText ); + + GAMESTATE->SetProcessedTimingData(NULL); } void ScreenEdit::DrawPrimitives() diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index e29d45fa63..a0eb87b581 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -2299,9 +2299,9 @@ void ScreenGameplay::SaveStats() GAMESTATE->SetProcessedTimingData(&GAMESTATE->m_pCurSteps[pn]->m_Timing); NoteDataUtil::CalculateRadarValues( nd, fMusicLen, rv ); pss.m_radarPossible += rv; - GAMESTATE->SetProcessedTimingData(NULL); NoteDataWithScoring::GetActualRadarValues( nd, pss, fMusicLen, rv ); pss.m_radarActual += rv; + GAMESTATE->SetProcessedTimingData(NULL); } } diff --git a/src/Song.cpp b/src/Song.cpp index 62696a93e2..e6196ac12e 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -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 = 179; +const int FILE_CACHE_VERSION = 180; /** @brief How long does a song sample last by default? */ const float DEFAULT_MUSIC_SAMPLE_LENGTH = 12.f; From 80196549567143f7dc2874bea874a20676ad0797 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 18:14:50 -0400 Subject: [PATCH 10/44] shakesoda was right. --- src/TimingData.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/TimingData.h b/src/TimingData.h index 58999a23e9..687016ea5b 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -851,9 +851,7 @@ public: * @return true if the row can be judged, false otherwise. */ bool IsJudgableAtRow( int row ) const { - if (IsWarpAtRow(row)) return false; - if (IsFakeAtRow(row)) return false; - return true; + return !(IsWarpAtRow(row) || IsFakeAtRow(row)); } /** * @brief Determine if this notes on this beat can be judged. From 2f896c38072bc165f86b820a4c742453a2821176 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 18:20:37 -0400 Subject: [PATCH 11/44] Missed a spot. --- src/ScreenEdit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index ac98d5c18e..e0c805a5ad 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3242,6 +3242,7 @@ static LocalizedString SAVE_CHANGES_BEFORE_EXITING ( "ScreenEdit", "Do you want void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAnswers ) { + GAMESTATE->SetProcessedTimingData(&m_pSteps->m_Timing); switch( c ) { DEFAULT_FAIL( c ); @@ -3460,6 +3461,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns } break; }; + GAMESTATE->SetProcessedTimingData(NULL); } void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAnswers, bool bAllowUndo ) From 42f39c7ab9bc7034b9d581a4262b73b3a5921ea9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 21:58:45 -0400 Subject: [PATCH 12/44] Restrict course editor to playable songs. This does not yet deal with songs with charts in multiple game types. ...at least, as far as I know. --- src/ScreenOptionsEditCourse.cpp | 2 +- src/SongUtil.cpp | 21 +++++++++++++++++++-- src/SongUtil.h | 15 ++++++++++++++- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/ScreenOptionsEditCourse.cpp b/src/ScreenOptionsEditCourse.cpp index 6f5c6aa111..020f328c1d 100644 --- a/src/ScreenOptionsEditCourse.cpp +++ b/src/ScreenOptionsEditCourse.cpp @@ -145,7 +145,7 @@ void ScreenOptionsEditCourse::Init() sc.m_Tutorial = SongCriteria::Tutorial_No; sc.m_Locked = SongCriteria::Locked_Unlocked; - SongUtil::FilterSongs( sc, SONGMAN->GetAllSongs(), m_vpSongs ); + SongUtil::FilterSongs( sc, SONGMAN->GetAllSongs(), m_vpSongs, true ); SongUtil::SortSongPointerArrayByTitle( m_vpSongs ); } diff --git a/src/SongUtil.cpp b/src/SongUtil.cpp index b188a0c108..f13576fbc0 100644 --- a/src/SongUtil.cpp +++ b/src/SongUtil.cpp @@ -871,13 +871,15 @@ void SongUtil::GetAllSongGenres( vector &vsOut ) } } -void SongUtil::FilterSongs( const SongCriteria &sc, const vector &in, vector &out ) +void SongUtil::FilterSongs( const SongCriteria &sc, const vector &in, + vector &out, bool doCareAboutGame ) { out.reserve( in.size() ); FOREACH_CONST( Song*, in, s ) { - if( sc.Matches( *s ) ) + if( sc.Matches( *s ) && (!doCareAboutGame || IsSongPlayable(*s) ) ) { + out.push_back( *s ); } } @@ -963,6 +965,21 @@ bool SongUtil::IsStepsPlayable( Song *pSong, Steps *pSteps ) return find( vpSteps.begin(), vpSteps.end(), pSteps ) != vpSteps.end(); } +bool SongUtil::IsSongPlayable( Song *s ) +{ + const vector & steps = s->GetAllSteps(); + // I'm sure there is a foreach loop, but I don't + FOREACH( Steps*, const_cast&>(steps), step ) + { + if (IsStepsPlayable(s, *step)) + { + return true; + } + } + + return false; +} + bool SongUtil::GetStepsTypeAndDifficultyFromSortOrder( SortOrder so, StepsType &stOut, Difficulty &dcOut ) { switch( so ) diff --git a/src/SongUtil.h b/src/SongUtil.h index 0c0a18043d..5432d455e3 100644 --- a/src/SongUtil.h +++ b/src/SongUtil.h @@ -163,12 +163,25 @@ namespace SongUtil bool ValidateCurrentStepsCredit( const RString &sAnswer, RString &sErrorOut ); void GetAllSongGenres( vector &vsOut ); - void FilterSongs( const SongCriteria &sc, const vector &in, vector &out ); + /** + * @brief Filter the selection of songs to only match certain criteria. + * @param sc the intended song criteria. + * @param in the starting batch of songs. + * @param out the resulting batch. + * @param doCareAboutGame a flag to see if we should only get playable steps. */ + void FilterSongs( const SongCriteria &sc, const vector &in, vector &out, + bool doCareAboutGame = false ); void GetPlayableStepsTypes( const Song *pSong, set &vOut ); void GetPlayableSteps( const Song *pSong, vector &vOut ); bool IsStepsTypePlayable( Song *pSong, StepsType st ); bool IsStepsPlayable( Song *pSong, Steps *pSteps ); + + /** + * @brief Determine if the song has any playable steps in the present game. + * @param s the current song. + * @return true if the song has playable steps, false otherwise. */ + bool IsSongPlayable( Song *s ); bool GetStepsTypeAndDifficultyFromSortOrder( SortOrder so, StepsType &st, Difficulty &dc ); } From 0fa0d425496cb07dd00676c6a4112f284a6ad579 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 8 Jun 2011 23:05:28 -0400 Subject: [PATCH 13/44] Minor updates. The extra padded space is for planning. Going to try to take care of another Pump thing. --- src/Player.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Player.cpp b/src/Player.cpp index 569a9080df..f8582c9a06 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2878,7 +2878,7 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) } else if( CHECKPOINTS_USE_TIME_SIGNATURES ) { - TimeSignatureSegment tSignature = m_Timing->GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) ); + TimeSignatureSegment & tSignature = m_Timing->GetTimeSignatureSegmentAtRow( iLastRowCrossed ); // Most songs are in 4/4 time. The frequency for checking tick counts should reflect that. iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.GetDen() / (tSignature.GetNum() * 4); @@ -2921,8 +2921,11 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) bool bHoldOverlapsRow = iFirstCheckpointOfHold <= r && r <= iLastCheckpointOfHold; if( !bHoldOverlapsRow ) continue; + + viColsWithHold.push_back( iTrack ); + if( tn.HoldResult.fLife > 0 ) { ++iNumHoldsHeldThisRow; From b6bf776716064bd96166e65dd2ebb1663d5aeddd Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 13:46:30 -0400 Subject: [PATCH 14/44] New branch: [notesloader] Time to better unify our files and refactor properly. --- src/GameSoundManager.cpp | 10 ++++++---- src/NotesLoader.cpp | 17 ++++++++++------- src/NotesLoaderSM.h | 8 +++++--- src/NotesLoaderSMA.h | 3 ++- src/NotesLoaderSSC.cpp | 13 +------------ src/NotesLoaderSSC.h | 6 ++++-- src/ScreenGameplaySyncMachine.cpp | 6 ++++-- src/ScreenHowToPlay.cpp | 6 ++++-- src/ScreenServiceAction.cpp | 3 ++- src/Song.cpp | 8 +++++--- src/SongManager.cpp | 9 ++++++--- src/Steps.cpp | 6 ++++-- 12 files changed, 53 insertions(+), 42 deletions(-) diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index a9e71fce24..8b878c50ef 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -142,8 +142,10 @@ static void StartMusic( MusicToPlay &ToPlay ) { LOG->Trace( "Found '%s'", ToPlay.m_sTimingFile.c_str() ); Song song; - if( GetExtension(ToPlay.m_sTimingFile) == ".ssc" && - SSCLoader::LoadFromSSCFile(ToPlay.m_sTimingFile, song) ) + SSCLoader loaderSSC; + SMLoader loaderSM; + if(GetExtension(ToPlay.m_sTimingFile) == ".ssc" && + loaderSSC.LoadFromSSCFile(ToPlay.m_sTimingFile, song) ) { ToPlay.HasTiming = true; ToPlay.m_TimingData = song.m_SongTiming; @@ -152,8 +154,8 @@ static void StartMusic( MusicToPlay &ToPlay ) if( pStepsCabinetLights ) pStepsCabinetLights->GetNoteData( ToPlay.m_LightsData ); } - else if( GetExtension(ToPlay.m_sTimingFile) == ".sm" && - SMLoader::LoadFromSMFile(ToPlay.m_sTimingFile, song) ) + else if(GetExtension(ToPlay.m_sTimingFile) == ".sm" && + loaderSM.LoadFromSMFile(ToPlay.m_sTimingFile, song) ) { ToPlay.HasTiming = true; ToPlay.m_TimingData = song.m_SongTiming; diff --git a/src/NotesLoader.cpp b/src/NotesLoader.cpp index 88f68787aa..983f35cedb 100644 --- a/src/NotesLoader.cpp +++ b/src/NotesLoader.cpp @@ -32,20 +32,23 @@ bool NotesLoader::LoadFromDir( const RString &sPath, Song &out, set &Bl vector list; BlacklistedImages.clear(); - SSCLoader::GetApplicableFiles( sPath, list ); + SSCLoader loaderSSC; + loaderSSC.GetApplicableFiles( sPath, list ); if( !list.empty() ) { - if( !SSCLoader::LoadFromDir( sPath, out ) ) + if( !loaderSSC.LoadFromDir( sPath, out ) ) return false; - SSCLoader::TidyUpData( out, false ); + loaderSSC.TidyUpData( out, false ); return true; } - SMALoader::GetApplicableFiles( sPath, list ); + SMALoader loaderSMA; + loaderSMA.GetApplicableFiles( sPath, list ); if (!list.empty() ) - return SMALoader::LoadFromDir( sPath, out ); - SMLoader::GetApplicableFiles( sPath, list ); + return loaderSMA.LoadFromDir( sPath, out ); + SMLoader loaderSM; + loaderSM.GetApplicableFiles( sPath, list ); if (!list.empty() ) - return SMLoader::LoadFromDir( sPath, out ); + return loaderSM.LoadFromDir( sPath, out ); DWILoader::GetApplicableFiles( sPath, list ); if( !list.empty() ) return DWILoader::LoadFromDir( sPath, out, BlacklistedImages ); diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 94dfdd2dfe..0d947ea28a 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -16,8 +16,9 @@ class TimingData; const float FAST_BPM_WARP = 9999999.f; /** @brief Reads a Song from an .SM file. */ -namespace SMLoader +struct SMLoader { + virtual ~SMLoader() {} void LoadFromSMTokens( RString sStepsType, RString sDescription, RString sDifficulty, RString sMeter, RString sRadarValues, RString sNoteData, Steps &out ); @@ -29,7 +30,8 @@ namespace SMLoader bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); - bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ); + virtual bool LoadFromBGChangesString(BackgroundChange &change, + const RString &sBGChangeExpression ); bool ProcessBPMs( TimingData &, const RString ); @@ -41,7 +43,7 @@ namespace SMLoader const RString &sPath, const RString &sParam ); void ProcessAttacks( Song &out, MsdFile::value_t sParams ); void ProcessInstrumentTracks( Song &out, const RString &sParam ); -} +}; #endif diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index c9e3dfa811..fec87e8fce 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -2,6 +2,7 @@ #define NOTES_LOADER_SMA_H #include "GameConstantsAndTypes.h" +#include "NotesLoaderSM.h" #include "BackgroundUtil.h" class MsdFile; @@ -20,7 +21,7 @@ enum SMALoadingStates }; /** @brief Reads a Song from a .SMA file. */ -namespace SMALoader +struct SMALoader : public SMLoader { void LoadFromSMATokens( RString sStepsType, RString sDescription, diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 04a4fdc167..b9180850ae 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -19,17 +19,6 @@ */ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB -/** - * @brief Attempt to load any background changes in use by this song. - * @param change a reference to the background change. - * @param sBGChangeExpression a reference to the list of changes to be made. - * @return its success or failure. - */ -bool LoadFromBGSSCChangesString( BackgroundChange &change, const RString &sBGChangeExpression ) -{ - return SMLoader::LoadFromBGChangesString( change, sBGChangeExpression ); -} - bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) { vector aFileNames; @@ -421,7 +410,7 @@ bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCach for( unsigned b=0; bGetPathO("ScreenGameplaySyncMachine","music"); // Allow themers to use either a .ssc or .sm file for this. -aj + SSCLoader loaderSSC; + SMLoader loaderSM; if(sFile.Right(4) == ".ssc") - SSCLoader::LoadFromSSCFile( sFile, m_Song ); + loaderSSC.LoadFromSSCFile( sFile, m_Song ); else - SMLoader::LoadFromSMFile( sFile, m_Song ); + loaderSM.LoadFromSMFile( sFile, m_Song ); m_Song.SetSongDir( Dirname(sFile) ); m_Song.TidyUpData(); diff --git a/src/ScreenHowToPlay.cpp b/src/ScreenHowToPlay.cpp index b38848bb7d..64ce65815c 100644 --- a/src/ScreenHowToPlay.cpp +++ b/src/ScreenHowToPlay.cpp @@ -135,10 +135,12 @@ void ScreenHowToPlay::Init() // Allow themers to use either a .ssc or .sm file for this. -aj RString sStepsPath = THEME->GetPathO(m_sName, "steps"); + SSCLoader loaderSSC; + SMLoader loaderSM; if( sStepsPath.Right(4) == ".ssc" ) - SSCLoader::LoadFromSSCFile( sStepsPath, m_Song, false ); + loaderSSC.LoadFromSSCFile( sStepsPath, m_Song, false ); else - SMLoader::LoadFromSMFile( sStepsPath, m_Song, false ); + loaderSM.LoadFromSMFile( sStepsPath, m_Song, false ); m_Song.AddAutoGenNotes(); const Style* pStyle = GAMESTATE->GetCurrentStyle(); diff --git a/src/ScreenServiceAction.cpp b/src/ScreenServiceAction.cpp index 13e1222260..c28086a72c 100644 --- a/src/ScreenServiceAction.cpp +++ b/src/ScreenServiceAction.cpp @@ -197,7 +197,8 @@ static void CopyEdits( const RString &sFromProfileDir, const RString &sToProfile iNumErrored++; // Test whether the song we need for this edit is present and ignore this edit if not present. - if( !SSCLoader::LoadEditFromFile( sFromDir+*i, ProfileSlot_Machine, false ) ) + SSCLoader loaderSSC; + if( !loaderSSC.LoadEditFromFile( sFromDir+*i, ProfileSlot_Machine, false ) ) { iNumIgnored++; continue; diff --git a/src/Song.cpp b/src/Song.cpp index e6196ac12e..d547a02e47 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -235,12 +235,14 @@ bool Song::LoadFromSongDir( RString sDir ) if( bUseCache ) { // LOG->Trace( "Loading '%s' from cache file '%s'.", m_sSongDir.c_str(), GetCacheFilePath().c_str() ); - bool bLoadedFromSSC = SSCLoader::LoadFromSSCFile( sCacheFilePath, *this, true ); + SSCLoader loaderSSC; + bool bLoadedFromSSC = loaderSSC.LoadFromSSCFile( sCacheFilePath, *this, true ); if( !bLoadedFromSSC ) { // load from .sm - SMLoader::LoadFromSMFile( sCacheFilePath, *this, true ); - SMLoader::TidyUpData( *this, true ); + SMLoader loaderSM; + loaderSM.LoadFromSMFile( sCacheFilePath, *this, true ); + loaderSM.TidyUpData( *this, true ); } } else diff --git a/src/SongManager.cpp b/src/SongManager.cpp index 48a7d3c5eb..e25374c739 100644 --- a/src/SongManager.cpp +++ b/src/SongManager.cpp @@ -1655,12 +1655,15 @@ void SongManager::LoadStepEditsFromProfileDir( const RString &sProfileDir, Profi for( int i=0; iWarn( "Couldn't load \"%s\"", m_sFilename.c_str() ); return; From e00b7f36160b9bd04c4c9f94f98e843e034fb81b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 14:01:55 -0400 Subject: [PATCH 15/44] [notesloader] Some refactoring done. --- src/NotesLoaderSM.cpp | 23 +++++++++++++++++++---- src/NotesLoaderSM.h | 29 +++++++++++++++++++++++++++-- src/NotesLoaderSMA.cpp | 33 ++------------------------------- src/NotesLoaderSMA.h | 12 +----------- src/NotesLoaderSSC.cpp | 10 +++++++--- 5 files changed, 56 insertions(+), 51 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index f18c556056..68a0f7d089 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -16,7 +16,22 @@ /** @brief The maximum file size for edits. */ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60KB -void SMLoader::LoadFromSMTokens( +float SMLoader::RowToBeat( RString line, const int rowsPerBeat ) +{ + RString backup = line; + Trim(line, "r"); + Trim(line, "R"); + if( backup != line ) + { + return StringToFloat( line ) / rowsPerBeat; + } + else + { + return StringToFloat( line ); + } +} + +void SMLoader::LoadFromTokens( RString sStepsType, RString sDescription, RString sDifficulty, @@ -34,7 +49,7 @@ void SMLoader::LoadFromSMTokens( Trim( sDifficulty ); Trim( sNoteData ); - // LOG->Trace( "Steps::LoadFromSMTokens()" ); + // LOG->Trace( "Steps::LoadFromTokens()" ); // insert stepstype hacks from GameManager.cpp here? -aj out.m_StepsType = GAMEMAN->StringToStepsType( sStepsType ); @@ -719,7 +734,7 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache } Steps* pNewNotes = out.CreateSteps(); - LoadFromSMTokens( + LoadFromTokens( sParams[1], sParams[2], sParams[3], @@ -853,7 +868,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath return true; Steps* pNewNotes = pSong->CreateSteps(); - LoadFromSMTokens( + LoadFromTokens( sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6], *pNewNotes); diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 0d947ea28a..3c635a2fb8 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -19,8 +19,6 @@ const float FAST_BPM_WARP = 9999999.f; struct SMLoader { virtual ~SMLoader() {} - void LoadFromSMTokens( RString sStepsType, RString sDescription, RString sDifficulty, - RString sMeter, RString sRadarValues, RString sNoteData, Steps &out ); bool LoadFromDir( const RString &sPath, Song &out ); void TidyUpData( Song &song, bool bFromCache ); @@ -43,6 +41,33 @@ struct SMLoader const RString &sPath, const RString &sParam ); void ProcessAttacks( Song &out, MsdFile::value_t sParams ); void ProcessInstrumentTracks( Song &out, const RString &sParam ); + + /** + * @brief Convert a row value to the proper beat value. + * + * This is primarily used for assistance with converting SMA files. + * @param line The line that contains the value. + * @param rowsPerBeat the number of rows per beat according to the original file. + * @return the converted beat value. */ + float RowToBeat(RString line, const int rowsPerBeat); + +protected: + /** + * @brief Process the different tokens we have available to get NoteData. + * @param stepsType The current StepsType. + * @param description The description of the chart. + * @param difficulty The difficulty (in words) of the chart. + * @param meter the difficulty (in numbers) of the chart. + * @param radarValues the calculated radar values. + * @param noteData the note data itself. + * @param out the Steps getting the data. */ + virtual void LoadFromTokens(RString sStepsType, + RString sDescription, + RString sDifficulty, + RString sMeter, + RString sRadarValues, + RString sNoteData, + Steps &out); }; #endif diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index c902b1f103..069724542a 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -39,19 +39,6 @@ bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) return LoadFromSMAFile( sPath + aFileNames[0], out ); } -float SMALoader::RowToBeat( RString sLine, const int iRowsPerBeat ) -{ - if( sLine.find("R") || sLine.find("r") ) - { - sLine = sLine.Left(sLine.size()-1); - return StringToFloat( sLine ) / iRowsPerBeat; - } - else - { - return StringToFloat( sLine ); - } -} - bool SMALoader::ProcessBPMs( TimingData &out, const int iRowsPerBeat, const RString sParam ) { vector arrayBPMChangeExpressions; @@ -391,22 +378,6 @@ void SMALoader::ProcessFakes( TimingData &out, const int iRowsPerBeat, const RSt } } - -void SMALoader::LoadFromSMATokens( - RString sStepsType, - RString sDescription, - RString sDifficulty, - RString sMeter, - RString sRadarValues, - RString sNoteData, - Steps &out -) -{ - SMLoader::LoadFromSMTokens( sStepsType, sDescription, - sDifficulty, sMeter, sRadarValues, - sNoteData, out ); -} - void SMALoader::TidyUpData( Song &song, bool bFromCache ) { SMLoader::TidyUpData( song, bFromCache ); @@ -706,7 +677,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) continue; } - LoadFromSMATokens( + LoadFromTokens( sParams[1], sParams[2], sParams[3], @@ -815,7 +786,7 @@ bool SMALoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat return true; Steps* pNewNotes = pSong->CreateSteps(); - LoadFromSMATokens( + LoadFromTokens( sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6], *pNewNotes); diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index fec87e8fce..31026f5089 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -22,15 +22,7 @@ enum SMALoadingStates /** @brief Reads a Song from a .SMA file. */ struct SMALoader : public SMLoader -{ - void LoadFromSMATokens( RString sStepsType, - RString sDescription, - RString sDifficulty, - RString sMeter, - RString sRadarValues, - RString sNoteData, - Steps &out ); - +{ bool LoadFromDir( const RString &sPath, Song &out ); void TidyUpData( Song &song, bool bFromCache ); @@ -50,8 +42,6 @@ struct SMALoader : public SMLoader void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessFakes( TimingData &out, const int iRowsPerBeat, const RString sParam ); - - float RowToBeat( RString sLine, const int iRowsPerBeat ); }; #endif diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index b9180850ae..54c7e208b5 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -872,9 +872,13 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat else { pNewNotes = pSong->CreateSteps(); - SMLoader::LoadFromSMTokens( - sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6], - *pNewNotes); + LoadFromTokens(sParams[1], + sParams[2], + sParams[3], + sParams[4], + sParams[5], + sParams[6], + *pNewNotes); } pNewNotes->SetLoadedFromProfile( slot ); From d2be04719d2849e69dc0e3b8b654cf177a315ed3 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 14:19:12 -0400 Subject: [PATCH 16/44] [notesloader] More refactoring. --- src/NotesLoaderSM.cpp | 18 ++--- src/NotesLoaderSM.h | 33 ++++++-- src/NotesLoaderSMA.cpp | 177 +---------------------------------------- src/NotesLoaderSMA.h | 3 - 4 files changed, 39 insertions(+), 192 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 68a0f7d089..574dc17fc4 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -186,10 +186,10 @@ void SMLoader::ProcessInstrumentTracks( Song &out, const RString &sParam ) } } -bool SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) +bool SMLoader::ProcessBPMs( TimingData &out, const RString line, const int rowsPerBeat ) { vector arrayBPMChangeExpressions; - split( sParam, ",", arrayBPMChangeExpressions ); + split( line, ",", arrayBPMChangeExpressions ); // prepare storage variables for negative BPMs -> Warps. float negBeat = -1; @@ -211,7 +211,7 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) bNotEmpty = true; - const float fBeat = StringToFloat( arrayBPMChangeValues[0] ); + const float fBeat = RowToBeat( arrayBPMChangeValues[0], rowsPerBeat ); const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); if( fNewBPM < 0.0f ) @@ -257,10 +257,10 @@ bool SMLoader::ProcessBPMs( TimingData &out, const RString sParam ) return bNotEmpty; } -void SMLoader::ProcessStops( TimingData &out, const RString sParam ) +void SMLoader::ProcessStops( TimingData &out, const RString line, const int rowsPerBeat ) { vector arrayFreezeExpressions; - split( sParam, ",", arrayFreezeExpressions ); + split( line, ",", arrayFreezeExpressions ); // Prepare variables for negative stop conversion. float negBeat = -1; @@ -278,7 +278,7 @@ void SMLoader::ProcessStops( TimingData &out, const RString sParam ) continue; } - const float fFreezeBeat = StringToFloat( arrayFreezeValues[0] ); + const float fFreezeBeat = RowToBeat( arrayFreezeValues[0], rowsPerBeat ); const float fFreezeSeconds = StringToFloat( arrayFreezeValues[1] ); // Process the prior stop. @@ -323,10 +323,10 @@ void SMLoader::ProcessStops( TimingData &out, const RString sParam ) } } -void SMLoader::ProcessDelays( TimingData &out, const RString sParam ) +void SMLoader::ProcessDelays( TimingData &out, const RString line, const int rowsPerBeat ) { vector arrayDelayExpressions; - split( sParam, ",", arrayDelayExpressions ); + split( line, ",", arrayDelayExpressions ); for( unsigned f=0; f arrayBPMChangeExpressions; - split( sParam, ",", arrayBPMChangeExpressions ); - - // prepare storage variables for negative BPMs -> Warps. - float negBeat = -1; - float negBPM = 1; - float highspeedBeat = -1; - bool bNotEmpty = false; - - for( unsigned b=0; b arrayBPMChangeValues; - split( arrayBPMChangeExpressions[b], "=", arrayBPMChangeValues ); - // XXX: Hard to tell which file caused this. - if( arrayBPMChangeValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #BPMs value \"%s\" (must have exactly one '='), ignored.", - arrayBPMChangeExpressions[b].c_str() ); - continue; - } - - bNotEmpty = true; - - const float fBeat = RowToBeat( arrayBPMChangeValues[0], iRowsPerBeat ); - const float fNewBPM = StringToFloat( arrayBPMChangeValues[1] ); - - if( fNewBPM < 0.0f ) - { - out.m_bHasNegativeBpms = true; - negBeat = fBeat; - negBPM = fNewBPM; - } - else if( fNewBPM > 0.0f ) - { - // add in a warp. - if( negBPM < 0 ) - { - float endBeat = fBeat + (fNewBPM / -negBPM) * (fBeat - negBeat); - WarpSegment new_seg(negBeat, endBeat - negBeat); - out.AddWarpSegment( new_seg ); - - negBeat = -1; - negBPM = 1; - } - // too fast. make it a warp. - if( fNewBPM > FAST_BPM_WARP ) - { - highspeedBeat = fBeat; - } - else - { - // add in a warp. - if( highspeedBeat > 0 ) - { - WarpSegment new_seg(highspeedBeat, fBeat - highspeedBeat); - out.AddWarpSegment( new_seg ); - highspeedBeat = -1; - } - { - BPMSegment new_seg( BeatToNoteRow( fBeat ), fNewBPM ); - out.AddBPMSegment( new_seg ); - } - } - } - } - - return bNotEmpty; -} - -void SMALoader::ProcessStops( TimingData &out, const int iRowsPerBeat, const RString sParam ) -{ - vector arrayFreezeExpressions; - split( sParam, ",", arrayFreezeExpressions ); - - // Prepare variables for negative stop conversion. - float negBeat = -1; - float negPause = 0; - - for( unsigned f=0; f arrayFreezeValues; - split( arrayFreezeExpressions[f], "=", arrayFreezeValues ); - if( arrayFreezeValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #STOPS value \"%s\" (must have exactly one '='), ignored.", - arrayFreezeExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = RowToBeat( arrayFreezeValues[0], iRowsPerBeat ); - 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 fSkipBeats = negPause / fSecondsPerBeat; - - if( negBeat + fSkipBeats > fFreezeBeat ) - fSkipBeats = fFreezeBeat - negBeat; - - WarpSegment ws( negBeat, fSkipBeats); - out.AddWarpSegment( ws ); - - negBeat = -1; - negPause = 0; - } - - if( fFreezeSeconds < 0.0f ) - { - negBeat = fFreezeBeat; - negPause = -fFreezeSeconds; - } - else if( fFreezeSeconds > 0.0f ) - { - StopSegment ss( BeatToNoteRow(fFreezeBeat), fFreezeSeconds ); - out.AddStopSegment( ss ); - } - - } - - // Process the prior stop if there was one. - if( negPause > 0 ) - { - BPMSegment oldBPM = out.GetBPMSegmentAtRow(BeatToNoteRow(negBeat)); - float fSecondsPerBeat = 60 / oldBPM.GetBPM(); - float fSkipBeats = negPause / fSecondsPerBeat; - - WarpSegment ws( negBeat, fSkipBeats); - out.AddWarpSegment( ws ); - } -} - -void SMALoader::ProcessDelays( TimingData &out, const int iRowsPerBeat, const RString sParam ) -{ - vector arrayDelayExpressions; - split( sParam, ",", arrayDelayExpressions ); - - for( unsigned f=0; f arrayDelayValues; - split( arrayDelayExpressions[f], "=", arrayDelayValues ); - if( arrayDelayValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #DELAYS value \"%s\" (must have exactly one '='), ignored.", - arrayDelayExpressions[f].c_str() ); - continue; - } - - const float fFreezeBeat = RowToBeat( arrayDelayValues[0], iRowsPerBeat ); - const float fFreezeSeconds = StringToFloat( arrayDelayValues[1] ); - - StopSegment new_seg( fFreezeBeat, fFreezeSeconds, true ); - // XXX: Remove Negatives Bug? - new_seg.SetBeat(fFreezeBeat); - new_seg.SetPause(fFreezeSeconds); - - // LOG->Trace( "Adding a delay segment: beat: %f, seconds = %f", new_seg.m_fStartBeat, new_seg.m_fStopSeconds ); - - if(fFreezeSeconds > 0.0f) - out.AddStopSegment( new_seg ); - else - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid delay at beat %f, length %f.", fFreezeBeat, fFreezeSeconds ); - } -} - void SMALoader::ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ) { vector arrayTickcountExpressions; @@ -606,21 +435,21 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) { TimingData &timing = (state == SMA_GETTING_STEP_INFO ? pNewNotes->m_Timing : out.m_SongTiming); - ProcessBPMs( timing, iRowsPerBeat, sParams[1] ); + ProcessBPMs( timing, sParams[1], iRowsPerBeat ); } else if( sValueName=="STOPS" || sValueName=="FREEZES" ) { TimingData &timing = (state == SMA_GETTING_STEP_INFO ? pNewNotes->m_Timing : out.m_SongTiming); - ProcessStops( timing, iRowsPerBeat, sParams[1] ); + ProcessStops( timing, sParams[1], iRowsPerBeat ); } else if( sValueName=="DELAYS" ) { TimingData &timing = (state == SMA_GETTING_STEP_INFO ? pNewNotes->m_Timing : out.m_SongTiming); - ProcessDelays( timing, iRowsPerBeat, sParams[1] ); + ProcessDelays( timing, sParams[1], iRowsPerBeat ); } else if( sValueName=="TICKCOUNT" ) diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 31026f5089..500e3de3f2 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -35,9 +35,6 @@ struct SMALoader : public SMLoader bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ); void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); - bool ProcessBPMs( TimingData &out, const int iRowsPerBeat, const RString sParam ); - void ProcessStops( TimingData &out, const int iRowsPerBeat, const RString sParam ); - void ProcessDelays( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ); From e37fe84d6a6dfdf9e29a916d03b9356466026401 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 14:32:14 -0400 Subject: [PATCH 17/44] [notesloader] Simplify. --- src/NotesLoaderSM.cpp | 27 ++++---- src/NotesLoaderSM.h | 28 ++++++-- src/NotesLoaderSMA.cpp | 148 +---------------------------------------- src/NotesLoaderSMA.h | 7 -- 4 files changed, 36 insertions(+), 174 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 574dc17fc4..bb465057d4 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -94,11 +94,6 @@ void SMLoader::LoadFromTokens( out.TidyUpData(); } -void SMLoader::GetApplicableFiles( const RString &sPath, vector &out ) -{ - GetDirListing( sPath + RString("*.sm"), out ); -} - void SMLoader::ProcessBGChanges( Song &out, const RString &sValueName, const RString &sPath, const RString &sParam ) { BackgroundLayer iLayer = BACKGROUND_LAYER_1; @@ -357,10 +352,10 @@ void SMLoader::ProcessDelays( TimingData &out, const RString line, const int row } } -void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) +void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const int rowsPerBeat ) { vector vs1; - split( sParam, ",", vs1 ); + split( line, ",", vs1 ); FOREACH_CONST( RString, vs1, s1 ) { @@ -373,9 +368,9 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) continue; } - const float fBeat = StringToFloat( vs2[0] ); + const float fBeat = RowToBeat( vs2[0], rowsPerBeat ); - TimeSignatureSegment seg( BeatToNoteRow( fBeat ), StringToInt( vs2[1] ), StringToInt( vs2[2] )); + TimeSignatureSegment seg( fBeat, StringToInt( vs2[1] ), StringToInt( vs2[2] )); if( fBeat < 0 ) { @@ -399,10 +394,10 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) } } -void SMLoader::ProcessTickcounts( TimingData &out, const RString sParam ) +void SMLoader::ProcessTickcounts( TimingData &out, const RString line, const int rowsPerBeat ) { vector arrayTickcountExpressions; - split( sParam, ",", arrayTickcountExpressions ); + split( line, ",", arrayTickcountExpressions ); for( unsigned f=0; f aBGChangeValues; @@ -896,6 +892,11 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath } +void SMLoader::GetApplicableFiles( const RString &sPath, vector &out ) +{ + GetDirListing( sPath + RString("*.sm"), out ); +} + void SMLoader::TidyUpData( Song &song, bool bFromCache ) { /* diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 21b5e20398..a3da6ecde1 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -21,13 +21,13 @@ struct SMLoader virtual ~SMLoader() {} bool LoadFromDir( const RString &sPath, Song &out ); - void TidyUpData( Song &song, bool bFromCache ); + virtual void TidyUpData( Song &song, bool bFromCache ); bool LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache = false ); void GetApplicableFiles( const RString &sPath, vector &out ); - bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); - bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); - bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); + virtual bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); + virtual bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); + virtual bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); virtual bool LoadFromBGChangesString(BackgroundChange &change, const RString &sBGChangeExpression ); @@ -49,15 +49,29 @@ struct SMLoader const RString line, const int rowsPerBeat = -1); /** - * @brief Process the Stop Segments from the string. + * @brief Process the Delay Segments from the string. * @param out the TimingData being modified. * @param line the string in question. * @param rowsPerBeat the number of rows per beat for this purpose. */ void ProcessDelays(TimingData & out, const RString line, const int rowsPerBeat = -1); - void ProcessTimeSignatures( TimingData & out, const RString line ); - void ProcessTickcounts( TimingData & out, const RString line ); + /** + * @brief Process the Time Signature Segments from the string. + * @param out the TimingData being modified. + * @param line the string in question. + * @param rowsPerBeat the number of rows per beat for this purpose. */ + void ProcessTimeSignatures(TimingData & out, + const RString line, + const int rowsPerBeat = -1); + /** + * @brief Process the Tickcount Segments from the string. + * @param out the TimingData being modified. + * @param line the string in question. + * @param rowsPerBeat the number of rows per beat for this purpose. */ + void ProcessTickcounts(TimingData & out, + const RString line, + const int rowsPerBeat = -1); void ProcessBGChanges( Song &out, const RString &sValueName, const RString &sPath, const RString &sParam ); void ProcessAttacks( Song &out, MsdFile::value_t sParams ); diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index d11600ba4b..c5cf98952d 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -19,12 +19,6 @@ */ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB -bool SMALoader::LoadFromBGChangesString( BackgroundChange &change, - const RString &sBGChangeExpression ) -{ - return SMLoader::LoadFromBGChangesString(change, sBGChangeExpression); -} - bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) { vector aFileNames; @@ -39,31 +33,6 @@ bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) return LoadFromSMAFile( sPath + aFileNames[0], out ); } -void SMALoader::ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ) -{ - vector arrayTickcountExpressions; - split( sParam, ",", arrayTickcountExpressions ); - - for( unsigned f=0; f arrayTickcountValues; - split( arrayTickcountExpressions[f], "=", arrayTickcountValues ); - if( arrayTickcountValues.size() != 2 ) - { - // XXX: Hard to tell which file caused this. - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #TICKCOUNTS value \"%s\" (must have exactly one '='), ignored.", - arrayTickcountExpressions[f].c_str() ); - continue; - } - - const float fTickcountBeat = RowToBeat( arrayTickcountValues[0], iRowsPerBeat ); - int iTicks = clamp(atoi( arrayTickcountValues[1] ), 0, ROWS_PER_BEAT); - - TickcountSegment new_seg( BeatToNoteRow(fTickcountBeat), iTicks ); - out.AddTickcountSegment( new_seg ); - } -} - void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ) { vector arrayMultiplierExpressions; @@ -207,11 +176,6 @@ void SMALoader::ProcessFakes( TimingData &out, const int iRowsPerBeat, const RSt } } -void SMALoader::TidyUpData( Song &song, bool bFromCache ) -{ - SMLoader::TidyUpData( song, bFromCache ); -} - bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) { LOG->Trace( "Song::LoadFromSMAFile(%s)", sPath.c_str() ); @@ -456,7 +420,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) { TimingData &timing = (state == SMA_GETTING_STEP_INFO ? pNewNotes->m_Timing : out.m_SongTiming); - ProcessTickcounts( timing, iRowsPerBeat, sParams[1] ); + ProcessTickcounts( timing, sParams[1], iRowsPerBeat ); } else if( sValueName=="SPEED" ) @@ -532,116 +496,6 @@ void SMALoader::GetApplicableFiles( const RString &sPath, vector &out ) GetDirListing( sPath + RString("*.sma"), out ); } -bool SMALoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ) -{ - LOG->Trace( "SMALoader::LoadEditFromFile(%s)", sEditFilePath.c_str() ); - - int iBytes = FILEMAN->GetFileSizeInBytes( sEditFilePath ); - if( iBytes > MAX_EDIT_STEPS_SIZE_BYTES ) - { - LOG->UserLog( "Edit file", sEditFilePath, "is unreasonably large. It won't be loaded." ); - return false; - } - - MsdFile msd; - if( !msd.ReadFile( sEditFilePath, true ) ) // unescape - { - LOG->UserLog( "Edit file", sEditFilePath, "couldn't be opened: %s", msd.GetError().c_str() ); - return false; - } - - return LoadEditFromMsd( msd, sEditFilePath, slot, bAddStepsToSong ); -} - -bool SMALoader::LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ) -{ - MsdFile msd; - msd.ReadFromString( sBuffer, true ); // unescape - return LoadEditFromMsd( msd, sEditFilePath, slot, true ); -} - -bool SMALoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ) -{ - Song* pSong = NULL; - - for( unsigned i=0; iUserLog( "Edit file", sEditFilePath, "has more than one #SONG tag." ); - return false; - } - - RString sSongFullTitle = sParams[1]; - sSongFullTitle.Replace( '\\', '/' ); - - pSong = SONGMAN->FindSong( sSongFullTitle ); - if( pSong == NULL ) - { - LOG->UserLog( "Edit file", sEditFilePath, "requires a song \"%s\" that isn't present.", sSongFullTitle.c_str() ); - return false; - } - - if( pSong->GetNumStepsLoadedFromProfile(slot) >= MAX_EDITS_PER_SONG_PER_PROFILE ) - { - LOG->UserLog( "Song file", sSongFullTitle, "already has the maximum number of edits allowed for ProfileSlotP%d.", slot+1 ); - return false; - } - } - - else if( sValueName=="NOTES" ) - { - if( pSong == NULL ) - { - LOG->UserLog( "Edit file", sEditFilePath, "doesn't have a #SONG tag preceeding the first #NOTES tag." ); - return false; - } - - if( iNumParams < 7 ) - { - LOG->UserLog( "Edit file", sEditFilePath, "has %d fields in a #NOTES tag, but should have at least 7.", iNumParams ); - continue; - } - - if( !bAddStepsToSong ) - return true; - - Steps* pNewNotes = pSong->CreateSteps(); - LoadFromTokens( - sParams[1], sParams[2], sParams[3], sParams[4], sParams[5], sParams[6], - *pNewNotes); - - pNewNotes->SetLoadedFromProfile( slot ); - pNewNotes->SetDifficulty( Difficulty_Edit ); - pNewNotes->SetFilename( sEditFilePath ); - - if( pSong->IsEditAlreadyLoaded(pNewNotes) ) - { - LOG->UserLog( "Edit file", sEditFilePath, "is a duplicate of another edit that was already loaded." ); - SAFE_DELETE( pNewNotes ); - return false; - } - - pSong->AddSteps( pNewNotes ); - return true; // Only allow one Steps per edit file! - } - else - { - LOG->UserLog( "Edit file", sEditFilePath, "has an unexpected value \"%s\".", sValueName.c_str() ); - } - } - - return true; -} - /** * @file * @author Aldo Fregoso, Jason Felds (c) 2009-2011 diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 500e3de3f2..494646026e 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -24,18 +24,11 @@ enum SMALoadingStates struct SMALoader : public SMLoader { bool LoadFromDir( const RString &sPath, Song &out ); - void TidyUpData( Song &song, bool bFromCache ); bool LoadFromSMAFile( const RString &sPath, Song &out ); void GetApplicableFiles( const RString &sPath, vector &out ); - bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); - bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); - bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); - bool LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ); - void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); - void ProcessTickcounts( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ); void ProcessFakes( TimingData &out, const int iRowsPerBeat, const RString sParam ); From 48eefc770010ae40b8373549e310763bc4076c92 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 14:45:30 -0400 Subject: [PATCH 18/44] [notesloader] Have common ground. --- src/NotesLoaderSM.cpp | 100 ++++++++++++++++++++++++++++++----------- src/NotesLoaderSM.h | 21 ++++++++- src/NotesLoaderSMA.cpp | 13 ++---- src/NotesLoaderSMA.h | 2 +- src/NotesLoaderSSC.cpp | 56 +---------------------- src/NotesLoaderSSC.h | 9 +--- 6 files changed, 101 insertions(+), 100 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index bb465057d4..bdb8a332ea 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -16,6 +16,33 @@ /** @brief The maximum file size for edits. */ const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60KB +bool SMLoader::LoadFromDir( const RString &sPath, Song &out ) +{ + vector aFileNames; + GetApplicableFiles( sPath, aFileNames ); + + if( aFileNames.size() > 1 ) + { + LOG->UserLog( "Song", sPath, "has more than one SM file. There can be only one (unless you are using TougaKiryuu's AnimeMix files somehow, which assume a different version of StepMania)!" ); + return false; + /* + for( unsigned i=0; i= 1 ); + + return LoadFromSMFile( sPath + aFileNames[0], out ); +} + float SMLoader::RowToBeat( RString line, const int rowsPerBeat ) { RString backup = line; @@ -419,6 +446,52 @@ void SMLoader::ProcessTickcounts( TimingData &out, const RString line, const int } } +void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int rowsPerBeat ) +{ + vector vs1; + split( line, ",", vs1 ); + + FOREACH_CONST( RString, vs1, s1 ) + { + vector 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", "(UNKNOWN)", "has an speed change with %i values.", (int)vs2.size() ); + continue; + } + + const float fBeat = RowToBeat( vs2[0], rowsPerBeat ); + + SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] )); + seg.SetUnit(StringToInt(vs2[3])); + + if( fBeat < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f.", fBeat ); + continue; + } + + if( seg.GetLength() < 0 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() ); + continue; + } + + out.AddSpeedSegment( seg ); + } +} bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ) { @@ -754,33 +827,6 @@ bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache return true; } -bool SMLoader::LoadFromDir( const RString &sPath, Song &out ) -{ - vector aFileNames; - GetApplicableFiles( sPath, aFileNames ); - - if( aFileNames.size() > 1 ) - { - LOG->UserLog( "Song", sPath, "has more than one SM file. There can be only one (unless you are using TougaKiryuu's AnimeMix files somehow, which assume a different version of StepMania)!" ); - return false; - /* - for( unsigned i=0; i= 1 ); - - return LoadFromSMFile( sPath + aFileNames[0], out ); -} - bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ) { LOG->Trace( "SMLoader::LoadEditFromFile(%s)", sEditFilePath.c_str() ); diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index a3da6ecde1..e63e80acdb 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -21,6 +21,11 @@ struct SMLoader virtual ~SMLoader() {} bool LoadFromDir( const RString &sPath, Song &out ); + /** + * @brief Perform some cleanup on the loaded song. + * @param song a reference to the song that may need cleaning up. + * @param bFromCache a flag to determine if this song is loaded from a cache file. + */ virtual void TidyUpData( Song &song, bool bFromCache ); bool LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache = false ); @@ -72,7 +77,21 @@ struct SMLoader void ProcessTickcounts(TimingData & out, const RString line, const int rowsPerBeat = -1); - void ProcessBGChanges( Song &out, const RString &sValueName, + + /** + * @brief Process the Speed Segments from the string. + * @param out the TimingData being modified. + * @param line the string in question. + * @param rowsPerBeat the number of rows per beat for this purpose. */ + virtual void ProcessSpeeds(TimingData & out, + const RString line, + const int rowsPerBeat = -1); + + virtual void ProcessCombos(TimingData & out, + const RString line, + const int rowsPerBeat = -1) {} + + virtual void ProcessBGChanges( Song &out, const RString &sValueName, const RString &sPath, const RString &sParam ); void ProcessAttacks( Song &out, MsdFile::value_t sParams ); void ProcessInstrumentTracks( Song &out, const RString &sParam ); diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index c5cf98952d..f5b726626f 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -91,15 +91,10 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) } } -float BeatToSeconds(float fromBeat, RString toSomething) -{ - return 0; -} - -void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ) +void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int rowsPerBeat ) { vector vs1; - split( sParam, ",", vs1 ); + split( line, ",", vs1 ); FOREACH_CONST( RString, vs1, s1 ) { @@ -120,7 +115,7 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS continue; } - const float fBeat = RowToBeat( vs2[0], iRowsPerBeat ); + const float fBeat = RowToBeat( vs2[0], rowsPerBeat ); RString backup = vs2[2]; Trim(vs2[2], "s"); @@ -429,7 +424,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) ? pNewNotes->m_Timing : out.m_SongTiming); RString tmp = sParams[1]; Trim( tmp ); - ProcessSpeeds( timing, iRowsPerBeat, tmp ); + ProcessSpeeds( timing, tmp, iRowsPerBeat ); } else if( sValueName=="MULTIPLIER" ) diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 494646026e..a38a07752f 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -30,7 +30,7 @@ struct SMALoader : public SMLoader void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); - void ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RString sParam ); + virtual void ProcessSpeeds( TimingData &out, const RString line, const int rowsPerBeat ); void ProcessFakes( TimingData &out, const int iRowsPerBeat, const RString sParam ); }; diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 54c7e208b5..1482054bb9 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -97,10 +97,10 @@ void SSCLoader::ProcessLabels( TimingData &out, const RString sParam ) } } -void SSCLoader::ProcessCombos( TimingData &out, const RString sParam ) +void SSCLoader::ProcessCombos( TimingData &out, const RString line, const int rowsPerBeat ) { vector arrayComboExpressions; - split( sParam, ",", arrayComboExpressions ); + split( line, ",", arrayComboExpressions ); for( unsigned f=0; f vs1; - split( sParam, ",", vs1 ); - - FOREACH_CONST( RString, vs1, s1 ) - { - vector 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", "(UNKNOWN)", "has an speed change with %i values.", (int)vs2.size() ); - continue; - } - - const float fBeat = StringToFloat( vs2[0] ); - - SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] )); - seg.SetUnit(StringToInt(vs2[3])); - - if( fBeat < 0 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f.", fBeat ); - continue; - } - - if( seg.GetLength() < 0 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() ); - continue; - } - - out.AddSpeedSegment( seg ); - } -} - void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam ) { vector vs1; @@ -906,11 +859,6 @@ bool SSCLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePat return bSSCFormat; } -void SSCLoader::TidyUpData( Song &song, bool bFromCache ) -{ - SMLoader::TidyUpData(song, bFromCache); -} - /* * (c) 2011 Jason Felds * All rights reserved. diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index d3ffe6c12c..29cf560458 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -70,18 +70,11 @@ struct SSCLoader : public SMLoader * @return its success or failure. */ bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); - /** - * @brief Perform some cleanup on the loaded song. - * @param song a reference to the song that may need cleaning up. - * @param bFromCache a flag to determine if this song is loaded from a cache file. - */ - void TidyUpData( Song &song, bool bFromCache ); void ProcessWarps( TimingData &, const RString, const float ); void ProcessLabels( TimingData &, const RString ); - void ProcessCombos( TimingData &, const RString ); - void ProcessSpeeds( TimingData &, const RString ); + virtual void ProcessCombos( TimingData &, const RString, const int = -1 ); void ProcessScrolls( TimingData &, const RString ); void ProcessFakes( TimingData &, const RString ); }; From dec615a2e7c8d10b9d8a499d562b429cbd178903 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 14:53:58 -0400 Subject: [PATCH 19/44] [notesloader] Handle fakes on their own. --- src/NotesLoaderSM.cpp | 29 +++++++++++++++++++++++++++++ src/NotesLoaderSM.h | 9 +++++++++ src/NotesLoaderSMA.cpp | 31 +------------------------------ src/NotesLoaderSMA.h | 1 - src/NotesLoaderSSC.cpp | 29 ----------------------------- src/NotesLoaderSSC.h | 1 - 6 files changed, 39 insertions(+), 61 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index bdb8a332ea..859ff6951e 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -493,6 +493,35 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row } } +void SMLoader::ProcessFakes( TimingData &out, const RString line, const int rowsPerBeat ) +{ + vector arrayFakeExpressions; + split( line, ",", arrayFakeExpressions ); + + for( unsigned b=0; b arrayFakeValues; + split( arrayFakeExpressions[b], "=", arrayFakeValues ); + // XXX: Hard to tell which file caused this. + if( arrayFakeValues.size() != 2 ) + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #FAKES value \"%s\" (must have exactly one '='), ignored.", + arrayFakeExpressions[b].c_str() ); + continue; + } + + const float fBeat = RowToBeat( arrayFakeValues[0], rowsPerBeat ); + const float fNewBeat = StringToFloat( arrayFakeValues[1] ); + + if(fNewBeat > 0) + out.AddFakeSegment( FakeSegment(fBeat, fNewBeat) ); + else + { + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Fake at beat %f, BPM %f.", fBeat, fNewBeat ); + } + } +} + bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString &sBGChangeExpression ) { vector aBGChangeValues; diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index e63e80acdb..0a85448022 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -91,6 +91,15 @@ struct SMLoader const RString line, const int rowsPerBeat = -1) {} + /** + * @brief Process the Fake Segments from the string. + * @param out the TimingData being modified. + * @param line the string in question. + * @param rowsPerBeat the number of rows per beat for this purpose. */ + virtual void ProcessFakes(TimingData & out, + const RString line, + const int rowsPerBeat = -1); + virtual void ProcessBGChanges( Song &out, const RString &sValueName, const RString &sPath, const RString &sParam ); void ProcessAttacks( Song &out, MsdFile::value_t sParams ); diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index f5b726626f..aa148933bc 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -142,35 +142,6 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro } } -void SMALoader::ProcessFakes( TimingData &out, const int iRowsPerBeat, const RString sParam ) -{ - vector arrayFakeExpressions; - split( sParam, ",", arrayFakeExpressions ); - - for( unsigned b=0; b arrayFakeValues; - split( arrayFakeExpressions[b], "=", arrayFakeValues ); - // XXX: Hard to tell which file caused this. - if( arrayFakeValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #FAKES value \"%s\" (must have exactly one '='), ignored.", - arrayFakeExpressions[b].c_str() ); - continue; - } - - const float fBeat = RowToBeat( arrayFakeValues[0], iRowsPerBeat ); - const float fNewBeat = StringToFloat( arrayFakeValues[1] ); - - if(fNewBeat > 0) - out.AddFakeSegment( FakeSegment(fBeat, fNewBeat) ); - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Fake at beat %f, BPM %f.", fBeat, fNewBeat ); - } - } -} - bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) { LOG->Trace( "Song::LoadFromSMAFile(%s)", sPath.c_str() ); @@ -438,7 +409,7 @@ bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) { TimingData &timing = (state == SMA_GETTING_STEP_INFO ? pNewNotes->m_Timing : out.m_SongTiming); - ProcessFakes( timing, iRowsPerBeat, sParams[1] ); + ProcessFakes( timing, sParams[1], iRowsPerBeat ); } else if( sValueName=="METERTYPE" ) diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index a38a07752f..223b489571 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -31,7 +31,6 @@ struct SMALoader : public SMLoader void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); virtual void ProcessSpeeds( TimingData &out, const RString line, const int rowsPerBeat ); - void ProcessFakes( TimingData &out, const int iRowsPerBeat, const RString sParam ); }; #endif diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 1482054bb9..f4bce60d21 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -149,35 +149,6 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam ) } } -void SSCLoader::ProcessFakes( TimingData &out, const RString sParam ) -{ - vector arrayFakeExpressions; - split( sParam, ",", arrayFakeExpressions ); - - for( unsigned b=0; b arrayFakeValues; - split( arrayFakeExpressions[b], "=", arrayFakeValues ); - // XXX: Hard to tell which file caused this. - if( arrayFakeValues.size() != 2 ) - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid #FAKES value \"%s\" (must have exactly one '='), ignored.", - arrayFakeExpressions[b].c_str() ); - continue; - } - - const float fBeat = StringToFloat( arrayFakeValues[0] ); - const float fNewBeat = StringToFloat( arrayFakeValues[1] ); - - if(fNewBeat > 0) - out.AddFakeSegment( FakeSegment(fBeat, fNewBeat) ); - else - { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid Fake at beat %f, BPM %f.", fBeat, fNewBeat ); - } - } -} - bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache ) { diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index 29cf560458..88fc17842a 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -76,7 +76,6 @@ struct SSCLoader : public SMLoader void ProcessLabels( TimingData &, const RString ); virtual void ProcessCombos( TimingData &, const RString, const int = -1 ); void ProcessScrolls( TimingData &, const RString ); - void ProcessFakes( TimingData &, const RString ); }; #endif From 68fd21fdc8159a973c1a5ee533f0d5a3b9b5d2f5 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 15:14:47 -0400 Subject: [PATCH 20/44] [notesloader] More cleanup. Need to test something in gameplay before continuing. --- src/NotesLoaderSM.cpp | 10 ---------- src/NotesLoaderSM.h | 7 ++++++- src/NotesLoaderSMA.h | 12 +++++++++++- src/NotesLoaderSSC.cpp | 3 +-- src/NotesLoaderSSC.h | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 859ff6951e..e75e1c5998 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -25,19 +25,9 @@ bool SMLoader::LoadFromDir( const RString &sPath, Song &out ) { LOG->UserLog( "Song", sPath, "has more than one SM file. There can be only one (unless you are using TougaKiryuu's AnimeMix files somehow, which assume a different version of StepMania)!" ); return false; - /* - for( unsigned i=0; i= 1 ); return LoadFromSMFile( sPath + aFileNames[0], out ); diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 0a85448022..4a1f3bc7c0 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -29,7 +29,12 @@ struct SMLoader virtual void TidyUpData( Song &song, bool bFromCache ); bool LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache = false ); - void GetApplicableFiles( const RString &sPath, vector &out ); + /** + * @brief Retrieve the list of .sm files. + * @param sPath a const reference to the path on the hard drive to check. + * @param out a vector of files found in the path. + */ + virtual void GetApplicableFiles( const RString &sPath, vector &out ); virtual bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); virtual bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot ); virtual bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ); diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 223b489571..040b1e9d38 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -26,10 +26,20 @@ struct SMALoader : public SMLoader bool LoadFromDir( const RString &sPath, Song &out ); bool LoadFromSMAFile( const RString &sPath, Song &out ); - void GetApplicableFiles( const RString &sPath, vector &out ); + /** + * @brief Retrieve the list of .sma files. + * @param sPath a const reference to the path on the hard drive to check. + * @param out a vector of files found in the path. + */ + virtual void GetApplicableFiles( const RString &sPath, vector &out ); void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); + /** + * @brief Process the Speed Segments from the string. + * @param out the TimingData being modified. + * @param line the string in question. + * @param rowsPerBeat the number of rows per beat for this purpose. */ virtual void ProcessSpeeds( TimingData &out, const RString line, const int rowsPerBeat ); }; diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index f4bce60d21..b5644b8243 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -30,8 +30,7 @@ bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) return false; } - ASSERT( aFileNames.size() == 1 ); // Ensure one was found entirely. - + ASSERT( aFileNames.size() == 1 ); return LoadFromSSCFile( sPath + aFileNames[0], out ); } diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index 88fc17842a..7a5cd3f172 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -52,7 +52,7 @@ struct SSCLoader : public SMLoader * @param sPath a const reference to the path on the hard drive to check. * @param out a vector of files found in the path. */ - void GetApplicableFiles( const RString &sPath, vector &out ); + virtual void GetApplicableFiles( const RString &sPath, vector &out ); /** * @brief Attempt to load an edit from the hard drive. * @param sEditFilePath a path on the hard drive to check. From 21ca14d5898a4c772de37b6a4dfd7c103adf8c6d Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 18:12:38 -0400 Subject: [PATCH 21/44] Fix F11/F12 split timing sync adjuster. --- Docs/Changelog_sm5.txt | 4 ++++ src/ScreenSyncOverlay.cpp | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index 0739778269..cce227e55d 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,6 +8,10 @@ ________________________________________________________________________________ StepMania 5.0 Preview 2 | 20110??? -------------------------------------------------------------------------------- +2011/06/09 +* [ScreenSyncOverlay] Ensure that F11 / F12 work with all charts due to Split + Timing. [Wolfman2000] + 2011/06/08 ---------- * Any notes in a fake segment or warp segment are completely ignored for diff --git a/src/ScreenSyncOverlay.cpp b/src/ScreenSyncOverlay.cpp index 3596c91e70..e91cf6569d 100644 --- a/src/ScreenSyncOverlay.cpp +++ b/src/ScreenSyncOverlay.cpp @@ -253,7 +253,14 @@ bool ScreenSyncOverlay::OverlayInput( const InputEventPlus &input ) case ChangeSongOffset: if( GAMESTATE->m_pCurSong != NULL ) + { GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fDelta; + const vector& vpSteps = GAMESTATE->m_pCurSong->GetAllSteps(); + FOREACH( Steps*, const_cast&>(vpSteps), s ) + { + (*s)->m_Timing.m_fBeat0OffsetInSeconds += fDelta; + } + } break; } } From 11dfc1dd8baa9760f0c9206f56bbe6da9c563d97 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 18:16:23 -0400 Subject: [PATCH 22/44] Deprecate Lua's HasNegativeBPMs(). Use HasWarps() instead. Hmm...is there a way to mark the XML with a deprecated tag? --- src/TimingData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 1e57e455ac..f65c00122e 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -1746,7 +1746,7 @@ public: LuaHelpers::CreateTableFromArray(fBPMs, L); return 1; } - static int HasNegativeBPMs( T* p, lua_State *L ) { lua_pushboolean(L, p->m_bHasNegativeBpms); return 1; } + static int HasNegativeBPMs( T* p, lua_State *L ) { lua_pushboolean(L, p->HasWarps()); return 1; } // formerly in Song.cpp in sm-ssc private beta 1.x: static int GetBPMAtBeat( T* p, lua_State *L ) { lua_pushnumber(L, p->GetBPMAtBeat(FArg(1))); return 1; } static int GetBeatFromElapsedTime( T* p, lua_State *L ) { lua_pushnumber(L, p->GetBeatFromElapsedTime(FArg(1))); return 1; } From 1e296ed0bf27fcd37ca99ff7d9282e701a5ec85c Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 21:27:47 -0400 Subject: [PATCH 23/44] [notesloader] More virtuals. --- src/GameSoundManager.cpp | 4 ++-- src/NotesLoaderSM.cpp | 4 ++-- src/NotesLoaderSM.h | 9 ++++++++- src/NotesLoaderSMA.cpp | 4 ++-- src/NotesLoaderSMA.h | 2 +- src/NotesLoaderSSC.cpp | 4 ++-- src/NotesLoaderSSC.h | 2 +- src/ScreenGameplaySyncMachine.cpp | 4 ++-- src/ScreenHowToPlay.cpp | 4 ++-- src/Song.cpp | 4 ++-- src/Steps.cpp | 4 ++-- 11 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index 8b878c50ef..27933d5d82 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -145,7 +145,7 @@ static void StartMusic( MusicToPlay &ToPlay ) SSCLoader loaderSSC; SMLoader loaderSM; if(GetExtension(ToPlay.m_sTimingFile) == ".ssc" && - loaderSSC.LoadFromSSCFile(ToPlay.m_sTimingFile, song) ) + loaderSSC.LoadFromSimfile(ToPlay.m_sTimingFile, song) ) { ToPlay.HasTiming = true; ToPlay.m_TimingData = song.m_SongTiming; @@ -155,7 +155,7 @@ static void StartMusic( MusicToPlay &ToPlay ) pStepsCabinetLights->GetNoteData( ToPlay.m_LightsData ); } else if(GetExtension(ToPlay.m_sTimingFile) == ".sm" && - loaderSM.LoadFromSMFile(ToPlay.m_sTimingFile, song) ) + loaderSM.LoadFromSimfile(ToPlay.m_sTimingFile, song) ) { ToPlay.HasTiming = true; ToPlay.m_TimingData = song.m_SongTiming; diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index e75e1c5998..4e1b073a9b 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -30,7 +30,7 @@ bool SMLoader::LoadFromDir( const RString &sPath, Song &out ) ASSERT( aFileNames.size() == 1 ); //ASSERT( aFileNames.size() >= 1 ); - return LoadFromSMFile( sPath + aFileNames[0], out ); + return LoadFromSimfile( sPath + aFileNames[0], out ); } float SMLoader::RowToBeat( RString line, const int rowsPerBeat ) @@ -598,7 +598,7 @@ bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString return aBGChangeValues.size() >= 2; } -bool SMLoader::LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache ) +bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache ) { LOG->Trace( "Song::LoadFromSMFile(%s)", sPath.c_str() ); diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 4a1f3bc7c0..f2c964a43a 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -28,7 +28,14 @@ struct SMLoader */ virtual void TidyUpData( Song &song, bool bFromCache ); - bool LoadFromSMFile( const RString &sPath, Song &out, bool bFromCache = false ); + /** + * @brief Attempt to load the specified sm file. + * @param sPath a const reference to the path on the hard drive to check. + * @param out a reference to the Song that will retrieve the song information. + * @param bFromCache a check to see if we are getting certain information from the cache file. + * @return its success or failure. + */ + virtual bool LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache = false ); /** * @brief Retrieve the list of .sm files. * @param sPath a const reference to the path on the hard drive to check. diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index aa148933bc..a52c7db68b 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -30,7 +30,7 @@ bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) return false; } ASSERT( aFileNames.size() == 1 ); - return LoadFromSMAFile( sPath + aFileNames[0], out ); + return LoadFromSimfile( sPath + aFileNames[0], out ); } void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ) @@ -142,7 +142,7 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro } } -bool SMALoader::LoadFromSMAFile( const RString &sPath, Song &out ) +bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache ) { LOG->Trace( "Song::LoadFromSMAFile(%s)", sPath.c_str() ); diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 040b1e9d38..71d307642b 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -25,7 +25,7 @@ struct SMALoader : public SMLoader { bool LoadFromDir( const RString &sPath, Song &out ); - bool LoadFromSMAFile( const RString &sPath, Song &out ); + virtual bool LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache = false ); /** * @brief Retrieve the list of .sma files. * @param sPath a const reference to the path on the hard drive to check. diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index b5644b8243..ddac4631fe 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -31,7 +31,7 @@ bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) } ASSERT( aFileNames.size() == 1 ); - return LoadFromSSCFile( sPath + aFileNames[0], out ); + return LoadFromSimfile( sPath + aFileNames[0], out ); } void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float fVersion ) @@ -149,7 +149,7 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam ) } -bool SSCLoader::LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache ) +bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache ) { LOG->Trace( "Song::LoadFromSSCFile(%s)", sPath.c_str() ); diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index 7a5cd3f172..e535f8ac48 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -46,7 +46,7 @@ struct SSCLoader : public SMLoader * @param bFromCache a check to see if we are getting certain information from the cache file. * @return its success or failure. */ - bool LoadFromSSCFile( const RString &sPath, Song &out, bool bFromCache = false ); + virtual bool LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache = false ); /** * @brief Retrieve the list of .ssc files. * @param sPath a const reference to the path on the hard drive to check. diff --git a/src/ScreenGameplaySyncMachine.cpp b/src/ScreenGameplaySyncMachine.cpp index f1202c3c13..3f72cd1976 100644 --- a/src/ScreenGameplaySyncMachine.cpp +++ b/src/ScreenGameplaySyncMachine.cpp @@ -24,9 +24,9 @@ void ScreenGameplaySyncMachine::Init() SSCLoader loaderSSC; SMLoader loaderSM; if(sFile.Right(4) == ".ssc") - loaderSSC.LoadFromSSCFile( sFile, m_Song ); + loaderSSC.LoadFromSimfile( sFile, m_Song ); else - loaderSM.LoadFromSMFile( sFile, m_Song ); + loaderSM.LoadFromSimfile( sFile, m_Song ); m_Song.SetSongDir( Dirname(sFile) ); m_Song.TidyUpData(); diff --git a/src/ScreenHowToPlay.cpp b/src/ScreenHowToPlay.cpp index 64ce65815c..bb5e021db2 100644 --- a/src/ScreenHowToPlay.cpp +++ b/src/ScreenHowToPlay.cpp @@ -138,9 +138,9 @@ void ScreenHowToPlay::Init() SSCLoader loaderSSC; SMLoader loaderSM; if( sStepsPath.Right(4) == ".ssc" ) - loaderSSC.LoadFromSSCFile( sStepsPath, m_Song, false ); + loaderSSC.LoadFromSimfile( sStepsPath, m_Song, false ); else - loaderSM.LoadFromSMFile( sStepsPath, m_Song, false ); + loaderSM.LoadFromSimfile( sStepsPath, m_Song, false ); m_Song.AddAutoGenNotes(); const Style* pStyle = GAMESTATE->GetCurrentStyle(); diff --git a/src/Song.cpp b/src/Song.cpp index d547a02e47..5bb35928f5 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -236,12 +236,12 @@ bool Song::LoadFromSongDir( RString sDir ) { // LOG->Trace( "Loading '%s' from cache file '%s'.", m_sSongDir.c_str(), GetCacheFilePath().c_str() ); SSCLoader loaderSSC; - bool bLoadedFromSSC = loaderSSC.LoadFromSSCFile( sCacheFilePath, *this, true ); + bool bLoadedFromSSC = loaderSSC.LoadFromSimfile( sCacheFilePath, *this, true ); if( !bLoadedFromSSC ) { // load from .sm SMLoader loaderSM; - loaderSM.LoadFromSMFile( sCacheFilePath, *this, true ); + loaderSM.LoadFromSimfile( sCacheFilePath, *this, true ); loaderSM.TidyUpData( *this, true ); } } diff --git a/src/Steps.cpp b/src/Steps.cpp index e78bed9c3f..ee7a27c98f 100644 --- a/src/Steps.cpp +++ b/src/Steps.cpp @@ -243,12 +243,12 @@ void Steps::Decompress() const // We have data on disk and not in memory. Load it. Song s; SSCLoader loaderSSC; - bool bLoadedFromSSC = loaderSSC.LoadFromSSCFile(m_sFilename, s, true); + bool bLoadedFromSSC = loaderSSC.LoadFromSimfile(m_sFilename, s, true); if( !bLoadedFromSSC ) { // try reading from .sm instead SMLoader loaderSM; - if( !loaderSM.LoadFromSMFile(m_sFilename, s, true) ) + if( !loaderSM.LoadFromSimfile(m_sFilename, s, true) ) { LOG->Warn( "Couldn't load \"%s\"", m_sFilename.c_str() ); return; From 1ec548442d833469d76ef83d83e1051211526b94 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 21:34:04 -0400 Subject: [PATCH 24/44] [notesloader] Take advantage of const members. --- src/NotesLoaderSM.h | 13 +++++++++++++ src/NotesLoaderSMA.h | 1 + src/NotesLoaderSSC.h | 2 ++ 3 files changed, 16 insertions(+) diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index f2c964a43a..168b7e411f 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -18,6 +18,10 @@ const float FAST_BPM_WARP = 9999999.f; /** @brief Reads a Song from an .SM file. */ struct SMLoader { + SMLoader() : fileExt(".sm") {} + + SMLoader(RString ext) : fileExt(ext) {} + virtual ~SMLoader() {} bool LoadFromDir( const RString &sPath, Song &out ); @@ -143,6 +147,15 @@ protected: RString sRadarValues, RString sNoteData, Steps &out); + + /** + * @brief Retrieve the file extension associated with this loader. + * @return the file extension. */ + RString GetFileExtension() const { return fileExt; } + +private: + /** @brief The file extension in use. */ + const RString fileExt; }; #endif diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index 71d307642b..dad853fa19 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -23,6 +23,7 @@ enum SMALoadingStates /** @brief Reads a Song from a .SMA file. */ struct SMALoader : public SMLoader { + SMALoader() : SMLoader(".sma") {} bool LoadFromDir( const RString &sPath, Song &out ); virtual bool LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache = false ); diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index e535f8ac48..e400b94bb7 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -32,6 +32,8 @@ const float VERSION_SPLIT_TIMING = 0.7f; */ struct SSCLoader : public SMLoader { + SSCLoader() : SMLoader(".ssc") {} + /** * @brief Attempt to load a song from a specified path. * @param sPath a const reference to the path on the hard drive to check. From bb642827a8fd6bde6a9367af0bcc56bc9c326815 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 21:41:56 -0400 Subject: [PATCH 25/44] [notesloader] More abstracting. --- src/NotesLoaderSM.cpp | 9 +++------ src/NotesLoaderSM.h | 11 ++++++++++- src/NotesLoaderSMA.cpp | 19 ------------------- src/NotesLoaderSMA.h | 1 - src/NotesLoaderSSC.cpp | 20 -------------------- src/NotesLoaderSSC.h | 7 ------- 6 files changed, 13 insertions(+), 54 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 4e1b073a9b..5e5ae1292a 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -13,9 +13,6 @@ #include "Attack.h" #include "PrefsManager.h" -/** @brief The maximum file size for edits. */ -const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60KB - bool SMLoader::LoadFromDir( const RString &sPath, Song &out ) { vector aFileNames; @@ -23,13 +20,13 @@ bool SMLoader::LoadFromDir( const RString &sPath, Song &out ) if( aFileNames.size() > 1 ) { - LOG->UserLog( "Song", sPath, "has more than one SM file. There can be only one (unless you are using TougaKiryuu's AnimeMix files somehow, which assume a different version of StepMania)!" ); + // Need to break this up first. + RString tmp = "Song " + sPath + " has more than one"; + LOG->UserLog(tmp, this->GetFileExtension(), "file. There can only be one!"); return false; } ASSERT( aFileNames.size() == 1 ); - //ASSERT( aFileNames.size() >= 1 ); - return LoadFromSimfile( sPath + aFileNames[0], out ); } diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 168b7e411f..0e03988b58 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -15,6 +15,9 @@ class TimingData; * This was brought in from StepMania 4's recent betas. */ const float FAST_BPM_WARP = 9999999.f; +/** @brief The maximum file size for edits. */ +const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60KB + /** @brief Reads a Song from an .SM file. */ struct SMLoader { @@ -24,7 +27,13 @@ struct SMLoader virtual ~SMLoader() {} - bool LoadFromDir( const RString &sPath, Song &out ); + /** + * @brief Attempt to load a song from a specified path. + * @param sPath a const reference to the path on the hard drive to check. + * @param out a reference to the Song that will retrieve the song information. + * @return its success or failure. + */ + virtual bool LoadFromDir( const RString &sPath, Song &out ); /** * @brief Perform some cleanup on the loaded song. * @param song a reference to the song that may need cleaning up. diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index a52c7db68b..930f718ec6 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -14,25 +14,6 @@ #include "Steps.h" #include "Attack.h" -/** - * @brief A custom .edit file can only be so big before we have to reject it. - */ -const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB - -bool SMALoader::LoadFromDir( const RString &sPath, Song &out ) -{ - vector aFileNames; - GetApplicableFiles( sPath, aFileNames ); - - if( aFileNames.size() > 1 ) - { - LOG->UserLog( "Song", sPath, "has more than one SMA file. Only one SMA file is allowed per song." ); - return false; - } - ASSERT( aFileNames.size() == 1 ); - return LoadFromSimfile( sPath + aFileNames[0], out ); -} - void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ) { vector arrayMultiplierExpressions; diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index dad853fa19..ecebd82676 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -24,7 +24,6 @@ enum SMALoadingStates struct SMALoader : public SMLoader { SMALoader() : SMLoader(".sma") {} - bool LoadFromDir( const RString &sPath, Song &out ); virtual bool LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache = false ); /** diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index ddac4631fe..6c32cc6c9e 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -14,26 +14,6 @@ #include "Attack.h" #include "PrefsManager.h" -/** - * @brief A custom .edit file can only be so big before we have to reject it. - */ -const int MAX_EDIT_STEPS_SIZE_BYTES = 60*1024; // 60 KB - -bool SSCLoader::LoadFromDir( const RString &sPath, Song &out ) -{ - vector aFileNames; - GetApplicableFiles( sPath, aFileNames ); - - if( aFileNames.size() > 1 ) - { - LOG->UserLog( "Song", sPath, "has more than one SSC file. Only one SSC file is allowed per song." ); - return false; - } - - ASSERT( aFileNames.size() == 1 ); - return LoadFromSimfile( sPath + aFileNames[0], out ); -} - void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float fVersion ) { vector arrayWarpExpressions; diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index e400b94bb7..fc6332f731 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -34,13 +34,6 @@ struct SSCLoader : public SMLoader { SSCLoader() : SMLoader(".ssc") {} - /** - * @brief Attempt to load a song from a specified path. - * @param sPath a const reference to the path on the hard drive to check. - * @param out a reference to the Song that will retrieve the song information. - * @return its success or failure. - */ - bool LoadFromDir( const RString &sPath, Song &out ); /** * @brief Attempt to load the specified ssc file. * @param sPath a const reference to the path on the hard drive to check. From 4830ecc730c09941e46bd2e220ff202d9208ee28 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Thu, 9 Jun 2011 22:00:10 -0400 Subject: [PATCH 26/44] [notesreader] Ready to test again. --- src/NotesLoaderSM.cpp | 2 +- src/NotesLoaderSMA.cpp | 5 ----- src/NotesLoaderSMA.h | 7 +------ src/NotesLoaderSSC.cpp | 5 ----- src/NotesLoaderSSC.h | 7 +------ 5 files changed, 3 insertions(+), 23 deletions(-) diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 5e5ae1292a..35562c1efd 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -956,7 +956,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath void SMLoader::GetApplicableFiles( const RString &sPath, vector &out ) { - GetDirListing( sPath + RString("*.sm"), out ); + GetDirListing( sPath + RString("*" + this->GetFileExtension() ), out ); } void SMLoader::TidyUpData( Song &song, bool bFromCache ) diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 930f718ec6..44f6f5026f 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -438,11 +438,6 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach return true; } -void SMALoader::GetApplicableFiles( const RString &sPath, vector &out ) -{ - GetDirListing( sPath + RString("*.sma"), out ); -} - /** * @file * @author Aldo Fregoso, Jason Felds (c) 2009-2011 diff --git a/src/NotesLoaderSMA.h b/src/NotesLoaderSMA.h index ecebd82676..f38acac470 100644 --- a/src/NotesLoaderSMA.h +++ b/src/NotesLoaderSMA.h @@ -26,12 +26,7 @@ struct SMALoader : public SMLoader SMALoader() : SMLoader(".sma") {} virtual bool LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache = false ); - /** - * @brief Retrieve the list of .sma files. - * @param sPath a const reference to the path on the hard drive to check. - * @param out a vector of files found in the path. - */ - virtual void GetApplicableFiles( const RString &sPath, vector &out ); + void ProcessBeatsPerMeasure( TimingData &out, const RString sParam ); void ProcessMultipliers( TimingData &out, const int iRowsPerBeat, const RString sParam ); diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 6c32cc6c9e..3c13899ff7 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -557,11 +557,6 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach return true; } -void SSCLoader::GetApplicableFiles( const RString &sPath, vector &out ) -{ - GetDirListing( sPath + RString("*.ssc"), out ); -} - bool SSCLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong ) { LOG->Trace( "SSCLoader::LoadEditFromFile(%s)", sEditFilePath.c_str() ); diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index fc6332f731..3031932841 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -42,12 +42,7 @@ struct SSCLoader : public SMLoader * @return its success or failure. */ virtual bool LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache = false ); - /** - * @brief Retrieve the list of .ssc files. - * @param sPath a const reference to the path on the hard drive to check. - * @param out a vector of files found in the path. - */ - virtual void GetApplicableFiles( const RString &sPath, vector &out ); + /** * @brief Attempt to load an edit from the hard drive. * @param sEditFilePath a path on the hard drive to check. From 61d935ba7011ecf6edd9fbf2f71dd2868b1ad7a9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 03:04:47 -0400 Subject: [PATCH 27/44] Split the Editor's Area menu into two menus. Use the "Enter" key for the old menu, and the "A" key for the Alter menu (requires having selected an area of notes). --- Docs/Changelog_sm5.txt | 8 + Themes/_fallback/Languages/en.ini | 3 +- Themes/_fallback/metrics.ini | 3 + src/ScreenEdit.cpp | 470 ++++++++++++++++-------------- src/ScreenEdit.h | 47 ++- 5 files changed, 307 insertions(+), 224 deletions(-) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index cce227e55d..3aff3dbb7f 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,7 +8,15 @@ ________________________________________________________________________________ StepMania 5.0 Preview 2 | 20110??? -------------------------------------------------------------------------------- +2011/06/10 +---------- +* [ScreenEdit] Split the Area Menu into the Area Menu and Alter Menu. Use the + "A" key to enter the Alter Menu when a selection of notes/rows are + highlighted. Use the Enter key to enter the old Area Menu for the options that + do not depend on selecting NoteData. [Wolfman2000] + 2011/06/09 +---------- * [ScreenSyncOverlay] Ensure that F11 / F12 work with all charts due to Split Timing. [Wolfman2000] diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 63c9701cc0..3b77e336c3 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1257,7 +1257,7 @@ Enter a new min BPM.=Enter the minimum displayed BPM. Enter a new max BPM.=Enter the maximum displayed BPM. More than %d notes per measure is not allowed. This change has been reverted.=More than %d notes per measure is not allowed. This change has been reverted. No backgrounds available=No backgrounds available -EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nT key:\n Switch Timing\nEnter:\n Area Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n +EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nT key:\n Switch Timing\nEnter:\n Area Menu\nA Key: Alter Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n PlayRecordHelpText=Press START to end Save successful.=Save successful. Saved as SM and DWI.=Saved as SM and DWI. @@ -1269,6 +1269,7 @@ This change creates notes past the end of the music and is not allowed.=This cha This will destroy all unsaved changes.=This will destroy all unsaved changes. Undo=Undo You must be in Song Timing Mode to edit BG Changes.=You must be in Song Timing Mode to edit BG Changes. +You must have an area selected to enter the Alter Menu.=You must have an area selected to enter the Alter Menu. Current beat=Current beat Current second=Current second diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 18712e9a16..e504462b0e 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3752,6 +3752,9 @@ TitleX=SCREEN_CENTER_X-80 [ScreenMiniMenuAreaMenu] Fallback="ScreenMiniMenu" +[ScreenMiniMenuAlterMenu] +Fallback="ScreenMiniMenu" + [ScreenMiniMenuStepsInformation] Fallback="ScreenMiniMenu" diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index e0c805a5ad..340545e112 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -61,6 +61,7 @@ const float RECORD_HOLD_SECONDS = 0.3f; AutoScreenMessage( SM_UpdateTextInfo ); AutoScreenMessage( SM_BackFromMainMenu ); AutoScreenMessage( SM_BackFromAreaMenu ); +AutoScreenMessage( SM_BackFromAlterMenu ); AutoScreenMessage( SM_BackFromStepsInformation ); AutoScreenMessage( SM_BackFromOptions ); AutoScreenMessage( SM_BackFromSongInformation ); @@ -170,6 +171,7 @@ void ScreenEdit::InitEditMappings() m_EditMappingsMenuButton.button [EDIT_BUTTON_OPEN_EDIT_MENU][0] = GAME_BUTTON_START; m_EditMappingsMenuButton.button [EDIT_BUTTON_OPEN_EDIT_MENU][1] = GAME_BUTTON_BACK; + // Escape, Enter = exit play/record m_PlayMappingsDeviceInput.button [EDIT_BUTTON_RETURN_TO_EDIT][0] = DeviceInput(DEVICE_KEYBOARD, KEY_ENTER); m_PlayMappingsDeviceInput.button [EDIT_BUTTON_RETURN_TO_EDIT][1] = DeviceInput(DEVICE_KEYBOARD, KEY_ESC); @@ -280,6 +282,7 @@ void ScreenEdit::InitEditMappings() m_EditMappingsMenuButton.button[EDIT_BUTTON_OPEN_EDIT_MENU][0] = GAME_BUTTON_START; m_EditMappingsMenuButton.button[EDIT_BUTTON_OPEN_EDIT_MENU][1] = GAME_BUTTON_BACK; m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_AREA_MENU][0] = DeviceInput(DEVICE_KEYBOARD, KEY_ENTER); + m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_ALTER_MENU][0] = DeviceInput(DEVICE_KEYBOARD, KEY_Ca); m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_INPUT_HELP][0] = DeviceInput(DEVICE_KEYBOARD, KEY_F1); m_EditMappingsDeviceInput.button[EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP][0] = DeviceInput(DEVICE_KEYBOARD, KEY_Cb); @@ -505,26 +508,48 @@ static MenuDef g_MainMenu( MenuRowDef( ScreenEdit::exit, "Exit Edit Mode", true, EditMode_Practice, true, true, 0, NULL ) ); +static MenuDef g_AlterMenu( + "ScreenMiniMenuAlterMenu", + MenuRowDef(ScreenEdit::cut, "Cut", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::copy, "Copy", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::clear, "Clear area", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::quantize, "Quantize", true, + EditMode_Practice, true, true, 0, + "4th","8th","12th","16th","24th","32nd","48th","64th","192nd"), + MenuRowDef(ScreenEdit::turn, "Turn", true, + EditMode_Practice, true, true, 0, "Left","Right","Mirror","Shuffle","SuperShuffle" ), + MenuRowDef(ScreenEdit::transform, "Transform", true, + EditMode_Practice, true, true, 0, "NoHolds","NoMines","Little","Wide", + "Big","Quick","Skippy","Mines","Echo","Stomp","Planted","Floored", + "Twister","NoJumps","NoHands","NoQuads","NoStretch" ), + MenuRowDef(ScreenEdit::alter, "Alter", true, + EditMode_Practice, true, true, 0, "Autogen To Fill Width","Backwards","Swap Sides", + "Copy Left To Right","Copy Right To Left","Clear Left","Clear Right", + "Collapse To One","Collapse Left","Shift Left","Shift Right" ), + MenuRowDef(ScreenEdit::tempo, "Tempo", true, + EditMode_Full, true, true, 0, "Compress 2x","Compress 3->2", + "Compress 4->3","Expand 3->4","Expand 2->3","Expand 2x" ), + MenuRowDef(ScreenEdit::play, "Play selection", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::record, "Record in selection", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_to_pause, "Convert selection to pause", true, + EditMode_Full, true, true, 0, NULL ) +); + static MenuDef g_AreaMenu( "ScreenMiniMenuAreaMenu", - MenuRowDef( ScreenEdit::cut, "Cut", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::copy, "Copy", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::paste_at_current_beat, "Paste at current beat", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::paste_at_begin_marker, "Paste at begin marker", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::clear, "Clear area", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::quantize, "Quantize", true, EditMode_Practice, true, true, 0, "4th","8th","12th","16th","24th","32nd","48th","64th","192nd"), - MenuRowDef( ScreenEdit::turn, "Turn", true, EditMode_Practice, true, true, 0, "Left","Right","Mirror","Shuffle","SuperShuffle" ), - MenuRowDef( ScreenEdit::transform, "Transform", true, EditMode_Practice, true, true, 0, "NoHolds","NoMines","Little","Wide","Big","Quick","Skippy","Mines","Echo","Stomp","Planted","Floored","Twister","NoJumps","NoHands","NoQuads","NoStretch" ), - MenuRowDef( ScreenEdit::alter, "Alter", true, EditMode_Practice, true, true, 0, "Autogen To Fill Width","Backwards","Swap Sides","Copy Left To Right","Copy Right To Left","Clear Left","Clear Right","Collapse To One","Collapse Left","Shift Left","Shift Right" ), - MenuRowDef( ScreenEdit::tempo, "Tempo", true, EditMode_Full, true, true, 0, "Compress 2x","Compress 3->2","Compress 4->3","Expand 3->4","Expand 2->3","Expand 2x" ), - MenuRowDef( ScreenEdit::play, "Play selection", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::record, "Record in selection", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::insert_and_shift, "Insert beat and shift down", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::delete_and_shift, "Delete beat and shift up", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::shift_pauses_forward, "Shift all timing changes down", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::shift_pauses_backward, "Shift all timing changes up", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::convert_to_pause, "Convert selection to pause", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::convert_pause_to_beat, "Convert pause to beats", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_pause_to_beat, "Convert pause to beats", true, + EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::undo, "Undo", true, EditMode_Practice, true, true, 0, NULL ) ); @@ -1299,7 +1324,7 @@ static int FindAttackAtTime( const AttackArray& attacks, float fStartTime ) } static LocalizedString BG_CHANGE_STEP_TIMING ( "ScreenEdit", "You must be in Song Timing Mode to edit BG Changes." ); - +static LocalizedString ALTER_MENU_NO_SELECTION ( "ScreenEdit", "You must have an area selected to enter the Alter Menu." ); static LocalizedString SWITCHED_TO ( "ScreenEdit", "Switched to" ); static LocalizedString NO_BACKGROUNDS_AVAILABLE ( "ScreenEdit", "No backgrounds available" ); static ThemeMetric INVERT_SCROLL_BUTTONS ( "ScreenEdit", "InvertScrollSpeedButtons" ); @@ -1561,24 +1586,27 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_OPEN_AREA_MENU: { // update enabled/disabled in g_AreaMenu - bool bAreaSelected = m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1; - g_AreaMenu.rows[cut].bEnabled = bAreaSelected; - g_AreaMenu.rows[copy].bEnabled = bAreaSelected; g_AreaMenu.rows[paste_at_current_beat].bEnabled = !m_Clipboard.IsEmpty(); g_AreaMenu.rows[paste_at_begin_marker].bEnabled = !m_Clipboard.IsEmpty() != 0 && m_NoteFieldEdit.m_iBeginMarker!=-1; - g_AreaMenu.rows[clear].bEnabled = bAreaSelected; - g_AreaMenu.rows[quantize].bEnabled = bAreaSelected; - g_AreaMenu.rows[turn].bEnabled = bAreaSelected; - g_AreaMenu.rows[transform].bEnabled = bAreaSelected; - g_AreaMenu.rows[alter].bEnabled = bAreaSelected; - g_AreaMenu.rows[tempo].bEnabled = bAreaSelected; - g_AreaMenu.rows[play].bEnabled = bAreaSelected; - g_AreaMenu.rows[record].bEnabled = bAreaSelected; - g_AreaMenu.rows[convert_to_pause].bEnabled = bAreaSelected; g_AreaMenu.rows[undo].bEnabled = m_bHasUndo; EditMiniMenu( &g_AreaMenu, SM_BackFromAreaMenu ); } break; + case EDIT_BUTTON_OPEN_ALTER_MENU: + { + bool bAreaSelected = m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1; + if (!bAreaSelected) + { + SCREENMAN->SystemMessage( ALTER_MENU_NO_SELECTION ); + SCREENMAN->PlayInvalidSound(); + } + else + { + EditMiniMenu(&g_AlterMenu, SM_BackFromAlterMenu); + } + break; + + } case EDIT_BUTTON_OPEN_EDIT_MENU: EditMiniMenu( &g_MainMenu, SM_BackFromMainMenu ); break; @@ -2044,7 +2072,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_RECORD_SELECTION: if( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ) { - HandleAreaMenuChoice( record ); + HandleAlterMenuChoice( record ); } else { @@ -2644,6 +2672,10 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { HandleAreaMenuChoice( (AreaMenuChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); } + else if( SM == SM_BackFromAlterMenu ) + { + HandleAlterMenuChoice( (AlterMenuChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); + } else if( SM == SM_BackFromStepsInformation ) { HandleStepsInformationChoice( (StepsInformationChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); @@ -3248,7 +3280,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns DEFAULT_FAIL( c ); case play_selection: if( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ) - HandleAreaMenuChoice( play ); + HandleAlterMenuChoice( play ); else if( m_NoteFieldEdit.m_iBeginMarker!=-1 ) HandleMainMenuChoice( play_selection_start_to_end ); else @@ -3464,14 +3496,208 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns GAMESTATE->SetProcessedTimingData(NULL); } +void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAnswers, bool bAllowUndo) +{ + bool bSaveUndo = true; + switch (c) + { + case cut: + case copy: + { + bSaveUndo = false; + } + default: + break; + } + + if( bSaveUndo ) + SetDirty( true ); + + /* We call HandleAreaMenuChoice recursively. Only the outermost + * HandleAreaMenuChoice should allow Undo so that the inner calls don't + * also save Undo and mess up the outermost */ + if( !bAllowUndo ) + bSaveUndo = false; + + if( bSaveUndo ) + SaveUndo(); + + switch(c) + { + case cut: + { + HandleAlterMenuChoice( copy ); + HandleAlterMenuChoice( clear ); + } + break; + case copy: + { + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_Clipboard.ClearAll(); + m_Clipboard.CopyRange( m_NoteDataEdit, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); + } + break; + case clear: + { + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_NoteDataEdit.ClearRange( m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); + } + break; + case quantize: + { + NoteType nt = (NoteType)iAnswers[c]; + NoteDataUtil::SnapToNearestNoteType(m_NoteDataEdit, nt, nt, + m_NoteFieldEdit.m_iBeginMarker, + m_NoteFieldEdit.m_iEndMarker ); + break; + } + case turn: + { + const NoteData OldClipboard( m_Clipboard ); + HandleAlterMenuChoice( cut ); + + StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; + TurnType tt = (TurnType)iAnswers[c]; + switch( tt ) + { + DEFAULT_FAIL( tt ); + case left: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::left ); break; + case right: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::right ); break; + case mirror: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::mirror ); break; + case shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::shuffle ); break; + case super_shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::super_shuffle ); break; + } + + HandleAreaMenuChoice( paste_at_begin_marker ); + m_Clipboard = OldClipboard; + } + break; + case transform: + { + int iBeginRow = m_NoteFieldEdit.m_iBeginMarker; + int iEndRow = m_NoteFieldEdit.m_iEndMarker; + TransformType tt = (TransformType)iAnswers[c]; + StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; + + switch( tt ) + { + DEFAULT_FAIL( tt ); + case noholds: NoteDataUtil::RemoveHoldNotes( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nomines: NoteDataUtil::RemoveMines( m_NoteDataEdit, iBeginRow, iBeginRow ); break; + case little: NoteDataUtil::Little( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case wide: NoteDataUtil::Wide( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case big: NoteDataUtil::Big( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case quick: NoteDataUtil::Quick( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case skippy: NoteDataUtil::Skippy( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case add_mines: NoteDataUtil::AddMines( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case echo: NoteDataUtil::Echo( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case stomp: NoteDataUtil::Stomp( m_NoteDataEdit, st, iBeginRow, iEndRow ); break; + case planted: NoteDataUtil::Planted( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case floored: NoteDataUtil::Floored( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case twister: NoteDataUtil::Twister( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nojumps: NoteDataUtil::RemoveJumps( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nohands: NoteDataUtil::RemoveHands( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case noquads: NoteDataUtil::RemoveQuads( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nostretch: NoteDataUtil::RemoveStretch( m_NoteDataEdit, st, iBeginRow, iBeginRow );break; + } + + // bake in the additions + NoteDataUtil::ConvertAdditionsToRegular( m_NoteDataEdit ); + break; + } + case alter: + { + const NoteData OldClipboard( m_Clipboard ); + HandleAlterMenuChoice( cut ); + + AlterType at = (AlterType)iAnswers[c]; + switch( at ) + { + DEFAULT_FAIL( at ); + case autogen_to_fill_width: + { + NoteData temp( m_Clipboard ); + int iMaxNonEmptyTrack = NoteDataUtil::GetMaxNonEmptyTrack( temp ); + if( iMaxNonEmptyTrack == -1 ) + break; + temp.SetNumTracks( iMaxNonEmptyTrack+1 ); + NoteDataUtil::LoadTransformedSlidingWindow( temp, m_Clipboard, m_Clipboard.GetNumTracks() ); + NoteDataUtil::RemoveStretch( m_Clipboard, GAMESTATE->m_pCurSteps[0]->m_StepsType ); + } + break; + case backwards: NoteDataUtil::Backwards( m_Clipboard ); break; + case swap_sides: NoteDataUtil::SwapSides( m_Clipboard ); break; + case copy_left_to_right: NoteDataUtil::CopyLeftToRight( m_Clipboard ); break; + case copy_right_to_left: NoteDataUtil::CopyRightToLeft( m_Clipboard ); break; + case clear_left: NoteDataUtil::ClearLeft( m_Clipboard ); break; + case clear_right: NoteDataUtil::ClearRight( m_Clipboard ); break; + case collapse_to_one: NoteDataUtil::CollapseToOne( m_Clipboard ); break; + case collapse_left: NoteDataUtil::CollapseLeft( m_Clipboard ); break; + case shift_left: NoteDataUtil::ShiftLeft( m_Clipboard ); break; + case shift_right: NoteDataUtil::ShiftRight( m_Clipboard ); break; + } + + HandleAreaMenuChoice( paste_at_begin_marker ); + m_Clipboard = OldClipboard; + break; + } + case tempo: + { + // This affects all steps. + AlterType at = (AlterType)iAnswers[c]; + float fScale = -1; + + switch( at ) + { + DEFAULT_FAIL( at ); + case compress_2x: fScale = 0.5f; break; + case compress_3_2: fScale = 2.0f/3; break; + case compress_4_3: fScale = 0.75f; break; + case expand_4_3: fScale = 4.0f/3; break; + case expand_3_2: fScale = 1.5f; break; + case expand_2x: fScale = 2; break; + } + + int iStartIndex = m_NoteFieldEdit.m_iBeginMarker; + int iEndIndex = m_NoteFieldEdit.m_iEndMarker; + int iNewEndIndex = iEndIndex + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + + // scale currently editing notes + NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex ); + + // scale timing data + GetAppropriateTiming().ScaleRegion(fScale, + m_NoteFieldEdit.m_iBeginMarker, + m_NoteFieldEdit.m_iEndMarker, true ); + + m_NoteFieldEdit.m_iEndMarker = iNewEndIndex; + break; + + } + + case play: + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; + m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; + TransitionEditState( STATE_PLAYING ); + break; + case record: + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; + m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; + TransitionEditState( STATE_RECORDING ); + break; + + } + +} + void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAnswers, bool bAllowUndo ) { bool bSaveUndo = false; switch( c ) { DEFAULT_FAIL( c ); - case cut: - case copy: case play: case record: case undo: @@ -3479,12 +3705,6 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns break; case paste_at_current_beat: case paste_at_begin_marker: - case clear: - case quantize: - case turn: - case transform: - case alter: - case tempo: case insert_and_shift: case delete_and_shift: case shift_pauses_forward: @@ -3510,19 +3730,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns switch( c ) { DEFAULT_FAIL( c ); - case cut: - { - HandleAreaMenuChoice( copy ); - HandleAreaMenuChoice( clear ); - } - break; - case copy: - { - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_Clipboard.ClearAll(); - m_Clipboard.CopyRange( m_NoteDataEdit, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - } - break; + case paste_at_current_beat: case paste_at_begin_marker: { @@ -3543,172 +3751,6 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns m_NoteDataEdit.CopyRange( m_Clipboard, 0, iRowsToCopy, iDestFirstRow ); } break; - case clear: - { - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_NoteDataEdit.ClearRange( m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - } - break; - case quantize: - { - NoteType nt = (NoteType)iAnswers[c]; - NoteDataUtil::SnapToNearestNoteType( m_NoteDataEdit, nt, nt, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - } - break; - case turn: - { - const NoteData OldClipboard( m_Clipboard ); - HandleAreaMenuChoice( cut ); - - StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; - TurnType tt = (TurnType)iAnswers[c]; - switch( tt ) - { - DEFAULT_FAIL( tt ); - case left: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::left ); break; - case right: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::right ); break; - case mirror: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::mirror ); break; - case shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::shuffle ); break; - case super_shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::super_shuffle ); break; - } - - HandleAreaMenuChoice( paste_at_begin_marker ); - m_Clipboard = OldClipboard; - } - break; - case transform: - { - int iBeginRow = m_NoteFieldEdit.m_iBeginMarker; - int iEndRow = m_NoteFieldEdit.m_iEndMarker; - TransformType tt = (TransformType)iAnswers[c]; - StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; - - switch( tt ) - { - DEFAULT_FAIL( tt ); - case noholds: NoteDataUtil::RemoveHoldNotes( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nomines: NoteDataUtil::RemoveMines( m_NoteDataEdit, iBeginRow, iBeginRow ); break; - case little: NoteDataUtil::Little( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case wide: NoteDataUtil::Wide( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case big: NoteDataUtil::Big( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case quick: NoteDataUtil::Quick( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case skippy: NoteDataUtil::Skippy( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case add_mines: NoteDataUtil::AddMines( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case echo: NoteDataUtil::Echo( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case stomp: NoteDataUtil::Stomp( m_NoteDataEdit, st, iBeginRow, iEndRow ); break; - case planted: NoteDataUtil::Planted( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case floored: NoteDataUtil::Floored( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case twister: NoteDataUtil::Twister( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nojumps: NoteDataUtil::RemoveJumps( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nohands: NoteDataUtil::RemoveHands( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case noquads: NoteDataUtil::RemoveQuads( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nostretch: NoteDataUtil::RemoveStretch( m_NoteDataEdit, st, iBeginRow, iBeginRow );break; - } - - // bake in the additions - NoteDataUtil::ConvertAdditionsToRegular( m_NoteDataEdit ); - } - break; - case alter: - { - const NoteData OldClipboard( m_Clipboard ); - HandleAreaMenuChoice( cut ); - - AlterType at = (AlterType)iAnswers[c]; - switch( at ) - { - DEFAULT_FAIL( at ); - case autogen_to_fill_width: - { - NoteData temp( m_Clipboard ); - int iMaxNonEmptyTrack = NoteDataUtil::GetMaxNonEmptyTrack( temp ); - if( iMaxNonEmptyTrack == -1 ) - break; - temp.SetNumTracks( iMaxNonEmptyTrack+1 ); - NoteDataUtil::LoadTransformedSlidingWindow( temp, m_Clipboard, m_Clipboard.GetNumTracks() ); - NoteDataUtil::RemoveStretch( m_Clipboard, GAMESTATE->m_pCurSteps[0]->m_StepsType ); - } - break; - case backwards: NoteDataUtil::Backwards( m_Clipboard ); break; - case swap_sides: NoteDataUtil::SwapSides( m_Clipboard ); break; - case copy_left_to_right: NoteDataUtil::CopyLeftToRight( m_Clipboard ); break; - case copy_right_to_left: NoteDataUtil::CopyRightToLeft( m_Clipboard ); break; - case clear_left: NoteDataUtil::ClearLeft( m_Clipboard ); break; - case clear_right: NoteDataUtil::ClearRight( m_Clipboard ); break; - case collapse_to_one: NoteDataUtil::CollapseToOne( m_Clipboard ); break; - case collapse_left: NoteDataUtil::CollapseLeft( m_Clipboard ); break; - case shift_left: NoteDataUtil::ShiftLeft( m_Clipboard ); break; - case shift_right: NoteDataUtil::ShiftRight( m_Clipboard ); break; - } - - HandleAreaMenuChoice( paste_at_begin_marker ); - m_Clipboard = OldClipboard; - } - break; - case tempo: - { - // This affects all steps. - AlterType at = (AlterType)iAnswers[c]; - float fScale = -1; - - switch( at ) - { - DEFAULT_FAIL( at ); - case compress_2x: fScale = 0.5f; break; - case compress_3_2: fScale = 2.0f/3; break; - case compress_4_3: fScale = 0.75f; break; - case expand_4_3: fScale = 4.0f/3; break; - case expand_3_2: fScale = 1.5f; break; - case expand_2x: fScale = 2; break; - } - - int iStartIndex = m_NoteFieldEdit.m_iBeginMarker; - int iEndIndex = m_NoteFieldEdit.m_iEndMarker; - int iNewEndIndex = iEndIndex + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); - - // scale currently editing notes - NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex ); - - // scale timing data - GetAppropriateTiming().ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); - - // scale all other steps. - /* - const vector sIter = m_pSong->GetAllSteps(); - RString sTempStyle, sTempDiff; - for( unsigned i = 0; i < sIter.size(); i++ ) - { - if( sIter[i]->IsAutogen() ) - continue; - - // XXX: Edits are distinguished by description. - // Compare vs m_pSteps. - if( (sIter[i]->m_StepsType == GAMESTATE->m_pCurSteps[PLAYER_1]->m_StepsType) && - (sIter[i]->GetDifficulty() == GAMESTATE->m_pCurSteps[PLAYER_1]->GetDifficulty()) ) - continue; - - NoteData ndTemp; - sIter[i]->GetNoteData( ndTemp ); - NoteDataUtil::ScaleRegion( ndTemp, fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - sIter[i]->SetNoteData( ndTemp ); - } - */ - m_NoteFieldEdit.m_iEndMarker = iNewEndIndex; - - } - break; - case play: - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; - m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; - TransitionEditState( STATE_PLAYING ); - break; - case record: - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; - m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; - TransitionEditState( STATE_RECORDING ); - break; case insert_and_shift: NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow( GetBeat() ), BeatToNoteRow(1) ); break; diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 2b92f8bbd5..7e2f82eebd 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -87,6 +87,7 @@ enum EditButton EDIT_BUTTON_OPEN_EDIT_MENU, EDIT_BUTTON_OPEN_TIMING_MENU, + EDIT_BUTTON_OPEN_ALTER_MENU, EDIT_BUTTON_OPEN_AREA_MENU, EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU, EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU, @@ -209,7 +210,12 @@ public: virtual void PushSelf( lua_State *L ); protected: - virtual ScreenType GetScreenType() const { return m_EditState==STATE_PLAYING ? gameplay : ScreenWithMenuElements::GetScreenType(); } + virtual ScreenType GetScreenType() const + { + return m_EditState==STATE_PLAYING ? + gameplay : + ScreenWithMenuElements::GetScreenType(); + } void TransitionEditState( EditState em ); void ScrollTo( float fDestinationBeat ); @@ -268,7 +274,8 @@ protected: BitmapText m_textPlayRecordHelp; // keep track of where we are and what we're doing - float m_fTrailingBeat; // this approaches GAMESTATE->m_fSongBeat, which is the actual beat + float m_fTrailingBeat; + // the above approaches GAMESTATE->m_fSongBeat, which is the actual beat /** * @brief The location we were at when shift was pressed. * @@ -365,13 +372,12 @@ public: void HandleMainMenuChoice( MainMenuChoice c ) { const vector v; HandleMainMenuChoice( c, v ); } MainMenuChoice m_CurrentAction; - enum AreaMenuChoice + enum AlterMenuChoice { cut, copy, - paste_at_current_beat, - paste_at_begin_marker, clear, + // clear_undo, quantize, turn, transform, @@ -379,17 +385,37 @@ public: tempo, play, record, + convert_to_pause, + NUM_ALTER_MENU_CHOICES + + }; + + enum AreaMenuChoice + { + paste_at_current_beat, + paste_at_begin_marker, insert_and_shift, delete_and_shift, shift_pauses_forward, shift_pauses_backward, - convert_to_pause, convert_pause_to_beat, undo, NUM_AREA_MENU_CHOICES }; + void HandleAlterMenuChoice(AlterMenuChoice c, + const vector &iAnswers, + bool bAllowUndo = true); + void HandleAlterMenuChoice(AlterMenuChoice c, + bool bAllowUndo = true) + { + const vector v; HandleAlterMenuChoice(c, v, bAllowUndo); + } + void HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAnswers, bool bAllowUndo = true ); - void HandleAreaMenuChoice( AreaMenuChoice c, bool bAllowUndo = true ) { const vector v; HandleAreaMenuChoice( c, v, bAllowUndo ); } + void HandleAreaMenuChoice( AreaMenuChoice c, bool bAllowUndo = true ) + { + const vector v; HandleAreaMenuChoice( c, v, bAllowUndo ); + } /** @brief How should the selected notes be transformed? */ enum TurnType { @@ -511,7 +537,8 @@ public: NUM_TIMING_DATA_INFORMATION_CHOICES }; - void HandleTimingDataInformationChoice ( TimingDataInformationChoice c, const vector &iAnswers ); + void HandleTimingDataInformationChoice (TimingDataInformationChoice c, + const vector &iAnswers ); enum BGChangeChoice { @@ -581,7 +608,9 @@ public: MapEditButtonToMenuButton m_RecordPausedMappingsMenuButton; void MakeFilteredMenuDef( const MenuDef* pDef, MenuDef &menu ); - void EditMiniMenu( const MenuDef* pDef, ScreenMessage SM_SendOnOK = SM_None, ScreenMessage SM_SendOnCancel = SM_None ); + void EditMiniMenu(const MenuDef* pDef, + ScreenMessage SM_SendOnOK = SM_None, + ScreenMessage SM_SendOnCancel = SM_None ); private: /** * @brief Retrieve the appropriate TimingData based on GAMESTATE. From 1486b72e2338a80c0b29edccadc651a7224726ef Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 11:02:02 -0400 Subject: [PATCH 28/44] AutoPlay shouldn't hit unjudgable notes. --- src/Player.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Player.cpp b/src/Player.cpp index f8582c9a06..ab8ebdb412 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2852,7 +2852,8 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) // check to see if there's a note at the crossed row if( m_pPlayerState->m_PlayerController != PC_HUMAN ) { - if( tn.type != TapNote::empty && tn.type != TapNote::fake && tn.result.tns == TNS_None ) + if(tn.type != TapNote::empty && tn.type != TapNote::fake && tn.result.tns == TNS_None + && this->m_Timing->IsJudgableAtRow(iRow) ) { Step( iTrack, iRow, now, false, false ); if( m_pPlayerState->m_PlayerController == PC_AUTOPLAY ) From 493a49f55e95736afd29ebb9f6c1c4e132464820 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 15:18:08 -0400 Subject: [PATCH 29/44] Missed a fix spot. Checkpoints... --- src/Player.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Player.cpp b/src/Player.cpp index ab8ebdb412..c853fc86f9 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2938,6 +2938,7 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) ++tn.HoldResult.iCheckpointsMissed; } } + GAMESTATE->SetProcessedTimingData(this->m_Timing); // TODO: Find a better way of handling hold checkpoints with other taps. if( !viColsWithHold.empty() && ( CHECKPOINTS_TAPS_SEPARATE_JUDGMENT || m_NoteData.GetNumTapNotesInRow( iLastRowCrossed ) == 0 ) ) From b857ead66dbfc8c72f4e03f80e93dbea0be8f1f3 Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Fri, 10 Jun 2011 14:55:48 -0500 Subject: [PATCH 30/44] people actually build WITHOUT_NETWORKING? shock. --- src/ScreenPackagesSSC.cpp | 3 +++ src/ScreenPackagesSSC.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/ScreenPackagesSSC.cpp b/src/ScreenPackagesSSC.cpp index 48d292612e..73ba2c57ed 100644 --- a/src/ScreenPackagesSSC.cpp +++ b/src/ScreenPackagesSSC.cpp @@ -1,4 +1,6 @@ #include "global.h" + +#if !defined(WITHOUT_NETWORKING) #include "ScreenPackagesSSC.h" #include "ThemeManager.h" #include "RageDisplay.h" @@ -50,6 +52,7 @@ RString ScreenPackagesSSC::JSONParse( const RString &string_in ) return ""; } +#endif /* * (c) 2009 Colby Klein * All rights reserved. diff --git a/src/ScreenPackagesSSC.h b/src/ScreenPackagesSSC.h index c9de431c7b..7db51bfef6 100644 --- a/src/ScreenPackagesSSC.h +++ b/src/ScreenPackagesSSC.h @@ -7,6 +7,8 @@ #include "RageFileManager.h" #include "RageFile.h" #include "Sprite.h" + +#if !defined(WITHOUT_NETWORKING) /** @brief Parses JSON for downloadable content. */ class ScreenPackagesSSC : public ScreenWithMenuElements { @@ -24,6 +26,7 @@ public: private: RString JSONParse( const RString &string_in ); }; +#endif // WITHOUT_NETWORKING? #endif From 866d72e660ff9e41bb34df989fcaa274b723d768 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 16:10:43 -0400 Subject: [PATCH 31/44] Add a Clear Clipboard function to the editor. --- Themes/_fallback/Languages/en.ini | 1 + src/ScreenEdit.cpp | 28 ++++++++++++++-------------- src/ScreenEdit.h | 2 +- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 3b77e336c3..bc3fd8b21e 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -807,6 +807,7 @@ Clear Machine Edits=Clear Machine Edits Clear Machine Stats=Clear Machine Scores Clear USB edits=Clear USB edits Clear area=Clear area +Clear clipboard=Clear clipboard CoinMode=Coin Mode CoinModeNoHome=Coin Mode CoinsPerCredit=Coins Per Credit diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 340545e112..7bad89f8b4 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -550,7 +550,10 @@ static MenuDef g_AreaMenu( MenuRowDef( ScreenEdit::shift_pauses_backward, "Shift all timing changes up", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef(ScreenEdit::convert_pause_to_beat, "Convert pause to beats", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::undo, "Undo", true, EditMode_Practice, true, true, 0, NULL ) + MenuRowDef( ScreenEdit::undo, "Undo", true, EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::clear_clipboard, "Clear clipboard", true, + EditMode_Practice, true, true, 0, NULL ) + ); static MenuDef g_StepsInformation( @@ -3501,6 +3504,8 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAn bool bSaveUndo = true; switch (c) { + case play: + case record: case cut: case copy: { @@ -3694,24 +3699,14 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAn void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAnswers, bool bAllowUndo ) { - bool bSaveUndo = false; + bool bSaveUndo = true; switch( c ) { - DEFAULT_FAIL( c ); - case play: - case record: + case clear_clipboard: case undo: bSaveUndo = false; break; - case paste_at_current_beat: - case paste_at_begin_marker: - case insert_and_shift: - case delete_and_shift: - case shift_pauses_forward: - case shift_pauses_backward: - case convert_to_pause: - case convert_pause_to_beat: - bSaveUndo = true; + default: break; } @@ -3802,6 +3797,11 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case undo: Undo(); break; + case clear_clipboard: + { + m_Clipboard.ClearAll(); + break; + } }; if( bSaveUndo ) diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 7e2f82eebd..81dc6346fa 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -377,7 +377,6 @@ public: cut, copy, clear, - // clear_undo, quantize, turn, transform, @@ -400,6 +399,7 @@ public: shift_pauses_backward, convert_pause_to_beat, undo, + clear_clipboard, NUM_AREA_MENU_CHOICES }; void HandleAlterMenuChoice(AlterMenuChoice c, From 0db9f87b74c5592736912be317b83e5abbc40d66 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 16:43:38 -0400 Subject: [PATCH 32/44] Add "Convert Selection to Warp Segment" option. Also, preemptively fix another bug with the menu moving. --- Themes/_fallback/Languages/en.ini | 1 + src/ScreenEdit.cpp | 57 ++++++++++++++++++------------- src/ScreenEdit.h | 1 + 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index bc3fd8b21e..89904c4cbe 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -814,6 +814,7 @@ CoinsPerCredit=Coins Per Credit Connection=Connection Convert pause to beats=Convert pause to beats Convert selection to pause=Convert selection to pause +Convert selection to warp=Convert selection to Warp Segment Copy=Copy CourseSortOrder=Course Sort Create New=Create New diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 7bad89f8b4..116b8762fb 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -537,7 +537,9 @@ static MenuDef g_AlterMenu( MenuRowDef(ScreenEdit::record, "Record in selection", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef(ScreenEdit::convert_to_pause, "Convert selection to pause", true, - EditMode_Full, true, true, 0, NULL ) + EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_to_warp, "Convert selection to warp", true, + EditMode_Full, true, true, 0, NULL ) ); static MenuDef g_AreaMenu( @@ -3692,6 +3694,37 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAn m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; TransitionEditState( STATE_RECORDING ); break; + case convert_to_pause: + { + ASSERT_M( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1, "Attempted to convert beats outside the notefield to pauses!" ); + float fMarkerStart = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); + float fMarkerEnd = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); + + // The length of the stop segment we're going to create. This includes time spent in any + // stops in the selection, which will be deleted and subsumed into the new stop. + float fStopLength = fMarkerEnd - fMarkerStart; + + // be sure not to clobber the row at the start - a row at the end + // can be dropped safely, though + NoteDataUtil::DeleteRows( m_NoteDataEdit, + m_NoteFieldEdit.m_iBeginMarker + 1, + m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker + ); + GetAppropriateTiming().DeleteRows( m_NoteFieldEdit.m_iBeginMarker + 1, + m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); + GetAppropriateTiming().SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); + m_NoteFieldEdit.m_iBeginMarker = -1; + m_NoteFieldEdit.m_iEndMarker = -1; + break; + } + case convert_to_warp: + { + float startBeat = NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker); + float lengthBeat = NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) - startBeat; + GetAppropriateTiming().SetWarpAtBeat(startBeat,lengthBeat); + SetDirty(true); + break; + } } @@ -3758,29 +3791,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns case shift_pauses_backward: GetAppropriateTiming().DeleteRows( GetRow() + 1, BeatToNoteRow(1) ); break; - case convert_to_pause: - { - ASSERT_M( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1, "Attempted to convert beats outside the notefield to pauses!" ); - float fMarkerStart = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); - float fMarkerEnd = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); - // The length of the stop segment we're going to create. This includes time spent in any - // stops in the selection, which will be deleted and subsumed into the new stop. - float fStopLength = fMarkerEnd - fMarkerStart; - - // be sure not to clobber the row at the start - a row at the end - // can be dropped safely, though - NoteDataUtil::DeleteRows( m_NoteDataEdit, - m_NoteFieldEdit.m_iBeginMarker + 1, - m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker - ); - GetAppropriateTiming().DeleteRows( m_NoteFieldEdit.m_iBeginMarker + 1, - m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); - GetAppropriateTiming().SetStopAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); - m_NoteFieldEdit.m_iBeginMarker = -1; - m_NoteFieldEdit.m_iEndMarker = -1; - break; - } case convert_pause_to_beat: { // TODO: Convert both Delays and Stops at once. diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 81dc6346fa..e01c332c27 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -385,6 +385,7 @@ public: play, record, convert_to_pause, + convert_to_warp, NUM_ALTER_MENU_CHOICES }; From 9a258e70427593c290e843849eb153f45ff29f17 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 16:52:23 -0400 Subject: [PATCH 33/44] Add "Convert Selection to Fake Segment" option. Once again, do things math free. --- Themes/_fallback/Languages/en.ini | 1 + src/ScreenEdit.cpp | 12 +++++++++++- src/ScreenEdit.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 89904c4cbe..01b038adf5 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -815,6 +815,7 @@ Connection=Connection Convert pause to beats=Convert pause to beats Convert selection to pause=Convert selection to pause Convert selection to warp=Convert selection to Warp Segment +Convert selection to fake=Convert selection to Fake Segment Copy=Copy CourseSortOrder=Course Sort Create New=Create New diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 116b8762fb..db85c529d5 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -539,7 +539,9 @@ static MenuDef g_AlterMenu( MenuRowDef(ScreenEdit::convert_to_pause, "Convert selection to pause", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef(ScreenEdit::convert_to_warp, "Convert selection to warp", true, - EditMode_Full, true, true, 0, NULL ) + EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_to_fake, "Convert selection to fake", true, + EditMode_Full, true, true, 0, NULL ) ); static MenuDef g_AreaMenu( @@ -3725,6 +3727,14 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAn SetDirty(true); break; } + case convert_to_fake: + { + float startBeat = NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker); + float lengthBeat = NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) - startBeat; + GetAppropriateTiming().SetFakeAtBeat(startBeat,lengthBeat); + SetDirty(true); + break; + } } diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index e01c332c27..35f30f155b 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -386,6 +386,7 @@ public: record, convert_to_pause, convert_to_warp, + convert_to_fake, NUM_ALTER_MENU_CHOICES }; From 7768134149a6dc70155cc52ac9feb1524e994d55 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 17:03:53 -0400 Subject: [PATCH 34/44] Alright pumpervinil, you got your Delay wish. I hope that's enough for you. --- Themes/_fallback/Languages/en.ini | 1 + src/ScreenEdit.cpp | 23 +++++++++++++++++++++++ src/ScreenEdit.h | 1 + 3 files changed, 25 insertions(+) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 01b038adf5..75e0cfdf1b 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -814,6 +814,7 @@ CoinsPerCredit=Coins Per Credit Connection=Connection Convert pause to beats=Convert pause to beats Convert selection to pause=Convert selection to pause +Convert selection to delay=Convert selection to delay Convert selection to warp=Convert selection to Warp Segment Convert selection to fake=Convert selection to Fake Segment Copy=Copy diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index db85c529d5..b5ff78ffae 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -538,6 +538,8 @@ static MenuDef g_AlterMenu( EditMode_Practice, true, true, 0, NULL ), MenuRowDef(ScreenEdit::convert_to_pause, "Convert selection to pause", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_to_delay, "Convert selection to delay", true, + EditMode_Full, true, true, 0, NULL ), MenuRowDef(ScreenEdit::convert_to_warp, "Convert selection to warp", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef(ScreenEdit::convert_to_fake, "Convert selection to fake", true, @@ -3719,6 +3721,27 @@ void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAn m_NoteFieldEdit.m_iEndMarker = -1; break; } + case convert_to_delay: + { + ASSERT_M( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1, "Attempted to convert beats outside the notefield to pauses!" ); + float fMarkerStart = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker) ); + float fMarkerEnd = GetAppropriateTiming().GetElapsedTimeFromBeat( NoteRowToBeat(m_NoteFieldEdit.m_iEndMarker) ); + + // The length of the delay segment we're going to create. This includes time spent in any + // stops in the selection, which will be deleted and subsumed into the new stop. + float fStopLength = fMarkerEnd - fMarkerStart; + + NoteDataUtil::DeleteRows( m_NoteDataEdit, + m_NoteFieldEdit.m_iBeginMarker, + m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker + ); + GetAppropriateTiming().DeleteRows( m_NoteFieldEdit.m_iBeginMarker, + m_NoteFieldEdit.m_iEndMarker-m_NoteFieldEdit.m_iBeginMarker ); + GetAppropriateTiming().SetDelayAtRow( m_NoteFieldEdit.m_iBeginMarker, fStopLength ); + m_NoteFieldEdit.m_iBeginMarker = -1; + m_NoteFieldEdit.m_iEndMarker = -1; + break; + } case convert_to_warp: { float startBeat = NoteRowToBeat(m_NoteFieldEdit.m_iBeginMarker); diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 35f30f155b..f3e4a912e5 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -385,6 +385,7 @@ public: play, record, convert_to_pause, + convert_to_delay, convert_to_warp, convert_to_fake, NUM_ALTER_MENU_CHOICES From 465ed345dbd4fce8533b63a22994a773b78072ca Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 17:05:57 -0400 Subject: [PATCH 35/44] May as well put this in the changelog. --- Docs/Changelog_sm5.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index 3aff3dbb7f..2263fcc511 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -14,6 +14,8 @@ StepMania 5.0 Preview 2 | 20110??? "A" key to enter the Alter Menu when a selection of notes/rows are highlighted. Use the Enter key to enter the old Area Menu for the options that do not depend on selecting NoteData. [Wolfman2000] +* [ScreenEdit] Allow converting selections to Delays, Warps, or Fakes as well + as Stops. Remember, use the Alter Menu for this. [Wolfman2000] 2011/06/09 ---------- From 3123bbaea0fee82b63bc0c4953fa2b55b138dbae Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 21:20:26 -0400 Subject: [PATCH 36/44] Revert 0b67f6b. Perhaps there is a better implementation. --- src/Song.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Song.cpp b/src/Song.cpp index 5bb35928f5..926ac196d1 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -1505,7 +1505,7 @@ public: { RString s = p->GetBackgroundPath(); if( s.empty() ) - s = ""; + return 0; lua_pushstring(L, s); return 1; } From ee742856b21ac027217b38d6a5d7426c91f2a11e Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Fri, 10 Jun 2011 20:39:31 -0500 Subject: [PATCH 37/44] fix this up --- src/Song.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Song.cpp b/src/Song.cpp index 926ac196d1..8cf6d352a7 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -1504,9 +1504,10 @@ public: static int GetBackgroundPath( T* p, lua_State *L ) { RString s = p->GetBackgroundPath(); - if( s.empty() ) - return 0; - lua_pushstring(L, s); + if( !s.empty() ) + lua_pushstring(L, s); + else + lua_pushnil(L); return 1; } static int GetCDTitlePath( T* p, lua_State *L ) { RString s = p->GetCDTitlePath(); if( s.empty() ) return 0; LuaHelpers::Push(L, s); return 1; } From b78c5350e3c7087cc28424f37917aacbf0631365 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 21:40:56 -0400 Subject: [PATCH 38/44] Only load the background if it exists. Took us awhile to find it. --- .../BGAnimations/ScreenEvaluation background/default.lua | 5 ++++- .../default/BGAnimations/ScreenPlayerOptions background.lua | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Themes/default/BGAnimations/ScreenEvaluation background/default.lua b/Themes/default/BGAnimations/ScreenEvaluation background/default.lua index ac0c710158..5cd05e9772 100644 --- a/Themes/default/BGAnimations/ScreenEvaluation background/default.lua +++ b/Themes/default/BGAnimations/ScreenEvaluation background/default.lua @@ -5,7 +5,10 @@ t[#t+1] = Def.ActorFrame { Def.Sprite { OnCommand=function(self) if GAMESTATE:GetCurrentSong() then - self:LoadBackground( GAMESTATE:GetCurrentSong():GetBackgroundPath() ); + local song = GAMESTATE:GetCurrentSong(); + if song:HasBackground() then + self:LoadBackground(song:GetBackgroundPath()); + end; self:scaletoclipped( SCREEN_WIDTH+1,SCREEN_HEIGHT ); (cmd(fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480))(self); else diff --git a/Themes/default/BGAnimations/ScreenPlayerOptions background.lua b/Themes/default/BGAnimations/ScreenPlayerOptions background.lua index a02c0291d9..e7cafc1283 100644 --- a/Themes/default/BGAnimations/ScreenPlayerOptions background.lua +++ b/Themes/default/BGAnimations/ScreenPlayerOptions background.lua @@ -6,7 +6,10 @@ t[#t+1] = Def.ActorFrame { Condition=not GAMESTATE:IsCourseMode(); OnCommand=function(self) if GAMESTATE:GetCurrentSong() then - self:LoadBackground( GAMESTATE:GetCurrentSong():GetBackgroundPath() ); + local song = GAMESTATE:GetCurrentSong(); + if song:HasBackground() then + self:LoadBackground(song:GetBackgroundPath()); + end; self:scaletoclipped( SCREEN_WIDTH+1,SCREEN_HEIGHT ); (cmd(fadebottom,0.25;fadetop,0.25;croptop,48/480;cropbottom,48/480))(self); else From 1b5853c5ea05956ce161d54789373eff6a8b0d53 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Sat, 11 Jun 2011 00:17:47 -0400 Subject: [PATCH 39/44] Make sure the music file exists. Well, better this than a bad access error. --- src/RageSoundReader_Extend.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/RageSoundReader_Extend.cpp b/src/RageSoundReader_Extend.cpp index 0c316c7a50..38beacfa35 100644 --- a/src/RageSoundReader_Extend.cpp +++ b/src/RageSoundReader_Extend.cpp @@ -15,6 +15,7 @@ RageSoundReader_Extend::RageSoundReader_Extend( RageSoundReader *pSource ): RageSoundReader_Filter( pSource ) { + ASSERT_M(pSource, "The music file was not found! Was it deleted or moved while the game was on?"); m_iPositionFrames = pSource->GetNextSourceFrame(); m_StopMode = M_STOP; From fb8c45066aceea9a2143201eb59ca66c7a81f013 Mon Sep 17 00:00:00 2001 From: Colby Klein Date: Fri, 10 Jun 2011 23:24:46 -0700 Subject: [PATCH 40/44] Don't overwrite global Screen table. --- Themes/_fallback/Scripts/02 Other.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Themes/_fallback/Scripts/02 Other.lua b/Themes/_fallback/Scripts/02 Other.lua index f9f2532a6f..ea544d1dd4 100644 --- a/Themes/_fallback/Scripts/02 Other.lua +++ b/Themes/_fallback/Scripts/02 Other.lua @@ -98,16 +98,15 @@ end -- Get a metric from the currently-loading screen. This is only valid while loading -- an actor, such as from File or InitCommand attributes; not from commands. -Screen = { - Metric = function ( sName ) - local sClass = Var "LoadingScreen" - return THEME:GetMetric( sClass, sName ) - end, - String = function ( sName ) - local sClass = Var "LoadingScreen"; - return THEME:GetString( sClass, sName ) - end -}; +Screen.Metric = function ( sName ) + local sClass = Var "LoadingScreen" + return THEME:GetMetric( sClass, sName ) +end + +Screen.String = function ( sName ) + local sClass = Var "LoadingScreen"; + return THEME:GetString( sClass, sName ) +end function TextBannerAfterSet(self,param) local Title=self:GetChild("Title"); From 9737b3f94f03206b78c6468da0912f4f575b2424 Mon Sep 17 00:00:00 2001 From: Colby Klein Date: Fri, 10 Jun 2011 23:43:21 -0700 Subject: [PATCH 41/44] Fix MaskSource. clearzbuffer likes to behave badly. --- Themes/_fallback/Scripts/03 ProductivityHelpers.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Themes/_fallback/Scripts/03 ProductivityHelpers.lua b/Themes/_fallback/Scripts/03 ProductivityHelpers.lua index 0d9fbd2816..4297389fc6 100644 --- a/Themes/_fallback/Scripts/03 ProductivityHelpers.lua +++ b/Themes/_fallback/Scripts/03 ProductivityHelpers.lua @@ -148,7 +148,9 @@ end -- MaskSource([clearzbuffer]) -- Sets an actor up as the source for a mask. Clears zBuffer by default. function Actor:MaskSource(noclear) - self:clearzbuffer(noclear or true) + if noclear == true then + self:clearzbuffer(true) + end self:zwrite(true) self:blend('BlendMode_NoEffect') end From d8cd86af2c95be19da7f545638f1ffc610ccdf97 Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Sat, 11 Jun 2011 01:44:00 -0500 Subject: [PATCH 42/44] lua doc updates --- Docs/Luadoc/Lua.xml | 62 +++++++++++++++++++++++++++++++++++++++++---- Docs/Luadoc/Lua.xsl | 7 ++++- 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index 201f0b6312..4ad7b93c44 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -39,11 +39,8 @@ - - - @@ -57,6 +54,7 @@ + @@ -130,7 +128,6 @@ - @@ -143,6 +140,8 @@ + + @@ -1026,6 +1025,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1093,6 +1138,13 @@ + + + + + + + @@ -2061,5 +2113,5 @@ StepMania 5 v5.0 Preview 1a - 2011-06-04 + 2011-06-11 diff --git a/Docs/Luadoc/Lua.xsl b/Docs/Luadoc/Lua.xsl index 2861185f63..01f3657220 100644 --- a/Docs/Luadoc/Lua.xsl +++ b/Docs/Luadoc/Lua.xsl @@ -395,7 +395,12 @@ $type='bool' or $type='table' or $type='color' or - $type='Enum'"> + $type='Enum' or + $type='ThreadVariable' or + $type='LuaOptionRow' or + $type='ActorDef' or + $type='chunk' or + $type='various'"> From 76c321bdd628b94de68eab7de78b59071f82c067 Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Sat, 11 Jun 2011 01:46:42 -0500 Subject: [PATCH 43/44] make ScreenString and ScreenMetric work for people coming over from sm4a5 or whatnot --- Themes/_fallback/Scripts/01 alias.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Themes/_fallback/Scripts/01 alias.lua b/Themes/_fallback/Scripts/01 alias.lua index 126d9c69ef..e0e3841f07 100644 --- a/Themes/_fallback/Scripts/01 alias.lua +++ b/Themes/_fallback/Scripts/01 alias.lua @@ -21,3 +21,11 @@ local _screen = { cx = SCREEN_CENTER_X, cy = SCREEN_CENTER_Y } + +if Screen.String then + ScreenString = Screen.String +end + +if Screen.Metric then + ScreenMetric = Screen.Metric +end \ No newline at end of file From e1c899f98dde0a200d31e617b19740e3c0d98708 Mon Sep 17 00:00:00 2001 From: AJ Kelly Date: Sat, 11 Jun 2011 02:16:12 -0500 Subject: [PATCH 44/44] remove unused define --- src/Background.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Background.cpp b/src/Background.cpp index 2761fd3b18..19e21abf7a 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -27,7 +27,6 @@ static ThemeMetric LEFT_EDGE ("Background","LeftEdge"); static ThemeMetric TOP_EDGE ("Background","TopEdge"); static ThemeMetric RIGHT_EDGE ("Background","RightEdge"); static ThemeMetric BOTTOM_EDGE ("Background","BottomEdge"); -#define RECT_BACKGROUND RectF (LEFT_EDGE,TOP_EDGE,RIGHT_EDGE,BOTTOM_EDGE) static ThemeMetric CLAMP_OUTPUT_PERCENT ("Background","ClampOutputPercent"); static ThemeMetric SHOW_DANCING_CHARACTERS ("Background","ShowDancingCharacters"); static ThemeMetric USE_STATIC_BG ("Background","UseStaticBackground");