aboutsummaryrefslogtreecommitdiff
path: root/engines/mads
diff options
context:
space:
mode:
authorPaul Gilbert2014-02-20 22:27:01 -0500
committerPaul Gilbert2014-02-20 22:27:01 -0500
commit4581b26b12d21801eee0c5df2dbd1b260300498c (patch)
treec81ec919b3c9df78cfe638d06388159fc91ebc09 /engines/mads
parentde384bae2ef1b904224b0fe00326e5a0597aafb6 (diff)
downloadscummvm-rg350-4581b26b12d21801eee0c5df2dbd1b260300498c.tar.gz
scummvm-rg350-4581b26b12d21801eee0c5df2dbd1b260300498c.tar.bz2
scummvm-rg350-4581b26b12d21801eee0c5df2dbd1b260300498c.zip
MADS: Implemented resource manager using ScummVM Archive interface
Diffstat (limited to 'engines/mads')
-rw-r--r--engines/mads/compression.cpp4
-rw-r--r--engines/mads/font.cpp4
-rw-r--r--engines/mads/mads.cpp2
-rw-r--r--engines/mads/msurface.cpp23
-rw-r--r--engines/mads/nebular/dialogs_nebular.h2
-rw-r--r--engines/mads/resources.cpp259
-rw-r--r--engines/mads/resources.h35
7 files changed, 293 insertions, 36 deletions
diff --git a/engines/mads/compression.cpp b/engines/mads/compression.cpp
index b5e24dfc5e..febb6ec90f 100644
--- a/engines/mads/compression.cpp
+++ b/engines/mads/compression.cpp
@@ -46,9 +46,9 @@ MadsPack::MadsPack(Common::SeekableReadStream *stream) {
}
MadsPack::MadsPack(const Common::String &resourceName, MADSEngine *vm) {
- Common::SeekableReadStream *stream = vm->_resources->get(resourceName);
+ Common::SeekableReadStream *stream = nullptr; //vm->_resources->get(resourceName);
initialise(stream);
- vm->_resources->toss(resourceName);
+// vm->_resources->toss(resourceName);
}
void MadsPack::initialise(Common::SeekableReadStream *stream) {
diff --git a/engines/mads/font.cpp b/engines/mads/font.cpp
index e97cc95fdf..076eca92c6 100644
--- a/engines/mads/font.cpp
+++ b/engines/mads/font.cpp
@@ -233,7 +233,7 @@ void FontM4::setFont(const Common::String &filename) {
_sysFont = false;
_filename = filename;
- Common::SeekableReadStream *fontFile = _vm->_resources->openFile(filename);
+ Common::SeekableReadStream *fontFile = nullptr; //_vm->_resources->openFile(filename);
if (fontFile->readUint32LE() != MKTAG('F', 'O', 'N', 'T')) {
warning("Font: FONT tag expected");
@@ -272,7 +272,7 @@ void FontM4::setFont(const Common::String &filename) {
_charData = new uint8[fontSize];
fontFile->read(_charData, fontSize);
- _vm->_resources->toss(filename);
+// _vm->_resources->toss(filename);
}
int FontM4::getBpp(int charWidth) {
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index 05c11409db..ec99b314a7 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -72,10 +72,10 @@ void MADSEngine::initialise() {
MSurface::setVm(this);
MSprite::setVm(this);
+ ResourcesManager::init(this);
_events = new EventsManager(this);
_palette = Palette::init(this);
_font = Font::init(this);
- _resources = new ResourcesManager(this);
_screen = MSurface::init(true);
_sound = new SoundManager(this, _mixer);
_userInterface = UserInterface::init(this);
diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp
index f71a4a7a4e..2c0b433159 100644
--- a/engines/mads/msurface.cpp
+++ b/engines/mads/msurface.cpp
@@ -26,6 +26,7 @@
#include "mads/mads.h"
#include "mads/msprite.h"
#include "mads/msurface.h"
+#include "mads/resources.h"
namespace MADS {
@@ -412,14 +413,14 @@ void MSurfaceMADS::loadBackground(int roomNumber, RGBList **palData) {
tileMap[i] = mapStream->readUint16LE();
delete mapStream;
- _vm->_resources->toss(resourceName);
+// _vm->_resources->toss(resourceName);
// --------------------------------------------------------------------------------
// Tile map data, which needs to be kept compressed, as the tile offsets refer to
// the compressed data. Each tile is then uncompressed separately
sprintf(resourceName, "rm%d.tt", roomNumber);
- Common::SeekableReadStream *tileDataComp = _vm->_resources->get(resourceName);
+ Common::SeekableReadStream *tileDataComp = nullptr; //_vm->_resources->get(resourceName);
MadsPack tileData(tileDataComp);
Common::SeekableReadStream *tileDataUncomp = tileData.getItemStream(0);
@@ -499,7 +500,7 @@ void MSurfaceMADS::loadBackground(int roomNumber, RGBList **palData) {
}
}
tileSet.clear();
- _vm->_resources->toss(resourceName);
+// _vm->_resources->toss(resourceName);
}
void MSurfaceMADS::loadInterface(int index, RGBList **palData) {
@@ -534,10 +535,10 @@ void MSurfaceNebular::loadBackground(int roomNumber, RGBList **palData) {
empty();
Common::String resourceName = Common::String::format("rm%d.art", roomNumber);
- Common::SeekableReadStream *stream = _vm->_resources->get(resourceName);
+ Common::SeekableReadStream *stream = nullptr; //_vm->_resources->get(resourceName);
loadBackgroundStream(stream, palData);
- _vm->_resources->toss(resourceName);
+// _vm->_resources->toss(resourceName);
}
void MSurfaceNebular::loadBackgroundStream(Common::SeekableReadStream *source, RGBList **palData) {
@@ -597,10 +598,10 @@ void MSurfaceM4::loadBackground(int roomNumber, RGBList **palData) {
if (palData)
*palData = NULL;
Common::String resourceName = Common::String::format("%i.tt", roomNumber);
- Common::SeekableReadStream *stream = _vm->_resources->get(resourceName);
+ Common::SeekableReadStream *stream = nullptr;//_vm->_resources->get(resourceName);
loadBackgroundStream(stream);
- _vm->_resources->toss(resourceName);
+// _vm->_resources->toss(resourceName);
}
void MSurfaceM4::loadBackgroundStream(Common::SeekableReadStream *source) {
@@ -663,15 +664,11 @@ void MSurfaceM4::loadBackgroundStream(Common::SeekableReadStream *source) {
/*------------------------------------------------------------------------*/
void MSurfaceRiddle::loadBackground(const Common::String &sceneName) {
- char resourceName[20];
- Common::SeekableReadStream *stream;
// Loads a Riddle scene
Common::String resName = Common::String::format("%s.tt", sceneName.c_str());
- stream = _vm->_resources->get(resourceName);
-
- loadBackgroundStream(stream);
+ File stream(resName);
- _vm->_resources->toss(resourceName);
+ loadBackgroundStream(&stream);
}
} // End of namespace MADS
diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h
index 669ac1e775..a747f7575d 100644
--- a/engines/mads/nebular/dialogs_nebular.h
+++ b/engines/mads/nebular/dialogs_nebular.h
@@ -31,6 +31,8 @@ namespace MADS {
namespace Nebular {
class CopyProtectionDialog {
+private:
+
public:
static bool show() { return false; }
};
diff --git a/engines/mads/resources.cpp b/engines/mads/resources.cpp
index 27b94a9e55..0630230bec 100644
--- a/engines/mads/resources.cpp
+++ b/engines/mads/resources.cpp
@@ -21,12 +21,267 @@
*/
#include "common/scummsys.h"
+#include "common/archive.h"
+#include "common/substream.h"
+#include "common/textconsole.h"
+#include "mads/mads.h"
#include "mads/resources.h"
namespace MADS {
-ResourcesManager::ResourcesManager(MADSEngine *vm) {
- _vm = vm;
+enum ResourceType {RESTYPE_ROOM, RESTYPE_SC, RESTYPE_TEXT, RESTYPE_QUO, RESTYPE_I,
+ RESTYPE_OB, RESTYPE_FONT, RESTYPE_SOUND, RESTYPE_SPEECH, RESTYPE_HAS_EXT, RESTYPE_NO_EXT};
+
+/**
+ * HAG Archives implementation
+ */
+class HagArchive : public Common::Archive {
+private:
+ /**
+ * Details of a single entry in a HAG file index
+ */
+ struct HagEntry {
+ Common::String _resourceName;
+ uint32 _offset;
+ uint32 _size;
+
+ HagEntry(): _offset(0), _size(0) {}
+ HagEntry(Common::String resourceName, uint32 offset, uint32 size):
+ _resourceName(resourceName), _offset(offset), _size(size) {}
+ };
+
+ class HagIndex {
+ public:
+ Common::List<HagEntry> _entries;
+ Common::String _filename;
+ };
+
+ Common::Array<HagIndex> _index;
+
+ /**
+ * Load the index of all the game's HAG files
+ */
+ void loadIndex();
+
+ /**
+ * Given a resource name, opens up the correct HAG file and returns whether
+ * an entry with the given name exists.
+ */
+ bool getHeaderEntry(const Common::String &resourceName, HagIndex &hagIndex, HagEntry &hagEntry) const;
+
+ /**
+ * Returns the HAG resource filename that will contain a given resource
+ */
+ Common::String getResourceFilename(const Common::String &resourceName) const;
+
+ /**
+ * Return a resource type given a resource name
+ */
+ ResourceType getResourceType(const Common::String &resourceName) const;
+public:
+ HagArchive();
+ virtual ~HagArchive();
+
+ // Archive implementation
+ virtual bool hasFile(const Common::String &name) const;
+ virtual int listMembers(Common::ArchiveMemberList &list) const;
+ virtual const Common::ArchiveMemberPtr getMember(const Common::String &name) const;
+ virtual Common::SeekableReadStream *createReadStreamForMember(const Common::String &name) const;
+};
+
+void ResourcesManager::init(MADSEngine *vm) {
+ if (vm->getGameFeatures() & GF_MADS)
+ SearchMan.add("HAG", new HagArchive());
+ else
+ error("Unsupported game engine");
+}
+
+/*------------------------------------------------------------------------*/
+
+void File::openFile(const Common::String &filename) {
+ if (!Common::File::open(filename))
+ error("Could not open file - %s", filename.c_str());
+}
+
+/*------------------------------------------------------------------------*/
+
+const char *const MADSCONCAT_STRING = "MADSCONCAT";
+
+HagArchive::HagArchive() {
+ loadIndex();
+}
+
+HagArchive::~HagArchive() {
+}
+
+// Archive implementation
+bool HagArchive::hasFile(const Common::String &name) const {
+ HagIndex hagIndex;
+ HagEntry hagEntry;
+ return getHeaderEntry(name, hagIndex, hagEntry);
+}
+
+int HagArchive::listMembers(Common::ArchiveMemberList &list) const {
+ int members = 0;
+
+ for (uint hagCtr = 0; hagCtr < _index.size(); ++hagCtr) {
+ HagIndex hagIndex = _index[hagCtr];
+ Common::List<HagEntry>::iterator i;
+
+ for (i = hagIndex._entries.begin(); i != hagIndex._entries.end(); ++i) {
+ list.push_back(Common::ArchiveMemberList::value_type(
+ new Common::GenericArchiveMember((*i)._resourceName, this)));
+ ++members;
+ }
+ }
+
+ return members;
+}
+
+const Common::ArchiveMemberPtr HagArchive::getMember(const Common::String &name) const {
+ if (!hasFile(name))
+ return Common::ArchiveMemberPtr();
+
+ return Common::ArchiveMemberPtr(new Common::GenericArchiveMember(name, this));
+}
+
+Common::SeekableReadStream *HagArchive::createReadStreamForMember(const Common::String &name) const {
+ HagIndex hagIndex;
+ HagEntry hagEntry;
+
+ if (getHeaderEntry(name, hagIndex, hagEntry)) {
+ // Entry found. If the correct file is not already open, open it
+ Common::File f;
+ if (!f.open(hagIndex._filename))
+ error("Could not open HAG file");
+
+ // Return a substream for the specific resource
+ return new Common::SeekableSubReadStream(&f,
+ hagEntry._offset, hagEntry._size, DisposeAfterUse::YES);
+ }
+
+ return nullptr;
+}
+
+void HagArchive::loadIndex() {
+ Common::File hagFile;
+
+ for (int sectionIndex = -1; sectionIndex < 10; ++sectionIndex) {
+ Common::String filename = (sectionIndex == -1) ? "GLOBAL.HAG" :
+ Common::String::format("SECTION%d.HAG", sectionIndex);
+ if (!hagFile.open(filename))
+ error("Could not locate HAG file - %s", filename.c_str());
+
+ // Check for header
+ char headerBuffer[16];
+ if ((hagFile.read(headerBuffer, 16) != 16) ||
+ (strncmp(headerBuffer, MADSCONCAT_STRING, 10) != 0))
+ error("Invalid HAG file opened");
+
+ // Scan through the HAG index
+ int numEntries = hagFile.readUint16LE();
+
+ HagIndex hagIndex;
+ for (int idx = 0; idx < numEntries; ++idx) {
+ // Read in the details of the next resource
+ char resourceBuffer[14];
+ uint32 offset = hagFile.readUint32LE();
+ uint32 size = hagFile.readUint32LE();
+ hagFile.read(resourceBuffer, 14);
+
+ hagIndex._entries.push_back(HagEntry(resourceBuffer, offset, size));
+ }
+
+ hagFile.close();
+ _index.push_back(hagIndex);
+ }
+}
+
+bool HagArchive::getHeaderEntry(const Common::String &resourceName,
+ HagIndex &hagIndex, HagEntry &hagEntry) const {
+ Common::String resName = resourceName;
+ resName.toUppercase();
+ if (resName[0] == '*')
+ resName.deleteChar(0);
+
+ Common::String hagFilename = getResourceFilename(resName);
+
+ // Find the index for the given file
+ for (uint hagCtr = 0; hagCtr < _index.size(); ++hagCtr) {
+ hagIndex = _index[hagCtr];
+
+ if (hagIndex._filename == hagFilename) {
+ Common::List<HagEntry>::iterator ei;
+ for (ei = hagIndex._entries.begin(); ei != hagIndex._entries.end(); ++ei) {
+ hagEntry = *ei;
+ if (hagEntry._resourceName == resName)
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+Common::String HagArchive::getResourceFilename(const Common::String &resourceName) const {
+ ResourceType resType = getResourceType(resourceName);
+ Common::String outputFilename = "GLOBAL.HAG";
+
+ if ((resType == RESTYPE_ROOM) || (resType == RESTYPE_SC)) {
+ int value = atoi(resourceName.c_str() + 2);
+ int hagFileNum = (resType == RESTYPE_ROOM) ? value / 100 : value;
+
+ if (hagFileNum > 0)
+ outputFilename = Common::String::format("SECTION%d.HAG", hagFileNum);
+ }
+
+ if (resType == RESTYPE_SPEECH)
+ outputFilename = "SPEECH.HAG";
+
+ return outputFilename;
+}
+
+ResourceType HagArchive::getResourceType(const Common::String &resourceName) const {
+ if (resourceName.hasPrefix("RM")) {
+ // Room resource
+ return RESTYPE_ROOM;
+ } else if (resourceName.hasPrefix("SC")) {
+ // SC resource
+ return RESTYPE_SC;
+ } else if (resourceName.hasSuffix(".TXT")) {
+ // Text resource
+ return RESTYPE_TEXT;
+ } else if (resourceName.hasSuffix(".QUO")) {
+ // QUO resource
+ return RESTYPE_QUO;
+ } else if (resourceName.hasPrefix("I")) {
+ // I resource
+ return RESTYPE_I;
+ } else if (resourceName.hasPrefix("OB")) {
+ // OB resource
+ return RESTYPE_OB;
+ } else if (resourceName.hasPrefix("FONT")) {
+ // FONT resource
+ return RESTYPE_FONT;
+ } else if (resourceName.hasPrefix("SOUND")) {
+ // SOUND resource
+ return RESTYPE_SOUND;
+ } else if (resourceName.hasPrefix("SPCHC")) {
+ // SPEECH resource
+ return RESTYPE_SPEECH;
+ }
+
+ // Check for a known extension
+ const char *extPos = strchr(resourceName.c_str(), '.');
+ if (extPos) {
+ ++extPos;
+ if (!strcmp(extPos, "FL") || !strcmp(extPos, "LBM") || !strcmp(extPos, "ANM") ||
+ !strcmp(extPos, "AA") || !strcmp(extPos, "SS")) {
+ return RESTYPE_HAS_EXT;
+ }
+ }
+
+ return RESTYPE_NO_EXT;
}
} // End of namespace MADS
diff --git a/engines/mads/resources.h b/engines/mads/resources.h
index 68bb475aee..f4b7009e13 100644
--- a/engines/mads/resources.h
+++ b/engines/mads/resources.h
@@ -24,7 +24,7 @@
#define MADS_RESOURCES_H
#include "common/scummsys.h"
-#include "common/stream.h"
+#include "common/file.h"
#include "common/str.h"
namespace MADS {
@@ -32,29 +32,32 @@ namespace MADS {
class MADSEngine;
class ResourcesManager {
-private:
- MADSEngine *_vm;
public:
- ResourcesManager(MADSEngine *vm);
+ /**
+ * Instantiates the resource manager
+ */
+ static void init(MADSEngine *vm);
+};
+/**
+ * Derived file class
+ */
+class File: public Common::File {
+public:
/**
- * Return a named resource
+ * Constructor
*/
- Common::SeekableReadStream *get(const Common::String &resourceName, bool loadFlag = false) {
- // TODO
- return nullptr;
- }
+ File(): Common::File() {}
- Common::SeekableReadStream *openFile(const Common::String &resourceName) {
- return get(resourceName, false);
- }
+ /**
+ * Constructor
+ */
+ File(const Common::String &filename) { openFile(filename); }
/**
- * Release a previously loaded resource
+ * Opens the given file, throwing an error if it can't be opened
*/
- void toss(const Common::String &resourceName) {
- // TODO
- }
+ void openFile(const Common::String &filename);
};
} // End of namespace MADS