From 6edf835853f5302b48c3aa9ad75910b54d792f4c Mon Sep 17 00:00:00 2001 From: Chris Danford Date: Mon, 16 Jun 2003 20:23:07 +0000 Subject: [PATCH] add sort by Artist, Top Grade --- stepmania/src/GameConstantsAndTypes.cpp | 23 +++-- stepmania/src/GameConstantsAndTypes.h | 2 + stepmania/src/Grade.h | 2 +- stepmania/src/MusicSortDisplay.cpp | 14 +-- stepmania/src/MusicWheel.cpp | 125 ++++++++++++++---------- stepmania/src/MusicWheelItem.cpp | 4 +- stepmania/src/Song.cpp | 77 +++++++++++++-- stepmania/src/StepMania.dsp | 23 +---- stepmania/src/song.h | 4 +- 9 files changed, 170 insertions(+), 104 deletions(-) diff --git a/stepmania/src/GameConstantsAndTypes.cpp b/stepmania/src/GameConstantsAndTypes.cpp index 6a13574478..0c45da9e2e 100644 --- a/stepmania/src/GameConstantsAndTypes.cpp +++ b/stepmania/src/GameConstantsAndTypes.cpp @@ -110,14 +110,17 @@ CString CoinModeToString( CoinMode cm ) CString SongSortOrderToString( SongSortOrder so ) { - CString s[NUM_SORT_ORDERS] = { - "PREFERRED", - "GROUP", - "TITLE", - "BPM", - "MOST PLAYED", - "SORT" - "ROULETTE" - }; - return s[so]; + switch( so ) + { + case SORT_PREFERRED: return "PREFERRED"; + case SORT_GROUP: return "GROUP"; + case SORT_TITLE: return "TITLE"; + case SORT_BPM: return "BPM"; + case SORT_MOST_PLAYED: return "PLAYERS BEST"; + case SORT_GRADE: return "TOP GRADE"; + case SORT_ARTIST: return "ARTIST"; + default: + ASSERT(0); + return ""; + } } diff --git a/stepmania/src/GameConstantsAndTypes.h b/stepmania/src/GameConstantsAndTypes.h index fc285f46da..f0ae850818 100644 --- a/stepmania/src/GameConstantsAndTypes.h +++ b/stepmania/src/GameConstantsAndTypes.h @@ -108,6 +108,8 @@ enum SongSortOrder { SORT_TITLE, SORT_BPM, SORT_MOST_PLAYED, + SORT_GRADE, + SORT_ARTIST, SORT_SORT, SORT_ROULETTE, NUM_SORT_ORDERS, diff --git a/stepmania/src/Grade.h b/stepmania/src/Grade.h index efaf2be314..43f0102115 100644 --- a/stepmania/src/Grade.h +++ b/stepmania/src/Grade.h @@ -15,7 +15,7 @@ enum Grade { GRADE_NO_DATA=0, GRADE_E, GRADE_D, GRADE_C, GRADE_B, GRADE_A, - GRADE_AA,GRADE_AAA,GRADE_AAAA }; + GRADE_AA,GRADE_AAA,GRADE_AAAA, NUM_GRADES }; CString GradeToString( Grade g ); Grade StringToGrade( const CString &s ); diff --git a/stepmania/src/MusicSortDisplay.cpp b/stepmania/src/MusicSortDisplay.cpp index f6f460bd92..ce9654f518 100644 --- a/stepmania/src/MusicSortDisplay.cpp +++ b/stepmania/src/MusicSortDisplay.cpp @@ -27,17 +27,5 @@ MusicSortDisplay::MusicSortDisplay() void MusicSortDisplay::Set( SongSortOrder so ) { - switch( so ) - { - case SORT_PREFERRED: - case SORT_GROUP: - case SORT_TITLE: - case SORT_BPM: - case SORT_MOST_PLAYED: - case SORT_SORT: - SetState( so ); - break; - default: - ASSERT(0); // unimplemented MusicSortOrder - } + SetState( so ); } diff --git a/stepmania/src/MusicWheel.cpp b/stepmania/src/MusicWheel.cpp index 6ff1834d21..74d07ffc71 100644 --- a/stepmania/src/MusicWheel.cpp +++ b/stepmania/src/MusicWheel.cpp @@ -316,24 +316,25 @@ void MusicWheel::GetSongList(vector &arraySongs, SongSortOrder so, CStrin } } -struct CompareSongPointerArrayBySectionName -{ - SongSortOrder so; - CompareSongPointerArrayBySectionName( SongSortOrder so_ ): so(so_) { } - bool operator() (const Song *p1, const Song *p2) const - { - CString sec1 = MusicWheel::GetSectionNameFromSongAndSort( p1, so ); - CString sec2 = MusicWheel::GetSectionNameFromSongAndSort( p2, so ); - /* In the TITLE sort, make sure NUM comes first and OTHER comes last. */ - - if(so == SORT_TITLE && sec1 == "NUM" && sec2 != "NUM") return true; - if(so == SORT_TITLE && sec1 != "NUM" && sec2 == "NUM") return false; - if(so == SORT_TITLE && sec1 != "OTHER" && sec2 == "OTHER") return true; - if(so == SORT_TITLE && sec1 == "OTHER" && sec2 != "OTHER") return false; - - return sec1 < sec2; - } -}; +// +//struct CompareSongPointerArrayBySectionName +//{ +// SongSortOrder so; +// CompareSongPointerArrayBySectionName( SongSortOrder so_ ): so(so_) { } +// bool operator() (const Song *p1, const Song *p2) const +// { +// CString sec1 = MusicWheel::GetSectionNameFromSongAndSort( p1, so ); +// CString sec2 = MusicWheel::GetSectionNameFromSongAndSort( p2, so ); +// +// /* In the TITLE sort, make sure NUM comes first and OTHER comes last. */ +// if(so == SORT_TITLE && sec1 == "NUM" && sec2 != "NUM") return true; +// if(so == SORT_TITLE && sec1 != "NUM" && sec2 == "NUM") return false; +// if(so == SORT_TITLE && sec1 != "OTHER" && sec2 == "OTHER") return true; +// if(so == SORT_TITLE && sec1 == "OTHER" && sec2 != "OTHER") return false; +// +// return sec1 < sec2; +// } +//}; void MusicWheel::BuildWheelItemDatas( vector &arrayWheelItemDatas, SongSortOrder so ) { @@ -384,6 +385,12 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelItemDatas if( arraySongs.size() > 30 ) arraySongs.erase(arraySongs.begin()+30, arraySongs.end()); break; + case SORT_GRADE: + SortSongPointerArrayByGrade( arraySongs ); + break; + case SORT_ARTIST: + SortSongPointerArrayByArtist( arraySongs ); + break; default: ASSERT(0); // unhandled SortOrder } @@ -398,10 +405,12 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelItemDatas switch( so ) { case SORT_PREFERRED: bUseSections = false; break; - case SORT_MOST_PLAYED: bUseSections = false; break; - case SORT_BPM: bUseSections = true; break; case SORT_GROUP: bUseSections = GAMESTATE->m_sPreferredGroup == GROUP_ALL_MUSIC; break; case SORT_TITLE: bUseSections = true; break; + case SORT_BPM: bUseSections = true; break; + case SORT_MOST_PLAYED: bUseSections = false; break; + case SORT_GRADE: bUseSections = true; break; + case SORT_ARTIST: bUseSections = true; break; case SORT_ROULETTE: bUseSections = false; break; default: ASSERT( 0 ); } @@ -411,10 +420,12 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelItemDatas if( bUseSections ) { - /* We're using sections, so use the section name as the top-level - * sort. */ - stable_sort(arraySongs.begin(), arraySongs.end(), - CompareSongPointerArrayBySectionName(so)); + // Sorting twice isn't necessary. Instead, modify the compatator functions + // in Song.cpp to have the desired effect. -Chris +// /* We're using sections, so use the section name as the top-level +// * sort. */ +// stable_sort(arraySongs.begin(), arraySongs.end(), +// CompareSongPointerArrayBySectionName(so)); // make WheelItemDatas with sections CString sLastSection = ""; @@ -749,6 +760,8 @@ void MusicWheel::Update( float fDeltaTime ) case SORT_GROUP: case SORT_TITLE: case SORT_BPM: + case SORT_GRADE: + case SORT_ARTIST: case SORT_MOST_PLAYED: case SORT_ROULETTE: // Look for the last selected song or course @@ -1228,36 +1241,33 @@ CString MusicWheel::GetSectionNameFromSongAndSort( const Song* pSong, SongSortOr if( pSong == NULL ) return ""; - CString sTemp; - switch( so ) { + case SORT_PREFERRED: + return ""; case SORT_GROUP: - sTemp = pSong->m_sGroupName; - return sTemp; -// case SORT_ARTIST: -// sTemp = pSong->m_sArtist; -// sTemp.MakeUpper(); -// sTemp = (sTemp.GetLength() > 0) ? sTemp.Left(1) : ""; -// if( IsAnInt(sTemp) ) -// sTemp = "NUM"; -// return sTemp; + return pSong->m_sGroupName; case SORT_TITLE: - sTemp = pSong->GetTranslitMainTitle(); - sTemp.MakeUpper(); - if(sTemp.empty()) return ""; - - /* If it starts with a number, or a decimal point followed by a number, - * sort it in NUM. */ - if( sTemp[0] >= '0' && sTemp[0] <= '9' ) - return "NUM"; - else if( sTemp.size() > 1 && sTemp[0] == '.' && sTemp[1] >= '0' && sTemp[1] <= '9' ) - return "NUM"; - else if(toupper(sTemp[0]) < 'A' || toupper(sTemp[0]) > 'Z') - return "OTHER"; - - sTemp = sTemp[0]; - return sTemp; + case SORT_ARTIST: + { + CString s; + switch( so ) + { + case SORT_TITLE: s = pSong->GetTranslitMainTitle(); break; + case SORT_ARTIST: s = pSong->m_sArtist; 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; @@ -1268,7 +1278,22 @@ CString MusicWheel::GetSectionNameFromSongAndSort( const Song* pSong, SongSortOr 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_SORT: + return ""; default: + ASSERT(0); return ""; } } diff --git a/stepmania/src/MusicWheelItem.cpp b/stepmania/src/MusicWheelItem.cpp index 6858268709..5cc32d4620 100644 --- a/stepmania/src/MusicWheelItem.cpp +++ b/stepmania/src/MusicWheelItem.cpp @@ -129,7 +129,7 @@ void MusicWheelItem::LoadFromWheelItemData( WheelItemData* pWID ) case TYPE_SORT: { CString sDisplayName; - BitmapText *bt; + BitmapText *bt = NULL; switch( pWID->m_Type ) { case TYPE_SECTION: @@ -144,6 +144,8 @@ void MusicWheelItem::LoadFromWheelItemData( WheelItemData* pWID ) sDisplayName = SongSortOrderToString(data->m_SongSortOrder); bt = &m_textSort; break; + default: + ASSERT(0); } bt->SetZoom( 1 ); diff --git a/stepmania/src/Song.cpp b/stepmania/src/Song.cpp index 92ecc18044..19d69240cc 100644 --- a/stepmania/src/Song.cpp +++ b/stepmania/src/Song.cpp @@ -1082,14 +1082,38 @@ bool Song::HasEdits( NotesType nt ) const // Sorting ///////////////////////////////////// +CString MakeSortString( CString s ) +{ + s.MakeUpper(); + + // Make sure that non-alphanumeric characters are placed at the very end + if( s.size()>0 ) + { + if( s[0] == '.' ) // ".59" + s.erase(s.begin()); + if( s[0] < 'A' || s[0] > 'Z' ) + if( s[0] < '0' && s[0] > '9' ) + s = char(126) + s; // prepend with a high ASCII character + } + + return s; +} + bool CompareSongPointersByTitle(const Song *pSong1, const Song *pSong2) { // Prefer transliterations to full titles - int ret = pSong1->GetTranslitMainTitle().CompareNoCase(pSong2->GetTranslitMainTitle()); - if(ret < 0) return true; - if(ret > 0) return false; + CString s1 = pSong1->GetTranslitMainTitle(); + CString s2 = pSong2->GetTranslitMainTitle(); + if( s1 == s2 ) + { + s1 = pSong1->GetTranslitSubTitle(); + s2 = pSong2->GetTranslitSubTitle(); + } - ret = pSong1->GetTranslitSubTitle().CompareNoCase(pSong2->GetTranslitSubTitle()); + s1 = MakeSortString(s1); + s2 = MakeSortString(s2); + + int ret = s1.CompareNoCase( s2 ); if(ret < 0) return true; if(ret > 0) return false; @@ -1184,14 +1208,40 @@ void SortSongPointerArrayByBPM( vector &arraySongPointers ) } +bool CompareSongPointersByGrade(const Song *pSong1, const Song *pSong2) +{ + for( int i=NUM_GRADES; i>GRADE_NO_DATA; i-- ) + { + Grade g = (Grade)i; + int iCount1 = pSong1->GetNumNotesWithGrade( g ); + int iCount2 = pSong2->GetNumNotesWithGrade( g ); + + if( iCount1 > iCount2 ) + return true; + if( iCount1 < iCount2 ) + return false; + } + + return CompareSongPointersByTitle( pSong1, pSong2 ); +} + +void SortSongPointerArrayByGrade( vector &arraySongPointers ) +{ + sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersByGrade ); +} + + int CompareSongPointersByArtist(const Song *pSong1, const Song *pSong2) { - CString sArtist1 = pSong1->m_sArtist; - CString sArtist2 = pSong2->m_sArtist; + CString s1 = pSong1->m_sArtist; + CString s2 = pSong2->m_sArtist; - if( sArtist1 < sArtist2 ) + s1 = MakeSortString(s1); + s2 = MakeSortString(s2); + + if( s1 < s2 ) return true; - if( sArtist1 > sArtist2 ) + if( s1 > s2 ) return false; return CompareSongPointersByTitle( pSong1, pSong2 ); } @@ -1441,3 +1491,14 @@ void Song::RemoveNotes( Notes* pNotes ) AddAutoGenNotes(); } + +int Song::GetNumNotesWithGrade( Grade g ) const +{ + int iCount = 0; + vector vNotes; + this->GetNotes( vNotes, GAMESTATE->GetCurrentStyleDef()->m_NotesType ); + for( unsigned j=0; jm_MemCardScores[MEMORY_CARD_MACHINE].grade == g ) + iCount++; + return iCount; +} diff --git a/stepmania/src/StepMania.dsp b/stepmania/src/StepMania.dsp index b8d92bc630..6d5918b730 100644 --- a/stepmania/src/StepMania.dsp +++ b/stepmania/src/StepMania.dsp @@ -64,7 +64,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 @@ -104,7 +104,7 @@ IntDir=.\StepMania___Xbox_Debug___VC6 TargetDir=.\StepMania___Xbox_Debug___VC6 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 @@ -144,7 +144,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 @@ -3731,23 +3731,6 @@ SOURCE=.\ScreenPlayerOptions.h # End Source File # Begin Source File -SOURCE=.\ScreenPlayerOptions2.cpp - -!IF "$(CFG)" == "StepMania - Win32 Debug" - -!ELSEIF "$(CFG)" == "StepMania - Xbox Debug" - -!ELSEIF "$(CFG)" == "StepMania - Win32 Release" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=.\ScreenPlayerOptions2.h -# End Source File -# Begin Source File - SOURCE=.\ScreenPrompt.cpp !IF "$(CFG)" == "StepMania - Win32 Debug" diff --git a/stepmania/src/song.h b/stepmania/src/song.h index b26d5480ad..36ce0442ab 100644 --- a/stepmania/src/song.h +++ b/stepmania/src/song.h @@ -255,15 +255,17 @@ public: Grade GetGradeForDifficulty( const StyleDef *s, PlayerNumber pn, Difficulty dc ) const; bool NormallyDisplayed() const; bool RouletteDisplayed() const; + int GetNumNotesWithGrade( Grade g ) const; void AddNotes( Notes* pNotes ); // we are responsible for deleting the memory pointed to by pNotes! void RemoveNotes( Notes* pNotes ); }; - +CString MakeSortString( CString s ); void SortSongPointerArrayByDifficulty( vector &arraySongPointers ); void SortSongPointerArrayByTitle( vector &arraySongPointers ); void SortSongPointerArrayByBPM( vector &arraySongPointers ); +void SortSongPointerArrayByGrade( vector &arraySongPointers ); void SortSongPointerArrayByArtist( vector &arraySongPointers ); void SortSongPointerArrayByGroupAndDifficulty( vector &arraySongPointers ); void SortSongPointerArrayByGroupAndTitle( vector &arraySongPointers );