diff options
| -rw-r--r-- | engines/kyra/animator_tim.cpp | 228 | ||||
| -rw-r--r-- | engines/kyra/lol.cpp | 4 | ||||
| -rw-r--r-- | engines/kyra/lol.h | 2 | ||||
| -rw-r--r-- | engines/kyra/module.mk | 1 | ||||
| -rw-r--r-- | engines/kyra/script_lol.cpp | 18 | ||||
| -rw-r--r-- | engines/kyra/script_tim.cpp | 246 | ||||
| -rw-r--r-- | engines/kyra/script_tim.h | 108 | 
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();  | 
