* 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
dev-ui
erihel 2013-04-01 18:24:12 +02:00
parent 9485e1a95f
commit 926126d5ad
4 changed files with 168 additions and 134 deletions

View File

@ -3873,12 +3873,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
int rankGadget = 0; int rankGadget = 0;
CObject* sel = 0; CObject* sel = 0;
std::string oldLocale; SetNumericLocale();
char *locale = setlocale(LC_NUMERIC, nullptr);
if (locale != nullptr)
oldLocale = locale;
setlocale(LC_NUMERIC, "C");
while (fgets(line, 500, file) != NULL) while (fgets(line, 500, file) != NULL)
{ {
@ -4746,7 +4741,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_dialog->SetSceneRead(""); m_dialog->SetSceneRead("");
m_dialog->SetStackRead(""); m_dialog->SetStackRead("");
setlocale(LC_NUMERIC, oldLocale.c_str()); RestoreNumericLocale();
} }
//! Creates an object of decoration mobile or stationary //! 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) void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd)
{ {
if (obj->GetType() == OBJECT_FIX) return; if (obj->GetType() == OBJECT_FIX) return;
SetNumericLocale();
char line[3000]; char line[3000];
char name[100]; char name[100];
@ -6040,6 +6037,8 @@ void CRobotMain::IOWriteObject(FILE *file, CObject* obj, const char *cmd)
strcat(line, "\n"); strcat(line, "\n");
fputs(line, file); fputs(line, file);
RestoreNumericLocale();
} }
//! Saves the current game //! Saves the current game
@ -6047,6 +6046,8 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *
{ {
FILE* file = fopen(filename, "w"); FILE* file = fopen(filename, "w");
if (file == NULL) return false; if (file == NULL) return false;
SetNumericLocale();
char line[500]; char line[500];
@ -6109,6 +6110,8 @@ bool CRobotMain::IOWriteScene(const char *filename, const char *filecbot, char *
SaveFileScript(obj, filename, objRank++); SaveFileScript(obj, filename, objRank++);
} }
fclose(file); fclose(file);
RestoreNumericLocale();
#if CBOT_STACK #if CBOT_STACK
// Writes the file of stacks of execution. // 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) if (type == OBJECT_NULL)
return nullptr; return nullptr;
SetNumericLocale();
int trainer = OpInt(line, "trainer", 0); int trainer = OpInt(line, "trainer", 0);
int toy = OpInt(line, "toy", 0); int toy = OpInt(line, "toy", 0);
int option = OpInt(line, "option", 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 automat->Start(run); // starts the film
} }
RestoreNumericLocale();
return obj; return obj;
} }
@ -6229,6 +6236,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
FILE* file = fopen(filename, "r"); FILE* file = fopen(filename, "r");
if (file == NULL) return 0; if (file == NULL) return 0;
SetNumericLocale();
CObject* fret = nullptr; CObject* fret = nullptr;
CObject* power = nullptr; CObject* power = nullptr;
@ -6351,6 +6360,8 @@ CObject* CRobotMain::IOReadScene(const char *filename, const char *filecbot)
} }
#endif #endif
RestoreNumericLocale();
return sel; return sel;
} }
@ -7047,3 +7058,18 @@ void CRobotMain::ClearInterface()
HiliteClear(); // removes setting evidence HiliteClear(); // removes setting evidence
m_tooltipName[0] = 0; // really removes the tooltip 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());
}

View File

@ -352,6 +352,9 @@ public:
CObject* IOReadObject(char *line, const char* filename, int objRank); CObject* IOReadObject(char *line, const char* filename, int objRank);
int CreateSpot(Math::Vector pos, Gfx::Color color); int CreateSpot(Math::Vector pos, Gfx::Color color);
void SetNumericLocale();
void RestoreNumericLocale();
protected: protected:
bool EventFrame(const Event &event); bool EventFrame(const Event &event);
@ -390,6 +393,7 @@ protected:
void ExecuteCmd(char *cmd); void ExecuteCmd(char *cmd);
bool TestGadgetQuantity(int rank); bool TestGadgetQuantity(int rank);
void UpdateSpeedLabel(); void UpdateSpeedLabel();
protected: protected:
CApplication* m_app; CApplication* m_app;
@ -540,5 +544,7 @@ protected:
Gfx::Color m_colorRefWater; Gfx::Color m_colorRefWater;
Gfx::Color m_colorNewWater; Gfx::Color m_colorNewWater;
float m_colorShiftWater; float m_colorShiftWater;
std::string m_oldLocale;
}; };

View File

@ -4256,14 +4256,18 @@ void CMainDialog::DefPerso()
bool CMainDialog::IsIOReadScene() bool CMainDialog::IsIOReadScene()
{ {
FILE* file; fs::directory_iterator end_iter;
std::string filename;
fs::path saveDir(m_savegameDir + "/" + m_main->GetGamerName());
filename = m_savegameDir + "/" + m_main->GetGamerName() + "/" + "save" + m_sceneName[0] + "000/data.sav"; if (fs::exists(saveDir) && fs::is_directory(saveDir)) {
file = fopen(filename.c_str(), "r"); for( fs::directory_iterator dir_iter(saveDir) ; dir_iter != end_iter ; ++dir_iter) {
if ( file == NULL ) return false; if ( fs::is_directory(dir_iter->status()) && fs::exists(dir_iter->path() / "data.sav") ) {
fclose(file); return true;
return true; }
}
}
return false;
} }
// Builds the file name by default. // Builds the file name by default.
@ -4283,9 +4287,9 @@ void CMainDialog::IOReadName()
int i; int i;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5)); 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)); 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); sprintf(resume, "%s %d", m_sceneName, m_chap[m_index]+1);
BuildSceneName(filename, m_sceneName, (m_chap[m_index]+1)*100); BuildSceneName(filename, m_sceneName, (m_chap[m_index]+1)*100);
@ -4337,7 +4341,8 @@ void CMainDialog::IOReadList()
CList* pl; CList* pl;
char line[500]; char line[500];
char name[100]; char name[100];
int i, j; int i;
fs::directory_iterator end_iter;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5)); pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5));
if ( pw == 0 ) return; if ( pw == 0 ) return;
@ -4345,50 +4350,46 @@ void CMainDialog::IOReadList()
if ( pl == 0 ) return; if ( pl == 0 ) return;
pl->Flush(); 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;
for ( j=0 ; j<999 ; j++ ) while ( fgets(line, 500, file) != NULL ) {
{ for ( i=0 ; i<500 ; i++ ) {
std::string filename; if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
std::ostringstream rankStream; if ( line[i] == '/' && line[i+1] == '/' ) {
rankStream << std::setfill('0') << std::setw(3) << j; line[i] = 0;
filename = m_savegameDir + "/" + m_main->GetGamerName() + "/save" + m_sceneName[0] + rankStream.str()+ "/data.sav"; break;
}
}
// sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->GetGamerName(), m_sceneName[0], j); if ( Cmd(line, "Title") ) {
file = fopen(fs::path(filename).make_preferred().string().c_str(), "r"); OpString(line, "text", name);
if ( file == NULL ) break; 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;
} }
} fclose(file);
if ( Cmd(line, "Title") ) pl->SetName(m_saveList.size(), name);
{ m_saveList.push_back(dir_iter->path());
OpString(line, "text", name);
break;
} }
} }
fclose(file);
pl->SetName(j, name);
} }
if ( m_phase == PHASE_WRITE || // zly indeks
m_phase == PHASE_WRITEs ) if ( m_phase == PHASE_WRITE || m_phase == PHASE_WRITEs ) {
{
GetResource(RES_TEXT, RT_IO_NEW, name); GetResource(RES_TEXT, RT_IO_NEW, name);
pl->SetName(j, name); pl->SetName(m_saveList.size(), name);
j ++;
} }
pl->SetSelect(j-1); pl->SetSelect(m_saveList.size());
pl->ShowSelect(false); // shows the selected columns pl->ShowSelect(false); // shows the selected columns
} }
@ -4403,35 +4404,31 @@ void CMainDialog::IOUpdateList()
int sel, max; int sel, max;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5)); 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)); 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)); pi = static_cast<CImage*>(pw->SearchControl(EVENT_INTERFACE_IOIMAGE));
if ( pi == 0 ) return; if ( pi == nullptr ) return;
sel = pl->GetSelect(); sel = pl->GetSelect();
max = pl->GetTotal(); max = pl->GetTotal();
std::string filename; if (m_saveList.size() <= static_cast<unsigned int>(sel)) {
std::ostringstream rankStream; return;
rankStream << std::setfill('0') << std::setw(3) << sel; }
filename = m_savegameDir + "/" + m_main->GetGamerName() + "/save" + m_sceneName[0] + rankStream.str()+ "/screen.png";
std::string filename = (m_saveList.at(sel) / "screen.png").make_preferred().string();
if ( m_phase == PHASE_WRITE || if ( m_phase == PHASE_WRITE || m_phase == PHASE_WRITEs )
m_phase == PHASE_WRITEs )
{ {
if ( sel < max-1 ) if ( sel < max-1 ) {
{
pi->SetFilenameImage(filename.c_str()); pi->SetFilenameImage(filename.c_str());
} }
else else {
{
pi->SetFilenameImage(""); pi->SetFilenameImage("");
} }
pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_IODELETE)); pb = static_cast<CButton*>(pw->SearchControl(EVENT_INTERFACE_IODELETE));
if ( pb != 0 ) if ( pb != nullptr ) {
{
pb->SetState(STATE_ENABLE, sel < max-1); pb->SetState(STATE_ENABLE, sel < max-1);
} }
} }
@ -4455,34 +4452,40 @@ void CMainDialog::IODeleteScene()
if ( pl == 0 ) return; if ( pl == 0 ) return;
sel = pl->GetSelect(); sel = pl->GetSelect();
if ( sel == -1 ) if ( sel == -1 || m_saveList.size() <= static_cast<unsigned int>(sel))
{ {
m_sound->Play(SOUND_TZOING); m_sound->Play(SOUND_TZOING);
return; 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 try
{ {
if (fs::exists(fileName) && fs::is_directory(fileName)) if (fs::exists(m_saveList.at(sel)) && fs::is_directory(m_saveList.at(sel))) {
{ fs::remove_all(m_saveList.at(sel));
fs::remove_all(fileName);
} }
} }
catch (std::exception & e) catch (std::exception & e) {
{ GetLogger()->Error("Error removing save %s : %s\n", pl->GetName(sel), e.what());
GetLogger()->Error("Error on removing directory %s : %s\n", e.what());
} }
IOReadList(); 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() bool CMainDialog::IOWriteScene()
{ {
CWindow* pw; CWindow* pw;
@ -4492,36 +4495,35 @@ bool CMainDialog::IOWriteScene()
int sel; int sel;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5)); 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)); 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)); pe = static_cast<CEdit*>(pw->SearchControl(EVENT_INTERFACE_IONAME));
if ( pe == 0 ) return false; if ( pe == nullptr ) return false;
sel = pl->GetSelect(); sel = pl->GetSelect();
if ( sel == -1 ) return false; if ( sel == -1 ) {
return false;
std::string directoryName; }
std::string fileName;
std::string fileCBot; fs::path dir;
std::ostringstream selectStream; pe->GetText(info, 100);
if (static_cast<unsigned int>(sel) >= m_saveList.size()) {
//TODO: Change this to point user dir according to operating system dir = fs::path(m_savegameDir) / m_main->GetGamerName() / ("save" + clearName(info));
GetLogger()->Debug("Creating save directory\n"); } else {
selectStream << std::setfill('0') << std::setw(3) << sel; dir = m_saveList.at(sel);
directoryName = m_savegameDir + "/" + m_main->GetGamerName() + "/" + "save" + m_sceneName[0] + selectStream.str(); }
if (!fs::exists(directoryName))
{ if (!fs::exists(dir)) {
fs::create_directories(directoryName); fs::create_directories(dir);
} }
fileName = directoryName + "/data.sav"; std::string fileName = (dir / "data.sav").make_preferred().string();
fileCBot = directoryName + "/cbot.run"; std::string fileCBot = (dir / "cbot.run").make_preferred().string();
pe->GetText(info, 100);
m_main->IOWriteScene(fileName.c_str(), fileCBot.c_str(), info); m_main->IOWriteScene(fileName.c_str(), fileCBot.c_str(), info);
m_shotDelay = 3; m_shotDelay = 3;
m_shotName = directoryName + "/screen.png"; m_shotName = (dir / "screen.png").make_preferred().string();
return true; return true;
} }
@ -4538,58 +4540,46 @@ bool CMainDialog::IOReadScene()
int sel, i; int sel, i;
pw = static_cast<CWindow*>(m_interface->SearchControl(EVENT_WINDOW5)); 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)); pl = static_cast<CList*>(pw->SearchControl(EVENT_INTERFACE_IOLIST));
if ( pl == 0 ) return false; if ( pl == nullptr ) return false;
sel = pl->GetSelect(); sel = pl->GetSelect();
if ( sel == -1 ) return false; if ( sel == -1 || m_saveList.size() <= static_cast<unsigned int>(sel) ) {
return false;
}
//TODO: Change this to point user dir according to operating system std::string fileName = (m_saveList.at(sel) / "data.sav").make_preferred().string();
std::string fileName; std::string fileCbot = (m_saveList.at(sel) / "cbot.run").make_preferred().string();
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();
fileName = directoryName + "/data.sav";
fileCbot = directoryName + "/cbot.run";
file = fopen(fileName.c_str(), "r"); file = fopen(fileName.c_str(), "r");
if ( file == NULL ) return false; if ( file == NULL ) {
return false;
}
while ( fgets(line, 500, file) != NULL ) while ( fgets(line, 500, file) != NULL ) {
{ for ( i=0 ; i<500 ; i++ ) {
for ( i=0 ; i<500 ; i++ )
{
if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space 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; line[i] = 0;
break; break;
} }
} }
if ( Cmd(line, "Mission") ) if ( Cmd(line, "Mission") ) {
{
OpString(line, "base", m_sceneName); OpString(line, "base", m_sceneName);
m_sceneRank = OpInt(line, "rank", 0); m_sceneRank = OpInt(line, "rank", 0);
if ( strcmp(m_sceneName, "user") == 0 ) if ( strcmp(m_sceneName, "user") == 0 ) {
{
m_sceneRank = m_sceneRank%100; m_sceneRank = m_sceneRank%100;
OpString(line, "dir", dir); OpString(line, "dir", dir);
for ( i=0 ; i<m_userTotal ; i++ ) for ( i=0 ; i<m_userTotal ; i++ ) {
{ if ( strcmp(m_userList[i].c_str(), dir) == 0 ) {
if ( strcmp(m_userList[i].c_str(), dir) == 0 )
{
m_sceneRank += (i+1)*100; m_sceneRank += (i+1)*100;
break; break;
} }
} }
if ( m_sceneRank/100 == 0 ) if ( m_sceneRank/100 == 0 ) {
{
fclose(file); fclose(file);
return false; return false;
} }
@ -4598,8 +4588,8 @@ bool CMainDialog::IOReadScene()
} }
fclose(file); fclose(file);
m_chap[m_index] = (m_sceneRank/100)-1; m_chap[m_index] = (m_sceneRank / 100)-1;
m_sel[m_index] = (m_sceneRank%100)-1; m_sel[m_index] = (m_sceneRank % 100)-1;
m_sceneRead = fileName; m_sceneRead = fileName;
m_stackRead = fileCbot; m_stackRead = fileCbot;
@ -6542,6 +6532,8 @@ void CMainDialog::WriteGamerPerso(char *gamer)
file = fopen(filename, "w"); file = fopen(filename, "w");
if ( file == NULL ) return; if ( file == NULL ) return;
m_main->SetNumericLocale();
sprintf(line, "Head face=%d glasses=%d hair=%.2f;%.2f;%.2f;%.2f\n", sprintf(line, "Head face=%d glasses=%d hair=%.2f;%.2f;%.2f;%.2f\n",
m_perso.face, m_perso.glasses, m_perso.face, m_perso.glasses,
m_perso.colorHair.r, m_perso.colorHair.g, m_perso.colorHair.b, m_perso.colorHair.a); 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); fputs(line, file);
fclose(file); fclose(file);
m_main->RestoreNumericLocale();
} }
// Reads the personalized player. // Reads the personalized player.
@ -6570,6 +6564,8 @@ void CMainDialog::ReadGamerPerso(char *gamer)
sprintf(filename, "%s/%s/face.gam", m_savegameDir.c_str(), gamer); sprintf(filename, "%s/%s/face.gam", m_savegameDir.c_str(), gamer);
file = fopen(filename, "r"); file = fopen(filename, "r");
if ( file == NULL ) return; if ( file == NULL ) return;
m_main->SetNumericLocale();
while ( fgets(line, 100, file) != NULL ) while ( fgets(line, 100, file) != NULL )
{ {
@ -6602,6 +6598,8 @@ void CMainDialog::ReadGamerPerso(char *gamer)
} }
fclose(file); fclose(file);
m_main->RestoreNumericLocale();
} }
// Specifies the face of the player. // Specifies the face of the player.

View File

@ -26,6 +26,8 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <vector>
namespace fs = boost::filesystem; namespace fs = boost::filesystem;
@ -260,6 +262,8 @@ protected:
Math::Point m_partiPos[10]; Math::Point m_partiPos[10];
SceneInfo m_sceneInfo[MAXSCENE]; SceneInfo m_sceneInfo[MAXSCENE];
std::vector<fs::path> m_saveList;
}; };
} // namespace Ui } // namespace Ui