diff options
author | David Turner | 2010-02-17 19:59:08 +0000 |
---|---|---|
committer | David Turner | 2010-02-17 19:59:08 +0000 |
commit | 2ab3e0fb3c74be9e94788eaab281c0bdbbb0c9a3 (patch) | |
tree | ae1a439efd74322a2938f8748eb572b57a01ff2f /engines | |
parent | c8470e1d8915134bca7836732c174c40d3b9cf97 (diff) | |
download | scummvm-rg350-2ab3e0fb3c74be9e94788eaab281c0bdbbb0c9a3.tar.gz scummvm-rg350-2ab3e0fb3c74be9e94788eaab281c0bdbbb0c9a3.tar.bz2 scummvm-rg350-2ab3e0fb3c74be9e94788eaab281c0bdbbb0c9a3.zip |
Mohawk : Adding resource cache class and integrating into Myst engine.
The resource caching trades increased memory usage against disk access.
This functionality can be disabled and enabled by the console "cache" command.
svn-id: r48080
Diffstat (limited to 'engines')
-rw-r--r-- | engines/mohawk/console.cpp | 22 | ||||
-rw-r--r-- | engines/mohawk/console.h | 1 | ||||
-rw-r--r-- | engines/mohawk/module.mk | 1 | ||||
-rw-r--r-- | engines/mohawk/mohawk.cpp | 2 | ||||
-rw-r--r-- | engines/mohawk/mohawk.h | 2 | ||||
-rw-r--r-- | engines/mohawk/myst.cpp | 86 | ||||
-rw-r--r-- | engines/mohawk/myst.h | 13 | ||||
-rw-r--r-- | engines/mohawk/resource_cache.cpp | 84 | ||||
-rw-r--r-- | engines/mohawk/resource_cache.h | 59 |
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 |