diff options
Diffstat (limited to 'engines/m4')
-rw-r--r-- | engines/m4/animation.cpp | 83 | ||||
-rw-r--r-- | engines/m4/animation.h | 12 | ||||
-rw-r--r-- | engines/m4/console.cpp | 3 | ||||
-rw-r--r-- | engines/m4/mads_logic.cpp | 4 | ||||
-rw-r--r-- | engines/m4/mads_logic.h | 2 | ||||
-rw-r--r-- | engines/m4/mads_scene.cpp | 31 | ||||
-rw-r--r-- | engines/m4/mads_scene.h | 4 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 30 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 16 |
9 files changed, 128 insertions, 57 deletions
diff --git a/engines/m4/animation.cpp b/engines/m4/animation.cpp index 58d829c4a2..43823c5ff1 100644 --- a/engines/m4/animation.cpp +++ b/engines/m4/animation.cpp @@ -33,19 +33,31 @@ namespace M4 { // TODO: this code needs cleanup MadsAnimation::MadsAnimation(MadsM4Engine *vm, MadsView *view): Animation(vm), _view(view) { - _playing = false; _font = NULL; - _unk1 = 0; + _freeFlag = false; _skipLoad = false; _unkIndex = -1; _messageCtr= 0; } MadsAnimation::~MadsAnimation() { + for (uint i = 0; i < _messages.size(); ++i) { + if (_messages[i].kernelMsgIndex >= 0) + _view->_kernelMessages.remove(_messages[i].kernelMsgIndex); + } + + // Further deletion logic + if (_field12) { + _view->_spriteSlots.deleteSprites(_spriteListIndexes[_spriteListIndex]); + } + delete _font; } -void MadsAnimation::load(const Common::String &filename, uint16 flags, M4Surface *interfaceSurface, M4Surface *sceneSurface) { +/** + * Initialises and loads the data of an animation + */ +void MadsAnimation::initialise(const Common::String &filename, uint16 flags, M4Surface *interfaceSurface, M4Surface *sceneSurface) { MadsPack anim(filename.c_str(), _vm); bool madsRes = filename[0] == '*'; char buffer[20]; @@ -74,7 +86,7 @@ void MadsAnimation::load(const Common::String &filename, uint16 flags, M4Surface animStream->skip(10); animStream->read(buffer, 13); - _infoFilename = Common::String(buffer, 13); + _interfaceFile = Common::String(buffer, 13); for (int i = 0; i < 10; ++i) { animStream->read(buffer, 13); @@ -160,7 +172,8 @@ void MadsAnimation::load(const Common::String &filename, uint16 flags, M4Surface for (int i = 0; i < miscEntriesCount; ++i) { AnimMiscEntry rec; - rec.soundNum = animStream->readUint16LE(); + rec.soundNum = animStream->readByte(); + animStream->skip(1); rec.numTicks = animStream->readUint16LE(); rec.posAdjust.x = animStream->readUint16LE(); rec.posAdjust.y = animStream->readUint16LE(); @@ -204,20 +217,37 @@ void MadsAnimation::load(const Common::String &filename, uint16 flags, M4Surface } -void MadsAnimation::start() { +/** + * Loads an animation file for display + */ +void MadsAnimation::load(const Common::String &filename, int abortTimers) { + initialise(filename, 0, NULL, NULL); + _messageCtr = 0; + _skipLoad = true; + + if (_field12) { + _unkIndex = -1; + int listIndex = _spriteListIndexes[_spriteListIndex]; + SpriteAsset &spriteSet = _view->_spriteSlots.getSprite(listIndex); +warning("%d", spriteSet.getCount()); + } + + // Initialise miscellaneous fields _currentFrame = 0; _oldFrameEntry = 0; - //for (int i = 0; i < _seriesCount; i++) { - //_spriteSeries[i] = new SpriteSeries((char*)_spriteSeriesNames[i].c_str()); - //} - _playing = true; - update(); -} + _nextFrameTimer = _madsVm->_currentTimer; + _abortTimers = abortTimers; + _abortMode = _madsVm->scene()->_abortTimersMode2; -bool MadsAnimation::update() { - if (!_playing) - return true; + for (int i = 0; i < 3; ++i) + _actionNouns[i] = _madsVm->scene()->actionNouns[i]; + // Initialise kernel message list + for (uint i = 0; i < _messages.size(); ++i) + _messages[i].kernelMsgIndex = -1; +} + +void MadsAnimation::update() { if (_field12) { int spriteListIndex = _spriteListIndexes[_spriteListIndex]; int newIndex = -1; @@ -235,7 +265,8 @@ bool MadsAnimation::update() { // If it's not time for the next frame, then exit if (_madsVm->_currentTimer < _nextFrameTimer) - return false; + return; +return;//*** TODO: This routine still needs to be properly tested // Loop checks for any prior animation sprite slots to be expired for (int slotIndex = 0; slotIndex < _view->_spriteSlots.startIndex; ++slotIndex) { @@ -253,8 +284,8 @@ bool MadsAnimation::update() { _currentFrame = 0; _oldFrameEntry = 0; } else { - _unk1 = true; - return true; + _freeFlag = true; + return; } } @@ -368,8 +399,6 @@ bool MadsAnimation::update() { _currentFrame++; if (_currentFrame >= (int)_miscEntries.size()) { // Animation is complete - stop(); - if (_abortTimers != 0) { _view->_abortTimers = _abortTimers; _view->_abortTimersMode = _abortMode; @@ -384,18 +413,12 @@ bool MadsAnimation::update() { int frameNum = MIN(_currentFrame, (int)_miscEntries.size() - 1); _nextFrameTimer = _madsVm->_currentTimer + _miscEntries[frameNum].numTicks; - - return _currentFrame >= (int)_miscEntries.size(); -} - -void MadsAnimation::stop() { - _playing = false; } void MadsAnimation::setCurrentFrame(int frameNumber) { _currentFrame = frameNumber; _oldFrameEntry = 0; - _unk1 = 0; + _freeFlag = false; } void MadsAnimation::load1(int frameNumber) { @@ -427,14 +450,14 @@ bool MadsAnimation::proc1(SpriteAsset &spriteSet, const Common::Point &pt, int f void MadsAnimation::loadInterface(M4Surface *&interfaceSurface, M4Surface *&depthSurface) { if (_animMode <= 2) { MadsSceneResources sceneResources; - sceneResources.load(_roomNumber, _infoFilename.c_str(), 0, depthSurface, interfaceSurface); + sceneResources.load(_roomNumber, _interfaceFile.c_str(), 0, depthSurface, interfaceSurface); // Rex only supports a single dialog draw style - assert(sceneResources.dialogStyle == 2); + assert(sceneResources.drawStyle == 2); } else if (_animMode == 4) { // Load a scene interface - interfaceSurface->madsLoadInterface(_infoFilename); + interfaceSurface->madsLoadInterface(_interfaceFile); } else { // This mode allocates two large surfaces for the animation // TODO: Are these ever properly freed? diff --git a/engines/m4/animation.h b/engines/m4/animation.h index 838e4b6175..59cb52cd87 100644 --- a/engines/m4/animation.h +++ b/engines/m4/animation.h @@ -67,7 +67,6 @@ enum MadsAnimationFlags {ANIM_CUSTOM_FONT = 0x20}; class MadsAnimation: public Animation { private: - bool _playing; MadsView *_view; int _spriteListCount; @@ -83,7 +82,7 @@ private: int _spriteListIndex; int _scrollX; int _scrollY; - Common::String _infoFilename; + Common::String _interfaceFile; Common::String _spriteSetNames[10]; Common::String _lbmFilename; Common::String _spritesFilename; @@ -92,7 +91,7 @@ private: int _currentFrame, _oldFrameEntry; bool _resetFlag; - int _unk1; + bool _freeFlag; bool _skipLoad; int _unkIndex; Common::Point _unkList[2]; @@ -109,10 +108,9 @@ public: MadsAnimation(MadsM4Engine *vm, MadsView *view); virtual ~MadsAnimation(); - virtual void load(const Common::String &filename, uint16 flags, M4Surface *interfaceSurface, M4Surface *sceneSurface); - virtual void start(); - virtual bool update(); - virtual void stop(); + virtual void initialise(const Common::String &filename, uint16 flags, M4Surface *interfaceSurface, M4Surface *sceneSurface); + virtual void load(const Common::String &filename, int abortTimers); + virtual void update(); virtual void setCurrentFrame(int frameNumber); }; diff --git a/engines/m4/console.cpp b/engines/m4/console.cpp index ccb1c8c182..4e14afdfaf 100644 --- a/engines/m4/console.cpp +++ b/engines/m4/console.cpp @@ -377,8 +377,7 @@ bool MadsConsole::cmdPlayAnimation(int argc, const char **argv) { if (argc == 3 && atoi(argv[2]) == 1) _madsVm->_palette->deleteAllRanges(); - _madsVm->scene()->_sceneAnimation->load(resourceName, 0, NULL, NULL); - _madsVm->scene()->_sceneAnimation->start(); + _madsVm->scene()->_sceneAnimation->load(resourceName, 0); view->restore(0, 0, view->width(), view->height()); return false; diff --git a/engines/m4/mads_logic.cpp b/engines/m4/mads_logic.cpp index 00ed146399..9cb053a876 100644 --- a/engines/m4/mads_logic.cpp +++ b/engines/m4/mads_logic.cpp @@ -146,6 +146,7 @@ void MadsSceneLogic::lowRoomsEntrySound() { } } + /*--------------------------------------------------------------------------*/ /** @@ -233,7 +234,8 @@ void MadsSceneLogic::enterScene() { _madsVm->globals()->loadQuoteSet(0x31, 0x32, 0x37, 0x38, 0x39, -1); if (_madsVm->globals()->_globals[10]) { - // TODO: Load scene animation + const char *animName = MADSResourceManager::getResourceName('S', 'e', EXTTYPE_AA, NULL, -1); + _madsVm->scene()->loadAnimation(animName, 0x47); _madsVm->scene()->getSceneResources().playerPos = Common::Point(68, 140); _madsVm->scene()->getSceneResources().playerDir = 4; diff --git a/engines/m4/mads_logic.h b/engines/m4/mads_logic.h index 774ed016a6..8c3f41d08b 100644 --- a/engines/m4/mads_logic.h +++ b/engines/m4/mads_logic.h @@ -29,6 +29,8 @@ #ifndef M4_MADS_LOGIC_H #define M4_MADS_LOGIC_H +#include "m4/mads_views.h" + namespace M4 { class MadsSceneLogic { diff --git a/engines/m4/mads_scene.cpp b/engines/m4/mads_scene.cpp index 1f88ad771d..69de12e4f6 100644 --- a/engines/m4/mads_scene.cpp +++ b/engines/m4/mads_scene.cpp @@ -37,6 +37,7 @@ #include "m4/mads_views.h" #include "m4/compression.h" #include "m4/staticres.h" +#include "m4/animation.h" namespace M4 { @@ -49,6 +50,7 @@ static const int SCROLLER_DELAY = 200; MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResources), MadsView(this) { _vm = vm; + _activeAnimation = NULL; MadsView::_bgSurface = Scene::_backgroundSurface; MadsView::_depthSurface = Scene::_walkSurface; @@ -58,6 +60,8 @@ MadsScene::MadsScene(MadsEngine *vm): _sceneResources(), Scene(vm, &_sceneResour } MadsScene::~MadsScene() { + delete _activeAnimation; + _activeAnimation = NULL; leaveScene(); _vm->_viewManager->deleteView(_interfaceSurface); } @@ -83,7 +87,7 @@ void MadsScene::loadScene2(const char *aaName) { if (_madsVm->globals()->_config.textWindowStill) flags |= 0x200; - _sceneAnimation->load(aaName, flags, _interfaceSurface, NULL); + _sceneAnimation->initialise(aaName, flags, _interfaceSurface, NULL); } /** @@ -166,6 +170,11 @@ void MadsScene::leaveScene() { delete _sceneResources.props; delete _walkSurface; + if (_activeAnimation) { + delete _activeAnimation; + _activeAnimation = NULL; + } + Scene::leaveScene(); } @@ -286,14 +295,15 @@ void MadsScene::update() { _vm->_font->setFont(FONT_MAIN_MADS); _vm->_font->current()->writeString(this, sStatusText, (width() - _vm->_font->current()->getWidth(sStatusText)) / 2, 142, 0); } - - //***DEBUG*** - _spriteSlots.getSprite(0).getFrame(1)->copyTo(this, 120, 90, 0); } void MadsScene::updateState() { _sceneLogic.sceneStep(); _sequenceList.tick(); + + if ((_activeAnimation) && !_abortTimers) + _activeAnimation->update(); + _kernelMessages.update(); } @@ -427,6 +437,15 @@ void MadsScene::showMADSV2TextBox(char *text, int x, int y, char *faceName) { boxSprites->getFrame(bottomRight)->copyTo(_backgroundSurface, curX, curY + 1); } +void MadsScene::loadAnimation(const Common::String &animName, int v0) { + if (_activeAnimation) + error("Multiple active animations are not allowed"); + + MadsAnimation *anim = new MadsAnimation(_vm, this); + anim->load(animName.c_str(), 0); + _activeAnimation = anim; +} + /*--------------------------------------------------------------------------*/ MadsAction::MadsAction() { @@ -628,7 +647,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su int resSceneId = stream->readUint16LE(); assert(resSceneId == sceneNumber); artFileNum = stream->readUint16LE(); - dialogStyle = stream->readUint16LE(); + drawStyle = stream->readUint16LE(); width = stream->readUint16LE(); height = stream->readUint16LE(); assert((width == 320) && (height == 156)); @@ -664,7 +683,7 @@ void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Su ssFlag = true; } int walkSize = gfxSize; - if (dialogStyle == 2) { + if (drawStyle == 2) { width >>= 2; walkSize = width * height; } diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h index e3e4c3c084..0269de75c8 100644 --- a/engines/m4/mads_scene.h +++ b/engines/m4/mads_scene.h @@ -39,7 +39,7 @@ class MadsSceneResources: public SceneResources { public: int sceneId; int artFileNum; - int dialogStyle; + int drawStyle; int width; int height; Common::Array<MadsObject> objects; @@ -93,6 +93,7 @@ private: MadsEngine *_vm; MadsSceneResources _sceneResources; MadsAction _action; + Animation *_activeAnimation; MadsSceneLogic _sceneLogic; SpriteAsset *_playerSprites; @@ -127,6 +128,7 @@ public: int loadSceneSpriteSet(const char *setName); void loadPlayerSprites(const char *prefix); void showMADSV2TextBox(char *text, int x, int y, char *faceName); + void loadAnimation(const Common::String &animName, int v0); MadsInterfaceView *getInterface() { return (MadsInterfaceView *)_interfaceSurface; } MadsSceneResources &getSceneResources() { return _sceneResources; } diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index 79ca2c51b7..c656db83f1 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -62,8 +62,15 @@ MadsSpriteSlots::MadsSpriteSlots(MadsView &owner): _owner(owner) { startIndex = 0; } +MadsSpriteSlots::~MadsSpriteSlots() { + for (uint i = 0; i < _sprites.size(); ++i) + delete _sprites[i]; +} + void MadsSpriteSlots::clear() { _owner._textDisplay.clear(); + for (uint i = 0; i < _sprites.size(); ++i) + delete _sprites[i]; _sprites.clear(); // Reset the sprite slots list back to a single entry for a full screen refresh @@ -86,12 +93,22 @@ int MadsSpriteSlots::addSprites(const char *resName) { spriteSet->translate(_madsVm->_palette); assert(spriteSet != NULL); - _sprites.push_back(SpriteList::value_type(spriteSet)); + _sprites.push_back(spriteSet); _vm->res()->toss(resName); return _sprites.size() - 1; } +void MadsSpriteSlots::deleteSprites(int listIndex) { + if (listIndex < 0) + return; + + delete _sprites[listIndex]; + _sprites[listIndex] = NULL; + if (listIndex == ((int)_sprites.size() - 1)) + _sprites.remove_at(listIndex); +} + /* * Deletes the sprite slot with the given timer entry */ @@ -173,7 +190,7 @@ void MadsSpriteSlots::drawForeground(View *view) { DepthEntry &de = *i; MadsSpriteSlot &slot = _entries[de.index]; assert(slot.spriteListIndex < (int)_sprites.size()); - SpriteAsset &spriteSet = *_sprites[slot.spriteListIndex].get(); + SpriteAsset &spriteSet = *_sprites[slot.spriteListIndex]; if (slot.scale < 100) { // Minimalised drawing @@ -1134,6 +1151,15 @@ void MadsSequenceList::setAnimRange(int seqIndex, int startVal, int endVal) { seqEntry.frameIndex = (seqEntry.frameInc < 0) ? tempStart : tempEnd; } +void MadsSequenceList::scan() { + for (uint i = 0; i < _entries.size(); ++i) { + if (!_entries[i].active && (_entries[i].spriteListIndex != -1)) { + int idx = _owner._spriteSlots.getIndex(); + setSpriteSlot(i, _owner._spriteSlots[idx]); + } + } +} + //-------------------------------------------------------------------------- Animation::Animation(MadsM4Engine *vm): _vm(vm) { diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 31b8cd891f..98944e6468 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -72,17 +72,16 @@ enum SpriteIdSpecial { SPRITE_FOUR = 4 }; -typedef Common::Array<Common::SharedPtr<SpriteAsset> > SpriteList; - class MadsSpriteSlots { private: MadsView &_owner; Common::Array<MadsSpriteSlot> _entries; - SpriteList _sprites; + Common::Array<SpriteAsset *> _sprites; public: int startIndex; MadsSpriteSlots(MadsView &owner); + ~MadsSpriteSlots(); MadsSpriteSlot &operator[](int idx) { assert(idx < SPRITE_SLOTS_SIZE); @@ -90,11 +89,12 @@ public: } SpriteAsset &getSprite(int idx) { assert(idx < (int)_sprites.size()); - return *_sprites[idx].get(); + return *_sprites[idx]; } int getIndex(); int addSprites(const char *resName); + void deleteSprites(int listIndex); void clear(); void deleteTimer(int seqIndex); @@ -359,6 +359,7 @@ public: void tick(); void delay(uint32 v1, uint32 v2); void setAnimRange(int seqIndex, int startVal, int endVal); + void scan(); }; class Animation { @@ -367,10 +368,9 @@ protected: public: Animation(MadsM4Engine *vm); virtual ~Animation(); - virtual void load(const Common::String &filename, uint16 flags, M4Surface *walkSurface, M4Surface *sceneSurface) = 0; - virtual void start() = 0; - virtual bool update() = 0; - virtual void stop() = 0; + virtual void initialise(const Common::String &filename, uint16 flags, M4Surface *walkSurface, M4Surface *sceneSurface) = 0; + virtual void load(const Common::String &filename, int v0) = 0; + virtual void update() = 0; virtual void setCurrentFrame(int frameNumber) = 0; }; |