move Song/Steps sorting into Song/StepsUtil.h/cpp

This commit is contained in:
Chris Danford
2004-04-18 07:34:37 +00:00
parent ad9e710766
commit 1920634135
21 changed files with 119 additions and 480 deletions
+2 -1
View File
@@ -9,6 +9,7 @@
#include "BitmapText.h"
#include "SongManager.h"
#include "ThemeManager.h"
#include "StepsUtil.h"
#define ITEMS_SPACING_Y THEME->GetMetricF(m_sName,"ItemsSpacingY")
#define DESCRIPTION_MAX_WIDTH THEME->GetMetricF(m_sName,"DescriptionMaxWidth")
@@ -289,7 +290,7 @@ void DifficultyList::SetFromGameState()
song->GetSteps( CurSteps, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
/* Should match the sort in ScreenSelectMusic::AfterMusicChange. */
SortNotesArrayByDifficulty( CurSteps );
StepsUtil::SortNotesArrayByDifficulty( CurSteps );
unsigned i;
for( i = 0; i < m_Rows.size(); ++i )
+2 -1
View File
@@ -59,7 +59,8 @@ NotesLoaderSM.cpp NotesLoaderSM.h NotesWriterDWI.cpp NotesWriterDWI.h NotesWrite
PlayerAI.cpp PlayerAI.h PlayerNumber.cpp PlayerNumber.h PlayerOptions.cpp PlayerOptions.h Profile.cpp Profile.h \
ProfileHtml.cpp ProfileHtml.h RandomSample.cpp RandomSample.h ScoreKeeper.h ScoreKeeperMAX2.cpp ScoreKeeperMAX2.h \
ScoreKeeperRave.cpp ScoreKeeperRave.h Song.cpp song.h SongCacheIndex.cpp SongCacheIndex.h \
SongOptions.cpp SongOptions.h StageStats.cpp StageStats.h Steps.cpp Steps.h Style.h StyleDef.cpp StyleDef.h \
SongOptions.cpp SongOptions.h SongUtil.cpp SongUtil.h StageStats.cpp StageStats.h Steps.cpp Steps.h \
StepsUtil.cpp StepsUtil.h Style.h StyleDef.cpp StyleDef.h \
StyleInput.h TimeConstants.cpp TimeConstants.h TimingData.cpp TimingData.h TitleSubstitution.cpp TitleSubstitution.h
FileTypes = IniFile.cpp IniFile.h \
+14 -13
View File
@@ -32,6 +32,7 @@
#include "UnlockSystem.h"
#include "ModeChoice.h"
#include "ActorUtil.h"
#include "SongUtil.h"
#define FADE_SECONDS THEME->GetMetricF("MusicWheel","FadeSeconds")
@@ -486,18 +487,18 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
{
case SORT_PREFERRED:
case SORT_ROULETTE:
SortSongPointerArrayByGroupAndDifficulty( arraySongs );
SongUtil::SortSongPointerArrayByGroupAndDifficulty( arraySongs );
bUseSections = false;
break;
case SORT_GROUP:
SortSongPointerArrayByGroupAndTitle( arraySongs );
SongUtil::SortSongPointerArrayByGroupAndTitle( arraySongs );
bUseSections = GAMESTATE->m_sPreferredGroup == GROUP_ALL_MUSIC;
break;
case SORT_TITLE:
SortSongPointerArrayByTitle( arraySongs );
SongUtil::SortSongPointerArrayByTitle( arraySongs );
break;
case SORT_BPM:
SortSongPointerArrayByBPM( arraySongs );
SongUtil::SortSongPointerArrayByBPM( arraySongs );
break;
case SORT_MOST_PLAYED:
if( (int) arraySongs.size() > MOST_PLAYED_SONGS_TO_SHOW )
@@ -505,22 +506,22 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
bUseSections = false;
break;
case SORT_GRADE:
SortSongPointerArrayByGrade( arraySongs );
SongUtil::SortSongPointerArrayByGrade( arraySongs );
break;
case SORT_ARTIST:
SortSongPointerArrayByArtist( arraySongs );
SongUtil::SortSongPointerArrayByArtist( arraySongs );
break;
case SORT_EASY_METER:
SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_EASY );
SongUtil::SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_EASY );
break;
case SORT_MEDIUM_METER:
SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_MEDIUM );
SongUtil::SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_MEDIUM );
break;
case SORT_HARD_METER:
SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_HARD );
SongUtil::SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_HARD );
break;
case SORT_CHALLENGE_METER:
SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_CHALLENGE );
SongUtil::SortSongPointerArrayByMeter( arraySongs, DIFFICULTY_CHALLENGE );
break;
default:
ASSERT(0); // unhandled SortOrder
@@ -547,7 +548,7 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
// /* We're using sections, so use the section name as the top-level
// * sort. */
if( so != SORT_GRADE && so != SORT_BPM )
SortSongPointerArrayBySectionName(arraySongs, so);
SongUtil::SortSongPointerArrayBySectionName(arraySongs, so);
// make WheelItemDatas with sections
CString sLastSection = "";
@@ -555,7 +556,7 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
for( unsigned i=0; i< arraySongs.size(); i++ )
{
Song* pSong = arraySongs[i];
CString sThisSection = GetSectionNameFromSongAndSort( pSong, so );
CString sThisSection = SongUtil::GetSectionNameFromSongAndSort( pSong, so );
if( sThisSection != sLastSection) // new section, make a section item
{
@@ -908,7 +909,7 @@ void MusicWheel::Update( float fDeltaTime )
SCREENMAN->PostMessageToTopScreen( SM_SortOrderChanged, 0 );
SetOpenGroup(GetSectionNameFromSongAndSort( pPrevSelectedSong, GAMESTATE->m_SortOrder ));
SetOpenGroup(SongUtil::GetSectionNameFromSongAndSort( pPrevSelectedSong, GAMESTATE->m_SortOrder ));
m_iSelection = 0;
+2 -1
View File
@@ -9,6 +9,7 @@
#include "GameManager.h"
#include "RageException.h"
#include "RageFile.h"
#include "StepsUtil.h"
/* BMS encoding: tap-hold
4&8panel: Player1 Player2
@@ -724,7 +725,7 @@ void BMSLoader::SlideDuplicateDifficulties( Song &p )
vector<Steps*> vSteps;
p.GetSteps( vSteps, st, dc );
SortNotesArrayByDifficulty( vSteps );
StepsUtil::SortNotesArrayByDifficulty( vSteps );
for( unsigned k=1; k<vSteps.size(); k++ )
{
Steps* pSteps = vSteps[k];
+5 -3
View File
@@ -25,6 +25,8 @@
#include "CryptManager.h"
#include "UnlockSystem.h"
#include "RageUtil.h"
#include "SongUtil.h"
#include "StepsUtil.h"
const CString STATS_HTML = "Stats.html";
@@ -374,7 +376,7 @@ void PrintPopularity( RageFile &f, const Profile *pProfile, CString sTitle, vect
PRINT_OPEN(f, sTitle );
if( vpSongs.size() )
{
SortSongPointerArrayByNumPlays( vpSongs, pProfile, true );
SongUtil::SortSongPointerArrayByNumPlays( vpSongs, pProfile, true );
Song* pSongPopularThreshold = vpSongs[ vpSongs.size()*2/3 ];
int iPopularNumPlaysThreshold = pProfile->GetSongNumTimesPlayed(pSongPopularThreshold);
@@ -411,7 +413,7 @@ void PrintPopularity( RageFile &f, const Profile *pProfile, CString sTitle, vect
}
{
SortSongPointerArrayByNumPlays( vpSongs, pProfile, false );
SongUtil::SortSongPointerArrayByNumPlays( vpSongs, pProfile, false );
PRINT_OPEN(f, "Least Popular Songs" );
{
BEGIN_TABLE(1);
@@ -434,7 +436,7 @@ void PrintPopularity( RageFile &f, const Profile *pProfile, CString sTitle, vect
{
unsigned uNumToShow = min( vpAllSteps.size(), (unsigned)100 );
SortStepsPointerArrayByNumPlays( vpAllSteps, pProfile, true );
StepsUtil::SortStepsPointerArrayByNumPlays( vpAllSteps, pProfile, true );
PRINT_OPEN(f, "Most Popular Steps" );
{
BEGIN_TABLE(1);
+2 -1
View File
@@ -30,6 +30,7 @@
#include "ThemeManager.h"
#include "MemoryCardManager.h"
#include "XmlFile.h"
#include "StepsUtil.h"
ProfileManager* PROFILEMAN = NULL; // global and accessable from anywhere in our program
@@ -453,7 +454,7 @@ HighScore ProfileManager::GetHighScoreForDifficulty( const Song *s, const StyleD
// return max grade of notes in difficulty class
vector<Steps*> aNotes;
s->GetSteps( aNotes, st->m_StepsType );
SortNotesArrayByDifficulty( aNotes );
StepsUtil::SortNotesArrayByDifficulty( aNotes );
const Steps* pSteps = s->GetStepsByDifficulty( st->m_StepsType, dc );
+3 -2
View File
@@ -21,6 +21,8 @@
#include "Sprite.h"
#include "song.h"
#include "BitmapText.h"
#include "ActorUtil.h"
#include "SongUtil.h"
#define BACKGROUNDS_SPACING_X THEME->GetMetricF("ScreenCredits","BackgroundsSpacingX")
@@ -164,13 +166,12 @@ static const CreditLine CREDIT_LINES[] =
{1,"Join the StepMania team"},
{1,"and help us out!"},
};
#include "ActorUtil.h"
ScreenCredits::ScreenCredits( CString sName ) : ScreenAttract( sName )
{
vector<Song*> arraySongs;
SONGMAN->GetSongs( arraySongs );
SortSongPointerArrayByTitle( arraySongs );
SongUtil::SortSongPointerArrayByTitle( arraySongs );
// FIXME: Redo this screen with a BGA
m_ScrollerBackgrounds.SetName( "Backgrounds" );
+3 -1
View File
@@ -32,6 +32,8 @@
#include "NoteFieldPositioning.h"
#include "arch/arch.h"
#include "NoteDataUtil.h"
#include "SongUtil.h"
#include "StepsUtil.h"
const float RECORD_HOLD_SECONDS = 0.3f;
@@ -947,7 +949,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
GAMESTATE->m_pCurSong->GetSteps( vSteps, st );
// Sort them by difficulty.
SortStepsByTypeAndDifficulty( vSteps );
StepsUtil::SortStepsByTypeAndDifficulty( vSteps );
// Find out what index the current Steps are
vector<Steps*>::iterator it = find( vSteps.begin(), vSteps.end(), pNotes );
+2 -1
View File
@@ -25,6 +25,7 @@
#include "RageLog.h"
#include "StyleDef.h"
#include "GameManager.h"
#include "SongUtil.h"
#define SCROLL_DELAY THEME->GetMetricF("ScreenEnding","ScrollDelay")
@@ -66,7 +67,7 @@ ScreenEnding::ScreenEnding( CString sClassName ) : ScreenAttract( sClassName, fa
{
vector<Song*> arraySongs;
SONGMAN->GetSongs( arraySongs );
SortSongPointerArrayByTitle( arraySongs );
SongUtil::SortSongPointerArrayByTitle( arraySongs );
for( int p=0; p<NUM_PLAYERS; p++ )
{
+2 -1
View File
@@ -27,6 +27,7 @@
#include "RageTextureManager.h"
#include "AnnouncerManager.h"
#include "MenuTimer.h"
#include "StepsUtil.h"
#define SCROLLING_LIST_X THEME->GetMetricF("ScreenEz2SelectMusic","ScrollingListX")
#define SCROLLING_LIST_Y THEME->GetMetricF("ScreenEz2SelectMusic","ScrollingListY")
@@ -654,7 +655,7 @@ void ScreenEz2SelectMusic::MusicChanged()
for( pn = 0; pn < NUM_PLAYERS; ++pn)
{
pSong->GetSteps( m_arrayNotes[pn], GAMESTATE->GetCurrentStyleDef()->m_StepsType );
SortNotesArrayByDifficulty( m_arrayNotes[pn] );
StepsUtil::SortNotesArrayByDifficulty( m_arrayNotes[pn] );
}
for( pn=0; pn<NUM_PLAYERS; pn++ )
+2 -1
View File
@@ -18,6 +18,7 @@
#include "ThemeManager.h"
#include "AnnouncerManager.h"
#include "song.h"
#include "SongUtil.h"
#define SCROLL_DELAY THEME->GetMetricF("ScreenMusicScroll","ScrollDelay")
@@ -36,7 +37,7 @@ ScreenMusicScroll::ScreenMusicScroll( CString sClassName ) : ScreenAttract( sCla
{
vector<Song*> arraySongs;
SONGMAN->GetSongs( arraySongs );
SortSongPointerArrayByTitle( arraySongs );
SongUtil::SortSongPointerArrayByTitle( arraySongs );
unsigned i;
for( i=0; i < arraySongs.size(); i++ )
+2 -1
View File
@@ -20,6 +20,7 @@
#include "StepMania.h"
#include "RageSoundManager.h"
#include "ProfileManager.h"
#include "StepsUtil.h"
#define LINE_NAMES THEME->GetMetric (m_sName,"LineNames")
#define OPTION_MENU_FLAGS THEME->GetMetric (m_sName,"OptionMenuFlags")
@@ -128,7 +129,7 @@ void ScreenOptionsMaster::SetStep( OptionRowData &row, OptionRowHandler &hand )
{
vector<Steps*> vSteps;
GAMESTATE->m_pCurSong->GetSteps( vSteps, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
SortNotesArrayByDifficulty( vSteps );
StepsUtil::SortNotesArrayByDifficulty( vSteps );
for( unsigned i=0; i<vSteps.size(); i++ )
{
Steps* pSteps = vSteps[i];
+2 -1
View File
@@ -27,6 +27,7 @@
#include "GameState.h"
#include "UnlockSystem.h"
#include "MenuTimer.h"
#include "SongUtil.h"
#define BANNER_WIDTH THEME->GetMetricF("ScreenSelectGroup","BannerWidth")
#define BANNER_HEIGHT THEME->GetMetricF("ScreenSelectGroup","BannerHeight")
@@ -101,7 +102,7 @@ ScreenSelectGroup::ScreenSelectGroup( CString sClassName ) : Screen( sClassName
aSongsInGroup.push_back( aAllSongs[i] );
}
SortSongPointerArrayByTitle( aSongsInGroup );
SongUtil::SortSongPointerArrayByTitle( aSongsInGroup );
m_MusicList.AddGroup();
m_MusicList.AddSongsToGroup(aSongsInGroup);
+2 -1
View File
@@ -36,6 +36,7 @@
#include "MenuTimer.h"
#include "LightsManager.h"
#include "StageStats.h"
#include "StepsUtil.h"
const int NUM_SCORE_DIGITS = 9;
@@ -1329,7 +1330,7 @@ void ScreenSelectMusic::AfterMusicChange()
m_fSampleLengthSeconds = pSong->m_fMusicSampleLengthSeconds;
pSong->GetSteps( m_arrayNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
SortNotesArrayByDifficulty( m_arrayNotes );
StepsUtil::SortNotesArrayByDifficulty( m_arrayNotes );
if ( PREFSMAN->m_bShowBanners )
m_Banner.LoadFromSong( pSong );
+3 -336
View File
@@ -3,7 +3,7 @@
-----------------------------------------------------------------------------
Class: Song
Desc: Holds metadata for a song and the song's step data.
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
@@ -36,6 +36,7 @@
#include "SDL_utils.h"
#include "ProfileManager.h"
#include "StageStats.h"
#include "StepsUtil.h"
#include "NotesLoaderSM.h"
#include "NotesLoaderDWI.h"
@@ -458,7 +459,7 @@ void Song::AdjustDuplicateSteps()
DeleteDuplicateSteps( this, vSteps );
CHECKPOINT;
SortNotesArrayByDifficulty( vSteps );
StepsUtil::SortNotesArrayByDifficulty( vSteps );
CHECKPOINT;
for( unsigned k=1; k<vSteps.size(); k++ )
{
@@ -1195,340 +1196,6 @@ bool Song::HasEdits( StepsType nt ) const
return vpNotes.size() > 0;
}
/////////////////////////////////////
// Sorting
/////////////////////////////////////
/* Just calculating GetNumTimesPlayed within the sort is pretty slow, so let's precompute
* it. (This could be generalized with a template.) */
map<const Song*, CString> song_sort_val;
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];
}
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') && (s[0] < '0' || s[0] > '9') )
s = char(126) + s;
}
return s;
}
bool CompareSongPointersByTitle(const Song *pSong1, const Song *pSong2)
{
// Prefer transliterations to full titles
CString s1 = pSong1->GetTranslitMainTitle();
CString s2 = pSong2->GetTranslitMainTitle();
if( s1 == s2 )
{
s1 = pSong1->GetTranslitSubTitle();
s2 = pSong2->GetTranslitSubTitle();
}
s1 = MakeSortString(s1);
s2 = MakeSortString(s2);
int ret = s1.CompareNoCase( s2 );
if(ret < 0) return true;
if(ret > 0) return false;
/* The titles are the same. Ensure we get a consistent ordering
* by comparing the unique SongFilePaths. */
return pSong1->GetSongFilePath().CompareNoCase(pSong2->GetSongFilePath()) < 0;
}
void SortSongPointerArrayByTitle( vector<Song*> &arraySongPointers )
{
sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersByTitle );
}
static int GetSongSortDifficulty(const Song *pSong)
{
vector<Steps*> aNotes;
pSong->GetSteps( aNotes, GAMESTATE->GetCurrentStyleDef()->m_StepsType );
/* Sort by the first difficulty found in the following order: */
const Difficulty d[] = { DIFFICULTY_EASY, DIFFICULTY_MEDIUM, DIFFICULTY_HARD,
DIFFICULTY_CHALLENGE, DIFFICULTY_INVALID };
for(int i = 0; d[i] != DIFFICULTY_INVALID; ++i)
{
for( unsigned j = 0; j < aNotes.size(); ++j)
{
if(aNotes[j]->GetDifficulty() != d[i])
continue;
return aNotes[j]->GetMeter();
}
}
return 1;
}
void SortSongPointerArrayByDifficulty( vector<Song*> &arraySongPointers )
{
for( unsigned i = 0; i < arraySongPointers.size(); ++i )
song_sort_val[arraySongPointers[i]] =
ssprintf("%9i", GetSongSortDifficulty(arraySongPointers[i]));
stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueAscending );
}
bool CompareSongPointersByBPM(const Song *pSong1, const Song *pSong2)
{
float fMinBPM1, fMaxBPM1, fMinBPM2, fMaxBPM2;
pSong1->GetDisplayBPM( fMinBPM1, fMaxBPM1 );
pSong2->GetDisplayBPM( fMinBPM2, fMaxBPM2 );
if( fMaxBPM1 < fMaxBPM2 )
return true;
if( fMaxBPM1 > fMaxBPM2 )
return false;
return CompareCStringsAsc( pSong1->GetSongFilePath(), pSong2->GetSongFilePath() );
}
void SortSongPointerArrayByBPM( vector<Song*> &arraySongPointers )
{
sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersByBPM );
}
void AppendOctal( int n, int digits, CString &out )
{
for( int p = digits-1; p >= 0; --p )
{
const int shift = p*3;
int n2 = (n >> shift) & 0x7;
out.insert( out.end(), (char) (n2+'0') );
}
}
bool CompDescending( const pair<Song *, CString> &a, const pair<Song *, CString> &b )
{ return a.second > b.second; }
void SortSongPointerArrayByGrade( vector<Song*> &arraySongPointers )
{
/* Optimize by pre-writing a string to compare, since doing GetNumNotesWithGrade
* inside the sort is too slow. */
typedef pair< Song *, CString > val;
vector<val> vals;
vals.reserve( arraySongPointers.size() );
unsigned i;
for( i = 0; i < arraySongPointers.size(); ++i )
{
Song *pSong = arraySongPointers[i];
CString foo;
foo.reserve(256);
for( int g=GRADE_TIER_1; g<=GRADE_NO_DATA; ++g )
{
int n = pSong->GetNumNotesWithGrade( (Grade)g );
AppendOctal( n, 3, foo );
}
vals.push_back( val(pSong, foo) );
}
sort( vals.begin(), vals.end(), CompDescending );
for( i = 0; i < arraySongPointers.size(); ++i )
arraySongPointers[i] = vals[i].first;
}
void SortSongPointerArrayByArtist( vector<Song*> &arraySongPointers )
{
for( unsigned i = 0; i < arraySongPointers.size(); ++i )
song_sort_val[arraySongPointers[i]] = MakeSortString( arraySongPointers[i]->GetTranslitArtist() );
stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueAscending );
}
static int CompareSongPointersByGroup(const Song *pSong1, const Song *pSong2)
{
return pSong1->m_sGroupName < pSong2->m_sGroupName;
}
void SortSongPointerArrayByGroupAndDifficulty( vector<Song*> &arraySongPointers )
{
SortSongPointerArrayByDifficulty( arraySongPointers );
stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersByGroup );
}
int CompareSongPointersByGroupAndTitle(const Song *pSong1, const Song *pSong2)
{
const CString &sGroup1 = pSong1->m_sGroupName;
const CString &sGroup2 = pSong2->m_sGroupName;
if( sGroup1 < sGroup2 )
return true;
if( sGroup1 > sGroup2 )
return false;
/* Same group; compare by name. */
return CompareSongPointersByTitle( pSong1, pSong2 );
}
void SortSongPointerArrayByGroupAndTitle( vector<Song*> &arraySongPointers )
{
sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersByGroupAndTitle );
}
void SortSongPointerArrayByNumPlays( vector<Song*> &arraySongPointers, ProfileSlot slot, bool bDescending )
{
Profile* pProfile = PROFILEMAN->GetProfile(slot);
if( pProfile == NULL )
return; // nothing to do since we don't have data
SortSongPointerArrayByNumPlays( arraySongPointers, pProfile, bDescending );
}
void SortSongPointerArrayByNumPlays( vector<Song*> &arraySongPointers, const Profile* pProfile, bool bDescending )
{
ASSERT( pProfile );
for(unsigned i = 0; i < arraySongPointers.size(); ++i)
song_sort_val[arraySongPointers[i]] = ssprintf("%9i", pProfile->GetSongNumTimesPlayed(arraySongPointers[i]));
stable_sort( arraySongPointers.begin(), arraySongPointers.end(), bDescending ? CompareSongPointersBySortValueDescending : CompareSongPointersBySortValueAscending );
song_sort_val.clear();
}
CString 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;
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=GRADE_TIER_1; i<NUM_GRADES; ++i )
{
Grade g = (Grade)i;
int iCount = pSong->GetNumNotesWithGrade( g );
if( iCount > 0 )
return ssprintf( "%4s x %d", GradeToThemedString(g).c_str(), iCount );
}
return GradeToThemedString( GRADE_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_CHALLENGE_METER:
{
Steps* pNotes = pSong->GetStepsByDifficulty(GAMESTATE->GetCurrentStyleDef()->m_StepsType,DIFFICULTY_CHALLENGE);
if( pNotes )
return ssprintf("%02d", pNotes->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 "";
}
}
void 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" + val;
song_sort_val[arraySongPointers[i]] = val;
}
stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueAscending );
song_sort_val.clear();
}
void SortSongPointerArrayByMeter( vector<Song*> &arraySongPointers, Difficulty dc )
{
song_sort_val.clear();
for(unsigned i = 0; i < arraySongPointers.size(); ++i)
{
Steps* pNotes = arraySongPointers[i]->GetStepsByDifficulty( GAMESTATE->GetCurrentStyleDef()->m_StepsType, dc );
song_sort_val[arraySongPointers[i]] = ssprintf("%i", pNotes ? pNotes->GetMeter() : 0);
}
stable_sort( arraySongPointers.begin(), arraySongPointers.end(), CompareSongPointersBySortValueAscending );
}
Song::SelectionDisplay Song::GetDisplayed() const
{
if( !PREFSMAN->m_bHiddenSongs )
+7 -5
View File
@@ -33,6 +33,8 @@
#include "ProfileManager.h"
#include "MemoryCardManager.h"
#include "NotesLoaderSM.h"
#include "SongUtil.h"
#include "StepsUtil.h"
SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program
@@ -679,11 +681,11 @@ bool CompareNotesPointersForExtra(const Steps *n1, const Steps *n2)
if(d1 > d2) return false;
/* n1 difficulty == n2 difficulty */
if(CompareNotesPointersByMeter(n1,n2)) return true;
if(CompareNotesPointersByMeter(n2,n1)) return false;
if(StepsUtil::CompareNotesPointersByMeter(n1,n2)) return true;
if(StepsUtil::CompareNotesPointersByMeter(n2,n1)) return false;
/* n1 meter == n2 meter */
return CompareNotesPointersByRadarValues(n1,n2);
return StepsUtil::CompareNotesPointersByRadarValues(n1,n2);
}
void SongManager::GetExtraStageInfo( bool bExtra2, const StyleDef *sd,
@@ -904,7 +906,7 @@ void SongManager::UpdateBest()
Best.erase( Best.end()-1 );
}
SortSongPointerArrayByNumPlays( m_pBestSongs[i], (ProfileSlot) i, true );
SongUtil::SortSongPointerArrayByNumPlays( m_pBestSongs[i], (ProfileSlot) i, true );
m_pBestCourses[i] = m_pCourses;
SortCoursePointerArrayByNumPlays( m_pBestCourses[i], (ProfileSlot) i, true );
@@ -923,7 +925,7 @@ void SongManager::UpdateShuffled()
void SongManager::SortSongs()
{
SortSongPointerArrayByTitle( m_pSongs );
SongUtil::SortSongPointerArrayByTitle( m_pSongs );
}
void SongManager::UpdateRankingCourses()
+51 -5
View File
@@ -1,5 +1,5 @@
# Microsoft Developer Studio Project File - Name="StepMania" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# Microsoft Developer Studio Generated Build File, Format Version 60000
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
@@ -62,10 +62,10 @@ LINK32=link.exe
# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no /nodefaultlib
# Begin Special Build Tool
IntDir=.\../Debug6
TargetDir=\temp\stepmania\Program
TargetDir=\stepmania\stepmania\Program
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
# End Special Build Tool
@@ -99,6 +99,10 @@ XBCP=xbecopy.exe
# ADD BASE XBCP /NOLOGO
# ADD XBCP /NOLOGO
# Begin Special Build Tool
IntDir=.\../Debug_Xbox
TargetDir=\stepmania\stepmania
TargetName=default
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -135,10 +139,10 @@ LINK32=link.exe
# SUBTRACT LINK32 /verbose /pdb:none /debug
# Begin Special Build Tool
IntDir=.\../Release6
TargetDir=\temp\stepmania\Program
TargetDir=\stepmania\stepmania\Program
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
# End Special Build Tool
@@ -174,6 +178,10 @@ XBCP=xbecopy.exe
# ADD BASE XBCP /NOLOGO
# ADD XBCP /NOLOGO
# Begin Special Build Tool
IntDir=.\../Release_Xbox
TargetDir=\stepmania\stepmania
TargetName=default
SOURCE="$(InputPath)"
PreLink_Cmds=disasm\verinc cl /Zl /nologo /c PostBuild_Cmds=disasm\mapconv $(IntDir)\$(TargetName).map $(TargetDir)\StepMania.vdi ia32.vdi
# End Special Build Tool
@@ -1899,6 +1907,25 @@ SOURCE=.\SongOptions.h
# End Source File
# Begin Source File
SOURCE=.\SongUtil.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
!ELSEIF "$(CFG)" == "StepMania - Xbox Debug"
!ELSEIF "$(CFG)" == "StepMania - Win32 Release"
!ELSEIF "$(CFG)" == "StepMania - Xbox Release"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\SongUtil.h
# End Source File
# Begin Source File
SOURCE=.\StageStats.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
@@ -1937,6 +1964,25 @@ SOURCE=.\Steps.h
# End Source File
# Begin Source File
SOURCE=.\StepsUtil.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
!ELSEIF "$(CFG)" == "StepMania - Xbox Debug"
!ELSEIF "$(CFG)" == "StepMania - Win32 Release"
!ELSEIF "$(CFG)" == "StepMania - Xbox Release"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\StepsUtil.h
# End Source File
# Begin Source File
SOURCE=.\StyleDef.cpp
!IF "$(CFG)" == "StepMania - Win32 Debug"
+12
View File
@@ -803,6 +803,12 @@ cl /Zl /nologo /c verstub.cpp /Fo&quot;$(IntDir)&quot;\
<File
RelativePath="SongOptions.h">
</File>
<File
RelativePath="SongUtil.cpp">
</File>
<File
RelativePath="SongUtil.h">
</File>
<File
RelativePath="StageStats.cpp">
</File>
@@ -815,6 +821,12 @@ cl /Zl /nologo /c verstub.cpp /Fo&quot;$(IntDir)&quot;\
<File
RelativePath="Steps.h">
</File>
<File
RelativePath="StepsUtil.cpp">
</File>
<File
RelativePath="StepsUtil.h">
</File>
<File
RelativePath="Style.h">
</File>
-79
View File
@@ -304,82 +304,3 @@ void Steps::SetRadarValue(int r, float val)
}
//
// Sorting stuff
//
map<const Steps*, CString> 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 SortStepsPointerArrayByNumPlays( vector<Steps*> &vStepsPointers, ProfileSlot slot, bool bDescending )
{
Profile* pProfile = PROFILEMAN->GetProfile(slot);
if( pProfile == NULL )
return; // nothing to do since we don't have data
SortStepsPointerArrayByNumPlays( vStepsPointers, pProfile, bDescending );
}
void SortStepsPointerArrayByNumPlays( vector<Steps*> &vStepsPointers, const Profile* pProfile, bool bDecending )
{
ASSERT( pProfile );
for(unsigned i = 0; i < vStepsPointers.size(); ++i)
steps_sort_val[vStepsPointers[i]] = ssprintf("%9i", pProfile->GetStepsNumTimesPlayed(vStepsPointers[i]));
stable_sort( vStepsPointers.begin(), vStepsPointers.end(), bDecending ? CompareStepsPointersBySortValueDescending : CompareStepsPointersBySortValueAscending );
steps_sort_val.clear();
}
bool CompareNotesPointersByRadarValues(const Steps* pNotes1, const Steps* pNotes2)
{
float fScore1 = 0;
float fScore2 = 0;
for( int r=0; r<NUM_RADAR_CATEGORIES; r++ )
{
fScore1 += pNotes1->GetRadarValues()[r];
fScore2 += pNotes2->GetRadarValues()[r];
}
return fScore1 < fScore2;
}
bool CompareNotesPointersByMeter(const Steps *pNotes1, const Steps* pNotes2)
{
return pNotes1->GetMeter() < pNotes2->GetMeter();
}
bool CompareNotesPointersByDifficulty(const Steps *pNotes1, const Steps *pNotes2)
{
return pNotes1->GetDifficulty() < pNotes2->GetDifficulty();
}
void SortNotesArrayByDifficulty( vector<Steps*> &arraySteps )
{
/* Sort in reverse order of priority. */
stable_sort( arraySteps.begin(), arraySteps.end(), CompareNotesPointersByRadarValues );
stable_sort( arraySteps.begin(), arraySteps.end(), CompareNotesPointersByMeter );
stable_sort( arraySteps.begin(), arraySteps.end(), CompareNotesPointersByDifficulty );
}
bool CompareStepsPointersByTypeAndDifficulty(const Steps *pStep1, const Steps *pStep2)
{
if( pStep1->m_StepsType < pStep2->m_StepsType )
return true;
if( pStep1->m_StepsType > pStep2->m_StepsType )
return false;
return pStep1->GetDifficulty() < pStep2->GetDifficulty();
}
void SortStepsByTypeAndDifficulty( vector<Steps*> &arraySongPointers )
{
sort( arraySongPointers.begin(), arraySongPointers.end(), CompareStepsPointersByTypeAndDifficulty );
}
-9
View File
@@ -94,13 +94,4 @@ protected:
RadarValues m_RadarValues;
};
bool CompareNotesPointersByRadarValues(const Steps* pNotes1, const Steps* pNotes2);
bool CompareNotesPointersByMeter(const Steps *pNotes1, const Steps* pNotes2);
bool CompareNotesPointersByDifficulty(const Steps *pNotes1, const Steps *pNotes2);
void SortNotesArrayByDifficulty( vector<Steps*> &arrayNotess );
bool CompareStepsPointersByTypeAndDifficulty(const Steps *pStep1, const Steps *pStep2);
void SortStepsByTypeAndDifficulty( vector<Steps*> &arraySongPointers );
void SortStepsPointerArrayByNumPlays( vector<Steps*> &vStepsPointers, ProfileSlot slot, bool bDescending );
void SortStepsPointerArrayByNumPlays( vector<Steps*> &vStepsPointers, const Profile* pProfile, bool bDescending );
#endif
+1 -17
View File
@@ -4,7 +4,7 @@
-----------------------------------------------------------------------------
Class: Song
Desc: See header.
Desc: Holds data all music metadata and notes data single, playable song.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
@@ -209,20 +209,4 @@ private:
CString GetUniqueSongDescription( StepsType st );
};
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 );
void SortSongPointerArrayByNumPlays( vector<Song*> &arraySongPointers, ProfileSlot slot, bool bDescending );
void SortSongPointerArrayByNumPlays( vector<Song*> &arraySongPointers, const Profile* pProfile, bool bDescending );
void SortSongPointerArrayByMeter( vector<Song*> &arraySongPointers, Difficulty dc );
CString GetSectionNameFromSongAndSort( const Song* pSong, SortOrder so );
void SortSongPointerArrayBySectionName( vector<Song*> &arraySongPointers, SortOrder so );
#endif