From ed75682b9fc702f4336091324e000a8dd383d86f Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Sun, 22 Mar 2009 08:42:27 +0000 Subject: [PATCH] remove Workout, fold into EditCourses --- stepmania/src/CatalogXml.cpp | 2 +- stepmania/src/ControllerStateDisplay.cpp | 2 +- stepmania/src/Course.cpp | 17 +- stepmania/src/Course.h | 6 +- stepmania/src/CourseContentsList.cpp | 3 +- stepmania/src/GameInput.cpp | 1 + stepmania/src/GameInput.h | 2 + stepmania/src/GameState.cpp | 15 +- stepmania/src/OptionRow.cpp | 11 +- stepmania/src/OptionRowHandler.cpp | 12 +- stepmania/src/OptionRowHandler.h | 4 +- stepmania/src/OptionsList.cpp | 2 +- stepmania/src/PercentageDisplay.cpp | 13 +- stepmania/src/Profile.cpp | 4 +- stepmania/src/ProfileManager.cpp | 5 + stepmania/src/ProfileManager.h | 3 +- stepmania/src/ScreenBookkeeping.cpp | 2 +- stepmania/src/ScreenDebugOverlay.cpp | 2 +- stepmania/src/ScreenGameplay.cpp | 7 +- stepmania/src/ScreenHighScores.cpp | 2 +- stepmania/src/ScreenMiniMenu.h | 2 +- stepmania/src/ScreenNameEntryTraditional.cpp | 2 +- stepmania/src/ScreenNetSelectMusic.cpp | 2 +- stepmania/src/ScreenOptionsEditCourse.cpp | 5 +- .../src/ScreenOptionsEditCourseEntry.cpp | 4 +- stepmania/src/ScreenOptionsEditPlaylist.cpp | 448 +++++++++++++++--- stepmania/src/ScreenOptionsEditPlaylist.h | 8 +- stepmania/src/ScreenOptionsEditWorkout.cpp | 19 +- stepmania/src/ScreenOptionsManageCourses.cpp | 11 - stepmania/src/ScreenOptionsManageWorkouts.cpp | 108 +++-- stepmania/src/ScreenOptionsManageWorkouts.h | 6 +- stepmania/src/ScreenOptionsReviewWorkout.cpp | 74 ++- stepmania/src/ScreenOptionsReviewWorkout.h | 3 +- stepmania/src/ScreenOptionsToggleSongs.cpp | 2 +- stepmania/src/SongManager.cpp | 25 +- stepmania/src/SongManager.h | 6 +- stepmania/src/SongUtil.cpp | 2 +- stepmania/src/StepMania-net2003.vcproj | 6 - stepmania/src/StepMania.cpp | 3 - stepmania/src/StepsUtil.cpp | 2 +- stepmania/src/TrailUtil.cpp | 47 ++ stepmania/src/TrailUtil.h | 6 + stepmania/src/UnlockManager.cpp | 2 +- stepmania/src/Workout.cpp | 36 +- stepmania/src/Workout.h | 2 +- stepmania/src/WorkoutGraph.cpp | 22 +- stepmania/src/WorkoutManager.cpp | 236 ++++----- stepmania/src/WorkoutManager.h | 41 +- 48 files changed, 781 insertions(+), 464 deletions(-) diff --git a/stepmania/src/CatalogXml.cpp b/stepmania/src/CatalogXml.cpp index 925fa0a31f..5a15d4f13f 100644 --- a/stepmania/src/CatalogXml.cpp +++ b/stepmania/src/CatalogXml.cpp @@ -170,7 +170,7 @@ void CatalogXml::Save( LoadingWindow *loading_window ) { XNode* pNode = xml.AppendChild( "Songs" ); - const vector& vpSongs = SONGMAN->GetSongs(); + const vector& vpSongs = SONGMAN->GetAllSongs(); for( unsigned i=0; i { public: - static int LoadGameController( T* p, lua_State *L ) { p->LoadGameController( SArg(1), (GameController)IArg(2) ); return 0; } + static int LoadGameController( T* p, lua_State *L ) { p->LoadGameController( SArg(1), Enum::Check(L, 2) ); return 0; } static int LoadMultiPlayer( T* p, lua_State *L ) { p->LoadMultiPlayer( SArg(1), Enum::Check(L, 2) ); return 0; } LunaControllerStateDisplay() diff --git a/stepmania/src/Course.cpp b/stepmania/src/Course.cpp index 8c37bc3f5a..f0f2d0ccef 100644 --- a/stepmania/src/Course.cpp +++ b/stepmania/src/Course.cpp @@ -207,7 +207,9 @@ void Course::Init() m_sGroupName = ""; m_bRepeat = false; + m_fGoalSeconds = 0; m_bShuffle = false; + m_iLives = -1; FOREACH_ENUM( Difficulty,dc) m_iCustomMeter[dc] = -1; @@ -471,13 +473,13 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) if( m_bShuffle ) { /* Always randomize the same way per round. Otherwise, the displayed course - * will change every time it's viewed, and the displayed order will have no - * bearing on what you'll actually play. */ + * will change every time it's viewed, and the displayed order will have no + * bearing on what you'll actually play. */ tmp_entries = m_vEntries; random_shuffle( tmp_entries.begin(), tmp_entries.end(), rnd ); } - const vector &entries = m_bShuffle? tmp_entries:m_vEntries; + const vector &entries = m_bShuffle ? tmp_entries:m_vEntries; /* This can take some time, so don't fill it out unless we need it. */ vector vSongsByMostPlayed; @@ -751,6 +753,11 @@ const Style *Course::GetCourseStyle( const Game *pGame, int iNumPlayers ) const return NULL; } +void Course::InvalidateTrailCache() +{ + m_TrailCache.clear(); +} + void Course::Invalidate( const Song *pStaleSong ) { FOREACH_CONST( CourseEntry, m_vEntries, e ) @@ -1032,6 +1039,8 @@ public: lua_pushnumber( L, fTotalSeconds ); return 1; } + DEFINE_METHOD( IsEndless, IsEndless() ) + DEFINE_METHOD( GetGoalSeconds, m_fGoalSeconds ) LunaCourse() { @@ -1048,6 +1057,8 @@ public: ADD_METHOD( IsAutogen ); ADD_METHOD( GetEstimatedNumStages ); ADD_METHOD( GetTotalSeconds ); + ADD_METHOD( IsEndless ); + ADD_METHOD( GetGoalSeconds ); } }; diff --git a/stepmania/src/Course.h b/stepmania/src/Course.h index 4fa5a062b8..d15801095d 100644 --- a/stepmania/src/Course.h +++ b/stepmania/src/Course.h @@ -92,7 +92,6 @@ public: void PushSelf( lua_State *L ); }; -const int MAX_ENTRIES_PER_COURSE = 50; class Course { @@ -151,6 +150,8 @@ public: /* Call to regenerate Trails with random entries */ void RegenerateNonFixedTrails() const; + void InvalidateTrailCache(); + /* Call when a Song or its Steps are deleted/changed. */ void Invalidate( const Song *pStaleSong ); @@ -186,7 +187,8 @@ public: RString m_sGroupName; bool m_bRepeat; // repeat after last song? "Endless" - bool m_bShuffle; // play the songs in a random order + float m_fGoalSeconds; // if not 0, stop play after this number of seconds + bool m_bShuffle; int m_iLives; // -1 means use bar life meter int m_iCustomMeter[NUM_Difficulty]; // -1 = no meter specified bool m_bSortByMeter; diff --git a/stepmania/src/CourseContentsList.cpp b/stepmania/src/CourseContentsList.cpp index 771e87f1eb..51a352981d 100644 --- a/stepmania/src/CourseContentsList.cpp +++ b/stepmania/src/CourseContentsList.cpp @@ -51,7 +51,8 @@ void CourseContentsList::SetFromGameState() const Trail *pMasterTrail = GAMESTATE->m_pCurTrail[GAMESTATE->m_MasterPlayerNumber]; if( pMasterTrail == NULL ) return; - unsigned uNumEntriesToShow = min( pMasterTrail->m_vEntries.size(), m_vpDisplay.size() ); + unsigned uNumEntriesToShow = pMasterTrail->m_vEntries.size(); + CLAMP( uNumEntriesToShow, 0, m_vpDisplay.size() ); for( int i=0; i<(int)uNumEntriesToShow; i++ ) { diff --git a/stepmania/src/GameInput.cpp b/stepmania/src/GameInput.cpp index 1e3b201471..a11ed9f216 100644 --- a/stepmania/src/GameInput.cpp +++ b/stepmania/src/GameInput.cpp @@ -12,6 +12,7 @@ static const char *GameControllerNames[] = { }; XToString( GameController ); StringToX( GameController ); +LuaXType( GameController ); RString GameButtonToString( const InputScheme* pInputs, GameButton i ) diff --git a/stepmania/src/GameInput.h b/stepmania/src/GameInput.h index cefd5e3fc8..ed18a490c4 100644 --- a/stepmania/src/GameInput.h +++ b/stepmania/src/GameInput.h @@ -14,6 +14,8 @@ enum GameController NUM_GameController, // leave this at the end GameController_Invalid, }; +const RString& GameControllerToString( GameController mp ); +LuaDeclareType( GameController ); enum GameButton { diff --git a/stepmania/src/GameState.cpp b/stepmania/src/GameState.cpp index bc7f4d2e22..0057f90b90 100644 --- a/stepmania/src/GameState.cpp +++ b/stepmania/src/GameState.cpp @@ -843,14 +843,17 @@ void GameState::Update( float fDelta ) } } - if( WORKOUTMAN->m_pCurWorkout != NULL && !m_bWorkoutGoalComplete ) + if( GAMESTATE->m_pCurCourse ) { - const StageStats &ssCurrent = STATSMAN->m_CurStageStats; - bool bGoalComplete = ssCurrent.m_fGameplaySeconds > WORKOUTMAN->m_pCurWorkout->m_iMinutes*60; - if( bGoalComplete ) + if( GAMESTATE->m_pCurCourse->m_fGoalSeconds > 0 && !m_bWorkoutGoalComplete ) { - MESSAGEMAN->Broadcast( "WorkoutGoalComplete" ); - m_bWorkoutGoalComplete = true; + const StageStats &ssCurrent = STATSMAN->m_CurStageStats; + bool bGoalComplete = ssCurrent.m_fGameplaySeconds > GAMESTATE->m_pCurCourse->m_fGoalSeconds; + if( bGoalComplete ) + { + MESSAGEMAN->Broadcast( "WorkoutGoalComplete" ); + m_bWorkoutGoalComplete = true; + } } } } diff --git a/stepmania/src/OptionRow.cpp b/stepmania/src/OptionRow.cpp index a4fde441ee..6b4085b019 100644 --- a/stepmania/src/OptionRow.cpp +++ b/stepmania/src/OptionRow.cpp @@ -702,11 +702,12 @@ int OptionRow::GetOneSharedSelection( bool bAllowFail ) const void OptionRow::SetOneSelection( PlayerNumber pn, int iChoice ) { - if( m_vbSelected[pn].empty() ) + vector &vb = m_vbSelected[pn]; + if( vb.empty() ) return; - for( unsigned i=0; i<(unsigned)m_vbSelected[pn].size(); i++ ) - m_vbSelected[pn][i] = false; - m_vbSelected[pn][iChoice] = true; + FOREACH( bool, vb, b ) + *b = false; + vb[iChoice] = true; } void OptionRow::SetOneSharedSelection( int iChoice ) @@ -888,7 +889,7 @@ void OptionRow::ImportOptions( const vector &vpns ) ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); } - m_pHand->ImportOption( vpns, m_vbSelected ); + m_pHand->ImportOption( this, vpns, m_vbSelected ); FOREACH_CONST( PlayerNumber, vpns, iter ) { diff --git a/stepmania/src/OptionRowHandler.cpp b/stepmania/src/OptionRowHandler.cpp index 24b0eae73e..18afa28e06 100644 --- a/stepmania/src/OptionRowHandler.cpp +++ b/stepmania/src/OptionRowHandler.cpp @@ -224,7 +224,7 @@ public: } } } - void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { FOREACH_CONST( PlayerNumber, vpns, pn ) { @@ -576,7 +576,7 @@ public: m_pDifficultyToFill->Set( m_vDifficulties[0] ); m_ppStepsToFill->Set( m_vSteps[0] ); } - virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { FOREACH_CONST( PlayerNumber, vpns, pn ) { @@ -961,7 +961,7 @@ public: return RELOAD_CHANGED_ENABLED; } - virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { Lua *L = LUA->Get(); @@ -1114,7 +1114,7 @@ public: m_Def.m_sName = m_pOpt->name; } - virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { FOREACH_CONST( PlayerNumber, vpns, pn ) { @@ -1213,7 +1213,7 @@ public: m_pstToFill->Set( m_vStepsTypesToShow[0] ); } - virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { FOREACH_CONST( PlayerNumber, vpns, pn ) { @@ -1276,7 +1276,7 @@ public: m_Def.m_selectType = SELECT_NONE; m_Def.m_vsChoices.push_back( "" ); } - virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { } virtual int ExportOption( const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const diff --git a/stepmania/src/OptionRowHandler.h b/stepmania/src/OptionRowHandler.h index db50cd38ae..89155da9a2 100644 --- a/stepmania/src/OptionRowHandler.h +++ b/stepmania/src/OptionRowHandler.h @@ -8,7 +8,7 @@ #include "RageUtil.h" #include struct MenuRowDef; - +class OptionRow; struct ConfOption; enum SelectType @@ -123,7 +123,7 @@ public: virtual ReloadChanged Reload() { return RELOAD_CHANGED_NONE; } virtual int GetDefaultOption() const { return -1; } - virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { } + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { } /* Returns an OPT mask. */ virtual int ExportOption( const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const { return 0; } virtual void GetIconTextAndGameCommand( int iFirstSelection, RString &sIconTextOut, GameCommand &gcOut ) const; diff --git a/stepmania/src/OptionsList.cpp b/stepmania/src/OptionsList.cpp index 1eb7dbfa98..277c8133a5 100644 --- a/stepmania/src/OptionsList.cpp +++ b/stepmania/src/OptionsList.cpp @@ -515,7 +515,7 @@ void OptionsList::ImportRow( RString sRow ) vpns.push_back( m_pn ); OptionRowHandler *pHandler = m_Rows[sRow]; aSelections[ m_pn ].resize( pHandler->m_Def.m_vsChoices.size() ); - pHandler->ImportOption( vpns, aSelections ); + pHandler->ImportOption( NULL, vpns, aSelections ); m_bSelections[sRow] = aSelections[ m_pn ]; if( m_setTopMenus.find(sRow) != m_setTopMenus.end() ) diff --git a/stepmania/src/PercentageDisplay.cpp b/stepmania/src/PercentageDisplay.cpp index c59d9397ae..dfce9b70d4 100644 --- a/stepmania/src/PercentageDisplay.cpp +++ b/stepmania/src/PercentageDisplay.cpp @@ -10,6 +10,7 @@ #include "PlayerState.h" #include "XmlFile.h" #include "WorkoutManager.h" +#include "Course.h" REGISTER_ACTOR_CLASS( PercentageDisplay ) @@ -191,7 +192,17 @@ void PercentageDisplay::Refresh() bool PercentageDisplay::ShowDancePointsNotPercentage() const { // Use staight dance points in workout because the percentage denominator isn't accurate - we don't know when the players are going to stop. - return (WORKOUTMAN->m_pCurWorkout != NULL) || PREFSMAN->m_bDancePointsForOni; + + if( GAMESTATE->m_pCurCourse ) + { + if( GAMESTATE->m_pCurCourse->m_fGoalSeconds > 0 ) + return true; + } + + if( PREFSMAN->m_bDancePointsForOni ) + return true; + + return false; } diff --git a/stepmania/src/Profile.cpp b/stepmania/src/Profile.cpp index dba75cb305..734276d76a 100644 --- a/stepmania/src/Profile.cpp +++ b/stepmania/src/Profile.cpp @@ -251,7 +251,7 @@ int Profile::GetTotalStepsWithTopGrade( StepsType st, Difficulty d, Grade g ) co { int iCount = 0; - FOREACH_CONST( Song*, SONGMAN->GetSongs(), pSong ) + FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), pSong ) { if( !(*pSong)->NormallyDisplayed() ) continue; // skip @@ -310,7 +310,7 @@ float Profile::GetSongsPossible( StepsType st, Difficulty dc ) const int iTotalSteps = 0; // add steps high scores - const vector &vSongs = SONGMAN->GetSongs(); + const vector &vSongs = SONGMAN->GetAllSongs(); for( unsigned i=0; im_sDisplayName = PREFSMAN->m_sMachineName; + LoadMachineProfileEdits(); +} + +void ProfileManager::LoadMachineProfileEdits() +{ SONGMAN->FreeAllLoadedFromProfile( ProfileSlot_Machine ); SONGMAN->LoadStepEditsFromProfileDir( MACHINE_PROFILE_DIR, ProfileSlot_Machine ); SONGMAN->LoadCourseEditsFromProfileDir( MACHINE_PROFILE_DIR, ProfileSlot_Machine ); diff --git a/stepmania/src/ProfileManager.h b/stepmania/src/ProfileManager.h index 211d770528..ea79b9316b 100644 --- a/stepmania/src/ProfileManager.h +++ b/stepmania/src/ProfileManager.h @@ -64,7 +64,8 @@ public: // // High scores // - void LoadMachineProfile(); + void LoadMachineProfile(); // including edits + void LoadMachineProfileEdits(); void SaveMachineProfile() const; bool IsPersistentProfile( PlayerNumber pn ) const { return !m_sProfileDir[pn].empty(); } diff --git a/stepmania/src/ScreenBookkeeping.cpp b/stepmania/src/ScreenBookkeeping.cpp index d1c0343f97..d62b688572 100644 --- a/stepmania/src/ScreenBookkeeping.cpp +++ b/stepmania/src/ScreenBookkeeping.cpp @@ -143,7 +143,7 @@ void ScreenBookkeeping::UpdateView() vector vpSongs; int iCount = 0; - FOREACH_CONST( Song *, SONGMAN->GetSongs(), s ) + FOREACH_CONST( Song *, SONGMAN->GetAllSongs(), s ) { Song *pSong = *s; if( UNLOCKMAN->SongIsLocked(pSong) & ~LOCKED_DISABLED ) diff --git a/stepmania/src/ScreenDebugOverlay.cpp b/stepmania/src/ScreenDebugOverlay.cpp index 1b497d48db..463a7c60ae 100644 --- a/stepmania/src/ScreenDebugOverlay.cpp +++ b/stepmania/src/ScreenDebugOverlay.cpp @@ -818,7 +818,7 @@ static void FillProfileStats( Profile *pProfile ) PREFSMAN->m_iMaxHighScoresPerListForMachine.Get(): PREFSMAN->m_iMaxHighScoresPerListForPlayer.Get(); - vector vpAllSongs = SONGMAN->GetSongs(); + vector vpAllSongs = SONGMAN->GetAllSongs(); FOREACH( Song*, vpAllSongs, pSong ) { vector vpAllSteps = (*pSong)->GetAllSteps(); diff --git a/stepmania/src/ScreenGameplay.cpp b/stepmania/src/ScreenGameplay.cpp index c51c9dc2c5..2e9c187996 100644 --- a/stepmania/src/ScreenGameplay.cpp +++ b/stepmania/src/ScreenGameplay.cpp @@ -906,8 +906,11 @@ ScreenGameplay::~ScreenGameplay() bool ScreenGameplay::IsLastSong() { - if( WORKOUTMAN->m_pCurWorkout != NULL && GAMESTATE->m_bWorkoutGoalComplete ) - return true; + if( GAMESTATE->m_pCurCourse ) + { + if( GAMESTATE->m_pCurCourse->m_fGoalSeconds > 0 && GAMESTATE->m_bWorkoutGoalComplete ) + return true; + } if( GAMESTATE->m_pCurCourse && GAMESTATE->m_pCurCourse->m_bRepeat ) return false; return GAMESTATE->GetCourseSongIndex() >= (int)m_apSongsQueue.size()-1; // GetCourseSongIndex() is 0-based diff --git a/stepmania/src/ScreenHighScores.cpp b/stepmania/src/ScreenHighScores.cpp index 0c4fea0dfd..8cbcb55fc1 100644 --- a/stepmania/src/ScreenHighScores.cpp +++ b/stepmania/src/ScreenHighScores.cpp @@ -21,7 +21,7 @@ REGISTER_SCREEN_CLASS( ScreenHighScores ); static void GetAllSongsToShow( vector &vpOut, int iNumMostRecentScoresToShow ) { vpOut.clear(); - FOREACH_CONST( Song*, SONGMAN->GetSongs(), s ) + FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), s ) { if( !(*s)->NormallyDisplayed() ) continue; // skip diff --git a/stepmania/src/ScreenMiniMenu.h b/stepmania/src/ScreenMiniMenu.h index 03fc203d54..2f7cb28c1a 100644 --- a/stepmania/src/ScreenMiniMenu.h +++ b/stepmania/src/ScreenMiniMenu.h @@ -13,7 +13,7 @@ struct MenuRowDef int iRowCode; RString sName; bool bEnabled; - MenuRowUpdateEnabled pfnEnabled; // if ! NULL, used to fill bEnabled + MenuRowUpdateEnabled pfnEnabled; // if ! NULL, used instead of bEnabled EditMode emShowIn; int iDefaultChoice; vector choices; diff --git a/stepmania/src/ScreenNameEntryTraditional.cpp b/stepmania/src/ScreenNameEntryTraditional.cpp index c403201797..0d90e9d9a7 100644 --- a/stepmania/src/ScreenNameEntryTraditional.cpp +++ b/stepmania/src/ScreenNameEntryTraditional.cpp @@ -28,7 +28,7 @@ void ScreenNameEntryTraditional::Init() for( int z = 0; z < 3; ++z ) { StageStats ss; - const vector &apSongs = SONGMAN->GetSongs(); + const vector &apSongs = SONGMAN->GetAllSongs(); ss.m_vpPlayedSongs.push_back( apSongs[rand()%apSongs.size()] ); ss.m_vpPossibleSongs = ss.m_vpPlayedSongs; ss.m_pStyle = GAMESTATE->GetCurrentStyle(); diff --git a/stepmania/src/ScreenNetSelectMusic.cpp b/stepmania/src/ScreenNetSelectMusic.cpp index 27811e5210..4df39fbd06 100644 --- a/stepmania/src/ScreenNetSelectMusic.cpp +++ b/stepmania/src/ScreenNetSelectMusic.cpp @@ -197,7 +197,7 @@ void ScreenNetSelectMusic::HandleScreenMessage( const ScreenMessage SM ) } } - vector AllSongs = SONGMAN->GetSongs(); + vector AllSongs = SONGMAN->GetAllSongs(); unsigned i; for( i=0; i < AllSongs.size(); i++ ) { diff --git a/stepmania/src/ScreenOptionsEditCourse.cpp b/stepmania/src/ScreenOptionsEditCourse.cpp index 7595a53fea..bd9005740c 100644 --- a/stepmania/src/ScreenOptionsEditCourse.cpp +++ b/stepmania/src/ScreenOptionsEditCourse.cpp @@ -13,6 +13,9 @@ #include "LocalizedString.h" #include "OptionRowHandler.h" +const int MAX_ENTRIES_PER_COURSE = 50; + + enum EditCourseRow { EditCourseRow_Type, @@ -57,7 +60,7 @@ void ScreenOptionsEditCourse::BeginScreen() ASSERT( GAMESTATE->m_pCurCourse ); Course *pCourse = GAMESTATE->m_pCurCourse; m_Original = *pCourse; - m_vpDisplayedSongs = SONGMAN->GetSongs(); + m_vpDisplayedSongs = SONGMAN->GetAllSongs(); vector vHands; diff --git a/stepmania/src/ScreenOptionsEditCourseEntry.cpp b/stepmania/src/ScreenOptionsEditCourseEntry.cpp index 6bf9ed2432..bb696f997a 100644 --- a/stepmania/src/ScreenOptionsEditCourseEntry.cpp +++ b/stepmania/src/ScreenOptionsEditCourseEntry.cpp @@ -69,7 +69,7 @@ public: return RELOAD_CHANGED_ALL; } - virtual void ImportOption( const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { vector::const_iterator iter = find( m_vpDisplayedSongs.begin(), m_vpDisplayedSongs.end(), GAMESTATE->m_pCurSong.Get() ); int iChoice = 0; @@ -250,7 +250,7 @@ void ScreenOptionsEditCourseEntry::HandleScreenMessage( const ScreenMessage SM ) if( pSong == NULL ) { // Find the longest non-tutorial song. - const vector &vSongs = SONGMAN->GetSongs(); + const vector &vSongs = SONGMAN->GetAllSongs(); float fLen = -1.f; FOREACH_CONST( Song*, vSongs, i ) diff --git a/stepmania/src/ScreenOptionsEditPlaylist.cpp b/stepmania/src/ScreenOptionsEditPlaylist.cpp index 31f79cabbb..d4d4181cc0 100644 --- a/stepmania/src/ScreenOptionsEditPlaylist.cpp +++ b/stepmania/src/ScreenOptionsEditPlaylist.cpp @@ -11,36 +11,230 @@ #include "ScreenPrompt.h" #include "LocalizedString.h" #include "WorkoutManager.h" +#include "song.h" +#include "Style.h" +#include "Steps.h" -static const MenuRowDef g_MenuSong = MenuRowDef( -1, "Song", true, EditMode_Practice, false, true, 0, "Off", "On" ); + +static void GetStepsForSong( Song *pSong, vector &vpStepsOut ) +{ + SongUtil::GetSteps( pSong, vpStepsOut, GAMESTATE->GetCurrentStyle()->m_StepsType ); + StepsUtil::RemoveLockedSteps( pSong, vpStepsOut ); + StepsUtil::SortNotesArrayByDifficulty( vpStepsOut ); +} + +// XXX: very similar to OptionRowHandlerSteps +class OptionRowHandlerSteps : public OptionRowHandler +{ +public: + void Load( int iEntryIndex ) + { + m_iEntryIndex = iEntryIndex; + } + virtual ReloadChanged Reload() + { + m_Def.m_vsChoices.clear(); + m_vpSteps.clear(); + + Song *pSong = GAMESTATE->m_pCurSong; + if( pSong ) // playing a song + { + GetStepsForSong( pSong, m_vpSteps ); + FOREACH_CONST( Steps*, m_vpSteps, steps ) + { + RString s; + if( (*steps)->GetDifficulty() == Difficulty_Edit ) + s = (*steps)->GetDescription(); + else + s = DifficultyToLocalizedString( (*steps)->GetDifficulty() ); + s += ssprintf( " %d", (*steps)->GetMeter() ); + m_Def.m_vsChoices.push_back( s ); + } + m_Def.m_vEnabledForPlayers.clear(); + m_Def.m_vEnabledForPlayers.insert( PLAYER_1 ); + } + else + { + m_Def.m_vsChoices.push_back( "n/a" ); + m_vpSteps.push_back( NULL ); + m_Def.m_vEnabledForPlayers.clear(); + } + + + return RELOAD_CHANGED_ALL; + } + virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const + { + Trail *pTrail = GAMESTATE->m_pCurTrail[PLAYER_1]; + Steps *pSteps; + if( m_iEntryIndex < (int)pTrail->m_vEntries.size() ) + pSteps = pTrail->m_vEntries[ m_iEntryIndex ].pSteps; + + vector::const_iterator iter = find( m_vpSteps.begin(), m_vpSteps.end(), pSteps ); + if( iter == m_vpSteps.end() ) + { + pRow->SetOneSharedSelection( 0 ); + } + else + { + int index = iter - m_vpSteps.begin(); + pRow->SetOneSharedSelection( index ); + } + + } + virtual int ExportOption( const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const + { + return 0; + } + Steps *GetSteps( int iStepsIndex ) const + { + return m_vpSteps[iStepsIndex]; + } + +protected: + int m_iEntryIndex; + vector m_vpSteps; +}; + + + +const int NUM_SONG_ROWS = 20; REGISTER_SCREEN_CLASS( ScreenOptionsEditPlaylist ); +enum WorkoutDetailsRow +{ + WorkoutDetailsRow_Minutes, + NUM_WorkoutDetailsRow +}; + +enum RowType +{ + RowType_Song, + RowType_Steps, + NUM_RowType, + RowType_Invalid, +}; +static int RowToEntryIndex( int iRow ) +{ + if( iRow < NUM_WorkoutDetailsRow ) + return -1; + + return (iRow-NUM_WorkoutDetailsRow)/NUM_RowType; +} +static RowType RowToRowType( int iRow ) +{ + if( iRow < NUM_WorkoutDetailsRow ) + return RowType_Invalid; + return (RowType)((iRow-NUM_WorkoutDetailsRow) % NUM_RowType); +} +static int EntryIndexAndRowTypeToRow( int iEntryIndex, RowType rowType ) +{ + return NUM_WorkoutDetailsRow + iEntryIndex*NUM_RowType + rowType; +} + void ScreenOptionsEditPlaylist::Init() { ScreenOptions::Init(); - SongUtil::GetAllSongGenres( m_vsSongGenres ); + SONGMAN->GetPreferredSortSongs( m_vpSongs ); + SongUtil::SortSongPointerArrayByTitle( m_vpSongs ); +} + +const MenuRowDef g_MenuRows[] = +{ + MenuRowDef( -1, "Workout Minutes", true, EditMode_Practice, true, false, 0, NULL ), +}; + +static LocalizedString EMPTY ("ScreenOptionsEditPlaylist","-Empty-"); +static LocalizedString SONG ("ScreenOptionsEditPlaylist","Song"); +static LocalizedString STEPS ("ScreenOptionsEditPlaylist","Steps"); +static LocalizedString MINUTES ("ScreenOptionsEditPlaylist","minutes"); + +static RString MakeMinutesString( int mins ) +{ + if( mins == 0 ) + return "No Cut-off"; + return ssprintf( "%d", mins ) + " " + MINUTES.GetValue(); } void ScreenOptionsEditPlaylist::BeginScreen() { vector vHands; - FOREACH_CONST( RString, m_vsSongGenres, s ) + FOREACH_ENUM( WorkoutDetailsRow, rowIndex ) { - OptionRowHandler *pHand = OptionRowHandlerUtil::MakeSimple( g_MenuSong ); - vHands.push_back( pHand ); - pHand->m_Def.m_sName = (*s); - pHand->m_Def.m_sExplanationName = "Enable Song Genre"; - pHand->m_Def.m_layoutType = LAYOUT_SHOW_ALL_IN_ROW; + const MenuRowDef &mr = g_MenuRows[rowIndex]; + OptionRowHandler *pHand = OptionRowHandlerUtil::MakeSimple( mr ); + + pHand->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; + pHand->m_Def.m_vsChoices.clear(); + + switch( rowIndex ) + { + DEFAULT_FAIL(rowIndex); + case WorkoutDetailsRow_Minutes: + pHand->m_Def.m_vsChoices.push_back( MakeMinutesString(0) ); + for( int i=MIN_WORKOUT_MINUTES; i<=20; i+=2 ) + pHand->m_Def.m_vsChoices.push_back( MakeMinutesString(i) ); + for( int i=20; i<=MAX_WORKOUT_MINUTES; i+=5 ) + pHand->m_Def.m_vsChoices.push_back( MakeMinutesString(i) ); + break; + } + pHand->m_Def.m_bExportOnChange = true; + vHands.push_back( pHand ); + } + + + + for( int i=0; iGetDisplayFullTitle() ); + mrd.sName = ssprintf(SONG.GetValue() + " %d",i+1); + OptionRowHandler *pHand = OptionRowHandlerUtil::MakeSimple( mrd ); + pHand->m_Def.m_bAllowThemeTitle = false; // already themed + pHand->m_Def.m_sExplanationName = "Choose Song"; + pHand->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; + pHand->m_Def.m_bExportOnChange = true; + vHands.push_back( pHand ); + } + + { + OptionRowHandlerSteps *pHand = new OptionRowHandlerSteps; + pHand->Load( i ); + pHand->m_Def.m_vsChoices.push_back( "n/a" ); + pHand->m_Def.m_sName = ssprintf(STEPS.GetValue() + " %d",i+1); + pHand->m_Def.m_bAllowThemeTitle = false; // already themed + pHand->m_Def.m_bAllowThemeItems = false; // already themed + pHand->m_Def.m_sExplanationName = "Choose Steps"; + pHand->m_Def.m_bOneChoiceForAllPlayers = true; + pHand->m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; + pHand->m_Def.m_bExportOnChange = true; + vHands.push_back( pHand ); + } + } ScreenOptions::InitMenu( vHands ); ScreenOptions::BeginScreen(); - this->AfterChangeRow( PLAYER_1 ); + + for( int i=0; i<(int)m_pRows.size(); i++ ) + { + OptionRow *pRow = m_pRows[i]; + m_iCurrentRow[PLAYER_1] = i; + this->SetCurrentSong(); + pRow->Reload(); + } + m_iCurrentRow[PLAYER_1] = 0; + + this->SetCurrentSong(); + + //this->AfterChangeRow( PLAYER_1 ); } ScreenOptionsEditPlaylist::~ScreenOptionsEditPlaylist() @@ -54,41 +248,100 @@ void ScreenOptionsEditPlaylist::ImportOptions( int iRow, const vectorm_pCurWorkout->m_vsSongGenres, s ) + switch( iRow ) { - if( *s == sSongGenre ) + case WorkoutDetailsRow_Minutes: + row.SetOneSharedSelection( 0 ); + row.SetOneSharedSelectionIfPresent( MakeMinutesString(GAMESTATE->m_pCurCourse->m_fGoalSeconds/60) ); + break; + default: { - bEnabled = true; - break; - } - } + int iEntryIndex = RowToEntryIndex( iRow ); + RowType rowType = RowToRowType( iRow ); - row.SetOneSharedSelection( bEnabled ? 1:0 ); + switch( rowType ) + { + DEFAULT_FAIL( rowType ); + case RowType_Song: + { + Song *pSong = NULL; + if( iEntryIndex < (int)GAMESTATE->m_pCurCourse->m_vEntries.size() ) + pSong = GAMESTATE->m_pCurCourse->m_vEntries[iEntryIndex].songID.ToSong(); + + vector::iterator iter = find( m_vpSongs.begin(), m_vpSongs.end(), pSong ); + if( iter == m_vpSongs.end() ) + row.SetOneSharedSelection( 0 ); + else + row.SetOneSharedSelection( 1 + iter - m_vpSongs.begin() ); + } + break; + case RowType_Steps: + // the OptionRowHandler does its own importing + break; + } + } + break; + } } void ScreenOptionsEditPlaylist::ExportOptions( int iRow, const vector &vpns ) { - OptionRow &row = *m_pRows[iRow]; - if( row.GetRowType() == OptionRow::RowType_Exit ) - return; - - RString sSongGenre = m_vsSongGenres[iRow]; - - bool bEnabled = !!row.GetOneSharedSelection(); - vector::iterator iter = find( WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.begin(), WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.end(), sSongGenre ); - bool bAlreadyExists = iter != WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.end(); - if( bEnabled && !bAlreadyExists ) + FOREACH_ENUM( WorkoutDetailsRow, i ) { - WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.push_back( sSongGenre ); - sort( WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.begin(), WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.end() ); + OptionRow &row = *m_pRows[i]; + int iIndex = row.GetOneSharedSelection( true ); + RString sValue; + if( iIndex >= 0 ) + sValue = row.GetRowDef().m_vsChoices[ iIndex ]; + + switch( i ) + { + DEFAULT_FAIL(i); + case WorkoutDetailsRow_Minutes: + GAMESTATE->m_pCurCourse->m_fGoalSeconds = 0; + int mins; + if( sscanf( sValue, "%d", &mins ) == 1 ) + GAMESTATE->m_pCurCourse->m_fGoalSeconds = mins * 60; + break; + } } - else if( !bEnabled && bAlreadyExists ) + + GAMESTATE->m_pCurCourse->m_vEntries.clear(); + + for( int i=NUM_WorkoutDetailsRow; i<(int)m_pRows.size(); i++ ) { - WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.erase( iter ); + OptionRow &row = *m_pRows[i]; + if( row.GetRowType() == OptionRow::RowType_Exit ) + continue; + + RowType rowType = RowToRowType( i ); + int iEntryIndex = RowToEntryIndex( i ); + + switch( rowType ) + { + case RowType_Song: + { + Song *pSong = this->GetSongForEntry( iEntryIndex ); + if( pSong ) + { + Steps *pSteps = this->GetStepsForEntry( iEntryIndex ); + ASSERT( pSteps ); + CourseEntry ce; + ce.songID.FromSong( pSong ); + ce.stepsCriteria.m_difficulty = pSteps->GetDifficulty(); + GAMESTATE->m_pCurCourse->m_vEntries.push_back( ce ); + } + } + break; + case RowType_Steps: + // push each CourseEntry when we handle each RowType_Song above + break; + default: + break; + } } + + EditCourseUtil::UpdateAndSetTrail(); } void ScreenOptionsEditPlaylist::GoToNextScreen() @@ -109,30 +362,106 @@ void ScreenOptionsEditPlaylist::HandleScreenMessage( const ScreenMessage SM ) ScreenOptions::HandleScreenMessage( SM ); } -static RString g_sSongGenre; +void ScreenOptionsEditPlaylist::SetCurrentSong() +{ + int iRow = m_iCurrentRow[PLAYER_1]; + OptionRow &row = *m_pRows[iRow]; + + if( row.GetRowType() == OptionRow::RowType_Exit ) + { + GAMESTATE->m_pCurSong.Set( NULL ); + GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL ); + } + else + { + int iRow = m_iCurrentRow[PLAYER_1]; + int iEntryIndex = RowToEntryIndex( iRow ); + Song *pSong = NULL; + if( iEntryIndex != -1 ) + { + int iCurrentSongRow = EntryIndexAndRowTypeToRow(iEntryIndex,RowType_Song); + OptionRow &row = *m_pRows[ iCurrentSongRow ]; + int index = row.GetOneSelection(PLAYER_1); + if( index != 0 ) + pSong = m_vpSongs[ index - 1 ]; + } + GAMESTATE->m_pCurSong.Set( pSong ); + } +} + +void ScreenOptionsEditPlaylist::SetCurrentSteps() +{ + Song *pSong = GAMESTATE->m_pCurSong; + if( pSong ) + { + int iRow = m_iCurrentRow[PLAYER_1]; + int iEntryIndex = RowToEntryIndex( iRow ); + OptionRow &row = *m_pRows[ EntryIndexAndRowTypeToRow(iEntryIndex, RowType_Steps) ]; + int iStepsIndex = row.GetOneSharedSelection(); + const OptionRowHandlerSteps *pHand = dynamic_cast( row.GetHandler() ); + ASSERT( pHand ); + Steps *pSteps = pHand->GetSteps( iStepsIndex ); + GAMESTATE->m_pCurSteps[PLAYER_1].Set( pSteps ); + } + else + { + GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL ); + } +} + +Song *ScreenOptionsEditPlaylist::GetSongForEntry( int iEntryIndex ) +{ + int iRow = EntryIndexAndRowTypeToRow( iEntryIndex, RowType_Song ); + OptionRow &row = *m_pRows[iRow]; + + int index = row.GetOneSharedSelection(); + if( index == 0 ) + return NULL; + return m_vpSongs[ index - 1 ]; +} + +Steps *ScreenOptionsEditPlaylist::GetStepsForEntry( int iEntryIndex ) +{ + int iRow = EntryIndexAndRowTypeToRow( iEntryIndex, RowType_Steps ); + OptionRow &row = *m_pRows[iRow]; + int index = row.GetOneSharedSelection(); + Song *pSong = GetSongForEntry( iEntryIndex ); + vector vpSteps; + GetStepsForSong( pSong, vpSteps ); + return vpSteps[index]; +} void ScreenOptionsEditPlaylist::AfterChangeRow( PlayerNumber pn ) { ScreenOptions::AfterChangeRow( pn ); - int iRow = m_iCurrentRow[pn]; - OptionRow &row = *m_pRows[iRow]; - if( row.GetRowType() == OptionRow::RowType_Exit ) - g_sSongGenre = ""; - else - g_sSongGenre = m_vsSongGenres[iRow]; - - MESSAGEMAN->Broadcast( "EditPlaylistSongGenreChanged" ); + SetCurrentSong(); } void ScreenOptionsEditPlaylist::AfterChangeValueInRow( int iRow, PlayerNumber pn ) { ScreenOptions::AfterChangeValueInRow( iRow, pn ); - MESSAGEMAN->Broadcast( "WorkoutChanged" ); + int iEntryIndex = RowToEntryIndex( iRow ); + RowType rowType = RowToRowType( iRow ); + switch( rowType ) + { + case RowType_Song: + { + SetCurrentSong(); + OptionRow &row = *m_pRows[ EntryIndexAndRowTypeToRow(iEntryIndex, RowType_Steps) ]; + row.Reload(); + } + break; + case RowType_Steps: + SetCurrentSteps(); + break; + default: + break; + } } -const int MIN_ENABLED_SONGS = 10; +const int MIN_ENABLED_SONGS = 2; static LocalizedString MUST_ENABLE_AT_LEAST("ScreenOptionsEditPlaylist","You must enable at least %d songs."); void ScreenOptionsEditPlaylist::ProcessMenuStart( const InputEventPlus &input ) @@ -142,10 +471,9 @@ void ScreenOptionsEditPlaylist::ProcessMenuStart( const InputEventPlus &input ) int iRow = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber]; - vector vpSongGenreSongs; - WORKOUTMAN->GetWorkoutSongsForGenres( WORKOUTMAN->m_pCurWorkout->m_vsSongGenres, vpSongGenreSongs ); + int iSongCount = GAMESTATE->m_pCurCourse->m_vEntries.size(); - if( m_pRows[iRow]->GetRowType() == OptionRow::RowType_Exit && vpSongGenreSongs.size() < unsigned(MIN_ENABLED_SONGS) ) + if( m_pRows[iRow]->GetRowType() == OptionRow::RowType_Exit && iSongCount < unsigned(MIN_ENABLED_SONGS) ) { ScreenPrompt::Prompt( SM_None, ssprintf(MUST_ENABLE_AT_LEAST.GetValue(),MIN_ENABLED_SONGS) ); return; @@ -154,32 +482,6 @@ void ScreenOptionsEditPlaylist::ProcessMenuStart( const InputEventPlus &input ) ScreenOptions::ProcessMenuStart( input ); } -RString GetEditPlaylistSelectedSongGenreText( int iColumnIndex, int iMaxPerCol ) -{ - vector vsSongGenres; - vsSongGenres.push_back( g_sSongGenre ); - vector vpSongGenreSongs; - WORKOUTMAN->GetWorkoutSongsForGenres( vsSongGenres, vpSongGenreSongs ); - - const int iSongPerCoumn = iMaxPerCol; - vector vs; - for( int i=iColumnIndex*iSongPerCoumn; i<(iColumnIndex+1)*iSongPerCoumn && i<(int)vpSongGenreSongs.size(); i++ ) - { - Song *pSong = vpSongGenreSongs[i]; - RString s2 = pSong->GetDisplayFullTitle(); - //if( s2.size() > 16 ) - // s2 = s2.Left(14) + "..."; - //s2.Replace( " ", " " ); - vs.push_back( s2 ); - } - - return join("\n", vs); -} - -#include "LuaManager.h" -LuaFunction( GetEditPlaylistSelectedSongGenre, g_sSongGenre ); -LuaFunction( GetEditPlaylistSelectedSongGenreText, GetEditPlaylistSelectedSongGenreText(IArg(1),IArg(2)) ); - /* * (c) 2003-2004 Chris Danford diff --git a/stepmania/src/ScreenOptionsEditPlaylist.h b/stepmania/src/ScreenOptionsEditPlaylist.h index 4c552d2b5d..1465f6c7bc 100644 --- a/stepmania/src/ScreenOptionsEditPlaylist.h +++ b/stepmania/src/ScreenOptionsEditPlaylist.h @@ -3,6 +3,7 @@ #include "ScreenOptions.h" class Song; +class Steps; class ScreenOptionsEditPlaylist : public ScreenOptions { @@ -25,7 +26,12 @@ private: virtual void AfterChangeValueInRow( int iRow, PlayerNumber pn ); virtual void ProcessMenuStart( const InputEventPlus &input ); - vector m_vsSongGenres; + void SetCurrentSong(); + void SetCurrentSteps(); + Song *GetSongForEntry( int iEntryIndex ); + Steps *GetStepsForEntry( int iEntryIndex ); + + vector m_vpSongs; }; #endif diff --git a/stepmania/src/ScreenOptionsEditWorkout.cpp b/stepmania/src/ScreenOptionsEditWorkout.cpp index 5eb5a77ddd..09b8cd827f 100644 --- a/stepmania/src/ScreenOptionsEditWorkout.cpp +++ b/stepmania/src/ScreenOptionsEditWorkout.cpp @@ -91,22 +91,27 @@ void ScreenOptionsEditWorkout::ImportOptions( int iRow, const vectorm_pCurWorkout->m_WorkoutProgram) ); + row.SetOneSharedSelectionIfPresent( WorkoutProgramToLocalizedString(WORKOUTMAN->GetCurrentWorkout()->m_WorkoutProgram) ); break; case WorkoutDetailsRow_Minutes: - row.SetOneSharedSelectionIfPresent( MakeMinutesString(WORKOUTMAN->m_pCurWorkout->m_iMinutes) ); + row.SetOneSharedSelectionIfPresent( MakeMinutesString(WORKOUTMAN->GetCurrentWorkout()->m_iMinutes) ); break; case WorkoutDetailsRow_Meter: - row.SetOneSharedSelectionIfPresent( MakeMeterString(WORKOUTMAN->m_pCurWorkout->m_iAverageMeter) ); + row.SetOneSharedSelectionIfPresent( MakeMeterString(WORKOUTMAN->GetCurrentWorkout()->m_iAverageMeter) ); break; } + */ } void ScreenOptionsEditWorkout::ExportOptions( int iRow, const vector &vpns ) { + /* + FIXME FOREACH_ENUM( WorkoutDetailsRow, i ) { iRow = i; @@ -120,18 +125,20 @@ void ScreenOptionsEditWorkout::ExportOptions( int iRow, const vectorm_pCurWorkout->m_WorkoutProgram = (WorkoutProgram)iIndex; + WORKOUTMAN->GetCurrentWorkout()->m_WorkoutProgram = (WorkoutProgram)iIndex; break; case WorkoutDetailsRow_Minutes: - sscanf( sValue, "%d", &WORKOUTMAN->m_pCurWorkout->m_iMinutes ); + sscanf( sValue, "%d", &WORKOUTMAN->GetCurrentWorkout()->m_iMinutes ); break; case WorkoutDetailsRow_Meter: - WORKOUTMAN->m_pCurWorkout->m_iAverageMeter = iIndex + MIN_METER; + WORKOUTMAN->GetCurrentWorkout()->m_iAverageMeter = iIndex + MIN_METER; break; } } MESSAGEMAN->Broadcast( "WorkoutChanged" ); + WORKOUTMAN->UpdateAndSetTrail(); + */ } void ScreenOptionsEditWorkout::GoToNextScreen() diff --git a/stepmania/src/ScreenOptionsManageCourses.cpp b/stepmania/src/ScreenOptionsManageCourses.cpp index de5e9bad10..c92d423a3c 100644 --- a/stepmania/src/ScreenOptionsManageCourses.cpp +++ b/stepmania/src/ScreenOptionsManageCourses.cpp @@ -403,8 +403,6 @@ void ScreenOptionsManageCourses::AfterChangeRow( PlayerNumber pn ) ScreenOptions::AfterChangeRow( pn ); } -static LocalizedString YOU_HAVE_MAXIMUM_EDITS_ALLOWED( "ScreenOptionsManageCourses", "You have %d course edits, the maximum number allowed." ); -static LocalizedString YOU_MUST_DELETE( "ScreenOptionsManageCourses", "You must delete an existing course edit before creating a new course edit." ); void ScreenOptionsManageCourses::ProcessMenuStart( const InputEventPlus &input ) { if( IsTransitioning() ) @@ -420,15 +418,6 @@ void ScreenOptionsManageCourses::ProcessMenuStart( const InputEventPlus &input ) } else { - if( SONGMAN->GetNumEditCourses(ProfileSlot_Machine) >= MAX_EDIT_COURSES_PER_PROFILE ) - { - RString s = ssprintf( - YOU_HAVE_MAXIMUM_EDITS_ALLOWED.GetValue() + "\n\n" + YOU_MUST_DELETE.GetValue(), - MAX_EDIT_COURSES_PER_PROFILE ); - ScreenPrompt::Prompt( SM_None, s ); - return; - } - RString sDefaultName; RString sThrowAway; for( int i=1; i<=9999; i++ ) diff --git a/stepmania/src/ScreenOptionsManageWorkouts.cpp b/stepmania/src/ScreenOptionsManageWorkouts.cpp index 197fdde554..a1120116e7 100644 --- a/stepmania/src/ScreenOptionsManageWorkouts.cpp +++ b/stepmania/src/ScreenOptionsManageWorkouts.cpp @@ -3,19 +3,24 @@ #include "ScreenManager.h" #include "ScreenMiniMenu.h" #include "OptionRowHandler.h" -#include "WorkoutManager.h" -#include "Workout.h" +#include "Course.h" +#include "SongManager.h" #include "LocalizedString.h" #include "GameState.h" #include "ScreenTextEntry.h" #include "ScreenPrompt.h" #include "StatsManager.h" #include "PrefsManager.h" +#include "WorkoutManager.h" +#include "ProfileManager.h" +#include "GameManager.h" +#include "CourseUtil.h" AutoScreenMessage( SM_BackFromRename ) AutoScreenMessage( SM_BackFromDelete ) AutoScreenMessage( SM_BackFromContextMenu ) + enum ManageWorkoutsAction { ManageWorkoutsAction_Choose, @@ -53,7 +58,17 @@ void ScreenOptionsManageWorkouts::BeginScreen() { STATSMAN->Reset(); - WORKOUTMAN->LoadAllFromDisk(); + + vector vpStyles; + GameManager::GetStylesForGame( GAMESTATE->m_pCurGame, vpStyles ); + const Style *pStyle = vpStyles[0]; + GAMESTATE->SetCurrentStyle( pStyle ); + + + // Remember the current course. All Course pointers will be invalidated when we load the machine profile below. + CourseID cidLast; + cidLast.FromCourse( GAMESTATE->m_pCurCourse ); + vector vHands; @@ -71,14 +86,16 @@ void ScreenOptionsManageWorkouts::BeginScreen() iIndex++; } - m_vpWorkouts = WORKOUTMAN->m_vpAllWorkouts; + FlushDirCache(); + PROFILEMAN->LoadMachineProfileEdits(); + EditCourseUtil::GetAllEditCourses( m_vpCourses ); - FOREACH_CONST( Workout*, m_vpWorkouts, p ) + FOREACH_CONST( Course*, m_vpCourses, p ) { vHands.push_back( OptionRowHandlerUtil::MakeNull() ); OptionRowDefinition &def = vHands.back()->m_Def; - def.m_sName = (*p)->m_sName; + def.m_sName = (*p)->GetDisplayFullTitle(); def.m_bAllowThemeTitle = false; // not themable def.m_sExplanationName = "Select Workout"; def.m_vsChoices.clear(); @@ -92,12 +109,14 @@ void ScreenOptionsManageWorkouts::BeginScreen() ScreenOptions::BeginScreen(); // select the last chosen course - if( WORKOUTMAN->m_pCurWorkout ) - { - vector::const_iterator iter = find( m_vpWorkouts.begin(), m_vpWorkouts.end(), WORKOUTMAN->m_pCurWorkout ); - if( iter != m_vpWorkouts.end() ) + GAMESTATE->m_pCurCourse.Set( cidLast.ToCourse() ); + if( GAMESTATE->m_pCurCourse ) + { + EditCourseUtil::UpdateAndSetTrail(); + vector::const_iterator iter = find( m_vpCourses.begin(), m_vpCourses.end(), GAMESTATE->m_pCurCourse ); + if( iter != m_vpCourses.end() ) { - int iIndex = iter - m_vpWorkouts.begin(); + int iIndex = iter - m_vpCourses.begin(); this->MoveRowAbsolute( PLAYER_1, 1 + iIndex ); } } @@ -105,11 +124,11 @@ void ScreenOptionsManageWorkouts::BeginScreen() AfterChangeRow( PLAYER_1 ); } -static LocalizedString ERROR_RENAMING_WORKOUT ("ScreenOptionsManageWorkouts", "Error renaming workout file."); -static LocalizedString ERROR_DELETING_WORKOUT_FILE ("ScreenOptionsManageWorkouts", "Error deleting the workout file '%s'."); -static LocalizedString THIS_WORKOUT_WILL_BE_LOST ("ScreenOptionsManageWorkouts", "This workout will be lost permanently."); -static LocalizedString CONTINUE_WITH_DELETE ("ScreenOptionsManageWorkouts", "Continue with delete?"); -static LocalizedString ENTER_NAME_FOR_WORKOUT ("ScreenOptionsManageWorkouts", "Enter a name for this workout."); +static LocalizedString ERROR_RENAMING ("ScreenOptionsManageWorkouts", "Error renaming file."); +static LocalizedString ERROR_DELETING_FILE ("ScreenOptionsManageWorkouts", "Error deleting the file '%s'."); +static LocalizedString THIS_WILL_BE_LOST ("ScreenOptionsManageWorkouts", "This file will be lost permanently."); +static LocalizedString CONTINUE_WITH_DELETE ("ScreenOptionsManageWorkouts", "Continue with delete?"); +static LocalizedString ENTER_NAME ("ScreenOptionsManageWorkouts", "Enter a name."); void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) { if( SM == SM_GoToNextScreen ) @@ -118,9 +137,14 @@ void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) if( iCurRow == 0 ) // "create new" { - WORKOUTMAN->m_pCurWorkout = new Workout; - WORKOUTMAN->LoadDefaults( *WORKOUTMAN->m_pCurWorkout ); - WORKOUTMAN->m_vpAllWorkouts.push_back( WORKOUTMAN->m_pCurWorkout ); + /* Allocate the Course now, but don't save the file until the user explicitly chooses Save */ + Course *pCourse = new Course; + EditCourseUtil::LoadDefaults( *pCourse ); + pCourse->m_LoadedFromProfile = ProfileSlot_Machine; + SONGMAN->AddCourse( pCourse ); + GAMESTATE->m_pCurCourse.Set( pCourse ); + EditCourseUtil::s_bNewCourseNeedsName = true; + EditCourseUtil::UpdateAndSetTrail(); SCREENMAN->SetNewScreen( CREATE_NEW_SCREEN ); return; // don't call base @@ -141,10 +165,9 @@ void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) { ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this - Workout *pWorkout = WORKOUTMAN->m_pCurWorkout; - if( !WORKOUTMAN->RenameAndSave(pWorkout, ScreenTextEntry::s_sLastAnswer) ) + if( !EditCourseUtil::RenameAndSave(GAMESTATE->m_pCurCourse, ScreenTextEntry::s_sLastAnswer) ) { - ScreenPrompt::Prompt( SM_None, ERROR_RENAMING_WORKOUT ); + ScreenPrompt::Prompt( SM_None, ERROR_RENAMING ); return; } @@ -155,14 +178,15 @@ void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) { if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) { - Workout *pWorkout = GetWorkoutWithFocus(); - if( !WORKOUTMAN->RemoveAndDeleteFile( pWorkout ) ) + Course *pCourse = GetCourseWithFocus(); + if( !EditCourseUtil::RemoveAndDeleteFile( pCourse ) ) { - ScreenPrompt::Prompt( SM_None, ssprintf(ERROR_DELETING_WORKOUT_FILE.GetValue(),pWorkout->m_sFile.c_str()) ); + ScreenPrompt::Prompt( SM_None, ssprintf(ERROR_DELETING_FILE.GetValue(),pCourse->m_sPath.c_str()) ); return; } - WORKOUTMAN->m_pCurWorkout = NULL; + GAMESTATE->m_pCurCourse.Set( NULL ); + GAMESTATE->m_pCurTrail[PLAYER_1].Set( NULL ); SCREENMAN->SetNewScreen( this->m_sName ); // reload } } @@ -174,9 +198,9 @@ void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) { case ManageWorkoutsAction_Choose: { - Workout *p = GetWorkoutWithFocus(); - WORKOUTMAN->m_pCurWorkout = p; - + GAMESTATE->m_pCurCourse.Set( GetCourseWithFocus() ); + EditCourseUtil::UpdateAndSetTrail(); + EditCourseUtil::s_bNewCourseNeedsName = false; ScreenOptions::BeginFadingOut(); } break; @@ -184,15 +208,15 @@ void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) { ScreenTextEntry::TextEntry( SM_BackFromRename, - ENTER_NAME_FOR_WORKOUT, - WORKOUTMAN->m_pCurWorkout->m_sName, - MAX_WORKOUT_NAME_LENGTH, - WorkoutManager::ValidateWorkoutName ); + ENTER_NAME, + GAMESTATE->m_pCurCourse->GetDisplayFullTitle(), + EditCourseUtil::MAX_NAME_LENGTH, + EditCourseUtil::ValidateEditCourseName ); } break; case ManageWorkoutsAction_Delete: { - ScreenPrompt::Prompt( SM_BackFromDelete, THIS_WORKOUT_WILL_BE_LOST.GetValue()+"\n\n"+CONTINUE_WITH_DELETE.GetValue(), PROMPT_YES_NO, ANSWER_NO ); + ScreenPrompt::Prompt( SM_BackFromDelete, THIS_WILL_BE_LOST.GetValue()+"\n\n"+CONTINUE_WITH_DELETE.GetValue(), PROMPT_YES_NO, ANSWER_NO ); } break; } @@ -212,13 +236,11 @@ void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) void ScreenOptionsManageWorkouts::AfterChangeRow( PlayerNumber pn ) { - WORKOUTMAN->m_pCurWorkout = GetWorkoutWithFocus(); - ScreenOptions::AfterChangeRow( pn ); } -static LocalizedString YOU_HAVE_MAX_WORKOUTS( "ScreenOptionsManageWorkouts", "You have %d workouts, the maximum number allowed." ); -static LocalizedString YOU_MUST_DELETE( "ScreenOptionsManageWorkouts", "You must delete an existing workout before creating a new workout." ); +static LocalizedString YOU_HAVE_MAX( "ScreenOptionsManageWorkouts", "You have %d, the maximum number allowed." ); +static LocalizedString YOU_MUST_DELETE( "ScreenOptionsManageWorkouts", "You must delete an existing before creating a new." ); void ScreenOptionsManageWorkouts::ProcessMenuStart( const InputEventPlus &input ) { if( IsTransitioning() ) @@ -228,9 +250,11 @@ void ScreenOptionsManageWorkouts::ProcessMenuStart( const InputEventPlus &input if( iCurRow == 0 ) // "create new" { - if( WORKOUTMAN->m_vpAllWorkouts.size() >= size_t(MAX_WORKOUTS_PER_PROFILE) ) + vector vpCourses; + EditCourseUtil::GetAllEditCourses( vpCourses ); + if( vpCourses.size() >= (size_t)EditCourseUtil::MAX_PER_PROFILE ) { - RString s = ssprintf( YOU_HAVE_MAX_WORKOUTS.GetValue()+"\n\n"+YOU_MUST_DELETE.GetValue(), MAX_WORKOUTS_PER_PROFILE ); + RString s = ssprintf( YOU_HAVE_MAX.GetValue()+"\n\n"+YOU_MUST_DELETE.GetValue(), EditCourseUtil::MAX_PER_PROFILE ); ScreenPrompt::Prompt( SM_None, s ); return; } @@ -267,7 +291,7 @@ void ScreenOptionsManageWorkouts::ExportOptions( int iRow, const vectorm_MasterPlayerNumber]; if( iCurRow == 0 ) @@ -277,7 +301,7 @@ Workout *ScreenOptionsManageWorkouts::GetWorkoutWithFocus() const // a Steps int iStepsIndex = iCurRow - 1; - return m_vpWorkouts[iStepsIndex]; + return m_vpCourses[iStepsIndex]; } /* diff --git a/stepmania/src/ScreenOptionsManageWorkouts.h b/stepmania/src/ScreenOptionsManageWorkouts.h index ecefeafae9..46e68efd30 100644 --- a/stepmania/src/ScreenOptionsManageWorkouts.h +++ b/stepmania/src/ScreenOptionsManageWorkouts.h @@ -4,7 +4,7 @@ #include "ScreenOptions.h" #include "GameConstantsAndTypes.h" -class Workout; +class Course; class ScreenOptionsManageWorkouts : public ScreenOptions { @@ -21,9 +21,9 @@ protected: virtual void AfterChangeRow( PlayerNumber pn ); virtual void ProcessMenuStart( const InputEventPlus &input ); - Workout *GetWorkoutWithFocus() const; + Course *GetCourseWithFocus() const; - vector m_vpWorkouts; + vector m_vpCourses; ThemeMetric CREATE_NEW_SCREEN; }; diff --git a/stepmania/src/ScreenOptionsReviewWorkout.cpp b/stepmania/src/ScreenOptionsReviewWorkout.cpp index 4d806cc6cc..6b560c4109 100644 --- a/stepmania/src/ScreenOptionsReviewWorkout.cpp +++ b/stepmania/src/ScreenOptionsReviewWorkout.cpp @@ -23,18 +23,18 @@ enum ReviewWorkoutRow { ReviewWorkoutRow_Play, - ReviewWorkoutRow_EditWorkout, - ReviewWorkoutRow_EditPlaylist, + ReviewWorkoutRow_Edit, + ReviewWorkoutRow_Shuffle, ReviewWorkoutRow_Save, NUM_ReviewWorkoutRow }; static const MenuRowDef g_MenuRows[] = { - MenuRowDef( -1, "Play", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Edit Workout", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Edit Playlist", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Save", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Play", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Edit Workout", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Shuffle", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Save", true, EditMode_Practice, true, false, 0, NULL ), }; REGISTER_SCREEN_CLASS( ScreenOptionsReviewWorkout ); @@ -50,8 +50,7 @@ void ScreenOptionsReviewWorkout::Init() m_soundSave.Load( THEME->GetPathS(m_sName,"Save") ); PLAY_SCREEN.Load(m_sName,"PlayScreen"); - EDIT_WORKOUT_SCREEN.Load(m_sName,"EditWorkoutScreen"); - EDIT_PLAYLIST_SCREEN.Load(m_sName,"EditPlaylistScreen"); + EDIT_SCREEN.Load(m_sName,"EditScreen"); } void ScreenOptionsReviewWorkout::BeginScreen() @@ -67,6 +66,9 @@ void ScreenOptionsReviewWorkout::BeginScreen() ScreenOptions::InitMenu( vHands ); ScreenOptions::BeginScreen(); + + // clear the current song in case it's set when we back out from gameplay + GAMESTATE->m_pCurSong.Set( NULL ); } ScreenOptionsReviewWorkout::~ScreenOptionsReviewWorkout() @@ -98,31 +100,11 @@ void ScreenOptionsReviewWorkout::HandleScreenMessage( const ScreenMessage SM ) switch( iRow ) { case ReviewWorkoutRow_Play: - { - Workout *pWorkout = WORKOUTMAN->m_pCurWorkout; - pWorkout->GenerateCourse( *WORKOUTMAN->m_pTempCourse ); - GAMESTATE->m_pCurSong.Set( NULL ); // CurSong will be set if we back out. Set it back to NULL so that ScreenStage won't show the last song. - GAMESTATE->m_pCurCourse.Set( WORKOUTMAN->m_pTempCourse ); - const Style *pStyle = GameManager::GameAndStringToStyle(GAMESTATE->m_pCurGame,"single"); - StepsType st = pStyle->m_StepsType; - Trail *pTrail = GAMESTATE->m_pCurCourse->GetTrail( st ); - ASSERT( pTrail ); - GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail ); - - GAMESTATE->m_PlayMode.Set( PLAY_MODE_ENDLESS ); - GAMESTATE->m_bSideIsJoined[0] = true; - GAMESTATE->SetCurrentStyle( pStyle ); - - PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_GoalType = GoalType_Time; - PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_iGoalSeconds = pWorkout->m_iMinutes * 60; - SCREENMAN->SetNewScreen( PLAY_SCREEN ); - } + EditCourseUtil::PrepareForPlay(); + SCREENMAN->SetNewScreen( PLAY_SCREEN ); return; // handled - case ReviewWorkoutRow_EditWorkout: - SCREENMAN->SetNewScreen( EDIT_WORKOUT_SCREEN ); - return; // handled - case ReviewWorkoutRow_EditPlaylist: - SCREENMAN->SetNewScreen( EDIT_PLAYLIST_SCREEN ); + case ReviewWorkoutRow_Edit: + SCREENMAN->SetNewScreen( EDIT_SCREEN ); return; // handled } } @@ -131,11 +113,11 @@ void ScreenOptionsReviewWorkout::HandleScreenMessage( const ScreenMessage SM ) if( !ScreenTextEntry::s_bCancelledLast ) { ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this - if( WORKOUTMAN->RenameAndSave( WORKOUTMAN->m_pCurWorkout, ScreenTextEntry::s_sLastAnswer ) ) + + if( EditCourseUtil::RenameAndSave( GAMESTATE->m_pCurCourse, ScreenTextEntry::s_sLastAnswer ) ) { m_soundSave.Play(); SCREENMAN->SystemMessage( WORKOUT_SAVED ); - MESSAGEMAN->Broadcast( "WorkoutChanged" ); } } } @@ -159,30 +141,38 @@ void ScreenOptionsReviewWorkout::ProcessMenuStart( const InputEventPlus &input ) switch( iRow ) { case ReviewWorkoutRow_Play: - case ReviewWorkoutRow_EditWorkout: - case ReviewWorkoutRow_EditPlaylist: + case ReviewWorkoutRow_Edit: SCREENMAN->PlayStartSound(); this->BeginFadingOut(); return; // handled + case ReviewWorkoutRow_Shuffle: + { + Course *pCourse = GAMESTATE->m_pCurCourse; + random_shuffle( pCourse->m_vEntries.begin(), pCourse->m_vEntries.end() ); + Trail *pTrail = pCourse->GetTrailForceRegenCache( GAMESTATE->m_pCurStyle->m_StepsType ); + GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail ); + SCREENMAN->PlayStartSound(); + MESSAGEMAN->Broadcast("CurrentCourseChanged"); + } + return; // handled case ReviewWorkoutRow_Save: { - bool bPromptForName = !WORKOUTMAN->m_pCurWorkout->m_bNameWasSetByUser; + bool bPromptForName = EditCourseUtil::s_bNewCourseNeedsName; if( bPromptForName ) { ScreenTextEntry::TextEntry( SM_BackFromEnterName, ENTER_WORKOUT_NAME, - WORKOUTMAN->m_pCurWorkout->m_sName, - MAX_WORKOUT_NAME_LENGTH, - WorkoutManager::ValidateWorkoutName ); + GAMESTATE->m_pCurCourse->GetDisplayFullTitle(), + EditCourseUtil::MAX_NAME_LENGTH, + EditCourseUtil::ValidateEditCourseName ); } else { - if( WORKOUTMAN->Save( WORKOUTMAN->m_pCurWorkout ) ) + if( EditCourseUtil::Save( GAMESTATE->m_pCurCourse ) ) { m_soundSave.Play(); SCREENMAN->SystemMessage( WORKOUT_SAVED ); - MESSAGEMAN->Broadcast( "WorkoutChanged" ); } else { diff --git a/stepmania/src/ScreenOptionsReviewWorkout.h b/stepmania/src/ScreenOptionsReviewWorkout.h index 71004cb84c..93a315705d 100644 --- a/stepmania/src/ScreenOptionsReviewWorkout.h +++ b/stepmania/src/ScreenOptionsReviewWorkout.h @@ -22,8 +22,7 @@ private: RageSound m_soundSave; ThemeMetric PLAY_SCREEN; - ThemeMetric EDIT_WORKOUT_SCREEN; - ThemeMetric EDIT_PLAYLIST_SCREEN; + ThemeMetric EDIT_SCREEN; }; #endif diff --git a/stepmania/src/ScreenOptionsToggleSongs.cpp b/stepmania/src/ScreenOptionsToggleSongs.cpp index 7e3fe73da8..e19e8e667f 100644 --- a/stepmania/src/ScreenOptionsToggleSongs.cpp +++ b/stepmania/src/ScreenOptionsToggleSongs.cpp @@ -16,7 +16,7 @@ void ScreenOptionsToggleSongs::BeginScreen() vector vHands; - const vector &apAllSongs = SONGMAN->GetSongs(); + const vector &apAllSongs = SONGMAN->GetAllSongs(); FOREACH_CONST( Song *, apAllSongs , s ) { Song *pSong = *s; diff --git a/stepmania/src/SongManager.cpp b/stepmania/src/SongManager.cpp index 9bbb71c1c3..fe2e473b92 100644 --- a/stepmania/src/SongManager.cpp +++ b/stepmania/src/SongManager.cpp @@ -313,7 +313,7 @@ void SongManager::PreloadSongImages() * that we don't need to. */ RageTexturePreloader preload; - const vector &songs = GetSongs(); + const vector &songs = GetAllSongs(); for( unsigned i = 0; i < songs.size(); ++i ) { if( !songs[i]->HasBanner() ) @@ -659,17 +659,6 @@ int SongManager::GetNumCourseGroups() const return m_mapCourseGroupToInfo.size(); } -int SongManager::GetNumEditCourses( ProfileSlot slot ) const -{ - int iNum = 0; - FOREACH_CONST( Course*, m_pCourses, p ) - { - if( (*p)->GetLoadedFromProfileSlot() == slot ) - ++iNum; - } - return iNum; -} - RString SongManager::ShortenGroupName( RString sLongGroupName ) { static TitleSubst tsub("Groups"); @@ -756,7 +745,7 @@ void SongManager::InitAutogenCourses() m_pCourses.push_back( pCourse ); } - vector apCourseSongs = GetSongs(); + vector apCourseSongs = GetAllSongs(); // Generate "All Songs" endless course. pCourse = new Course; @@ -769,7 +758,7 @@ void SongManager::InitAutogenCourses() /* We normally sort by translit artist. However, display artist is more * consistent. For example, transliterated Japanese names are alternately * spelled given- and family-name first, but display titles are more consistent. */ - vector apSongs = this->GetSongs(); + vector apSongs = this->GetAllSongs(); SongUtil::SortSongPointerArrayByDisplayArtist( apSongs ); RString sCurArtist = ""; @@ -984,7 +973,7 @@ void SongManager::SaveEnabledSongsToPref() // Intentionally drop disabled song entries for songs that aren't currently loaded. - const vector &apSongs = SONGMAN->GetSongs(); + const vector &apSongs = SONGMAN->GetAllSongs(); FOREACH_CONST( Song *, apSongs, s ) { Song *pSong = (*s); @@ -1016,7 +1005,7 @@ void SongManager::LoadEnabledSongsFromPref() void SongManager::GetStepsLoadedFromProfile( vector &AddTo, ProfileSlot slot ) const { - const vector &vSongs = GetSongs(); + const vector &vSongs = GetAllSongs(); FOREACH_CONST( Song*, vSongs, song ) { (*song)->GetStepsLoadedFromProfile( slot, AddTo ); @@ -1026,7 +1015,7 @@ void SongManager::GetStepsLoadedFromProfile( vector &AddTo, ProfileSlot Song *SongManager::GetSongFromSteps( Steps *pSteps ) const { ASSERT( pSteps ); - const vector &vSongs = GetSongs(); + const vector &vSongs = GetAllSongs(); FOREACH_CONST( Song*, vSongs, song ) { vector vSteps; @@ -1759,7 +1748,7 @@ class LunaSongManager: public Luna public: static int GetAllSongs( T* p, lua_State *L ) { - const vector &v = p->GetSongs(); + const vector &v = p->GetAllSongs(); LuaHelpers::CreateTableFromArray( v, L ); return 1; } diff --git a/stepmania/src/SongManager.h b/stepmania/src/SongManager.h index 49f00e049b..d2667b7c85 100644 --- a/stepmania/src/SongManager.h +++ b/stepmania/src/SongManager.h @@ -77,11 +77,12 @@ public: // Lookup - const vector &GetSongs( const RString &sGroupName = GROUP_ALL ) const; + const vector &GetSongs( const RString &sGroupName ) const; + const vector &GetAllSongs() const { return GetSongs(GROUP_ALL); } void GetPopularSongs( vector &AddTo, const RString &sGroupName ) const; + const vector &GetAllPopularSongs() const { return m_pPopularSongs; } void GetPreferredSortSongs( vector &AddTo ) const; RString SongToPreferredSortSectionName( const Song *pSong ) const; - const vector &GetPopularSongs() const { return m_pPopularSongs; } const vector &GetPopularCourses( CourseType ct ) const { return m_pPopularCourses[ct]; } Song *FindSong( RString sPath ) const; Song *FindSong( RString sGroup, RString sSong ) const; @@ -95,7 +96,6 @@ public: int GetNumCourses() const; int GetNumAdditionalCourses() const; int GetNumCourseGroups() const; - int GetNumEditCourses( ProfileSlot slot ) const; Song* GetRandomSong(); Course* GetRandomCourse(); diff --git a/stepmania/src/SongUtil.cpp b/stepmania/src/SongUtil.cpp index 0287551c84..5a04985450 100644 --- a/stepmania/src/SongUtil.cpp +++ b/stepmania/src/SongUtil.cpp @@ -800,7 +800,7 @@ bool SongUtil::ValidateCurrentStepsDescription( const RString &sAnswer, RString void SongUtil::GetAllSongGenres( vector &vsOut ) { set genres; - FOREACH_CONST( Song*, SONGMAN->GetSongs(), song ) + FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), song ) { if( !(*song)->m_sGenre.empty() ) genres.insert( (*song)->m_sGenre ); diff --git a/stepmania/src/StepMania-net2003.vcproj b/stepmania/src/StepMania-net2003.vcproj index ca9fdab213..2fcdb70b29 100644 --- a/stepmania/src/StepMania-net2003.vcproj +++ b/stepmania/src/StepMania-net2003.vcproj @@ -466,12 +466,6 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ - - - - diff --git a/stepmania/src/StepMania.cpp b/stepmania/src/StepMania.cpp index 7c01dd0cdc..f728d2f313 100644 --- a/stepmania/src/StepMania.cpp +++ b/stepmania/src/StepMania.cpp @@ -45,7 +45,6 @@ #include "NoteSkinManager.h" #include "PrefsManager.h" #include "SongManager.h" -#include "WorkoutManager.h" #include "CharacterManager.h" #include "GameState.h" #include "AnnouncerManager.h" @@ -260,7 +259,6 @@ void ShutdownGame() SAFE_DELETE( UNLOCKMAN ); SAFE_DELETE( CRYPTMAN ); SAFE_DELETE( MEMCARDMAN ); - SAFE_DELETE( WORKOUTMAN ); SAFE_DELETE( SONGMAN ); SAFE_DELETE( BANNERCACHE ); SAFE_DELETE( SONGINDEX ); @@ -1082,7 +1080,6 @@ int main(int argc, char* argv[]) /* depends on SONGINDEX: */ SONGMAN = new SongManager; - WORKOUTMAN = new WorkoutManager; SONGMAN->InitAll( pLoadingWindow ); // this takes a long time CRYPTMAN = new CryptManager; // need to do this before ProfileMan if( PREFSMAN->m_bSignProfileData ) diff --git a/stepmania/src/StepsUtil.cpp b/stepmania/src/StepsUtil.cpp index 13b99f2365..536d747907 100644 --- a/stepmania/src/StepsUtil.cpp +++ b/stepmania/src/StepsUtil.cpp @@ -113,7 +113,7 @@ void StepsUtil::SortStepsPointerArrayByNumPlays( vector &vStepsPointers, void StepsUtil::SortStepsPointerArrayByNumPlays( vector &vStepsPointers, const Profile* pProfile, bool bDecending ) { // ugly... - vector vpSongs = SONGMAN->GetSongs(); + vector vpSongs = SONGMAN->GetAllSongs(); vector vpAllSteps; map mapStepsToSong; { diff --git a/stepmania/src/TrailUtil.cpp b/stepmania/src/TrailUtil.cpp index fc9a2936cf..6d1002ed05 100644 --- a/stepmania/src/TrailUtil.cpp +++ b/stepmania/src/TrailUtil.cpp @@ -4,8 +4,24 @@ #include "Course.h" #include "XmlFile.h" #include "GameManager.h" +#include "Song.h" +int TrailUtil::GetNumSongs( const Trail *pTrail ) +{ + return pTrail->m_vEntries.size(); +} + +float TrailUtil::GetTotalSeconds( const Trail *pTrail ) +{ + float fSecs = 0; + FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) + fSecs += e->pSong->m_fMusicLengthSeconds; + return fSecs; +} + +/////////////////////////////////////////////////////////////////////// + void TrailID::FromTrail( const Trail *p ) { if( p == NULL ) @@ -84,6 +100,37 @@ bool TrailID::operator<( const TrailID &rhs ) const return false; } + +// lua start +#include "LuaBinding.h" + +namespace +{ + int GetNumSongs( lua_State *L ) + { + Trail *pTrail = Luna::check( L, 1, true ); + int iNum = TrailUtil::GetNumSongs( pTrail ); + LuaHelpers::Push( L, iNum ); + return 1; + } + int GetTotalSeconds( lua_State *L ) + { + Trail *pTrail = Luna::check( L, 1, true ); + float fSecs = TrailUtil::GetTotalSeconds( pTrail ); + LuaHelpers::Push( L, fSecs ); + return 1; + } + + const luaL_Reg TrailUtilTable[] = + { + LIST_METHOD( GetNumSongs ), + LIST_METHOD( GetTotalSeconds ), + { NULL, NULL } + }; +} + +LUA_REGISTER_NAMESPACE( TrailUtil ) + /* * (c) 2004 Chris Danford * All rights reserved. diff --git a/stepmania/src/TrailUtil.h b/stepmania/src/TrailUtil.h index bee610cd46..6ec92ba691 100644 --- a/stepmania/src/TrailUtil.h +++ b/stepmania/src/TrailUtil.h @@ -10,6 +10,12 @@ class Trail; class Course; class XNode; +namespace TrailUtil +{ + int GetNumSongs( const Trail *pTrail ); + float GetTotalSeconds( const Trail *pTrail ); +}; + class TrailID { StepsType st; diff --git a/stepmania/src/UnlockManager.cpp b/stepmania/src/UnlockManager.cpp index b4967734ee..6d030e219c 100644 --- a/stepmania/src/UnlockManager.cpp +++ b/stepmania/src/UnlockManager.cpp @@ -446,7 +446,7 @@ void UnlockManager::Load() if( AUTO_LOCK_CHALLENGE_STEPS ) { - FOREACH_CONST( Song*, SONGMAN->GetSongs(), s ) + FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), s ) { // If no hard steps to play to unlock, skip if( SongUtil::GetOneSteps(*s, StepsType_Invalid, Difficulty_Hard) == NULL ) diff --git a/stepmania/src/Workout.cpp b/stepmania/src/Workout.cpp index e812ec71fb..4487aa254a 100644 --- a/stepmania/src/Workout.cpp +++ b/stepmania/src/Workout.cpp @@ -103,22 +103,10 @@ void Workout::GenerateCourse( Course &out ) out.m_sMainTitle = "temp"; out.m_bRepeat = true; - // Choose a large number of course entries. We may loop if the goal - // is not yet reached, and it would be bad to play the same sequence - // of songs over again. - const int iNumCourseEntries = 6*5; // choose a multiple of the intervals above, or else the WorkoutGraph will get out of sync with the actual songs. - - vector viMeter; - GetEstimatedMeters( iNumCourseEntries, viMeter ); - - for( int i=0; iGetName() == "SongGenre" ) + if( song->GetName() == "Song" ) { RString s; - songGenre->GetTextValue( s ); - m_vsSongGenres.push_back( s ); + song->GetTextValue( s ); + SongID sid; + sid.FromString( s ); + m_vSongs.push_back( sid ); } } } @@ -175,10 +165,10 @@ bool Workout::SaveToFile( RString sFile ) xml.AppendChild( "Minutes", m_iMinutes ); xml.AppendChild( "AverageMeter", m_iAverageMeter ); - XNode *songGenres = xml.AppendChild("SongGenres"); - FOREACH_CONST( RString, m_vsSongGenres, s ) + XNode *songs = xml.AppendChild("Songs"); + FOREACH_CONST( SongID, m_vSongs, s ) { - songGenres->AppendChild( "SongGenre", *s ); + songs->AppendChild( "Song", s->ToString() ); } return XmlFileUtil::SaveToFile( &xml, sFile ); diff --git a/stepmania/src/Workout.h b/stepmania/src/Workout.h index 0547224854..ea00eca6a7 100644 --- a/stepmania/src/Workout.h +++ b/stepmania/src/Workout.h @@ -37,7 +37,7 @@ public: WorkoutProgram m_WorkoutProgram; int m_iMinutes; int m_iAverageMeter; - vector m_vsSongGenres; + vector m_vSongs; int GetEstimatedNumSongs() const; static int GetEstimatedNumSongsFromSeconds( float fSeconds ); diff --git a/stepmania/src/WorkoutGraph.cpp b/stepmania/src/WorkoutGraph.cpp index 9b732021fa..8bb5699929 100644 --- a/stepmania/src/WorkoutGraph.cpp +++ b/stepmania/src/WorkoutGraph.cpp @@ -7,12 +7,12 @@ #include "Steps.h" #include "GameState.h" #include "ThemeManager.h" -#include "Workout.h" -#include "WorkoutManager.h" #include "StatsManager.h" #include "Foreach.h" +#include "Course.h" +#include "Style.h" -const int MAX_METERS_TO_SHOW = Workout::GetEstimatedNumSongsFromSeconds( 90 * 60 ); +const int MAX_METERS_TO_SHOW = 50; REGISTER_ACTOR_CLASS( WorkoutGraph ) @@ -48,7 +48,10 @@ void WorkoutGraph::SetFromCurrentWorkout() void WorkoutGraph::SetInternal( int iMinSongsPlayed ) { - ASSERT( WORKOUTMAN->m_pCurWorkout ); + Course *pCourse = GAMESTATE->m_pCurCourse; + ASSERT( pCourse ); + Trail *pTrail = GAMESTATE->m_pCurTrail[PLAYER_1]; + ASSERT( pTrail ); FOREACH( Sprite*, m_vpBars, p ) { @@ -57,13 +60,12 @@ void WorkoutGraph::SetInternal( int iMinSongsPlayed ) } m_vpBars.clear(); - int iWorkoutEstimatedSongs = WORKOUTMAN->m_pCurWorkout->GetEstimatedNumSongs(); - int iNumSongsToShow = max( iMinSongsPlayed, iWorkoutEstimatedSongs ); vector viMeters; - WORKOUTMAN->m_pCurWorkout->GetEstimatedMeters( iNumSongsToShow, viMeters ); - - m_iSongsChoppedOffAtBeginning = max( 0, ((int)viMeters.size()) - MAX_METERS_TO_SHOW ); - viMeters.erase( viMeters.begin(), viMeters.begin()+m_iSongsChoppedOffAtBeginning ); + FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) + { + ASSERT( e->pSteps ); + viMeters.push_back( e->pSteps->GetMeter() ); + } int iBlocksWide = viMeters.size(); int iBlocksHigh = MAX_METER; diff --git a/stepmania/src/WorkoutManager.cpp b/stepmania/src/WorkoutManager.cpp index 969068b9ea..8b0f5daa42 100644 --- a/stepmania/src/WorkoutManager.cpp +++ b/stepmania/src/WorkoutManager.cpp @@ -8,111 +8,54 @@ #include "FontCharAliases.h" #include "ProfileManager.h" #include "LocalizedString.h" +#include "GameState.h" +#include "GameManager.h" +#include "Style.h" +#include "Profile.h" +#include "CourseWriterCRS.h" -static const RString WORKOUTS_SUBDIR = "Workouts/"; +int EditCourseUtil::MAX_NAME_LENGTH = 16; +int EditCourseUtil::MAX_PER_PROFILE = 32; +bool EditCourseUtil::s_bNewCourseNeedsName = false; -WorkoutManager* WORKOUTMAN = NULL; // global and accessable from anywhere in our program - -WorkoutManager::WorkoutManager() +bool EditCourseUtil::Save( Course *pCourse ) { - m_pCurWorkout = NULL; - m_pTempCourse = new Course; + return EditCourseUtil::RenameAndSave( pCourse, pCourse->GetDisplayFullTitle() ); +} - // Register with Lua. +bool EditCourseUtil::RenameAndSave( Course *pCourse, RString sName ) +{ + ASSERT( !sName.empty() ); + + EditCourseUtil::s_bNewCourseNeedsName = false; + + RString sNewFilePath = PROFILEMAN->GetProfileDir(ProfileSlot_Machine) + EDIT_COURSES_SUBDIR + sName + ".crs"; + + // remove the old file if the name is changing + if( !pCourse->m_sPath.empty() && sNewFilePath != pCourse->m_sPath ) { - Lua *L = LUA->Get(); - lua_pushstring( L, "WORKOUTMAN" ); - this->PushSelf( L ); - lua_settable(L, LUA_GLOBALSINDEX); - LUA->Release( L ); + FILEMAN->Remove( pCourse->m_sPath ); // not fatal if this fails + FlushDirCache(); } + + pCourse->m_sMainTitle = sName; + pCourse->m_sPath = sNewFilePath; + return CourseWriterCRS::Write( *pCourse, pCourse->m_sPath, false ); } -WorkoutManager::~WorkoutManager() +bool EditCourseUtil::RemoveAndDeleteFile( Course *pCourse ) { - // Unregister with Lua. - LUA->UnsetGlobal( "WORKOUTMAN" ); - - FOREACH( Workout*, m_vpAllWorkouts, p ) - SAFE_DELETE( *p ); - m_vpAllWorkouts.clear(); - - SAFE_DELETE( m_pTempCourse ); -} - -void WorkoutManager::LoadAllFromDisk() -{ - m_vpAllWorkouts.clear(); - vector vsFiles; - GetDirListing( PROFILEMAN->GetProfileDir(ProfileSlot_Machine) + WORKOUTS_SUBDIR + "*.xml", vsFiles, false, true ); - FOREACH_CONST( RString, vsFiles, s ) - { - Workout *p = new Workout; - if( p->LoadFromFile( *s ) ) - m_vpAllWorkouts.push_back( p ); - } -} - -void WorkoutManager::LoadDefaults( Workout &out ) -{ - out = Workout(); - - // pick a default name - // XXX: Make this localizable - for( int i=0; i<10000; i++ ) - { - out.m_sName = ssprintf("Workout %d", i+1); - bool bNameInUse = false; - FOREACH_CONST( Workout*, m_vpAllWorkouts, p ) - { - if( out.m_sName == (*p)->m_sName ) - { - bNameInUse = true; - break; - } - } - - if( !bNameInUse ) - break; - } - SongUtil::GetAllSongGenres( out.m_vsSongGenres ); -} - -bool WorkoutManager::RenameAndSave( Workout *pWorkout, RString sNewName ) -{ - pWorkout->m_bNameWasSetByUser = true; - ASSERT( !sNewName.empty() ); - vector::iterator iter = find( m_vpAllWorkouts.begin(), m_vpAllWorkouts.end(), pWorkout ); - if( iter == m_vpAllWorkouts.end() ) - return false; - pWorkout->m_sName = sNewName; - FILEMAN->Remove( pWorkout->m_sFile ); - FlushDirCache(); // not fatal if this fails - pWorkout->m_sFile = PROFILEMAN->GetProfileDir(ProfileSlot_Machine) + WORKOUTS_SUBDIR + pWorkout->m_sName + ".xml"; - return pWorkout->SaveToFile( pWorkout->m_sFile ); -} - -bool WorkoutManager::Save( Workout *pWorkout ) -{ - ASSERT( !pWorkout->m_sFile.empty() ); - return pWorkout->SaveToFile( pWorkout->m_sFile ); -} - -bool WorkoutManager::RemoveAndDeleteFile( Workout *pToDelete ) -{ - vector::iterator iter = find( m_vpAllWorkouts.begin(), m_vpAllWorkouts.end(), pToDelete ); - if( iter == m_vpAllWorkouts.end() ) - return false; - if( !FILEMAN->Remove( pToDelete->m_sFile ) ) + if( !FILEMAN->Remove( pCourse->m_sPath ) ) return false; FlushDirCache(); + PROFILEMAN->LoadMachineProfile(); return true; } static LocalizedString YOU_MUST_SUPPLY_NAME ( "WorkoutManager", "You must supply a name for your workout." ); static LocalizedString EDIT_NAME_CONFLICTS ( "WorkoutManager", "The name you chose conflicts with another workout. Please use a different name." ); static LocalizedString EDIT_NAME_CANNOT_CONTAIN ( "WorkoutManager", "The workout name cannot contain any of the following characters: %s" ); -bool WorkoutManager::ValidateWorkoutName( const RString &sAnswer, RString &sErrorOut ) +bool EditCourseUtil::ValidateEditCourseName( const RString &sAnswer, RString &sErrorOut ) { if( sAnswer.empty() ) { @@ -127,15 +70,15 @@ bool WorkoutManager::ValidateWorkoutName( const RString &sAnswer, RString &sErro return false; } - Workout *pWorkout = WORKOUTMAN->m_pCurWorkout; - - // Steps name must be unique for this song. - FOREACH_CONST( Workout*, WORKOUTMAN->m_vpAllWorkouts, p ) + // Check for name conflicts + vector vpCourses; + EditCourseUtil::GetAllEditCourses( vpCourses ); + FOREACH_CONST( Course*, vpCourses, p ) { - if( pWorkout == *p ) + if( GAMESTATE->m_pCurCourse == *p ) continue; // don't comepare name against ourself - if( (*p)->m_sName == sAnswer ) + if( (*p)->GetDisplayFullTitle() == sAnswer ) { sErrorOut = EDIT_NAME_CONFLICTS; return false; @@ -145,73 +88,76 @@ bool WorkoutManager::ValidateWorkoutName( const RString &sAnswer, RString &sErro return true; } -void WorkoutManager::GetWorkoutSongsForGenres( const vector &vsSongGenres, vector &vpSongsOut ) +void EditCourseUtil::UpdateAndSetTrail() { - SongCriteria soc; - soc.m_Selectable = SongCriteria::Selectable_Yes; - soc.m_bUseSongGenreAllowedList = true; - soc.m_vsSongGenreAllowedList = vsSongGenres; - SongUtil::FilterSongs( soc, SONGMAN->GetSongs(), vpSongsOut ); + StepsType st = GAMESTATE->m_pCurStyle->m_StepsType; + Trail *pTrail = GAMESTATE->m_pCurCourse->GetTrailForceRegenCache( st ); + ASSERT( pTrail ); + GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail ); } -static LocalizedString SONGS_ENABLED( "WorkoutManager", "%d/%d songs enabled" ); -static RString GetWorkoutSongsOverview() +void EditCourseUtil::PrepareForPlay() { - SongCriteria soc; + GAMESTATE->m_pCurSong.Set( NULL ); // CurSong will be set if we back out. Set it back to NULL so that ScreenStage won't show the last song. + GAMESTATE->m_PlayMode.Set( PLAY_MODE_ENDLESS ); + GAMESTATE->m_bSideIsJoined[0] = true; - Workout defaultWorkout; - WORKOUTMAN->LoadDefaults( defaultWorkout ); - soc.m_Selectable = SongCriteria::Selectable_Yes; - vector vpAllSongs; - WORKOUTMAN->GetWorkoutSongsForGenres( defaultWorkout.m_vsSongGenres, vpAllSongs ); - - vector vpSelectedSongs; - WORKOUTMAN->GetWorkoutSongsForGenres( WORKOUTMAN->m_pCurWorkout->m_vsSongGenres, vpSelectedSongs ); - - return ssprintf( SONGS_ENABLED.GetValue(), (int)vpSelectedSongs.size(), (int)vpAllSongs.size() ); + PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_GoalType = GoalType_Time; + Course *pCourse = GAMESTATE->m_pCurCourse; + PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_iGoalSeconds = pCourse->m_fGoalSeconds; } -static RString GetWorkoutSongTitleText() +void EditCourseUtil::GetAllEditCourses( vector &vpCoursesOut ) { - vector vs; - FOREACH_CONST( RString, WORKOUTMAN->m_pCurWorkout->m_vsSongGenres, s ) + vector vpCoursesTemp; + SONGMAN->GetAllCourses( vpCoursesTemp, false ); + FOREACH_CONST( Course*, vpCoursesTemp, c ) { - RString s2 = *s; - s2.Replace( " ", " " ); - vs.push_back( s2 ); + if( (*c)->GetLoadedFromProfileSlot() != ProfileSlot_Invalid ) + vpCoursesOut.push_back( *c ); + } +} - // show max N to avoid frame rate slowdown - if( vs.size() >= 40 ) +void EditCourseUtil::LoadDefaults( Course &out ) +{ + out = Course(); + + out.m_fGoalSeconds = 0; + + // pick a default name + // XXX: Make this localizable + for( int i=0; i<10000; i++ ) + { + out.m_sMainTitle = ssprintf("Workout %d", i+1); + bool bNameInUse = false; + + vector vpCourses; + EditCourseUtil::GetAllEditCourses( vpCourses ); + FOREACH_CONST( Course*, vpCourses, p ) + { + if( out.m_sMainTitle == (*p)->m_sMainTitle ) + { + bNameInUse = true; + break; + } + } + + if( !bNameInUse ) break; } - RString sReturn = join( ", ", vs ); - FontCharAliases::ReplaceMarkers( sReturn ); - return sReturn; + vector vpSongs; + SONGMAN->GetPreferredSortSongs( vpSongs ); + for( int i=0; i<(int)vpSongs.size() && i<6; i++ ) + { + CourseEntry ce; + ce.songID.FromSong( vpSongs[i] ); + ce.stepsCriteria.m_difficulty = Difficulty_Easy; + out.m_vEntries.push_back( ce ); + } } -// lua start -#include "LuaBinding.h" - -class LunaWorkoutManager: public Luna -{ -public: - static int GetCurrentWorkout( T* p, lua_State *L ) { if(p->m_pCurWorkout) p->m_pCurWorkout->PushSelf(L); else lua_pushnil(L); return 1; } - static int GetWorkoutSongsOverview( T* p, lua_State *L ) { lua_pushstring( L, ::GetWorkoutSongsOverview() ); return 1; } - static int GetWorkoutSongTitleText( T* p, lua_State *L ) { lua_pushstring( L, ::GetWorkoutSongTitleText() ); return 1; } - - LunaWorkoutManager() - { - ADD_METHOD( GetCurrentWorkout ); - ADD_METHOD( GetWorkoutSongsOverview ); - ADD_METHOD( GetWorkoutSongTitleText ); - } -}; - -LUA_REGISTER_CLASS( WorkoutManager ) -// lua end - /* * (c) 2003-2004 Chris Danford * All rights reserved. diff --git a/stepmania/src/WorkoutManager.h b/stepmania/src/WorkoutManager.h index 11622ef130..fc8a1947b4 100644 --- a/stepmania/src/WorkoutManager.h +++ b/stepmania/src/WorkoutManager.h @@ -1,41 +1,26 @@ #ifndef WorkoutManager_H #define WorkoutManager_H -struct lua_State; -class Song; -class Workout; class Course; -const int MAX_WORKOUT_NAME_LENGTH = 16; -const int MAX_WORKOUTS_PER_PROFILE = 32; - -class WorkoutManager +namespace EditCourseUtil { -public: - WorkoutManager(); - ~WorkoutManager(); + void UpdateAndSetTrail(); + void PrepareForPlay(); + void LoadDefaults( Course &out ); + bool RemoveAndDeleteFile( Course *pCourse ); + bool ValidateEditCourseName( const RString &sAnswer, RString &sErrorOut ); + void GetAllEditCourses( vector &vpCoursesOut ); + bool Save( Course *pCourse ); + bool RenameAndSave( Course *pCourse, RString sName ); - void LoadAllFromDisk(); + bool ValidateEditCourseNametName( const RString &sAnswer, RString &sErrorOut ); - void LoadDefaults( Workout &out ); - bool RenameAndSave( Workout *pToRename, RString sNewName ); - bool Save( Workout *pToRename ); - bool RemoveAndDeleteFile( Workout *pToDelete ); - - static bool ValidateWorkoutName( const RString &sAnswer, RString &sErrorOut ); - - void GetWorkoutSongsForGenres( const vector &vsSongGenres, vector &vpSongsOut ); - - vector m_vpAllWorkouts; - Workout *m_pCurWorkout; - - Course *m_pTempCourse; - - // Lua - void PushSelf( lua_State *L ); + extern int MAX_NAME_LENGTH; + extern int MAX_PER_PROFILE; + extern bool s_bNewCourseNeedsName; // if true, we are working with a Course that has never been named }; -extern WorkoutManager* WORKOUTMAN; // global and accessable from anywhere in our program #endif