diff --git a/stepmania/src/Course.cpp b/stepmania/src/Course.cpp index 450bc65ee7..fc211f3eba 100644 --- a/stepmania/src/Course.cpp +++ b/stepmania/src/Course.cpp @@ -559,6 +559,8 @@ CString Course::GetDisplayName() const /* XXX: if !HasCourseDifficulty(cd), return NULL instead of COURSE_DIFFICULTY_REGULAR */ Trail* Course::GetTrail( StepsType st, CourseDifficulty cd ) const { + ASSERT( cd != COURSE_DIFFICULTY_INVALID ); + // // Look in the Trail cache // @@ -570,6 +572,14 @@ Trail* Course::GetTrail( StepsType st, CourseDifficulty cd ) const // Trail &trail = m_TrailCache[st][cd]; trail = Trail(); + GetTrailSorted( st, cd, trail ); + + m_TrailCacheValid[st][cd] = true; + return &m_TrailCache[st][cd]; +} + +void Course::GetTrailSorted( StepsType st, CourseDifficulty cd, Trail &trail ) const +{ GetTrailUnsorted( st, cd, trail ); if( this->m_bSortByMeter ) @@ -597,13 +607,12 @@ Trail* Course::GetTrail( StepsType st, CourseDifficulty cd ) const for( unsigned i = 0; i < trail.m_vEntries.size(); ++i ) trail.m_vEntries[i] = entries[i].entry; } - - m_TrailCacheValid[st][cd] = true; - return &m_TrailCache[st][cd]; } void Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const { + trail.Init(); + // // Construct a new Trail, add it to the cache, then return it. // @@ -802,12 +811,10 @@ void Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) /* If we have a manually-entered meter for this difficulty, use it. */ if( m_iCustomMeter[cd] != -1 ) - trail.m_iMeter = m_iCustomMeter[cd]; - else - trail.m_iMeter = (int) roundf( trail.GetAverageMeter() ); + trail.m_iSpecifiedMeter = m_iCustomMeter[cd]; } -void Course::GetTrails( vector &out, StepsType st ) const +void Course::GetTrails( vector &AddTo, StepsType st ) const { FOREACH_CourseDifficulty( cd ) { @@ -817,7 +824,7 @@ void Course::GetTrails( vector &out, StepsType st ) const Trail *pTrail = GetTrail( st, cd ); if( pTrail == NULL ) continue; - out.push_back( pTrail ); + AddTo.push_back( pTrail ); } } @@ -842,7 +849,7 @@ bool Course::AllSongsAreFixed() const return true; } -void Course::ClearCache() +void Course::RegenTrails() { ZERO( m_TrailCacheValid ); } @@ -989,15 +996,6 @@ bool Course::IsRanking() const return false; } -float Course::GetMeter( StepsType st, CourseDifficulty cd ) const -{ - /* If we have a manually-entered meter for this difficulty, use it. */ - if( m_iCustomMeter[cd] != -1 ) - return (float)m_iCustomMeter[cd]; - - return roundf( GetTrail(st,cd)->GetAverageMeter() ); -} - /* * (c) 2001-2004 Chris Danford, Glenn Maynard * All rights reserved. diff --git a/stepmania/src/Course.h b/stepmania/src/Course.h index f3313b2c6f..2724466992 100644 --- a/stepmania/src/Course.h +++ b/stepmania/src/Course.h @@ -96,7 +96,7 @@ public: // Dereferences course_entries and returns only the playable Songs and Steps Trail* GetTrail( StepsType st, CourseDifficulty cd ) const; - void GetTrails( vector &out, StepsType st ) const; + void GetTrails( vector &AddTo, StepsType st ) const; float GetMeter( StepsType st, CourseDifficulty cd ) const; bool HasMods() const; bool AllSongsAreFixed() const; @@ -129,10 +129,11 @@ public: void UpdateCourseStats( StepsType st ); - /* Call per-screen, and if song or notes pointers change: */ - void ClearCache(); + /* Call to generate Trails with random entries and if song or notes pointers change. */ + void RegenTrails(); private: + void GetTrailSorted( StepsType st, CourseDifficulty cd, Trail &trail ) const; void GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) const; mutable Trail m_TrailCache[NUM_STEPS_TYPES][NUM_COURSE_DIFFICULTIES]; diff --git a/stepmania/src/CourseContentsList.cpp b/stepmania/src/CourseContentsList.cpp index 80c1d7900f..1e27d33edf 100644 --- a/stepmania/src/CourseContentsList.cpp +++ b/stepmania/src/CourseContentsList.cpp @@ -48,8 +48,10 @@ CourseContentsList::CourseContentsList() } -void CourseContentsList::SetFromCourse( const Course* pCourse ) +void CourseContentsList::SetFromGameState() { + Course* pCourse = GAMESTATE->m_pCurCourse; + if( pCourse == NULL ) { m_iNumContents = 0; @@ -59,16 +61,19 @@ void CourseContentsList::SetFromCourse( const Course* pCourse ) Trail* pTrail[NUM_PLAYERS]; FOREACH_PlayerNumber(pn) { - pTrail[pn] = pCourse->GetTrail( GAMESTATE->GetCurrentStyleDef()->m_StepsType, GAMESTATE->m_PreferredCourseDifficulty[pn] ); + pTrail[pn] = GAMESTATE->m_pCurTrail[pn]; } // FIXME: Is there a better way to handle when players don't have // the same number of TrailEntries? // They have to have the same number, and of the same songs, or gameplay // isn't going to line up. + Trail* pMasterTrail = pTrail[GAMESTATE->m_MasterPlayerNumber]; + int iNumEntriesToShow = min((int)pMasterTrail->m_vEntries.size(), MAX_TOTAL_CONTENTS); + m_iNumContents = 0; - for( int i=0; im_vEntries.size(), MAX_TOTAL_CONTENTS); i++ ) + for( int i=0; i &apCours RageTimer foo; course_sort_val.clear(); for(unsigned i = 0; i < apCourses.size(); ++i) - course_sort_val[apCourses[i]] = apCourses[i]->GetMeter( GAMESTATE->GetCurrentStyleDef()->m_StepsType, COURSE_DIFFICULTY_REGULAR ); + { + Trail* pTrail = apCourses[i]->GetTrail( GAMESTATE->GetCurrentStyleDef()->m_StepsType, COURSE_DIFFICULTY_REGULAR ); + course_sort_val[apCourses[i]] = pTrail->GetMeter(); + } sort( apCourses.begin(), apCourses.end(), CompareCoursePointersByTitle ); stable_sort( apCourses.begin(), apCourses.end(), CompareCoursePointersBySortValueAscending ); diff --git a/stepmania/src/DifficultyIcon.cpp b/stepmania/src/DifficultyIcon.cpp index 544276ec0c..1704b44ff6 100644 --- a/stepmania/src/DifficultyIcon.cpp +++ b/stepmania/src/DifficultyIcon.cpp @@ -15,6 +15,7 @@ #include "GameState.h" #include "RageDisplay.h" #include "arch/ArchHooks/ArchHooks.h" +#include "Trail.h" DifficultyIcon::DifficultyIcon() { @@ -47,6 +48,14 @@ void DifficultyIcon::SetFromSteps( PlayerNumber pn, Steps* pSteps ) SetFromDifficulty( pn, pSteps->GetDifficulty() ); } +void DifficultyIcon::SetFromTrail( PlayerNumber pn, Trail* pTrail ) +{ + if( pTrail == NULL ) + m_bBlank = true; + else + SetFromCourseDifficulty( pn, pTrail->m_CourseDifficulty ); +} + void DifficultyIcon::SetFromDifficulty( PlayerNumber pn, Difficulty dc ) { m_bBlank = false; @@ -58,7 +67,7 @@ void DifficultyIcon::SetFromDifficulty( PlayerNumber pn, Difficulty dc ) } } -void DifficultyIcon::SetFromCourseDifficulty( PlayerNumber pn, CourseDifficulty cd ) +void DifficultyIcon::SetFromCourseDifficulty( PlayerNumber pn, CourseDifficulty cd ) { m_bBlank = false; switch( cd ) diff --git a/stepmania/src/DifficultyIcon.h b/stepmania/src/DifficultyIcon.h index 50eb13a41b..dd3c91791f 100644 --- a/stepmania/src/DifficultyIcon.h +++ b/stepmania/src/DifficultyIcon.h @@ -7,12 +7,11 @@ #include "PlayerNumber.h" #include "GameConstantsAndTypes.h" class Steps; +class Trail; class DifficultyIcon : public Sprite { - bool m_bBlank; - public: DifficultyIcon(); virtual bool EarlyAbortDraw() { return m_bBlank || Sprite::EarlyAbortDraw(); } @@ -20,8 +19,12 @@ public: bool Load( CString sFilePath ); void SetFromSteps( PlayerNumber pn, Steps* pSteps ); + void SetFromTrail( PlayerNumber pn, Trail* pTrail ); void SetFromDifficulty( PlayerNumber pn, Difficulty dc ); void SetFromCourseDifficulty( PlayerNumber pn, CourseDifficulty cd ); + +protected: + bool m_bBlank; }; #endif diff --git a/stepmania/src/DifficultyMeter.cpp b/stepmania/src/DifficultyMeter.cpp index 671db03ef1..2f4a4b15c1 100644 --- a/stepmania/src/DifficultyMeter.cpp +++ b/stepmania/src/DifficultyMeter.cpp @@ -127,46 +127,7 @@ void DifficultyMeter::SetFromTrail( const Trail* pTrail ) default: ASSERT(0); } - -/* - if( pTrail->m_iMeter <= 1 ) - FakeDifficulty = DIFFICULTY_BEGINNER; - else if( pTrail->m_iMeter <= 3 ) - FakeDifficulty = DIFFICULTY_EASY; - else if( pTrail->m_iMeter <= 6 ) - FakeDifficulty = DIFFICULTY_MEDIUM; - else if( pTrail->m_iMeter <= 9 ) - FakeDifficulty = DIFFICULTY_HARD; - else - FakeDifficulty = DIFFICULTY_CHALLENGE; -*/ - SetFromMeterAndDifficulty( pTrail->m_iMeter, FakeDifficulty ); - SetDifficulty( DifficultyToString(FakeDifficulty) + "Course" ); -} - -void DifficultyMeter::SetFromCourse( const Course* pCourse, PlayerNumber pn ) -{ - if( pCourse == NULL ) - { - Unset(); - return; - } - - StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; - CourseDifficulty cd = GAMESTATE->m_PreferredCourseDifficulty[pn]; - const int meter = (int) roundf( pCourse->GetMeter(st,cd) ); - - // XXX metrics - Difficulty FakeDifficulty; - switch( cd ) - { - case COURSE_DIFFICULTY_EASY: FakeDifficulty = DIFFICULTY_EASY; break; - case COURSE_DIFFICULTY_REGULAR: FakeDifficulty = DIFFICULTY_MEDIUM; break; - case COURSE_DIFFICULTY_DIFFICULT: FakeDifficulty = DIFFICULTY_HARD; break; - default: ASSERT(0); - } - - SetFromMeterAndDifficulty( meter, FakeDifficulty ); + SetFromMeterAndDifficulty( pTrail->GetMeter(), FakeDifficulty ); SetDifficulty( DifficultyToString(FakeDifficulty) + "Course" ); } @@ -201,9 +162,9 @@ void DifficultyMeter::SetFromGameState( PlayerNumber pn ) { if( GAMESTATE->IsCourseMode() ) { - Course* pCourse = GAMESTATE->m_pCurCourse; - if( pCourse ) - SetFromCourse( pCourse, pn ); + Trail* pTrail = GAMESTATE->m_pCurTrail[pn]; + if( pTrail ) + SetFromTrail( pTrail ); else SetFromCourseDifficulty( GAMESTATE->m_PreferredCourseDifficulty[pn] ); } diff --git a/stepmania/src/DifficultyMeter.h b/stepmania/src/DifficultyMeter.h index 93f0a1708c..6912e6d77f 100644 --- a/stepmania/src/DifficultyMeter.h +++ b/stepmania/src/DifficultyMeter.h @@ -18,7 +18,6 @@ #include "ActorUtil.h" class Steps; -class Course; class Trail; @@ -31,7 +30,6 @@ public: void SetFromGameState( PlayerNumber pn ); void SetFromMeterAndDifficulty( int iMeter, Difficulty dc ); void SetFromSteps( const Steps* pSteps ); - void SetFromCourse( const Course* pCourse, PlayerNumber pn ); /* deprecated */ void SetFromTrail( const Trail* pTrail ); void Unset(); diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index e3e14e38d6..39483d62e5 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -124,7 +124,7 @@ void GameState::Reset() FOREACH_PlayerNumber( p ) { m_PreferredDifficulty[p] = DIFFICULTY_INVALID; - m_PreferredCourseDifficulty[p] = COURSE_DIFFICULTY_REGULAR; + m_PreferredCourseDifficulty[p] = COURSE_DIFFICULTY_INVALID; } m_SortOrder = SORT_INVALID; m_PlayMode = PLAY_MODE_INVALID; @@ -1046,10 +1046,9 @@ bool GameState::IsDisqualified( PlayerNumber pn ) if( GAMESTATE->IsCourseMode() ) { - return GAMESTATE->m_PlayerOptions[pn].IsEasierForCourse( + return GAMESTATE->m_PlayerOptions[pn].IsEasierForCourseAndTrail( GAMESTATE->m_pCurCourse, - GAMESTATE->GetCurrentStyleDef()->m_StepsType, - GAMESTATE->m_PreferredCourseDifficulty[pn] ); + GAMESTATE->m_pCurTrail[pn] ); } else { @@ -1492,15 +1491,16 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector &asFeatsOu case PLAY_MODE_ENDLESS: { CHECKPOINT; - StepsType st = this->GetCurrentStyleDef()->m_StepsType; - Course* pCourse = this->m_pCurCourse; + StepsType st = GetCurrentStyleDef()->m_StepsType; + Course* pCourse = m_pCurCourse; ASSERT( pCourse ); - CourseDifficulty cd = this->m_PreferredCourseDifficulty[pn]; + Trail *pTrail = m_pCurTrail[pn]; + ASSERT( pTrail ); + CourseDifficulty cd = pTrail->m_CourseDifficulty; // Find Machine Records { Profile* pProfile = PROFILEMAN->GetMachineProfile(); - Trail *pTrail = pCourse->GetTrail( st, cd ); HighScoreList &hsl = pProfile->GetCourseHighScoreList( pCourse, pTrail ); for( unsigned i=0; im_PlayMode == PLAY_MODE_RAVE; + if( GAMESTATE->m_PlayMode == PLAY_MODE_RAVE ) + return true; + if( IsCourseMode() ) + return PREFSMAN->m_bLockCourseDifficulties; + return false; } -bool GameState::ChangeDifficulty( PlayerNumber pn, Difficulty dc ) +bool GameState::ChangePreferredDifficulty( PlayerNumber pn, Difficulty dc ) { this->m_PreferredDifficulty[pn] = dc; if( DifficultiesLocked() ) @@ -1657,7 +1661,7 @@ bool GameState::ChangeDifficulty( PlayerNumber pn, Difficulty dc ) return true; } -bool GameState::ChangeDifficulty( PlayerNumber pn, int dir ) +bool GameState::ChangePreferredDifficulty( PlayerNumber pn, int dir ) { // FIXME: This clamps to between the min and the max difficulty, but // it really should round to the nearest difficulty that's in @@ -1681,7 +1685,7 @@ bool GameState::ChangeDifficulty( PlayerNumber pn, int dir ) if( diff < mind || diff > maxd ) return false; - return ChangeDifficulty( pn, diff ); + return ChangePreferredDifficulty( pn, diff ); } static void GetCourseDifficultiesToShow( set &ret ) @@ -1711,7 +1715,18 @@ static void GetCourseDifficultiesToShow( set &ret ) ret = cache; } -bool GameState::ChangeCourseDifficulty( PlayerNumber pn, int dir ) +bool GameState::ChangePreferredCourseDifficulty( PlayerNumber pn, CourseDifficulty cd ) +{ + m_PreferredCourseDifficulty[pn] = cd; + + if( PREFSMAN->m_bLockCourseDifficulties ) + for( int p = 0; p < NUM_PLAYERS; ++p ) + m_PreferredCourseDifficulty[p] = m_PreferredCourseDifficulty[pn]; + + return true; +} + +bool GameState::ChangePreferredCourseDifficulty( PlayerNumber pn, int dir ) { set asDiff; GetCourseDifficultiesToShow( asDiff ); @@ -1723,13 +1738,7 @@ bool GameState::ChangeCourseDifficulty( PlayerNumber pn, int dir ) return false; } while( asDiff.find(cd) == asDiff.end() ); - this->m_PreferredCourseDifficulty[pn] = cd; - - if( PREFSMAN->m_bLockCourseDifficulties ) - for( int p = 0; p < NUM_PLAYERS; ++p ) - m_PreferredCourseDifficulty[p] = m_PreferredCourseDifficulty[pn]; - - return true; + return ChangePreferredCourseDifficulty( pn, cd ); } bool GameState::IsCourseDifficultyShown( CourseDifficulty cd ) diff --git a/stepmania/src/GameState.h b/stepmania/src/GameState.h index b08955ab24..e3e3a4d655 100644 --- a/stepmania/src/GameState.h +++ b/stepmania/src/GameState.h @@ -63,9 +63,10 @@ public: bool m_bIsOnSystemMenu; // system screens will not be effected by the operator key -- Miryokuteki CourseDifficulty m_PreferredCourseDifficulty[NUM_PLAYERS]; // used in nonstop bool DifficultiesLocked(); - bool ChangeDifficulty( PlayerNumber pn, Difficulty dc ); - bool ChangeDifficulty( PlayerNumber pn, int dir ); - bool ChangeCourseDifficulty( PlayerNumber pn, int dir ); + bool ChangePreferredDifficulty( PlayerNumber pn, Difficulty dc ); + bool ChangePreferredDifficulty( PlayerNumber pn, int dir ); + bool ChangePreferredCourseDifficulty( PlayerNumber pn, CourseDifficulty cd ); + bool ChangePreferredCourseDifficulty( PlayerNumber pn, int dir ); bool IsCourseDifficultyShown( CourseDifficulty cd ); Difficulty GetEasiestNotesDifficulty() const; RageTimer m_timeGameStarted; // from the moment the first player pressed Start @@ -150,7 +151,7 @@ public: Course* m_pCurCourse; // The last Course that the user manually changed to. Course* m_pPreferredCourse; - Course* m_pCurTrail[NUM_PLAYERS]; + Trail* m_pCurTrail[NUM_PLAYERS]; // diff --git a/stepmania/src/GrooveRadar.h b/stepmania/src/GrooveRadar.h index 8a8acdc426..85bd4e1264 100644 --- a/stepmania/src/GrooveRadar.h +++ b/stepmania/src/GrooveRadar.h @@ -23,6 +23,11 @@ class GrooveRadar : public ActorFrame public: GrooveRadar(); + void SetEmpty( PlayerNumber pn ) + { + SetFromSteps( pn, NULL ); + } + void SetFromSteps( PlayerNumber pn, Steps* pSteps ) // NULL means no Song { m_GrooveRadarValueMap.SetFromSteps( pn, pSteps ); diff --git a/stepmania/src/ModeChoice.cpp b/stepmania/src/ModeChoice.cpp index 6113711bf8..cf5203054e 100644 --- a/stepmania/src/ModeChoice.cpp +++ b/stepmania/src/ModeChoice.cpp @@ -24,14 +24,15 @@ void ModeChoice::Init() m_style = STYLE_INVALID; m_pm = PLAY_MODE_INVALID; m_dc = DIFFICULTY_INVALID; + m_CourseDifficulty = COURSE_DIFFICULTY_INVALID; m_sModifiers = ""; m_sAnnouncer = ""; m_sScreen = ""; m_pSong = NULL; m_pSteps = NULL; m_pCourse = NULL; + m_pTrail = NULL; m_pCharacter = NULL; - m_CourseDifficulty = COURSE_DIFFICULTY_INVALID; } bool CompareSongOptions( const SongOptions &so1, const SongOptions &so2 ); @@ -39,7 +40,7 @@ bool CompareSongOptions( const SongOptions &so1, const SongOptions &so2 ); bool ModeChoice::DescribesCurrentModeForAllPlayers() const { FOREACH_PlayerNumber( pn ) - if( !DescribesCurrentMode( (PlayerNumber) pn) ) + if( !DescribesCurrentMode(pn) ) return false; return true; @@ -87,7 +88,7 @@ bool ModeChoice::DescribesCurrentMode( PlayerNumber pn ) const return false; if( m_pCharacter && GAMESTATE->m_pCurCharacters[pn] != m_pCharacter ) return false; - if( m_CourseDifficulty != COURSE_DIFFICULTY_INVALID && GAMESTATE->m_PreferredCourseDifficulty[pn] != m_CourseDifficulty ) + if( m_pTrail && GAMESTATE->m_pCurTrail[pn] != m_pTrail ) return false; return true; @@ -416,7 +417,7 @@ void ModeChoice::Apply( PlayerNumber pn ) const } } if( m_dc != DIFFICULTY_INVALID && pn != PLAYER_INVALID ) - GAMESTATE->m_PreferredDifficulty[pn] = m_dc; + GAMESTATE->ChangePreferredDifficulty( pn, m_dc ); if( m_sAnnouncer != "" ) ANNOUNCER->SwitchAnnouncer( m_sAnnouncer ); if( m_sModifiers != "" ) @@ -433,15 +434,12 @@ void ModeChoice::Apply( PlayerNumber pn ) const GAMESTATE->m_pCurCourse = m_pCourse; GAMESTATE->m_pPreferredCourse = m_pCourse; } + if( m_pTrail ) + GAMESTATE->m_pCurSteps[pn] = m_pSteps; + if( m_CourseDifficulty != COURSE_DIFFICULTY_INVALID ) + GAMESTATE->ChangePreferredCourseDifficulty( pn, m_CourseDifficulty ); if( m_pCharacter ) GAMESTATE->m_pCurCharacters[pn] = m_pCharacter; - if( m_CourseDifficulty != COURSE_DIFFICULTY_INVALID ) - { - GAMESTATE->m_PreferredCourseDifficulty[pn] = m_CourseDifficulty; - if( PREFSMAN->m_bLockCourseDifficulties ) - for( int p = 0; p < NUM_PLAYERS; ++p ) - GAMESTATE->m_PreferredCourseDifficulty[p] = GAMESTATE->m_PreferredCourseDifficulty[pn]; - } // HACK: Set life type to BATTERY just once here so it happens once and // we don't override the user's changes if they back out. diff --git a/stepmania/src/ModeChoice.h b/stepmania/src/ModeChoice.h index 8a4e321464..222f819287 100644 --- a/stepmania/src/ModeChoice.h +++ b/stepmania/src/ModeChoice.h @@ -11,6 +11,7 @@ class Song; class Steps; class Course; +class Trail; class Character; struct ModeChoice // used in SelectMode @@ -34,14 +35,15 @@ struct ModeChoice // used in SelectMode Style m_style; PlayMode m_pm; Difficulty m_dc; + CourseDifficulty m_CourseDifficulty; CString m_sAnnouncer; CString m_sModifiers; CString m_sScreen; Song* m_pSong; Steps* m_pSteps; Course* m_pCourse; + Trail* m_pTrail; Character* m_pCharacter; - CourseDifficulty m_CourseDifficulty; }; #endif diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index be66e81767..3fcc595c85 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -799,7 +799,7 @@ void MusicWheel::RebuildMusicWheelItems() } -void MusicWheel::NotesChanged( PlayerNumber pn ) // update grade graphics and top score +void MusicWheel::NotesOrTrailChanged( PlayerNumber pn ) // update grade graphics and top score { for( int i=0; im_pCurSteps[m_PlayerNumber] ) return; - if( (g_Contents[c].req&NEED_COURSE) && !GAMESTATE->m_pCurCourse ) + if( (g_Contents[c].req&NEED_COURSE) && !GAMESTATE->m_pCurTrail[m_PlayerNumber] ) return; if( (g_Contents[c].req&NEED_PROFILE) && !PROFILEMAN->IsUsingProfile( m_PlayerNumber ) ) return; @@ -155,18 +155,14 @@ void PaneDisplay::SetContent( PaneContents c ) const Steps *pSteps = GAMESTATE->m_pCurSteps[m_PlayerNumber]; StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; const Course *pCourse = GAMESTATE->m_pCurCourse; - const CourseDifficulty cd = GAMESTATE->m_PreferredCourseDifficulty[m_PlayerNumber]; - const Trail *pTrail = pCourse ? pCourse->GetTrail(st,cd) : NULL; + const Trail *pTrail = GAMESTATE->m_pCurTrail[m_PlayerNumber]; RadarValues rv; if( g_Contents[c].req&NEED_NOTES ) - rv = GAMESTATE->m_pCurSteps[m_PlayerNumber]->GetRadarValues(); + rv = pSteps->GetRadarValues(); else if( g_Contents[c].req&NEED_COURSE ) - { - ASSERT( pCourse ); rv = pTrail->GetRadarValues(); - } float val = 0; CString str; diff --git a/stepmania/src/PlayerOptions.cpp b/stepmania/src/PlayerOptions.cpp index 2284acd0a0..2faf420c3a 100644 --- a/stepmania/src/PlayerOptions.cpp +++ b/stepmania/src/PlayerOptions.cpp @@ -561,10 +561,10 @@ bool PlayerOptions::IsEasierForSongAndSteps( Song* pSong, Steps* pSteps ) return false; } -bool PlayerOptions::IsEasierForCourse( Course* pCourse, StepsType st, CourseDifficulty cd ) +bool PlayerOptions::IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail ) { ASSERT( pCourse ); - Trail *pTrail = pCourse->GetTrail( st, cd ); + ASSERT( pTrail ); FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) { diff --git a/stepmania/src/PlayerOptions.h b/stepmania/src/PlayerOptions.h index 6e5a20fb15..1439bda1aa 100644 --- a/stepmania/src/PlayerOptions.h +++ b/stepmania/src/PlayerOptions.h @@ -6,6 +6,7 @@ class Song; class Steps; class Course; +class Trail; #include "GameConstantsAndTypes.h" @@ -136,7 +137,7 @@ struct PlayerOptions // return true if any mods being used will make the song(s) easier bool IsEasierForSongAndSteps( Song* pSong, Steps* pSteps ); - bool IsEasierForCourse( Course* pCourse, StepsType st, CourseDifficulty cd ); + bool IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail ); }; #endif diff --git a/stepmania/src/ProfileHtml.cpp b/stepmania/src/ProfileHtml.cpp index 69102d1478..c7e771ec7f 100644 --- a/stepmania/src/ProfileHtml.cpp +++ b/stepmania/src/ProfileHtml.cpp @@ -888,8 +888,8 @@ bool PrintPercentCompleteForStepsType( RageFile &f, const Profile *pProfile, Ste * style is set. */ if( GAMESTATE->m_CurStyle == STYLE_INVALID ) GAMESTATE->m_CurStyle = STYLE_DANCE_SINGLE; - float fMeter = pCourse->GetMeter(st,cd); - TranslatedWrite(f, ssprintf("(%.2f)",fMeter) ); + int iMeter = pTrail->GetMeter(); + TranslatedWrite(f, ssprintf("(%d)",iMeter) ); HighScore hs = pProfile->GetCourseHighScoreList(pCourse,pTrail).GetTopScore(); Grade grade = hs.grade; if( grade != GRADE_NO_DATA ) diff --git a/stepmania/src/RageUtil.h b/stepmania/src/RageUtil.h index dea8b01343..6ac276e6b3 100644 --- a/stepmania/src/RageUtil.h +++ b/stepmania/src/RageUtil.h @@ -45,21 +45,29 @@ inline unsigned long max(unsigned long a, unsigned int b) { return a > b? a:b; } // Do the multiply before the divide to that integer scales have more precision. #define SCALE(x, l1, h1, l2, h2) (((x) - (l1)) * ((h2) - (l2)) / ((h1) - (l1)) + (l2)) -#define CLAMP(x, l, h) {if (x > h) x = h; else if (x < l) x = l;} +inline bool CLAMP(int &x, int l, int h) +{ + if (x > h) { x = h; return true; } + else if (x < l) { x = l; return true; } + return false; +} +inline bool CLAMP(float &x, float l, float h) +{ + if (x > h) { x = h; return true; } + else if (x < l) { x = l; return true; } + return false; +} inline void wrap( int &x, int n) { if (x<0) x += ((-x/n)+1)*n; - x %= n; } - inline void wrap( float &x, float n) { if (x<0) x += truncf(((-x/n)+1))*n; - x = fmodf(x,n); } diff --git a/stepmania/src/ScreenEvaluation.cpp b/stepmania/src/ScreenEvaluation.cpp index 0effda09da..7bafdb8368 100644 --- a/stepmania/src/ScreenEvaluation.cpp +++ b/stepmania/src/ScreenEvaluation.cpp @@ -396,7 +396,7 @@ void ScreenEvaluation::Init() m_DifficultyMeter[p].SetFromSteps( GAMESTATE->m_pCurSteps[p] ); break; case course: - m_DifficultyMeter[p].SetFromCourse( GAMESTATE->m_pCurCourse, p ); + m_DifficultyMeter[p].SetFromTrail( GAMESTATE->m_pCurTrail[p] ); break; default: ASSERT(0); @@ -969,9 +969,8 @@ void ScreenEvaluation::CommitScores( { Course* pCourse = GAMESTATE->m_pCurCourse; ASSERT( pCourse ); - CourseDifficulty cd = GAMESTATE->m_PreferredCourseDifficulty[p]; StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; - Trail* pTrail = pCourse->GetTrail( st, cd ); + Trail* pTrail = GAMESTATE->m_pCurTrail[p]; // don't save scores for a failed Nonstop // DO save scores for a failed Oni/Endless @@ -1021,8 +1020,7 @@ void ScreenEvaluation::CommitScores( { Course* pCourse = GAMESTATE->m_pCurCourse; ASSERT( pCourse ); - CourseDifficulty cd = GAMESTATE->m_PreferredCourseDifficulty[p]; - Trail *pTrail = pCourse->GetTrail( st, cd ); + Trail *pTrail = GAMESTATE->m_pCurTrail[p]; ASSERT( pTrail ); pHSL = &pProfile->GetCourseHighScoreList( pCourse, pTrail ); } diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index 38df10b54a..4bee7627d9 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -192,23 +192,23 @@ void ScreenGameplay::Init() { FOREACH_EnabledPlayer(p) { - CourseDifficulty cd = GAMESTATE->m_PreferredCourseDifficulty[p]; - Trail* pTrail = pCourse->GetTrail( st, cd ); + Trail* pTrail = GAMESTATE->m_pCurTrail[p]; PROFILEMAN->IncrementCoursePlayCount( pCourse, pTrail, p ); } } m_apSongsQueue.clear(); PlayerNumber pnMaster = GAMESTATE->m_MasterPlayerNumber; - Trail *pTrail = pCourse->GetTrail( st, GAMESTATE->m_PreferredCourseDifficulty[pnMaster] ); + Trail *pTrail = GAMESTATE->m_pCurTrail[pnMaster]; FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) { m_apSongsQueue.push_back( e->pSong ); } - FOREACH_PlayerNumber(p) + FOREACH_EnabledPlayer(p) { - Trail *pTrail = pCourse->GetTrail( st, GAMESTATE->m_PreferredCourseDifficulty[p] ); + Trail *pTrail = GAMESTATE->m_pCurTrail[p]; + ASSERT( pTrail ); m_vpStepsQueue[p].clear(); m_asModifiersQueue[p].clear(); diff --git a/stepmania/src/ScreenNameEntryTraditional.cpp b/stepmania/src/ScreenNameEntryTraditional.cpp index bdc39767ce..a6ee7f8b7c 100644 --- a/stepmania/src/ScreenNameEntryTraditional.cpp +++ b/stepmania/src/ScreenNameEntryTraditional.cpp @@ -323,8 +323,7 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S Steps* pSteps = ss.pSteps[p]; Course* pCourse = GAMESTATE->m_pCurCourse; StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; - CourseDifficulty cd = GAMESTATE->m_PreferredCourseDifficulty[p]; - Trail* pTrail = pCourse ? pCourse->GetTrail( st, cd ) : NULL; + Trail* pTrail = GAMESTATE->m_pCurTrail[p]; int iHighScoreIndex = -1; // -1 means "out of ranking" Grade grade = ss.GetGrade( p ); @@ -341,7 +340,7 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S const HighScoreList& hsl = GAMESTATE->IsCourseMode() ? - PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse, pTrail) : + PROFILEMAN->GetMachineProfile()->GetCourseHighScoreList(pCourse,pTrail) : PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSong,pSteps); for( unsigned h=0; hGetPathToG("ScreenNameEntryTraditional grades") ); - display.m_Grade.SetGrade( (PlayerNumber)p, grade ); + display.m_Grade.SetGrade( p, grade ); SET_ON( display.m_Grade ); this->AddChild( &display.m_Grade ); } @@ -386,14 +385,14 @@ ScreenNameEntryTraditional::ScreenNameEntryTraditional( CString sClassName ) : S display.m_Difficulty.SetName( ssprintf("DifficultyP%i",p+1) ); display.m_Difficulty.Load( THEME->GetPathToG("ScreenNameEntryTraditional difficulty icons") ); if( GAMESTATE->IsCourseMode() ) - display.m_Difficulty.SetFromCourseDifficulty( (PlayerNumber)p, GAMESTATE->m_PreferredCourseDifficulty[p] ); + display.m_Difficulty.SetFromTrail( p, pTrail ); else - display.m_Difficulty.SetFromSteps( (PlayerNumber)p, pSteps ); + display.m_Difficulty.SetFromSteps( p, pSteps ); SET_ON( display.m_Difficulty ); this->AddChild( &display.m_Difficulty ); display.m_textScore.SetName( "ScreenNameEntryTraditional Percent" ); - display.m_textScore.Load( (PlayerNumber)p, &ss, false ); + display.m_textScore.Load( p, &ss, false ); display.m_textScore.SetName( ssprintf("ScoreP%i",p+1) ); SET_ON( display.m_textScore ); this->AddChild( &display.m_textScore ); diff --git a/stepmania/src/ScreenPlayerOptions.cpp b/stepmania/src/ScreenPlayerOptions.cpp index 77c718e1e2..d5b3d3f089 100644 --- a/stepmania/src/ScreenPlayerOptions.cpp +++ b/stepmania/src/ScreenPlayerOptions.cpp @@ -175,25 +175,22 @@ void ScreenPlayerOptions::UpdateDisqualified() { // save current player options PlayerOptions po[2]; + + FOREACH_PlayerNumber( p ) { - FOREACH_PlayerNumber( p ) - { - po[p] = GAMESTATE->m_PlayerOptions[p]; - } + po[p] = GAMESTATE->m_PlayerOptions[p]; } // export the currently selection options, which will fill GAMESTATE->m_PlayerOptions ScreenOptionsMaster::ExportOptions(); + FOREACH_HumanPlayer( p ) { - FOREACH_PlayerNumber( p ) - { - bool bIsHandicap = GAMESTATE->IsDisqualified((PlayerNumber)p); - - m_sprDisqualify[p]->SetHidden( !bIsHandicap ); + bool bIsHandicap = GAMESTATE->IsDisqualified(p); + + m_sprDisqualify[p]->SetHidden( !bIsHandicap ); - // restore previous player options in case the user escapes back after this - GAMESTATE->m_PlayerOptions[p] = po[p]; - } + // restore previous player options in case the user escapes back after this + GAMESTATE->m_PlayerOptions[p] = po[p]; } } diff --git a/stepmania/src/ScreenSelectMusic.cpp b/stepmania/src/ScreenSelectMusic.cpp index b57616f028..f4daf3d3c0 100644 --- a/stepmania/src/ScreenSelectMusic.cpp +++ b/stepmania/src/ScreenSelectMusic.cpp @@ -68,6 +68,8 @@ ScreenSelectMusic::ScreenSelectMusic( CString sClassName ) : ScreenWithMenuEleme LIGHTSMAN->SetLightsMode( LIGHTSMODE_MENU ); + SONGMAN->RegenRandomTrailEntries(); + m_DisplayMode = GAMESTATE->IsCourseMode() ? DISPLAY_COURSES : DISPLAY_SONGS; /* Finish any previous stage. It's OK to call this when we havn't played a stage yet. @@ -215,11 +217,8 @@ ScreenSelectMusic::ScreenSelectMusic( CString sClassName ) : ScreenWithMenuEleme this->AddChild( &m_DifficultyList ); } - FOREACH_PlayerNumber( p ) + FOREACH_HumanPlayer( p ) { - if( !GAMESTATE->IsHumanPlayer(p) ) - continue; // skip - m_sprDifficultyFrame[p].SetName( ssprintf("DifficultyFrameP%d",p+1) ); m_sprDifficultyFrame[p].Load( THEME->GetPathG(m_sName,ssprintf("difficulty frame p%d",p+1)) ); m_sprDifficultyFrame[p].StopAnimating(); @@ -294,14 +293,12 @@ ScreenSelectMusic::ScreenSelectMusic( CString sClassName ) : ScreenWithMenuEleme m_sprOptionsMessage.SetDiffuse( RageColor(1,1,1,0) ); // invisible //this->AddChild( &m_sprOptionsMessage ); // we have to draw this manually over the top of transitions + FOREACH_PlayerNumber( p ) { - FOREACH_PlayerNumber( p ) - { - m_sprNonPresence[p].SetName( ssprintf("NonPresenceP%d",p+1) ); - m_sprNonPresence[p].Load( THEME->GetPathG(m_sName,ssprintf("nonpresence p%d",p+1)) ); - SET_XY( m_sprNonPresence[p] ); - this->AddChild( &m_sprNonPresence[p] ); - } + m_sprNonPresence[p].SetName( ssprintf("NonPresenceP%d",p+1) ); + m_sprNonPresence[p].Load( THEME->GetPathG(m_sName,ssprintf("nonpresence p%d",p+1)) ); + SET_XY( m_sprNonPresence[p] ); + this->AddChild( &m_sprNonPresence[p] ); } m_Overlay.SetName( "Overlay"); @@ -430,7 +427,7 @@ void ScreenSelectMusic::TweenCoursePartsOnScreen( bool Initial ) } else { - m_CourseContentsFrame.SetFromCourse(NULL); + m_CourseContentsFrame.SetFromGameState(); COMMAND( m_CourseContentsFrame, "Show" ); } } @@ -690,9 +687,7 @@ void ScreenSelectMusic::Input( const DeviceInput& DeviceI, InputEventType type, if( type != IET_FIRST_PRESS ) return; PREFSMAN->m_bShowNative ^= 1; m_MusicWheel.RebuildMusicWheelItems(); - Course* pCourse = m_MusicWheel.GetSelectedCourse(); - if(pCourse) - m_CourseContentsFrame.SetFromCourse( pCourse ); + m_CourseContentsFrame.SetFromGameState(); return; } @@ -882,46 +877,58 @@ void ScreenSelectMusic::ChangeDifficulty( PlayerNumber pn, int dir ) { LOG->Trace( "ScreenSelectMusic::ChangeDifficulty( %d, %d )", pn, dir ); - if( !GAMESTATE->IsHumanPlayer(pn) ) - return; + ASSERT( GAMESTATE->IsHumanPlayer(pn) ); switch( m_MusicWheel.GetSelectedType() ) { case TYPE_SONG: case TYPE_PORTAL: - if( dir > 0 && m_iSelection[pn] == int(m_arrayNotes.size()-1) ) - return; - if( dir < 0 && m_iSelection[pn] == 0 ) - return; - - m_iSelection[pn] += dir; - - // the user explicity switched difficulties. Update the preferred difficulty - GAMESTATE->ChangeDifficulty( pn, m_arrayNotes[ m_iSelection[pn] ]->GetDifficulty() ); - - if( dir < 0 ) - m_soundDifficultyEasier.Play(); - else - m_soundDifficultyHarder.Play(); - - FOREACH_HumanPlayer( p ) { - if( pn == p || GAMESTATE->DifficultiesLocked() ) + m_iSelection[pn] += dir; + if( CLAMP(m_iSelection[pn],0,m_vpSteps.size()-1) ) + return; + + // the user explicity switched difficulties. Update the preferred difficulty + GAMESTATE->ChangePreferredDifficulty( pn, m_vpSteps[ m_iSelection[pn] ]->GetDifficulty() ); + + if( dir < 0 ) + m_soundDifficultyEasier.Play(); + else + m_soundDifficultyHarder.Play(); + + FOREACH_HumanPlayer( p ) { - m_iSelection[p] = m_iSelection[pn]; - AfterNotesChange( p ); + if( pn == p || GAMESTATE->DifficultiesLocked() ) + { + m_iSelection[p] = m_iSelection[pn]; + AfterStepsChange( p ); + } } } break; case TYPE_COURSE: - if( GAMESTATE->ChangeCourseDifficulty( pn, dir ) ) { + m_iSelection[pn] += dir; + if( CLAMP(m_iSelection[pn],0,m_vpTrails.size()-1) ) + return; + + // the user explicity switched difficulties. Update the preferred difficulty + GAMESTATE->ChangePreferredCourseDifficulty( pn, m_vpTrails[ m_iSelection[pn] ]->m_CourseDifficulty ); + if( dir < 0 ) m_soundDifficultyEasier.Play(); else m_soundDifficultyHarder.Play(); - AfterMusicChange(); + + FOREACH_HumanPlayer( p ) + { + if( pn == p || GAMESTATE->DifficultiesLocked() ) + { + m_iSelection[p] = m_iSelection[pn]; + AfterTrailChange( p ); + } + } } break; @@ -930,7 +937,7 @@ void ScreenSelectMusic::ChangeDifficulty( PlayerNumber pn, int dir ) /* XXX: We could be on a music or course sort, or even one with both; we don't * really know which difficulty to change. Maybe the two difficulties should be * linked ... */ - if( GAMESTATE->ChangeDifficulty( pn, dir ) ) + if( GAMESTATE->ChangePreferredDifficulty( pn, dir ) ) { if( dir < 0 ) m_soundDifficultyEasier.Play(); @@ -943,7 +950,7 @@ void ScreenSelectMusic::ChangeDifficulty( PlayerNumber pn, int dir ) if( pn == p || GAMESTATE->DifficultiesLocked() ) { m_iSelection[p] = m_iSelection[pn]; - AfterNotesChange( p ); + AfterStepsChange( p ); } } } @@ -1050,10 +1057,8 @@ void ScreenSelectMusic::MenuStart( PlayerNumber pn ) { const bool bIsNew = PROFILEMAN->IsSongNew( m_MusicWheel.GetSelectedSong() ); bool bIsHard = false; - FOREACH_PlayerNumber( p ) + FOREACH_HumanPlayer( p ) { - if( !GAMESTATE->IsHumanPlayer( (PlayerNumber)p ) ) - continue; // skip if( GAMESTATE->m_pCurSteps[p] && GAMESTATE->m_pCurSteps[p]->GetMeter() >= 10 ) bIsHard = true; } @@ -1166,32 +1171,27 @@ void ScreenSelectMusic::MenuBack( PlayerNumber pn ) Back( SM_GoToPrevScreen ); } -void ScreenSelectMusic::AfterNotesChange( PlayerNumber pn ) +void ScreenSelectMusic::AfterStepsChange( PlayerNumber pn ) { - if( !GAMESTATE->IsHumanPlayer(pn) ) - return; + ASSERT( GAMESTATE->IsHumanPlayer(pn) ); - m_iSelection[pn] = clamp( m_iSelection[pn], 0, int(m_arrayNotes.size()-1) ); // bounds clamping + CLAMP( m_iSelection[pn], 0, m_vpSteps.size()-1 ); Song* pSong = GAMESTATE->m_pCurSong; - Steps* pSteps = m_arrayNotes.empty()? NULL: m_arrayNotes[m_iSelection[pn]]; + Steps* pSteps = m_vpSteps.empty()? NULL: m_vpSteps[m_iSelection[pn]]; GAMESTATE->m_pCurSteps[pn] = pSteps; + int iScore = 0; if( pSteps ) { int iScore = 0; - if( PROFILEMAN->IsUsingProfile(pn) ) - iScore = PROFILEMAN->GetProfile(pn)->GetStepsHighScoreList(pSong,pSteps).GetTopScore().iScore; - else - iScore = PROFILEMAN->GetMachineProfile()->GetStepsHighScoreList(pSong,pSteps).GetTopScore().iScore; - m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, iScore) ); - } - else - { - m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, 0) ); + Profile* pProfile = PROFILEMAN->IsUsingProfile(pn) ? PROFILEMAN->GetProfile(pn) : PROFILEMAN->GetMachineProfile(); + iScore = pProfile->GetStepsHighScoreList(pSong,pSteps).GetTopScore().iScore; } + m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, iScore) ); + m_DifficultyIcon[pn].SetFromSteps( pn, pSteps ); if( pSteps && pSteps->IsAutogen() ) { @@ -1206,7 +1206,49 @@ void ScreenSelectMusic::AfterNotesChange( PlayerNumber pn ) if( SHOW_DIFFICULTY_LIST ) m_DifficultyList.SetFromGameState(); m_GrooveRadar.SetFromSteps( pn, pSteps ); - m_MusicWheel.NotesChanged( pn ); + m_MusicWheel.NotesOrTrailChanged( pn ); + if( SHOW_PANES ) + m_PaneDisplay[pn].SetFromGameState(); +} + +void ScreenSelectMusic::AfterTrailChange( PlayerNumber pn ) +{ + ASSERT( GAMESTATE->IsHumanPlayer(pn) ); + + CLAMP( m_iSelection[pn], 0, m_vpTrails.size()-1 ); + + Course* pCourse = GAMESTATE->m_pCurCourse; + Trail* pTrail = m_vpTrails.empty()? NULL: m_vpTrails[m_iSelection[pn]]; + + GAMESTATE->m_pCurTrail[pn] = pTrail; + + int iScore = 0; + if( pTrail ) + { + int iScore = 0; + Profile* pProfile = PROFILEMAN->IsUsingProfile(pn) ? PROFILEMAN->GetProfile(pn) : PROFILEMAN->GetMachineProfile(); + iScore = pProfile->GetCourseHighScoreList(pCourse,pTrail).GetTopScore().iScore; + } + + m_textHighScore[pn].SetText( ssprintf("%*i", NUM_SCORE_DIGITS, iScore) ); + + m_DifficultyIcon[pn].SetFromTrail( pn, pTrail ); + //if( pTrail && pTrail->IsAutogen() ) + //{ + // m_AutoGenIcon[pn].SetEffectDiffuseShift(); + //} + //else + //{ + // m_AutoGenIcon[pn].SetEffectNone(); + // m_AutoGenIcon[pn].SetDiffuse( RageColor(1,1,1,0) ); + //} + m_CourseContentsFrame.SetFromGameState(); + m_CourseContentsFrame.TweenInAfterChangedCourse(); + m_DifficultyMeter[pn].SetFromGameState( pn ); + if( SHOW_DIFFICULTY_LIST ) + m_DifficultyList.SetFromGameState(); + m_GrooveRadar.SetEmpty( pn ); + m_MusicWheel.NotesOrTrailChanged( pn ); if( SHOW_PANES ) m_PaneDisplay[pn].SetFromGameState(); } @@ -1217,9 +1259,9 @@ void ScreenSelectMusic::SwitchToPreferredSongDifficulty() { /* Find the closest match to the user's preferred difficulty. */ int CurDifference = -1; - for( unsigned i=0; iGetDifficulty() - GAMESTATE->m_PreferredDifficulty[p]); + int Diff = abs(m_vpSteps[i]->GetDifficulty() - GAMESTATE->m_PreferredDifficulty[p]); if( CurDifference == -1 || Diff < CurDifference ) { @@ -1228,7 +1270,7 @@ void ScreenSelectMusic::SwitchToPreferredSongDifficulty() } } - m_iSelection[p] = clamp( m_iSelection[p], 0, int(m_arrayNotes.size()) ) ; + m_iSelection[p] = clamp( m_iSelection[p], 0, int(m_vpSteps.size()) ) ; } } @@ -1283,10 +1325,13 @@ void ScreenSelectMusic::AfterMusicChange() if( pCourse ) GAMESTATE->m_pPreferredCourse = pCourse; - - int pn; - for( pn = 0; pn < NUM_PLAYERS; ++pn) - m_arrayNotes.clear(); + FOREACH_PlayerNumber( p ) + { + GAMESTATE->m_pCurSteps[p] = NULL; + GAMESTATE->m_pCurTrail[p] = NULL; + m_vpSteps.clear(); + m_vpTrails.clear(); + } m_Banner.SetMovingFast( !!m_MusicWheel.IsMoving() ); @@ -1354,8 +1399,8 @@ void ScreenSelectMusic::AfterMusicChange() m_textNumSongs.SetText( ssprintf("%d", SongManager::GetNumStagesForSong(pSong) ) ); m_textTotalTime.SetText( SecondsToMMSSMsMs(pSong->m_fMusicLengthSeconds) ); - pSong->GetSteps( m_arrayNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType ); - StepsUtil::SortNotesArrayByDifficulty( m_arrayNotes ); + pSong->GetSteps( m_vpSteps, GAMESTATE->GetCurrentStyleDef()->m_StepsType ); + StepsUtil::SortNotesArrayByDifficulty( m_vpSteps ); if ( PREFSMAN->m_bShowBanners ) m_Banner.LoadFromSong( pSong ); @@ -1462,6 +1507,8 @@ void ScreenSelectMusic::AfterMusicChange() StepsType st = GAMESTATE->GetCurrentStyleDef()->m_StepsType; Trail *pTrail = pCourse->GetTrail( st, COURSE_DIFFICULTY_REGULAR ); + pCourse->GetTrails( m_vpTrails, GAMESTATE->GetCurrentStyleDef()->m_StepsType ); + SampleMusicToPlay = THEME->GetPathS(m_sName,"course music"); m_fSampleStartSeconds = 0; m_fSampleLengthSeconds = -1; @@ -1476,8 +1523,6 @@ void ScreenSelectMusic::AfterMusicChange() m_Banner.LoadFromCourse( pCourse ); m_BPMDisplay.SetBPM( pCourse ); - m_CourseContentsFrame.SetFromCourse( pCourse ); - m_CourseContentsFrame.TweenInAfterChangedCourse(); m_DifficultyDisplay.UnsetDifficulties(); FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) @@ -1535,9 +1580,12 @@ void ScreenSelectMusic::AfterMusicChange() m_Artist.SetTips( m_Artists, m_AltArtists ); - FOREACH_PlayerNumber( p ) + FOREACH_HumanPlayer( p ) { - AfterNotesChange( p ); + if( GAMESTATE->m_pCurCourse ) + AfterTrailChange( p ); + else + AfterStepsChange( p ); } /* Make sure we never start the sample when moving fast. */ diff --git a/stepmania/src/ScreenSelectMusic.h b/stepmania/src/ScreenSelectMusic.h index 56dc4ab617..c26058cb57 100644 --- a/stepmania/src/ScreenSelectMusic.h +++ b/stepmania/src/ScreenSelectMusic.h @@ -60,14 +60,16 @@ protected: void ChangeDifficulty( PlayerNumber pn, int dir ); - void AfterNotesChange( PlayerNumber pn ); + void AfterStepsChange( PlayerNumber pn ); + void AfterTrailChange( PlayerNumber pn ); void SwitchToPreferredSongDifficulty(); void AfterMusicChange(); void SortOrderChanged(); void UpdateOptionsDisplays(); - vector m_arrayNotes; + vector m_vpSteps; + vector m_vpTrails; int m_iSelection[NUM_PLAYERS]; Sprite m_sprCharacterIcon[NUM_PLAYERS]; diff --git a/stepmania/src/SongManager.cpp b/stepmania/src/SongManager.cpp index d2465fa770..a50f1f8ade 100644 --- a/stepmania/src/SongManager.cpp +++ b/stepmania/src/SongManager.cpp @@ -654,8 +654,7 @@ void SongManager::FreeCourses() * screens. */ void SongManager::Cleanup() { - unsigned i; - for( i=0; im_vpSteps.size(); n++ ) @@ -665,9 +664,20 @@ void SongManager::Cleanup() } } - /* Erase cached course info. */ - for( i=0; i < m_pCourses.size(); i++ ) - m_pCourses[i]->ClearCache(); + // FIXME +// /* Erase cached course info. */ +// for( unsigned i=0; i < m_pCourses.size(); i++ ) +// m_pCourses[i]->ClearCache(); +} + +void SongManager::RegenRandomTrailEntries() +{ + /* Regenerate Trails so that any random entires get re-picked. */ + for( unsigned i=0; i < m_pCourses.size(); i++ ) + { + // FIXME: only regen entries that are random - not all entries + m_pCourses[i]->RegenTrails(); + } } void SongManager::GetAllCourses( vector &AddTo, bool bIncludeAutogen ) diff --git a/stepmania/src/SongManager.h b/stepmania/src/SongManager.h index f0234c1780..58ebf35b5d 100644 --- a/stepmania/src/SongManager.h +++ b/stepmania/src/SongManager.h @@ -35,6 +35,7 @@ public: void InitSongsFromDisk( LoadingWindow *ld ); void FreeSongs(); void Cleanup(); + void RegenRandomTrailEntries(); void LoadAllFromProfiles(); // song, edits void FreeAllLoadedFromProfiles(); diff --git a/stepmania/src/Trail.cpp b/stepmania/src/Trail.cpp index ea5e02e678..3ffbfa68b8 100644 --- a/stepmania/src/Trail.cpp +++ b/stepmania/src/Trail.cpp @@ -49,12 +49,17 @@ RadarValues Trail::GetRadarValues() const return rv; } -float Trail::GetAverageMeter() const +int Trail::GetMeter() const { + if( m_iSpecifiedMeter != -1 ) + return m_iSpecifiedMeter; + if( m_vEntries.empty() ) return 0; - return GetTotalMeter() / (float)m_vEntries.size(); + float fMeter = GetTotalMeter() / (float)m_vEntries.size(); + + return (int)roundf( fMeter ); } int Trail::GetTotalMeter() const diff --git a/stepmania/src/Trail.h b/stepmania/src/Trail.h index 876efb56ff..79a21400fb 100644 --- a/stepmania/src/Trail.h +++ b/stepmania/src/Trail.h @@ -42,17 +42,22 @@ public: StepsType m_StepsType; CourseDifficulty m_CourseDifficulty; vector m_vEntries; - int m_iMeter; + int m_iSpecifiedMeter; // == -1 if no meter specified Trail() + { + Init(); + } + void Init() { m_StepsType = STEPS_TYPE_INVALID; m_CourseDifficulty = COURSE_DIFFICULTY_INVALID; - m_iMeter = 1; + m_iSpecifiedMeter = -1; + m_vEntries.clear(); } RadarValues GetRadarValues() const; - float GetAverageMeter() const; + int GetMeter() const; int GetTotalMeter() const; float GetLengthSeconds() const; void GetDisplayBpms( DisplayBpms &AddTo );