diff --git a/stepmania/Themes/default/BGAnimations/ScreenEditCoursesMenu in.redir b/stepmania/Themes/default/BGAnimations/ScreenEditCoursesMenu in.redir new file mode 100644 index 0000000000..3c553c7cd9 --- /dev/null +++ b/stepmania/Themes/default/BGAnimations/ScreenEditCoursesMenu in.redir @@ -0,0 +1 @@ +_fade in with sound \ No newline at end of file diff --git a/stepmania/Themes/default/BGAnimations/ScreenEditCoursesMenu out.redir b/stepmania/Themes/default/BGAnimations/ScreenEditCoursesMenu out.redir new file mode 100644 index 0000000000..5ffda2b1ba --- /dev/null +++ b/stepmania/Themes/default/BGAnimations/ScreenEditCoursesMenu out.redir @@ -0,0 +1 @@ +_fade out with sound \ No newline at end of file diff --git a/stepmania/Themes/default/Graphics/EditCoursesMenu left.redir b/stepmania/Themes/default/Graphics/EditCoursesMenu left.redir new file mode 100644 index 0000000000..fe64130f9e --- /dev/null +++ b/stepmania/Themes/default/Graphics/EditCoursesMenu left.redir @@ -0,0 +1 @@ +EditMenu left diff --git a/stepmania/Themes/default/Graphics/EditCoursesMenu right.redir b/stepmania/Themes/default/Graphics/EditCoursesMenu right.redir new file mode 100644 index 0000000000..54077c215c --- /dev/null +++ b/stepmania/Themes/default/Graphics/EditCoursesMenu right.redir @@ -0,0 +1 @@ +EditMenu right diff --git a/stepmania/Themes/default/Graphics/EditMenu Right 1x4.png b/stepmania/Themes/default/Graphics/EditMenu Right 1x4.png index 80ca9fdb87..c6521a8ff2 100644 Binary files a/stepmania/Themes/default/Graphics/EditMenu Right 1x4.png and b/stepmania/Themes/default/Graphics/EditMenu Right 1x4.png differ diff --git a/stepmania/Themes/default/Graphics/JukeboxMenu left.redir b/stepmania/Themes/default/Graphics/JukeboxMenu left.redir new file mode 100644 index 0000000000..fe64130f9e --- /dev/null +++ b/stepmania/Themes/default/Graphics/JukeboxMenu left.redir @@ -0,0 +1 @@ +EditMenu left diff --git a/stepmania/Themes/default/Graphics/JukeboxMenu right.redir b/stepmania/Themes/default/Graphics/JukeboxMenu right.redir new file mode 100644 index 0000000000..54077c215c --- /dev/null +++ b/stepmania/Themes/default/Graphics/JukeboxMenu right.redir @@ -0,0 +1 @@ +EditMenu right diff --git a/stepmania/Themes/default/Graphics/MenuElements icon double 2x1.png b/stepmania/Themes/default/Graphics/MenuElements icon double 2x1.png index ce06dbaacf..3118ccdd6e 100644 Binary files a/stepmania/Themes/default/Graphics/MenuElements icon double 2x1.png and b/stepmania/Themes/default/Graphics/MenuElements icon double 2x1.png differ diff --git a/stepmania/Themes/default/Graphics/ScreenEditCoursesMenu header.redir b/stepmania/Themes/default/Graphics/ScreenEditCoursesMenu header.redir new file mode 100644 index 0000000000..843d326fc0 --- /dev/null +++ b/stepmania/Themes/default/Graphics/ScreenEditCoursesMenu header.redir @@ -0,0 +1 @@ +_shared menu header.png \ No newline at end of file diff --git a/stepmania/Themes/default/Sounds/EditCoursesMenu row.redir b/stepmania/Themes/default/Sounds/EditCoursesMenu row.redir new file mode 100644 index 0000000000..2d211773e6 --- /dev/null +++ b/stepmania/Themes/default/Sounds/EditCoursesMenu row.redir @@ -0,0 +1 @@ +EditMenu row diff --git a/stepmania/Themes/default/Sounds/EditCoursesMenu value.redir b/stepmania/Themes/default/Sounds/EditCoursesMenu value.redir new file mode 100644 index 0000000000..30ee5f98ef --- /dev/null +++ b/stepmania/Themes/default/Sounds/EditCoursesMenu value.redir @@ -0,0 +1 @@ +EditMenu value diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index f8ed5cc8f3..eae159929c 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -1603,6 +1603,12 @@ ExplanationY=410 ExplanationText=In this mode, you can watch demos and listen to music. HelpText=&UP; &DOWN; change line &LEFT; &RIGHT; change value START to continue +[ScreenEditCoursesMenu] +ExplanationX=320 +ExplanationY=410 +ExplanationText=In this mode, you can edit courses. +HelpText=&UP; &DOWN; change line &LEFT; &RIGHT; change value START to continue + [ScreenSystemLayer] StatsX=632 StatsY=10 @@ -2236,6 +2242,35 @@ Row2Y=130 Row3Y=180 Row4Y=230 +[EditCoursesMenu] +Arrows1X=190 +Arrows2X=590 +EntryBannerX=490 +EntryBannerY=130 +EntryBannerWidth=130 +EntryBannerHeight=40 +EntryTextBannerX=320 +EntryTextBannerY=130 +CourseBannerX=490 +CourseBannerY=80 +CourseBannerWidth=130 +CourseBannerHeight=40 +RowLabelsX=20 +RowValue1X=320 +RowValue2X=380 +RowValue3X=380 +RowValue4X=320 +RowValue5X=380 +RowValue6X=320 +RowValue7X=380 +Row1Y=80 +Row2Y=130 +Row3Y=180 +Row4Y=220 +Row5Y=260 +Row6Y=300 +Row7Y=340 + [ScreenOptionsMenu] HelpText=&UP; &DOWN; to change line then press START InputOptions= diff --git a/stepmania/src/Course.cpp b/stepmania/src/Course.cpp index 866815dc3f..31f64822a1 100644 --- a/stepmania/src/Course.cpp +++ b/stepmania/src/Course.cpp @@ -179,30 +179,30 @@ void Course::LoadFromCRSFile( CString sPath ) else if( 0 == stricmp(sValueName, "SONG") ) { - Entry new_entry; + CourseEntry new_entry; // infer entry::Type from the first param if( sParams[1].Left(strlen("BEST")) == "BEST" ) { - new_entry.type = Entry::best; + new_entry.type = COURSE_ENTRY_BEST; new_entry.players_index = atoi( sParams[1].Right(sParams[1].size()-strlen("BEST")) ) - 1; CLAMP( new_entry.players_index, 0, 500 ); } else if( sParams[1].Left(strlen("WORST")) == "WORST" ) { - new_entry.type = Entry::worst; + new_entry.type = COURSE_ENTRY_WORST; new_entry.players_index = atoi( sParams[1].Right(sParams[1].size()-strlen("WORST")) ) - 1; CLAMP( new_entry.players_index, 0, 500 ); } else if( sParams[1] == "*" ) { new_entry.mystery = true; - new_entry.type = Entry::random; + new_entry.type = COURSE_ENTRY_RANDOM; } else if( sParams[1].Right(1) == "*" ) { new_entry.mystery = true; - new_entry.type = Entry::random_within_group; + new_entry.type = COURSE_ENTRY_RANDOM_WITHIN_GROUP; CString sSong = sParams[1]; sSong.Replace( "\\", "/" ); CStringArray bits; @@ -225,7 +225,7 @@ void Course::LoadFromCRSFile( CString sPath ) } else { - new_entry.type = Entry::fixed; + new_entry.type = COURSE_ENTRY_FIXED; CString sSong = sParams[1]; new_entry.pSong = SONGMAN->FindSong( sSong ); @@ -308,23 +308,23 @@ void Course::Save() for( unsigned i=0; iGetSongDir().c_str() ); break; - case Entry::random: + case COURSE_ENTRY_RANDOM: fprintf( fp, "#SONG:*" ); break; - case Entry::random_within_group: + case COURSE_ENTRY_RANDOM_WITHIN_GROUP: fprintf( fp, "#SONG:%s/*", entry.group_name.c_str() ); break; - case Entry::best: + case COURSE_ENTRY_BEST: fprintf( fp, "#SONG:BEST%d", entry.players_index+1 ); break; - case Entry::worst: + case COURSE_ENTRY_WORST: fprintf( fp, "#SONG:WORST%d", entry.players_index+1 ); break; default: @@ -340,7 +340,7 @@ void Course::Save() fprintf( fp, "%d..%d", entry.low_meter, entry.high_meter ); fprintf( fp, ":%s", entry.modifiers.c_str() ); - bool default_mystery = !(entry.type == Entry::random || entry.type == Entry::random_within_group); + bool default_mystery = !(entry.type == COURSE_ENTRY_RANDOM || entry.type == COURSE_ENTRY_RANDOM_WITHIN_GROUP); if( default_mystery != entry.mystery ) { if( entry.modifiers != "" ) @@ -369,8 +369,8 @@ void Course::AutogenEndlessFromGroup( CString sGroupName, vector &apSongs // We want multiple songs, so we can try to prevent repeats during // gameplay. (We might still get a repeat at the repeat boundary, // but that'd be rare.) -glenn - Entry e; - e.type = Entry::random_within_group; + CourseEntry e; + e.type = COURSE_ENTRY_RANDOM_WITHIN_GROUP; e.group_name = sGroupName; e.difficulty = DIFFICULTY_MEDIUM; e.mystery = true; @@ -429,7 +429,7 @@ bool Course::HasDifficult( StepsType nt ) const if( Normal[i].Mystery ) { - const Entry &e = m_entries[ Normal[i].CourseIndex ]; + const CourseEntry &e = m_entries[ Normal[i].CourseIndex ]; /* Difficulties under CHALLENGE change by getting harder. */ if( e.difficulty < DIFFICULTY_CHALLENGE ) @@ -476,7 +476,7 @@ static vector GetFilteredBestSongs( StepsType nt ) void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficult ) const { - vector entries = m_entries; + vector entries = m_entries; /* Different seed for each course, but the same for the whole round: */ RandomGen rnd( GAMESTATE->m_iRoundSeed + GetHashForString(m_sName) ); @@ -501,7 +501,7 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul for( unsigned i=0; i &ci, int Difficul switch( e.type ) { - case Entry::fixed: + case COURSE_ENTRY_FIXED: pSong = e.pSong; if( pSong ) { @@ -523,8 +523,8 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul pNotes = pSong->GetStepsByDifficulty( nt, e.difficulty, PREFSMAN->m_bAutogenMissingTypes ); } break; - case Entry::random: - case Entry::random_within_group: + case COURSE_ENTRY_RANDOM: + case COURSE_ENTRY_RANDOM_WITHIN_GROUP: { // find a song with the notes we want for( unsigned j=0; j &ci, int Difficul ASSERT( pSong ); CurSong = (CurSong+1) % AllSongsShuffled.size(); - if(e.type == Entry::random_within_group && + if(e.type == COURSE_ENTRY_RANDOM_WITHIN_GROUP && pSong->m_sGroupName.CompareNoCase(e.group_name)) continue; /* wrong group */ @@ -552,8 +552,8 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul } } break; - case Entry::best: - case Entry::worst: + case COURSE_ENTRY_BEST: + case COURSE_ENTRY_WORST: { if( !bMostPlayedSet ) { @@ -566,10 +566,10 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul switch( e.type ) { - case Entry::best: + case COURSE_ENTRY_BEST: pSong = vSongsByMostPlayed[e.players_index]; break; - case Entry::worst: + case COURSE_ENTRY_WORST: pSong = vSongsByMostPlayed[vSongsByMostPlayed.size()-1-e.players_index]; break; default: @@ -612,7 +612,7 @@ void Course::GetCourseInfo( StepsType nt, vector &ci, int Difficul cinfo.pSong = pSong; cinfo.pNotes = pNotes; cinfo.Modifiers = e.modifiers; - cinfo.Random = ( e.type == Entry::random || e.type == Entry::random_within_group ); + cinfo.Random = ( e.type == COURSE_ENTRY_RANDOM || e.type == COURSE_ENTRY_RANDOM_WITHIN_GROUP ); cinfo.Mystery = e.mystery; cinfo.CourseIndex = i; cinfo.Difficult = IsDifficult(Difficult); @@ -937,7 +937,7 @@ void Course::UpdateCourseStats() // courses with random/players best-worst songs should go at the end for(i = 0; i < m_entries.size(); i++) { - if ( m_entries[i].type == Entry::fixed ) + if ( m_entries[i].type == COURSE_ENTRY_FIXED ) continue; SortOrder_AvgDifficulty = 9999999; // large number diff --git a/stepmania/src/Course.h b/stepmania/src/Course.h index 5ca2575fc2..191c81b690 100644 --- a/stepmania/src/Course.h +++ b/stepmania/src/Course.h @@ -19,30 +19,52 @@ struct SongOptions; class Song; class Steps; +enum CourseEntryType +{ + COURSE_ENTRY_FIXED, + COURSE_ENTRY_RANDOM, + COURSE_ENTRY_RANDOM_WITHIN_GROUP, + COURSE_ENTRY_BEST, + COURSE_ENTRY_WORST, + NUM_COURSE_ENTRY_TYPES // leave this at the end +}; + +inline CString CourseEntryTypeToString( CourseEntryType cet ) +{ + switch( cet ) + { + case COURSE_ENTRY_FIXED: return "fixed"; + case COURSE_ENTRY_RANDOM: return "random"; + case COURSE_ENTRY_RANDOM_WITHIN_GROUP: return "random_within_group"; + case COURSE_ENTRY_BEST: return "best"; + case COURSE_ENTRY_WORST: return "worst"; + default: ASSERT(0); return ""; + } +} + +struct CourseEntry { + CourseEntryType type; + bool mystery; // show "??????" + Song* pSong; // used in type=fixed + CString group_name; // used in type=random_within_group + Difficulty difficulty; // = DIFFICULTY_INVALID if no difficulty specified + int low_meter; // = -1 if no meter range specified + int high_meter; // = -1 if no meter range specified + int players_index; // ignored if type isn't 'best' or 'worst' + CString modifiers; // set player and song options using these + + CourseEntry() + { + difficulty = DIFFICULTY_INVALID; + low_meter = -1; + high_meter = -1; + players_index = -1; + mystery = false; + } +}; + class Course { - struct Entry { - enum Type { fixed, random, random_within_group, best, worst } type; - bool mystery; // show "??????" - Song* pSong; // used in type=fixed - CString group_name; // used in type=random_within_group - Difficulty difficulty; // = DIFFICULTY_INVALID if no difficulty specified - int low_meter; // = -1 if no meter range specified - int high_meter; // = -1 if no meter range specified - int players_index; // ignored if type isn't 'best' or 'worst' - CString modifiers; // set player and song options using these - - Entry() - { - difficulty = DIFFICULTY_INVALID; - low_meter = -1; - high_meter = -1; - players_index = -1; - mystery = false; - } - }; - vector m_entries; - public: Course(); @@ -62,6 +84,8 @@ public: int m_iLives; // -1 means use bar life meter int m_iMeter; // -1 autogens + vector m_entries; + struct Info { Info(): pSong(NULL), pNotes(NULL), Random(false), Difficult(false) { } diff --git a/stepmania/src/EditCoursesMenu.cpp b/stepmania/src/EditCoursesMenu.cpp new file mode 100644 index 0000000000..e90e172b89 --- /dev/null +++ b/stepmania/src/EditCoursesMenu.cpp @@ -0,0 +1,237 @@ +#include "global.h" +/* +----------------------------------------------------------------------------- + Class: EditCoursesMenu + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "EditCoursesMenu.h" +#include "RageLog.h" +#include "SongManager.h" +#include "GameState.h" +#include "ThemeManager.h" +#include "GameManager.h" +#include "Steps.h" +#include "song.h" +#include "Course.h" + +// +// Defines specific to EditCoursesMenu +// +#define ARROWS_X( i ) THEME->GetMetricF("EditCoursesMenu",ssprintf("Arrows%dX",i+1)) +#define COURSE_BANNER_X THEME->GetMetricF("EditCoursesMenu","CourseBannerX") +#define COURSE_BANNER_Y THEME->GetMetricF("EditCoursesMenu","CourseBannerY") +#define COURSE_BANNER_WIDTH THEME->GetMetricF("EditCoursesMenu","CourseBannerWidth") +#define COURSE_BANNER_HEIGHT THEME->GetMetricF("EditCoursesMenu","CourseBannerHeight") +#define COURSE_TEXT_BANNER_X THEME->GetMetricF("EditCoursesMenu","CourseTextBannerX") +#define COURSE_TEXT_BANNER_Y THEME->GetMetricF("EditCoursesMenu","CourseTextBannerY") +#define ENTRY_BANNER_X THEME->GetMetricF("EditCoursesMenu","EntryBannerX") +#define ENTRY_BANNER_Y THEME->GetMetricF("EditCoursesMenu","EntryBannerY") +#define ENTRY_BANNER_WIDTH THEME->GetMetricF("EditCoursesMenu","EntryBannerWidth") +#define ENTRY_BANNER_HEIGHT THEME->GetMetricF("EditCoursesMenu","EntryBannerHeight") +#define ENTRY_TEXT_BANNER_X THEME->GetMetricF("EditCoursesMenu","EntryTextBannerX") +#define ENTRY_TEXT_BANNER_Y THEME->GetMetricF("EditCoursesMenu","EntryTextBannerY") +#define ROW_LABELS_X THEME->GetMetricF("EditCoursesMenu","RowLabelsX") +#define ROW_VALUE_X( i ) THEME->GetMetricF("EditCoursesMenu",ssprintf("RowValue%dX",i+1)) +#define ROW_Y( i ) THEME->GetMetricF("EditCoursesMenu",ssprintf("Row%dY",i+1)) + + +const int MAX_EDIT_COURSES_ENTRIES = 100; + +EditCoursesMenu::EditCoursesMenu() +{ + LOG->Trace( "ScreenEditCoursesMenu::ScreenEditCoursesMenu()" ); + + int i; + + for( i=0; i<2; i++ ) + { + m_sprArrows[i].Load( THEME->GetPathToG(ssprintf("EditCoursesMenu %s",(i==0?"left":"right"))) ); + m_sprArrows[i].SetX( ARROWS_X(i) ); + this->AddChild( &m_sprArrows[i] ); + } + + m_SelectedRow = (Row)0; + + ZERO( m_iSelection ); + + + + for( i=0; iGetPathToF("Common title") ); + m_textLabel[i].SetXY( ROW_LABELS_X, ROW_Y(i) ); + m_textLabel[i].SetText( RowToString((Row)i) ); + m_textLabel[i].SetZoom( 0.8f ); + m_textLabel[i].SetHorizAlign( Actor::align_left ); + this->AddChild( &m_textLabel[i] ); + + m_textValue[i].LoadFromFont( THEME->GetPathToF("Common normal") ); + m_textValue[i].SetXY( ROW_VALUE_X(i), ROW_Y(i) ); + m_textValue[i].SetText( "blah" ); + m_textValue[i].SetZoom( 0.8f ); + this->AddChild( &m_textValue[i] ); + } + + m_CourseBanner.SetXY( COURSE_BANNER_X, COURSE_BANNER_Y ); + this->AddChild( &m_CourseBanner ); + + m_EntryBanner.SetXY( ENTRY_BANNER_X, ENTRY_BANNER_Y ); + this->AddChild( &m_EntryBanner ); + + m_EntryTextBanner.SetXY( ENTRY_TEXT_BANNER_X, ENTRY_TEXT_BANNER_Y ); + this->AddChild( &m_EntryTextBanner ); + + + m_soundChangeRow.Load( THEME->GetPathToS("EditCoursesMenu row") ); + m_soundChangeValue.Load( THEME->GetPathToS("EditCoursesMenu value") ); + + + // fill in data structures + SONGMAN->GetAllCourses( m_pCourses, false ); + + ChangeToRow( (Row)0 ); + OnRowValueChanged( (Row)0 ); +} + +EditCoursesMenu::~EditCoursesMenu() +{ + +} + +void EditCoursesMenu::DrawPrimitives() +{ + ActorFrame::DrawPrimitives(); +} + +bool EditCoursesMenu::CanGoUp() +{ + return m_SelectedRow != 0; +} + +bool EditCoursesMenu::CanGoDown() +{ + return m_SelectedRow != NUM_ROWS-1; +} + +bool EditCoursesMenu::CanGoLeft() +{ + return m_iSelection[m_SelectedRow] != 0; +} + +bool EditCoursesMenu::CanGoRight() +{ + int num_values[NUM_ROWS] = + { + m_pCourses.size(), + 1, + 1, + MAX_EDIT_COURSES_ENTRIES, + NUM_COURSE_ENTRY_TYPES, + 1, + 1 + }; + + return m_iSelection[m_SelectedRow] != (num_values[m_SelectedRow]-1); +} + +void EditCoursesMenu::Up() +{ + if( CanGoUp() ) + { + m_soundChangeRow.PlayRandom(); + } +} + +void EditCoursesMenu::Down() +{ + if( CanGoDown() ) + { + m_soundChangeRow.PlayRandom(); + } +} + +void EditCoursesMenu::Left() +{ + if( CanGoLeft() ) + { + m_iSelection[m_SelectedRow]--; + OnRowValueChanged( m_SelectedRow ); + m_soundChangeValue.PlayRandom(); + } +} + +void EditCoursesMenu::Right() +{ + if( CanGoRight() ) + { + m_iSelection[m_SelectedRow]++; + OnRowValueChanged( m_SelectedRow ); + m_soundChangeValue.PlayRandom(); + } +} + + +void EditCoursesMenu::ChangeToRow( Row newRow ) +{ + m_SelectedRow = newRow; + + for( int i=0; i<2; i++ ) + m_sprArrows[i].SetY( ROW_Y(newRow) ); + m_sprArrows[0].SetDiffuse( CanGoLeft()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); + m_sprArrows[1].SetDiffuse( CanGoRight()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); + m_sprArrows[0].EnableAnimation( CanGoLeft() ); + m_sprArrows[1].EnableAnimation( CanGoRight() ); +} + +void EditCoursesMenu::OnRowValueChanged( Row row ) +{ + m_sprArrows[0].SetDiffuse( CanGoLeft()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); + m_sprArrows[1].SetDiffuse( CanGoRight()?RageColor(1,1,1,1):RageColor(0.2f,0.2f,0.2f,1) ); + m_sprArrows[0].EnableAnimation( CanGoLeft() ); + m_sprArrows[1].EnableAnimation( CanGoRight() ); + + Course* pCourse = GetSelectedCourse(); + CourseEntry* pEntry = NULL; + if( m_iSelection[ROW_ENTRY] < pCourse->m_entries.size() ) + pEntry = &pCourse->m_entries[m_iSelection[ROW_ENTRY]]; + + switch( row ) + { + case ROW_COURSE: + m_textValue[ROW_COURSE].SetText( GetSelectedCourse()->m_sName ); + m_CourseBanner.LoadFromGroup( GetSelectedCourse()->m_sBannerPath ); + m_CourseBanner.ScaleToClipped( COURSE_BANNER_WIDTH, COURSE_BANNER_HEIGHT ); + m_iSelection[ROW_ENTRY] = 0; + // fall through + case ROW_SAVE: + // fall through + case ROW_COURSE_OPTIONS: + m_textValue[ROW_COURSE_OPTIONS].SetText( + ssprintf( + "%s, %s, %d", + pCourse->m_bRepeat ? "repeat" : "no repeat", + pCourse->m_bRandomize ? "randomize" : "no randomize", + pCourse->m_iLives ) ); + // fall through + case ROW_ENTRY: + m_textValue[ROW_ENTRY].SetText( ssprintf("%d",m_iSelection[ROW_ENTRY]+1) ); + // fall through + case ROW_ENTRY_TYPE: + m_textValue[ROW_ENTRY_TYPE].SetText( pEntry ? CourseEntryTypeToString(pEntry->type) : "none" ); + // fall through + case ROW_ENTRY_OPTIONS: + m_textValue[ROW_ENTRY_OPTIONS].SetText( "coming soon" ); + // fall through + case ROW_ENTRY_MODIFIERS: + m_textValue[ROW_ENTRY_OPTIONS].SetText( "coming soon" ); + break; + default: + ASSERT(0); // invalid row + } +} diff --git a/stepmania/src/EditCoursesMenu.h b/stepmania/src/EditCoursesMenu.h new file mode 100644 index 0000000000..541cf3dd84 --- /dev/null +++ b/stepmania/src/EditCoursesMenu.h @@ -0,0 +1,88 @@ +#ifndef EditCoursesMenu_H +#define EditCoursesMenu_H +/* +----------------------------------------------------------------------------- + Class: EditCoursesMenu + + Desc: UI on Edit Menu screen. Create Steps, delete Steps, or launch Steps + in editor. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ActorFrame.h" +#include "Banner.h" +#include "TextBanner.h" +#include "GameConstantsAndTypes.h" +#include "DifficultyMeter.h" +#include "RandomSample.h" + + +class EditCoursesMenu: public ActorFrame +{ +public: + EditCoursesMenu(); + ~EditCoursesMenu(); + virtual void DrawPrimitives(); + + bool CanGoUp(); + bool CanGoDown(); + bool CanGoLeft(); + bool CanGoRight(); + + void Up(); + void Down(); + void Left(); + void Right(); + + enum Row + { + ROW_COURSE, + ROW_SAVE, + ROW_COURSE_OPTIONS, + ROW_ENTRY, + ROW_ENTRY_TYPE, + ROW_ENTRY_OPTIONS, + ROW_ENTRY_MODIFIERS, + NUM_ROWS + } m_SelectedRow; + CString RowToString( Row r ) + { + const CString s[NUM_ROWS] = + { + "Course", + "Save", + "Course Options", + "Entry", + "Entry Type", + "Entry Options", + "Entry Modifiers" + }; + return s[r]; + } + + Course* GetSelectedCourse() { return m_pCourses[m_iSelection[ROW_COURSE]]; } + +private: + Sprite m_sprArrows[2]; + + int m_iSelection[NUM_ROWS]; + BitmapText m_textLabel[NUM_ROWS]; + BitmapText m_textValue[NUM_ROWS]; + + Banner m_CourseBanner; + Banner m_EntryBanner; + TextBanner m_EntryTextBanner; + + vector m_pCourses; + + void OnRowValueChanged( Row row ); + void ChangeToRow( Row newRow ); + + RandomSample m_soundChangeRow; + RandomSample m_soundChangeValue; +}; + +#endif diff --git a/stepmania/src/Screen.cpp b/stepmania/src/Screen.cpp index 511b6ce6d7..f0f61800e9 100644 --- a/stepmania/src/Screen.cpp +++ b/stepmania/src/Screen.cpp @@ -297,6 +297,7 @@ void Screen::ClearMessageQueue( const ScreenMessage SM ) #include "ScreenSelectMode.h" #include "ScreenBackgroundOptions.h" #include "ScreenSelectMaster.h" +#include "ScreenEditCoursesMenu.h" Screen* Screen::Create( CString sClassName ) { @@ -364,6 +365,7 @@ Screen* Screen::Create( CString sClassName ) IF_RETURN( ScreenRaveOptions ); IF_RETURN( ScreenBackgroundOptions ); IF_RETURN( ScreenSelectMaster ); + IF_RETURN( ScreenEditCoursesMenu ); RageException::Throw( "Invalid Screen class name '%s'", sClassName.c_str() ); } diff --git a/stepmania/src/ScreenEditCoursesMenu.cpp b/stepmania/src/ScreenEditCoursesMenu.cpp new file mode 100644 index 0000000000..ae43927cf3 --- /dev/null +++ b/stepmania/src/ScreenEditCoursesMenu.cpp @@ -0,0 +1,136 @@ +#include "global.h" +/* +----------------------------------------------------------------------------- + Class: ScreenEditCoursesMenu + + Desc: The main title screen and menu. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "ScreenEditCoursesMenu.h" +#include "SongManager.h" +#include "ScreenManager.h" +#include "GameConstantsAndTypes.h" +#include "RageUtil.h" +#include "PrefsManager.h" +#include "GameManager.h" +#include "RageLog.h" +#include "GameState.h" +#include "RageSounds.h" +#include "ThemeManager.h" +#include "Steps.h" + + +// +// Defines specific to ScreenEditCoursesMenu +// +#define EXPLANATION_X THEME->GetMetricF("ScreenEditCoursesMenu","ExplanationX") +#define EXPLANATION_Y THEME->GetMetricF("ScreenEditCoursesMenu","ExplanationY") +#define EXPLANATION_TEXT THEME->GetMetric("ScreenEditCoursesMenu","ExplanationText") +#define HELP_TEXT THEME->GetMetric("ScreenEditCoursesMenu","HelpText") + +const ScreenMessage SM_RefreshSelector = (ScreenMessage)(SM_User+1); + +ScreenEditCoursesMenu::ScreenEditCoursesMenu() : Screen("ScreenEditCoursesMenu") +{ + LOG->Trace( "ScreenEditCoursesMenu::ScreenEditCoursesMenu()" ); + + GAMESTATE->m_CurStyle = STYLE_INVALID; + + m_Selector.SetXY( 0, 0 ); +// m_Selector.AllowNewNotes(); + this->AddChild( &m_Selector ); + + m_Menu.Load( "ScreenEditCoursesMenu", false ); // disable timer + this->AddChild( &m_Menu ); + + + m_textExplanation.LoadFromFont( THEME->GetPathToF("Common normal") ); + m_textExplanation.SetXY( EXPLANATION_X, EXPLANATION_Y ); + m_textExplanation.SetText( EXPLANATION_TEXT ); + m_textExplanation.SetZoom( 0.7f ); + this->AddChild( &m_textExplanation ); + + SOUND->PlayMusic( THEME->GetPathToS("ScreenEditCoursesMenu music") ); +} + + +ScreenEditCoursesMenu::~ScreenEditCoursesMenu() +{ + LOG->Trace( "ScreenEditCoursesMenu::~ScreenEditCoursesMenu()" ); +} + +void ScreenEditCoursesMenu::DrawPrimitives() +{ + m_Menu.DrawBottomLayer(); + Screen::DrawPrimitives(); + m_Menu.DrawTopLayer(); +} + +void ScreenEditCoursesMenu::Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ) +{ + LOG->Trace( "ScreenEditCoursesMenu::Input()" ); + + Screen::Input( DeviceI, type, GameI, MenuI, StyleI ); +} + +void ScreenEditCoursesMenu::HandleScreenMessage( const ScreenMessage SM ) +{ + switch( SM ) + { + case SM_GoToPrevScreen: + SCREENMAN->SetNewScreen( "ScreenTitleMenu" ); + break; + case SM_GoToNextScreen: + SCREENMAN->SetNewScreen( "ScreenEdit" ); + break; + } +} + +void ScreenEditCoursesMenu::MenuUp( PlayerNumber pn ) +{ + m_Selector.Up(); +} + +void ScreenEditCoursesMenu::MenuDown( PlayerNumber pn ) +{ + m_Selector.Down(); +} + +void ScreenEditCoursesMenu::MenuLeft( PlayerNumber pn, const InputEventType type ) +{ + m_Selector.Left(); +} + +void ScreenEditCoursesMenu::MenuRight( PlayerNumber pn, const InputEventType type ) +{ + m_Selector.Right(); +} + + +// helpers for MenuStart() below +void DeleteCurNotes() +{ + Song* pSong = GAMESTATE->m_pCurSong; + Steps* pNotesToDelete = GAMESTATE->m_pCurNotes[PLAYER_1]; + pSong->RemoveNotes( pNotesToDelete ); + pSong->Save(); +} + +void ScreenEditCoursesMenu::MenuStart( PlayerNumber pn ) +{ + if( m_Menu.IsTransitioning() ) + return; + + Course* pCourse = m_Selector.GetSelectedCourse(); +} + +void ScreenEditCoursesMenu::MenuBack( PlayerNumber pn ) +{ + m_Menu.Back( SM_GoToPrevScreen ); + + SOUND->StopMusic(); +} diff --git a/stepmania/src/ScreenEditCoursesMenu.h b/stepmania/src/ScreenEditCoursesMenu.h new file mode 100644 index 0000000000..21ebaf7fa4 --- /dev/null +++ b/stepmania/src/ScreenEditCoursesMenu.h @@ -0,0 +1,45 @@ +/* +----------------------------------------------------------------------------- + Class: ScreenEditCoursesMenu + + Desc: See header. + + Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. + Chris Danford +----------------------------------------------------------------------------- +*/ + +#include "Screen.h" +#include "EditCoursesMenu.h" +#include "BitmapText.h" +#include "MenuElements.h" + + +class ScreenEditCoursesMenu : public Screen +{ +public: + ScreenEditCoursesMenu(); + virtual ~ScreenEditCoursesMenu(); + + virtual void DrawPrimitives(); + virtual void Input( const DeviceInput& DeviceI, const InputEventType type, const GameInput &GameI, const MenuInput &MenuI, const StyleInput &StyleI ); + virtual void HandleScreenMessage( const ScreenMessage SM ); + +private: + + void MenuUp( PlayerNumber pn ); + void MenuDown( PlayerNumber pn ); + void MenuLeft( PlayerNumber pn, const InputEventType type ); + void MenuRight( PlayerNumber pn, const InputEventType type ); + void MenuBack( PlayerNumber pn ); + void MenuStart( PlayerNumber pn ); + + EditCoursesMenu m_Selector; + + BitmapText m_textExplanation; + + MenuElements m_Menu; +}; + + + diff --git a/stepmania/src/ScreenEditMenu.cpp b/stepmania/src/ScreenEditMenu.cpp index 4aa43bfeb8..628c965ceb 100644 --- a/stepmania/src/ScreenEditMenu.cpp +++ b/stepmania/src/ScreenEditMenu.cpp @@ -114,15 +114,6 @@ void ScreenEditMenu::MenuRight( PlayerNumber pn, const InputEventType type ) } -// helpers for MenuStart() below -void DeleteCurNotes() -{ - Song* pSong = GAMESTATE->m_pCurSong; - Steps* pNotesToDelete = GAMESTATE->m_pCurNotes[PLAYER_1]; - pSong->RemoveNotes( pNotesToDelete ); - pSong->Save(); -} - void ScreenEditMenu::MenuStart( PlayerNumber pn ) { if( m_Menu.IsTransitioning() ) @@ -162,7 +153,7 @@ void ScreenEditMenu::MenuStart( PlayerNumber pn ) break; case EditMenu::ACTION_DELETE: ASSERT( pNotes ); - SCREENMAN->Prompt( SM_RefreshSelector, "These notes will be lost permanently.\n\nContinue with delete?", true, false, DeleteCurNotes ); + SCREENMAN->Prompt( SM_RefreshSelector, "These notes will be lost permanently.\n\nContinue with delete?", true, false, NULL ); m_Selector.RefreshNotes(); return; case EditMenu::ACTION_COPY: diff --git a/stepmania/src/ScreenTitleMenu.cpp b/stepmania/src/ScreenTitleMenu.cpp index db1497320b..f5145c88c5 100644 --- a/stepmania/src/ScreenTitleMenu.cpp +++ b/stepmania/src/ScreenTitleMenu.cpp @@ -233,6 +233,15 @@ void ScreenTitleMenu::Input( const DeviceInput& DeviceI, const InputEventType ty return; } } + if( m_Choice == CHOICE_EDIT_COURSES ) + { + if( SONGMAN->GetNumCourses() == 0 ) + { + m_soundInvalid.Play(); + SCREENMAN->SystemMessage( "No courses are installed" ); + return; + } + } if( m_Choice == CHOICE_EXIT ) { LOG->Trace("CHOICE_EXIT: shutting down"); @@ -314,6 +323,9 @@ void ScreenTitleMenu::HandleScreenMessage( const ScreenMessage SM ) case CHOICE_EDIT: SCREENMAN->SetNewScreen( "ScreenEditMenu" ); break; + case CHOICE_EDIT_COURSES: + SCREENMAN->SetNewScreen( "ScreenEditCoursesMenu" ); + break; case CHOICE_EXIT: default: RAGE_ASSERT_M(0, "CHOICE_EXIT reached?"); // should never get here diff --git a/stepmania/src/ScreenTitleMenu.h b/stepmania/src/ScreenTitleMenu.h index c98cd8daf6..ac8a5e54f1 100644 --- a/stepmania/src/ScreenTitleMenu.h +++ b/stepmania/src/ScreenTitleMenu.h @@ -35,6 +35,7 @@ public: CHOICE_SELECT_GAME, CHOICE_OPTIONS, CHOICE_EDIT, + CHOICE_EDIT_COURSES, CHOICE_JUKEBOX, #ifdef DEBUG CHOICE_SANDBOX, @@ -50,6 +51,7 @@ public: "SELECT GAME", "OPTIONS", "EDIT/SYNC SONGS", + "EDIT COURSES", "JUKEBOX", #ifdef DEBUG "SANDBOX", diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index 215bd49fe6..074cd96f32 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -65,7 +65,7 @@ IntDir=.\../Debug6 TargetDir=\stepmania\stepmania TargetName=StepMania-debug SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -102,7 +102,7 @@ IntDir=.\Debug TargetDir=\stepmania\stepmania TargetName=default SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -142,7 +142,7 @@ IntDir=.\../Release6 TargetDir=\stepmania\stepmania TargetName=StepMania SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -183,7 +183,7 @@ IntDir=.\StepMania___Xbox_Release TargetDir=\stepmania\stepmania TargetName=default SOURCE="$(InputPath)" -PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ +PreLink_Cmds=disasm\verinc cl /Zl /nologo /c verstub.cpp /Fo$(IntDir)\ PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi # End Special Build Tool @@ -3509,6 +3509,25 @@ SOURCE=.\DifficultyRating.h # End Source File # Begin Source File +SOURCE=.\EditCoursesMenu.cpp + +!IF "$(CFG)" == "StepMania - Win32 Debug" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Debug" + +!ELSEIF "$(CFG)" == "StepMania - Win32 Release" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\EditCoursesMenu.h +# End Source File +# Begin Source File + SOURCE=.\EditMenu.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" @@ -4144,6 +4163,25 @@ SOURCE=.\ScreenEdit.h # End Source File # Begin Source File +SOURCE=.\ScreenEditCoursesMenu.cpp + +!IF "$(CFG)" == "StepMania - Win32 Debug" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Debug" + +!ELSEIF "$(CFG)" == "StepMania - Win32 Release" + +!ELSEIF "$(CFG)" == "StepMania - Xbox Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\ScreenEditCoursesMenu.h +# End Source File +# Begin Source File + SOURCE=.\ScreenEditMenu.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" diff --git a/stepmania/src/StepMania.vcproj b/stepmania/src/StepMania.vcproj index 3fc8fcfe6d..177c2af772 100644 --- a/stepmania/src/StepMania.vcproj +++ b/stepmania/src/StepMania.vcproj @@ -229,6 +229,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + @@ -1147,6 +1153,12 @@ cl /Zl /nologo /c verstub.cpp /Fo"$(IntDir)"\ + + + + diff --git a/stepmania/src/arch/arch.h b/stepmania/src/arch/arch.h index 7259d7bb24..72e117483d 100644 --- a/stepmania/src/arch/arch.h +++ b/stepmania/src/arch/arch.h @@ -17,7 +17,7 @@ LowLevelWindow *MakeLowLevelWindow(); void MakeInputHandlers(vector &Add); RageSoundDriver *MakeRageSoundDriver(CString drivers); -/* These definitions are in here, instead of in arch_*.h, because they +/* These definitions are in here, instead of i n arch_*.h, because they * need to be available to other modules. It'd be overkill to create separate * "config" and "driver" headers for each arch. */