aboutsummaryrefslogtreecommitdiff
path: root/engines/m4
diff options
context:
space:
mode:
authorPaul Gilbert2010-06-04 11:28:30 +0000
committerPaul Gilbert2010-06-04 11:28:30 +0000
commit86462c66a04fd208716f072d4ba0028a04bf9ad8 (patch)
tree73c6b9f090ab91a49e22b6a294afcf2adc34b8d1 /engines/m4
parent997fdac4271aac6a345bbdd0782d55d48ed0b400 (diff)
downloadscummvm-rg350-86462c66a04fd208716f072d4ba0028a04bf9ad8.tar.gz
scummvm-rg350-86462c66a04fd208716f072d4ba0028a04bf9ad8.tar.bz2
scummvm-rg350-86462c66a04fd208716f072d4ba0028a04bf9ad8.zip
Added code and support routines for destroying animations correctly, which also necessitated changing the sprite list code
svn-id: r49426
Diffstat (limited to 'engines/m4')
-rw-r--r--engines/m4/animation.cpp83
-rw-r--r--engines/m4/animation.h12
-rw-r--r--engines/m4/console.cpp3
-rw-r--r--engines/m4/mads_logic.cpp4
-rw-r--r--engines/m4/mads_logic.h2
-rw-r--r--engines/m4/mads_scene.cpp31
-rw-r--r--engines/m4/mads_scene.h4
-rw-r--r--engines/m4/mads_views.cpp30
-rw-r--r--engines/m4/mads_views.h16
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;
};