From 58603a48f2df31b0f1b9941b9643859e3fafb5ab Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Fri, 22 Sep 2006 11:36:12 +0000 Subject: [PATCH] add Workout files --- stepmania/src/ScreenOptionsEditPlaylist.cpp | 208 ++++++++++++ stepmania/src/ScreenOptionsEditPlaylist.h | 56 ++++ stepmania/src/ScreenOptionsEditWorkout.cpp | 219 +++++++++++++ stepmania/src/ScreenOptionsEditWorkout.h | 52 +++ stepmania/src/ScreenOptionsManageWorkouts.cpp | 302 ++++++++++++++++++ stepmania/src/ScreenOptionsManageWorkouts.h | 56 ++++ stepmania/src/ScreenOptionsReviewWorkout.cpp | 223 +++++++++++++ stepmania/src/ScreenOptionsReviewWorkout.h | 54 ++++ stepmania/src/StepMania-net2003.vcproj | 44 ++- stepmania/src/Workout.cpp | 270 ++++++++++++++++ stepmania/src/Workout.h | 90 ++++++ stepmania/src/WorkoutGraph.cpp | 163 ++++++++++ stepmania/src/WorkoutGraph.h | 60 ++++ stepmania/src/WorkoutManager.cpp | 220 +++++++++++++ stepmania/src/WorkoutManager.h | 65 ++++ 15 files changed, 2081 insertions(+), 1 deletion(-) create mode 100644 stepmania/src/ScreenOptionsEditPlaylist.cpp create mode 100644 stepmania/src/ScreenOptionsEditPlaylist.h create mode 100644 stepmania/src/ScreenOptionsEditWorkout.cpp create mode 100644 stepmania/src/ScreenOptionsEditWorkout.h create mode 100644 stepmania/src/ScreenOptionsManageWorkouts.cpp create mode 100644 stepmania/src/ScreenOptionsManageWorkouts.h create mode 100644 stepmania/src/ScreenOptionsReviewWorkout.cpp create mode 100644 stepmania/src/ScreenOptionsReviewWorkout.h create mode 100644 stepmania/src/Workout.cpp create mode 100644 stepmania/src/Workout.h create mode 100644 stepmania/src/WorkoutGraph.cpp create mode 100644 stepmania/src/WorkoutGraph.h create mode 100644 stepmania/src/WorkoutManager.cpp create mode 100644 stepmania/src/WorkoutManager.h diff --git a/stepmania/src/ScreenOptionsEditPlaylist.cpp b/stepmania/src/ScreenOptionsEditPlaylist.cpp new file mode 100644 index 0000000000..ca9c8df0fc --- /dev/null +++ b/stepmania/src/ScreenOptionsEditPlaylist.cpp @@ -0,0 +1,208 @@ +#include "global.h" + +#include "ScreenOptionsEditPlaylist.h" +#include "ScreenMiniMenu.h" +#include "SongUtil.h" +#include "SongManager.h" +#include "OptionRowHandler.h" +#include "song.h" +#include "Workout.h" +#include "GameState.h" +#include "ScreenPrompt.h" +#include "LocalizedString.h" +#include "WorkoutManager.h" +#include "song.h" + +static const MenuRowDef g_MenuSong = MenuRowDef( -1, "Song", true, EditMode_Practice, false, true, 0, "Off", "On" ); + +REGISTER_SCREEN_CLASS( ScreenOptionsEditPlaylist ); + +void ScreenOptionsEditPlaylist::Init() +{ + ScreenOptions::Init(); + SongUtil::GetAllSongGenres( m_vsSongGenres ); +} + +void ScreenOptionsEditPlaylist::BeginScreen() +{ + vector vHands; + + FOREACH_CONST( RString, m_vsSongGenres, s ) + { + 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; + pHand->m_Def.m_bExportOnChange = true; + } + + ScreenOptions::InitMenu( vHands ); + + ScreenOptions::BeginScreen(); + + this->AfterChangeRow( PLAYER_1 ); +} + +ScreenOptionsEditPlaylist::~ScreenOptionsEditPlaylist() +{ + +} + +void ScreenOptionsEditPlaylist::ImportOptions( int iRow, const vector &vpns ) +{ + OptionRow &row = *m_pRows[iRow]; + if( row.GetRowType() == OptionRow::RowType_Exit ) + return; + + RString sSongGenre = m_vsSongGenres[iRow]; + + bool bEnabled = false; + FOREACH_CONST( RString, WORKOUTMAN->m_pCurWorkout->m_vsSongGenres, s ) + { + if( *s == sSongGenre ) + { + bEnabled = true; + break; + } + } + + row.SetOneSharedSelection( bEnabled ? 1:0 ); +} + +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 ) + { + WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.push_back( sSongGenre ); + sort( WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.begin(), WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.end() ); + } + else if( !bEnabled && bAlreadyExists ) + { + WORKOUTMAN->m_pCurWorkout->m_vsSongGenres.erase( iter ); + } +} + +void ScreenOptionsEditPlaylist::GoToNextScreen() +{ +} + +void ScreenOptionsEditPlaylist::GoToPrevScreen() +{ +} + +void ScreenOptionsEditPlaylist::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_ExportOptions ) + { + //g_Workout.m_vpSongs.clear(); + } + + ScreenOptions::HandleScreenMessage( SM ); +} + +static RString g_sSongGenre; + +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" ); +} + +void ScreenOptionsEditPlaylist::AfterChangeValueInRow( int iRow, PlayerNumber pn ) +{ + ScreenOptions::AfterChangeValueInRow( iRow, pn ); + + MESSAGEMAN->Broadcast( "WorkoutChanged" ); +} + +const int MIN_ENABLED_SONGS = 10; + +static LocalizedString MUST_ENABLE_AT_LEAST("ScreenOptionsEditPlaylist","You must enable at least %d songs."); +void ScreenOptionsEditPlaylist::ProcessMenuStart( const InputEventPlus &input ) +{ + if( IsTransitioning() ) + return; + + int iRow = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber]; + + vector vpSongGenreSongs; + WORKOUTMAN->GetWorkoutSongsForGenres( WORKOUTMAN->m_pCurWorkout->m_vsSongGenres, vpSongGenreSongs ); + + if( m_pRows[iRow]->GetRowType() == OptionRow::RowType_Exit && vpSongGenreSongs.size() < unsigned(MIN_ENABLED_SONGS) ) + { + ScreenPrompt::Prompt( SM_None, ssprintf(MUST_ENABLE_AT_LEAST.GetValue(),MIN_ENABLED_SONGS) ); + return; + } + + ScreenOptions::ProcessMenuStart( input ); +} + +RString GetEditPlaylistSelectedSongGenreText( int iColumnIndex ) +{ + vector vsSongGenres; + vsSongGenres.push_back( g_sSongGenre ); + vector vpSongGenreSongs; + WORKOUTMAN->GetWorkoutSongsForGenres( vsSongGenres, vpSongGenreSongs ); + + const int iSongPerCoumn = 20; + 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 "LuaFunctions.h" +LuaFunction( GetEditPlaylistSelectedSongGenre, g_sSongGenre ); +LuaFunction( GetEditPlaylistSelectedSongGenreText, GetEditPlaylistSelectedSongGenreText(IArg(1)) ); + + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenOptionsEditPlaylist.h b/stepmania/src/ScreenOptionsEditPlaylist.h new file mode 100644 index 0000000000..4c552d2b5d --- /dev/null +++ b/stepmania/src/ScreenOptionsEditPlaylist.h @@ -0,0 +1,56 @@ +#ifndef ScreenOptionsEditPlaylist_H +#define ScreenOptionsEditPlaylist_H + +#include "ScreenOptions.h" +class Song; + +class ScreenOptionsEditPlaylist : public ScreenOptions +{ +public: + virtual ~ScreenOptionsEditPlaylist(); + + virtual void Init(); + virtual void BeginScreen(); + +protected: +private: + virtual void ImportOptions( int row, const vector &vpns ); + virtual void ExportOptions( int row, const vector &vpns ); + + virtual void GoToNextScreen(); + virtual void GoToPrevScreen(); + + virtual void HandleScreenMessage( const ScreenMessage SM ); + virtual void AfterChangeRow( PlayerNumber pn ); + virtual void AfterChangeValueInRow( int iRow, PlayerNumber pn ); + virtual void ProcessMenuStart( const InputEventPlus &input ); + + vector m_vsSongGenres; +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenOptionsEditWorkout.cpp b/stepmania/src/ScreenOptionsEditWorkout.cpp new file mode 100644 index 0000000000..09fd83f95e --- /dev/null +++ b/stepmania/src/ScreenOptionsEditWorkout.cpp @@ -0,0 +1,219 @@ +#include "global.h" + +#include "ScreenOptionsEditWorkout.h" +#include "ScreenManager.h" +#include "RageUtil.h" +#include "GameState.h" +#include "OptionRowHandler.h" +#include "ProfileManager.h" +#include "ScreenMiniMenu.h" +#include "Workout.h" +#include "LocalizedString.h" +#include "SongManager.h" +#include "SongUtil.h" +#include "WorkoutManager.h" + +enum WorkoutDetailsRow +{ + WorkoutDetailsRow_WorkoutProgram, + WorkoutDetailsRow_Minutes, + WorkoutDetailsRow_Meter, + //WorkoutDetailsRow_SongGenre, + WorkoutDetailsRow_WorkoutStepsType, + NUM_WorkoutDetailsRow +}; + +const MenuRowDef g_MenuRows[] = +{ + MenuRowDef( -1, "Workout Program", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Minutes", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Difficulty", true, EditMode_Practice, true, false, 0, NULL ), + //MenuRowDef( -1, "Song Genre", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Workout Steps Type", true, EditMode_Practice, true, false, 0, NULL ), +}; + +REGISTER_SCREEN_CLASS( ScreenOptionsEditWorkout ); + +void ScreenOptionsEditWorkout::Init() +{ + ScreenOptions::Init(); +} + +static RString MakeMinutesString( int iMeter ) +{ + return ssprintf( "%d", iMeter ); +} +static RString MakeMeterString( int iMeter ) +{ + return ssprintf( "%d", iMeter ); +} +void ScreenOptionsEditWorkout::BeginScreen() +{ + vector vHands; + FOREACH_ENUM2( WorkoutDetailsRow, rowIndex ) + { + 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_WorkoutProgram: + FOREACH_ENUM2( WorkoutProgram, i ) + pHand->m_Def.m_vsChoices.push_back( WorkoutProgramToLocalizedString(i) ); + break; + case WorkoutDetailsRow_Minutes: + 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; + case WorkoutDetailsRow_Meter: + for( int i=MIN_METER; i<=MAX_METER; i++ ) + pHand->m_Def.m_vsChoices.push_back( MakeMeterString(i) ); + break; + //case WorkoutDetailsRow_SongGenre: + // { + // vector vs; + // SongUtil::GetAllSongGenres( vs ); + // FOREACH_CONST( RString, vs, s ) + // pHand->m_Def.m_vsChoices.push_back( *s ); + // } + // break; + case WorkoutDetailsRow_WorkoutStepsType: + FOREACH_ENUM2( WorkoutStepsType, i ) + pHand->m_Def.m_vsChoices.push_back( WorkoutStepsTypeToLocalizedString(i) ); + break; + } + + pHand->m_Def.m_bExportOnChange = true; + vHands.push_back( pHand ); + } + + ScreenOptions::InitMenu( vHands ); + + ScreenOptions::BeginScreen(); +} + +ScreenOptionsEditWorkout::~ScreenOptionsEditWorkout() +{ + +} + +void ScreenOptionsEditWorkout::ImportOptions( int iRow, const vector &vpns ) +{ + OptionRow &row = *m_pRows[iRow]; + + switch( iRow ) + { + case WorkoutDetailsRow_WorkoutProgram: + row.SetOneSharedSelectionIfPresent( WorkoutProgramToLocalizedString(WORKOUTMAN->m_pCurWorkout->m_WorkoutProgram) ); + break; + case WorkoutDetailsRow_Minutes: + row.SetOneSharedSelectionIfPresent( MakeMinutesString(WORKOUTMAN->m_pCurWorkout->m_iMinutes) ); + break; + case WorkoutDetailsRow_Meter: + row.SetOneSharedSelectionIfPresent( MakeMeterString(WORKOUTMAN->m_pCurWorkout->m_iAverageMeter) ); + break; + //case WorkoutDetailsRow_SongGenre: + // row.SetOneSharedSelectionIfPresent( g_Workout.m_sSongGenre ); + // break; + case WorkoutDetailsRow_WorkoutStepsType: + row.SetOneSharedSelection( WORKOUTMAN->m_pCurWorkout->m_WorkoutStepsType ); + break; + } +} + +void ScreenOptionsEditWorkout::ExportOptions( int iRow, const vector &vpns ) +{ + FOREACH_ENUM2( WorkoutDetailsRow, i ) + { + iRow = i; + OptionRow &row = *m_pRows[iRow]; + int iIndex = row.GetOneSharedSelection( true ); + RString sValue; + if( iIndex >= 0 ) + sValue = row.GetRowDef().m_vsChoices[ iIndex ]; + + switch( iRow ) + { + DEFAULT_FAIL(iRow); + case WorkoutDetailsRow_WorkoutProgram: + WORKOUTMAN->m_pCurWorkout->m_WorkoutProgram = (WorkoutProgram)iIndex; + break; + case WorkoutDetailsRow_Minutes: + sscanf( sValue, "%d", &WORKOUTMAN->m_pCurWorkout->m_iMinutes ); + break; + case WorkoutDetailsRow_Meter: + WORKOUTMAN->m_pCurWorkout->m_iAverageMeter = iIndex + MIN_METER; + break; + //case WorkoutDetailsRow_SongGenre: + // g_Workout.m_sSongGenre = sValue; + // break; + case WorkoutDetailsRow_WorkoutStepsType: + WORKOUTMAN->m_pCurWorkout->m_WorkoutStepsType = (WorkoutStepsType)iIndex; + break; + } + } + + MESSAGEMAN->Broadcast( "WorkoutChanged" ); +} + +void ScreenOptionsEditWorkout::GoToNextScreen() +{ +} + +void ScreenOptionsEditWorkout::GoToPrevScreen() +{ +} + +void ScreenOptionsEditWorkout::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_GoToNextScreen ) + { + } + else if( SM == SM_GoToPrevScreen ) + { + } + + ScreenOptions::HandleScreenMessage( SM ); +} + +void ScreenOptionsEditWorkout::AfterChangeValueInRow( int iRow, PlayerNumber pn ) +{ + ScreenOptions::AfterChangeValueInRow( iRow, pn ); +} + +void ScreenOptionsEditWorkout::ProcessMenuStart( const InputEventPlus &input ) +{ + ScreenOptions::ProcessMenuStart( input ); +} + + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenOptionsEditWorkout.h b/stepmania/src/ScreenOptionsEditWorkout.h new file mode 100644 index 0000000000..2206aebd37 --- /dev/null +++ b/stepmania/src/ScreenOptionsEditWorkout.h @@ -0,0 +1,52 @@ +#ifndef ScreenOptionsEditWorkout_H +#define ScreenOptionsEditWorkout_H + +#include "ScreenOptions.h" + +class ScreenOptionsEditWorkout : public ScreenOptions +{ +public: + virtual ~ScreenOptionsEditWorkout(); + + virtual void Init(); + virtual void BeginScreen(); + +protected: +private: + virtual void ImportOptions( int row, const vector &vpns ); + virtual void ExportOptions( int row, const vector &vpns ); + + virtual void GoToNextScreen(); + virtual void GoToPrevScreen(); + + virtual void HandleScreenMessage( const ScreenMessage SM ); + virtual void AfterChangeValueInRow( int iRow, PlayerNumber pn ); + virtual void ProcessMenuStart( const InputEventPlus &input ); +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenOptionsManageWorkouts.cpp b/stepmania/src/ScreenOptionsManageWorkouts.cpp new file mode 100644 index 0000000000..1961b7772d --- /dev/null +++ b/stepmania/src/ScreenOptionsManageWorkouts.cpp @@ -0,0 +1,302 @@ +#include "global.h" +#include "ScreenOptionsManageWorkouts.h" +#include "ScreenManager.h" +#include "ScreenMiniMenu.h" +#include "OptionRowHandler.h" +#include "WorkoutManager.h" +#include "Workout.h" +#include "LocalizedString.h" +#include "GameState.h" +#include "ScreenTextEntry.h" +#include "ScreenPrompt.h" +#include "StatsManager.h" + +AutoScreenMessage( SM_BackFromRename ) +AutoScreenMessage( SM_BackFromDelete ) +AutoScreenMessage( SM_BackFromContextMenu ) + +enum ManageWorkoutsAction +{ + ManageWorkoutsAction_Choose, + ManageWorkoutsAction_Rename, + ManageWorkoutsAction_Delete, + NUM_ManageWorkoutsAction +}; +static const char *ManageWorkoutsActionNames[] = { + "Choose", + "Rename", + "Delete", +}; +XToString( ManageWorkoutsAction, NUM_ManageWorkoutsAction ); +#define FOREACH_ManageWorkoutsAction( i ) FOREACH_ENUM( ManageWorkoutsAction, NUM_ManageWorkoutsAction, i ) + +static MenuDef g_TempMenu( + "ScreenMiniMenuContext" +); + + + +REGISTER_SCREEN_CLASS( ScreenOptionsManageWorkouts ); + +void ScreenOptionsManageWorkouts::Init() +{ + ScreenOptions::Init(); + + CREATE_NEW_SCREEN.Load( m_sName, "CreateNewScreen" ); +} + +void ScreenOptionsManageWorkouts::BeginScreen() +{ + STATSMAN->Reset(); + + WORKOUTMAN->LoadAllFromDisk(); + + vector vHands; + + int iIndex = 0; + + { + vHands.push_back( OptionRowHandlerUtil::MakeNull() ); + OptionRowDefinition &def = vHands.back()->m_Def; + def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; + def.m_bOneChoiceForAllPlayers = true; + def.m_sName = "Create New Workout"; + def.m_sExplanationName = "Create New Workout"; + def.m_vsChoices.clear(); + def.m_vsChoices.push_back( "" ); + iIndex++; + } + + m_vpWorkouts = WORKOUTMAN->m_vpAllWorkouts; + + FOREACH_CONST( Workout*, m_vpWorkouts, p ) + { + vHands.push_back( OptionRowHandlerUtil::MakeNull() ); + OptionRowDefinition &def = vHands.back()->m_Def; + + def.m_sName = (*p)->m_sName; + def.m_bAllowThemeTitle = false; // not themable + def.m_sExplanationName = "Select Workout"; + def.m_vsChoices.clear(); + def.m_vsChoices.push_back( "" ); + def.m_bAllowThemeItems = false; // already themed + iIndex++; + } + + ScreenOptions::InitMenu( vHands ); + + 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() ) + { + int iIndex = iter - m_vpWorkouts.begin(); + this->MoveRowAbsolute( PLAYER_1, 1 + iIndex ); + } + } + + 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."); +void ScreenOptionsManageWorkouts::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_GoToNextScreen ) + { + int iCurRow = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber]; + + if( iCurRow == 0 ) // "create new" + { + WORKOUTMAN->m_pCurWorkout = new Workout; + WORKOUTMAN->LoadDefaults( *WORKOUTMAN->m_pCurWorkout ); + WORKOUTMAN->m_vpAllWorkouts.push_back( WORKOUTMAN->m_pCurWorkout ); + + SCREENMAN->SetNewScreen( CREATE_NEW_SCREEN ); + return; // don't call base + } + else if( m_pRows[iCurRow]->GetRowType() == OptionRow::RowType_Exit ) + { + this->HandleScreenMessage( SM_GoToPrevScreen ); + return; // don't call base + } + else // a Workout + { + // do base behavior + } + } + else if( SM == SM_BackFromRename ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + { + ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this + + Workout *pWorkout = WORKOUTMAN->m_pCurWorkout; + if( !WORKOUTMAN->RenameAndSave(pWorkout, ScreenTextEntry::s_sLastAnswer) ) + { + ScreenPrompt::Prompt( SM_None, ERROR_RENAMING_WORKOUT ); + return; + } + + SCREENMAN->SetNewScreen( this->m_sName ); // reload + } + } + else if( SM == SM_BackFromDelete ) + { + if( ScreenPrompt::s_LastAnswer == ANSWER_YES ) + { + Workout *pWorkout = GetWorkoutWithFocus(); + if( !WORKOUTMAN->RemoveAndDeleteFile( pWorkout ) ) + { + ScreenPrompt::Prompt( SM_None, ssprintf(ERROR_DELETING_WORKOUT_FILE.GetValue(),pWorkout->m_sFile.c_str()) ); + return; + } + + WORKOUTMAN->m_pCurWorkout = NULL; + SCREENMAN->SetNewScreen( this->m_sName ); // reload + } + } + else if( SM == SM_BackFromContextMenu ) + { + if( !ScreenMiniMenu::s_bCancelled ) + { + switch( ScreenMiniMenu::s_iLastRowCode ) + { + case ManageWorkoutsAction_Choose: + { + Workout *p = GetWorkoutWithFocus(); + WORKOUTMAN->m_pCurWorkout = p; + + ScreenOptions::BeginFadingOut(); + } + break; + case ManageWorkoutsAction_Rename: + { + ScreenTextEntry::TextEntry( + SM_BackFromRename, + ENTER_NAME_FOR_WORKOUT, + WORKOUTMAN->m_pCurWorkout->m_sName, + MAX_WORKOUT_NAME_LENGTH, + WorkoutManager::ValidateWorkoutName ); + } + 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 ); + } + break; + } + } + } + else if( SM == SM_LoseFocus ) + { + this->PlayCommand( "ScreenLoseFocus" ); + } + else if( SM == SM_GainFocus ) + { + this->PlayCommand( "ScreenGainFocus" ); + } + + ScreenOptions::HandleScreenMessage( 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." ); +void ScreenOptionsManageWorkouts::ProcessMenuStart( const InputEventPlus &input ) +{ + if( IsTransitioning() ) + return; + + int iCurRow = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber]; + + if( iCurRow == 0 ) // "create new" + { + if( WORKOUTMAN->m_vpAllWorkouts.size() >= size_t(MAX_WORKOUTS_PER_PROFILE) ) + { + RString s = ssprintf( YOU_HAVE_MAX_WORKOUTS.GetValue()+"\n\n"+YOU_MUST_DELETE.GetValue(), MAX_WORKOUTS_PER_PROFILE ); + ScreenPrompt::Prompt( SM_None, s ); + return; + } + SCREENMAN->PlayStartSound(); + this->BeginFadingOut(); + } + else if( m_pRows[iCurRow]->GetRowType() == OptionRow::RowType_Exit ) + { + SCREENMAN->PlayStartSound(); + this->BeginFadingOut(); + } + else // a Steps + { + g_TempMenu.rows.clear(); + FOREACH_ManageWorkoutsAction( i ) + { + MenuRowDef mrd( i, ManageWorkoutsActionToString(i), true, EditMode_Home, true, true, 0, "" ); + g_TempMenu.rows.push_back( mrd ); + } + + int iWidth, iX, iY; + this->GetWidthXY( PLAYER_1, iCurRow, 0, iWidth, iX, iY ); + ScreenMiniMenu::MiniMenu( &g_TempMenu, SM_BackFromContextMenu, SM_BackFromContextMenu, (float)iX, (float)iY ); + } +} + +void ScreenOptionsManageWorkouts::ImportOptions( int iRow, const vector &vpns ) +{ + +} + +void ScreenOptionsManageWorkouts::ExportOptions( int iRow, const vector &vpns ) +{ + +} + +Workout *ScreenOptionsManageWorkouts::GetWorkoutWithFocus() const +{ + int iCurRow = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber]; + if( iCurRow == 0 ) + return NULL; + else if( m_pRows[iCurRow]->GetRowType() == OptionRow::RowType_Exit ) + return NULL; + + // a Steps + int iStepsIndex = iCurRow - 1; + return m_vpWorkouts[iStepsIndex]; +} + +/* + * (c) 2002-2005 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenOptionsManageWorkouts.h b/stepmania/src/ScreenOptionsManageWorkouts.h new file mode 100644 index 0000000000..ecefeafae9 --- /dev/null +++ b/stepmania/src/ScreenOptionsManageWorkouts.h @@ -0,0 +1,56 @@ +#ifndef ScreenOptionsManageWorkouts_H +#define ScreenOptionsManageWorkouts_H + +#include "ScreenOptions.h" +#include "GameConstantsAndTypes.h" + +class Workout; + +class ScreenOptionsManageWorkouts : public ScreenOptions +{ +public: + void Init(); + virtual void BeginScreen(); + + virtual void HandleScreenMessage( const ScreenMessage SM ); + +protected: + virtual void ImportOptions( int iRow, const vector &vpns ); + virtual void ExportOptions( int iRow, const vector &vpns ); + + virtual void AfterChangeRow( PlayerNumber pn ); + virtual void ProcessMenuStart( const InputEventPlus &input ); + + Workout *GetWorkoutWithFocus() const; + + vector m_vpWorkouts; + + ThemeMetric CREATE_NEW_SCREEN; +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenOptionsReviewWorkout.cpp b/stepmania/src/ScreenOptionsReviewWorkout.cpp new file mode 100644 index 0000000000..7349e205ba --- /dev/null +++ b/stepmania/src/ScreenOptionsReviewWorkout.cpp @@ -0,0 +1,223 @@ +#include "global.h" + +#include "ScreenOptionsReviewWorkout.h" +#include "ScreenManager.h" +#include "RageUtil.h" +#include "GameState.h" +#include "OptionRowHandler.h" +#include "ProfileManager.h" +#include "ScreenMiniMenu.h" +#include "Workout.h" +#include "LocalizedString.h" +#include "SongManager.h" +#include "SongUtil.h" +#include "ScreenTextEntry.h" +#include "WorkoutManager.h" +#include "GameManager.h" +#include "Profile.h" +#include "ScreenPrompt.h" +#include "PlayerState.h" + +enum ReviewWorkoutRow +{ + ReviewWorkoutRow_Play, + ReviewWorkoutRow_EditWorkout, + ReviewWorkoutRow_EditPlaylist, + 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 ), +}; + +REGISTER_SCREEN_CLASS( ScreenOptionsReviewWorkout ); + +AutoScreenMessage( SM_BackFromEnterName ) + +void ScreenOptionsReviewWorkout::Init() +{ + ScreenOptions::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"); +} + +void ScreenOptionsReviewWorkout::BeginScreen() +{ + vector vHands; + FOREACH_ENUM2( ReviewWorkoutRow, rowIndex ) + { + const MenuRowDef &mr = g_MenuRows[rowIndex]; + OptionRowHandler *pHand = OptionRowHandlerUtil::MakeSimple( mr ); + vHands.push_back( pHand ); + } + + ScreenOptions::InitMenu( vHands ); + + ScreenOptions::BeginScreen(); +} + +ScreenOptionsReviewWorkout::~ScreenOptionsReviewWorkout() +{ + +} + +void ScreenOptionsReviewWorkout::ImportOptions( int iRow, const vector &vpns ) +{ + //OptionRow &row = *m_pRows[iRow]; +} + +void ScreenOptionsReviewWorkout::ExportOptions( int iRow, const vector &vpns ) +{ + OptionRow &row = *m_pRows[iRow]; + int iIndex = row.GetOneSharedSelection( true ); + RString sValue; + if( iIndex >= 0 ) + sValue = row.GetRowDef().m_vsChoices[ iIndex ]; +} + +static LocalizedString ERROR_SAVING_WORKOUT ( "ScreenOptionsReviewWorkout", "Error saving workout." ); +static LocalizedString WORKOUT_SAVED ( "ScreenOptionsReviewWorkout", "Workout saved successfully." ); +void ScreenOptionsReviewWorkout::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_GoToNextScreen ) + { + int iRow = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber]; + switch( iRow ) + { + case ReviewWorkoutRow_Play: + { + Workout *pWorkout = WORKOUTMAN->m_pCurWorkout; + pWorkout->GenerateCourse( *WORKOUTMAN->m_pTempCourse ); + GAMESTATE->m_pCurCourse.Set( WORKOUTMAN->m_pTempCourse ); + GAMESTATE->m_pCurTrail[PLAYER_1].Set( GAMESTATE->m_pCurCourse->GetTrail(STEPS_TYPE_DANCE_SINGLE) ); + switch( pWorkout->m_WorkoutStepsType ) + { + DEFAULT_FAIL(pWorkout->m_WorkoutStepsType); + case WorkoutStepsType_NormalSteps: + PO_GROUP_ASSIGN_N( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_bTransforms, PlayerOptions::TRANSFORM_LITTLE, false ); + PO_GROUP_ASSIGN_N( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_bTransforms, PlayerOptions::TRANSFORM_NOHANDS, false ); + break; + case WorkoutStepsType_WorkoutSteps: + PO_GROUP_ASSIGN_N( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_bTransforms, PlayerOptions::TRANSFORM_LITTLE, true ); + PO_GROUP_ASSIGN_N( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions, ModsLevel_Stage, m_bTransforms, PlayerOptions::TRANSFORM_NOHANDS, true ); + break; + } + + GAMESTATE->m_PlayMode.Set( PLAY_MODE_ENDLESS ); + GAMESTATE->m_bSideIsJoined[0] = true; + GAMESTATE->m_pCurStyle.Set( GAMEMAN->GameAndStringToStyle(GAMESTATE->m_pCurGame,"single") ); + + PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_GoalType = GoalType_Time; + PROFILEMAN->GetProfile(ProfileSlot_Player1)->m_iGoalSeconds = pWorkout->m_iMinutes * 60; + SCREENMAN->SetNewScreen( PLAY_SCREEN ); + } + return; // handled + case ReviewWorkoutRow_EditWorkout: + SCREENMAN->SetNewScreen( EDIT_WORKOUT_SCREEN ); + return; // handled + case ReviewWorkoutRow_EditPlaylist: + SCREENMAN->SetNewScreen( EDIT_PLAYLIST_SCREEN ); + return; // handled + } + } + else if( SM == SM_BackFromEnterName ) + { + if( !ScreenTextEntry::s_bCancelledLast ) + { + ASSERT( ScreenTextEntry::s_sLastAnswer != "" ); // validate should have assured this + if( WORKOUTMAN->RenameAndSave( WORKOUTMAN->m_pCurWorkout, ScreenTextEntry::s_sLastAnswer ) ) + { + m_soundSave.Play(); + SCREENMAN->SystemMessage( WORKOUT_SAVED ); + MESSAGEMAN->Broadcast( "WorkoutChanged" ); + } + } + } + + ScreenOptions::HandleScreenMessage( SM ); +} + +void ScreenOptionsReviewWorkout::AfterChangeValueInRow( int iRow, PlayerNumber pn ) +{ + ScreenOptions::AfterChangeValueInRow( iRow, pn ); +} + + +static LocalizedString ENTER_WORKOUT_NAME ( "ScreenOptionsReviewWorkout", "Enter a name for the workout." ); +void ScreenOptionsReviewWorkout::ProcessMenuStart( const InputEventPlus &input ) +{ + if( IsTransitioning() ) + return; + + int iRow = m_iCurrentRow[GAMESTATE->m_MasterPlayerNumber]; + switch( iRow ) + { + case ReviewWorkoutRow_Play: + case ReviewWorkoutRow_EditWorkout: + case ReviewWorkoutRow_EditPlaylist: + SCREENMAN->PlayStartSound(); + this->BeginFadingOut(); + return; // handled + case ReviewWorkoutRow_Save: + if( WORKOUTMAN->m_pCurWorkout->m_sName.empty() ) + { + ScreenTextEntry::TextEntry( + SM_BackFromEnterName, + ENTER_WORKOUT_NAME, + WORKOUTMAN->m_pCurWorkout->m_sName, + MAX_WORKOUT_NAME_LENGTH, + WorkoutManager::ValidateWorkoutName ); + } + else + { + if( WORKOUTMAN->Save( WORKOUTMAN->m_pCurWorkout ) ) + { + m_soundSave.Play(); + SCREENMAN->SystemMessage( WORKOUT_SAVED ); + MESSAGEMAN->Broadcast( "WorkoutChanged" ); + } + else + { + SCREENMAN->PlayInvalidSound(); + SCREENMAN->SystemMessage( ERROR_SAVING_WORKOUT ); + } + } + return; // handled + } + + ScreenOptions::ProcessMenuStart( input ); +} + + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/ScreenOptionsReviewWorkout.h b/stepmania/src/ScreenOptionsReviewWorkout.h new file mode 100644 index 0000000000..71004cb84c --- /dev/null +++ b/stepmania/src/ScreenOptionsReviewWorkout.h @@ -0,0 +1,54 @@ +#ifndef ScreenOptionsReviewWorkout_H +#define ScreenOptionsReviewWorkout_H + +#include "ScreenOptions.h" + +class ScreenOptionsReviewWorkout : public ScreenOptions +{ +public: + virtual ~ScreenOptionsReviewWorkout(); + + virtual void Init(); + virtual void BeginScreen(); + +protected: +private: + virtual void ImportOptions( int row, const vector &vpns ); + virtual void ExportOptions( int row, const vector &vpns ); + + virtual void HandleScreenMessage( const ScreenMessage SM ); + virtual void AfterChangeValueInRow( int iRow, PlayerNumber pn ); + virtual void ProcessMenuStart( const InputEventPlus &input ); + + RageSound m_soundSave; + ThemeMetric PLAY_SCREEN; + ThemeMetric EDIT_WORKOUT_SCREEN; + ThemeMetric EDIT_PLAYLIST_SCREEN; +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/StepMania-net2003.vcproj b/stepmania/src/StepMania-net2003.vcproj index 3bb47985e8..96bab8be8d 100644 --- a/stepmania/src/StepMania-net2003.vcproj +++ b/stepmania/src/StepMania-net2003.vcproj @@ -468,12 +468,24 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + + + + + @@ -492,6 +504,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + @@ -510,6 +528,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + @@ -1177,6 +1201,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + - + + + + + + + + = 4 ) + fMeter = SCALE( fMeter, (float)iMinMeter, (float)iMaxMeter, (float)iMaxMeter, (float)iMinMeter ); + iMeter = (int)roundf( fMeter ); + } + break; + case WorkoutProgram_Flat: + { + iMeter = iAverageMeter; + } + break; + } + + CLAMP( iMeter, MIN_METER, MAX_METER ); + return iMeter; +} + +void Workout::GetEstimatedMeters( int iNumSongs, vector &viMetersOut ) +{ + viMetersOut.clear(); + + for( int i=0; i viMeter; + GetEstimatedMeters( iNumCourseEntries, viMeter ); + + for( int i=0; im_sName == "SongGenre" ) + m_vsSongGenres.push_back( songGenre->m_sValue ); + } + } + return true; +} + +bool Workout::SaveToFile( RString sFile ) +{ + m_sFile = sFile; + + XNode xml; + xml.m_sName = "Workout"; + xml.AppendChild( "Name", m_sName ); + RString s; + xml.AppendChild( "WorkoutProgram", WorkoutProgramToString(m_WorkoutProgram) ); + xml.AppendChild( "Minutes", m_iMinutes ); + xml.AppendChild( "AverageMeter", m_iAverageMeter ); + xml.AppendChild( "WorkoutStepsType", WorkoutStepsTypeToString(m_WorkoutStepsType) ); + + XNode *songGenres = xml.AppendChild("SongGenres"); + FOREACH_CONST( RString, m_vsSongGenres, s ) + { + songGenres->AppendChild( "SongGenre", *s ); + } + + DISP_OPT opts; + return xml.SaveToFile( sFile, opts ); +} + +// lua start +#include "LuaBinding.h" + +class LunaWorkout: public Luna +{ +public: + LunaWorkout() { LUA->Register( Register ); } + + static int GetName( T* p, lua_State *L ) { lua_pushstring(L, p->m_sName ); return 1; } + static int GetMinutes( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iMinutes ); return 1; } + static int GetEstimatedNumSongs( T* p, lua_State *L ) { lua_pushnumber(L, p->GetEstimatedNumSongs() ); return 1; } + static int GetWorkoutStepsType( T* p, lua_State *L ) { lua_pushnumber(L, p->m_WorkoutStepsType ); return 1; } + + static void Register(lua_State *L) + { + ADD_METHOD( GetName ); + ADD_METHOD( GetMinutes ); + ADD_METHOD( GetEstimatedNumSongs ); + ADD_METHOD( GetWorkoutStepsType ); + + Luna::Register( L ); + } +}; + +LUA_REGISTER_CLASS( Workout ) +// lua end + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/Workout.h b/stepmania/src/Workout.h new file mode 100644 index 0000000000..0111e230b2 --- /dev/null +++ b/stepmania/src/Workout.h @@ -0,0 +1,90 @@ +#ifndef Workout_H +#define Workout_H + +#include "SongUtil.h" + +enum WorkoutProgram +{ + WorkoutProgram_FatBurn, + WorkoutProgram_FitnessTest, + WorkoutProgram_Intermediate, + WorkoutProgram_Interval, + WorkoutProgram_Runner, + WorkoutProgram_Flat, + NUM_WorkoutProgram, + WorkoutProgram_INVALID +}; +const RString& WorkoutProgramToLocalizedString( WorkoutProgram i ); +const RString& WorkoutProgramToLocalizedString( WorkoutProgram i ); +WorkoutProgram StringToWorkoutProgram( const RString& str ); + +enum WorkoutStepsType +{ + WorkoutStepsType_NormalSteps, + WorkoutStepsType_WorkoutSteps, + NUM_WorkoutStepsType, + WorkoutStepsType_INVALID +}; +const RString& WorkoutStepsTypeToLocalizedString( WorkoutStepsType i ); +WorkoutStepsType StringToWorkoutStepsType( const RString& str ); + + +const int MIN_WORKOUT_MINUTES = 4; +const int MAX_WORKOUT_MINUTES = 90; + + +struct lua_State; +class Course; +class Song; +class Steps; + +class Workout +{ +public: + Workout(); + + RString m_sFile; + RString m_sName; + WorkoutProgram m_WorkoutProgram; + int m_iMinutes; + int m_iAverageMeter; + WorkoutStepsType m_WorkoutStepsType; + vector m_vsSongGenres; + + int GetEstimatedNumSongs() const; + static int GetEstimatedNumSongsFromSeconds( float fSeconds ); + void GetEstimatedMeters( int iNumSongs, vector &viMetersOut ); + void GenerateCourse( Course &out ); + bool LoadFromFile( RString sFile ); + bool SaveToFile( RString sFile ); + + // Lua + void PushSelf( lua_State *L ); +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/WorkoutGraph.cpp b/stepmania/src/WorkoutGraph.cpp new file mode 100644 index 0000000000..c3de0da429 --- /dev/null +++ b/stepmania/src/WorkoutGraph.cpp @@ -0,0 +1,163 @@ +#include "global.h" +#include "WorkoutGraph.h" +#include "RageUtil.h" +#include "ActorUtil.h" +#include "Sprite.h" +#include "Trail.h" +#include "Steps.h" +#include "GameState.h" +#include "ThemeManager.h" +#include "Workout.h" +#include "WorkoutManager.h" +#include "StatsManager.h" + +const int MAX_METERS_TO_SHOW = Workout::GetEstimatedNumSongsFromSeconds( 90 * 60 ); + +REGISTER_ACTOR_CLASS( WorkoutGraph ) + +WorkoutGraph::WorkoutGraph() +{ + m_iSongsChoppedOffAtBeginning = 0; +} + +WorkoutGraph::~WorkoutGraph() +{ + FOREACH( Sprite*, m_vpBars, a ) + delete *a; + m_vpBars.clear(); +} + +void WorkoutGraph::Load() +{ + m_sprEmpty.Load( THEME->GetPathG("WorkoutGraph","empty") ); + this->AddChild( &m_sprEmpty ); +} + +void WorkoutGraph::LoadFromNode( const RString& sDir, const XNode* pNode ) +{ + ActorFrame::LoadFromNode( sDir, pNode ); + + Load(); +} + +void WorkoutGraph::SetFromGameState() +{ + SetFromGameStateInternal( STATSMAN->m_CurStageStats.vpPlayedSongs.size() ); +} + +void WorkoutGraph::SetFromGameStateInternal( int iNumSongsToShowForCurrentStage ) +{ + FOREACH( Sprite*, m_vpBars, p ) + { + this->RemoveChild( *p ); + delete *p; + } + m_vpBars.clear(); + + int iTotalSongsPlayed = + STATSMAN->GetAccumPlayedStageStats().vpPlayedSongs.size() + + iNumSongsToShowForCurrentStage; + int iWorkoutEstimatedSongs = WORKOUTMAN->m_pCurWorkout->GetEstimatedNumSongs(); + int iNumSongsToShow = max( iTotalSongsPlayed, 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 ); + + int iBlocksWide = viMeters.size(); + int iBlocksHigh = MAX_METER; + + const float fMaxWidth = 300; + float fTotalWidth = SCALE( iBlocksWide, 1.0f, 10.0f, 50.0f, fMaxWidth ); + CLAMP( fTotalWidth, 50, fMaxWidth ); + + const float fMaxHeight = 130; + float fTotalHeight = SCALE( iBlocksHigh, 1.0f, 10.0f, 50.0f, fMaxHeight ); + CLAMP( fTotalHeight, 50, fMaxHeight ); + + float fBlockSize = min( fTotalWidth / iBlocksWide, fTotalHeight / iBlocksHigh ); + + m_sprEmpty.SetVertAlign( Actor::align_bottom ); + m_sprEmpty.SetCustomImageRect( RectF(0,0,(float)iBlocksWide,(float)iBlocksHigh) ); + m_sprEmpty.ZoomToWidth( iBlocksWide * fBlockSize ); + m_sprEmpty.ZoomToHeight( iBlocksHigh * fBlockSize ); + + FOREACH_CONST( int, viMeters, iter ) + { + int iIndex = iter - viMeters.begin(); + float fOffsetFromCenter = iIndex - (iBlocksWide-1)/2.0f; + Sprite *p = new Sprite; + p->Load( THEME->GetPathG("WorkoutGraph","bar") ); + p->SetVertAlign( Actor::align_bottom ); + p->ZoomToWidth( fBlockSize ); + int iMetersToCover = (MAX_METER - *iter); + p->SetCustomImageRect( RectF(0,(float)iMetersToCover/(float)iBlocksHigh,1,1) ); + p->ZoomToHeight( *iter * fBlockSize ); + p->SetX( fOffsetFromCenter * fBlockSize ); + m_vpBars.push_back( p ); + this->AddChild( p ); + } +} + +void WorkoutGraph::SetFromGameStateAndHighlightSong( int iSongIndex ) +{ + SetFromGameStateInternal( iSongIndex+1 ); + + FOREACH( Sprite*, m_vpBars, spr ) + (*spr)->StopEffect(); + + int iBarIndex = iSongIndex - m_iSongsChoppedOffAtBeginning; + + if( iBarIndex < (int)m_vpBars.size() ) + m_vpBars[iBarIndex]->SetEffectGlowBlink(0.3f); +} + + +// lua start +#include "LuaBinding.h" + +class LunaWorkoutGraph: public Luna +{ +public: + LunaWorkoutGraph() { LUA->Register( Register ); } + + static int SetFromGameState( T* p, lua_State *L ) { p->SetFromGameState(); return 0; } + static int SetFromGameStateAndHighlightSong( T* p, lua_State *L ) { p->SetFromGameStateAndHighlightSong(IArg(1)); return 0; } + + static void Register(lua_State *L) + { + ADD_METHOD( SetFromGameState ); + ADD_METHOD( SetFromGameStateAndHighlightSong ); + + Luna::Register( L ); + } +}; + +LUA_REGISTER_DERIVED_CLASS( WorkoutGraph, ActorFrame ) +// lua end + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/WorkoutGraph.h b/stepmania/src/WorkoutGraph.h new file mode 100644 index 0000000000..29a4ded915 --- /dev/null +++ b/stepmania/src/WorkoutGraph.h @@ -0,0 +1,60 @@ +/* WorkoutGraph - A bar graph of the Steps in a Trail. */ + +#ifndef WorkoutGraph_H +#define WorkoutGraph_H + +#include "ActorFrame.h" +#include "Sprite.h" +class Trail; + +class WorkoutGraph : public ActorFrame +{ +public: + WorkoutGraph(); + ~WorkoutGraph(); + virtual Actor *Copy() const; + + void Load(); + void LoadFromNode( const RString& sDir, const XNode* pNode ); + void SetFromGameState(); + void SetFromGameStateAndHighlightSong( int iSongIndex ); + + // Lua + void PushSelf( lua_State *L ); + +protected: + void SetFromGameStateInternal( int iNumSongsToShowForCurrentStage ); + void HighlightSong( int iSongIndex ); + + Sprite m_sprEmpty; + vector m_vpBars; + + int m_iSongsChoppedOffAtBeginning; +}; + +#endif + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/WorkoutManager.cpp b/stepmania/src/WorkoutManager.cpp new file mode 100644 index 0000000000..a41a9aab55 --- /dev/null +++ b/stepmania/src/WorkoutManager.cpp @@ -0,0 +1,220 @@ +#include "global.h" +#include "WorkoutManager.h" +#include "SongUtil.h" +#include "SongManager.h" +#include "RageFileManager.h" +#include "Workout.h" +#include "song.h" +#include "FontCharAliases.h" +#include "ProfileManager.h" +#include "LocalizedString.h" + +static const RString WORKOUTS_SUBDIR = "Workouts/"; + +WorkoutManager* WORKOUTMAN = new WorkoutManager; // global and accessable from anywhere in our program + +WorkoutManager::WorkoutManager() +{ + m_pCurWorkout = NULL; + m_pTempCourse = new Course; +} + +WorkoutManager::~WorkoutManager() +{ + 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(); + SongUtil::GetAllSongGenres( out.m_vsSongGenres ); +} + +bool WorkoutManager::RenameAndSave( Workout *pWorkout, RString sNewName ) +{ + 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 ) ) + return false; + FlushDirCache(); + 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 ) +{ + if( sAnswer.empty() ) + { + sErrorOut = YOU_MUST_SUPPLY_NAME; + return false; + } + + static const RString sInvalidChars = "\\/:*?\"<>|"; + if( strpbrk(sAnswer, sInvalidChars) != NULL ) + { + sErrorOut = ssprintf( EDIT_NAME_CANNOT_CONTAIN.GetValue(), sInvalidChars.c_str() ); + return false; + } + + Workout *pWorkout = WORKOUTMAN->m_pCurWorkout; + + // Steps name must be unique for this song. + FOREACH_CONST( Workout*, WORKOUTMAN->m_vpAllWorkouts, p ) + { + if( pWorkout == *p ) + continue; // don't comepare name against ourself + + if( (*p)->m_sName == sAnswer ) + { + sErrorOut = EDIT_NAME_CONFLICTS; + return false; + } + } + + return true; +} + +void WorkoutManager::GetWorkoutSongsForGenres( const vector &vsSongGenres, vector &vpSongsOut ) +{ + SongCriteria soc; + soc.m_Selectable = SongCriteria::Selectable_Yes; + soc.m_bUseSongGenreAllowedList = true; + soc.m_vsSongGenreAllowedList = vsSongGenres; + SongUtil::FilterSongs( soc, SONGMAN->GetAllSongs(), vpSongsOut ); +} + +static LocalizedString SONGS_ENABLED( "WorkoutManager", "%d/%d songs enabled" ); +static RString GetWorkoutSongsOverview() +{ + SongCriteria soc; + + 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() ); +} + +static RString GetWorkoutSongTitleText() +{ + vector vs; + FOREACH_CONST( RString, WORKOUTMAN->m_pCurWorkout->m_vsSongGenres, s ) + { + RString s2 = *s; + s2.Replace( " ", " " ); + vs.push_back( s2 ); + + // show max N to avoid frame rate slowdown + if( vs.size() >= 40 ) + break; + } + + RString sReturn = join( ", ", vs ); + FontCharAliases::ReplaceMarkers( sReturn ); + return sReturn; +} + + +// lua start +#include "LuaBinding.h" + +class LunaWorkoutManager: public Luna +{ +public: + LunaWorkoutManager() { LUA->Register( Register ); } + + 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; } + + static void Register(lua_State *L) + { + ADD_METHOD( GetCurrentWorkout ); + ADD_METHOD( GetWorkoutSongsOverview ); + ADD_METHOD( GetWorkoutSongTitleText ); + + Luna::Register( L ); + + // Add global singleton if constructed already. If it's not constructed yet, + // then we'll register it later when we reinit Lua just before + // initializing the display. + if( true ) + { + lua_pushstring(L, "WORKOUTMAN"); + WORKOUTMAN->PushSelf( L ); + lua_settable(L, LUA_GLOBALSINDEX); + } + } +}; + +LUA_REGISTER_CLASS( WorkoutManager ) +// lua end + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/stepmania/src/WorkoutManager.h b/stepmania/src/WorkoutManager.h new file mode 100644 index 0000000000..11622ef130 --- /dev/null +++ b/stepmania/src/WorkoutManager.h @@ -0,0 +1,65 @@ +#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 +{ +public: + WorkoutManager(); + ~WorkoutManager(); + + void LoadAllFromDisk(); + + 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 WorkoutManager* WORKOUTMAN; // global and accessable from anywhere in our program + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */