Skip to content

Commit

Permalink
XEEN: Add prefix support to CC files, initial save state fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
dreammaster committed Jan 8, 2015
1 parent cd7c00c commit 96d086a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 10 deletions.
48 changes: 44 additions & 4 deletions engines/xeen/files.cpp
Expand Up @@ -39,6 +39,14 @@ uint16 BaseCCArchive::convertNameToId(const Common::String &resourceName) const
Common::String name = resourceName;
name.toUppercase();

// Check if a resource number is being directly specified
if (name.size() == 4) {
char *endPtr;
uint16 num = (uint16)strtol(name.c_str(), &endPtr, 16);
if (!*endPtr)
return num;
}

const byte *msgP = (const byte *)name.c_str();
int total = *msgP++;
for (; *msgP; total += *msgP++) {
Expand Down Expand Up @@ -121,14 +129,41 @@ int BaseCCArchive::listMembers(Common::ArchiveMemberList &list) const {
/*------------------------------------------------------------------------*/

CCArchive::CCArchive(const Common::String &filename, bool encoded):
_filename(filename), _encoded(encoded) {
BaseCCArchive(), _filename(filename), _encoded(encoded) {
File f(filename);
loadIndex(&f);
}

CCArchive::CCArchive(const Common::String &filename, const Common::String &prefix,
bool encoded): BaseCCArchive(), _filename(filename),
_prefix(prefix), _encoded(encoded) {
_prefix.toLowercase();
File f(filename);
loadIndex(&f);
}

CCArchive::~CCArchive() {
}

bool CCArchive::getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const {
Common::String resName = resourceName;

if (!_prefix.empty() && resName.contains('|')) {
resName.toLowercase();
Common::String prefix = _prefix + "|";

if (!strncmp(resName.c_str(), prefix.c_str(), prefix.size()))
// Matching CC prefix, so strip it off and allow processing to
// continue onto the base getHeaderEntry method
resName = Common::String(resName.c_str() + prefix.size());
else
// Not matching prefix, so don't allow a match
return false;
}

return BaseCCArchive::getHeaderEntry(resName, ccEntry);
}

Common::SeekableReadStream *CCArchive::createReadStreamForMember(const Common::String &name) const {
CCEntry ccEntry;

Expand Down Expand Up @@ -166,9 +201,9 @@ FileManager::FileManager(XeenEngine *vm) {

_isDarkCc = vm->getGameID() != GType_Clouds;
if (_isDarkCc)
SearchMan.add("dark", new CCArchive("dark.cc"));
SearchMan.add("xeen", new CCArchive("xeen.cc"));
SearchMan.add("intro", new CCArchive("intro.cc"));
SearchMan.add("dark", new CCArchive("dark.cc", "dark", true));
SearchMan.add("xeen", new CCArchive("xeen.cc", "xeen", true));
SearchMan.add("intro", new CCArchive("intro.cc", "intro", true));
}

/*------------------------------------------------------------------------*/
Expand All @@ -181,4 +216,9 @@ void File::openFile(const Common::String &filename) {
error("Could not open file - %s", filename.c_str());
}

void File::openFile(const Common::String &filename, Common::Archive &archive) {
if (!Common::File::open(filename, archive))
error("Could not open file - %s", filename.c_str());
}

} // End of namespace Xeen
12 changes: 10 additions & 2 deletions engines/xeen/files.h
Expand Up @@ -52,9 +52,13 @@ class File : public Common::File {
public:
File() : Common::File() {}
File(const Common::String &filename) { openFile(filename); }
File(const Common::String &filename, Common::Archive &archive) {
openFile(filename, archive);
}
virtual ~File() {}

void openFile(const Common::String &filename);
void openFile(const Common::String &filename, Common::Archive &archive);
};

/**
Expand Down Expand Up @@ -82,7 +86,7 @@ class BaseCCArchive : public Common::Archive {

void loadIndex(Common::SeekableReadStream *stream);

bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
virtual bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
public:
BaseCCArchive() {}

Expand All @@ -98,9 +102,13 @@ class BaseCCArchive : public Common::Archive {
class CCArchive : public BaseCCArchive {
private:
Common::String _filename;
Common::String _prefix;
bool _encoded;
protected:
virtual bool getHeaderEntry(const Common::String &resourceName, CCEntry &ccEntry) const;
public:
CCArchive(const Common::String &filename, bool encoded = true);
CCArchive(const Common::String &filename, bool encoded);
CCArchive(const Common::String &filename, const Common::String &prefix, bool encoded);
virtual ~CCArchive();

// Archive implementation
Expand Down
4 changes: 2 additions & 2 deletions engines/xeen/map.cpp
Expand Up @@ -714,7 +714,7 @@ void MonsterObjectData::synchronize(Common::SeekableReadStream &s,
}

// Merge up wall items
_wallItems.clear();
_wallItems.resize(1);
for (uint i = 0; i < wallItemData.size(); ++i) {
MazeWallItem &dest = _wallItems[i];
dest._position = wallItemData[i]._pos;
Expand Down Expand Up @@ -897,7 +897,7 @@ void Map::load(int mapId) {
// Reload the monster data for the main maze that we're loading
Common::String filename = Common::String::format("maze%c%03u.mob",
(_vm->_party._mazeId >= 100) ? 'x' : '0', _vm->_party._mazeId);
File mobFile(filename);
File mobFile(filename, *_vm->_saves);
_mobData.synchronize(mobFile, _isOutdoors, _monsterData);
mobFile.close();

Expand Down
33 changes: 31 additions & 2 deletions engines/xeen/saves.cpp
Expand Up @@ -99,10 +99,39 @@ void SavesManager::load(Common::SeekableReadStream *stream) {
* Sets up the dynamic data for the game for a new game
*/
void SavesManager::reset() {
Common::String name(_vm->getGameID() == GType_Clouds ? "xeen.cur" : "dark.cur");
File f(name);
Common::String prefix = _vm->getGameID() == GType_Clouds ? "xeen|" : "dark|";
Common::MemoryWriteStreamDynamic saveFile(DisposeAfterUse::YES);
Common::File fIn;

for (int i = 0; i <= 5; ++i) {
Common::String filename = prefix + Common::String::format("2A%dC", i);
if (fIn.exists(filename)) {
// Read in the next resource
fIn.open(filename);
byte *data = new byte[fIn.size()];
fIn.read(data, fIn.size());

// Copy it to the combined savefile resource
saveFile.write(data, fIn.size());
delete[] data;
fIn.close();
}
}

Common::MemoryReadStream f(saveFile.getData(), saveFile.size());
load(&f);

// Set up the party and characters from dark.cur
CCArchive gameCur("xeen.cur", false);
File fParty("maze.pty", gameCur);
Common::Serializer sParty(&fParty, nullptr);
_party.synchronize(sParty);
fParty.close();

File fChar("maze.chr", gameCur);
Common::Serializer sChar(&fChar, nullptr);
_roster.synchronize(sChar);
fChar.close();
}

void SavesManager::readCharFile() {
Expand Down

0 comments on commit 96d086a

Please sign in to comment.