clean up ranking/memory card saving

This commit is contained in:
Chris Danford
2003-10-19 23:30:09 +00:00
parent 10688ad0e2
commit c474b18afe
+231 -170
View File
@@ -39,9 +39,9 @@ SongManager* SONGMAN = NULL; // global and accessable from anywhere in our progr
const CString CATEGORY_RANKING_FILE = BASE_PATH "Data" SLASH "CategoryRanking.dat"; const CString CATEGORY_RANKING_FILE = BASE_PATH "Data" SLASH "CategoryRanking.dat";
const CString MACHINE_STEPS_MEM_CARD_DATA = BASE_PATH "Data" SLASH "MachineStepsMemCardData.dat"; const CString MACHINE_STEPS_MEM_CARD_DATA = BASE_PATH "Data" SLASH "MachineStepsMemCardData.dat";
const CString MACHINE_COURSE_MEM_CARD_DATA = BASE_PATH "Data" SLASH "MachineCourseMemCardData.dat"; const CString MACHINE_COURSE_MEM_CARD_DATA = BASE_PATH "Data" SLASH "MachineCourseMemCardData.dat";
const int CATEGORY_RANKING_VERSION = 1; const int CATEGORY_RANKING_VERSION = 2;
const int STEPS_MEM_CARD_DATA_VERSION = 3; const int STEPS_MEM_CARD_DATA_VERSION = 4;
const int COURSE_MEM_CARD_DATA_VERSION = 2; const int COURSE_MEM_CARD_DATA_VERSION = 3;
#define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors") #define NUM_GROUP_COLORS THEME->GetMetricI("SongManager","NumGroupColors")
@@ -311,53 +311,103 @@ void SongManager::FreeSongs()
m_sGroupBannerPaths.clear(); m_sGroupBannerPaths.clear();
} }
static CString ReadLine( FILE *fp )
{
char buf[1024];
fgets( buf, sizeof(buf), fp );
CString ret( buf ); //
TrimRight( ret ); // Helper function for reading/writing scores
return ret; //
bool FileRead( ifstream& f, CString& sOut )
{
if( f.eof() )
return false;
getline(f, sOut);
return true;
}
bool FileRead( ifstream& f, int& iOut )
{
CString s;
if( !FileRead( f, s ) )
return false;
iOut = atoi( s );
return true;
}
bool FileRead( ifstream& f, unsigned& uOut )
{
CString s;
if( !FileRead( f, s ) )
return false;
uOut = atoi( s );
return true;
}
bool FileRead( ifstream& f, float& fOut )
{
CString s;
if( !FileRead( f, s ) )
return false;
fOut = atof( s );
return true;
}
void FileWrite( ofstream& f, const CString& sWrite )
{
f << sWrite << endl;
}
void FileWrite( ofstream& f, int iWrite )
{
f << iWrite << endl;
}
void FileWrite( ofstream& f, unsigned uWrite )
{
f << uWrite << endl;
}
void FileWrite( ofstream& f, float fWrite )
{
f << fWrite << endl;
} }
#define WARN_AND_RETURN { LOG->Warn("Error parsing file '%s' at %s:%d",fn.c_str(),__FILE__,__LINE__); return; }
void SongManager::ReadStepsMemCardDataFromFile( CString fn, int c ) void SongManager::ReadStepsMemCardDataFromFile( CString fn, int mc )
{ {
ifstream f(fn); ifstream f(fn);
if( !f.good() ) if( !f.good() )
return; WARN_AND_RETURN;
CString line;
getline(f, line);
int version; int version;
sscanf(line.c_str(), "%i", &version); if( !FileRead(f, version) )
WARN_AND_RETURN;
if( version != STEPS_MEM_CARD_DATA_VERSION ) if( version != STEPS_MEM_CARD_DATA_VERSION )
return; WARN_AND_RETURN;
while( f && !f.eof() ) int iNumSongs;
if( !FileRead(f, iNumSongs) )
WARN_AND_RETURN;
for( int s=0; s<iNumSongs; s++ )
{ {
CString sSongDir; CString sSongDir;
getline(f, sSongDir); if( !FileRead(f, sSongDir) )
WARN_AND_RETURN;
getline(f, line);
unsigned uNumNotes;
sscanf(line.c_str(), "%u", &uNumNotes);
Song* pSong = this->GetSongFromDir( sSongDir ); Song* pSong = this->GetSongFromDir( sSongDir );
for( unsigned i=0; i<uNumNotes; i++ ) int iNumNotes;
if( !FileRead(f, iNumNotes) )
WARN_AND_RETURN;
for( unsigned n=0; n<iNumNotes; n++ )
{ {
StepsType nt; StepsType nt;
Difficulty dc; if( !FileRead(f, (int&)nt) )
WARN_AND_RETURN;
getline(f, line); Difficulty dc;
if( sscanf(line.c_str(), "%d %d", (int *)&nt, (int *)&dc) != 2 ) if( !FileRead(f, (int&)dc) )
break; WARN_AND_RETURN;
CString sDescription; CString sDescription;
getline(f, sDescription); if( !FileRead(f, sDescription) )
WARN_AND_RETURN;
// Even if pSong or pNotes is null, we still have to skip over that data.
Steps* pNotes = NULL; Steps* pNotes = NULL;
if( pSong ) if( pSong )
@@ -368,29 +418,36 @@ void SongManager::ReadStepsMemCardDataFromFile( CString fn, int c )
pNotes = pSong->GetStepsByDifficulty( nt, dc ); pNotes = pSong->GetStepsByDifficulty( nt, dc );
} }
getline(f, line);
int iNumTimesPlayed; int iNumTimesPlayed;
if( sscanf(line.c_str(), "%d\n", &iNumTimesPlayed ) != 1 ) if( !FileRead(f, iNumTimesPlayed) )
return; WARN_AND_RETURN;
if( pNotes )
pNotes->m_MemCardDatas[c].iNumTimesPlayed = iNumTimesPlayed;
if( pNotes ) if( pNotes )
pNotes->m_MemCardDatas[c].vHighScores.resize(NUM_RANKING_LINES); pNotes->m_MemCardDatas[mc].iNumTimesPlayed = iNumTimesPlayed;
for( int k=0; k<NUM_RANKING_LINES; k++ ) if( pNotes )
pNotes->m_MemCardDatas[mc].vHighScores.resize(NUM_RANKING_LINES);
for( int l=0; l<NUM_RANKING_LINES; l++ )
{ {
Grade grade; Grade grade;
if( !FileRead(f, (int&)grade) )
WARN_AND_RETURN;
CLAMP( grade, (Grade)0, (Grade)(NUM_GRADES-1) );
float fScore; float fScore;
char szName[256]; // TODO: not overflow safe if( !FileRead(f, fScore) )
if( sscanf(line.c_str(), "%d %f %[^\n]\n", (int *)&grade, &fScore, szName) != 3 ) WARN_AND_RETURN;
return;
CString sName;
if( !FileRead(f, sName) )
WARN_AND_RETURN;
if( pNotes ) if( pNotes )
{ {
pNotes->m_MemCardDatas[c].vHighScores[k].grade = grade; pNotes->m_MemCardDatas[mc].vHighScores[l].grade = grade;
pNotes->m_MemCardDatas[c].vHighScores[k].fScore = fScore; pNotes->m_MemCardDatas[mc].vHighScores[l].fScore = fScore;
pNotes->m_MemCardDatas[c].vHighScores[k].sName = szName; pNotes->m_MemCardDatas[mc].vHighScores[l].sName = sName;
} }
} }
} }
@@ -400,80 +457,98 @@ void SongManager::ReadStepsMemCardDataFromFile( CString fn, int c )
void SongManager::ReadCategoryRankingsFromFile( CString fn ) void SongManager::ReadCategoryRankingsFromFile( CString fn )
{ {
FILE* fp = fopen( fn, "r" ); ifstream f(fn);
if( !fp ) if( !f.good() )
return; WARN_AND_RETURN;
int version; int version;
fscanf(fp, "%d\n", &version ); if( !FileRead(f, version) )
if( version == CATEGORY_RANKING_VERSION ) WARN_AND_RETURN;
{ if( version != CATEGORY_RANKING_VERSION )
for( int i=0; i<NUM_STEPS_TYPES; i++ ) WARN_AND_RETURN;
{
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ )
{
m_CategoryDatas[i][j].vHighScores.resize(NUM_RANKING_LINES);
for( int k=0; k<NUM_RANKING_LINES; k++ )
if( !feof(fp) )
{
char szName[256]; // TODO: not overflow safe
fscanf(fp, "%i %[^\n]\n", &m_CategoryDatas[i][j].vHighScores[k].iScore, szName);
m_CategoryDatas[i][j].vHighScores[k].sName = szName;
}
}
}
}
fclose(fp);
}
void SongManager::ReadCourseMemCardDataFromFile( CString fn, int c ) for( int st=0; st<NUM_STEPS_TYPES; st++ )
{
FILE* fp = fopen( fn, "r" );
if( !fp )
return;
int version;
fscanf(fp, "%i\n", &version );
if( version == COURSE_MEM_CARD_DATA_VERSION )
{ {
while( fp && !feof(fp) ) for( int rc=0; rc<NUM_RANKING_CATEGORIES; rc++ )
{ {
CString path=ReadLine( fp ); m_CategoryDatas[st][rc].vHighScores.resize(NUM_RANKING_LINES);
for( int l=0; l<NUM_RANKING_LINES; l++ )
Course* pCourse = GetCourseFromPath( path );
if( pCourse == NULL )
pCourse = GetCourseFromName( path );
// even if we don't find the Course*, we still have to read past the input
for( int i=0; i<NUM_STEPS_TYPES; i++ )
{
int iNumTimesPlayed;
fscanf(fp, "%d\n", &iNumTimesPlayed);
if( pCourse )
pCourse->m_MemCardDatas[i][c].iNumTimesPlayed = iNumTimesPlayed;
if( pCourse )
pCourse->m_MemCardDatas[i][c].vHighScores.resize(NUM_RANKING_LINES);
for( int j=0; j<NUM_RANKING_LINES; j++ )
{
if( !feof(fp) )
{ {
int iScore; int iScore;
if( !FileRead(f, iScore) )
WARN_AND_RETURN;
CString sName;
if( !FileRead(f, sName) )
WARN_AND_RETURN;
m_CategoryDatas[st][rc].vHighScores[l].iScore = iScore;
m_CategoryDatas[st][rc].vHighScores[l].sName = sName;
}
}
}
}
void SongManager::ReadCourseMemCardDataFromFile( CString fn, int mc )
{
ifstream f(fn);
if( !f.good() )
WARN_AND_RETURN;
int version;
if( !FileRead(f, version) )
WARN_AND_RETURN;
if( version != COURSE_MEM_CARD_DATA_VERSION )
WARN_AND_RETURN;
int iNumCourses;
if( !FileRead(f, iNumCourses) )
WARN_AND_RETURN;
for( int c=0; c<iNumCourses; c++ )
{
CString sPath;
if( !FileRead(f, sPath) )
WARN_AND_RETURN;
Course* pCourse = GetCourseFromPath( sPath );
if( pCourse == NULL )
pCourse = GetCourseFromName( sPath );
// even if we don't find the Course*, we still have to read past the input
for( int st=0; st<NUM_STEPS_TYPES; st++ )
{
int iNumTimesPlayed;
if( !FileRead(f, iNumTimesPlayed) )
WARN_AND_RETURN;
if( pCourse )
pCourse->m_MemCardDatas[st][mc].iNumTimesPlayed = iNumTimesPlayed;
if( pCourse )
pCourse->m_MemCardDatas[st][mc].vHighScores.resize(NUM_RANKING_LINES);
for( int l=0; l<NUM_RANKING_LINES; l++ )
{
int iScore;
if( !FileRead(f, iScore) )
WARN_AND_RETURN;
float fSurviveTime; float fSurviveTime;
char szName[256]; // TODO: not overflow safe if( !FileRead(f, fSurviveTime) )
fscanf(fp, "%d %f %[^\n]\n", &iScore, &fSurviveTime, szName); WARN_AND_RETURN;
CString sName;
if( !FileRead(f, sName) )
WARN_AND_RETURN;
if( pCourse ) if( pCourse )
{ {
pCourse->m_MemCardDatas[i][c].vHighScores[j].iScore = iScore; pCourse->m_MemCardDatas[st][mc].vHighScores[l].iScore = iScore;
pCourse->m_MemCardDatas[i][c].vHighScores[j].fSurviveTime = fSurviveTime; pCourse->m_MemCardDatas[st][mc].vHighScores[l].fSurviveTime = fSurviveTime;
pCourse->m_MemCardDatas[i][c].vHighScores[j].sName = szName; pCourse->m_MemCardDatas[st][mc].vHighScores[l].sName = sName;
} }
} }
} }
} }
}
}
fclose(fp);
} }
void SongManager::InitMachineScoresFromDisk() void SongManager::InitMachineScoresFromDisk()
@@ -559,80 +634,75 @@ void SongManager::ReadSM300NoteScores()
void SongManager::SaveCategoryRankingsToFile( CString fn ) void SongManager::SaveCategoryRankingsToFile( CString fn )
{ {
// category ranking
LOG->Trace("SongManager::SaveCategoryRankingsToFile"); LOG->Trace("SongManager::SaveCategoryRankingsToFile");
FILE* fp = fopen( fn, "w" ); ofstream f(fn);
if( fp ) if( !f.good() )
return;
FileWrite( f, CATEGORY_RANKING_VERSION );
for( int st=0; st<NUM_STEPS_TYPES; st++ )
{ {
fprintf(fp,"%d\n",CATEGORY_RANKING_VERSION); for( int rc=0; rc<NUM_RANKING_CATEGORIES; rc++ )
for( int i=0; i<NUM_STEPS_TYPES; i++ )
{ {
for( int j=0; j<NUM_RANKING_CATEGORIES; j++ ) m_CategoryDatas[st][rc].vHighScores.resize(NUM_RANKING_LINES);
for( int l=0; l<NUM_RANKING_LINES; l++ )
{ {
m_CategoryDatas[i][j].vHighScores.resize(NUM_RANKING_LINES); FileWrite( f, m_CategoryDatas[st][rc].vHighScores[l].iScore );
for( int k=0; k<NUM_RANKING_LINES; k++ ) FileWrite( f, m_CategoryDatas[st][rc].vHighScores[l].sName );
{
if( fp )
{
fprintf(fp, "%i %s\n",
m_CategoryDatas[i][j].vHighScores[k].iScore,
m_CategoryDatas[i][j].vHighScores[k].sName.c_str());
} }
} }
} }
}
fclose(fp);
}
} }
void SongManager::SaveCourseMemCardDataToFile( CString fn, int c ) void SongManager::SaveCourseMemCardDataToFile( CString fn, int mc )
{ {
// course ranking
LOG->Trace("SongManager::SaveCourseMemCardDataToFile"); LOG->Trace("SongManager::SaveCourseMemCardDataToFile");
FILE* fp = fopen( fn, "w" ); ofstream f(fn);
if( !f.good() )
return;
if( fp ) FileWrite( f, COURSE_MEM_CARD_DATA_VERSION );
FileWrite( f, m_pCourses.size() );
for( unsigned c=0; c<m_pCourses.size(); c++ ) // foreach course
{ {
fprintf(fp,"%d\n",COURSE_MEM_CARD_DATA_VERSION); Course* pCourse = m_pCourses[c];
for( unsigned i=0; i<m_pCourses.size(); i++ ) // foreach course
{
Course* pCourse = m_pCourses[i];
ASSERT(pCourse); ASSERT(pCourse);
if( pCourse->m_bIsAutogen ) if( pCourse->m_bIsAutogen )
fprintf(fp, "%s\n", pCourse->m_sName.c_str()); FileWrite( f, pCourse->m_sName );
else else
fprintf(fp, "%s\n", pCourse->m_sPath.c_str()); FileWrite( f, pCourse->m_sPath );
for( int j=0; j<NUM_STEPS_TYPES; j++ ) for( int st=0; st<NUM_STEPS_TYPES; st++ )
{ {
fprintf(fp, "%d\n", pCourse->m_MemCardDatas[j][c].iNumTimesPlayed); FileWrite( f, pCourse->m_MemCardDatas[st][mc].iNumTimesPlayed );
pCourse->m_MemCardDatas[j][c].vHighScores.resize(NUM_RANKING_LINES); pCourse->m_MemCardDatas[st][mc].vHighScores.resize(NUM_RANKING_LINES);
for( int k=0; k<NUM_RANKING_LINES; k++ ) for( int l=0; l<NUM_RANKING_LINES; l++ )
{ {
fprintf(fp, "%d %f %s\n", FileWrite( f, pCourse->m_MemCardDatas[st][mc].vHighScores[l].iScore );
pCourse->m_MemCardDatas[j][c].vHighScores[k].iScore, FileWrite( f, pCourse->m_MemCardDatas[st][mc].vHighScores[l].fSurviveTime );
pCourse->m_MemCardDatas[j][c].vHighScores[k].fSurviveTime, FileWrite( f, pCourse->m_MemCardDatas[st][mc].vHighScores[l].sName );
pCourse->m_MemCardDatas[j][c].vHighScores[k].sName.c_str());
} }
} }
} }
fclose(fp);
}
} }
void SongManager::SaveStepsMemCardDataToFile( CString fn, int c ) void SongManager::SaveStepsMemCardDataToFile( CString fn, int mc )
{ {
// notes scores
LOG->Trace("SongManager::SaveStepsMemCardDataToFile %s", fn.c_str()); LOG->Trace("SongManager::SaveStepsMemCardDataToFile %s", fn.c_str());
{
FILE* fp = fopen( fn, "w" ); ofstream f(fn);
if( fp ) if( !f.good() )
{ return;
fprintf(fp,"%d\n",STEPS_MEM_CARD_DATA_VERSION);
FileWrite( f, STEPS_MEM_CARD_DATA_VERSION );
FileWrite( f, m_pSongs.size() );
for( unsigned s=0; s<m_pSongs.size(); s++ ) // foreach song for( unsigned s=0; s<m_pSongs.size(); s++ ) // foreach song
{ {
@@ -643,37 +713,28 @@ void SongManager::SaveStepsMemCardDataToFile( CString fn, int c )
if( vNotes.size() == 0 ) if( vNotes.size() == 0 )
continue; // skip continue; // skip
fprintf(fp, "%s\n%u\n", FileWrite( f, pSong->GetSongDir() );
pSong->GetSongDir().c_str(), FileWrite( f, vNotes.size() );
(unsigned)vNotes.size() );
for( unsigned i=0; i<vNotes.size(); i++ ) for( unsigned n=0; n<vNotes.size(); n++ )
{ {
Steps* pNotes = vNotes[i]; Steps* pNotes = vNotes[n];
ASSERT(pNotes); ASSERT(pNotes);
fprintf(fp, "%d %d\n%s\n", FileWrite( f, pNotes->m_StepsType );
pNotes->m_StepsType, FileWrite( f, pNotes->GetDifficulty() );
pNotes->GetDifficulty(), FileWrite( f, pNotes->GetDescription() );
pNotes->GetDescription().c_str() ); FileWrite( f, pNotes->m_MemCardDatas[mc].iNumTimesPlayed );
pNotes->m_MemCardDatas[mc].vHighScores.resize(NUM_RANKING_LINES);
fprintf(fp, "%d\n", pNotes->m_MemCardDatas[c].iNumTimesPlayed ); for( int l=0; l<NUM_RANKING_LINES; l++ )
pNotes->m_MemCardDatas[c].vHighScores.resize(NUM_RANKING_LINES);
for( int j=0; j<NUM_RANKING_LINES; j++ )
{ {
fprintf(fp, "%d %f %s\n", FileWrite( f, pNotes->m_MemCardDatas[mc].vHighScores[l].grade );
pNotes->m_MemCardDatas[c].vHighScores[j].grade, FileWrite( f, pNotes->m_MemCardDatas[mc].vHighScores[l].fScore );
pNotes->m_MemCardDatas[c].vHighScores[j].fScore, FileWrite( f, pNotes->m_MemCardDatas[mc].vHighScores[l].sName );
pNotes->m_MemCardDatas[c].vHighScores[j].sName.c_str());
} }
} }
} }
fclose(fp);
}
}
} }