STARK: Implement anim scripts

This commit is contained in:
Bastien Bouclet 2015-01-02 10:33:42 +01:00
parent 1c2348d784
commit e416158ab8
6 changed files with 127 additions and 9 deletions

View file

@ -58,6 +58,10 @@ void Anim::readData(XRCReadStream *stream) {
_numFrames = stream->readUint32LE();
}
void Anim::selectFrame(uint32 frameIndex) {
//TODO
}
void Anim::reference(Item *item) {
_refCount++;
}

View file

@ -52,6 +52,8 @@ public:
// Resource API
void readData(XRCReadStream *stream) override;
void selectFrame(uint32 frameIndex);
// Refcounting, used to know if the anim script needs to run
virtual void reference(Item *item);
virtual void dereference(Item *item);

View file

@ -20,9 +20,13 @@
*
*/
#include "common/debug.h"
#include "engines/stark/resources/animscript.h"
#include "common/debug.h"
#include "common/random.h"
#include "engines/stark/resources/anim.h"
#include "engines/stark/stark.h"
#include "engines/stark/xrcreader.h"
namespace Stark {
@ -31,11 +35,81 @@ AnimScript::~AnimScript() {
}
AnimScript::AnimScript(Resource *parent, byte subType, uint16 index, const Common::String &name) :
Resource(parent, subType, index, name) {
Resource(parent, subType, index, name),
_anim(nullptr),
_msecsToNextUpdate(0),
_nextItemIndex(-1) {
_type = TYPE;
}
void AnimScript::printData() {
void AnimScript::onAllLoaded() {
Resource::onAllLoaded();
_anim = Resource::cast<Anim>(_parent);
_items = listChildren<AnimScriptItem>();
if (!_items.empty()) {
// Setup the next item to the first
_nextItemIndex = 0;
}
}
void AnimScript::onGameLoop(uint msecs) {
Resource::onGameLoop(msecs);
if (!_anim || !_anim->isReferenced() || _nextItemIndex == -1) {
// The script is disabled, do nothing
return;
}
Common::RandomSource *randomSource = StarkServices::instance().randomSource;
while (_msecsToNextUpdate <= (int32)msecs) {
AnimScriptItem *item = _items[_nextItemIndex];
_msecsToNextUpdate += item->getDuration();
switch (item->getOpcode()) {
case AnimScriptItem::kDisplayFrame:
_anim->selectFrame(item->getOperand());
goToNextItem();
break;
case AnimScriptItem::kPlayAnimSound:
// TODO
goToNextItem();
break;
case AnimScriptItem::kGoToItem:
_nextItemIndex = item->getOperand();
break;
case AnimScriptItem::kDisplayRandomFrame: {
uint32 startFrame = item->getOperand() >> 16;
uint32 endFrame = item->getOperand() & 0xFFFF;
uint32 frame = randomSource->getRandomNumberRng(startFrame, endFrame);
_anim->selectFrame(frame);
goToNextItem();
break;
}
case AnimScriptItem::kSleepRandomDuration: {
uint duration = randomSource->getRandomNumber(item->getOperand());
_msecsToNextUpdate += duration;
goToNextItem();
break;
}
case AnimScriptItem::kPlayStockSound:
// TODO
goToNextItem();
break;
default:
error("Unknown anim script type %d", item->getOpcode());
}
}
_msecsToNextUpdate -= msecs;
}
void AnimScript::goToNextItem() {
_nextItemIndex += 1;
_nextItemIndex %= _items.size();
}
AnimScriptItem::~AnimScriptItem() {

View file

@ -29,6 +29,8 @@
namespace Stark {
class Anim;
class AnimScriptItem;
class XRCReadStream;
class AnimScript : public Resource {
@ -38,25 +40,49 @@ public:
AnimScript(Resource *parent, byte subType, uint16 index, const Common::String &name);
virtual ~AnimScript();
// Resource API
void onAllLoaded() override;
void onGameLoop(uint msecs) override;
protected:
void printData() override;
void goToNextItem();
Anim *_anim;
Common::Array<AnimScriptItem *> _items;
int32 _nextItemIndex;
int32 _msecsToNextUpdate;
};
class AnimScriptItem : public Resource {
public:
static const ResourceType::Type TYPE = ResourceType::kAnimScriptItem;
enum Opcodes {
kDisplayFrame = 0,
kPlayAnimSound = 1,
kGoToItem = 2,
kDisplayRandomFrame = 3,
kSleepRandomDuration = 4,
kPlayStockSound = 5
};
AnimScriptItem(Resource *parent, byte subType, uint16 index, const Common::String &name);
virtual ~AnimScriptItem();
// Resource API
void readData(XRCReadStream *stream) override;
uint32 getOpcode() const { return _opcode; }
uint32 getOperand() const { return _operand; }
uint32 getDuration() const { return _duration; }
protected:
void printData() override;
uint32 _opcode;
uint32 _operand;
uint32 _duration;
protected:
void printData() override;
};
} // End of namespace Stark

View file

@ -33,6 +33,7 @@
#include "common/config-manager.h"
#include "common/events.h"
#include "common/random.h"
#include "common/savefile.h"
#include "common/system.h"
#include "audio/mixer.h"
@ -52,7 +53,8 @@ StarkEngine::StarkEngine(OSystem *syst, const ADGameDescription *gameDesc) :
_global(nullptr),
_archiveLoader(nullptr),
_stateProvider(nullptr),
_resourceProvider(nullptr) {
_resourceProvider(nullptr),
_randomSource(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"));
@ -66,6 +68,7 @@ StarkEngine::StarkEngine(OSystem *syst, const ADGameDescription *gameDesc) :
}
StarkEngine::~StarkEngine() {
delete _randomSource;
delete _scene;
delete _console;
delete _gfx;
@ -88,12 +91,14 @@ Common::Error StarkEngine::run() {
_stateProvider = new StateProvider();
_global = new Global();
_resourceProvider = new ResourceProvider(_archiveLoader, _stateProvider, _global);
_randomSource = new Common::RandomSource("stark");
// Setup the public services
StarkServices &services = StarkServices::instance();
services.archiveLoader = _archiveLoader;
services.resourceProvider = _resourceProvider;
services.global = _global;
services.randomSource = _randomSource;
// Load global resources
_resourceProvider->initGlobal();

View file

@ -26,6 +26,10 @@
#include "engines/advancedDetector.h"
#include "engines/engine.h"
namespace Common {
class RandomSource;
}
namespace Stark {
/*
@ -56,11 +60,13 @@ public:
global = nullptr;
archiveLoader = nullptr;
resourceProvider = nullptr;
randomSource = nullptr;
}
Global *global;
ArchiveLoader *archiveLoader;
ResourceProvider *resourceProvider;
Common::RandomSource *randomSource;
};
class StarkEngine : public Engine {
@ -89,6 +95,7 @@ private:
ArchiveLoader *_archiveLoader;
StateProvider *_stateProvider;
ResourceProvider *_resourceProvider;
Common::RandomSource *_randomSource;
const ADGameDescription *_gameDescription;