From 3e30014b9b2e257969c60b243ad715b0e64077a3 Mon Sep 17 00:00:00 2001 From: nkorslund Date: Thu, 17 Jul 2008 10:22:13 +0000 Subject: [PATCH] Testing savegame support git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@28 ea6a568a-9f4f-0410-981a-c910a81bb256 --- esm/esmmain.d | 30 +++++++++++++++++++++++++++--- esm/filereader.d | 37 ++++++++++++++++++++++++------------- openmw.d | 7 +++++++ 3 files changed, 58 insertions(+), 16 deletions(-) diff --git a/esm/esmmain.d b/esm/esmmain.d index f333557a14..0ca83d808b 100644 --- a/esm/esmmain.d +++ b/esm/esmmain.d @@ -66,9 +66,8 @@ void loadTESFiles(char[][] files) } // We have to loop through the lists and check for broken - // references at this point, if all forward references were - // loaded. There might be other end-of-file things to do - // also. + // references at this point, and if all forward references were + // loaded. There might be other end-of-file things to do also. endFiles(); } @@ -115,3 +114,28 @@ void loadTESFiles(char[][] files) // Finally, sort the hyperlink lists hyperlinks.sort(); } + +// Load a TES savegame file (.ess). Currently VERY limited, only reads +// the header. +void importSavegame(char[] file) +{ + writefln("Loading savegame %s", file); + esFile.open(file, esmRegion); + scope(exit) esFile.close(); + + if(esFile.getFileType != FileType.Ess) + throw new TES3FileException(file ~ " is not a savegame"); + + with(esFile.saveData) + { + writefln("Floats:"); + foreach(i, f; unknown) + writefln(" %s: %s", i, f); + + writefln("Cell name: ", stripz(cell)); + + writefln("Strange value: ", unk2); + writefln("Player name: ", stripz(player)); + } + writefln(); +} diff --git a/esm/filereader.d b/esm/filereader.d index 88301c1e73..b730a07788 100644 --- a/esm/filereader.d +++ b/esm/filereader.d @@ -140,12 +140,13 @@ struct TES3File char[] name; // File name of an esm master for this file ulong size; // The master file's size in bytes (used for // version control) - } + } // List of esm masters for this file. For savegames this list also // contains all plugins. _mast masters[]; + // TES3.HEDR, file header struct align(1) struct HEDRstruct { @@ -167,6 +168,19 @@ struct TES3File public: + // A struct found in the headers of savegame files. Contains quick + // information to get us going, like the cell name and the player + // name. + struct _saveData + { + float[6] unknown; // 24 bytes + char[64] cell; // Cell name + float unk2; // Unknown value + char[32] player; // Player name + } + static assert(_saveData.sizeof == 124); + _saveData saveData; + // Get file information char[] getFilename() { return filename; } ulong getFileSize() { return file.size; } @@ -244,16 +258,10 @@ struct TES3File debug writefln("Reading header"); + // Do NOT .dup this filename, since it is referenced outside the + // GC's reach and might be deleted. this.filename = filename; - // Make a copy so the file name is not overwritten (not really needed?) - // this.filename = region.copy(filename); - - // Oops, this was bad. The file name ends up in various - // TES3FileContext structs, allocated outside the GC's reach. A - // .dup'ed copy might be released and overwritten. - // this.filename = filename.dup; - leftFile = file.size; // First things first @@ -316,13 +324,16 @@ struct TES3File if(type == FileType.Savegame) { - // What are these again? I don't remember. - getSubNameIs("GMDT"); - skipHSubSize(124); + // Savegame-related data + + // Cell name, player name and player position + readHNExact(&saveData, 124, "GMDT"); + + // Contains eg. 0xff0000, 0xff00, 0xff, 0x0, 0x20. No idea. getSubNameIs("SCRD"); skipHSubSize(20); - // Screenshot, used for save games. + // Screenshot. Fits with 128x128x4 bytes getSubNameIs("SCRS"); skipHSubSize(65536); } diff --git a/openmw.d b/openmw.d index 10af5ab1b0..a14bb45230 100644 --- a/openmw.d +++ b/openmw.d @@ -101,6 +101,13 @@ void main(char[][] args) } initializeMemoryRegions(); + + /* + importSavegame("data/quiksave.ess"); + importSavegame("data/Perm1hal0000.ess"); + return; + */ + config.initialize(resetKeys); scope(exit) config.writeConfig();