diff --git a/stepmania/Themes/default/metrics.ini b/stepmania/Themes/default/metrics.ini index 2c0c79cab6..c4ccc1964f 100644 --- a/stepmania/Themes/default/metrics.ini +++ b/stepmania/Themes/default/metrics.ini @@ -1606,8 +1606,8 @@ HelpText=&UP; &DOWN; change line &LEFT; &RIGHT; change value START to con [ScreenEditCoursesMenu] ExplanationX=320 ExplanationY=410 -ExplanationText=In this mode, you can edit courses. -HelpText=&UP; &DOWN; change line &LEFT; &RIGHT; change value START to open sub-menu +ExplanationText=In this mode, you can edit courses.::For lines marked with "START", press the START button::to accept the action or open a sub-menu. +HelpText=&UP; &DOWN; change line &LEFT; &RIGHT; change value [ScreenSystemLayer] StatsX=632 @@ -2246,13 +2246,13 @@ Row4Y=230 Arrows1X=190 Arrows2X=590 EntryBannerX=490 -EntryBannerY=130 +EntryBannerY=110 EntryBannerWidth=130 EntryBannerHeight=40 EntryTextBannerX=320 -EntryTextBannerY=130 +EntryTextBannerY=110 CourseBannerX=490 -CourseBannerY=90 +CourseBannerY=70 CourseBannerWidth=130 CourseBannerHeight=40 RowLabelsX=20 @@ -2263,13 +2263,15 @@ RowValue4X=380 RowValue5X=380 RowValue6X=380 RowValue7X=380 -Row1Y=90 -Row2Y=140 -Row3Y=180 -Row4Y=220 -Row5Y=260 -Row6Y=300 -Row7Y=340 +RowValue8X=380 +Row1Y=70 +Row2Y=120 +Row3Y=160 +Row4Y=200 +Row5Y=240 +Row6Y=280 +Row7Y=320 +Row8Y=360 [ScreenOptionsMenu] HelpText=&UP; &DOWN; to change line then press START diff --git a/stepmania/src/Course.h b/stepmania/src/Course.h index 191c81b690..ee484f78c9 100644 --- a/stepmania/src/Course.h +++ b/stepmania/src/Course.h @@ -42,7 +42,9 @@ inline CString CourseEntryTypeToString( CourseEntryType cet ) } } -struct CourseEntry { +class CourseEntry +{ +public: CourseEntryType type; bool mystery; // show "??????" Song* pSong; // used in type=fixed diff --git a/stepmania/src/EditCoursesMenu.cpp b/stepmania/src/EditCoursesMenu.cpp index 68cf0ac156..0eed727574 100644 --- a/stepmania/src/EditCoursesMenu.cpp +++ b/stepmania/src/EditCoursesMenu.cpp @@ -19,6 +19,8 @@ #include "Steps.h" #include "song.h" #include "Course.h" +#include "ScreenMiniMenu.h" +#include "ScreenManager.h" // // Defines specific to EditCoursesMenu @@ -40,13 +42,45 @@ #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 ScreenMessage SM_BackFromCourseOptionsMenu = (ScreenMessage)(SM_User+1); +const ScreenMessage SM_BackFromCourseEntryOptionsMenu = (ScreenMessage)(SM_User+2); + +Menu g_CourseOptionsMenu +( + "Course Options", + MenuRow( "Repeat", true, 0, "NO","YES" ), + MenuRow( "Randomize", true, 0, "NO","YES" ), + MenuRow( "Lives", true, 4, "Use Bar Life","1","2","3","4","5","6","7","8","9","10" ) +); + +enum CourseEntryOptionsMenuRow +{ + song, + group, + difficulty, + low_meter, + high_meter, + best_worst_value +}; + +Menu g_CourseEntryOptionsMenu +( + "Course Entry Options", + MenuRow( "Song", true, 0 ), + MenuRow( "Group", true, 0 ), + MenuRow( "Difficulty", true, 0 ), + MenuRow( "Low Meter", true, 0 ), + MenuRow( "High Meter", true, 0 ), + MenuRow( "Best/Worst value",true, 0 ) +); -const int MAX_EDIT_COURSES_ENTRIES = 100; EditCoursesMenu::EditCoursesMenu() { LOG->Trace( "ScreenEditCoursesMenu::ScreenEditCoursesMenu()" ); + GAMESTATE->m_bEditing = true; + int i; for( i=0; i<2; i++ ) @@ -74,7 +108,7 @@ EditCoursesMenu::EditCoursesMenu() 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 ); + m_textValue[i].SetZoom( 0.6f ); this->AddChild( &m_textValue[i] ); } @@ -90,6 +124,8 @@ EditCoursesMenu::EditCoursesMenu() m_soundChangeRow.Load( THEME->GetPathToS("EditCoursesMenu row") ); m_soundChangeValue.Load( THEME->GetPathToS("EditCoursesMenu value") ); + m_soundStart.Load( THEME->GetPathToS("Common start") ); + m_soundInvalid.Load( THEME->GetPathToS("Common invalid") ); // fill in data structures @@ -130,10 +166,11 @@ bool EditCoursesMenu::CanGoRight() { m_pCourses.size(), 1, - 1, - MAX_EDIT_COURSES_ENTRIES, + NUM_ACTIONS, + (int)GetSelectedCourse()->m_entries.size(), NUM_COURSE_ENTRY_TYPES, 1, + 1, 1 }; @@ -145,7 +182,7 @@ void EditCoursesMenu::Up() if( CanGoUp() ) { ChangeToRow( Row(m_SelectedRow-1) ); - m_soundChangeRow.PlayRandom(); + m_soundChangeRow.Play(); } } @@ -154,7 +191,7 @@ void EditCoursesMenu::Down() if( CanGoDown() ) { ChangeToRow( Row(m_SelectedRow+1) ); - m_soundChangeRow.PlayRandom(); + m_soundChangeRow.Play(); } } @@ -163,8 +200,16 @@ void EditCoursesMenu::Left() if( CanGoLeft() ) { m_iSelection[m_SelectedRow]--; + + switch( m_SelectedRow ) + { + case ROW_ENTRY_TYPE: + GetSelectedEntry()->type = GetSelectedEntryType(); + break; + } + OnRowValueChanged( m_SelectedRow ); - m_soundChangeValue.PlayRandom(); + m_soundChangeValue.Play(); } } @@ -173,8 +218,70 @@ void EditCoursesMenu::Right() if( CanGoRight() ) { m_iSelection[m_SelectedRow]++; + + switch( m_SelectedRow ) + { + case ROW_ENTRY_TYPE: + GetSelectedEntry()->type = GetSelectedEntryType(); + break; + } + OnRowValueChanged( m_SelectedRow ); - m_soundChangeValue.PlayRandom(); + m_soundChangeValue.Play(); + } +} + +void EditCoursesMenu::Start() +{ + switch( m_SelectedRow ) + { + case ROW_COURSE_OPTIONS: + SCREENMAN->MiniMenu( &g_CourseOptionsMenu, SM_BackFromCourseOptionsMenu ); + break; + case ROW_ACTION: + m_soundStart.Play(); + break; + case ROW_ENTRY_OPTIONS: + { + // update enabled/disabled lines + for( int i=0; itype ) + { + case COURSE_ENTRY_FIXED: + g_CourseEntryOptionsMenu.rows[song].enabled = true; + break; + case COURSE_ENTRY_RANDOM: + g_CourseEntryOptionsMenu.rows[low_meter].enabled = true; + g_CourseEntryOptionsMenu.rows[high_meter].enabled = true; + break; + case COURSE_ENTRY_RANDOM_WITHIN_GROUP: + g_CourseEntryOptionsMenu.rows[group].enabled = true; + g_CourseEntryOptionsMenu.rows[low_meter].enabled = true; + g_CourseEntryOptionsMenu.rows[high_meter].enabled = true; + break; + case COURSE_ENTRY_BEST: + g_CourseEntryOptionsMenu.rows[best_worst_value].enabled = true; + break; + case COURSE_ENTRY_WORST: + g_CourseEntryOptionsMenu.rows[best_worst_value].enabled = true; + break; + default: + ASSERT(0); + break; + } + SCREENMAN->MiniMenu( &g_CourseEntryOptionsMenu, SM_BackFromCourseEntryOptionsMenu ); + } + break; + case ROW_ENTRY_PLAYER_OPTIONS: + SCREENMAN->AddNewScreenToTop( "ScreenPlayerOptions" ); + break; + case ROW_ENTRY_SONG_OPTIONS: + SCREENMAN->AddNewScreenToTop( "ScreenSongOptions" ); + break; + default: + m_soundInvalid.Play(); + return; } } @@ -199,9 +306,7 @@ void EditCoursesMenu::OnRowValueChanged( Row row ) 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]]; + CourseEntry* pEntry = GetSelectedEntry(); switch( row ) { @@ -211,44 +316,44 @@ void EditCoursesMenu::OnRowValueChanged( Row row ) m_CourseBanner.ScaleToClipped( COURSE_BANNER_WIDTH, COURSE_BANNER_HEIGHT ); m_iSelection[ROW_ENTRY] = 0; // fall through - case ROW_SAVE: - m_textValue[ROW_SAVE].SetText( "(press START)" ); - // fall through case ROW_COURSE_OPTIONS: m_textValue[ROW_COURSE_OPTIONS].SetText( ssprintf( - "%s, %s, %d lives", + "(START) %s, %s, %d lives", pCourse->m_bRepeat ? "repeat" : "no repeat", pCourse->m_bRandomize ? "randomize" : "no randomize", pCourse->m_iLives ) ); // fall through + case ROW_ACTION: + m_textValue[ROW_ACTION].SetText( "(START) " + ActionToString(GetSelectedAction()) ); + // fall through case ROW_ENTRY: - m_textValue[ROW_ENTRY].SetText( ssprintf("%d",m_iSelection[ROW_ENTRY]+1) ); + m_textValue[ROW_ENTRY].SetText( ssprintf("%d of %d",m_iSelection[ROW_ENTRY]+1, (int)GetSelectedCourse()->m_entries.size()) ); // fall through case ROW_ENTRY_TYPE: m_textValue[ROW_ENTRY_TYPE].SetText( pEntry ? CourseEntryTypeToString(pEntry->type) : "(none)" ); // fall through case ROW_ENTRY_OPTIONS: { - CString s; + CString s = "(START) "; if( pEntry ) { switch( pEntry->type ) { case COURSE_ENTRY_FIXED: - s = pEntry->pSong ? "missing song" : pEntry->pSong->GetFullTranslitTitle(); + s += pEntry->pSong ? "(missing song)" : pEntry->pSong->GetFullTranslitTitle(); break; case COURSE_ENTRY_RANDOM: - s = "any group"; + s += "any group"; break; case COURSE_ENTRY_RANDOM_WITHIN_GROUP: - s = "group: " + pEntry->group_name; + s += "group: " + pEntry->group_name; break; case COURSE_ENTRY_BEST: - s = ssprintf( "best - %d", pEntry->players_index+1 ); + s += ssprintf( "rank %d", pEntry->players_index+1 ); break; case COURSE_ENTRY_WORST: - s = ssprintf( "worst - %d", pEntry->players_index+1 ); + s += ssprintf( "rank %d", pEntry->players_index+1 ); break; default: ASSERT(0); @@ -263,24 +368,52 @@ void EditCoursesMenu::OnRowValueChanged( Row row ) m_textValue[ROW_ENTRY_OPTIONS].SetText( s ); } // fall through - case ROW_ENTRY_MODIFIERS: + case ROW_ENTRY_PLAYER_OPTIONS: { - CString s; + CString s = "(START) "; if( pEntry ) { - s = pEntry->modifiers; - if( s.empty() ) - s = "(none)"; + if( pEntry->modifiers.empty() ) + s += "(none)"; + else + s += pEntry->modifiers; } else { s = "n/a"; } - m_textValue[ROW_ENTRY_MODIFIERS].SetText( s ); + m_textValue[ROW_ENTRY_PLAYER_OPTIONS].SetText( s ); + } + // fall through + case ROW_ENTRY_SONG_OPTIONS: + { + CString s = "(START) "; + if( pEntry ) + { + if( pEntry->modifiers.empty() ) + s += "(none)"; + else + s += pEntry->modifiers; + } + else + { + s = "n/a"; + } + + m_textValue[ROW_ENTRY_SONG_OPTIONS].SetText( s ); } break; default: ASSERT(0); // invalid row } } + +CourseEntry* EditCoursesMenu::GetSelectedEntry() +{ + Course* pCourse = GetSelectedCourse(); + if( m_iSelection[ROW_ENTRY] < pCourse->m_entries.size() ) + return &pCourse->m_entries[m_iSelection[ROW_ENTRY]]; + else + return NULL; +} diff --git a/stepmania/src/EditCoursesMenu.h b/stepmania/src/EditCoursesMenu.h index 541cf3dd84..4d291a2c84 100644 --- a/stepmania/src/EditCoursesMenu.h +++ b/stepmania/src/EditCoursesMenu.h @@ -17,7 +17,8 @@ #include "TextBanner.h" #include "GameConstantsAndTypes.h" #include "DifficultyMeter.h" -#include "RandomSample.h" +#include "RageSound.h" +#include "Course.h" class EditCoursesMenu: public ActorFrame @@ -36,16 +37,18 @@ public: void Down(); void Left(); void Right(); + void Start(); enum Row { ROW_COURSE, - ROW_SAVE, ROW_COURSE_OPTIONS, + ROW_ACTION, ROW_ENTRY, ROW_ENTRY_TYPE, ROW_ENTRY_OPTIONS, - ROW_ENTRY_MODIFIERS, + ROW_ENTRY_PLAYER_OPTIONS, + ROW_ENTRY_SONG_OPTIONS, NUM_ROWS } m_SelectedRow; CString RowToString( Row r ) @@ -53,17 +56,39 @@ public: const CString s[NUM_ROWS] = { "Course", - "Save", "Course Options", + "Action", "Entry", "Entry Type", "Entry Options", - "Entry Modifiers" + "Entry Player Options", + "Entry Song Options" }; return s[r]; } - Course* GetSelectedCourse() { return m_pCourses[m_iSelection[ROW_COURSE]]; } + enum Action + { + save, + add_entry, + delete_selected_entry, + NUM_ACTIONS + }; + CString ActionToString( Action a ) + { + switch( a ) + { + case save: return "Save Current Course"; + case add_entry: return "Add Entry"; + case delete_selected_entry: return "Delete Selected Entry"; + default: ASSERT(0); return ""; + } + } + + Course* GetSelectedCourse() { return m_pCourses[m_iSelection[ROW_COURSE]]; } + CourseEntry* GetSelectedEntry(); + Action GetSelectedAction() { return (Action)m_iSelection[ROW_ACTION]; } + CourseEntryType GetSelectedEntryType() { return (CourseEntryType)m_iSelection[ROW_ENTRY_TYPE]; } private: Sprite m_sprArrows[2]; @@ -81,8 +106,10 @@ private: void OnRowValueChanged( Row row ); void ChangeToRow( Row newRow ); - RandomSample m_soundChangeRow; - RandomSample m_soundChangeValue; + RageSound m_soundChangeRow; + RageSound m_soundChangeValue; + RageSound m_soundStart; + RageSound m_soundInvalid; }; #endif diff --git a/stepmania/src/ScreenEditCoursesMenu.cpp b/stepmania/src/ScreenEditCoursesMenu.cpp index ae43927cf3..4542482162 100644 --- a/stepmania/src/ScreenEditCoursesMenu.cpp +++ b/stepmania/src/ScreenEditCoursesMenu.cpp @@ -125,7 +125,7 @@ void ScreenEditCoursesMenu::MenuStart( PlayerNumber pn ) if( m_Menu.IsTransitioning() ) return; - Course* pCourse = m_Selector.GetSelectedCourse(); + m_Selector.Start(); } void ScreenEditCoursesMenu::MenuBack( PlayerNumber pn ) diff --git a/stepmania/src/ScreenPlayerOptions.cpp b/stepmania/src/ScreenPlayerOptions.cpp index 5f7396fde6..96c5bf974e 100644 --- a/stepmania/src/ScreenPlayerOptions.cpp +++ b/stepmania/src/ScreenPlayerOptions.cpp @@ -106,13 +106,17 @@ void ScreenPlayerOptions::ImportOptions() { // fill in difficulty names m_OptionRow[PO_STEP].choices.clear(); - if( GAMESTATE->m_pCurCourse ) // playing a course + if( GAMESTATE->m_bEditing ) + { + m_OptionRow[PO_STEP].choices.push_back( "" ); + } + else if( GAMESTATE->m_pCurCourse ) // playing a course { m_OptionRow[PO_STEP].choices.push_back( "REGULAR" ); if( GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) ) m_OptionRow[PO_STEP].choices.push_back( "DIFFICULT" ); } - else + else if( GAMESTATE->m_pCurSong ) // playing a song { vector vNotes; GAMESTATE->m_pCurSong->GetSteps( vNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType ); @@ -219,7 +223,12 @@ void ScreenPlayerOptions::ImportOptions() m_iSelectedOption[p][PO_HOLD_NOTES] = po.m_bHoldNotes ? 1 : 0; m_iSelectedOption[p][PO_DARK] = po.m_fDark ? 1 : 0; - if( GAMESTATE->m_pCurCourse ) // playing a course + + if( GAMESTATE->m_bEditing ) + { + m_iSelectedOption[p][PO_STEP] = 0; + } + else if( GAMESTATE->m_pCurCourse ) // playing a course { if( GAMESTATE->m_bDifficultCourses && GAMESTATE->m_pCurCourse->HasDifficult( GAMESTATE->GetCurrentStyleDef()->m_StepsType ) ) @@ -227,7 +236,7 @@ void ScreenPlayerOptions::ImportOptions() else m_iSelectedOption[p][PO_STEP] = 0; } - else + else if( GAMESTATE->m_pCurSong ) // playing a song { vector vNotes; GAMESTATE->m_pCurSong->GetSteps( vNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType );