1
0
Fork 0
mirror of https://github.com/TerryCavanagh/VVVVVV.git synced 2024-12-22 17:49:43 +01:00

Replace TiXmlDocument load and save functions by PHYSFS

The TinyXml functions to load and save files don't properly support
unicode file paths on Windows, so in order to support that properly, I
saw no other option than to do the actual loading and saving via PHYSFS
(or to use the Windows API on Windows and retain doc.LoadFile and
doc.SaveFile on other OSes, but that'd be more complicated and
unnecessary, we already have PHYSFS, right?).

There are two new functions in FileSystemUtils:
bool FILESYSTEM_saveTiXmlDocument(const char *name, TiXmlDocument *doc)
bool FILESYSTEM_loadTiXmlDocument(const char *name, TiXmlDocument *doc)

Any instances of doc.SaveFile(<FULL_PATH>) have been replaced by
FILESYSTEM_saveTiXmlDocument(<VVVVVV_FOLDER_PATH>, &doc), where
<FULL_PATH> included the full path to the saves or levels directory,
and <VVVVVV_FOLDER_PATH> only includes the path relative to the VVVVVV
directory.
When loading a document, a TiXmlDocument used to be created with a full
path in its constructor and doc.LoadFile() would then be called, now a
TiXmlDocument is constructed with no path name and
FILESYSTEM_loadTiXmlDocument(<VVVVVV_FOLDER_PATH>, &doc) is called.
This commit is contained in:
Dav999-v 2020-01-12 15:17:39 +01:00 committed by Ethan Lee
parent ddaa5e13c8
commit b884b7e4e9
5 changed files with 61 additions and 23 deletions

View file

@ -10,6 +10,8 @@
#include <SDL.h> #include <SDL.h>
#include <physfs.h> #include <physfs.h>
#include "tinyxml.h"
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h> #include <windows.h>
#include <shlobj.h> #include <shlobj.h>
@ -53,6 +55,7 @@ int FILESYSTEM_init(char *argvZero)
/* Mount our base user directory */ /* Mount our base user directory */
PHYSFS_mount(output, NULL, 1); PHYSFS_mount(output, NULL, 1);
PHYSFS_setWriteDir(output);
printf("Base directory: %s\n", output); printf("Base directory: %s\n", output);
/* Create save directory */ /* Create save directory */
@ -136,6 +139,35 @@ void FILESYSTEM_freeMemory(unsigned char **mem)
*mem = NULL; *mem = NULL;
} }
bool FILESYSTEM_saveTiXmlDocument(const char *name, TiXmlDocument *doc)
{
/* TiXmlDocument.SaveFile doesn't account for Unicode paths, PHYSFS does */
TiXmlPrinter printer;
doc->Accept(&printer);
PHYSFS_File* handle = PHYSFS_openWrite(name);
if (handle == NULL)
{
return false;
}
PHYSFS_writeBytes(handle, printer.CStr(), printer.Size());
PHYSFS_close(handle);
return true;
}
bool FILESYSTEM_loadTiXmlDocument(const char *name, TiXmlDocument *doc)
{
/* TiXmlDocument.SaveFile doesn't account for Unicode paths, PHYSFS does */
unsigned char *mem = NULL;
FILESYSTEM_loadFileToMemory(name, &mem, NULL);
if (mem == NULL)
{
return false;
}
doc->Parse((const char*)mem);
FILESYSTEM_freeMemory(&mem);
return true;
}
std::vector<std::string> FILESYSTEM_getLevelDirFileNames() std::vector<std::string> FILESYSTEM_getLevelDirFileNames()
{ {
std::vector<std::string> list; std::vector<std::string> list;

View file

@ -4,6 +4,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "tinyxml.h"
int FILESYSTEM_init(char *argvZero); int FILESYSTEM_init(char *argvZero);
void FILESYSTEM_deinit(); void FILESYSTEM_deinit();
@ -12,6 +14,8 @@ char *FILESYSTEM_getUserLevelDirectory();
void FILESYSTEM_loadFileToMemory(const char *name, unsigned char **mem, size_t *len); void FILESYSTEM_loadFileToMemory(const char *name, unsigned char **mem, size_t *len);
void FILESYSTEM_freeMemory(unsigned char **mem); void FILESYSTEM_freeMemory(unsigned char **mem);
bool FILESYSTEM_saveTiXmlDocument(const char *name, TiXmlDocument *doc);
bool FILESYSTEM_loadTiXmlDocument(const char *name, TiXmlDocument *doc);
std::vector<std::string> FILESYSTEM_getLevelDirFileNames(); std::vector<std::string> FILESYSTEM_getLevelDirFileNames();

View file

@ -293,8 +293,8 @@ Game::Game(void):
saveFilePath = FILESYSTEM_getUserSaveDirectory(); saveFilePath = FILESYSTEM_getUserSaveDirectory();
TiXmlDocument doc((saveFilePath + "qsave.vvv").c_str()); TiXmlDocument doc;
if (!doc.LoadFile()) if (!FILESYSTEM_loadTiXmlDocument("saves/qsave.vvv", &doc))
{ {
quickcookieexists = false; quickcookieexists = false;
quicksummary = ""; quicksummary = "";
@ -470,8 +470,8 @@ void Game::loadcustomlevelstats()
//testing //testing
if(!customlevelstatsloaded) if(!customlevelstatsloaded)
{ {
TiXmlDocument doc((saveFilePath+"levelstats.vvv").c_str()); TiXmlDocument doc;
if (!doc.LoadFile()) if (!FILESYSTEM_loadTiXmlDocument("saves/levelstats.vvv", &doc))
{ {
//No levelstats file exists; start new //No levelstats file exists; start new
numcustomlevelstats=0; numcustomlevelstats=0;
@ -581,7 +581,7 @@ void Game::savecustomlevelstats()
msg->LinkEndChild( new TiXmlText( customlevelstatsstr.c_str() )); msg->LinkEndChild( new TiXmlText( customlevelstatsstr.c_str() ));
msgs->LinkEndChild( msg ); msgs->LinkEndChild( msg );
if(doc.SaveFile( (saveFilePath+"levelstats.vvv").c_str() )) if(FILESYSTEM_saveTiXmlDocument("saves/levelstats.vvv", &doc))
{ {
printf("Level stats saved\n"); printf("Level stats saved\n");
} }
@ -4105,8 +4105,8 @@ void Game::unlocknum( int t, mapclass& map, Graphics& dwgfx )
void Game::loadstats( mapclass& map, Graphics& dwgfx ) void Game::loadstats( mapclass& map, Graphics& dwgfx )
{ {
// TODO loadstats // TODO loadstats
TiXmlDocument doc((saveFilePath+"unlock.vvv").c_str()); TiXmlDocument doc;
if (!doc.LoadFile()) if (!FILESYSTEM_loadTiXmlDocument("saves/unlock.vvv", &doc))
{ {
savestats(map, dwgfx); savestats(map, dwgfx);
printf("No Stats found. Assuming a new player\n"); printf("No Stats found. Assuming a new player\n");
@ -4564,7 +4564,7 @@ void Game::savestats( mapclass& _map, Graphics& _dwgfx )
msg->LinkEndChild( new TiXmlText( tu.String(controllerSensitivity).c_str())); msg->LinkEndChild( new TiXmlText( tu.String(controllerSensitivity).c_str()));
dataNode->LinkEndChild( msg ); dataNode->LinkEndChild( msg );
doc.SaveFile( (saveFilePath+"unlock.vvv").c_str() ); FILESYSTEM_saveTiXmlDocument("saves/unlock.vvv", &doc);
} }
void Game::customstart( entityclass& obj, musicclass& music ) void Game::customstart( entityclass& obj, musicclass& music )
@ -4792,8 +4792,8 @@ void Game::starttrial( int t, entityclass& obj, musicclass& music )
void Game::loadquick( mapclass& map, entityclass& obj, musicclass& music ) void Game::loadquick( mapclass& map, entityclass& obj, musicclass& music )
{ {
TiXmlDocument doc((saveFilePath+"qsave.vvv").c_str()); TiXmlDocument doc;
if (!doc.LoadFile()) return; ; if (!FILESYSTEM_loadTiXmlDocument("saves/qsave.vvv", &doc)) return;
TiXmlHandle hDoc(&doc); TiXmlHandle hDoc(&doc);
TiXmlElement* pElem; TiXmlElement* pElem;
@ -5014,8 +5014,8 @@ void Game::loadquick( mapclass& map, entityclass& obj, musicclass& music )
void Game::customloadquick(std::string savfile, mapclass& map, entityclass& obj, musicclass& music ) void Game::customloadquick(std::string savfile, mapclass& map, entityclass& obj, musicclass& music )
{ {
std::string levelfile = savfile.substr(7); std::string levelfile = savfile.substr(7);
TiXmlDocument doc((saveFilePath+levelfile+".vvv").c_str()); TiXmlDocument doc;
if (!doc.LoadFile()) return; ; if (!FILESYSTEM_loadTiXmlDocument(("saves/"+levelfile+".vvv").c_str(), &doc)) return;
TiXmlHandle hDoc(&doc); TiXmlHandle hDoc(&doc);
TiXmlElement* pElem; TiXmlElement* pElem;
@ -5389,8 +5389,8 @@ void Game::loadsummary( mapclass& map, UtilityClass& help )
tele_currentarea = map.currentarea(map.area(l_saveX, l_saveY)); tele_currentarea = map.currentarea(map.area(l_saveX, l_saveY));
} }
TiXmlDocument doc((saveFilePath+"qsave.vvv").c_str()); TiXmlDocument doc;
if (!doc.LoadFile()) if (!FILESYSTEM_loadTiXmlDocument("saves/qsave.vvv", &doc))
{ {
quickcookieexists = false; quickcookieexists = false;
quicksummary = ""; quicksummary = "";
@ -5734,7 +5734,7 @@ void Game::savetele( mapclass& map, entityclass& obj, musicclass& music )
//telecookie.flush(); //telecookie.flush();
//telecookie.close(); //telecookie.close();
if(doc.SaveFile( (saveFilePath+"tsave.vvv").c_str() )) if(FILESYSTEM_saveTiXmlDocument("saves/tsave.vvv", &doc))
{ {
printf("Game saved\n"); printf("Game saved\n");
} }
@ -5978,7 +5978,7 @@ void Game::savequick( mapclass& map, entityclass& obj, musicclass& music )
//telecookie.flush(); //telecookie.flush();
//telecookie.close(); //telecookie.close();
if(doc.SaveFile( (saveFilePath+ "qsave.vvv").c_str() )) if(FILESYSTEM_saveTiXmlDocument("saves/qsave.vvv", &doc))
{ {
printf("Game saved\n"); printf("Game saved\n");
} }
@ -6239,7 +6239,7 @@ void Game::customsavequick(std::string savfile, mapclass& map, entityclass& obj,
//telecookie.close(); //telecookie.close();
std::string levelfile = savfile.substr(7); std::string levelfile = savfile.substr(7);
if(doc.SaveFile( (saveFilePath+ levelfile+".vvv").c_str() )) if(FILESYSTEM_saveTiXmlDocument(("saves/"+levelfile+".vvv").c_str(), &doc))
{ {
printf("Game saved\n"); printf("Game saved\n");
} }
@ -6253,8 +6253,8 @@ void Game::customsavequick(std::string savfile, mapclass& map, entityclass& obj,
void Game::loadtele( mapclass& map, entityclass& obj, musicclass& music ) void Game::loadtele( mapclass& map, entityclass& obj, musicclass& music )
{ {
TiXmlDocument doc((saveFilePath+"tsave.vvv").c_str()); TiXmlDocument doc;
if (!doc.LoadFile()) return; ; if (!FILESYSTEM_loadTiXmlDocument("saves/tsave.vvv", &doc)) return;
TiXmlHandle hDoc(&doc); TiXmlHandle hDoc(&doc);
TiXmlElement* pElem; TiXmlElement* pElem;

View file

@ -4,6 +4,8 @@
#include "tinyxml.h" #include "tinyxml.h"
#include "FileSystemUtils.h"
// Found in titlerender.cpp // Found in titlerender.cpp
void updategraphicsmode(Game& game, Graphics& dwgfx); void updategraphicsmode(Game& game, Graphics& dwgfx);
@ -358,9 +360,9 @@ void titleinput(KeyPoll& key, Graphics& dwgfx, mapclass& map, Game& game, entity
game.customleveltitle=ed.ListOfMetaData[game.playcustomlevel].title; game.customleveltitle=ed.ListOfMetaData[game.playcustomlevel].title;
game.customlevelfilename=ed.ListOfMetaData[game.playcustomlevel].filename; game.customlevelfilename=ed.ListOfMetaData[game.playcustomlevel].filename;
std::string name = game.saveFilePath + ed.ListOfMetaData[game.playcustomlevel].filename.substr(7) + ".vvv"; std::string name = "saves/" + ed.ListOfMetaData[game.playcustomlevel].filename.substr(7) + ".vvv";
TiXmlDocument doc(name.c_str()); TiXmlDocument doc;
if (!doc.LoadFile()){ if (!FILESYSTEM_loadTiXmlDocument(name.c_str(), &doc)){
game.mainmenu = 22; game.mainmenu = 22;
dwgfx.fademode = 2; dwgfx.fademode = 2;
}else{ }else{

View file

@ -2107,7 +2107,7 @@ void editorclass::save(std::string& _path)
msg->LinkEndChild( new TiXmlText( scriptString.c_str() )); msg->LinkEndChild( new TiXmlText( scriptString.c_str() ));
data->LinkEndChild( msg ); data->LinkEndChild( msg );
doc.SaveFile((std::string(FILESYSTEM_getUserLevelDirectory()) + _path).c_str() ); FILESYSTEM_saveTiXmlDocument(("levels/" + _path).c_str(), &doc);
} }