aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorFlorian Kagerer2009-12-12 20:06:42 +0000
committerFlorian Kagerer2009-12-12 20:06:42 +0000
commitf4c54fb636478b4bdf4a2e8c3a76b060459a0ca1 (patch)
tree263efd9b89dae1acc97076509afc3de5efc6376e /engines
parent0e7c2265b57b05b38929cbebf66feb446238d41c (diff)
downloadscummvm-rg350-f4c54fb636478b4bdf4a2e8c3a76b060459a0ca1.tar.gz
scummvm-rg350-f4c54fb636478b4bdf4a2e8c3a76b060459a0ca1.tar.bz2
scummvm-rg350-f4c54fb636478b4bdf4a2e8c3a76b060459a0ca1.zip
LOL: moved TIM animation code into a separate class
svn-id: r46351
Diffstat (limited to 'engines')
-rw-r--r--engines/kyra/animator_tim.cpp228
-rw-r--r--engines/kyra/lol.cpp4
-rw-r--r--engines/kyra/lol.h2
-rw-r--r--engines/kyra/module.mk1
-rw-r--r--engines/kyra/script_lol.cpp18
-rw-r--r--engines/kyra/script_tim.cpp246
-rw-r--r--engines/kyra/script_tim.h108
7 files changed, 343 insertions, 264 deletions
diff --git a/engines/kyra/animator_tim.cpp b/engines/kyra/animator_tim.cpp
new file mode 100644
index 0000000000..5e2245608f
--- /dev/null
+++ b/engines/kyra/animator_tim.cpp
@@ -0,0 +1,228 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+#include "common/system.h"
+
+#include "kyra/script_tim.h"
+#include "kyra/wsamovie.h"
+#include "kyra/screen_lol.h"
+
+#ifdef ENABLE_LOL
+#include "kyra/lol.h"
+#endif ENABLE_LOL
+
+namespace Kyra {
+
+TimAnimator::TimAnimator(LoLEngine *engine, Screen_v2 *screen_v2, OSystem *system, bool useParts) : _vm(engine), _screen(screen_v2), _system(system), _useParts(useParts) {
+ _animations = new Animation[TIM::kWSASlots];
+ memset(_animations, 0, TIM::kWSASlots * sizeof(Animation));
+
+ if (_useParts) {
+ for (int i = 0; i < TIM::kWSASlots; i++) {
+ _animations[i].parts = new AnimPart[TIM::kAnimParts];
+ memset(_animations[i].parts, 0, TIM::kAnimParts * sizeof(AnimPart));
+ }
+ }
+}
+
+TimAnimator::~TimAnimator() {
+ for (int i = 0; i < TIM::kWSASlots; i++) {
+ delete _animations[i].wsa;
+ if (_useParts)
+ delete[] _animations[i].parts;
+ }
+
+ delete[] _animations;
+}
+
+void TimAnimator::init(int animIndex, Movie *wsa, int x, int y, int wsaCopyParams, int frameDelay) {
+ TimAnimator::Animation *anim = &_animations[animIndex];
+ anim->wsa = wsa;
+ anim->x = x;
+ anim->y = y;
+ anim->wsaCopyParams = wsaCopyParams;
+ anim->frameDelay = frameDelay;
+ anim->enable = 0;
+ anim->lastPart = -1;
+}
+
+void TimAnimator::reset(int animIndex, bool clearStruct) {
+ TimAnimator::Animation *anim = &_animations[animIndex];
+ if (!anim)
+ return;
+ anim->field_D = 0;
+ anim->enable = 0;
+ delete anim->wsa;
+ anim->wsa = 0;
+
+ if (clearStruct) {
+ if (_useParts)
+ delete[] anim->parts;
+
+ memset(anim, 0, sizeof(Animation));
+
+ if (_useParts) {
+ anim->parts = new AnimPart[TIM::kAnimParts];
+ memset(anim->parts, 0, TIM::kAnimParts * sizeof(AnimPart));
+ }
+ }
+}
+
+void TimAnimator::displayFrame(int animIndex, int page, int frame) {
+ TimAnimator::Animation *anim = &_animations[animIndex];
+ if ((anim->wsaCopyParams & 0x4000) != 0)
+ page = 2;
+ // WORKAROUND for some bugged scripts that will try to display frames of non-existent animations
+ if (anim->wsa)
+ anim->wsa->displayFrame(frame, page, anim->x, anim->y, anim->wsaCopyParams & 0xF0FF, 0, 0);
+ if (!page)
+ _screen->updateScreen();
+}
+
+void TimAnimator::setupPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame) {
+ AnimPart *a = &_animations[animIndex].parts[part];
+ a->firstFrame = firstFrame;
+ a->lastFrame = lastFrame;
+ a->cycles = cycles;
+ a->nextPart = nextPart;
+ a->partDelay = partDelay;
+ a->field_A = f;
+ a->sfxIndex = sfxIndex;
+ a->sfxFrame = sfxFrame;
+}
+
+void TimAnimator::start(int animIndex, int part) {
+ if (!_vm || !_system || !_screen)
+ return;
+
+ Animation *anim = &_animations[animIndex];
+ anim->curPart = part;
+ AnimPart *p = &anim->parts[part];
+ anim->enable = 1;
+ anim->nextFrame = _system->getMillis() + anim->frameDelay * _vm->_tickLength;
+ anim->curFrame = p->firstFrame;
+ anim->cyclesCompleted = 0;
+
+ // WORKAROUND for some bugged scripts that will try to display frames of non-existent animations
+ if (anim->wsa)
+ anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
+}
+
+void TimAnimator::stop(int animIndex) {
+ Animation *anim = &_animations[animIndex];
+ anim->enable = 0;
+ anim->field_D = 0;
+ if (animIndex == 5) {
+ delete anim->wsa;
+ anim->wsa = 0;
+ }
+}
+
+void TimAnimator::update(int animIndex) {
+ if (!_vm || !_system || !_screen)
+ return;
+
+ Animation *anim = &_animations[animIndex];
+ if (!anim->enable || anim->nextFrame >= _system->getMillis())
+ return;
+
+ AnimPart *p = &anim->parts[anim->curPart];
+ anim->nextFrame = 0;
+
+ int step = 0;
+ if (p->lastFrame >= p->firstFrame) {
+ step = 1;
+ anim->curFrame++;
+ } else {
+ step = -1;
+ anim->curFrame--;
+ }
+
+ if (anim->curFrame == (p->lastFrame + step)) {
+ anim->cyclesCompleted++;
+
+ if ((anim->cyclesCompleted > p->cycles) || anim->field_D) {
+ anim->lastPart = anim->curPart;
+
+ if ((p->nextPart == -1) || (anim->field_D && p->field_A)) {
+ anim->enable = 0;
+ anim->field_D = 0;
+ return;
+ }
+
+ anim->nextFrame += (p->partDelay * _vm->_tickLength);
+ anim->curPart = p->nextPart;
+
+ p = &anim->parts[anim->curPart];
+ anim->curFrame = p->firstFrame;
+ anim->cyclesCompleted = 0;
+
+ } else {
+ anim->curFrame = p->firstFrame;
+ }
+ }
+
+ if (p->sfxIndex != -1 && p->sfxFrame == anim->curFrame)
+ _vm->snd_playSoundEffect(p->sfxIndex, -1);
+
+ anim->nextFrame += (anim->frameDelay * _vm->_tickLength);
+
+ anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
+ anim->nextFrame += _system->getMillis();
+}
+
+void TimAnimator::playPart(int animIndex, int firstFrame, int lastFrame, int delay) {
+ if (!_vm || !_system || !_screen)
+ return;
+
+ Animation *anim = &_animations[animIndex];
+
+ int step = (lastFrame >= firstFrame) ? 1 : -1;
+ for (int i = firstFrame; i != (lastFrame + step) ; i += step) {
+ uint32 next = _system->getMillis() + delay * _vm->_tickLength;
+ if (anim->wsaCopyParams & 0x4000) {
+ _screen->copyRegion(112, 0, 112, 0, 176, 120, 6, 2);
+ anim->wsa->displayFrame(i - 1, 2, anim->x, anim->y, anim->wsaCopyParams & 0x1000 ? 0x5000 : 0x4000, _vm->_transparencyTable1, _vm->_transparencyTable2);
+ _screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
+ _screen->updateScreen();
+ } else {
+ anim->wsa->displayFrame(i - 1, 0, anim->x, anim->y, 0, 0, 0);
+ _screen->updateScreen();
+ }
+ int32 del = (int32)(next - _system->getMillis());
+ if (del > 0)
+ _vm->delay(del, true);
+ }
+}
+
+int TimAnimator::resetLastPart(int animIndex) {
+ Animation *anim = &_animations[animIndex];
+ int8 res = -1;
+ SWAP(res, anim->lastPart);
+ return res;
+}
+
+} // End of namespace Kyra
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 6f122c890e..4808223020 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -47,6 +47,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
_gui = 0;
_txt = 0;
_tim = 0;
+ _animator = 0;
switch (_flags.lang) {
case Common::EN_ANY:
@@ -579,6 +580,7 @@ Common::Error LoLEngine::go() {
_tim = new TIMInterpreter_LoL(this, _screen, _system);
assert(_tim);
+ _animator = _tim->animator();
if (shouldQuit())
return Common::kNoError;
@@ -1796,7 +1798,7 @@ void LoLEngine::updateSequenceBackgroundAnimations() {
return;
for (int i = 0; i < 6; i++)
- _tim->updateBackgroundAnimation(i);
+ _animator->update(i);
}
void LoLEngine::loadTalkFile(int index) {
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 0f2bca21e0..780b318775 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -300,6 +300,7 @@ class LoLEngine : public KyraEngine_v1 {
friend class GUI_LoL;
friend class TextDisplayer_LoL;
friend class TIMInterpreter_LoL;
+friend class TimAnimator;
friend class Debugger_LoL;
friend class HistoryPlayer;
public:
@@ -314,6 +315,7 @@ private:
GUI_LoL *_gui;
TIMInterpreter *_tim;
+ TimAnimator *_animator;
Common::Error init();
Common::Error go();
diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk
index b484fa345f..b9006431d7 100644
--- a/engines/kyra/module.mk
+++ b/engines/kyra/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
animator_v2.o \
animator_hof.o \
animator_mr.o \
+ animator_tim.o \
debugger.o \
detection.o \
gui.o \
diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp
index 7fe89fb1cb..c49cc9d8d5 100644
--- a/engines/kyra/script_lol.cpp
+++ b/engines/kyra/script_lol.cpp
@@ -520,7 +520,7 @@ int LoLEngine::olol_initAnimStruct(EMCState *script) {
int LoLEngine::olol_playAnimationPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_playAnimationPart(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
- _tim->playAnimationPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
+ _animator->playPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
return 1;
}
@@ -589,13 +589,13 @@ int LoLEngine::olol_clearDialogueField(EMCState *script) {
int LoLEngine::olol_setupBackgroundAnimationPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setupBackgroundAnimationPart(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
- _tim->setupBackgroundAnimationPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
+ _animator->setupPart(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9));
return 0;
}
int LoLEngine::olol_startBackgroundAnimation(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_startBackgroundAnimation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
- _tim->startBackgroundAnimation(stackPos(0), stackPos(1));
+ _animator->start(stackPos(0), stackPos(1));
return 1;
}
@@ -625,7 +625,7 @@ int LoLEngine::olol_loadBitmap(EMCState *script) {
int LoLEngine::olol_stopBackgroundAnimation(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_stopBackgroundAnimation(%p) (%d)", (const void *)script, stackPos(0));
- _tim->stopBackgroundAnimation(stackPos(0));
+ _animator->stop(stackPos(0));
return 1;
}
@@ -1978,7 +1978,7 @@ int LoLEngine::olol_removeInventoryItem(EMCState *script) {
int LoLEngine::olol_getAnimationLastPart(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_getAnimationLastPart(%p) (%d)", (const void *)script, stackPos(0));
- return _tim->resetAnimationLastPart(stackPos(0));
+ return _animator->resetLastPart(stackPos(0));
}
int LoLEngine::olol_assignSpecialGuiShape(EMCState *script) {
@@ -2393,7 +2393,7 @@ int LoLEngine::tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_processWsaFrame(%p, %p) (%d, %d, %d, %d, %d)",
(const void *)tim, (const void *)param, param[0], param[1], param[2], param[3], param[4]);
- TIMInterpreter::Animation *anim = (TIMInterpreter::Animation *)tim->wsa[param[0]].anim;
+ TimAnimator::Animation *anim = (TimAnimator::Animation *) tim->wsa[param[0]].anim;
const int frame = param[1];
const int x2 = param[2];
const int y2 = param[3];
@@ -2576,13 +2576,13 @@ int LoLEngine::tlol_playSoundEffect(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_startBackgroundAnimation(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_startBackgroundAnimation(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
- _tim->startBackgroundAnimation(param[0], param[1]);
+ _animator->start(param[0], param[1]);
return 1;
}
int LoLEngine::tlol_stopBackgroundAnimation(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_stopBackgroundAnimation(%p, %p) (%d)", (const void *)tim, (const void *)param, param[0]);
- _tim->stopBackgroundAnimation(param[0]);
+ _animator->stop(param[0]);
return 1;
}
@@ -2665,7 +2665,7 @@ int LoLEngine::tlol_fadeOutSound(const TIM *tim, const uint16 *param) {
int LoLEngine::tlol_displayAnimFrame(const TIM *tim, const uint16 *param) {
debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayAnimFrame(%p, %p) (%d, %d)", (const void *)tim, (const void *)param, param[0], param[1]);
- TIMInterpreter::Animation *anim = (TIMInterpreter::Animation *)tim->wsa[param[0]].anim;
+ TimAnimator::Animation *anim = (TimAnimator::Animation *)tim->wsa[param[0]].anim;
if (param[1] == 0xFFFF) {
_screen->copyRegion(0, 0, 0, 0, 320, 200, 0, 2, Screen::CR_NO_P_CHECK);
} else {
diff --git a/engines/kyra/script_tim.cpp b/engines/kyra/script_tim.cpp
index 80e159433a..807d40c000 100644
--- a/engines/kyra/script_tim.cpp
+++ b/engines/kyra/script_tim.cpp
@@ -91,9 +91,6 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys
_commands = commandProcs;
_commandsSize = ARRAYSIZE(commandProcs);
- _animations = new Animation[TIM::kWSASlots];
- memset(_animations, 0, TIM::kWSASlots * sizeof(Animation));
-
_langData = 0;
_textDisplayed = false;
_textAreaBuffer = new uint8[320*40];
@@ -103,6 +100,8 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys
else
_drawPage2 = 8;
+ _animator = new TimAnimator(0, 0, 0, false);
+
_palDelayInc = _palDiff = _palDelayAcc = 0;
_abortFlag = 0;
_tim = 0;
@@ -111,13 +110,7 @@ TIMInterpreter::TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSys
TIMInterpreter::~TIMInterpreter() {
delete[] _langData;
delete[] _textAreaBuffer;
-
- for (int i = 0; i < TIM::kWSASlots; i++) {
- delete _animations[i].wsa;
- delete[] _animations[i].parts;
- }
-
- delete[] _animations;
+ delete _animator;
}
bool TIMInterpreter::callback(Common::IFFChunk &chunk) {
@@ -472,11 +465,9 @@ void TIMInterpreter::setupTextPalette(uint index, int fadePalette) {
}
}
-TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) {
- Animation *anim = &_animations[index];
- anim->x = x;
- anim->y = y;
- anim->wsaCopyParams = wsaFlags;
+TimAnimator::Animation *TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) {
+ Movie *wsa = 0;
+
const bool isLoLDemo = _vm->gameFlags().isDemo && _vm->gameFlags().gameID == GI_LOL;
if (isLoLDemo || _vm->gameFlags().platform == Common::kPlatformPC98 || _currentTim->isLoLOutro)
@@ -502,34 +493,34 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
if (_vm->resource()->exists(file)) {
if (isLoLDemo)
- anim->wsa = new WSAMovie_v1(_vm);
+ wsa = new WSAMovie_v1(_vm);
else
- anim->wsa = new WSAMovie_v2(_vm);
- assert(anim->wsa);
+ wsa = new WSAMovie_v2(_vm);
+ assert(wsa);
- anim->wsa->open(file, wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
+ wsa->open(file, wsaOpenFlags, (index == 1) ? &_screen->getPalette(0) : 0);
}
- if (anim->wsa && anim->wsa->opened()) {
+ if (wsa && wsa->opened()) {
if (isLoLDemo) {
if (x == -1) {
- int16 t = int8(320 - anim->wsa->width());
+ int16 t = int8(320 - wsa->width());
uint8 v = int8(t & 0x00FF) - int8((t & 0xFF00) >> 8);
v >>= 1;
- anim->x = x = v;
+ x = v;
}
if (y == -1) {
- int16 t = int8(200 - anim->wsa->height());
+ int16 t = int8(200 - wsa->height());
uint8 v = int8(t & 0x00FF) - int8((t & 0xFF00) >> 8);
v >>= 1;
- anim->y = y = v;
+ y = v;
}
} else {
if (x == -1)
- anim->x = x = 0;
+ x = 0;
if (y == -1)
- anim->y = y = 0;
+ y = 0;
}
if (wsaFlags & 2) {
@@ -551,7 +542,7 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
_screen->updateScreen();
}
- anim->wsa->displayFrame(0, 0, x, y, 0, 0, 0);
+ wsa->displayFrame(0, 0, x, y, 0, 0, 0);
}
if (wsaFlags & 2)
@@ -579,16 +570,13 @@ TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char
_screen->fadePalette(_screen->getPalette(0), 30, 0);
}
- return anim;
+ _animator->init(index, wsa, x, y, wsaFlags, 0);
+
+ return _animator->getAnimPtr(index);
}
int TIMInterpreter::freeAnimStruct(int index) {
- Animation *anim = &_animations[index];
- if (!anim)
- return 0;
-
- delete anim->wsa;
- memset(anim, 0, sizeof(Animation));
+ _animator->reset(index, true);
return 1;
}
@@ -666,26 +654,13 @@ int TIMInterpreter::cmd_uninitWSA(const uint16 *param) {
if (!slot.anim)
return 0;
- Animation &anim = _animations[index];
-
if (slot.offscreen) {
- delete anim.wsa;
- anim.wsa = 0;
+ _animator->reset(index, false);
slot.anim = 0;
} else {
//XXX
-
- delete anim.wsa;
- bool hasParts = anim.parts ? true : false;
- delete[] anim.parts;
-
- memset(&anim, 0, sizeof(Animation));
+ _animator->reset(index, true);
memset(&slot, 0, sizeof(TIM::WSASlot));
-
- if (hasParts) {
- anim.parts = new AnimPart[TIM::kAnimParts];
- memset(anim.parts, 0, TIM::kAnimParts * sizeof(AnimPart));
- }
}
return 1;
@@ -709,14 +684,7 @@ int TIMInterpreter::cmd_stopFunc(const uint16 *param) {
}
int TIMInterpreter::cmd_wsaDisplayFrame(const uint16 *param) {
- Animation &anim = _animations[param[0]];
- const int frame = param[1];
- int page = (anim.wsaCopyParams & 0x4000) != 0 ? 2 : _drawPage2;
- // WORKAROUND for some bugged scripts that will try to display frames of non-existent animations
- if (anim.wsa)
- anim.wsa->displayFrame(frame, page, anim.x, anim.y, anim.wsaCopyParams & 0xF0FF, 0, 0);
- if (!page)
- _screen->updateScreen();
+ _animator->displayFrame(param[0], _drawPage2, param[1]);
return 1;
}
@@ -944,10 +912,7 @@ TIMInterpreter_LoL::TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2,
_screen = engine->_screen;
- for (int i = 0; i < TIM::kWSASlots; i++) {
- _animations[i].parts = new AnimPart[TIM::kAnimParts];
- memset(_animations[i].parts, 0, TIM::kAnimParts * sizeof(AnimPart));
- }
+ _animator = new TimAnimator(engine, screen_v2, system, true);
_drawPage2 = 0;
@@ -955,15 +920,8 @@ TIMInterpreter_LoL::TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2,
_dialogueButtonPosX = _dialogueButtonPosY = _dialogueNumButtons = _dialogueButtonXoffs = _dialogueHighlightedButton = 0;
}
-TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaFlags) {
- Animation *anim = &_animations[index];
- anim->x = x;
- anim->y = y;
- anim->frameDelay = frameDelay;
- anim->wsaCopyParams = wsaFlags;
- anim->enable = 0;
- anim->lastPart = -1;
-
+TimAnimator::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaFlags) {
+ Movie *wsa = 0;
uint16 wsaOpenFlags = 0;
if (wsaFlags & 0x10)
wsaOpenFlags |= 2;
@@ -974,9 +932,9 @@ TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const c
snprintf(file, 32, "%s.WSA", filename);
if (_vm->resource()->exists(file)) {
- anim->wsa = new WSAMovie_v2(_vm);
- assert(anim->wsa);
- anim->wsa->open(file, wsaOpenFlags, &_screen->getPalette(3));
+ wsa = new WSAMovie_v2(_vm);
+ assert(wsa);
+ wsa->open(file, wsaOpenFlags, &_screen->getPalette(3));
}
if (!_vm->_flags.use16ColorMode) {
@@ -990,7 +948,7 @@ TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const c
}
if (wsaFlags & 7)
- anim->wsa->displayFrame(0, 0, x, y, 0, 0, 0);
+ wsa->displayFrame(0, 0, x, y, 0, 0, 0);
if (wsaFlags & 3) {
if (_vm->_flags.use16ColorMode) {
@@ -1002,21 +960,13 @@ TIMInterpreter::Animation *TIMInterpreter_LoL::initAnimStruct(int index, const c
_screen->_fadeFlag = 0;
}
- return anim;
+ _animator->init(index, wsa, x, y, wsaFlags, frameDelay);
+
+ return _animator->getAnimPtr(index);
}
int TIMInterpreter_LoL::freeAnimStruct(int index) {
- Animation *anim = &_animations[index];
- if (!anim)
- return 0;
-
- delete anim->wsa;
- delete[] anim->parts;
- memset(anim, 0, sizeof(Animation));
-
- anim->parts = new AnimPart[TIM::kAnimParts];
- memset(anim->parts, 0, TIM::kAnimParts * sizeof(AnimPart));
-
+ _animator->reset(index, true);
return 1;
}
@@ -1067,120 +1017,6 @@ void TIMInterpreter_LoL::drawDialogueBox(int numStr, const char *s1, const char
_vm->removeInputTop();
}
-void TIMInterpreter_LoL::setupBackgroundAnimationPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame) {
- AnimPart *a = &_animations[animIndex].parts[part];
- a->firstFrame = firstFrame;
- a->lastFrame = lastFrame;
- a->cycles = cycles;
- a->nextPart = nextPart;
- a->partDelay = partDelay;
- a->field_A = f;
- a->sfxIndex = sfxIndex;
- a->sfxFrame = sfxFrame;
-}
-
-void TIMInterpreter_LoL::startBackgroundAnimation(int animIndex, int part) {
- Animation *anim = &_animations[animIndex];
- anim->curPart = part;
- AnimPart *p = &anim->parts[part];
- anim->enable = 1;
- anim->nextFrame = _system->getMillis() + anim->frameDelay * _vm->_tickLength;
- anim->curFrame = p->firstFrame;
- anim->cyclesCompleted = 0;
-
- // WORKAROUND for some bugged scripts that will try to display frames of non-existent animations
- if (anim->wsa)
- anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
-}
-
-void TIMInterpreter_LoL::stopBackgroundAnimation(int animIndex) {
- Animation *anim = &_animations[animIndex];
- anim->enable = 0;
- anim->field_D = 0;
- if (animIndex == 5) {
- delete anim->wsa;
- anim->wsa = 0;
- }
-}
-
-void TIMInterpreter_LoL::updateBackgroundAnimation(int animIndex) {
- Animation *anim = &_animations[animIndex];
- if (!anim->enable || anim->nextFrame >= _system->getMillis())
- return;
-
- AnimPart *p = &anim->parts[anim->curPart];
- anim->nextFrame = 0;
-
- int step = 0;
- if (p->lastFrame >= p->firstFrame) {
- step = 1;
- anim->curFrame++;
- } else {
- step = -1;
- anim->curFrame--;
- }
-
- if (anim->curFrame == (p->lastFrame + step)) {
- anim->cyclesCompleted++;
-
- if ((anim->cyclesCompleted > p->cycles) || anim->field_D) {
- anim->lastPart = anim->curPart;
-
- if ((p->nextPart == -1) || (anim->field_D && p->field_A)) {
- anim->enable = 0;
- anim->field_D = 0;
- return;
- }
-
- anim->nextFrame += (p->partDelay * _vm->_tickLength);
- anim->curPart = p->nextPart;
-
- p = &anim->parts[anim->curPart];
- anim->curFrame = p->firstFrame;
- anim->cyclesCompleted = 0;
-
- } else {
- anim->curFrame = p->firstFrame;
- }
- }
-
- if (p->sfxIndex != -1 && p->sfxFrame == anim->curFrame)
- _vm->snd_playSoundEffect(p->sfxIndex, -1);
-
- anim->nextFrame += (anim->frameDelay * _vm->_tickLength);
-
- anim->wsa->displayFrame(anim->curFrame - 1, 0, anim->x, anim->y, 0, 0, 0);
- anim->nextFrame += _system->getMillis();
-}
-
-void TIMInterpreter_LoL::playAnimationPart(int animIndex, int firstFrame, int lastFrame, int delay) {
- Animation *anim = &_animations[animIndex];
-
- int step = (lastFrame >= firstFrame) ? 1 : -1;
- for (int i = firstFrame; i != (lastFrame + step) ; i += step) {
- uint32 next = _system->getMillis() + delay * _vm->_tickLength;
- if (anim->wsaCopyParams & 0x4000) {
- _screen->copyRegion(112, 0, 112, 0, 176, 120, 6, 2);
- anim->wsa->displayFrame(i - 1, 2, anim->x, anim->y, anim->wsaCopyParams & 0x1000 ? 0x5000 : 0x4000, _vm->_transparencyTable1, _vm->_transparencyTable2);
- _screen->copyRegion(112, 0, 112, 0, 176, 120, 2, 0);
- _screen->updateScreen();
- } else {
- anim->wsa->displayFrame(i - 1, 0, anim->x, anim->y, 0, 0, 0);
- _screen->updateScreen();
- }
- int32 del = (int32)(next - _system->getMillis());
- if (del > 0)
- _vm->delay(del, true);
- }
-}
-
-int TIMInterpreter_LoL::resetAnimationLastPart(int animIndex) {
- Animation *anim = &_animations[animIndex];
- int8 res = -1;
- SWAP(res, anim->lastPart);
- return res;
-}
-
void TIMInterpreter_LoL::drawDialogueButtons() {
int cp = _screen->setCurPage(0);
Screen::FontId of = _screen->setFont(_vm->gameFlags().use16ColorMode ? Screen::FID_SJIS_FNT : Screen::FID_6_FNT);
@@ -1316,10 +1152,7 @@ void TIMInterpreter_LoL::checkSpeechProgress() {
_currentTim->dlgFunc = _currentFunc;
advanceToOpcode(21);
_currentTim->dlgFunc = -1;
- _animations[5].field_D = 0;
- _animations[5].enable = 0;
- delete _animations[5].wsa;
- _animations[5].wsa = 0;
+ _animator->reset(5, false);
}
}
}
@@ -1387,10 +1220,7 @@ int TIMInterpreter_LoL::cmd_processDialogue(const uint16 *param) {
_currentTim->procFunc = -1;
_currentTim->clickedButton = res;
- _animations[5].field_D = 0;
- _animations[5].enable = 0;
- delete _animations[5].wsa;
- _animations[5].wsa = 0;
+ _animator->reset(5, false);
if (_currentTim->procParam)
advanceToOpcode(21);
diff --git a/engines/kyra/script_tim.h b/engines/kyra/script_tim.h
index 7958dc66fc..ec9601721e 100644
--- a/engines/kyra/script_tim.h
+++ b/engines/kyra/script_tim.h
@@ -36,6 +36,63 @@ namespace Kyra {
class WSAMovie_v2;
class Screen_v2;
+class LoLEngine;
+
+class TimAnimator {
+public:
+ struct AnimPart {
+ uint16 firstFrame;
+ uint16 lastFrame;
+ uint16 cycles;
+ int16 nextPart;
+ int16 partDelay;
+ uint16 field_A;
+ int16 sfxIndex;
+ uint16 sfxFrame;
+ };
+
+ struct Animation {
+ Movie *wsa;
+ int16 x, y;
+ uint32 nextFrame;
+ uint8 enable;
+ uint8 field_D;
+ uint8 frameDelay;
+ int8 curPart;
+ uint8 curFrame;
+ uint8 cyclesCompleted;
+ uint16 wsaCopyParams;
+ int8 lastPart;
+ AnimPart *parts;
+ };
+
+ TimAnimator(LoLEngine *engine, Screen_v2 *screen_v2, OSystem *system, bool useParts);
+ ~TimAnimator();
+
+ Animation *getAnimPtr(int index) { return (index >= 0 && index < 6) ? &_animations[index] : 0; }
+
+ void init(int animIndex, Movie *wsa, int x, int y, int wsaCopyParams, int frameDelay);
+ void reset(int animIndex, bool clearStruct);
+
+ void displayFrame(int animIndex, int page, int frame);
+
+ void setupPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame);
+ void start(int animIndex, int part);
+ void stop(int animIndex);
+ void update(int animIndex);
+ void playPart(int animIndex, int firstFrame, int lastFrame, int delay);
+ int resetLastPart(int animIndex);
+
+private:
+ LoLEngine *_vm;
+ Screen_v2 *_screen;
+ OSystem *_system;
+
+ Animation *_animations;
+
+ const bool _useParts;
+};
+
struct TIM;
typedef Common::Functor2<const TIM*, const uint16*, int> TIMOpcode;
@@ -89,32 +146,6 @@ struct TIM {
class TIMInterpreter {
public:
- struct AnimPart {
- uint16 firstFrame;
- uint16 lastFrame;
- uint16 cycles;
- int16 nextPart;
- int16 partDelay;
- uint16 field_A;
- int16 sfxIndex;
- uint16 sfxFrame;
- };
-
- struct Animation {
- Movie *wsa;
- int16 x, y;
- uint32 nextFrame;
- uint8 enable;
- uint8 field_D;
- uint8 frameDelay;
- int8 curPart;
- uint8 curFrame;
- uint8 cyclesCompleted;
- uint16 wsaCopyParams;
- int8 lastPart;
- AnimPart *parts;
- };
-
TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSystem *system);
virtual ~TIMInterpreter();
@@ -123,8 +154,9 @@ public:
bool callback(Common::IFFChunk &chunk);
- virtual Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
+ virtual TimAnimator::Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
virtual int freeAnimStruct(int index);
+ TimAnimator *animator() { return _animator; }
void setLangData(const char *filename);
void clearLangData() { delete[] _langData; _langData = 0; }
@@ -146,14 +178,6 @@ public:
virtual void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3) {}
virtual uint16 processDialogue() { return 1; }
-
- virtual void setupBackgroundAnimationPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame) {}
- virtual void startBackgroundAnimation(int animIndex, int part) {}
- virtual void stopBackgroundAnimation(int animIndex) {}
- virtual void updateBackgroundAnimation(int animIndex) {}
- virtual void playAnimationPart(int animIndex, int firstFrame, int lastFrame, int delay) {}
- virtual int resetAnimationLastPart(int animIndex) { return -1; }
-
virtual void resetDialogueState(TIM *tim) {}
int _drawPage2;
@@ -169,6 +193,8 @@ protected:
TIM *_currentTim;
int _currentFunc;
+ TimAnimator *_animator;
+
bool _finished;
// used when loading
@@ -178,8 +204,6 @@ protected:
Common::String _vocFiles[120];
- Animation *_animations;
-
virtual void update() {}
virtual void checkSpeechProgress() {}
@@ -233,24 +257,16 @@ protected:
class LoLEngine;
class Screen_LoL;
class TIMInterpreter_LoL : public TIMInterpreter {
-friend class LoLEngine;
public:
TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2, OSystem *system);
- Animation *initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaCopyParams);
+ TimAnimator::Animation *initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaCopyParams);
int freeAnimStruct(int index);
void drawDialogueBox(int numStr, const char *s1, const char *s2, const char *s3);
uint16 processDialogue();
void resetDialogueState(TIM *tim);
- void setupBackgroundAnimationPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame);
- void startBackgroundAnimation(int animIndex, int part);
- void stopBackgroundAnimation(int animIndex);
- void updateBackgroundAnimation(int animIndex);
- void playAnimationPart(int animIndex, int firstFrame, int lastFrame, int delay);
- int resetAnimationLastPart(int animIndex);
-
private:
void update();
void checkSpeechProgress();