diff --git a/stepmania/src/Course.cpp b/stepmania/src/Course.cpp index c48985cdc0..48d6bb9581 100644 --- a/stepmania/src/Course.cpp +++ b/stepmania/src/Course.cpp @@ -1018,16 +1018,20 @@ int Course::GetNumTimesPlayed( MemoryCard card ) const static map course_sort_val; -bool CompareCoursePointersBySortVal(const Course *pSong1, const Course *pSong2) +bool CompareCoursePointersBySortValueAscending(const Course *pSong1, const Course *pSong2) { return course_sort_val[pSong1] < course_sort_val[pSong2]; } +bool CompareCoursePointersBySortValueDescending(const Course *pSong1, const Course *pSong2) +{ + return course_sort_val[pSong1] > course_sort_val[pSong2]; +} + void SortCoursePointerArrayByMostPlayed( vector &arrayCoursePointers, MemoryCard card ) { for(unsigned i = 0; i < arrayCoursePointers.size(); ++i) course_sort_val[arrayCoursePointers[i]] = arrayCoursePointers[i]->GetNumTimesPlayed( card ); - stable_sort( arrayCoursePointers.begin(), arrayCoursePointers.end(), CompareCoursePointersBySortVal ); - reverse( arrayCoursePointers.begin(), arrayCoursePointers.end() ); + stable_sort( arrayCoursePointers.begin(), arrayCoursePointers.end(), CompareCoursePointersBySortValueDescending ); course_sort_val.clear(); } diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index 148881b2f7..f5a04fa321 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -362,26 +362,7 @@ void MusicWheel::GetSongList(vector &arraySongs, SongSortOrder so, CStrin } } -extern map song_sort_val; -bool CompareSongPointersBySortVal(const Song *pSong1, const Song *pSong2); -void MusicWheel::SortSongPointerArrayBySectionName( vector &arraySongPointers, SongSortOrder so ) -{ - for(unsigned i = 0; i < arraySongPointers.size(); ++i) - { - CString val = MusicWheel::GetSectionNameFromSongAndSort( arraySongPointers[i], so ); - - /* Make sure NUM comes first and OTHER comes last. */ - if( val == "NUM" ) val = "0"; - else if( val == "OTHER" ) val = "2"; - else val = "1" + val; - - song_sort_val[arraySongPointers[i]] = val; - } - - stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortVal ); - song_sort_val.clear(); -} void MusicWheel::BuildWheelItemDatas( vector &arrayWheelItemDatas, SongSortOrder so ) @@ -1408,93 +1389,6 @@ void MusicWheel::TweenOffScreen(bool changing_sort) m_fTimeLeftInState = GetTweenTimeLeft() + 0.100f; } -CString MusicWheel::GetSectionNameFromSongAndSort( const Song* pSong, SongSortOrder so ) -{ - if( pSong == NULL ) - return ""; - - switch( so ) - { - case SORT_PREFERRED: - return ""; - case SORT_GROUP: - return pSong->m_sGroupName; - case SORT_TITLE: - case SORT_ARTIST: - { - CString s; - switch( so ) - { - case SORT_TITLE: s = pSong->GetTranslitMainTitle(); break; - case SORT_ARTIST: s = pSong->GetTranslitArtist(); break; - default: ASSERT(0); - } - s = MakeSortString(s); // resulting string will be uppercase - - if( s.empty() ) - return ""; - else if( s[0] >= '0' && s[0] <= '9' ) - return "NUM"; - else if( s[0] < 'A' || s[0] > 'Z') - return "OTHER"; - else - return s.Left(1); - } - case SORT_BPM: - { - const int iBPMGroupSize = 20; - float fMinBPM, fMaxBPM; - pSong->GetDisplayBPM( fMinBPM, fMaxBPM ); - int iMaxBPM = (int)fMaxBPM; - iMaxBPM += iBPMGroupSize - (iMaxBPM%iBPMGroupSize) - 1; - return ssprintf("%03d-%03d",iMaxBPM-(iBPMGroupSize-1), iMaxBPM); - } - case SORT_MOST_PLAYED: - return ""; - case SORT_GRADE: - { - for( int i=NUM_GRADES; i>GRADE_NO_DATA; i-- ) - { - Grade g = (Grade)i; - int iCount = pSong->GetNumNotesWithGrade( g ); - if( iCount > 0 ) - return ssprintf( "%4s x %d", GradeToString(g).c_str(), iCount ); - } - return "NO DATA"; - } - case SORT_EASY_METER: - { - Steps* pNotes = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyleDef()->m_StepsType,DIFFICULTY_EASY); - if( pNotes ) - return ssprintf("%02d", pNotes->GetMeter() ); - return "N/A"; - } - case SORT_MEDIUM_METER: - { - Steps* pNotes = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyleDef()->m_StepsType,DIFFICULTY_MEDIUM); - if( pNotes ) - return ssprintf("%02d", pNotes->GetMeter() ); - return "N/A"; - } - case SORT_HARD_METER: - { - Steps* pNotes = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyleDef()->m_StepsType,DIFFICULTY_HARD); - if( pNotes ) - return ssprintf("%02d", pNotes->GetMeter() ); - return "N/A"; - } - case SORT_MENU: - return ""; - case SORT_ALL_COURSES: - case SORT_NONSTOP_COURSES: - case SORT_ONI_COURSES: - case SORT_ENDLESS_COURSES: - default: - ASSERT(0); - return ""; - } -} - void MusicWheel::Move(int n) { if(n == m_Moving) diff --git a/stepmania/src/MusicWheel.h b/stepmania/src/MusicWheel.h index 44b60bf595..943c4c132b 100644 --- a/stepmania/src/MusicWheel.h +++ b/stepmania/src/MusicWheel.h @@ -125,8 +125,6 @@ protected: RageSound m_soundStart; RageSound m_soundLocked; - static CString GetSectionNameFromSongAndSort( const Song* pSong, SongSortOrder so ); - static void SortSongPointerArrayBySectionName( vector &arraySongPointers, SongSortOrder so ); bool WheelItemIsVisible(int n); void UpdateScrollbar(); }; diff --git a/stepmania/src/ProfileManager.cpp b/stepmania/src/ProfileManager.cpp index 570dca79cf..f7607e913c 100644 --- a/stepmania/src/ProfileManager.cpp +++ b/stepmania/src/ProfileManager.cpp @@ -871,174 +871,279 @@ void ProfileManager::SaveStatsWebPageToDir( CString sDir, MemoryCard mc ) } // - // Make local song list + // Gather data // vector vpSongs = SONGMAN->GetAllSongs(); - SortSongPointerArrayByGroupAndTitle( vpSongs ); + vector vpAllSteps; + map mapStepsToSong; + { + for( unsigned i=0; i vpSteps = pSong->GetAllSteps(); + for( unsigned j=0; jIsAutogen() ) + continue; // skip + vpAllSteps.push_back( pSteps ); + mapStepsToSong[pSteps] = pSong; + } + } + } + vector vpCourses; + SONGMAN->GetAllCourses( vpCourses, false ); + + // + // Calculate which StepTypes to show + // + vector vStepsTypesToShow; + { + for( StepsType st=(StepsType)0; st vpSteps; + pSong->GetSteps( vpSteps, st, DIFFICULTY_INVALID, -1, -1, "", false ); + if( !vpSteps.empty() ) + { + bOneSongHasStepsForThisStepsType = true; + break; + } + } + + if( bOneSongHasStepsForThisStepsType ) + vStepsTypesToShow.push_back( st ); + } + } // // print HTML headers // - f.PutLine( "" ); - f.PutLine( "" ); - f.PutLine( "" ); - f.PutLine( ssprintf("%s", PRODUCT_NAME_VER) ); - f.PutLine( "" ); - f.PutLine( "" ); - f.PutLine( "" ); + { + f.PutLine( "" ); + f.PutLine( "" ); + f.PutLine( "" ); + f.PutLine( ssprintf("%s", PRODUCT_NAME_VER) ); + f.PutLine( "" ); + f.PutLine( "" ); + f.PutLine( "" ); + } + +#define PRINT_SECTION_START(szName) f.Write( ssprintf("

"szName" (top)

\n", szName) ) +#define PRINT_SECTION_END f.Write( "\n" ) +#define PRINT_DIV_START(szName) f.Write( ssprintf("
\n" "

%s

\n", szName) ) +#define PRINT_DIV_START_ANCHOR(uAnchor,szName) f.Write( ssprintf("
\n" "

%s

\n", uAnchor, szName) ) +#define PRINT_DIV_END f.Write( "
\n" ) +#define PRINT_DIV2_START(szName) f.Write( ssprintf("
\n" "

%s

\n", szName) ) +#define PRINT_DIV2_START_ANCHOR(uAnchor,szName) f.Write( ssprintf("
\n" "

%s

\n", uAnchor, szName) ) +#define PRINT_DIV2_END f.Write( "
\n" ) +#define PRINT_LINK(szName,szLink) f.Write( ssprintf("

%s

\n",szLink,szName) ) +#define PRINT_LINE_S(szName,sVal) f.Write( ssprintf("

%s = %s

\n",szName,sVal.c_str()) ) +#define PRINT_LINE_B(szName,bVal) f.Write( ssprintf("

%s = %s

\n",szName,(bVal)?"yes":"no") ) +#define PRINT_LINE_I(szName,iVal) f.Write( ssprintf("

%s = %d

\n",szName,iVal) ) +#define PRINT_LINE_RANK(iRank,sName,iVal) f.Write( ssprintf("

%d - %s (%d)

\n",iRank,sName.c_str(),iVal) ) -#define PRINT_LINK(szName,szLink) f.Write( ssprintf("

%s

\n",szLink,szName) ) -#define PRINT_LINE_S(szName,sVal) f.Write( ssprintf("

%s = %s

\n",szName,sVal.c_str()) ) -#define PRINT_LINE_B(szName,bVal) f.Write( ssprintf("

%s = %s

\n",szName,(bVal)?"yes":"no") ) -#define PRINT_LINE_I(szName,iVal) f.Write( ssprintf("

%s = %d

\n",szName,iVal) ) // // Print table of contents // - f.PutLine( "

Table of Contents

\n" ); - f.PutLine( "
\n" ); - f.PutLine( "

Sections

\n" ); - PRINT_LINK( "My Statistics", "#My Statistics" ); - PRINT_LINK( "Difficulty Table", "#Difficulty Table" ); - PRINT_LINK( "Song/Steps List", "#Song/Steps List" ); - f.PutLine( "
\n" ); - - + { + PRINT_SECTION_START( "Table of Contents" ); + PRINT_DIV_START("Sections"); + PRINT_LINK( "My Statistics", "#My Statistics" ); + PRINT_LINK( "Popularity Lists", "#Popularity Lists" ); + PRINT_LINK( "Difficulty Table", "#Difficulty Table" ); + PRINT_LINK( "Song/Steps List", "#Song/Steps List" ); + PRINT_DIV_END; + PRINT_SECTION_END; + } // // Print My Statistics // - f.PutLine( "

My Statistics (top)

\n" ); - f.PutLine( "
\n" ); - CString sName = pProfile->m_sLastUsedHighScoreName.empty() ? - pProfile->m_sName : - pProfile->m_sLastUsedHighScoreName; - f.PutLine( ssprintf("

%s

\n",sName.c_str()) ); - PRINT_LINE_S( "LastUsedHighScoreName", pProfile->m_sLastUsedHighScoreName ); - PRINT_LINE_B( "UsingProfileDefaultModifiers", pProfile->m_bUsingProfileDefaultModifiers ); - PRINT_LINE_S( "DefaultModifiers", pProfile->m_sDefaultModifiers ); - PRINT_LINE_I( "TotalPlays", pProfile->m_iTotalPlays ); - PRINT_LINE_I( "TotalPlaySeconds", pProfile->m_iTotalPlaySeconds ); - PRINT_LINE_I( "TotalGameplaySeconds", pProfile->m_iTotalGameplaySeconds ); - PRINT_LINE_I( "CurrentCombo", pProfile->m_iCurrentCombo ); - f.PutLine( "
\n" ); + { + PRINT_SECTION_START( "My Statistics" ); + CString sName = pProfile->m_sLastUsedHighScoreName.empty() ? + pProfile->m_sName : + pProfile->m_sLastUsedHighScoreName; + PRINT_DIV_START( sName.c_str() ); + PRINT_LINE_S( "LastUsedHighScoreName", pProfile->m_sLastUsedHighScoreName ); + PRINT_LINE_B( "UsingProfileDefaultModifiers", pProfile->m_bUsingProfileDefaultModifiers ); + PRINT_LINE_S( "DefaultModifiers", pProfile->m_sDefaultModifiers ); + PRINT_LINE_I( "TotalPlays", pProfile->m_iTotalPlays ); + PRINT_LINE_I( "TotalPlaySeconds", pProfile->m_iTotalPlaySeconds ); + PRINT_LINE_I( "TotalGameplaySeconds", pProfile->m_iTotalGameplaySeconds ); + PRINT_LINE_I( "CurrentCombo", pProfile->m_iCurrentCombo ); + PRINT_DIV_END; + PRINT_SECTION_END; + } + + // + // Print Popularity Lists + // + { + PRINT_SECTION_START( "Popularity Lists" ); + + // Songs by popularity + { + unsigned uNumToShow = min( vpSongs.size(), (unsigned)100 ); + + SortSongPointerArrayByMostPlayed( vpSongs, mc ); + PRINT_DIV_START( "Songs by Popularity" ); + for( unsigned i=0; iGetFullDisplayTitle(), pSong->GetNumTimesPlayed(mc) ); + } + PRINT_DIV_END; + } + + // Steps by popularity + { + unsigned uNumToShow = min( vpAllSteps.size(), (unsigned)100 ); + + SortStepsPointerArrayByMostPlayed( vpAllSteps, mc ); + PRINT_DIV_START( "Steps by Popularity" ); + for( unsigned i=0; iGetFullDisplayTitle(); + s += " - "; + s += GAMEMAN->NotesTypeToString(pSteps->m_StepsType); + s += " "; + s += DifficultyToString(pSteps->GetDifficulty()); + PRINT_LINE_RANK( i+1, s, pSteps->GetNumTimesPlayed(mc) ); + } + PRINT_DIV_END; + } + + // Course by popularity + { + unsigned uNumToShow = min( vpCourses.size(), (unsigned)100 ); + + SortCoursePointerArrayByMostPlayed( vpCourses, mc ); + PRINT_DIV_START( "Courses by Popularity" ); + for( unsigned i=0; im_sName, pCourse->GetNumTimesPlayed(mc) ); + } + PRINT_DIV_END; + } + PRINT_SECTION_END; + } // // Print Difficulty tables // - f.PutLine( "

Difficulty Table (top)

\n" ); - for( StepsType st=(StepsType)0; st vpSteps; - pSong->GetSteps( vpSteps, st, DIFFICULTY_INVALID, -1, -1, "", false ); - if( !vpSteps.empty() ) + StepsType st = vStepsTypesToShow[s]; + + unsigned i; + + PRINT_DIV_START( GAMEMAN->NotesTypeToString(st).c_str() ); + f.PutLine( "\n" ); + + // table header row + f.Write( "" ); + for( unsigned k=0; k%s", Capitalize(DifficultyToString(d).Left(3)).c_str()) ); } - } - - if( !bOneSongHasStepsForThisStepsType ) - continue; // don't print this table + f.PutLine( "" ); - f.PutLine( "
\n" ); - f.PutLine( ssprintf("

%s

\n", GAMEMAN->NotesTypeToString(st).c_str()) ); - f.PutLine( "
 
\n" ); - - // table header row - f.Write( "" ); - for( unsigned k=0; k%s", Capitalize(DifficultyToString(d).Left(3)).c_str()) ); - } - f.PutLine( "" ); - - // table body rows - for( i=0; i" ); - - f.Write( ssprintf("", - pSong, // use pointer value as the hash - pSong->GetFullDisplayTitle().c_str()) ); - - for( Difficulty dc=(Difficulty)0; dcGetStepsByDifficulty( st, dc, false ); - if( pSteps ) - f.PutLine( ssprintf("", - pSteps, // use pointer value as the hash - pSteps->GetMeter()) ); - else - f.PutLine( "" ); + Song* pSong = vpSongs[i]; + + f.PutLine( "" ); + + f.Write( ssprintf("", + pSong, // use pointer value as the hash + pSong->GetFullDisplayTitle().c_str()) ); + + for( Difficulty dc=(Difficulty)0; dcGetStepsByDifficulty( st, dc, false ); + if( pSteps ) + f.PutLine( ssprintf("", + pSteps, // use pointer value as the hash + pSteps->GetMeter()) ); + else + f.PutLine( "" ); + } + + f.Write( "" ); } - f.Write( "" ); + f.PutLine( "
 
%s

%d

 
%s

%d

 
\n" ); + PRINT_DIV_END; } - - f.PutLine( "\n" ); - f.PutLine( "
\n" ); + PRINT_SECTION_END; } - // // Print song list // - f.PutLine( "

Song/Steps List (top)

\n" ); - for( unsigned i=0; i vpSteps = pSong->GetAllSteps(); - - /* XXX: We can't call pSong->HasBanner on every song; it'll effectively re-traverse the entire - * song directory tree checking if each banner file really exists. - * - * (Note for testing this: remember that we'll cache directories for a time; this is only slow if - * the directory cache expires before we get here.) */ - /* Don't print the song banner anyway since this is going on the memory card. -Chris */ - //CString sImagePath = pSong->HasBanner() ? pSong->GetBannerPath() : (pSong->HasBackground() ? pSong->GetBackgroundPath() : "" ); - f.PutLine( "
\n" ); - f.PutLine( ssprintf("

%s

\n", - pSong, // use pointer value as the hash - pSong->GetFullDisplayTitle().c_str()) ); - PRINT_LINE_S( "Artist", pSong->GetDisplayArtist() ); - PRINT_LINE_S( "GroupName", pSong->m_sGroupName ); - float fMinBPM, fMaxBPM; - pSong->GetDisplayBPM( fMinBPM, fMaxBPM ); - CString sBPM = (fMinBPM==fMaxBPM) ? ssprintf("%.1f",fMinBPM) : ssprintf("%.1f - %.1f",fMinBPM,fMaxBPM); - PRINT_LINE_S( "BPM", sBPM ); - PRINT_LINE_I( "NumTimesPlayed", pSong->GetNumTimesPlayed(mc) ); - PRINT_LINE_S( "Credit", pSong->m_sCredit ); - PRINT_LINE_S( "MusicLength", SecondsToTime(pSong->m_fMusicLengthSeconds) ); - PRINT_LINE_B( "Lyrics", !pSong->m_sLyricsFile.empty() ); - f.PutLine( "
\n" ); - - // - // Print Steps list - // - for( unsigned j=0; jIsAutogen() ) - continue; // skip autogen - f.PutLine( "
\n" ); - f.PutLine( ssprintf("

%s - %s

\n", - pSteps, // use pointer value as the hash - GAMEMAN->NotesTypeToString(pSteps->m_StepsType).c_str(), - DifficultyToString(pSteps->GetDifficulty()).c_str()) ); - PRINT_LINE_I( "NumTimesPlayed", pSteps->m_MemCardDatas[mc].iNumTimesPlayed ); - f.PutLine( "
\n" ); - } + Song* pSong = vpSongs[i]; + vector vpSteps = pSong->GetAllSteps(); + /* XXX: We can't call pSong->HasBanner on every song; it'll effectively re-traverse the entire + * song directory tree checking if each banner file really exists. + * + * (Note for testing this: remember that we'll cache directories for a time; this is only slow if + * the directory cache expires before we get here.) */ + /* Don't print the song banner anyway since this is going on the memory card. -Chris */ + //CString sImagePath = pSong->HasBanner() ? pSong->GetBannerPath() : (pSong->HasBackground() ? pSong->GetBackgroundPath() : "" ); + PRINT_DIV_START_ANCHOR( /*Song primary key*/pSong, pSong->GetFullDisplayTitle().c_str() ); + PRINT_LINE_S( "Artist", pSong->GetDisplayArtist() ); + PRINT_LINE_S( "GroupName", pSong->m_sGroupName ); + float fMinBPM, fMaxBPM; + pSong->GetDisplayBPM( fMinBPM, fMaxBPM ); + CString sBPM = (fMinBPM==fMaxBPM) ? ssprintf("%.1f",fMinBPM) : ssprintf("%.1f - %.1f",fMinBPM,fMaxBPM); + PRINT_LINE_S( "BPM", sBPM ); + PRINT_LINE_I( "NumTimesPlayed", pSong->GetNumTimesPlayed(mc) ); + PRINT_LINE_S( "Credit", pSong->m_sCredit ); + PRINT_LINE_S( "MusicLength", SecondsToTime(pSong->m_fMusicLengthSeconds) ); + PRINT_LINE_B( "Lyrics", !pSong->m_sLyricsFile.empty() ); + PRINT_DIV_END; + + // + // Print Steps list + // + for( unsigned j=0; jIsAutogen() ) + continue; // skip autogen + f.PutLine( "
\n" ); + CString s = + GAMEMAN->NotesTypeToString(pSteps->m_StepsType) + + " - " + + DifficultyToString(pSteps->GetDifficulty()); + PRINT_DIV2_START_ANCHOR( /*Steps primary key*/pSteps, s.c_str() ); // use pointer value as the hash + PRINT_LINE_I( "NumTimesPlayed", pSteps->m_MemCardDatas[mc].iNumTimesPlayed ); + f.PutLine( "
\n" ); + PRINT_DIV2_END; + } + } + PRINT_SECTION_END; } f.PutLine( "" ); diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 9c4ac9c277..07876349ec 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -1468,17 +1468,126 @@ void SortSongPointerArrayByGroupAndTitle( vector &arraySongPointers ) * it. (This could be generalized with a template.) */ map song_sort_val; -bool CompareSongPointersBySortVal(const Song *pSong1, const Song *pSong2) +bool CompareSongPointersBySortValueAscending(const Song *pSong1, const Song *pSong2) { return song_sort_val[pSong1] < song_sort_val[pSong2]; } +bool CompareSongPointersBySortValueDescending(const Song *pSong1, const Song *pSong2) +{ + return song_sort_val[pSong1] > song_sort_val[pSong2]; +} + void SortSongPointerArrayByMostPlayed( vector &arraySongPointers, MemoryCard card ) { for(unsigned i = 0; i < arraySongPointers.size(); ++i) song_sort_val[arraySongPointers[i]] = ssprintf("%9i", arraySongPointers[i]->GetNumTimesPlayed(card)); - stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortVal ); - reverse( arraySongPointers.begin(), arraySongPointers.end() ); + stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueDescending ); + song_sort_val.clear(); +} + +CString GetSectionNameFromSongAndSort( const Song* pSong, SongSortOrder so ) +{ + if( pSong == NULL ) + return ""; + + switch( so ) + { + case SORT_PREFERRED: + return ""; + case SORT_GROUP: + return pSong->m_sGroupName; + case SORT_TITLE: + case SORT_ARTIST: + { + CString s; + switch( so ) + { + case SORT_TITLE: s = pSong->GetTranslitMainTitle(); break; + case SORT_ARTIST: s = pSong->GetTranslitArtist(); break; + default: ASSERT(0); + } + s = MakeSortString(s); // resulting string will be uppercase + + if( s.empty() ) + return ""; + else if( s[0] >= '0' && s[0] <= '9' ) + return "NUM"; + else if( s[0] < 'A' || s[0] > 'Z') + return "OTHER"; + else + return s.Left(1); + } + case SORT_BPM: + { + const int iBPMGroupSize = 20; + float fMinBPM, fMaxBPM; + pSong->GetDisplayBPM( fMinBPM, fMaxBPM ); + int iMaxBPM = (int)fMaxBPM; + iMaxBPM += iBPMGroupSize - (iMaxBPM%iBPMGroupSize) - 1; + return ssprintf("%03d-%03d",iMaxBPM-(iBPMGroupSize-1), iMaxBPM); + } + case SORT_MOST_PLAYED: + return ""; + case SORT_GRADE: + { + for( int i=NUM_GRADES; i>GRADE_NO_DATA; i-- ) + { + Grade g = (Grade)i; + int iCount = pSong->GetNumNotesWithGrade( g ); + if( iCount > 0 ) + return ssprintf( "%4s x %d", GradeToString(g).c_str(), iCount ); + } + return "NO DATA"; + } + case SORT_EASY_METER: + { + Steps* pNotes = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyleDef()->m_StepsType,DIFFICULTY_EASY); + if( pNotes ) + return ssprintf("%02d", pNotes->GetMeter() ); + return "N/A"; + } + case SORT_MEDIUM_METER: + { + Steps* pNotes = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyleDef()->m_StepsType,DIFFICULTY_MEDIUM); + if( pNotes ) + return ssprintf("%02d", pNotes->GetMeter() ); + return "N/A"; + } + case SORT_HARD_METER: + { + Steps* pNotes = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyleDef()->m_StepsType,DIFFICULTY_HARD); + if( pNotes ) + return ssprintf("%02d", pNotes->GetMeter() ); + return "N/A"; + } + case SORT_MENU: + return ""; + case SORT_ALL_COURSES: + case SORT_NONSTOP_COURSES: + case SORT_ONI_COURSES: + case SORT_ENDLESS_COURSES: + default: + ASSERT(0); + return ""; + } +} + +void SortSongPointerArrayBySectionName( vector &arraySongPointers, SongSortOrder so ) +{ + for(unsigned i = 0; i < arraySongPointers.size(); ++i) + { + CString val = GetSectionNameFromSongAndSort( arraySongPointers[i], so ); + + /* Make sure NUM comes first and OTHER comes last. */ + if( val == "NUM" ) val = "0"; + else if( val == "OTHER" ) val = "2"; + else val = "1" + val; + + song_sort_val[arraySongPointers[i]] = val; + } + + stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueAscending ); song_sort_val.clear(); } diff --git a/stepmania/src/Steps.cpp b/stepmania/src/Steps.cpp index 0d9fb25a70..4692b5cbe7 100644 --- a/stepmania/src/Steps.cpp +++ b/stepmania/src/Steps.cpp @@ -280,6 +280,25 @@ void Steps::SetRadarValue(int r, float val) // // Sorting stuff // +map steps_sort_val; + +bool CompareStepsPointersBySortValueAscending(const Steps *pSteps1, const Steps *pSteps2) +{ + return steps_sort_val[pSteps1] < steps_sort_val[pSteps2]; +} + +bool CompareStepsPointersBySortValueDescending(const Steps *pSteps1, const Steps *pSteps2) +{ + return steps_sort_val[pSteps1] > steps_sort_val[pSteps2]; +} + +void SortStepsPointerArrayByMostPlayed( vector &vStepsPointers, MemoryCard card ) +{ + for(unsigned i = 0; i < vStepsPointers.size(); ++i) + steps_sort_val[vStepsPointers[i]] = ssprintf("%9i", vStepsPointers[i]->GetNumTimesPlayed(card)); + stable_sort( vStepsPointers.begin(), vStepsPointers.end(), CompareStepsPointersBySortValueDescending ); + steps_sort_val.clear(); +} bool CompareNotesPointersByRadarValues(const Steps* pNotes1, const Steps* pNotes2) { diff --git a/stepmania/src/Steps.h b/stepmania/src/Steps.h index 1746f2df21..7ab4feed0d 100644 --- a/stepmania/src/Steps.h +++ b/stepmania/src/Steps.h @@ -137,5 +137,6 @@ bool CompareNotesPointersByDifficulty(const Steps *pNotes1, const Steps *pNotes2 void SortNotesArrayByDifficulty( vector &arrayNotess ); bool CompareStepsPointersByTypeAndDifficulty(const Steps *pStep1, const Steps *pStep2); void SortStepsByTypeAndDifficulty( vector &arraySongPointers ); +void SortStepsPointerArrayByMostPlayed( vector &vStepsPointers, MemoryCard card ); #endif diff --git a/stepmania/src/song.h b/stepmania/src/song.h index e21bab8fd8..0d6a953e0f 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -273,6 +273,8 @@ void SortSongPointerArrayByGroupAndDifficulty( vector &arraySongPointers void SortSongPointerArrayByGroupAndTitle( vector &arraySongPointers ); void SortSongPointerArrayByMostPlayed( vector &arraySongPointers, MemoryCard card ); void SortSongPointerArrayByMeter( vector &arraySongPointers, Difficulty dc ); +CString GetSectionNameFromSongAndSort( const Song* pSong, SongSortOrder so ); +void SortSongPointerArrayBySectionName( vector &arraySongPointers, SongSortOrder so );