Skip to content

Commit

Permalink
AURORA: Add a writer for TheWitcherSave files
Browse files Browse the repository at this point in the history
  • Loading branch information
Nostritius authored and DrMcCoy committed Sep 23, 2018
1 parent 43b3d8f commit 378347f
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/aurora/rules.mk
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ src_aurora_libaurora_la_SOURCES += \
src/aurora/ltrfile.h \
src/aurora/textureatlasfile.h \
src/aurora/thewitchersavefile.h \
src/aurora/thewitchersavewriter.h \
src/aurora/sacfile.h \
src/aurora/fevfile.h \
$(EMPTY)
Expand Down Expand Up @@ -114,6 +115,7 @@ src_aurora_libaurora_la_SOURCES += \
src/aurora/ltrfile.cpp \
src/aurora/textureatlasfile.cpp \
src/aurora/thewitchersavefile.cpp \
src/aurora/thewitchersavewriter.cpp \
src/aurora/sacfile.cpp \
src/aurora/fevfile.cpp \
$(EMPTY)
Expand Down
94 changes: 94 additions & 0 deletions src/aurora/thewitchersavewriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* xoreos - A reimplementation of BioWare's Aurora engine
*
* xoreos is the legal property of its developers, whose names
* can be found in the AUTHORS file distributed with this source
* distribution.
*
* xoreos is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* xoreos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xoreos. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file
* Writer for writing TheWitcherSave files.
*/

#include "src/common/encoding.h"

#include "src/aurora/thewitchersavewriter.h"

namespace Aurora {

static const uint32 kRGMHID = MKTAG('R', 'G', 'M', 'H');

TheWitcherSaveWriter::TheWitcherSaveWriter(const Common::UString &areaName, Common::SeekableWriteStream &stream) :
_stream(stream), _finished(false) {
// Write the magic id
stream.writeUint32BE(kRGMHID);

// Write the version 1
stream.writeUint32LE(1);

// Write the constant header length
stream.writeUint64LE(8232);

// Write some zeros
stream.writeZeros(8);

// Write some values, which are always the same
stream.writeUint32LE(0xEE7C4A60);
stream.writeUint32LE(0x459E4568);
stream.writeUint32LE(0x10D3DBBD);
stream.writeUint32LE(0x1CBCF20B);

// Write Lightning Storm
Common::writeStringFixed(stream, "Lightning Storm", Common::kEncodingUTF16LE, 2048);

// Write the current area name two times
Common::writeStringFixed(stream, areaName, Common::kEncodingUTF16LE, 2048);
Common::writeStringFixed(stream, areaName, Common::kEncodingUTF16LE, 2048);

// Write 2048 zeros
stream.writeZeros(2048);
}

void TheWitcherSaveWriter::add(const Common::UString &fileName, Common::ReadStream &stream) {
if (_finished)
throw Common::Exception("TheWitcherSave::add() Archive is already finished");

Resource resource;
resource.name = fileName;
resource.offset = _stream.pos();
resource.size = _stream.writeStream(stream);

_resources.push_back(resource);
}

void TheWitcherSaveWriter::finish() {
if (_finished)
throw Common::Exception("TheWitcherSave::finish() Archive is already finished");

const size_t resourceTableOffset = _stream.pos();

for (size_t i = 0; i < _resources.size(); ++i) {
const Resource &r = _resources[i];
_stream.writeUint32LE(r.name.size());
Common::writeString(_stream, r.name, Common::kEncodingASCII, false);
_stream.writeUint32LE(r.size);
_stream.writeUint32LE(r.offset);
}

_stream.writeUint32LE(resourceTableOffset);
_stream.writeUint32LE(_resources.size());
}

} // End of namespace Aurora
69 changes: 69 additions & 0 deletions src/aurora/thewitchersavewriter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* xoreos - A reimplementation of BioWare's Aurora engine
*
* xoreos is the legal property of its developers, whose names
* can be found in the AUTHORS file distributed with this source
* distribution.
*
* xoreos is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* xoreos is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xoreos. If not, see <http://www.gnu.org/licenses/>.
*/

/** @file
* Writer for writing TheWitcherSave files.
*/

#ifndef AURORA_THEWITCHERSAVEWRITER_H
#define AURORA_THEWITCHERSAVEWRITER_H

#include "src/common/writestream.h"

namespace Aurora {

class TheWitcherSaveWriter {
public:
/** Create a new TheWitcherSave writer.
*
* @param areaName Set the area name which should be written
* into the header.
* @param stream The stream to write the file to.
*/
TheWitcherSaveWriter(const Common::UString &areaName, Common::SeekableWriteStream &stream);

/** Add a file to this TheWitcherSave archive.
*
* @param fileName The filename of the stream to write
* @param stream The stream of the
*/
void add(const Common::UString &fileName, Common::ReadStream &stream);

/** Finish the stream and write the file table at the
* end of the stream, and set the finished flag to prevent
* further adds.
*/
void finish();

private:
struct Resource {
Common::UString name;
size_t size, offset;
};

Common::SeekableWriteStream &_stream;

bool _finished;
std::vector<Resource> _resources;
};

} // End of namespace Aurora

#endif // AURORA_THEWITCHERSAVEWRITER_H

0 comments on commit 378347f

Please sign in to comment.