add sort by Artist, Top Grade
This commit is contained in:
@@ -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 "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,8 @@ enum SongSortOrder {
|
||||
SORT_TITLE,
|
||||
SORT_BPM,
|
||||
SORT_MOST_PLAYED,
|
||||
SORT_GRADE,
|
||||
SORT_ARTIST,
|
||||
SORT_SORT,
|
||||
SORT_ROULETTE,
|
||||
NUM_SORT_ORDERS,
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -316,24 +316,25 @@ void MusicWheel::GetSongList(vector<Song*> &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<WheelItemData> &arrayWheelItemDatas, SongSortOrder so )
|
||||
{
|
||||
@@ -384,6 +385,12 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &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<WheelItemData> &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<WheelItemData> &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 "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
+69
-8
@@ -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<Song*> &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<Song*> &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<Notes*> vNotes;
|
||||
this->GetNotes( vNotes, GAMESTATE->GetCurrentStyleDef()->m_NotesType );
|
||||
for( unsigned j=0; j<vNotes.size(); j++ )
|
||||
if( vNotes[j]->m_MemCardScores[MEMORY_CARD_MACHINE].grade == g )
|
||||
iCount++;
|
||||
return iCount;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<Song*> &arraySongPointers );
|
||||
void SortSongPointerArrayByTitle( vector<Song*> &arraySongPointers );
|
||||
void SortSongPointerArrayByBPM( vector<Song*> &arraySongPointers );
|
||||
void SortSongPointerArrayByGrade( vector<Song*> &arraySongPointers );
|
||||
void SortSongPointerArrayByArtist( vector<Song*> &arraySongPointers );
|
||||
void SortSongPointerArrayByGroupAndDifficulty( vector<Song*> &arraySongPointers );
|
||||
void SortSongPointerArrayByGroupAndTitle( vector<Song*> &arraySongPointers );
|
||||
|
||||
Reference in New Issue
Block a user