mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-20 00:41:12 +00:00
XEEN: Implemented code for 'saving' resources to the loaded savefile
This commit is contained in:
parent
0b5f79afb7
commit
3b1edcdf36
@ -32,7 +32,7 @@ namespace Xeen {
|
||||
/**
|
||||
* Hash a given filename to produce the Id that represents it
|
||||
*/
|
||||
uint16 BaseCCArchive::convertNameToId(const Common::String &resourceName) const {
|
||||
uint16 BaseCCArchive::convertNameToId(const Common::String &resourceName) {
|
||||
if (resourceName.empty())
|
||||
return 0xffff;
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "common/scummsys.h"
|
||||
#include "common/array.h"
|
||||
#include "common/file.h"
|
||||
#include "common/serializer.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "xeen/xsurface.h"
|
||||
|
||||
@ -61,6 +62,16 @@ public:
|
||||
void openFile(const Common::String &filename, Common::Archive &archive);
|
||||
};
|
||||
|
||||
class XeenSerializer : public Common::Serializer {
|
||||
private:
|
||||
Common::SeekableReadStream *_in;
|
||||
public:
|
||||
XeenSerializer(Common::SeekableReadStream *in, Common::WriteStream *out) :
|
||||
Common::Serializer(in, out), _in(in) {}
|
||||
|
||||
bool finished() const { return _in != nullptr && _in->pos() >= _in->size(); }
|
||||
};
|
||||
|
||||
/**
|
||||
* Details of a single entry in a CC file index
|
||||
*/
|
||||
@ -79,14 +90,14 @@ struct CCEntry {
|
||||
* Base Xeen CC file implementation
|
||||
*/
|
||||
class BaseCCArchive : public Common::Archive {
|
||||
private:
|
||||
uint16 convertNameToId(const Common::String &resourceName) const;
|
||||
protected:
|
||||
Common::Array<CCEntry> _index;
|
||||
|
||||
void loadIndex(Common::SeekableReadStream *stream);
|
||||
|
||||
virtual bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
|
||||
public:
|
||||
static uint16 convertNameToId(const Common::String &resourceName);
|
||||
public:
|
||||
BaseCCArchive() {}
|
||||
|
||||
|
@ -1042,8 +1042,9 @@ void Map::loadEvents(int mapId) {
|
||||
// Load events
|
||||
Common::String filename = Common::String::format("maze%c%03d.evt",
|
||||
(mapId >= 100) ? 'x' : '0', mapId);
|
||||
File fEvents(filename);
|
||||
_events.synchronize(fEvents);
|
||||
File fEvents(filename, *_vm->_saves);
|
||||
XeenSerializer sEvents(&fEvents, nullptr);
|
||||
_events.synchronize(sEvents);
|
||||
fEvents.close();
|
||||
|
||||
// Load text data
|
||||
@ -1052,11 +1053,23 @@ void Map::loadEvents(int mapId) {
|
||||
File fText(filename);
|
||||
_events._text.resize(fText.size());
|
||||
fText.read(&_events._text[0], fText.size());
|
||||
|
||||
_events.synchronize(fText);
|
||||
fText.close();
|
||||
}
|
||||
|
||||
void Map::saveMaze() {
|
||||
int mazeNum = _mazeData[0]._mazeNumber;
|
||||
if (!mazeNum || (mazeNum == 85 && !_vm->_files->_isDarkCc))
|
||||
return;
|
||||
|
||||
// Save the event data
|
||||
Common::String filename = Common::String::format("maze%c%03d.evt",
|
||||
(mazeNum >= 100) ? 'x' : '0', mazeNum);
|
||||
OutFile fEvents(_vm, filename);
|
||||
XeenSerializer sEvents(nullptr, &fEvents);
|
||||
_events.synchronize(sEvents);
|
||||
fEvents.finalize();
|
||||
}
|
||||
|
||||
void Map::cellFlagLookup(const Common::Point &pt) {
|
||||
Common::Point pos = pt;
|
||||
int mapId = _vm->_party._mazeId;
|
||||
|
@ -350,6 +350,8 @@ public:
|
||||
int mazeLookup(const Common::Point &pt, int directionLayerIndex);
|
||||
|
||||
void setCellSurfaceFlags(const Common::Point &pt, int bits);
|
||||
|
||||
void saveMaze();
|
||||
};
|
||||
|
||||
} // End of namespace Xeen
|
||||
|
@ -29,6 +29,22 @@
|
||||
|
||||
namespace Xeen {
|
||||
|
||||
OutFile::OutFile(XeenEngine *vm, const Common::String filename) :
|
||||
_vm(vm), _filename(filename) {
|
||||
}
|
||||
|
||||
void OutFile::finalize() {
|
||||
uint16 id = BaseCCArchive::convertNameToId(_filename);
|
||||
|
||||
if (!_vm->_saves->_newData.contains(id))
|
||||
_vm->_saves->_newData[id] = Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
|
||||
|
||||
Common::MemoryWriteStreamDynamic &out = _vm->_saves->_newData[id];
|
||||
out.write(getData(), size());
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
SavesManager::SavesManager(XeenEngine *vm, Party &party, Roster &roster) :
|
||||
BaseCCArchive(), _vm(vm), _party(party), _roster(roster) {
|
||||
SearchMan.add("saves", this, 0, false);
|
||||
@ -67,6 +83,15 @@ void SavesManager::syncBitFlags(Common::Serializer &s, bool *startP, bool *endP)
|
||||
Common::SeekableReadStream *SavesManager::createReadStreamForMember(const Common::String &name) const {
|
||||
CCEntry ccEntry;
|
||||
|
||||
// If the given resource has already been perviously "written" to the
|
||||
// save manager, then return that new resource
|
||||
uint16 id = BaseCCArchive::convertNameToId(name);
|
||||
if (_newData.contains(id)) {
|
||||
Common::MemoryWriteStreamDynamic stream = _newData[id];
|
||||
return new Common::MemoryReadStream(stream.getData(), stream.size());
|
||||
}
|
||||
|
||||
// Retrieve the resource from the loaded savefile
|
||||
if (getHeaderEntry(name, ccEntry)) {
|
||||
// Open the correct CC entry
|
||||
return new Common::MemoryReadStream(_data + ccEntry._offset, ccEntry._size);
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define XEEN_SAVES_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/memstream.h"
|
||||
#include "common/savefile.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "xeen/party.h"
|
||||
@ -40,12 +41,27 @@ struct XeenSavegameHeader {
|
||||
int _totalFrames;
|
||||
};
|
||||
|
||||
class XeenEngine;
|
||||
class SavesManager;
|
||||
|
||||
class OutFile : public Common::MemoryWriteStreamDynamic {
|
||||
private:
|
||||
XeenEngine *_vm;
|
||||
Common::String _filename;
|
||||
public:
|
||||
OutFile(XeenEngine *vm, const Common::String filename);
|
||||
|
||||
void finalize();
|
||||
};
|
||||
|
||||
class SavesManager: public BaseCCArchive {
|
||||
friend class OutFile;
|
||||
private:
|
||||
XeenEngine *_vm;
|
||||
Party &_party;
|
||||
Roster &_roster;
|
||||
byte *_data;
|
||||
Common::HashMap<uint16, Common::MemoryWriteStreamDynamic > _newData;
|
||||
|
||||
void load(Common::SeekableReadStream *stream);
|
||||
public:
|
||||
|
@ -27,27 +27,37 @@ namespace Xeen {
|
||||
MazeEvent::MazeEvent() : _direction(DIR_ALL), _line(-1), _opcode(OP_None) {
|
||||
}
|
||||
|
||||
void MazeEvent::synchronize(Common::SeekableReadStream &s) {
|
||||
int len = s.readByte();
|
||||
_position.x = s.readByte();
|
||||
_position.y = s.readByte();
|
||||
_direction = (Direction)s.readByte();
|
||||
_line = s.readByte();
|
||||
_opcode = (Opcode)s.readByte();
|
||||
void MazeEvent::synchronize(Common::Serializer &s) {
|
||||
int len = 5 + _parameters.size();
|
||||
s.syncAsByte(len);
|
||||
|
||||
for (int i = 0; i < (len - 5); ++i)
|
||||
_parameters.push_back(s.readByte());
|
||||
s.syncAsByte(_position.x);
|
||||
s.syncAsByte(_position.y);
|
||||
s.syncAsByte(_direction);
|
||||
s.syncAsByte(_line);
|
||||
s.syncAsByte(_opcode);
|
||||
|
||||
len -= 5;
|
||||
if (s.isLoading())
|
||||
_parameters.resize(len);
|
||||
for (int i = 0; i < len; ++i)
|
||||
s.syncAsByte(_parameters[i]);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
void MazeEvents::synchronize(Common::SeekableReadStream &s) {
|
||||
void MazeEvents::synchronize(XeenSerializer &s) {
|
||||
MazeEvent e;
|
||||
|
||||
clear();
|
||||
while (!s.eos()) {
|
||||
e.synchronize(s);
|
||||
push_back(e);
|
||||
if (s.isLoading()) {
|
||||
clear();
|
||||
while (!s.finished()) {
|
||||
e.synchronize(s);
|
||||
push_back(e);
|
||||
}
|
||||
} else {
|
||||
for (uint i = 0; i < size(); ++i)
|
||||
(*this).operator[](i).synchronize(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,8 @@
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/system.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/serializer.h"
|
||||
#include "xeen/files.h"
|
||||
#include "xeen/party.h"
|
||||
|
||||
namespace Xeen {
|
||||
@ -104,14 +105,14 @@ public:
|
||||
public:
|
||||
MazeEvent();
|
||||
|
||||
void synchronize(Common::SeekableReadStream &s);
|
||||
void synchronize(Common::Serializer &s);
|
||||
};
|
||||
|
||||
class MazeEvents : public Common::Array<MazeEvent> {
|
||||
public:
|
||||
Common::Array<byte> _text;
|
||||
public:
|
||||
void synchronize(Common::SeekableReadStream &s);
|
||||
void synchronize(XeenSerializer &s);
|
||||
};
|
||||
|
||||
} // End of namespace Xeen
|
||||
|
Loading…
Reference in New Issue
Block a user