From 926126d5adf457dbc5c92fd83c7231415ea22d04 Mon Sep 17 00:00:00 2001 From: erihel Date: Mon, 1 Apr 2013 18:24:12 +0200 Subject: * Changed loading of scene and player info (there's problem with locales using , as comma separator). Issue #137 * Changed way of saving files. Now it's not based on slot (from 000 to 999) but it uses save name as a base. * Changed way of displaying saved games. Listing directory instead of checking from 000 to 999. Issue #138 --- src/ui/maindialog.cpp | 254 +++++++++++++++++++++++++------------------------- src/ui/maindialog.h | 4 + 2 files changed, 130 insertions(+), 128 deletions(-) (limited to 'src/ui') diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp index 9060e8b..75db2a6 100644 --- a/src/ui/maindialog.cpp +++ b/src/ui/maindialog.cpp @@ -4256,14 +4256,18 @@ void CMainDialog::DefPerso() bool CMainDialog::IsIOReadScene() { - FILE* file; - std::string filename; - - filename = m_savegameDir + "/" + m_main->GetGamerName() + "/" + "save" + m_sceneName[0] + "000/data.sav"; - file = fopen(filename.c_str(), "r"); - if ( file == NULL ) return false; - fclose(file); - return true; + fs::directory_iterator end_iter; + + fs::path saveDir(m_savegameDir + "/" + m_main->GetGamerName()); + if (fs::exists(saveDir) && fs::is_directory(saveDir)) { + for( fs::directory_iterator dir_iter(saveDir) ; dir_iter != end_iter ; ++dir_iter) { + if ( fs::is_directory(dir_iter->status()) && fs::exists(dir_iter->path() / "data.sav") ) { + return true; + } + } + } + + return false; } // Builds the file name by default. @@ -4283,9 +4287,9 @@ void CMainDialog::IOReadName() int i; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); - if ( pw == 0 ) return; + if ( pw == nullptr ) return; pe = static_cast(pw->SearchControl(EVENT_INTERFACE_IONAME)); - if ( pe == 0 ) return; + if ( pe == nullptr ) return; sprintf(resume, "%s %d", m_sceneName, m_chap[m_index]+1); BuildSceneName(filename, m_sceneName, (m_chap[m_index]+1)*100); @@ -4337,7 +4341,8 @@ void CMainDialog::IOReadList() CList* pl; char line[500]; char name[100]; - int i, j; + int i; + fs::directory_iterator end_iter; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); if ( pw == 0 ) return; @@ -4345,50 +4350,46 @@ void CMainDialog::IOReadList() if ( pl == 0 ) return; pl->Flush(); + + fs::path saveDir(m_savegameDir + "/" + m_main->GetGamerName()); + m_saveList.clear(); + + if (fs::exists(saveDir) && fs::is_directory(saveDir)) { + for( fs::directory_iterator dir_iter(saveDir) ; dir_iter != end_iter ; ++dir_iter) { + if ( fs::is_directory(dir_iter->status()) && fs::exists(dir_iter->path() / "data.sav") ) { + + file = fopen((dir_iter->path() / "data.sav").make_preferred().string().c_str(), "r"); + if ( file == NULL ) continue; + + while ( fgets(line, 500, file) != NULL ) { + for ( i=0 ; i<500 ; i++ ) { + if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space + if ( line[i] == '/' && line[i+1] == '/' ) { + line[i] = 0; + break; + } + } - for ( j=0 ; j<999 ; j++ ) - { - std::string filename; - std::ostringstream rankStream; - rankStream << std::setfill('0') << std::setw(3) << j; - filename = m_savegameDir + "/" + m_main->GetGamerName() + "/save" + m_sceneName[0] + rankStream.str()+ "/data.sav"; - - // sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->GetGamerName(), m_sceneName[0], j); - file = fopen(fs::path(filename).make_preferred().string().c_str(), "r"); - if ( file == NULL ) break; - - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { - if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { - line[i] = 0; - break; + if ( Cmd(line, "Title") ) { + OpString(line, "text", name); + break; + } } - } + fclose(file); - if ( Cmd(line, "Title") ) - { - OpString(line, "text", name); - break; + pl->SetName(m_saveList.size(), name); + m_saveList.push_back(dir_iter->path()); } } - fclose(file); - - pl->SetName(j, name); } - - if ( m_phase == PHASE_WRITE || - m_phase == PHASE_WRITEs ) - { + + // zly indeks + if ( m_phase == PHASE_WRITE || m_phase == PHASE_WRITEs ) { GetResource(RES_TEXT, RT_IO_NEW, name); - pl->SetName(j, name); - j ++; + pl->SetName(m_saveList.size(), name); } - pl->SetSelect(j-1); + pl->SetSelect(m_saveList.size()); pl->ShowSelect(false); // shows the selected columns } @@ -4403,35 +4404,31 @@ void CMainDialog::IOUpdateList() int sel, max; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); - if ( pw == 0 ) return; + if ( pw == nullptr ) return; pl = static_cast(pw->SearchControl(EVENT_INTERFACE_IOLIST)); - if ( pl == 0 ) return; + if ( pl == nullptr ) return; pi = static_cast(pw->SearchControl(EVENT_INTERFACE_IOIMAGE)); - if ( pi == 0 ) return; + if ( pi == nullptr ) return; sel = pl->GetSelect(); max = pl->GetTotal(); - std::string filename; - std::ostringstream rankStream; - rankStream << std::setfill('0') << std::setw(3) << sel; - filename = m_savegameDir + "/" + m_main->GetGamerName() + "/save" + m_sceneName[0] + rankStream.str()+ "/screen.png"; - - if ( m_phase == PHASE_WRITE || - m_phase == PHASE_WRITEs ) + if (m_saveList.size() <= static_cast(sel)) { + return; + } + + std::string filename = (m_saveList.at(sel) / "screen.png").make_preferred().string(); + if ( m_phase == PHASE_WRITE || m_phase == PHASE_WRITEs ) { - if ( sel < max-1 ) - { + if ( sel < max-1 ) { pi->SetFilenameImage(filename.c_str()); } - else - { + else { pi->SetFilenameImage(""); } pb = static_cast(pw->SearchControl(EVENT_INTERFACE_IODELETE)); - if ( pb != 0 ) - { + if ( pb != nullptr ) { pb->SetState(STATE_ENABLE, sel < max-1); } } @@ -4455,34 +4452,40 @@ void CMainDialog::IODeleteScene() if ( pl == 0 ) return; sel = pl->GetSelect(); - if ( sel == -1 ) + if ( sel == -1 || m_saveList.size() <= static_cast(sel)) { m_sound->Play(SOUND_TZOING); return; } - - std::ostringstream rankStream; - std::string fileName; - rankStream << std::setfill('0') << std::setw(3) << sel; - fileName = m_savegameDir + "/" + m_main->GetGamerName() + "/save" + m_sceneName[0] + rankStream.str(); try { - if (fs::exists(fileName) && fs::is_directory(fileName)) - { - fs::remove_all(fileName); + if (fs::exists(m_saveList.at(sel)) && fs::is_directory(m_saveList.at(sel))) { + fs::remove_all(m_saveList.at(sel)); } } - catch (std::exception & e) - { - GetLogger()->Error("Error on removing directory %s : %s\n", e.what()); + catch (std::exception & e) { + GetLogger()->Error("Error removing save %s : %s\n", pl->GetName(sel), e.what()); } IOReadList(); } -// Writes the scene. +// clears filename only to leave letter or numbers +std::string clearName(char *name) +{ + std::string ret; + int len = strlen(name); + for (int i = 0; i < len; i++) { + if (isalnum(name[i])) { + ret += name[i]; + } + } + return ret; +} + +// Writes the scene. bool CMainDialog::IOWriteScene() { CWindow* pw; @@ -4492,36 +4495,35 @@ bool CMainDialog::IOWriteScene() int sel; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); - if ( pw == 0 ) return false; + if ( pw == nullptr ) return false; pl = static_cast(pw->SearchControl(EVENT_INTERFACE_IOLIST)); - if ( pl == 0 ) return false; + if ( pl == nullptr ) return false; pe = static_cast(pw->SearchControl(EVENT_INTERFACE_IONAME)); - if ( pe == 0 ) return false; + if ( pe == nullptr ) return false; sel = pl->GetSelect(); - if ( sel == -1 ) return false; - - std::string directoryName; - std::string fileName; - std::string fileCBot; - std::ostringstream selectStream; - - //TODO: Change this to point user dir according to operating system - GetLogger()->Debug("Creating save directory\n"); - selectStream << std::setfill('0') << std::setw(3) << sel; - directoryName = m_savegameDir + "/" + m_main->GetGamerName() + "/" + "save" + m_sceneName[0] + selectStream.str(); - if (!fs::exists(directoryName)) - { - fs::create_directories(directoryName); + if ( sel == -1 ) { + return false; } - - fileName = directoryName + "/data.sav"; - fileCBot = directoryName + "/cbot.run"; + + fs::path dir; pe->GetText(info, 100); + if (static_cast(sel) >= m_saveList.size()) { + dir = fs::path(m_savegameDir) / m_main->GetGamerName() / ("save" + clearName(info)); + } else { + dir = m_saveList.at(sel); + } + + if (!fs::exists(dir)) { + fs::create_directories(dir); + } + + std::string fileName = (dir / "data.sav").make_preferred().string(); + std::string fileCBot = (dir / "cbot.run").make_preferred().string(); m_main->IOWriteScene(fileName.c_str(), fileCBot.c_str(), info); m_shotDelay = 3; - m_shotName = directoryName + "/screen.png"; + m_shotName = (dir / "screen.png").make_preferred().string(); return true; } @@ -4538,58 +4540,46 @@ bool CMainDialog::IOReadScene() int sel, i; pw = static_cast(m_interface->SearchControl(EVENT_WINDOW5)); - if ( pw == 0 ) return false; + if ( pw == nullptr ) return false; pl = static_cast(pw->SearchControl(EVENT_INTERFACE_IOLIST)); - if ( pl == 0 ) return false; + if ( pl == nullptr ) return false; sel = pl->GetSelect(); - if ( sel == -1 ) return false; - - //TODO: Change this to point user dir according to operating system - std::string fileName; - std::string fileCbot; - std::string directoryName; - std::ostringstream selectStream; - selectStream << std::setfill('0') << std::setw(3) << sel; - directoryName = m_savegameDir + "/" + m_main->GetGamerName() + "/" + "save" + m_sceneName[0] + selectStream.str(); + if ( sel == -1 || m_saveList.size() <= static_cast(sel) ) { + return false; + } - fileName = directoryName + "/data.sav"; - fileCbot = directoryName + "/cbot.run"; + std::string fileName = (m_saveList.at(sel) / "data.sav").make_preferred().string(); + std::string fileCbot = (m_saveList.at(sel) / "cbot.run").make_preferred().string(); file = fopen(fileName.c_str(), "r"); - if ( file == NULL ) return false; + if ( file == NULL ) { + return false; + } - while ( fgets(line, 500, file) != NULL ) - { - for ( i=0 ; i<500 ; i++ ) - { + while ( fgets(line, 500, file) != NULL ) { + for ( i=0 ; i<500 ; i++ ) { if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space - if ( line[i] == '/' && line[i+1] == '/' ) - { + if ( line[i] == '/' && line[i+1] == '/' ) { line[i] = 0; break; } } - if ( Cmd(line, "Mission") ) - { + if ( Cmd(line, "Mission") ) { OpString(line, "base", m_sceneName); m_sceneRank = OpInt(line, "rank", 0); - if ( strcmp(m_sceneName, "user") == 0 ) - { + if ( strcmp(m_sceneName, "user") == 0 ) { m_sceneRank = m_sceneRank%100; OpString(line, "dir", dir); - for ( i=0 ; iSetNumericLocale(); + sprintf(line, "Head face=%d glasses=%d hair=%.2f;%.2f;%.2f;%.2f\n", m_perso.face, m_perso.glasses, m_perso.colorHair.r, m_perso.colorHair.g, m_perso.colorHair.b, m_perso.colorHair.a); @@ -6553,6 +6545,8 @@ void CMainDialog::WriteGamerPerso(char *gamer) fputs(line, file); fclose(file); + + m_main->RestoreNumericLocale(); } // Reads the personalized player. @@ -6570,6 +6564,8 @@ void CMainDialog::ReadGamerPerso(char *gamer) sprintf(filename, "%s/%s/face.gam", m_savegameDir.c_str(), gamer); file = fopen(filename, "r"); if ( file == NULL ) return; + + m_main->SetNumericLocale(); while ( fgets(line, 100, file) != NULL ) { @@ -6602,6 +6598,8 @@ void CMainDialog::ReadGamerPerso(char *gamer) } fclose(file); + + m_main->RestoreNumericLocale(); } // Specifies the face of the player. diff --git a/src/ui/maindialog.h b/src/ui/maindialog.h index a79b95e..afdf94f 100644 --- a/src/ui/maindialog.h +++ b/src/ui/maindialog.h @@ -26,6 +26,8 @@ #include #include +#include + namespace fs = boost::filesystem; @@ -260,6 +262,8 @@ protected: Math::Point m_partiPos[10]; SceneInfo m_sceneInfo[MAXSCENE]; + + std::vector m_saveList; }; } // namespace Ui -- cgit v1.2.3-1-g7c22