void SongUtil::SortSongPointerArrayBySectionName( vector<Song*> &arraySongPointers, SortOrder 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" + MakeSortString(val); song_sort_val[arraySongPointers[i]] = val; } stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueAscending ); song_sort_val.clear(); }
/* This is for internal use, not display; sorting by Unicode codepoints isn't very * interesting for display. */ void SongUtil::SortSongPointerArrayByDisplayArtist( vector<Song*> &arraySongPointers ) { for( unsigned i = 0; i < arraySongPointers.size(); ++i ) song_sort_val[arraySongPointers[i]] = MakeSortString( arraySongPointers[i]->GetDisplayArtist() ); stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueAscending ); }
CString SongUtil::GetSectionNameFromSongAndSort( const Song* pSong, SortOrder 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; DisplayBpms bpms; pSong->GetDisplayBpms( bpms ); int iMaxBPM = (int)bpms.GetMax(); iMaxBPM += iBPMGroupSize - (iMaxBPM%iBPMGroupSize) - 1; return ssprintf("%03d-%03d",iMaxBPM-(iBPMGroupSize-1), iMaxBPM); } case SORT_MOST_PLAYED: return ""; case SORT_GRADE: { int iCounts[NUM_GRADES]; PROFILEMAN->GetMachineProfile()->GetGrades( pSong, GAMESTATE->GetCurrentStyle()->m_StepsType, iCounts ); for( int i=GRADE_TIER_1; i<NUM_GRADES; ++i ) { Grade g = (Grade)i; if( iCounts[i] > 0 ) return ssprintf( "%4s x %d", GradeToThemedString(g).c_str(), iCounts[i] ); } return GradeToThemedString( GRADE_NO_DATA ); } case SORT_EASY_METER: { Steps* pSteps = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyle()->m_StepsType,DIFFICULTY_EASY); if( pSteps ) return ssprintf("%02d", pSteps->GetMeter() ); return "N/A"; } case SORT_MEDIUM_METER: { Steps* pSteps = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyle()->m_StepsType,DIFFICULTY_MEDIUM); if( pSteps ) return ssprintf("%02d", pSteps->GetMeter() ); return "N/A"; } case SORT_HARD_METER: { Steps* pSteps = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyle()->m_StepsType,DIFFICULTY_HARD); if( pSteps ) return ssprintf("%02d", pSteps->GetMeter() ); return "N/A"; } case SORT_CHALLENGE_METER: { Steps* pSteps = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyle()->m_StepsType,DIFFICULTY_CHALLENGE); if( pSteps ) return ssprintf("%02d", pSteps->GetMeter() ); return "N/A"; } case SORT_SORT_MENU: case SORT_MODE_MENU: return ""; case SORT_ALL_COURSES: case SORT_NONSTOP_COURSES: case SORT_ONI_COURSES: case SORT_ENDLESS_COURSES: default: ASSERT(0); return ""; } }
/* This is for internal use, not display; sorting by Unicode codepoints isn't very * interesting for display. */ void SongUtil::SortSongPointerArrayByDisplayArtist( vector<Song*> &vpSongsInOut ) { for( unsigned i = 0; i < vpSongsInOut.size(); ++i ) song_sort_val[vpSongsInOut[i]] = MakeSortString( vpSongsInOut[i]->GetDisplayArtist() ); stable_sort( vpSongsInOut.begin(), vpSongsInOut.end(), CompareSongPointersBySortValueAscending ); }