mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-21 03:31:40 +00:00
Added code and support routines for destroying animations correctly, which also necessitated changing the sprite list code
svn-id: r49426
This commit is contained in:
parent
997fdac427
commit
86462c66a0
@ -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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool MadsAnimation::update() {
|
||||
if (!_playing)
|
||||
return true;
|
||||
|
||||
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?
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -29,6 +29,8 @@
|
||||
#ifndef M4_MADS_LOGIC_H
|
||||
#define M4_MADS_LOGIC_H
|
||||
|
||||
#include "m4/mads_views.h"
|
||||
|
||||
namespace M4 {
|
||||
|
||||
class MadsSceneLogic {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user