#include "stdafx.h" /* ----------------------------------------------------------------------------- Class: Course Desc: See header. Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved. Chris Danford ----------------------------------------------------------------------------- */ #include "Course.h" #include "PrefsManager.h" #include "Song.h" #include "GameManager.h" #include "SongManager.h" #include "GameState.h" #include "RageException.h" #include "RageLog.h" #include "MsdFile.h" #include "PlayerOptions.h" #include "SongOptions.h" void Course::LoadFromCRSFile( CString sPath, CArray &apSongs ) { MsdFile msd; if( !msd.ReadFile(sPath) ) throw RageException( "Error opening CRS file '%s'.", sPath ); CString sDir, sFName, sExt; splitrelpath( sPath, sDir, sFName, sExt ); CStringArray arrayPossibleBanners; GetDirListing( "Courses\\" + sFName + ".png", arrayPossibleBanners, false, true ); GetDirListing( "Courses\\" + sFName + ".jpg", arrayPossibleBanners, false, true ); GetDirListing( "Courses\\" + sFName + ".bmp", arrayPossibleBanners, false, true ); GetDirListing( "Courses\\" + sFName + ".gif", arrayPossibleBanners, false, true ); if( arrayPossibleBanners.GetSize() > 0 ) m_sBannerPath = arrayPossibleBanners[0]; for( int i=0; im_sSongDir; if( 0 == stricmp(sThisSongDir, sSongDir) ) pSong = apSongs[i]; } if( pSong == NULL ) // we didn't find the Song continue; // skip this song AddStage( pSong, sNotesDescription, sModifiers ); } else LOG->Trace( "Unexpected value named '%s'", sValueName ); } } void Course::CreateEndlessCourseFromGroupAndDifficultyClass( CString sGroupName, DifficultyClass dc, CArray &apSongsInGroup ) { m_bRepeat = true; m_bRandomize = true; m_iLives = -1; CStringArray asPossibleBannerPaths; GetDirListing( "Songs\\" + sGroupName + "\\banner.png", asPossibleBannerPaths, false, true ); GetDirListing( "Songs\\" + sGroupName + "\\banner.jpg", asPossibleBannerPaths, false, true ); GetDirListing( "Songs\\" + sGroupName + "\\banner.gif", asPossibleBannerPaths, false, true ); GetDirListing( "Songs\\" + sGroupName + "\\banner.bmp", asPossibleBannerPaths, false, true ); if( asPossibleBannerPaths.GetSize() > 0 ) m_sBannerPath = asPossibleBannerPaths[0]; CString sShortGroupName = SONGMAN->ShortenGroupName( sGroupName ); m_sName = sShortGroupName + " "; switch( dc ) { case CLASS_EASY: m_sName += "Easy"; break; case CLASS_MEDIUM: m_sName += "Medium"; break; case CLASS_HARD: m_sName += "Hard"; break; } for( int s=0; sm_apNotes.GetSize(); i++ ) { Notes* pNotes = pSong->m_apNotes[i]; /* XXX: hmm. We need to match the first player, then set up other players * later ... */ if( 0==stricmp(pNotes->m_sDescription, sDescription) && GAMESTATE->GetCurrentStyleDef()->MatchesNotesType(pNotes->m_NotesType, 0) ) return pNotes; } // Didn't find a matching description. Try to match the DifficultyClass instead. DifficultyClass dc = Notes::DifficultyClassFromDescriptionAndMeter( sDescription, 5 ); for( i=0; im_apNotes.GetSize(); i++ ) { Notes* pNotes = pSong->m_apNotes[i]; if( pNotes->m_DifficultyClass == dc && GAMESTATE->GetCurrentStyleDef()->MatchesNotesType(pNotes->m_NotesType, 0) ) return pNotes; } return NULL; } /* When bShuffled is true, returns courses in the song ordering list. */ void Course::GetSongAndNotesForCurrentStyle( CArray& apSongsOut, CArray& apNotesOut, CStringArray& asModifiersOut, bool bShuffled ) { for( int i=0; iHasMusic() ) continue; // skip if( pNotes == NULL ) continue; // skip apSongsOut.Add( pSong ); apNotesOut.Add( pNotes ); asModifiersOut.Add( sModifiers ); } } D3DXCOLOR Course::GetColor() { // This could be made smarter if( m_iStages >= 7 ) return D3DXCOLOR(1,0,0,1); // red else if( m_iStages >= 4 ) return D3DXCOLOR(1,0.5f,0,1); // orange else return D3DXCOLOR(0,1,0,1); // green } void Course::GetPlayerOptions( PlayerOptions* pPO_out ) { *pPO_out = PlayerOptions(); } void Course::GetSongOptions( SongOptions* pSO_out ) { *pSO_out = SongOptions(); pSO_out->m_LifeType = (m_iLives==-1) ? SongOptions::LIFE_BAR : SongOptions::LIFE_BATTERY; if( m_iLives != -1 ) pSO_out->m_iBatteryLives = m_iLives; } // // Sorting stuff // int CompareCoursePointersByDifficulty(const void *arg1, const void *arg2) { Course* pCourse1 = *(Course**)arg1; Course* pCourse2 = *(Course**)arg2; float fScore1 = (float)pCourse1->m_iStages; float fScore2 = (float)pCourse2->m_iStages; if( fScore1 < fScore2 ) return -1; else if( fScore1 == fScore2 ) return 0; else return 1; } void SortCoursePointerArrayByDifficulty( CArray &apCourses ) { qsort( apCourses.GetData(), apCourses.GetSize(), sizeof(Course*), CompareCoursePointersByDifficulty ); }