diff --git a/engines/stark/archiveloader.cpp b/engines/stark/archiveloader.cpp index 09d780b2f7c..281fab53317 100644 --- a/engines/stark/archiveloader.cpp +++ b/engines/stark/archiveloader.cpp @@ -61,17 +61,25 @@ Resource *ArchiveLoader::LoadedArchive::importResources() { return root; } +ArchiveLoader::~ArchiveLoader() { + for (uint i = 0; i < _archives.size(); i++) { + delete _archives[i]; + } +} + void ArchiveLoader::load(const Common::String &archiveName) { if (hasArchive(archiveName)) { // Already loaded return; } - _archives.push_back(LoadedArchive(archiveName)); + + LoadedArchive *archive = new LoadedArchive(archiveName); + _archives.push_back(archive); } void ArchiveLoader::unload(const Common::String &archiveName) { for (uint i = 0; i < _archives.size(); i++) { - if (_archives[i].getFilename() == archiveName) { + if (_archives[i]->getFilename() == archiveName) { _archives.remove_at(i); return; } @@ -81,19 +89,19 @@ void ArchiveLoader::unload(const Common::String &archiveName) { } Common::ReadStream *ArchiveLoader::getFile(const Common::String &fileName, const Common::String &archiveName) { - LoadedArchive &archive = findArchive(archiveName); - XARCArchive &xarc = archive.getXArc(); + LoadedArchive *archive = findArchive(archiveName); + XARCArchive &xarc = archive->getXArc(); return xarc.createReadStreamForMember(fileName); } Resource *ArchiveLoader::getRoot(const Common::String &archiveName) { - LoadedArchive &archive = findArchive(archiveName); - return archive.getRoot(); + LoadedArchive *archive = findArchive(archiveName); + return archive->getRoot(); } bool ArchiveLoader::hasArchive(const Common::String &archiveName) { for (uint i = 0; i < _archives.size(); i++) { - if (_archives[i].getFilename() == archiveName) { + if (_archives[i]->getFilename() == archiveName) { return true; } } @@ -101,9 +109,9 @@ bool ArchiveLoader::hasArchive(const Common::String &archiveName) { return false; } -ArchiveLoader::LoadedArchive &ArchiveLoader::findArchive(const Common::String &archiveName) { +ArchiveLoader::LoadedArchive *ArchiveLoader::findArchive(const Common::String &archiveName) { for (uint i = 0; i < _archives.size(); i++) { - if (_archives[i].getFilename() == archiveName) { + if (_archives[i]->getFilename() == archiveName) { return _archives[i]; } } diff --git a/engines/stark/archiveloader.h b/engines/stark/archiveloader.h index 2bf31aabb3b..b1515fdd948 100644 --- a/engines/stark/archiveloader.h +++ b/engines/stark/archiveloader.h @@ -41,6 +41,8 @@ class Resource; class ArchiveLoader { public: + ~ArchiveLoader(); + /** Load a Xarc archive, and add it to the managed archives list */ void load(const Common::String &archiveName); @@ -72,9 +74,9 @@ private: }; bool hasArchive(const Common::String &archiveName); - LoadedArchive &findArchive(const Common::String &archiveName); + LoadedArchive *findArchive(const Common::String &archiveName); - Common::Array _archives; + Common::Array _archives; }; } // End of namespace Stark diff --git a/engines/stark/console.cpp b/engines/stark/console.cpp index 67e5badbd4a..a810e7a909d 100644 --- a/engines/stark/console.cpp +++ b/engines/stark/console.cpp @@ -141,7 +141,7 @@ bool Console::Cmd_ListRooms(int argc, const char **argv) { Resource *level = root->getChildren()[i]; // Only consider levels - if (!level->getType().is(ResourceType::kLevel)) continue; + if (level->getType() != ResourceType::kLevel) continue; Common::String levelArchive = level->getArchive(); debugPrintf("%s - %s\n", levelArchive.c_str(), level->getName().c_str()); @@ -157,7 +157,7 @@ bool Console::Cmd_ListRooms(int argc, const char **argv) { Resource *room = level->getChildren()[j]; // Only consider rooms - if (!room->getType().is(ResourceType::kLocation)) continue; + if (room->getType() != ResourceType::kLocation) continue; Common::String roomArchive = room->getArchive(); debugPrintf("%s - %s\n", roomArchive.c_str(), room->getName().c_str()); diff --git a/engines/stark/module.mk b/engines/stark/module.mk index ba9a7941b89..72991e6c7fb 100644 --- a/engines/stark/module.mk +++ b/engines/stark/module.mk @@ -18,7 +18,8 @@ MODULE_OBJS := \ resources/level.o \ resources/location.o \ resources/resource.o \ - resources/root.o \ + resources/root.o \ + resourceprovider.o \ resourcereference.o \ scene.o \ skeleton.o \ diff --git a/engines/stark/resourceprovider.cpp b/engines/stark/resourceprovider.cpp new file mode 100644 index 00000000000..5e9dc4fd6c1 --- /dev/null +++ b/engines/stark/resourceprovider.cpp @@ -0,0 +1,66 @@ +/* ResidualVM - A 3D game interpreter + * + * ResidualVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the AUTHORS + * 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. + * + */ + +#include "engines/stark/resourceprovider.h" + +#include "engines/stark/archiveloader.h" +#include "engines/stark/resources/root.h" +#include "engines/stark/resources/level.h" + +namespace Stark { + +ResourceProvider::ResourceProvider(ArchiveLoader *archiveLoader, Global *global) : + _archiveLoader(archiveLoader), + _global(global) { +} + + +void ResourceProvider::initGlobal() { + // Load the root archive + _archiveLoader->load("x.xarc"); + + // Set the root tree + Root *root = static_cast(_archiveLoader->getRoot("x.xarc")); + _global->setRoot(root); + + // Find the global level node + Level *global = static_cast(root->findChild(ResourceType::kLevel, 1)); + + // Load the global archive + Common::String globalArchiveName = global->getArchive(); + _archiveLoader->load(globalArchiveName); + + // Set the global tree + global = static_cast(_archiveLoader->getRoot(globalArchiveName)); + _global->setLevel(global); + + //TODO: Retrieve the inventory and April from the global tree +} + +void ResourceProvider::shutdown() { + _archiveLoader->unload(_global->getLevel()->getArchive()); + _global->setLevel(nullptr); + _archiveLoader->unload("x.xarc"); + _global->setRoot(nullptr); +} + +} // End of namespace Stark diff --git a/engines/stark/resourceprovider.h b/engines/stark/resourceprovider.h new file mode 100644 index 00000000000..34268980eab --- /dev/null +++ b/engines/stark/resourceprovider.h @@ -0,0 +1,118 @@ +/* ResidualVM - A 3D game interpreter + * + * ResidualVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the AUTHORS + * 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. + * + */ + +#ifndef STARK_RESOURCE_PROVIDER_H +#define STARK_RESOURCE_PROVIDER_H + +#include "common/array.h" + +namespace Stark { + +class Resource; +class Root; +class Level; +class Location; + +class ArchiveLoader; + +/** + * Current level / location holder object + */ +class Current { +public: + Current() : + _level(nullptr), + _location(nullptr) { + } + + Level *getLevel() const { return _level; } + Location *getLocation() const { return _location; } + + void setLevel(Level *level) { _level = level; } + void setLocation(Location *location) { _location = location; } + +private: + Level *_level; + Location *_location; + /* Item *_interactive; */ +}; + +/** + * Global resources holder object + */ +class Global { +public: + Global() : + _millisecondsPerGameloop(0), + _root(nullptr), + _level(nullptr), + _current(nullptr), + _debug(false), + _fastForward(false) { + } + + Root *getRoot() const { return _root; } + Level *getLevel() const { return _level; } + Current *getCurrent() const { return _current; } + bool isDebug() const { return _debug; } + bool isFastForward() const { return _fastForward; } + uint getMillisecondsPerGameloop() const { return _millisecondsPerGameloop; } + + void setRoot(Root *root) { _root = root; } + void setLevel(Level *level) { _level = level; } + void setCurrent(Current *current) { _current = current; } + void setDebug(bool debug) { _debug = debug; } + void setFastForward(bool fastForward) { _fastForward = fastForward; } + void setMillisecondsPerGameloop(uint millisecondsPerGameloop) { _millisecondsPerGameloop = millisecondsPerGameloop; } + +private: + uint _millisecondsPerGameloop; + Root *_root; + Level *_level; + /* Inventory *_inventory; */ + /* ItemVis3D *_april; */ + Current *_current; + bool _debug; + bool _fastForward; +}; + +/** + * Game Resource provider. + * + * Maintains a list of resource trees. + * Maintained trees are the global and the current ones. + */ +class ResourceProvider { +public: + ResourceProvider(ArchiveLoader *archiveLoader, Global *global); + + void initGlobal(); + void shutdown(); + +private: + Global *_global; + ArchiveLoader *_archiveLoader; +}; + +} // End of namespace Stark + +#endif // STARK_RESOURCE_PROVIDER_H diff --git a/engines/stark/resources/resource.cpp b/engines/stark/resources/resource.cpp index 4e5e74a2e73..31cc85c9d95 100644 --- a/engines/stark/resources/resource.cpp +++ b/engines/stark/resources/resource.cpp @@ -93,10 +93,6 @@ ResourceType::Type ResourceType::get() { return _type; } -bool ResourceType::is(ResourceType::Type type) { - return _type == type; -} - Resource::Resource(Resource *parent, byte subType, uint16 index, const Common::String &name) : _parent(parent), _type(ResourceType::kInvalid), @@ -171,6 +167,24 @@ Common::String Resource::getArchive() { return archive; } +Resource *Resource::findChild(ResourceType type, int subType, bool mustBeUnique) { + Resource *child = nullptr; + + for (uint i = 0; i < _children.size(); i++) { + if (_children[i]->getType() == type + && (_children[i]->getSubType() == subType || subType == -1)) { + // Found a matching child + if (!child) { + child = _children[i]; + } else if (mustBeUnique) { + error("Several children resources matching criteria type = %s, subtype = %d", type.getName(), subType); + } + } + } + + return child; +} + UnimplementedResource::UnimplementedResource(Resource *parent, ResourceType type, byte subType, uint16 index, const Common::String &name) : Resource(parent, subType, index, name), _dataLength(0), diff --git a/engines/stark/resources/resource.h b/engines/stark/resources/resource.h index b8d58dff257..43a834ad4b2 100644 --- a/engines/stark/resources/resource.h +++ b/engines/stark/resources/resource.h @@ -75,7 +75,22 @@ public: Type get(); const char *getName(); - bool is(Type type); + + bool operator==(const ResourceType &other) const { + return other._type == _type; + } + + bool operator!=(const ResourceType &other) const { + return other._type != _type; + } + + bool operator==(const ResourceType::Type other) const { + return other == _type; + } + + bool operator!=(const ResourceType::Type other) const { + return other != _type; + } private: Type _type; @@ -86,6 +101,7 @@ public: virtual ~Resource(); ResourceType getType() const { return _type; } + byte getSubType() const { return _subType; } Common::String getName() const { return _name; } Common::Array getChildren() const { return _children; } @@ -96,10 +112,12 @@ public: /** * Get the archive file name containing the data for this resource. - * Only Levels and Rooms have archives. + * Only Levels and Locations have archives. */ Common::String getArchive(); + Resource *findChild(ResourceType type, int subType, bool mustBeUnique = true); + void print(uint depth = 0); protected: diff --git a/engines/stark/stark.cpp b/engines/stark/stark.cpp index b473a5e4b5b..cfe5ef8157c 100644 --- a/engines/stark/stark.cpp +++ b/engines/stark/stark.cpp @@ -21,8 +21,10 @@ */ #include "engines/stark/stark.h" +#include "engines/stark/archiveloader.h" #include "engines/stark/console.h" #include "engines/stark/debug.h" +#include "engines/stark/resourceprovider.h" #include "engines/stark/scene.h" #include "engines/stark/gfx/driver.h" @@ -34,8 +36,14 @@ namespace Stark { StarkEngine::StarkEngine(OSystem *syst, const ADGameDescription *gameDesc) : - Engine(syst), _gameDescription(gameDesc), _gfx(NULL), _scene(NULL), - _console(NULL) { + Engine(syst), + _gameDescription(gameDesc), + _gfx(nullptr), + _scene(nullptr), + _console(nullptr), + _global(nullptr), + _archiveLoader(nullptr), + _resourceProvider(nullptr) { _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, 127); _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume")); @@ -51,6 +59,10 @@ StarkEngine::StarkEngine(OSystem *syst, const ADGameDescription *gameDesc) : StarkEngine::~StarkEngine() { delete _scene; delete _console; + delete _gfx; + delete _resourceProvider; + delete _global; + delete _archiveLoader; } Common::Error StarkEngine::run() { @@ -60,9 +72,17 @@ Common::Error StarkEngine::run() { // Get the screen prepared _gfx->setupScreen(640, 480, ConfMan.getBool("fullscreen")); + _archiveLoader = new ArchiveLoader(); + _global = new Global(); + _resourceProvider = new ResourceProvider(_archiveLoader, _global); + + _resourceProvider->initGlobal(); + // Start running mainLoop(); + _resourceProvider->shutdown(); + return Common::kNoError; } diff --git a/engines/stark/stark.h b/engines/stark/stark.h index 63d3dbd0f37..edb34f5bcf9 100644 --- a/engines/stark/stark.h +++ b/engines/stark/stark.h @@ -42,6 +42,9 @@ enum StarkGameFeatures { class Console; class GfxDriver; class Scene; +class Global; +class ArchiveLoader; +class ResourceProvider; class StarkEngine : public Engine { public: @@ -60,6 +63,10 @@ private: GfxDriver *_gfx; Console *_console; + Global *_global; + ArchiveLoader *_archiveLoader; + ResourceProvider *_resourceProvider; + const ADGameDescription *_gameDescription; Scene *_scene;