mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-30 07:23:05 +00:00
LOL: moved TIM animation code into a separate class
svn-id: r46351
This commit is contained in:
parent
0e7c2265b5
commit
f4c54fb636
228
engines/kyra/animator_tim.cpp
Normal file
228
engines/kyra/animator_tim.cpp
Normal file
@ -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
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -5,6 +5,7 @@ MODULE_OBJS := \
|
||||
animator_v2.o \
|
||||
animator_hof.o \
|
||||
animator_mr.o \
|
||||
animator_tim.o \
|
||||
debugger.o \
|
||||
detection.o \
|
||||
gui.o \
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user