aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mohawk/console.cpp22
-rw-r--r--engines/mohawk/console.h1
-rw-r--r--engines/mohawk/module.mk1
-rw-r--r--engines/mohawk/mohawk.cpp2
-rw-r--r--engines/mohawk/mohawk.h2
-rw-r--r--engines/mohawk/myst.cpp86
-rw-r--r--engines/mohawk/myst.h13
-rw-r--r--engines/mohawk/resource_cache.cpp84
-rw-r--r--engines/mohawk/resource_cache.h59
9 files changed, 266 insertions, 4 deletions
diff --git a/engines/mohawk/console.cpp b/engines/mohawk/console.cpp
index 80ba710a47..7521bcd194 100644
--- a/engines/mohawk/console.cpp
+++ b/engines/mohawk/console.cpp
@@ -47,6 +47,7 @@ MystConsole::MystConsole(MohawkEngine_Myst *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("stopSound", WRAP_METHOD(MystConsole, Cmd_StopSound));
DCmd_Register("playMovie", WRAP_METHOD(MystConsole, Cmd_PlayMovie));
DCmd_Register("disableInitOpcodes", WRAP_METHOD(MystConsole, Cmd_DisableInitOpcodes));
+ DCmd_Register("cache", WRAP_METHOD(MystConsole, Cmd_Cache));
}
MystConsole::~MystConsole() {
@@ -270,6 +271,27 @@ bool MystConsole::Cmd_DisableInitOpcodes(int argc, const char **argv) {
return true;
}
+bool MystConsole::Cmd_Cache(int argc, const char **argv) {
+ if (argc > 2) {
+ DebugPrintf("Usage: cache on/off - Omit parameter to get current state\n");
+ return true;
+ }
+
+ bool state = false;
+
+ if (argc == 1) {
+ state = _vm->getCacheState();
+ } else {
+ if (!scumm_stricmp(argv[1], "on"))
+ state = true;
+
+ _vm->setCacheState(state);
+ }
+
+ DebugPrintf("Cache: %s\n", state ? "Enabled" : "Disabled");
+ return true;
+}
+
RivenConsole::RivenConsole(MohawkEngine_Riven *vm) : GUI::Debugger(), _vm(vm) {
DCmd_Register("changeCard", WRAP_METHOD(RivenConsole, Cmd_ChangeCard));
DCmd_Register("curCard", WRAP_METHOD(RivenConsole, Cmd_CurCard));
diff --git a/engines/mohawk/console.h b/engines/mohawk/console.h
index e79f151894..9a30d46225 100644
--- a/engines/mohawk/console.h
+++ b/engines/mohawk/console.h
@@ -58,6 +58,7 @@ private:
bool Cmd_StopSound(int argc, const char **argv);
bool Cmd_PlayMovie(int argc, const char **argv);
bool Cmd_DisableInitOpcodes(int argc, const char **argv);
+ bool Cmd_Cache(int argc, const char **argv);
};
class RivenConsole : public GUI::Debugger {
diff --git a/engines/mohawk/module.mk b/engines/mohawk/module.mk
index ef1b5f7bb5..b224a8b143 100644
--- a/engines/mohawk/module.mk
+++ b/engines/mohawk/module.mk
@@ -15,6 +15,7 @@ MODULE_OBJS = \
myst_saveload.o \
myst_scripts.o \
resource.o \
+ resource_cache.o \
riven.o \
riven_external.o \
riven_saveload.o \
diff --git a/engines/mohawk/mohawk.cpp b/engines/mohawk/mohawk.cpp
index a4eba550d9..5bde6bbeec 100644
--- a/engines/mohawk/mohawk.cpp
+++ b/engines/mohawk/mohawk.cpp
@@ -90,7 +90,7 @@ Common::SeekableReadStream *MohawkEngine::getRawData(uint32 tag, uint16 id) {
return _mhk[i]->getRawData(tag, id);
error ("Could not find a \'%s\' resource with ID %04x", tag2str(tag), id);
- return 0;
+ return NULL;
}
bool MohawkEngine::hasResource(uint32 tag, uint16 id) {
diff --git a/engines/mohawk/mohawk.h b/engines/mohawk/mohawk.h
index 280995d070..f5ad730d81 100644
--- a/engines/mohawk/mohawk.h
+++ b/engines/mohawk/mohawk.h
@@ -86,7 +86,7 @@ public:
Sound *_sound;
VideoManager *_video;
- Common::SeekableReadStream *getRawData(uint32 tag, uint16 id);
+ virtual Common::SeekableReadStream *getRawData(uint32 tag, uint16 id);
bool hasResource(uint32 tag, uint16 id);
uint32 getResourceOffset(uint32 tag, uint16 id);
diff --git a/engines/mohawk/myst.cpp b/engines/mohawk/myst.cpp
index f7b373b359..1055414d1f 100644
--- a/engines/mohawk/myst.cpp
+++ b/engines/mohawk/myst.cpp
@@ -31,6 +31,7 @@
#include "mohawk/myst_saveload.h"
#include "mohawk/dialogs.h"
#include "mohawk/resource.h"
+#include "mohawk/resource_cache.h"
#include "mohawk/video/video.h"
namespace Mohawk {
@@ -45,6 +46,7 @@ MohawkEngine_Myst::MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription
Common::addDebugChannel(kDebugEXIT, "Exit", "Track Card Exit Script (EXIT) Parsing");
Common::addDebugChannel(kDebugScript, "Script", "Track Script Execution");
Common::addDebugChannel(kDebugHelp, "Help", "Track Help File (HELP) Parsing");
+ Common::addDebugChannel(kDebugCache, "Cache", "Track Resource Cache Accesses");
_zipMode = false;
_transitionsEnabled = false;
@@ -90,6 +92,40 @@ MohawkEngine_Myst::~MohawkEngine_Myst() {
_resources.clear();
}
+// Uses cached data objects in preference to disk access
+Common::SeekableReadStream *MohawkEngine_Myst::getRawData(uint32 tag, uint16 id) {
+ Common::SeekableReadStream *ret;
+
+ ret = _cache.search(tag, id);
+ if(ret != NULL) return ret;
+
+ for (uint32 i = 0; i < _mhk.size(); i++)
+ if (_mhk[i]->hasResource(tag, id)) {
+ ret = _mhk[i]->getRawData(tag, id);
+ _cache.add(tag, id, ret);
+ return ret;
+ }
+
+ error ("Could not find a \'%s\' resource with ID %04x", tag2str(tag), id);
+ return NULL;
+}
+
+void MohawkEngine_Myst::cachePreload(uint32 tag, uint16 id) {
+ Common::SeekableReadStream *tempData;
+
+ if (!_cache.enabled) return;
+
+ for (uint32 i = 0; i < _mhk.size(); i++)
+ if (_mhk[i]->hasResource(tag, id)) {
+ tempData = _mhk[i]->getRawData(tag, id);
+ _cache.add(tag, id, tempData);
+ delete tempData;
+ return;
+ }
+
+ warning ("cachePreload : Could not find a \'%s\' resource with ID %04x", tag2str(tag), id);
+}
+
static const char *mystFiles[] = {
"channel.dat",
"credits.dat",
@@ -299,6 +335,8 @@ void MohawkEngine_Myst::changeToStack(uint16 stack) {
_gfx->loadExternalPictureFile(_curStack);
_runExitScript = false;
+
+ _cache.clear();
}
void MohawkEngine_Myst::changeToCard(uint16 card) {
@@ -316,6 +354,8 @@ void MohawkEngine_Myst::changeToCard(uint16 card) {
unloadCard();
+ _cache.clear();
+
_curCard = card;
// Load a bunch of stuff
@@ -550,6 +590,52 @@ void MohawkEngine_Myst::loadCard() {
_view.exit = viewStream->readUint16LE();
delete viewStream;
+
+ // Precache Card Resources
+ // TODO: Deal with Mac ME External Picture File
+ uint32 cacheImageType;
+ if (getFeatures() & GF_ME)
+ cacheImageType = ID_PICT;
+ else
+ cacheImageType = ID_WDIB;
+
+ // Precache Image Block data
+ if (_view.conditionalImageCount != 0) {
+ for (uint16 i = 0; i < _view.conditionalImageCount; i++)
+ for (uint16 j = 0; j < _view.conditionalImages[i].numStates; j++)
+ cachePreload(cacheImageType, _view.conditionalImages[i].values[j]);
+ } else
+ cachePreload(cacheImageType, _view.mainImage);
+
+ // Precache Sound Block data
+ if (_view.sound > 0)
+ cachePreload(ID_MSND, _view.sound);
+ else if (_view.sound == kMystSoundActionConditional) {
+ for (uint16 i = 0; i < _view.soundCount; i++) {
+ if (_view.soundList[i] > 0)
+ cachePreload(ID_MSND, _view.soundList[i]);
+ }
+ }
+
+ // Precache Script Resources
+ if (_view.scriptResCount != 0) {
+ for (uint16 i = 0; i < _view.scriptResCount; i++) {
+ switch (_view.scriptResources[i].type) {
+ case 1:
+ cachePreload(cacheImageType, _view.scriptResources[i].id);
+ break;
+ case 2:
+ cachePreload(ID_MSND, _view.scriptResources[i].id);
+ break;
+ case 3:
+ warning("TODO: Precaching of Script Resource List not supported");
+ break;
+ default:
+ warning("Unknown Resource in Script Resource List Precaching");
+ break;
+ }
+ }
+ }
}
void MohawkEngine_Myst::unloadCard() {
diff --git a/engines/mohawk/myst.h b/engines/mohawk/myst.h
index 60231260dd..7486e559bb 100644
--- a/engines/mohawk/myst.h
+++ b/engines/mohawk/myst.h
@@ -28,6 +28,7 @@
#include "mohawk/console.h"
#include "mohawk/mohawk.h"
+#include "mohawk/resource_cache.h"
#include "mohawk/myst_vars.h"
#include "gui/saveload.h"
@@ -52,7 +53,8 @@ enum {
kDebugINIT = (1 << 5),
kDebugEXIT = (1 << 6),
kDebugScript = (1 << 7),
- kDebugHelp = (1 << 8)
+ kDebugHelp = (1 << 8),
+ kDebugCache = (1 << 9)
};
// Myst Stacks
@@ -342,6 +344,8 @@ public:
MohawkEngine_Myst(OSystem *syst, const MohawkGameDescription *gamedesc);
virtual ~MohawkEngine_Myst();
+ Common::SeekableReadStream *getRawData(uint32 tag, uint16 id);
+
Common::String wrapMovieFilename(Common::String movieName, uint16 stack);
void reloadSaveList();
@@ -369,6 +373,9 @@ public:
bool _showResourceRects;
void setResourceEnabled(uint16 resourceId, bool enable);
+ void setCacheState(bool state) { _cache.enabled = state; }
+ bool getCacheState(void) { return _cache.enabled; }
+
GUI::Debugger *getDebugger() { return _console; }
bool canLoadGameStateCurrently() { return !(getFeatures() & GF_DEMO); }
@@ -381,6 +388,8 @@ private:
MystConsole *_console;
GUI::SaveLoadChooser *_loadDialog;
MystOptionsDialog *_optionsDialog;
+ ResourceCache _cache;
+ void cachePreload(uint32 tag, uint16 id);
uint16 _curStack;
uint16 _curCard;
@@ -406,7 +415,7 @@ private:
void checkCursorHints();
Common::Point _mousePos;
uint16 _currentCursor;
- uint16 _mainCursor; // Also defines the current page being held (white, blue, red, or none)
+ uint16 _mainCursor; // Also defines the current page being held (white, blue, red, or none)
};
} // End of namespace Mohawk
diff --git a/engines/mohawk/resource_cache.cpp b/engines/mohawk/resource_cache.cpp
new file mode 100644
index 0000000000..20838ec1bd
--- /dev/null
+++ b/engines/mohawk/resource_cache.cpp
@@ -0,0 +1,84 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/debug.h"
+#include "mohawk/myst.h"
+#include "mohawk/resource_cache.h"
+
+namespace Mohawk {
+
+ResourceCache::ResourceCache() {
+ enabled = true;
+}
+
+ResourceCache::~ResourceCache() {
+ clear();
+}
+
+void ResourceCache::clear() {
+ if (!enabled) return;
+
+ debugC(kDebugCache, "Clearing Cache...");
+
+ // TODO : Not sure if need to explicitly delete dataObject.data element ie.
+ // returned by readStream method here.
+ store.clear();
+}
+
+void ResourceCache::add(uint32 tag, uint16 id, Common::SeekableReadStream *data) {
+ if (!enabled) return;
+
+ debugC(kDebugCache, "Adding item %u - tag 0x%04X id %u", store.size(), tag, id);
+
+ dataObject current;
+ current.tag = tag;
+ current.id = id;
+ uint32 dataCurPos = data->pos();
+ current.data = data->readStream(data->size());
+ data->seek(dataCurPos, SEEK_SET);
+ store.push_back(current);
+}
+
+// Returns NULL if not found
+Common::SeekableReadStream *ResourceCache::search(uint32 tag, uint16 id) {
+ if (!enabled) return NULL;
+
+ debugC(kDebugCache, "Searching for tag 0x%04X id %u", tag, id);
+
+ for (uint32 i = 0; i < store.size(); i++) {
+ if (tag == store[i].tag && id == store[i].id) {
+ debugC(kDebugCache, "Found cached tag 0x%04X id %u", tag, id);
+ uint32 dataCurPos = store[i].data->pos();
+ Common::SeekableReadStream *ret = store[i].data->readStream(store[i].data->size());
+ store[i].data->seek(dataCurPos, SEEK_SET);
+ return ret;
+ }
+ }
+
+ debugC(kDebugCache, "tag 0x%04X id %u not found", tag, id);
+ return NULL;
+}
+
+} // End of namespace Mohawk
diff --git a/engines/mohawk/resource_cache.h b/engines/mohawk/resource_cache.h
new file mode 100644
index 0000000000..e82b43b89e
--- /dev/null
+++ b/engines/mohawk/resource_cache.h
@@ -0,0 +1,59 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef RESOURCE_CACHE_H
+#define RESOURCE_CACHE_H
+
+#include "common/array.h"
+#include "common/stream.h"
+
+namespace Mohawk {
+
+class ResourceCache {
+public:
+ ResourceCache();
+ ~ResourceCache();
+
+ bool enabled;
+
+ void clear();
+ void add(uint32 tag, uint16 id, Common::SeekableReadStream *data);
+
+ // Returns NULL if not found
+ Common::SeekableReadStream *search(uint32 tag, uint16 id);
+
+private:
+ typedef struct {
+ uint32 tag;
+ uint16 id;
+ Common::SeekableReadStream *data;
+ } dataObject;
+
+ Common::Array<dataObject> store;
+};
+
+} // End of namespace Mohawk
+
+#endif