summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerihel <erihel@gmail.com>2013-04-01 18:24:12 +0200
committererihel <erihel@gmail.com>2013-04-01 18:24:12 +0200
commit926126d5adf457dbc5c92fd83c7231415ea22d04 (patch)
treee61d3be2558432f2c92bacb4e3ad480ab73059ec
parent9485e1a95fc264beb121bc2fc92dd3303b80ce5e (diff)
downloadcolobot-926126d5adf457dbc5c92fd83c7231415ea22d04.tar.gz
colobot-926126d5adf457dbc5c92fd83c7231415ea22d04.tar.bz2
colobot-926126d5adf457dbc5c92fd83c7231415ea22d04.zip
* 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
-rw-r--r--src/object/robotmain.cpp40
-rw-r--r--src/object/robotmain.h6
-rw-r--r--src/ui/maindialog.cpp254
-rw-r--r--src/ui/maindialog.h4
4 files changed, 169 insertions, 135 deletions
diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp
index 733bf6b..2c890a4 100644
--- a/src/object/robotmain.cpp
+++ b/src/object/robotmain.cpp
@@ -3873,12 +3873,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
int rankGadget = 0;
CObject* sel = 0;
- std::string oldLocale;
- char *locale = setlocale(LC_NUMERIC, nullptr);
- if (locale != nullptr)
- oldLocale = locale;
-
- setlocale(LC_NUMERIC, "C");
+ SetNumericLocale();
while (fgets(line, 500, file) != NULL)
{
@@ -4746,7 +4741,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_dialog->SetSceneRead("");
m_dialog->SetStackRead("");
- setlocale(LC_NUMERIC, oldLocale.c_str());
+ RestoreNumericLocale();
}
//! Creates an object of decoration mobile or stationary
@@ -5953,6 +5948,8 @@ bool CRobotMain::IsBusy()
void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd)
{
if (obj->GetType() == OBJECT_FIX) return;
+
+ SetNumericLocale();
char line[3000];
char name[100];
@@ -6040,6 +6037,8 @@ void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd)
strcat(line, "\n");
fputs(line, file);
+
+ RestoreNumericLocale();
}
//! Saves the current game
@@ -6047,6 +6046,8 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *
{
FILE* file = fopen(filename, "w");
if (file == NULL) return false;
+
+ SetNumericLocale();
char line[500];
@@ -6109,6 +6110,8 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *
SaveFileScript(obj, filename, objRank++);
}
fclose(file);
+
+ RestoreNumericLocale();
#if CBOT_STACK
// Writes the file of stacks of execution.
@@ -6154,6 +6157,8 @@ CObject* CRobotMain::IOReadObject(char *line, const char* filename, int objRank)
if (type == OBJECT_NULL)
return nullptr;
+ SetNumericLocale();
+
int trainer = OpInt(line, "trainer", 0);
int toy = OpInt(line, "toy", 0);
int option = OpInt(line, "option", 0);
@@ -6219,6 +6224,8 @@ CObject* CRobotMain::IOReadObject(char *line, const char* filename, int objRank)
automat->Start(run); // starts the film
}
+ RestoreNumericLocale();
+
return obj;
}
@@ -6229,6 +6236,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
FILE* file = fopen(filename, "r");
if (file == NULL) return 0;
+
+ SetNumericLocale();
CObject* fret = nullptr;
CObject* power = nullptr;
@@ -6351,6 +6360,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
}
#endif
+ RestoreNumericLocale();
+
return sel;
}
@@ -7047,3 +7058,18 @@ void CRobotMain::ClearInterface()
HiliteClear(); // removes setting evidence
m_tooltipName[0] = 0; // really removes the tooltip
}
+
+void CRobotMain::SetNumericLocale()
+{
+ char *locale = setlocale(LC_NUMERIC, nullptr);
+ if (locale != nullptr)
+ m_oldLocale = locale;
+
+ setlocale(LC_NUMERIC, "C");
+}
+
+void CRobotMain::RestoreNumericLocale()
+{
+ setlocale(LC_NUMERIC, m_oldLocale.c_str());
+}
+ \ No newline at end of file
diff --git a/src/object/robotmain.h b/src/object/robotmain.h
index fe5fbd5..fc62072 100644
--- a/src/object/robotmain.h
+++ b/src/object/robotmain.h
@@ -352,6 +352,9 @@ public:
CObject* IOReadObject(char *line, const char* filename, int objRank);
int CreateSpot(Math::Vector pos, Gfx::Color color);
+
+ void SetNumericLocale();
+ void RestoreNumericLocale();
protected:
bool EventFrame(const Event &event);
@@ -390,6 +393,7 @@ protected:
void ExecuteCmd(char *cmd);
bool TestGadgetQuantity(int rank);
void UpdateSpeedLabel();
+
protected:
CApplication* m_app;
@@ -540,5 +544,7 @@ protected:
Gfx::Color m_colorRefWater;
Gfx::Color m_colorNewWater;
float m_colorShiftWater;
+
+ std::string m_oldLocale;
};
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<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
- if ( pw == 0 ) return;
+ if ( pw == nullptr ) return;
pe = static_cast<CEdit*>(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<CWindow*>(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<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
- if ( pw == 0 ) return;
+ if ( pw == nullptr ) return;
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_IOLIST));
- if ( pl == 0 ) return;
+ if ( pl == nullptr ) return;
pi = static_cast<CImage*>(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<unsigned int>(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<CButton*>(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<unsigned int>(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<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
- if ( pw == 0 ) return false;
+ if ( pw == nullptr ) return false;
pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_IOLIST));
- if ( pl == 0 ) return false;
+ if ( pl == nullptr ) return false;
pe = static_cast<CEdit*>(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<unsigned int>(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<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
- if ( pw == 0 ) return false;
+ if ( pw == nullptr ) return false;
pl = static_cast<CList*>(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<unsigned int>(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 ; i<m_userTotal ; i++ )
- {
- if ( strcmp(m_userList[i].c_str(), dir) == 0 )
- {
+ for ( i=0 ; i<m_userTotal ; i++ ) {
+ if ( strcmp(m_userList[i].c_str(), dir) == 0 ) {
m_sceneRank += (i+1)*100;
break;
}
}
- if ( m_sceneRank/100 == 0 )
- {
+ if ( m_sceneRank/100 == 0 ) {
fclose(file);
return false;
}
@@ -4598,8 +4588,8 @@ bool CMainDialog::IOReadScene()
}
fclose(file);
- m_chap[m_index] = (m_sceneRank/100)-1;
- m_sel[m_index] = (m_sceneRank%100)-1;
+ m_chap[m_index] = (m_sceneRank / 100)-1;
+ m_sel[m_index] = (m_sceneRank % 100)-1;
m_sceneRead = fileName;
m_stackRead = fileCbot;
@@ -6542,6 +6532,8 @@ void CMainDialog::WriteGamerPerso(char *gamer)
file = fopen(filename, "w");
if ( file == NULL ) return;
+ m_main->SetNumericLocale();
+
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 <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
+#include <vector>
+
namespace fs = boost::filesystem;
@@ -260,6 +262,8 @@ protected:
Math::Point m_partiPos[10];
SceneInfo m_sceneInfo[MAXSCENE];
+
+ std::vector<fs::path> m_saveList;
};
} // namespace Ui