Initial setup for saving game states
(code may or may not compile at this point)
This commit is contained in:
@@ -501,6 +501,8 @@
|
|||||||
91B3EF5B0F969F3000BF5B67 /* scen.dlgutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EEF60F969BA700BF5B67 /* scen.dlgutil.cpp */; };
|
91B3EF5B0F969F3000BF5B67 /* scen.dlgutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EEF60F969BA700BF5B67 /* scen.dlgutil.cpp */; };
|
||||||
91B3F1850F97894A00BF5B67 /* scen.graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EEF30F969BA700BF5B67 /* scen.graphics.cpp */; };
|
91B3F1850F97894A00BF5B67 /* scen.graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EEF30F969BA700BF5B67 /* scen.graphics.cpp */; };
|
||||||
91BFA3D71901B18F001686E4 /* mask.vert in Copy Shaders */ = {isa = PBXBuildFile; fileRef = 91BFA3D61901B024001686E4 /* mask.vert */; };
|
91BFA3D71901B18F001686E4 /* mask.vert in Copy Shaders */ = {isa = PBXBuildFile; fileRef = 91BFA3D61901B024001686E4 /* mask.vert */; };
|
||||||
|
91BFA3DA1902B13D001686E4 /* tarball.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3D81902AD78001686E4 /* tarball.cpp */; };
|
||||||
|
91BFA3DB1902B13F001686E4 /* tarball.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3D81902AD78001686E4 /* tarball.cpp */; };
|
||||||
91BFA3E919033E01001686E4 /* gzstream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3DE19033E01001686E4 /* gzstream.cpp */; };
|
91BFA3E919033E01001686E4 /* gzstream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3DE19033E01001686E4 /* gzstream.cpp */; };
|
||||||
91BFA3EA19033E01001686E4 /* gzstream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3DE19033E01001686E4 /* gzstream.cpp */; };
|
91BFA3EA19033E01001686E4 /* gzstream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3DE19033E01001686E4 /* gzstream.cpp */; };
|
||||||
91BFA3EB19033E01001686E4 /* gzstream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3DE19033E01001686E4 /* gzstream.cpp */; };
|
91BFA3EB19033E01001686E4 /* gzstream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3DE19033E01001686E4 /* gzstream.cpp */; };
|
||||||
@@ -1607,6 +1609,8 @@
|
|||||||
91B3F11D0F97801F00BF5B67 /* mathutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mathutil.h; sourceTree = "<group>"; };
|
91B3F11D0F97801F00BF5B67 /* mathutil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mathutil.h; sourceTree = "<group>"; };
|
||||||
91B3F11E0F97801F00BF5B67 /* mathutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mathutil.cpp; sourceTree = "<group>"; };
|
91B3F11E0F97801F00BF5B67 /* mathutil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = mathutil.cpp; sourceTree = "<group>"; };
|
||||||
91BFA3D61901B024001686E4 /* mask.vert */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = mask.vert; sourceTree = "<group>"; };
|
91BFA3D61901B024001686E4 /* mask.vert */ = {isa = PBXFileReference; explicitFileType = sourcecode.glsl; fileEncoding = 4; path = mask.vert; sourceTree = "<group>"; };
|
||||||
|
91BFA3D81902AD78001686E4 /* tarball.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tarball.cpp; sourceTree = "<group>"; };
|
||||||
|
91BFA3D91902ADD5001686E4 /* tarball.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = tarball.hpp; sourceTree = "<group>"; };
|
||||||
91BFA3DE19033E01001686E4 /* gzstream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gzstream.cpp; sourceTree = "<group>"; };
|
91BFA3DE19033E01001686E4 /* gzstream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gzstream.cpp; sourceTree = "<group>"; };
|
||||||
91BFA3DF19033E01001686E4 /* gzstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gzstream.h; sourceTree = "<group>"; };
|
91BFA3DF19033E01001686E4 /* gzstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = gzstream.h; sourceTree = "<group>"; };
|
||||||
91C688E60FD702B9000F6D01 /* cursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursors.h; sourceTree = "<group>"; };
|
91C688E60FD702B9000F6D01 /* cursors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cursors.h; sourceTree = "<group>"; };
|
||||||
@@ -2097,11 +2101,12 @@
|
|||||||
91B3F10A0F9779C300BF5B67 /* graphtool.cpp */,
|
91B3F10A0F9779C300BF5B67 /* graphtool.cpp */,
|
||||||
91B3F11E0F97801F00BF5B67 /* mathutil.cpp */,
|
91B3F11E0F97801F00BF5B67 /* mathutil.cpp */,
|
||||||
913D005A0F9FEEC200184C18 /* porting.cpp */,
|
913D005A0F9FEEC200184C18 /* porting.cpp */,
|
||||||
|
91EC481018FBABB100BB1E86 /* prefs.mac.mm */,
|
||||||
91F6F8F518F8DE6300E3EA15 /* qdpict.cpp */,
|
91F6F8F518F8DE6300E3EA15 /* qdpict.cpp */,
|
||||||
91B3F10F0F9779D000BF5B67 /* soundtool.cpp */,
|
91B3F10F0F9779D000BF5B67 /* soundtool.cpp */,
|
||||||
|
91BFA3D81902AD78001686E4 /* tarball.cpp */,
|
||||||
912283C80FD0E16C00B21642 /* undo.cpp */,
|
912283C80FD0E16C00B21642 /* undo.cpp */,
|
||||||
919145FF18E63B70005CF3A4 /* winutil.mac.mm */,
|
919145FF18E63B70005CF3A4 /* winutil.mac.mm */,
|
||||||
91EC481018FBABB100BB1E86 /* prefs.mac.mm */,
|
|
||||||
91A0B15A1900F73E00EF438F /* mask.frag */,
|
91A0B15A1900F73E00EF438F /* mask.frag */,
|
||||||
91BFA3D61901B024001686E4 /* mask.vert */,
|
91BFA3D61901B024001686E4 /* mask.vert */,
|
||||||
);
|
);
|
||||||
@@ -2116,10 +2121,11 @@
|
|||||||
91B3F1090F9779C300BF5B67 /* graphtool.h */,
|
91B3F1090F9779C300BF5B67 /* graphtool.h */,
|
||||||
91B3F11D0F97801F00BF5B67 /* mathutil.h */,
|
91B3F11D0F97801F00BF5B67 /* mathutil.h */,
|
||||||
913D00590F9FEEC200184C18 /* porting.h */,
|
913D00590F9FEEC200184C18 /* porting.h */,
|
||||||
|
91EC480E18FBAA8700BB1E86 /* prefs.hpp */,
|
||||||
91B3F10E0F9779D000BF5B67 /* soundtool.h */,
|
91B3F10E0F9779D000BF5B67 /* soundtool.h */,
|
||||||
|
91BFA3D91902ADD5001686E4 /* tarball.hpp */,
|
||||||
917B573F100B956C0096C978 /* undo.h */,
|
917B573F100B956C0096C978 /* undo.h */,
|
||||||
919145FE18E63B41005CF3A4 /* winutil.h */,
|
919145FE18E63B41005CF3A4 /* winutil.h */,
|
||||||
91EC480E18FBAA8700BB1E86 /* prefs.hpp */,
|
|
||||||
);
|
);
|
||||||
name = headers;
|
name = headers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -2820,6 +2826,7 @@
|
|||||||
91F6F8F618F8DE6300E3EA15 /* qdpict.cpp in Sources */,
|
91F6F8F618F8DE6300E3EA15 /* qdpict.cpp in Sources */,
|
||||||
91EC483B18FBAD8000BB1E86 /* prefs.mac.mm in Sources */,
|
91EC483B18FBAD8000BB1E86 /* prefs.mac.mm in Sources */,
|
||||||
91FCC8F218FEEFE0007026CE /* pc.editors.cpp in Sources */,
|
91FCC8F218FEEFE0007026CE /* pc.editors.cpp in Sources */,
|
||||||
|
91BFA3DA1902B13D001686E4 /* tarball.cpp in Sources */,
|
||||||
91BFA3E919033E01001686E4 /* gzstream.cpp in Sources */,
|
91BFA3E919033E01001686E4 /* gzstream.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@@ -2872,6 +2879,7 @@
|
|||||||
91FCC8DC18FE2CE8007026CE /* pc.menus.mac.mm in Sources */,
|
91FCC8DC18FE2CE8007026CE /* pc.menus.mac.mm in Sources */,
|
||||||
91FCC8F118FEEDC6007026CE /* winutil.mac.mm in Sources */,
|
91FCC8F118FEEDC6007026CE /* winutil.mac.mm in Sources */,
|
||||||
91FCC8F418FF0866007026CE /* pc.appleevents.mm in Sources */,
|
91FCC8F418FF0866007026CE /* pc.appleevents.mm in Sources */,
|
||||||
|
91BFA3DB1902B13F001686E4 /* tarball.cpp in Sources */,
|
||||||
91BFA3EA19033E01001686E4 /* gzstream.cpp in Sources */,
|
91BFA3EA19033E01001686E4 /* gzstream.cpp in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@@ -86,7 +86,7 @@ void add_outdoor_maps();
|
|||||||
short specials_res_id,data_dump_file_id;
|
short specials_res_id,data_dump_file_id;
|
||||||
char start_name[256];
|
char start_name[256];
|
||||||
short start_volume,data_volume;
|
short start_volume,data_volume;
|
||||||
fs::path progDir;
|
extern fs::path progDir;
|
||||||
|
|
||||||
//outdoor_record_type dummy_out;////
|
//outdoor_record_type dummy_out;////
|
||||||
//town_record_type dummy_town;
|
//town_record_type dummy_town;
|
||||||
@@ -99,44 +99,6 @@ fs::path progDir;
|
|||||||
cCustomGraphics spec_scen_g;
|
cCustomGraphics spec_scen_g;
|
||||||
|
|
||||||
std::ofstream flog("bladeslog.txt");
|
std::ofstream flog("bladeslog.txt");
|
||||||
// TODO: Move this to the common fileio.cpp
|
|
||||||
void init_directories()
|
|
||||||
{
|
|
||||||
char cPath[768];
|
|
||||||
CFBundleRef mainBundle=CFBundleGetMainBundle();
|
|
||||||
|
|
||||||
CFStringRef progURL = CFURLCopyFileSystemPath(CFBundleCopyBundleURL(mainBundle), kCFURLPOSIXPathStyle);
|
|
||||||
const char* tmp = CFStringGetCStringPtr(progURL, kCFStringEncodingASCII);//kCFStringEncodingUTF8);
|
|
||||||
if(tmp == NULL){
|
|
||||||
bool success = CFStringGetCString(progURL, cPath, sizeof(cPath), kCFStringEncodingUTF8);
|
|
||||||
if(success) {
|
|
||||||
progDir = cPath;
|
|
||||||
std::cout << cPath << "\n\n" << progDir << "\n\n";
|
|
||||||
} else {
|
|
||||||
std::cout << "Couldn't retrieve application path.\n";
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}else progDir = tmp;
|
|
||||||
progDir = progDir.parent_path();
|
|
||||||
std::cout<<progDir<<'\n';
|
|
||||||
// Initialize the resource manager paths
|
|
||||||
ResMgr::pushPath<ImageRsrc>(progDir/"Scenario Editor"/"graphics.exd"/"mac");
|
|
||||||
ResMgr::pushPath<CursorRsrc>(progDir/"Scenario Editor"/"graphics.exd"/"mac"/"cursors");
|
|
||||||
ResMgr::pushPath<FontRsrc>(progDir/"data"/"fonts");
|
|
||||||
ResMgr::pushPath<StringRsrc>(progDir/"data"/"strings");
|
|
||||||
ResMgr::pushPath<SoundRsrc>(progDir/"Scenario Editor"/"sounds.exa");
|
|
||||||
|
|
||||||
// now I generate the directory ID of the folder which contains the scenarios
|
|
||||||
// code copied from Mac Prog FAQ book
|
|
||||||
// myCPB.dirInfo.ioNamePtr = folder_name;
|
|
||||||
// myCPB.dirInfo.ioVRefNum = start_volume;
|
|
||||||
// myCPB.dirInfo.ioFDirIndex = 0;
|
|
||||||
// myCPB.dirInfo.ioDrDirID = start_dir;
|
|
||||||
// error = PBGetCatalogInfoSync(&myCPB); // false means not async
|
|
||||||
//
|
|
||||||
// scen_dir = myCPB.dirInfo.ioDrDirID;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void finish_load_party(){
|
void finish_load_party(){
|
||||||
bool town_restore = (univ.town.num < 200) ? true : false;
|
bool town_restore = (univ.town.num < 200) ? true : false;
|
||||||
|
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
namespace fs = boost::filesystem; // TODO: Centralize this alias!
|
namespace fs = boost::filesystem; // TODO: Centralize this alias!
|
||||||
|
|
||||||
void init_directories();
|
|
||||||
//void load_file();
|
//void load_file();
|
||||||
//void save_file(short mode);
|
//void save_file(short mode);
|
||||||
void change_rect_terrain(RECT r,ter_num_t terrain_type,short probability,bool hollow);
|
void change_rect_terrain(RECT r,ter_num_t terrain_type,short probability,bool hollow);
|
||||||
|
@@ -11,7 +11,6 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <zlib.h>
|
|
||||||
//#include "scen.global.h"
|
//#include "scen.global.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "classes.h"
|
#include "classes.h"
|
||||||
@@ -25,6 +24,8 @@
|
|||||||
#include "porting.h"
|
#include "porting.h"
|
||||||
#include "dlogutil.h"
|
#include "dlogutil.h"
|
||||||
#include "restypes.hpp"
|
#include "restypes.hpp"
|
||||||
|
#include "tarball.hpp"
|
||||||
|
#include "gzstream.h"
|
||||||
|
|
||||||
extern bool cur_scen_is_mac, mac_is_intel;
|
extern bool cur_scen_is_mac, mac_is_intel;
|
||||||
extern cScenario scenario;
|
extern cScenario scenario;
|
||||||
@@ -36,66 +37,53 @@ extern cUniverse univ;
|
|||||||
//extern unsigned char borders[4][50];
|
//extern unsigned char borders[4][50];
|
||||||
//extern cOutdoors current_terrain;
|
//extern cOutdoors current_terrain;
|
||||||
//extern cTown* town;
|
//extern cTown* town;
|
||||||
extern fs::path progDir;
|
fs::path progDir, tempDir;
|
||||||
//extern short overall_mode;
|
//extern short overall_mode;
|
||||||
|
|
||||||
struct header_posix_ustar {
|
|
||||||
char name[100];
|
|
||||||
char mode[8];
|
|
||||||
char uid[8];
|
|
||||||
char gid[8];
|
|
||||||
char size[12];
|
|
||||||
char mtime[12];
|
|
||||||
char checksum[8];
|
|
||||||
char typeflag[1];
|
|
||||||
char linkname[100];
|
|
||||||
char magic[6];
|
|
||||||
char version[2];
|
|
||||||
char uname[32];
|
|
||||||
char gname[32];
|
|
||||||
char devmajor[8];
|
|
||||||
char devminor[8];
|
|
||||||
char prefix[155];
|
|
||||||
char pad[12];
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
// TODO: Try to find a way to get our path without using CoreFoundation, and also replace cout with printf
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
|
||||||
static header_posix_ustar generateTarHeader(const std::string& fileName, unsigned long long fileSize,bool directory=false){
|
void init_directories() {
|
||||||
if(fileSize>077777777777LL)
|
char cPath[768];
|
||||||
throw std::length_error("Specified file size >= 8 GB");
|
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||||
if(fileName.length()>=100)
|
|
||||||
throw std::length_error("Specified file name longer than 99 characters.");
|
|
||||||
header_posix_ustar header;
|
|
||||||
char* init = (char*) &header;
|
|
||||||
for(unsigned int i = 0; i < sizeof(header); i++) init[i] = 0;
|
|
||||||
|
|
||||||
sprintf(header.name,"%s",fileName.c_str());
|
CFStringRef progURL = CFURLCopyFileSystemPath(CFBundleCopyBundleURL(mainBundle), kCFURLPOSIXPathStyle);
|
||||||
sprintf(header.mode,"%07o",0600);
|
const char* tmp = CFStringGetCStringPtr(progURL, kCFStringEncodingASCII);
|
||||||
//leave uid filled with NULs
|
if(tmp == NULL){
|
||||||
//leave gid filled with NULs
|
bool success = CFStringGetCString(progURL, cPath, sizeof(cPath), kCFStringEncodingUTF8);
|
||||||
sprintf(header.size,"%011llo",fileSize);
|
if(success) {
|
||||||
sprintf(header.mtime,"%011lo",time(NULL));
|
progDir = cPath;
|
||||||
memset(header.checksum,' ',8);
|
std::cout << cPath << "\n\n" << progDir << "\n\n";
|
||||||
header.typeflag[0]=directory?'5':'0';
|
} else {
|
||||||
//leave linkname filled with NULs
|
std::cout << "Couldn't retrieve application path.\n";
|
||||||
sprintf(header.magic,"ustar "); //overwrites header with " \0"
|
exit(1);
|
||||||
//leave uname filled with NULs
|
}
|
||||||
//leave gname filled with NULs
|
} else progDir = tmp;
|
||||||
//leave devmajor filled with NULs
|
progDir = progDir.parent_path();
|
||||||
//leave devminor filled with NULs
|
// TODO: If this places us in the "Scenario Editor" folder, back out one more directory
|
||||||
//leave prefix filled with NULs
|
std::cout << progDir << '\n';
|
||||||
//leave pad filled with NULs
|
// Initialize the resource manager paths
|
||||||
|
ResMgr::pushPath<ImageRsrc>(progDir/"Scenario Editor"/"graphics.exd"/"mac");
|
||||||
|
ResMgr::pushPath<CursorRsrc>(progDir/"Scenario Editor"/"graphics.exd"/"mac"/"cursors");
|
||||||
|
ResMgr::pushPath<FontRsrc>(progDir/"data"/"fonts");
|
||||||
|
ResMgr::pushPath<StringRsrc>(progDir/"data"/"strings");
|
||||||
|
ResMgr::pushPath<SoundRsrc>(progDir/"Scenario Editor"/"sounds.exa");
|
||||||
|
|
||||||
unsigned int sum=0;
|
// We need a location for temporary files, primarily for loading and saving operations
|
||||||
unsigned char* ptr=reinterpret_cast<unsigned char*>(&header);
|
// The scenario editor may also use this location as "scratch space"
|
||||||
for(unsigned int i=0; i<sizeof(header); i++){
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
sum+=ptr[i];
|
tempDir = getenv("APPDATA");
|
||||||
}
|
tempDir /= "Blades of Exile";
|
||||||
if(sum>0777777)
|
#else
|
||||||
throw std::runtime_error("Checksum overflow");
|
tempDir = getenv("HOME");
|
||||||
sprintf(header.checksum,"%o",sum);
|
#ifdef __APPLE__
|
||||||
return(header);
|
tempDir /= "Library/Application Support/Blades of Exile";
|
||||||
|
#else
|
||||||
|
tempDir /= ".oboe/blades";
|
||||||
|
#endif // __APPLE__
|
||||||
|
#endif // _Win32||_Win64
|
||||||
|
tempDir /= "Temporary Files";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_scenario(fs::path file_to_load, bool skip_strings){
|
bool load_scenario(fs::path file_to_load, bool skip_strings){
|
||||||
@@ -1264,450 +1252,85 @@ bool load_party_v2(fs::path file_to_load, bool town_restore, bool in_scen, bool
|
|||||||
bool save_party(fs::path dest_file)
|
bool save_party(fs::path dest_file)
|
||||||
//mode; // 0 - normal 1 - save as
|
//mode; // 0 - normal 1 - save as
|
||||||
{
|
{
|
||||||
//printf("Saving is currently disabled.\n");
|
if(!fs::exists(tempDir)) fs::create_directories(tempDir);
|
||||||
|
|
||||||
bool in_scen = univ.party.scen_name != "";
|
bool in_scen = univ.party.scen_name != "";
|
||||||
bool in_town = univ.town.num < 200;
|
bool in_town = univ.town.num < 200;
|
||||||
bool save_maps = !univ.party.stuff_done[306][0];
|
bool save_maps = !univ.party.stuff_done[306][0];
|
||||||
|
|
||||||
// TODO: Strip off the header and save the remainder to a temporary file, then use gzip on that; this should fix the issue of the header being interpreted as compressed.
|
tarball partyOut;
|
||||||
/* Open the GZip file and write the (uncompressed) header */
|
|
||||||
std::ofstream fout(dest_file.c_str(), std::ios_base::binary);
|
// First, write the main party data
|
||||||
|
univ.party.writeTo(partyOut.newFile("save/party.txt"));
|
||||||
|
{
|
||||||
|
std::ostream& fout = partyOut.newFile("save/setup.dat");
|
||||||
|
static uint16_t magic = 0x0B0E;
|
||||||
|
fout.write((char*)&magic, 2);
|
||||||
|
fout.write((char*)&univ.party.setup, sizeof(cParty::setup));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then write the data for each of the party members
|
||||||
|
for(int i = 0; i < 6; i++) {
|
||||||
|
static char fname[] = "save/pc1.txt";
|
||||||
|
fname[7] = i + '1';
|
||||||
|
univ.party[i].writeTo(partyOut.newFile(fname));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(in_scen) {
|
||||||
|
if(in_town) {
|
||||||
|
// Write the current town data
|
||||||
|
univ.town.writeTo(partyOut.newFile("save/town.txt"));
|
||||||
|
|
||||||
|
if(save_maps) {
|
||||||
|
// Write the town map data
|
||||||
|
std::ostream& fout = partyOut.newFile("save/townmaps.dat");
|
||||||
|
for(int i = 0; i < 200; i++)
|
||||||
|
for(int j = 0; j < 8; j++)
|
||||||
|
for(int k = 0; k < 64; k++)
|
||||||
|
fout.put(univ.town_maps[i][j][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the current outdoors data
|
||||||
|
univ.out.writeTo(partyOut.newFile("save/out.txt"));
|
||||||
|
|
||||||
|
if(save_maps) {
|
||||||
|
// Write the outdoors map data
|
||||||
|
std::ostream& fout = partyOut.newFile("save/outmaps.dat");
|
||||||
|
for(int i = 0; i < 100; i++)
|
||||||
|
for(int j = 0; j < 6; j++)
|
||||||
|
for(int k = 0; k < 48; k++)
|
||||||
|
fout.put(univ.out_maps[i][j][k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add the party graphics sheet
|
||||||
|
|
||||||
|
// Write out the compressed data
|
||||||
|
fs::path tempPath = tempDir/"savetemp.exg";
|
||||||
|
ogzstream zout(tempPath.c_str());
|
||||||
|
partyOut.writeTo(zout);
|
||||||
|
zout.close();
|
||||||
|
|
||||||
|
// Now add the header. We use the temporary file because we want the header to be uncompressed.
|
||||||
short flags[] = {
|
short flags[] = {
|
||||||
0x0B0E, // to indicate new format
|
0x0B0E, // to indicate new format
|
||||||
static_cast<short>(in_town ? 1342 : 5790), // is the party in town?
|
static_cast<short>(in_town ? 1342 : 5790), // is the party in town?
|
||||||
static_cast<short>(in_scen ? 100 : 200), // is the party in a scenario?
|
static_cast<short>(in_scen ? 100 : 200), // is the party in a scenario?
|
||||||
static_cast<short>(save_maps ? 5567 : 3422), // is the save maps feature enabled?
|
static_cast<short>(save_maps ? 5567 : 3422), // is the save maps feature enabled?
|
||||||
0x0100, // current version number, major and minor revisions only
|
0x0100, // current version number, major and minor revisions only
|
||||||
// Version 1 indicates a beta format that won't be supported in the final release
|
// Version 1 indicates a beta format that may not be supported in the final release
|
||||||
};
|
};
|
||||||
if(!mac_is_intel) // must flip all the flags to little-endian
|
if(!mac_is_intel) // must flip all the flags to little-endian
|
||||||
for(int i = 0; i < 5; i++)
|
for(int i = 0; i < 5; i++)
|
||||||
flip_short(&flags[i]);
|
flip_short(&flags[i]);
|
||||||
//fwrite(flags, sizeof(short), 5, f);
|
|
||||||
//gzFile party_file = gzdopen(fileno(f),"wb0"); // 0 indicates no compression; this is temporary
|
std::ifstream fin(tempPath.c_str(), std::ios_base::binary);
|
||||||
//gzwrite(party_file, flags, sizeof(short)*5);
|
std::ofstream fout(dest_file.c_str(), std::ios_base::binary);
|
||||||
//int q = gzflush(party_file, Z_FULL_FLUSH); // required in order to avoid the header getting compressed
|
|
||||||
//gzsetparams(party_file, Z_DEFAULT_COMPRESSION, Z_DEFAULT_STRATEGY);
|
|
||||||
fout.write((char*) flags, 5*sizeof(short));
|
fout.write((char*) flags, 5*sizeof(short));
|
||||||
|
fout << fin.rdbuf();
|
||||||
/* Initialize buffer and other variables */
|
fin.close();
|
||||||
header_posix_ustar header;
|
|
||||||
static char footer[2*sizeof(header_posix_ustar)] = {0};
|
|
||||||
std::ostringstream sout("");
|
|
||||||
std::ostringstream bout("",std::ios_base::binary);
|
|
||||||
std::string tar_entry;
|
|
||||||
size_t tar_size, y;
|
|
||||||
int x;
|
|
||||||
sout << x;
|
|
||||||
/* Write main party data to a buffer, and then to the file */
|
|
||||||
univ.party.writeTo(sout);
|
|
||||||
//write the footer to end the file
|
|
||||||
// for(unsigned int j=0; j<2*sizeof(header_posix_ustar); j++)
|
|
||||||
// sout.put('\0');
|
|
||||||
tar_entry = sout.str();
|
|
||||||
y = tar_size = tar_entry.length();
|
|
||||||
while(y % 512){
|
|
||||||
y++;
|
|
||||||
tar_entry += '\0';
|
|
||||||
}
|
|
||||||
header = generateTarHeader("save/party.txt",tar_size);
|
|
||||||
bout.write((char*) &header, sizeof(header));
|
|
||||||
bout.write(tar_entry.c_str(), y);
|
|
||||||
// x = gzwrite(party_file, (char*) &header, sizeof(header));
|
|
||||||
// x = gzwrite(party_file, tar_entry.c_str(), y);
|
|
||||||
// //x = gzwrite(party_file, footer, 2*sizeof(header_posix_ustar));
|
|
||||||
// if(x == 0) { // error
|
|
||||||
// gzerror(party_file, &x);
|
|
||||||
// oops_error((x == Z_ERRNO) ? Z_ERRNO + 1000 : 1, (x == Z_ERRNO) ? errno : x, 1);
|
|
||||||
// gzclose(party_file);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
sout.str(""); // clear the stream (I think)
|
|
||||||
|
|
||||||
/* Write player character data to a buffer, and then to the file */
|
|
||||||
for(int i = 0; i < 6; i++){
|
|
||||||
char f_name[20];
|
|
||||||
univ.party[i].writeTo(sout);
|
|
||||||
//write the footer to end the file
|
|
||||||
// for(unsigned int j=0; j<2*sizeof(header_posix_ustar); j++)
|
|
||||||
// sout.put('\0');
|
|
||||||
tar_entry = sout.str();
|
|
||||||
y = tar_size = tar_entry.length();
|
|
||||||
while(y % 512){
|
|
||||||
y++;
|
|
||||||
tar_entry += '\0';
|
|
||||||
}
|
|
||||||
sprintf(f_name,"save/pc%i.txt",i+1);
|
|
||||||
header = generateTarHeader(f_name,tar_size);
|
|
||||||
bout.write((char*) &header, sizeof(header));
|
|
||||||
bout.write(tar_entry.c_str(), y);
|
|
||||||
// x = gzwrite(party_file, (char*) &header, sizeof(header));
|
|
||||||
// x = gzwrite(party_file, tar_entry.c_str(), y);
|
|
||||||
// //x = gzwrite(party_file, footer, 2*sizeof(header_posix_ustar));
|
|
||||||
// if(x == 0) { // error
|
|
||||||
// gzerror(party_file, &x);
|
|
||||||
// oops_error((x == Z_ERRNO) ? Z_ERRNO + 1000 : 1, (x == Z_ERRNO) ? errno : x, 1);
|
|
||||||
// gzclose(party_file);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
sout.str(""); // clear the stream (I think)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(in_scen){
|
|
||||||
if(in_town){
|
|
||||||
/* Write current town data to a buffer, and then to the file */
|
|
||||||
univ.town.writeTo(sout);
|
|
||||||
//write the footer to end the file
|
|
||||||
// for(unsigned int j=0; j<2*sizeof(header_posix_ustar); j++)
|
|
||||||
// sout.put('\0');
|
|
||||||
tar_entry = sout.str();
|
|
||||||
y = tar_size = tar_entry.length();
|
|
||||||
while(y % 512){
|
|
||||||
y++;
|
|
||||||
tar_entry += '\0';
|
|
||||||
}
|
|
||||||
header = generateTarHeader("save/town.txt",tar_size);
|
|
||||||
bout.write((char*) &header, sizeof(header));
|
|
||||||
bout.write(tar_entry.c_str(), y);
|
|
||||||
// x = gzwrite(party_file, (char*) &header, sizeof(header));
|
|
||||||
// x = gzwrite(party_file, tar_entry.c_str(), y);
|
|
||||||
// //x = gzwrite(party_file, footer, 2*sizeof(header_posix_ustar));
|
|
||||||
// if(x == 0) { // error
|
|
||||||
// gzerror(party_file, &x);
|
|
||||||
// oops_error((x == Z_ERRNO) ? Z_ERRNO + 1000 : 1, (x == Z_ERRNO) ? errno : x, 1);
|
|
||||||
// gzclose(party_file);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
sout.str(""); // clear the stream (I think)
|
|
||||||
|
|
||||||
if(save_maps){
|
|
||||||
/* Write town maps data to a buffer, and then to the file */
|
|
||||||
for(int i = 0; i < 200; i++)
|
|
||||||
for(int j = 0; j < 8; j++)
|
|
||||||
for(int k = 0; k < 64; k++)
|
|
||||||
sout.put(univ.town_maps[i][j][k]);
|
|
||||||
//write the footer to end the file
|
|
||||||
// for(unsigned int j=0; j<2*sizeof(header_posix_ustar); j++)
|
|
||||||
// sout.put('\0');
|
|
||||||
tar_entry = sout.str();
|
|
||||||
y = tar_size = tar_entry.length();
|
|
||||||
while(y % 512){
|
|
||||||
y++;
|
|
||||||
tar_entry += '\0';
|
|
||||||
}
|
|
||||||
header = generateTarHeader("save/townmaps.dat",tar_size);
|
|
||||||
bout.write((char*) &header, sizeof(header));
|
|
||||||
bout.write(tar_entry.c_str(), y);
|
|
||||||
// x = gzwrite(party_file, (char*) &header, sizeof(header));
|
|
||||||
// x = gzwrite(party_file, tar_entry.c_str(), y);
|
|
||||||
// //x = gzwrite(party_file, footer, 2*sizeof(header_posix_ustar));
|
|
||||||
// if(x == 0) { // error
|
|
||||||
// gzerror(party_file, &x);
|
|
||||||
// oops_error((x == Z_ERRNO) ? Z_ERRNO + 1000 : 1, (x == Z_ERRNO) ? errno : x, 1);
|
|
||||||
// gzclose(party_file);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
sout.str(""); // clear the stream (I think)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write current outdoors data to a buffer, and then to the file */
|
|
||||||
univ.out.writeTo(sout);
|
|
||||||
//write the footer to end the file
|
|
||||||
// for(unsigned int j=0; j<2*sizeof(header_posix_ustar); j++)
|
|
||||||
// sout.put('\0');
|
|
||||||
tar_entry = sout.str();
|
|
||||||
y = tar_size = tar_entry.length();
|
|
||||||
while(y % 512){
|
|
||||||
y++;
|
|
||||||
tar_entry += '\0';
|
|
||||||
}
|
|
||||||
header = generateTarHeader("save/out.txt",tar_size);
|
|
||||||
bout.write((char*) &header, sizeof(header));
|
|
||||||
bout.write(tar_entry.c_str(), y);
|
|
||||||
// x = gzwrite(party_file, (char*) &header, sizeof(header));
|
|
||||||
// x = gzwrite(party_file, tar_entry.c_str(), y);
|
|
||||||
// //x = gzwrite(party_file, footer, 2*sizeof(header_posix_ustar));
|
|
||||||
// if(x == 0) { // error
|
|
||||||
// gzerror(party_file, &x);
|
|
||||||
// oops_error((x == Z_ERRNO) ? Z_ERRNO + 1000 : 1, (x == Z_ERRNO) ? errno : x, 1);
|
|
||||||
// gzclose(party_file);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
sout.str(""); // clear the stream (I think)
|
|
||||||
|
|
||||||
if(save_maps){
|
|
||||||
/* Write outdoor maps data to a buffer, and then to the file */
|
|
||||||
for(int i = 0; i < 100; i++)
|
|
||||||
for(int j = 0; j < 6; j++)
|
|
||||||
for(int k = 0; k < 48; k++)
|
|
||||||
sout.put(univ.out_maps[i][j][k]);
|
|
||||||
//write the footer to end the file
|
|
||||||
// for(unsigned int j=0; j<2*sizeof(header_posix_ustar); j++)
|
|
||||||
// sout.put('\0');
|
|
||||||
tar_entry = sout.str();
|
|
||||||
y = tar_size = tar_entry.length();
|
|
||||||
while(y % 512){
|
|
||||||
y++;
|
|
||||||
tar_entry += '\0';
|
|
||||||
}
|
|
||||||
header = generateTarHeader("save/outmaps.dat",tar_size);
|
|
||||||
bout.write((char*) &header, sizeof(header));
|
|
||||||
bout.write(tar_entry.c_str(), y);
|
|
||||||
// x = gzwrite(party_file, (char*) &header, sizeof(header));
|
|
||||||
// x = gzwrite(party_file, tar_entry.c_str(), y);
|
|
||||||
// //x = gzwrite(party_file, footer, 2*sizeof(header_posix_ustar));
|
|
||||||
// if(x == 0) { // error
|
|
||||||
// gzerror(party_file, &x);
|
|
||||||
// oops_error((x == Z_ERRNO) ? Z_ERRNO + 1000 : 1, (x == Z_ERRNO) ? errno : x, 1);
|
|
||||||
// gzclose(party_file);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// sout.str(""); // clear the stream (I think)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//x = gzwrite(party_file, footer, 2*sizeof(header_posix_ustar));
|
|
||||||
//gzclose(party_file);
|
|
||||||
bout.write(footer, 2*sizeof(header_posix_ustar));
|
|
||||||
tar_entry = bout.str();
|
|
||||||
tar_size = tar_entry.length();
|
|
||||||
unsigned char* buf = new unsigned char[tar_size];
|
|
||||||
compress(buf, &tar_size, (unsigned char*) tar_entry.data(), tar_size);
|
|
||||||
fout.write((char*)buf, tar_size);
|
|
||||||
delete buf;
|
|
||||||
fout.close();
|
fout.close();
|
||||||
// NavReplyRecord reply;
|
|
||||||
// OSErr error;
|
|
||||||
// short file_id;
|
|
||||||
// bool town_save = false;
|
|
||||||
// Str63 store_name;
|
|
||||||
// FSSpec to_load;
|
|
||||||
//
|
|
||||||
// short i;
|
|
||||||
//
|
|
||||||
// long len,store_len,count;
|
|
||||||
// flag_type flag;
|
|
||||||
// flag_type *store;
|
|
||||||
// party_record_type *party_ptr;
|
|
||||||
// setup_save_type *setup_ptr;
|
|
||||||
// pc_record_type *pc_ptr;
|
|
||||||
// // out_info_type store_explored;
|
|
||||||
// current_town_type *town_ptr;
|
|
||||||
// big_tr_type *town_data_ptr;
|
|
||||||
// town_item_list *item_ptr;
|
|
||||||
// stored_items_list_type *items_ptr;
|
|
||||||
// stored_town_maps_type *maps_ptr;
|
|
||||||
// stored_outdoor_maps_type *o_maps_ptr;
|
|
||||||
//
|
|
||||||
// char *party_encryptor;
|
|
||||||
//
|
|
||||||
// if ((in_startup_mode == false) && (is_town()))
|
|
||||||
// town_save = true;
|
|
||||||
//
|
|
||||||
// strcpy ((char *) store_name, (char *) last_load_file);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// if ((mode == 1) || (loaded_yet == false)) {
|
|
||||||
// NavPutFile(NULL,&reply,NULL,NULL,'beSV','blx!',NULL);
|
|
||||||
// if (reply.validRecord == false)
|
|
||||||
// return;
|
|
||||||
//
|
|
||||||
// AEKeyword keyword;
|
|
||||||
// DescType descType;
|
|
||||||
// Size actualSize;
|
|
||||||
//
|
|
||||||
// AEGetNthPtr(&reply.selection,1,typeFSS,&keyword,&descType,&to_load,sizeof(FSSpec),&actualSize);
|
|
||||||
// loaded_yet = true;
|
|
||||||
// }
|
|
||||||
// else to_load = store_file_reply;
|
|
||||||
//
|
|
||||||
// error = FSpCreate(&to_load,'blx!','beSV',reply.keyScript);
|
|
||||||
// if ((error != 0) && (error != dupFNErr)) {
|
|
||||||
// add_string_to_buf("Save: Couldn't create file. ");
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if ((error = FSpOpenDF(&to_load,3,&file_id)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't open file. ");
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// strcpy ((char *) last_load_file, (char *) to_load.name);
|
|
||||||
// store_file_reply = to_load;
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// store = &flag;
|
|
||||||
//
|
|
||||||
// len = sizeof(flag_type);
|
|
||||||
//
|
|
||||||
// flag.i = (town_save == true) ? 1342 : 5790;
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) store)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// }
|
|
||||||
// flag.i = (in_startup_mode == false) ? 100 : 200;
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) store)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// flag.i = (save_maps == true) ? 5567 : 3422;
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) store)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // SAVE PARTY
|
|
||||||
// party_ptr = &party;
|
|
||||||
// len = sizeof(party_record_type);
|
|
||||||
//
|
|
||||||
// store_len = len;
|
|
||||||
// party_encryptor = (char *) party_ptr;
|
|
||||||
// for (count = 0; count < store_len; count++)
|
|
||||||
// party_encryptor[count] ^= 0x5C;
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) party_ptr)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// for (count = 0; count < store_len; count++)
|
|
||||||
// party_encryptor[count] ^= 0x5C;
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// for (count = 0; count < store_len; count++)
|
|
||||||
// party_encryptor[count] ^= 0x5C;
|
|
||||||
//
|
|
||||||
// // SAVE SETUP
|
|
||||||
// setup_ptr = &setup_save;
|
|
||||||
// len = sizeof(setup_save_type);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) setup_ptr)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // SAVE PCS
|
|
||||||
// store_len = sizeof(pc_record_type);
|
|
||||||
// for (i = 0; i < 6; i++) {
|
|
||||||
// pc_ptr = &adven[i];
|
|
||||||
//
|
|
||||||
// len = store_len;
|
|
||||||
// party_encryptor = (char *) pc_ptr;
|
|
||||||
// for (count = 0; count < store_len; count++)
|
|
||||||
// party_encryptor[count] ^= 0x6B;
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) pc_ptr)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// for (count = 0; count < store_len; count++)
|
|
||||||
// party_encryptor[count] ^= 0x6B;
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// for (count = 0; count < store_len; count++)
|
|
||||||
// party_encryptor[count] ^= 0x6B;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (in_startup_mode == false) {
|
|
||||||
//
|
|
||||||
// // SAVE OUT DATA
|
|
||||||
// len = sizeof(out_info_type);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) out_e)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (town_save == true) {
|
|
||||||
// town_ptr = &c_town;
|
|
||||||
// len = sizeof(current_town_type);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) town_ptr)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// town_data_ptr = &t_d;
|
|
||||||
// len = sizeof(big_tr_type);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) town_data_ptr)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// item_ptr = &t_i;
|
|
||||||
// len = sizeof(town_item_list);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) item_ptr)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Save stored items
|
|
||||||
// for (i = 0; i < 3; i++) {
|
|
||||||
// items_ptr = &stored_items[i];
|
|
||||||
// len = (long) sizeof(stored_items_list_type);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) items_ptr)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // If saving maps, save maps
|
|
||||||
// if (save_maps == true) {
|
|
||||||
// maps_ptr = &(town_maps);
|
|
||||||
// len = (long) sizeof(stored_town_maps_type);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) maps_ptr)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// o_maps_ptr = &o_maps;
|
|
||||||
// len = (long) sizeof(stored_outdoor_maps_type);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) o_maps_ptr)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // SAVE SFX and MISC_I
|
|
||||||
// len = (long) (64 * 64);
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) sfx)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if ((error = FSWrite(file_id, &len, (char *) misc_i)) != 0){
|
|
||||||
// add_string_to_buf("Save: Couldn't write to file. ");
|
|
||||||
// FSClose(file_id);
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if ((error = FSClose(file_id)) != 0) {
|
|
||||||
// add_string_to_buf("Save: Couldn't close file. ");
|
|
||||||
// SysBeep(2);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// if (in_startup_mode == false)
|
|
||||||
// add_string_to_buf("Save: Game saved. ");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -27,3 +27,5 @@ std::vector<std::string> load_strings(std::string which);
|
|||||||
|
|
||||||
bool load_party(fs::path file_to_load);
|
bool load_party(fs::path file_to_load);
|
||||||
bool save_party(fs::path dest_file);
|
bool save_party(fs::path dest_file);
|
||||||
|
|
||||||
|
void init_directories();
|
||||||
|
98
osx/tools/tarball.cpp
Normal file
98
osx/tools/tarball.cpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
//
|
||||||
|
// tarball.cpp
|
||||||
|
// BoE
|
||||||
|
//
|
||||||
|
// Created by Celtic Minstrel on 14-04-19.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "tarball.hpp"
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
tarball::header_posix_ustar tarball::generateTarHeader(const std::string& fileName, unsigned long long fileSize, bool directory){
|
||||||
|
static_assert(sizeof(header_posix_ustar) == 512, "Uh-oh! Padding in the tarball header!");
|
||||||
|
if(fileSize > 077777777777LL)
|
||||||
|
throw std::length_error("Specified file size >= 8 GB");
|
||||||
|
if(fileName.length() >= 100)
|
||||||
|
throw std::length_error("Specified file name longer than 99 characters.");
|
||||||
|
header_posix_ustar header;
|
||||||
|
char* init = (char*) &header;
|
||||||
|
for(unsigned int i = 0; i < sizeof(header); i++) init[i] = 0;
|
||||||
|
|
||||||
|
snprintf(header.name,100,"%s",fileName.c_str());
|
||||||
|
snprintf(header.mode,8,"%07o",0600);
|
||||||
|
// leave uid filled with NULs
|
||||||
|
// leave gid filled with NULs
|
||||||
|
snprintf(header.size,12,"%011llo",fileSize);
|
||||||
|
snprintf(header.mtime,12,"%011lo",time(NULL));
|
||||||
|
memset(header.checksum,' ',8);
|
||||||
|
header.typeflag[0] = directory ? '5' : '0';
|
||||||
|
// leave linkname filled with NULs
|
||||||
|
snprintf(header.magic,6,"ustar ");
|
||||||
|
snprintf(header.version,2," ");
|
||||||
|
// leave uname filled with NULs
|
||||||
|
// leave gname filled with NULs
|
||||||
|
// leave devmajor filled with NULs
|
||||||
|
// leave devminor filled with NULs
|
||||||
|
// leave prefix filled with NULs
|
||||||
|
// leave pad filled with NULs
|
||||||
|
|
||||||
|
unsigned int sum = 0;
|
||||||
|
unsigned char* ptr = reinterpret_cast<unsigned char*>(&header);
|
||||||
|
for(unsigned int i = 0; i < sizeof(header); i++){
|
||||||
|
sum += ptr[i];
|
||||||
|
}
|
||||||
|
if(sum > 0777777)
|
||||||
|
throw std::runtime_error("Checksum overflow");
|
||||||
|
snprintf(header.checksum,8,"%o",sum);
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tarball::writeTo(std::ostream& out) {
|
||||||
|
static const char padding[512] = {0};
|
||||||
|
for(tarfile& entry : files) {
|
||||||
|
entry.contents.seekg(0, std::ios_base::end);
|
||||||
|
unsigned long long size = entry.contents.tellg();
|
||||||
|
unsigned long long padLength = 512 - size % 512;
|
||||||
|
entry.contents.seekg(0);
|
||||||
|
entry.header = generateTarHeader(entry.filename, size);
|
||||||
|
out.write((char*)&entry.header, sizeof(header_posix_ustar));
|
||||||
|
out << entry.contents.rdbuf();
|
||||||
|
out.write(padding, padLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tarball::readFrom(std::istream& in) {
|
||||||
|
static char buf[513];
|
||||||
|
while(!in.eof()) {
|
||||||
|
files.push_back(tarfile());
|
||||||
|
header_posix_ustar& header = files.back().header;
|
||||||
|
in.read((char*)&header, sizeof(header_posix_ustar));
|
||||||
|
files.back().filename = header.name;
|
||||||
|
unsigned long long size = boost::lexical_cast<unsigned long long>(header.size);
|
||||||
|
unsigned long long padLength = 512 - size % 512;
|
||||||
|
in.read(buf, size);
|
||||||
|
files.back().contents.write(buf, size);
|
||||||
|
in.seekg(padLength, std::ios_base::cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream& tarball::newFile(std::string fname) {
|
||||||
|
files.push_back(tarfile());
|
||||||
|
files.back().filename = fname;
|
||||||
|
return files.back().contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream& tarball::getFile(std::string fname) {
|
||||||
|
for(tarfile& entry : files) {
|
||||||
|
if(entry.filename == fname) {
|
||||||
|
entry.contents.seekg(0);
|
||||||
|
return entry.contents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the file doesn't exist, return an empty stream
|
||||||
|
static std::istringstream empty;
|
||||||
|
empty.clear();
|
||||||
|
empty.seekg(0);
|
||||||
|
return empty;
|
||||||
|
}
|
51
osx/tools/tarball.hpp
Normal file
51
osx/tools/tarball.hpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// tarball.hpp
|
||||||
|
// BoE
|
||||||
|
//
|
||||||
|
// Created by Celtic Minstrel on 14-04-19.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef BoE_tarball_hpp
|
||||||
|
#define BoE_tarball_hpp
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
class tarball {
|
||||||
|
struct header_posix_ustar {
|
||||||
|
char name[100];
|
||||||
|
char mode[8];
|
||||||
|
char uid[8];
|
||||||
|
char gid[8];
|
||||||
|
char size[12];
|
||||||
|
char mtime[12];
|
||||||
|
char checksum[8];
|
||||||
|
char typeflag[1];
|
||||||
|
char linkname[100];
|
||||||
|
char magic[6];
|
||||||
|
char version[2];
|
||||||
|
char uname[32];
|
||||||
|
char gname[32];
|
||||||
|
char devmajor[8];
|
||||||
|
char devminor[8];
|
||||||
|
char prefix[155];
|
||||||
|
char pad[12];
|
||||||
|
};
|
||||||
|
struct tarfile {
|
||||||
|
header_posix_ustar header;
|
||||||
|
std::string filename;
|
||||||
|
std::stringstream contents;
|
||||||
|
};
|
||||||
|
std::deque<tarfile> files;
|
||||||
|
static header_posix_ustar generateTarHeader(const std::string& fileName, unsigned long long fileSize, bool directory=false);
|
||||||
|
public:
|
||||||
|
void writeTo(std::ostream& out);
|
||||||
|
void readFrom(std::istream& in);
|
||||||
|
std::ostream& newFile(std::string fname);
|
||||||
|
void newDirectory(std::string dname);
|
||||||
|
std::istream& getFile(std::string fname);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user