aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/access/animation.cpp129
-rw-r--r--engines/access/animation.h53
-rw-r--r--engines/access/room.cpp8
-rw-r--r--engines/access/scripts.cpp91
-rw-r--r--engines/access/scripts.h2
5 files changed, 219 insertions, 64 deletions
diff --git a/engines/access/animation.cpp b/engines/access/animation.cpp
index 4d73801e5d..0d8589d4f1 100644
--- a/engines/access/animation.cpp
+++ b/engines/access/animation.cpp
@@ -21,24 +21,123 @@
*/
#include "common/endian.h"
+#include "common/memstream.h"
#include "access/animation.h"
namespace Access {
+AnimationResource::AnimationResource(const byte *data, int size) {
+ Common::MemoryReadStream stream(data, size);
+ int count = stream.readUint16LE();
+
+ Common::Array<int> offsets;
+ for (int i = 0; i < count; ++i)
+ offsets.push_back(stream.readUint32LE());
+
+ _animations.reserve(count);
+ for (int i = 0; i < count; ++i) {
+ stream.seek(offsets[i]);
+ Animation *anim = new Animation(stream);
+ _animations.push_back(anim);
+ }
+}
+
+AnimationResource::~AnimationResource() {
+ for (int i = 0; i < (int)_animations.size(); ++i)
+ delete _animations[i];
+}
+
+/*------------------------------------------------------------------------*/
+
+Animation::Animation(Common::MemoryReadStream &stream) {
+ uint32 startOfs = stream.pos();
+
+ _type = stream.readByte();
+ _scaling = stream.readByte();
+ stream.readByte(); // unk
+ _frameNumber = stream.readByte();
+ _initialTicks = stream.readUint16LE();
+ stream.readUint16LE(); // unk
+ stream.readUint16LE(); // unk
+ _loopCount = stream.readUint16LE();
+ _countdownTicks = stream.readUint16LE();
+ _currentLoopCount = stream.readUint16LE();
+ stream.readUint16LE(); // unk
+
+ Common::Array<uint16> frameOffsets;
+ uint16 ofs;
+ while ((ofs = stream.readUint16LE()) != 0)
+ frameOffsets.push_back(ofs);
+
+ for (int i = 0; i < (int)frameOffsets.size(); i++) {
+ stream.seek(startOfs + frameOffsets[i]);
+
+ AnimationFrame *frame = new AnimationFrame(stream, startOfs);
+ _frames.push_back(frame);
+ }
+}
+
+Animation::~Animation() {
+ for (int i = 0; i < (int)_frames.size(); ++i)
+ delete _frames[i];
+}
+
+void Animation::animate() {
+ error("TODO");
+}
+
+/*------------------------------------------------------------------------*/
+
+AnimationFrame::AnimationFrame(Common::MemoryReadStream &stream, int startOffset) {
+ uint16 nextOffset;
+
+ stream.readByte(); // unk
+ _baseX = stream.readUint16LE();
+ _baseY = stream.readUint16LE();
+ _frameDelay = stream.readUint16LE();
+ nextOffset = stream.readUint16LE();
+
+ while (nextOffset != 0) {
+ stream.seek(startOffset + nextOffset);
+
+ AnimationFramePart *framePart = new AnimationFramePart(stream);
+ _parts.push_back(framePart);
+
+ nextOffset = stream.readUint16LE();
+ }
+}
+
+AnimationFrame::~AnimationFrame() {
+ for (int i = 0; i < (int)_parts.size(); ++i)
+ delete _parts[i];
+}
+
+/*------------------------------------------------------------------------*/
+
+AnimationFramePart::AnimationFramePart(Common::MemoryReadStream &stream) {
+ _flags = stream.readByte();
+ _slotIndex = stream.readByte();
+ _spriteIndex = stream.readByte();
+ _position.x = stream.readUint16LE();
+ _position.y = stream.readUint16LE();
+ _priority = stream.readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
AnimationManager::AnimationManager(AccessEngine *vm) : Manager(vm) {
- _anim = nullptr;
_animation = nullptr;
+ _animStart = nullptr;
}
AnimationManager::~AnimationManager() {
- delete[] _anim;
delete _animation;
}
void AnimationManager::freeAnimationData() {
- delete[] _anim;
- _anim = nullptr;
+ delete _animation;
_animation = nullptr;
+ _animStart = nullptr;
}
void AnimationManager::clearTimers() {
@@ -48,10 +147,17 @@ void AnimationManager::clearTimers() {
_animationTimers.clear();
}
+void AnimationManager::loadAnimations(const byte *data, int size) {
+ _animationTimers.clear();
+ delete _animation;
+ _animation = new AnimationResource(data, size);
+}
+
+
Animation *AnimationManager::setAnimation(int animId) {
Animation *anim = findAnimation(animId);
- anim->_countdownTicks = anim->_ticks;
+ anim->_countdownTicks = anim->_initialTicks;
anim->_frameNumber = 0;
anim->_currentLoopCount = (anim->_type != 3 && anim->_type != 4) ? 0 :
@@ -62,18 +168,17 @@ Animation *AnimationManager::setAnimation(int animId) {
}
void AnimationManager::setAnimTimer(Animation *anim) {
-
+ _animationTimers.push_back(anim);
}
Animation *AnimationManager::findAnimation(int animId) {
- _animation = new Animation(_anim + READ_LE_UINT16(_anim + animId * 4 + 2));
- return _animation;
+ _animStart = _animation->getAnimation(animId);
+ return _animStart;
}
-/*------------------------------------------------------------------------*/
-
-Animation::Animation(const byte *data) {
-
+void AnimationManager::animate(int animId) {
+ Animation *anim = findAnimation(animId);
+ anim->animate();
}
} // End of namespace Access
diff --git a/engines/access/animation.h b/engines/access/animation.h
index 879d1e9318..45a59efb68 100644
--- a/engines/access/animation.h
+++ b/engines/access/animation.h
@@ -25,41 +25,86 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "common/memstream.h"
#include "access/data.h"
namespace Access {
+class AnimationResource;
class Animation;
+class AnimationFrame;
+class AnimationFramePart;
class AnimationManager : public Manager {
public:
- const byte *_anim;
- Animation *_animation;
Common::Array<Animation *> _animationTimers;
+ AnimationResource *_animation;
+ Animation *_animStart;
public:
AnimationManager(AccessEngine *vm);
~AnimationManager();
void freeAnimationData();
+ void loadAnimations(const byte *data, int size);
+
void clearTimers();
Animation *findAnimation(int animId);
Animation *setAnimation(int animId);
void setAnimTimer(Animation *anim);
+
+ void animate(int animId);
+};
+
+class AnimationResource {
+private:
+ Common::Array<Animation *> _animations;
+public:
+ AnimationResource(const byte *data, int size);
+ ~AnimationResource();
+
+ int getCount() { return _animations.size(); }
+ Animation *getAnimation(int idx) { return _animations[idx]; }
};
class Animation {
+private:
+ Common::Array<AnimationFrame *> _frames;
public:
int _type;
int _scaling;
int _frameNumber;
- int _ticks;
+ int _initialTicks;
int _loopCount;
int _countdownTicks;
int _currentLoopCount;
int _field10;
public:
- Animation(const byte *data);
+ Animation(Common::MemoryReadStream &stream);
+ ~Animation();
+
+ void animate();
+};
+
+class AnimationFrame {
+public:
+ int _baseX, _baseY;
+ int _frameDelay;
+ Common::Array<AnimationFramePart *> _parts;
+public:
+ AnimationFrame(Common::MemoryReadStream &stream, int startOffset);
+ ~AnimationFrame();
+};
+
+class AnimationFramePart {
+public:
+ byte _flags;
+ int _slotIndex;
+ int _spriteIndex;
+ Common::Point _position;
+ int _priority;
+public:
+ AnimationFramePart(Common::MemoryReadStream &stream);
};
} // End of namespace Access
diff --git a/engines/access/room.cpp b/engines/access/room.cpp
index 371b714467..98e9d5ed6f 100644
--- a/engines/access/room.cpp
+++ b/engines/access/room.cpp
@@ -207,9 +207,11 @@ void Room::loadRoomData(const byte *roomData) {
// Load animation data
_vm->_animation->freeAnimationData();
- if (roomInfo._animFile._fileNum != -1)
- _vm->_animation->_anim = _vm->_files->loadFile(roomInfo._animFile._fileNum,
- roomInfo._animFile._subfile);
+ if (roomInfo._animFile._fileNum != -1) {
+ byte *data = _vm->_files->loadFile(roomInfo._animFile._fileNum,
+ roomInfo._animFile._subfile);
+ _vm->_animation->loadAnimations(data, _vm->_files->_filesize);
+ }
_vm->_scaleI = roomInfo._scaleI;
_vm->_screen->_scrollThreshold = roomInfo._scrollThreshold;
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index a6ecfa3eff..fd42530eb9 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -85,7 +85,7 @@ void Scripts::executeCommand(int commandIndex) {
&Scripts::CMDOBJECT, &Scripts::CMDENDOBJECT, &Scripts::cmdJumpLook,
&Scripts::cmdJumpHelp, &Scripts::cmdJumpGet, &Scripts::cmdJumpMove,
&Scripts::cmdJumpUse, &Scripts::cmdJumpTalk, &Scripts::cmdNull,
- &Scripts::CMDPRINT, &Scripts::cmdRetPos, &Scripts::CMDANIM,
+ &Scripts::CMDPRINT, &Scripts::cmdRetPos, &Scripts::cmdAnim,
&Scripts::cmdSetFlag, &Scripts::cmdCheckFlag, &Scripts::cmdGoto,
&Scripts::cmdSetInventory, &Scripts::cmdSetInventory, &Scripts::cmdCheckInventory,
&Scripts::CMDSETTEX, &Scripts::CMDNEWROOM, &Scripts::CMDCONVERSE,
@@ -114,9 +114,9 @@ void Scripts::executeCommand(int commandIndex) {
(this->*COMMAND_LIST[commandIndex])();
}
-void Scripts::CMDOBJECT() { }
+void Scripts::CMDOBJECT() { error("TODO"); }
-void Scripts::CMDENDOBJECT() { }
+void Scripts::CMDENDOBJECT() { error("TODO"); }
void Scripts::cmdJumpLook() {
if (_vm->_selectCommand == 0)
@@ -163,14 +163,17 @@ void Scripts::cmdJumpTalk() {
void Scripts::cmdNull() {
}
-void Scripts::CMDPRINT() { }
+void Scripts::CMDPRINT() { error("TODO"); }
void Scripts::cmdRetPos() {
_endFlag = true;
_returnCode = 0;
}
-void Scripts::CMDANIM() { }
+void Scripts::cmdAnim() {
+ int animId = _data->readUint16LE();
+ _vm->_animation->animate(animId);
+}
void Scripts::cmdSetFlag() {
int flagNum = _data->readByte();
@@ -216,10 +219,10 @@ void Scripts::cmdCheckInventory() {
_data->skip(2);
}
-void Scripts::CMDSETTEX() { }
-void Scripts::CMDNEWROOM() { }
-void Scripts::CMDCONVERSE() { }
-void Scripts::CMDCHECKFRAME() { }
+void Scripts::CMDSETTEX() { error("TODO"); }
+void Scripts::CMDNEWROOM() { error("TODO"); }
+void Scripts::CMDCONVERSE() { error("TODO"); }
+void Scripts::CMDCHECKFRAME() { error("TODO"); }
void Scripts::cmdCheckAnim() {
int id = _data->readUint16LE();
@@ -232,7 +235,7 @@ void Scripts::cmdCheckAnim() {
_data->skip(4);
}
-void Scripts::CMDSND() { }
+void Scripts::CMDSND() { error("TODO"); }
void Scripts::cmdRetNeg() {
_endFlag = true;
@@ -260,9 +263,9 @@ void Scripts::cmdSetAnim() {
_vm->_animation->setAnimTimer(anim);
}
-void Scripts::CMDDISPINV() { }
-void Scripts::CMDSETTIMER() { }
-void Scripts::CMDCHECKTIMER() { }
+void Scripts::CMDDISPINV() { error("TODO"); }
+void Scripts::CMDSETTIMER() { error("TODO"); }
+void Scripts::CMDCHECKTIMER() { error("TODO"); }
void Scripts::cmdSetTravel() {
if (_vm->_selectCommand == 5)
@@ -271,8 +274,8 @@ void Scripts::cmdSetTravel() {
_data->skip(2);
}
-void Scripts::CMDSETVID() { }
-void Scripts::CMDPLAYVID() { }
+void Scripts::CMDSETVID() { error("TODO"); }
+void Scripts::CMDPLAYVID() { error("TODO"); }
void Scripts::cmdPlotImage() {
_vm->_destIn = _vm->_current;
@@ -290,7 +293,7 @@ void Scripts::cmdSetDisplay() {
_vm->_current = _vm->_screen;
}
-void Scripts::CMDSETBUFFER() { }
+void Scripts::CMDSETBUFFER() { error("TODO"); }
void Scripts::cmdSetScroll() {
_vm->_screen->_scrollCol = _data->readUint16LE();
@@ -299,31 +302,31 @@ void Scripts::cmdSetScroll() {
_vm->_screen->_scrollY = 0;
}
-void Scripts::CMDSAVERECT() { }
-void Scripts::CMDSETBUFVID() { }
-void Scripts::CMDPLAYBUFVID() { }
+void Scripts::CMDSAVERECT() { error("TODO"); }
+void Scripts::CMDSETBUFVID() { error("TODO"); }
+void Scripts::CMDPLAYBUFVID() { error("TODO"); }
void Scripts::cmeRemoveLast() {
--_vm->_numAnimTimers;
}
-void Scripts::CMDSPECIAL() { }
-void Scripts::CMDSETCYCLE() { }
-void Scripts::CMDCYCLE() { }
-void Scripts::CMDCHARSPEAK() { }
-void Scripts::CMDTEXSPEAK() { }
-void Scripts::CMDTEXCHOICE() { }
-void Scripts::CMDWAIT() { }
-void Scripts::CMDSETCONPOS() { }
-void Scripts::CMDCHECKVFRAME() { }
-void Scripts::CMDJUMPCHOICE() { }
-void Scripts::CMDRETURNCHOICE() { }
-void Scripts::CMDCLEARBLOCK() { }
-void Scripts::CMDLOADSOUND() { }
-void Scripts::CMDFREESOUND() { }
-void Scripts::CMDSETVIDSND() { }
-void Scripts::CMDPLAYVIDSND() { }
-void Scripts::CMDPUSHLOCATION() { }
+void Scripts::CMDSPECIAL() { error("TODO"); }
+void Scripts::CMDSETCYCLE() { error("TODO"); }
+void Scripts::CMDCYCLE() { error("TODO"); }
+void Scripts::CMDCHARSPEAK() { error("TODO"); }
+void Scripts::CMDTEXSPEAK() { error("TODO"); }
+void Scripts::CMDTEXCHOICE() { error("TODO"); }
+void Scripts::CMDWAIT() { error("TODO"); }
+void Scripts::CMDSETCONPOS() { error("TODO"); }
+void Scripts::CMDCHECKVFRAME() { error("TODO"); }
+void Scripts::CMDJUMPCHOICE() { error("TODO"); }
+void Scripts::CMDRETURNCHOICE() { error("TODO"); }
+void Scripts::CMDCLEARBLOCK() { error("TODO"); }
+void Scripts::CMDLOADSOUND() { error("TODO"); }
+void Scripts::CMDFREESOUND() { error("TODO"); }
+void Scripts::CMDSETVIDSND() { error("TODO"); }
+void Scripts::CMDPLAYVIDSND() { error("TODO"); }
+void Scripts::CMDPUSHLOCATION() { error("TODO"); }
void Scripts::cmdPlayerOff() {
_vm->_player->_playerOff = true;
@@ -333,18 +336,18 @@ void Scripts::cmdPlayerOn() {
_vm->_player->_playerOff = false;
}
-void Scripts::CMDDEAD() { }
+void Scripts::CMDDEAD() { error("TODO"); }
void Scripts::cmdFadeOut() {
_vm->_screen->forceFadeOut();
}
-void Scripts::CMDENDVID() { }
-void Scripts::CMDHELP() { }
-void Scripts::CMDCYCLEBACK() { }
-void Scripts::CMDCHAPTER() { }
-void Scripts::CMDSETHELP() { }
-void Scripts::CMDCENTERPANEL() { }
+void Scripts::CMDENDVID() { error("TODO"); }
+void Scripts::CMDHELP() { error("TODO"); }
+void Scripts::CMDCYCLEBACK() { error("TODO"); }
+void Scripts::CMDCHAPTER() { error("TODO"); }
+void Scripts::CMDSETHELP() { error("TODO"); }
+void Scripts::CMDCENTERPANEL() { error("TODO"); }
void Scripts::cmdMainPanel() {
if (_vm->_screen->_vesaMode) {
@@ -353,7 +356,7 @@ void Scripts::cmdMainPanel() {
}
}
-void Scripts::CMDRETFLASH() { }
+void Scripts::CMDRETFLASH() { error("TODO"); }
} // End of namespace Access
diff --git a/engines/access/scripts.h b/engines/access/scripts.h
index 3173c8a587..c8f951deae 100644
--- a/engines/access/scripts.h
+++ b/engines/access/scripts.h
@@ -52,7 +52,7 @@ protected:
void cmdNull();
void CMDPRINT();
void cmdRetPos();
- void CMDANIM();
+ void cmdAnim();
void cmdSetFlag();
void cmdCheckFlag();