Files
itgmania212121/stepmania/src/SongManager.cpp
T

376 lines
10 KiB
C++
Raw Normal View History

2002-02-28 19:40:40 +00:00
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: SongManager
Desc: See header.
2002-05-19 01:59:48 +00:00
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
2002-02-28 19:40:40 +00:00
Chris Danford
-----------------------------------------------------------------------------
*/
2002-04-16 17:31:00 +00:00
//#include <d3dxmath.h>
2002-02-28 19:40:40 +00:00
#include "SongManager.h"
#include "IniFile.h"
2002-05-01 19:14:55 +00:00
#include "RageLog.h"
2002-04-16 17:31:00 +00:00
#include "ErrorCatcher/ErrorCatcher.h"
2002-02-28 19:40:40 +00:00
2002-05-19 01:59:48 +00:00
SongManager* SONGMAN = NULL; // global and accessable from anywhere in our program
2002-02-28 19:40:40 +00:00
const CString g_sStatisticsFileName = "statistics.ini";
2002-04-16 17:31:00 +00:00
D3DXCOLOR GROUP_COLORS[] = {
D3DXCOLOR( 0.9f, 0.0f, 0.2f, 1 ), // red
2002-05-19 01:59:48 +00:00
D3DXCOLOR( 0.7f, 0.0f, 0.5f, 1 ), // pink
D3DXCOLOR( 0.4f, 0.2f, 0.6f, 1 ), // purple
2002-04-16 17:31:00 +00:00
D3DXCOLOR( 0.0f, 0.4f, 0.8f, 1 ), // sky blue
D3DXCOLOR( 0.0f, 0.6f, 0.6f, 1 ), // sea green
D3DXCOLOR( 0.0f, 0.6f, 0.2f, 1 ), // green
D3DXCOLOR( 0.8f, 0.6f, 0.0f, 1 ), // orange
};
const int NUM_GROUP_COLORS = sizeof(GROUP_COLORS) / sizeof(D3DXCOLOR);
2002-02-28 19:40:40 +00:00
SongManager::SongManager()
{
m_pCurSong = NULL;
for( int p=0; p<NUM_PLAYERS; p++ )
2002-05-19 01:59:48 +00:00
m_pCurNotes[p] = NULL;
2002-02-28 19:40:40 +00:00
InitSongArrayFromDisk();
ReadStatisticsFromDisk();
}
SongManager::~SongManager()
{
SaveStatisticsToDisk();
CleanUpSongArray();
2002-04-16 17:31:00 +00:00
m_arrayGroupNames.RemoveAll();
2002-02-28 19:40:40 +00:00
}
void SongManager::InitSongArrayFromDisk()
{
2002-03-06 08:25:09 +00:00
LoadStepManiaSongDir( "Songs" );
2002-05-19 01:59:48 +00:00
//LoadDWISongDir( "DWI Support" );
2002-04-16 17:31:00 +00:00
// computer group names
CArray<Song*, Song*> arraySongs;
arraySongs.Copy( m_pSongs );
SortSongPointerArrayByGroup( arraySongs );
for( int i=0; i<m_pSongs.GetSize(); i++ )
{
Song* pSong = m_pSongs[i];
const CString sGroupName = m_pSongs[i]->GetGroupName();
if( m_arrayGroupNames.GetSize() == 0 || m_arrayGroupNames[m_arrayGroupNames.GetSize()-1] != sGroupName )
m_arrayGroupNames.Add( sGroupName );
}
2002-05-01 19:14:55 +00:00
LOG->WriteLine( "Found %d Songs.", m_pSongs.GetSize() );
2002-03-06 08:25:09 +00:00
}
void SongManager::LoadStepManiaSongDir( CString sDir )
{
// trim off the trailing slash if any
sDir.TrimRight( "/\\" );
// Find all group directories in "Songs" folder
CStringArray arrayGroupDirs;
GetDirListing( sDir+"\\*.*", arrayGroupDirs, true );
SortCStringArray( arrayGroupDirs );
for( int i=0; i< arrayGroupDirs.GetSize(); i++ ) // for each dir in /Songs/
{
CString sGroupDirName = arrayGroupDirs[i];
if( 0 == stricmp( sGroupDirName, "cvs" ) ) // the directory called "CVS"
continue; // ignore it
// Check to see if they put a song directly inside of the group folder
CStringArray arrayFiles;
GetDirListing( ssprintf("%s\\%s\\*.mp3", sDir, sGroupDirName), arrayFiles );
2002-05-19 01:59:48 +00:00
GetDirListing( ssprintf("%s\\%s\\*.ogg", sDir, sGroupDirName), arrayFiles );
2002-03-06 08:25:09 +00:00
GetDirListing( ssprintf("%s\\%s\\*.wav", sDir, sGroupDirName), arrayFiles );
if( arrayFiles.GetSize() > 0 )
2002-04-16 17:31:00 +00:00
FatalError(
2002-03-06 08:25:09 +00:00
ssprintf( "The song folder '%s' must be placed inside of a group folder.\n\n"
"All song folders must be placed below a group folder. For example, 'Songs\\DDR 4th Mix\\B4U'. See the StepMania readme for more info.",
ssprintf("%s\\%s", sDir, sGroupDirName ) )
);
// Look for a group banner in this group folder
CStringArray arrayGroupBanners;
GetDirListing( ssprintf("%s\\%s\\*.png", sDir, sGroupDirName), arrayGroupBanners );
GetDirListing( ssprintf("%s\\%s\\*.jpg", sDir, sGroupDirName), arrayGroupBanners );
GetDirListing( ssprintf("%s\\%s\\*.gif", sDir, sGroupDirName), arrayGroupBanners );
GetDirListing( ssprintf("%s\\%s\\*.bmp", sDir, sGroupDirName), arrayGroupBanners );
if( arrayGroupBanners.GetSize() > 0 )
{
m_mapGroupToBannerPath[sGroupDirName] = ssprintf("%s\\%s\\%s", sDir, sGroupDirName, arrayGroupBanners[0] );
2002-05-01 19:14:55 +00:00
LOG->WriteLine( ssprintf("Group banner for '%s' is '%s'.", sGroupDirName, m_mapGroupToBannerPath[sGroupDirName]) );
2002-03-06 08:25:09 +00:00
}
// Find all Song folders in this group directory
CStringArray arraySongDirs;
GetDirListing( ssprintf("%s\\%s\\*.*", sDir, sGroupDirName), arraySongDirs, true );
SortCStringArray( arraySongDirs );
for( int j=0; j< arraySongDirs.GetSize(); j++ ) // for each song dir
{
CString sSongDirName = arraySongDirs[j];
if( 0 == stricmp( sSongDirName, "cvs" ) ) // the directory called "CVS"
continue; // ignore it
// this is a song directory. Load a new song!
Song* pNewSong = new Song;
pNewSong->LoadFromSongDir( ssprintf("%s\\%s\\%s", sDir, sGroupDirName, sSongDirName) );
m_pSongs.Add( pNewSong );
}
}
}
2002-04-28 20:42:32 +00:00
2002-05-19 01:59:48 +00:00
/*
2002-04-28 20:42:32 +00:00
void SongManager::LoadDWISongDir( CString DWIHome )
2002-03-06 08:25:09 +00:00
{
// trim off the trailing slash if any
2002-04-28 20:42:32 +00:00
DWIHome.TrimRight( "/\\" );
2002-02-28 19:40:40 +00:00
2002-04-28 20:42:32 +00:00
// this has to be fixed, DWI doesn't put files
// in it's DWI folder. It puts them in Songs/<MIX>/<SONGNAME>
// so what we have to do, is go to the DWI directory (which will
// be changeable by the user so they don't have to copy everything
// over and have two copies of everything
2002-02-28 19:40:40 +00:00
// Find all directories in "DWIs" folder
CStringArray arrayDirs;
2002-04-28 20:42:32 +00:00
CStringArray MixDirs;
// now we've got the listing of the mix directories
// and we need to use THOSE directories to find our
// dwis
GetDirListing( ssprintf("%s\\Songs\\*.*", DWIHome ), MixDirs, true );
SortCStringArray( MixDirs );
2002-02-28 19:40:40 +00:00
2002-04-28 20:42:32 +00:00
for( int i=0; i< MixDirs.GetSize(); i++ ) // for each dir in /Songs/
2002-02-28 19:40:40 +00:00
{
2002-04-28 20:42:32 +00:00
// the dir name will most likely be something like
// Dance Dance Revolution 4th Mix, etc.
CString sDirName = MixDirs[i];
2002-02-28 19:40:40 +00:00
sDirName.MakeLower();
if( sDirName == "cvs" ) // ignore the directory called "CVS"
continue;
2002-04-28 20:42:32 +00:00
GetDirListing( ssprintf("%s\\Songs\\%s\\*.*", DWIHome, MixDirs[i]), arrayDirs, true);
SortCStringArray(arrayDirs, true);
2002-02-28 19:40:40 +00:00
2002-04-28 20:42:32 +00:00
for( int b = 0; b < arrayDirs.GetSize(); b++)
2002-02-28 19:40:40 +00:00
{
2002-04-28 20:42:32 +00:00
// Find all DWIs in this directory
CStringArray arrayDWIFiles;
GetDirListing( ssprintf("%s\\Songs\\%s\\%s\\*.dwi", DWIHome, MixDirs[i], arrayDirs[b]), arrayDWIFiles, false);
SortCStringArray( arrayDWIFiles );
2002-02-28 19:40:40 +00:00
2002-04-28 20:42:32 +00:00
for( int j=0; j< arrayDWIFiles.GetSize(); j++ ) // for each DWI file
{
CString sDWIFileName = arrayDWIFiles[j];
sDWIFileName.MakeLower();
// load DWIs from the sub dirs
Song* pNewSong = new Song;
pNewSong->LoadFromDWIFile( ssprintf("%s\\Songs\\%s\\%s\\%s", DWIHome, MixDirs[i], arrayDirs[b], sDWIFileName) );
m_pSongs.Add( pNewSong );
}
2002-02-28 19:40:40 +00:00
}
}
}
2002-05-19 01:59:48 +00:00
*/
2002-02-28 19:40:40 +00:00
2002-03-06 08:25:09 +00:00
2002-02-28 19:40:40 +00:00
void SongManager::CleanUpSongArray()
{
for( int i=0; i<m_pSongs.GetSize(); i++ )
{
SAFE_DELETE( m_pSongs[i] );
}
m_pSongs.RemoveAll();
2002-03-06 08:25:09 +00:00
m_mapGroupToBannerPath.RemoveAll();
2002-02-28 19:40:40 +00:00
}
void SongManager::ReloadSongArray()
{
InitSongArrayFromDisk();
CleanUpSongArray();
}
void SongManager::ReadStatisticsFromDisk()
{
IniFile ini;
ini.SetPath( g_sStatisticsFileName );
if( !ini.ReadFile() ) {
2002-05-01 19:14:55 +00:00
LOG->WriteLine( "WARNING: Could not read config file '%s'.", g_sStatisticsFileName );
2002-02-28 19:40:40 +00:00
return; // load nothing
}
// load song statistics
CMapStringToString* pKey = ini.GetKeyPointer( "Statistics" );
if( pKey )
{
for( POSITION pos = pKey->GetStartPosition(); pos != NULL; )
{
CString name_string, value_string;
pKey->GetNextAssoc( pos, name_string, value_string );
// Each value has the format "SongName::StepsName=TimesPlayed::TopGrade::TopScore::MaxCombo".
char szSongName[256];
char szStepsName[256];
int iRetVal;
int i;
2002-05-19 01:59:48 +00:00
// Parse for Song name and Notes name
2002-02-28 19:40:40 +00:00
iRetVal = sscanf( name_string, "%[^:]::%[^\n]", szSongName, szStepsName );
if( iRetVal != 2 )
continue; // this line doesn't match what is expected
// Search for the corresponding Song pointer.
Song* pSong = NULL;
for( i=0; i<m_pSongs.GetSize(); i++ )
{
2002-04-28 20:42:32 +00:00
if( m_pSongs[i]->GetMainTitle() == szSongName ) // match!
2002-02-28 19:40:40 +00:00
{
pSong = m_pSongs[i];
break;
}
}
if( pSong == NULL ) // didn't find a match
continue; // skip this entry
2002-05-19 01:59:48 +00:00
// Search for the corresponding Notes pointer.
Notes* pNotes = NULL;
for( i=0; i<pSong->m_arrayNotes.GetSize(); i++ )
2002-02-28 19:40:40 +00:00
{
2002-05-19 01:59:48 +00:00
if( pSong->m_arrayNotes[i].m_sDescription == szStepsName ) // match!
2002-02-28 19:40:40 +00:00
{
2002-05-19 01:59:48 +00:00
pNotes = &pSong->m_arrayNotes[i];
2002-02-28 19:40:40 +00:00
break;
}
}
2002-05-19 01:59:48 +00:00
if( pNotes == NULL ) // didn't find a match
2002-02-28 19:40:40 +00:00
continue; // skip this entry
2002-05-19 01:59:48 +00:00
// Parse the Notes statistics.
2002-02-28 19:40:40 +00:00
char szGradeLetters[10]; // longest possible string is "AAA"
iRetVal = sscanf(
value_string,
"%d::%[^:]::%d::%d",
2002-05-19 01:59:48 +00:00
&pNotes->m_iNumTimesPlayed,
2002-02-28 19:40:40 +00:00
szGradeLetters,
2002-05-19 01:59:48 +00:00
&pNotes->m_iTopScore,
&pNotes->m_iMaxCombo
2002-02-28 19:40:40 +00:00
);
if( iRetVal != 4 )
continue;
2002-05-19 01:59:48 +00:00
pNotes->m_TopGrade = StringToGrade( szGradeLetters );
2002-02-28 19:40:40 +00:00
}
}
}
void SongManager::SaveStatisticsToDisk()
{
IniFile ini;
ini.SetPath( g_sStatisticsFileName );
// save song statistics
for( int i=0; i<m_pSongs.GetSize(); i++ ) // for each Song
{
Song* pSong = m_pSongs[i];
2002-05-19 01:59:48 +00:00
for( int j=0; j<pSong->m_arrayNotes.GetSize(); j++ ) // for each Notes
2002-02-28 19:40:40 +00:00
{
2002-05-19 01:59:48 +00:00
Notes* pNotes = &pSong->m_arrayNotes[j];
2002-02-28 19:40:40 +00:00
2002-05-19 01:59:48 +00:00
if( pNotes->m_TopGrade == GRADE_NO_DATA )
continue; // skip
2002-02-28 19:40:40 +00:00
2002-05-19 01:59:48 +00:00
// Each value has the format "SongName::NotesName=TimesPlayed::TopGrade::TopScore::MaxCombo".
2002-02-28 19:40:40 +00:00
2002-05-19 01:59:48 +00:00
CString sName = ssprintf( "%s::%s", pSong->GetMainTitle(), pNotes->m_sDescription );
2002-02-28 19:40:40 +00:00
CString sValue = ssprintf(
"%d::%s::%d::%d",
2002-05-19 01:59:48 +00:00
pNotes->m_iNumTimesPlayed,
GradeToString( pNotes->m_TopGrade ),
pNotes->m_iTopScore,
pNotes->m_iMaxCombo
2002-02-28 19:40:40 +00:00
);
ini.SetValue( "Statistics", sName, sValue );
}
}
ini.WriteFile();
2002-03-06 08:25:09 +00:00
}
CString SongManager::GetGroupBannerPath( CString sGroupName )
2002-03-06 08:25:09 +00:00
{
CString sPath;
if( m_mapGroupToBannerPath.Lookup( sGroupName, sPath ) )
return sPath;
else
return "";
}
2002-04-01 02:04:43 +00:00
void SongManager::GetGroupNames( CStringArray &AddTo )
{
2002-04-16 17:31:00 +00:00
AddTo.Copy( m_arrayGroupNames );
}
2002-04-01 02:04:43 +00:00
2002-04-16 17:31:00 +00:00
D3DXCOLOR SongManager::GetGroupColor( const CString &sGroupName )
{
// search for the group index
for( int i=0; i<m_arrayGroupNames.GetSize(); i++ )
2002-04-01 02:04:43 +00:00
{
2002-04-16 17:31:00 +00:00
if( m_arrayGroupNames[i] == sGroupName )
break;
2002-04-01 02:04:43 +00:00
}
2002-04-16 17:31:00 +00:00
ASSERT( i != m_arrayGroupNames.GetSize() ); // this is not a valid group
return GROUP_COLORS[i%NUM_GROUP_COLORS];
2002-04-01 02:04:43 +00:00
}
void SongManager::GetSongsInGroup( const CString sGroupName, CArray<Song*, Song*> &AddTo )
{
for( int i=0; i<m_pSongs.GetSize(); i++ )
{
Song* pSong = m_pSongs[i];
if( sGroupName == m_pSongs[i]->GetGroupName() )
AddTo.Add( pSong );
}
SortSongPointerArrayByGroup( AddTo );
}
2002-04-16 17:31:00 +00:00
CString SongManager::ShortenGroupName( const CString &sOrigGroupName )
{
CString sShortName = sOrigGroupName;
sShortName.Replace( "Dance Dance Revolution", "DDR" );
sShortName.Replace( "dance dance revolution", "DDR" );
sShortName.Replace( "DANCE DANCE REVOLUTION", "DDR" );
return sShortName;
}