* 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;
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());
}

View File

@ -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;
};

View File

@ -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;
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";
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;
}
}
// 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;
}
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);
}
fileName = directoryName + "/data.sav";
fileCBot = directoryName + "/cbot.run";
pe->GetText(info, 100);
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;
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;
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";
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.

View File

@ -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