STARK: Add a skeleton resource provider

This commit is contained in:
Bastien Bouclet 2014-12-27 19:48:17 +01:00
parent 1022c161d4
commit f22b11560e
10 changed files with 276 additions and 22 deletions

View File

@ -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];
}
}

View File

@ -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<LoadedArchive> _archives;
Common::Array<LoadedArchive *> _archives;
};
} // End of namespace Stark

View File

@ -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());

View File

@ -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 \

View File

@ -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<Root *>(_archiveLoader->getRoot("x.xarc"));
_global->setRoot(root);
// Find the global level node
Level *global = static_cast<Level *>(root->findChild(ResourceType::kLevel, 1));
// Load the global archive
Common::String globalArchiveName = global->getArchive();
_archiveLoader->load(globalArchiveName);
// Set the global tree
global = static_cast<Level *>(_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

View File

@ -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

View File

@ -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),

View File

@ -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<Resource *> 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:

View File

@ -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;
}

View File

@ -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;