[Scummvm-cvs-logs] SF.net SVN: scummvm:[46351] scummvm/trunk/engines/kyra

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Sat Dec 12 21:06:42 CET 2009


Revision: 46351
          http://scummvm.svn.sourceforge.net/scummvm/?rev=46351&view=rev
Author:   athrxx
Date:     2009-12-12 20:06:42 +0000 (Sat, 12 Dec 2009)

Log Message:
-----------
LOL: moved TIM animation code into a separate class

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/lol.cpp
    scummvm/trunk/engines/kyra/lol.h
    scummvm/trunk/engines/kyra/module.mk
    scummvm/trunk/engines/kyra/script_lol.cpp
    scummvm/trunk/engines/kyra/script_tim.cpp
    scummvm/trunk/engines/kyra/script_tim.h

Added Paths:
-----------
    scummvm/trunk/engines/kyra/animator_tim.cpp

Added: scummvm/trunk/engines/kyra/animator_tim.cpp
===================================================================
--- scummvm/trunk/engines/kyra/animator_tim.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/animator_tim.cpp	2009-12-12 20:06:42 UTC (rev 46351)
@@ -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


Property changes on: scummvm/trunk/engines/kyra/animator_tim.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/trunk/engines/kyra/lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/lol.cpp	2009-12-12 20:02:03 UTC (rev 46350)
+++ scummvm/trunk/engines/kyra/lol.cpp	2009-12-12 20:06:42 UTC (rev 46351)
@@ -47,6 +47,7 @@
 	_gui = 0;
 	_txt = 0;
 	_tim = 0;
+	_animator = 0;
 
 	switch (_flags.lang) {
 	case Common::EN_ANY:
@@ -579,6 +580,7 @@
 
 	_tim = new TIMInterpreter_LoL(this, _screen, _system);
 	assert(_tim);
+	_animator = _tim->animator();
 
 	if (shouldQuit())
 		return Common::kNoError;
@@ -1796,7 +1798,7 @@
 		return;
 
 	for (int i = 0; i < 6; i++)
-		_tim->updateBackgroundAnimation(i);
+		_animator->update(i);
 }
 
 void LoLEngine::loadTalkFile(int index) {

Modified: scummvm/trunk/engines/kyra/lol.h
===================================================================
--- scummvm/trunk/engines/kyra/lol.h	2009-12-12 20:02:03 UTC (rev 46350)
+++ scummvm/trunk/engines/kyra/lol.h	2009-12-12 20:06:42 UTC (rev 46351)
@@ -300,6 +300,7 @@
 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 @@
 	GUI_LoL *_gui;
 
 	TIMInterpreter *_tim;
+	TimAnimator *_animator;
 
 	Common::Error init();
 	Common::Error go();

Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk	2009-12-12 20:02:03 UTC (rev 46350)
+++ scummvm/trunk/engines/kyra/module.mk	2009-12-12 20:06:42 UTC (rev 46351)
@@ -5,6 +5,7 @@
 	animator_v2.o \
 	animator_hof.o \
 	animator_mr.o \
+	animator_tim.o \
 	debugger.o \
 	detection.o \
 	gui.o \

Modified: scummvm/trunk/engines/kyra/script_lol.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_lol.cpp	2009-12-12 20:02:03 UTC (rev 46350)
+++ scummvm/trunk/engines/kyra/script_lol.cpp	2009-12-12 20:06:42 UTC (rev 46351)
@@ -520,7 +520,7 @@
 
 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_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_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_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_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_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_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 {

Modified: scummvm/trunk/engines/kyra/script_tim.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.cpp	2009-12-12 20:02:03 UTC (rev 46350)
+++ scummvm/trunk/engines/kyra/script_tim.cpp	2009-12-12 20:06:42 UTC (rev 46351)
@@ -91,9 +91,6 @@
 	_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 @@
 	else
 		_drawPage2 = 8;
 
+	_animator = new TimAnimator(0, 0, 0, false);
+
 	_palDelayInc = _palDiff = _palDelayAcc = 0;
 	_abortFlag = 0;
 	_tim = 0;
@@ -111,13 +110,7 @@
 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 @@
 	}
 }
 
-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 @@
 
 	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 @@
 				_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 @@
 			_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 @@
 	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_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 @@
 
 	_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 @@
 	_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 @@
 	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 @@
 	}
 
 	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 @@
 		_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 @@
 		_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 @@
 			_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 @@
 	_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);

Modified: scummvm/trunk/engines/kyra/script_tim.h
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.h	2009-12-12 20:02:03 UTC (rev 46350)
+++ scummvm/trunk/engines/kyra/script_tim.h	2009-12-12 20:06:42 UTC (rev 46351)
@@ -36,6 +36,63 @@
 
 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 @@
 
 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 @@
 
 	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 @@
 
 	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 @@
 	TIM *_currentTim;
 	int _currentFunc;
 
+	TimAnimator *_animator;
+
 	bool _finished;
 
 	// used when loading
@@ -178,8 +204,6 @@
 
 	Common::String _vocFiles[120];
 
-	Animation *_animations;
-
 	virtual void update() {}
 	virtual void checkSpeechProgress() {}
 
@@ -233,24 +257,16 @@
 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();


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list