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

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Sat Apr 19 15:52:09 CEST 2008


Revision: 31569
          http://scummvm.svn.sourceforge.net/scummvm/?rev=31569&view=rev
Author:   lordhoto
Date:     2008-04-19 06:52:09 -0700 (Sat, 19 Apr 2008)

Log Message:
-----------
- reworked tim handling
- moved tim interpreter to new class TIMInterpreter

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/kyra_v2.cpp
    scummvm/trunk/engines/kyra/kyra_v2.h
    scummvm/trunk/engines/kyra/module.mk
    scummvm/trunk/engines/kyra/script.cpp
    scummvm/trunk/engines/kyra/script_v2.cpp
    scummvm/trunk/engines/kyra/text_v2.cpp
    scummvm/trunk/engines/kyra/util.h

Added Paths:
-----------
    scummvm/trunk/engines/kyra/script_tim.cpp
    scummvm/trunk/engines/kyra/script_tim.h

Removed Paths:
-------------
    scummvm/trunk/engines/kyra/sequences_tim.cpp

Modified: scummvm/trunk/engines/kyra/kyra_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v2.cpp	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/kyra_v2.cpp	2008-04-19 13:52:09 UTC (rev 31569)
@@ -30,6 +30,7 @@
 #include "kyra/wsamovie.h"
 #include "kyra/sound.h"
 #include "kyra/script.h"
+#include "kyra/script_tim.h"
 #include "kyra/text_v2.h"
 #include "kyra/timer.h"
 #include "kyra/debugger.h"
@@ -87,13 +88,10 @@
 	_chatObject = -1;
 	_lastIdleScript = -1;
 
-	_timChatText = 0;
-	_timChatObject = -1;
+	_currentTalkSections.STATim = 0;
+	_currentTalkSections.TLKTim = 0;
+	_currentTalkSections.ENDTim = 0;
 
-	_currentTalkSections.STATim = NULL;
-	_currentTalkSections.TLKTim = NULL;
-	_currentTalkSections.ENDTim = NULL;
-
 	memset(&_invWsa, 0, sizeof(_invWsa));
 	_itemAnimData = 0;
 	_demoAnimData = 0;
@@ -159,6 +157,7 @@
 	delete _screen;
 	delete _text;
 	delete _gui;
+	delete _tim;
 	_text = 0;
 	delete _debugger;
 	delete _invWsa.wsa;
@@ -196,6 +195,8 @@
 	assert(_text);
 	_gui = new GUI_v2(this);
 	assert(_gui);
+	_tim = new TIMInterpreter(this, _system);
+	assert(_tim);
 
 	if (_flags.isDemo && !_flags.isTalkie) {
 		_screen->loadFont(_screen->FID_8_FNT, "FONT9P.FNT");
@@ -223,8 +224,6 @@
 	if (_flags.isDemo && !_flags.isTalkie)
 		return 0;
 
-	tim_setupOpcodes();
-
 	_mouseSHPBuf = _res->fileData("PWGMOUSE.SHP", 0);
 	assert(_mouseSHPBuf);
 
@@ -2252,6 +2251,26 @@
 
 #pragma mark -
 
+void KyraEngine_v2::playTim(const char *filename) {
+	TIM *tim = _tim->load(filename, &_timOpcodes);
+	if (!tim)
+		return;
+
+	_tim->resetFinishedFlag();
+	while (!_quitFlag && !_tim->finished()) {
+		_tim->exec(tim, 0);
+		if (_chatText)
+			updateWithText();
+		else
+			update();
+		delay(10);
+	}
+
+	_tim->unload(tim);
+}
+
+#pragma mark -
+
 void KyraEngine_v2::registerDefaultSettings() {
 	KyraEngine::registerDefaultSettings();
 

Modified: scummvm/trunk/engines/kyra/kyra_v2.h
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v2.h	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/kyra_v2.h	2008-04-19 13:52:09 UTC (rev 31569)
@@ -31,6 +31,7 @@
 #include "kyra/screen_v2.h"
 #include "kyra/text_v2.h"
 #include "kyra/gui_v2.h"
+#include "kyra/util.h"
 
 #include "common/list.h"
 
@@ -98,8 +99,11 @@
 class WSAMovieV2;
 class KyraEngine_v2;
 class TextDisplayer_v2;
+class TIMInterpreter;
 class Debugger_v2;
 
+struct TIM;
+
 typedef int (KyraEngine_v2::*SeqProc)(WSAMovieV2*, int, int, int);
 
 struct FrameControl {
@@ -286,6 +290,7 @@
 	Screen_v2 *_screen;
 	TextDisplayer_v2 *_text;
 	Debugger_v2 *_debugger;
+	TIMInterpreter *_tim;
 
 	uint8 *_mouseSHPBuf;
 
@@ -809,74 +814,24 @@
 	TalkObject *_talkObjectList;
 
 	struct TalkSections {
-		uint8 *STATim;
-		uint8 *TLKTim;
-		uint8 *ENDTim;
+		TIM *STATim;
+		TIM *TLKTim;
+		TIM *ENDTim;
 	};
 	TalkSections _currentTalkSections;
 
 	char _TLKFilename[13];
-	bool _objectChatFinished;
 
-	// tim sequence
-	void tim_setupOpcodes();
-	uint8 *tim_loadFile(const char *filename, uint8 *buffer, int32 bufferSize);
-	void tim_releaseBuffer(uint8 *buffer);
-	void tim_processSequence(uint8 *timBuffer, int loop);
-	void tim_playFullSequence(const char *filename);
+	// tim
+	void playTim(const char *filename);
 
-	int tim_o_dummy_r0(uint8 *ptr);
-	int tim_o_dummy_r1(uint8 *ptr);
-	int tim_o_clearCmds2(uint8 *ptr);
-	int tim_o_abort(uint8 *ptr);
-	int tim_o_selectcurrentCommandSet(uint8 *ptr);
-	int tim_o_deleteBuffer(uint8 *ptr);
-	int tim_o_refreshTimers(uint8 *ptr);
-	int tim_o_execSubOpcode(uint8 *ptr);
-	int tim_o_initActiveSub(uint8 *ptr);
-	int tim_o_resetActiveSub(uint8 *ptr);
-	int tim_o_printTalkText(uint8 *ptr);
-	int tim_o_updateSceneAnim(uint8 *ptr);
-	int tim_o_resetChat(uint8 *ptr);
-	int tim_o_playSoundEffect(uint8 *ptr);
+	int t2_initChat(const TIM *tim, const uint16 *param);
+	int t2_updateSceneAnim(const TIM *tim, const uint16 *param);
+	int t2_resetChat(const TIM *tim, const uint16 *param);
+	int t2_playSoundEffect(const TIM *tim, const uint16 *param);
 
-	typedef int (KyraEngine_v2::*TimOpc)(uint8 *ptr);
-	const TimOpc * _timOpcodes;
+	Common::Array<const TIMOpcode*> _timOpcodes;
 
-	struct TIMHeader {
-		uint16 deleteBufferFlag;
-		int16 unkFlag;
-		int16 unkFlag2;
-		int16 cmdsOffset;
-		int16 unkOffset2;
-		int16 AVTLOffset;
-		int16 TEXTOffset;
-	};
-
-	struct Cmds {
-		uint8 *dataPtr;
-		uint32 unk_2;
-		uint32 timer1;
-		uint32 timer2;
-		uint8 *backupPtr;
-		uint8 *AVTLSubChunk;
-	};
-
-	struct TIMBuffers {
-		uint8 *AVTLChunk;
-		uint8 *TEXTChunk;
-		uint8 *offsUnkFlag2;
-		uint8 *offsUnkFlag;
-		int16 currentEntry;
-		int16 unk_12;
-		Cmds *currentCommandSet;
-		uint8 *unkCmds;
-	};
-	TIMBuffers _TIMBuffers;
-
-	const char *_timChatText;
-	int _timChatObject;
-
 	// sound
 	int _oldTalkFile;
 	int _currentTalkFile;

Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/module.mk	2008-04-19 13:52:09 UTC (rev 31569)
@@ -32,8 +32,8 @@
 	script_v2.o \
 	script_v3.o \
 	script.o \
+	script_tim.o \
 	seqplayer.o \
-	sequences_tim.o \
 	sequences_v1.o \
 	sequences_v2.o \
 	sound_adlib.o \

Modified: scummvm/trunk/engines/kyra/script.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script.cpp	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/script.cpp	2008-04-19 13:52:09 UTC (rev 31569)
@@ -207,7 +207,7 @@
 	if (opcode > 18) {
 		error("Script unknown command: %d", opcode);
 	} else {
-		debugC(5, kDebugLevelScript, "[0x%.08X] %s([%d/%u])", instOffset, _commands[opcode].desc, _parameter, (uint)_parameter);
+		debugC(5, kDebugLevelScript, "[0x%.08X] ScriptHelper::%s([%d/%u])", instOffset, _commands[opcode].desc, _parameter, (uint)_parameter);
 		(this->*(_commands[opcode].proc))(script);
 	}
 

Added: scummvm/trunk/engines/kyra/script_tim.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/script_tim.cpp	2008-04-19 13:52:09 UTC (rev 31569)
@@ -0,0 +1,269 @@
+/* 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 "kyra/script_tim.h"
+#include "kyra/script.h"
+
+#include "common/endian.h"
+
+namespace Kyra {
+
+TIMInterpreter::TIMInterpreter(KyraEngine *vm, OSystem *system) : _vm(vm), _system(system), _currentTim(0) {
+#define COMMAND(x) { &TIMInterpreter::x, #x }
+#define COMMAND_UNIMPL() { 0, 0 }
+	static CommandEntry commandProcs[] = {
+		// 0x00
+		COMMAND(cmd_restartFunc0),
+		COMMAND(cmd_stopCurFunc),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		// 0x04
+		COMMAND(cmd_initFunc),
+		COMMAND(cmd_stopFunc),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		// 0x08
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		// 0x0C
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		// 0x10
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		// 0x14
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND_UNIMPL(),
+		COMMAND(cmd_resetAllNextTime),
+		// 0x18
+		COMMAND(cmd_return<1>),
+		COMMAND(cmd_execOpcode),
+		COMMAND(cmd_initFuncNow),
+		COMMAND(cmd_stopFuncNow),
+		// 0x1C
+		COMMAND(cmd_return<1>),
+		COMMAND(cmd_return<1>),
+		COMMAND(cmd_return<-1>)
+	};
+
+	_commands = commandProcs;
+	_commandsSize = ARRAYSIZE(commandProcs);
+}
+
+TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes) {
+	ScriptFileParser file(filename, _vm->resource());
+	if (!file)
+		error("Couldn't open TIM file '%s'", filename);
+
+	uint32 formBlockSize = file.getFORMBlockSize();
+	if (formBlockSize == 0xFFFFFFFF) {
+		warning("No FORM chunk found in TIM file '%s'", filename);
+		return 0;
+	}
+
+	if (formBlockSize < 20) {
+		warning("TIM file '%s' FORM chunk size smaller than 20", filename);
+		return 0;
+	}
+
+	TIM *tim = new TIM;
+	assert(tim);
+	memset(tim, 0, sizeof(TIM));
+
+	tim->procFunc = -1;
+	tim->opcodes = opcodes;
+
+	uint32 avtlChunkSize = file.getIFFBlockSize(AVTL_CHUNK);
+	uint32 textChunkSize = file.getIFFBlockSize(TEXT_CHUNK);
+
+	tim->avtl = new uint16[avtlChunkSize/2];
+	if (textChunkSize != 0xFFFFFFFF)
+		tim->text = new byte[textChunkSize];
+
+	if (!file.loadIFFBlock(AVTL_CHUNK, tim->avtl, avtlChunkSize))
+		error("Couldn't read AVTL chunk in TIM file '%s'", filename);
+	if (textChunkSize != 0xFFFFFFFF && !file.loadIFFBlock(TEXT_CHUNK, tim->text, textChunkSize))
+		error("Couldn't read TEXT chunk in TIM file '%s'", filename);
+
+	avtlChunkSize >>= 1;
+	for (uint i = 0; i < avtlChunkSize; ++i)
+		tim->avtl[i] = READ_LE_UINT16(tim->avtl + i);
+	
+	for (int i = 0; i < 10; ++i)
+		tim->func[i].avtl = tim->avtl + tim->avtl[i];	
+
+	return tim;
+}
+
+void TIMInterpreter::unload(TIM *&tim) const {
+	if (!tim)
+		return;
+
+	delete [] tim->text;
+	delete [] tim->avtl;
+	delete tim;
+	tim = 0;
+}
+
+void TIMInterpreter::exec(TIM *tim, bool loop) {
+	if (!tim)
+		return;
+
+	_currentTim = tim;
+	if (!_currentTim->func[0].ip) {
+		_currentTim->func[0].ip = _currentTim->func[0].avtl;
+		_currentTim->func[0].nextTime = _currentTim->func[0].lastTime = _system->getMillis();
+	}
+
+	do {
+		for (_currentFunc = 0; _currentFunc < 10; ++_currentFunc) {
+			TIM::Function &cur = _currentTim->func[_currentFunc];
+
+			if (_currentTim->procFunc != -1)
+				execCommand(28, &_currentTim->unkFlag);
+
+			bool running = true;
+			while (cur.ip && cur.nextTime <= _system->getMillis() && running) {
+				int8 opcode = int8(cur.ip[2] & 0xFF);
+
+				switch (execCommand(opcode, cur.ip + 3)) {
+				case -1:
+					loop = false;
+					running = false;
+					_currentFunc = 11;
+					break;
+
+				case -2:
+					running = false;
+					break;
+
+				case -3:
+					_currentTim->procFunc = _currentFunc;
+					break;
+
+				default:
+					break;
+				}
+
+				if (cur.ip) {
+					cur.ip += cur.ip[0];
+					cur.lastTime = cur.nextTime;
+					cur.nextTime += cur.ip[1] * _vm->tickLength();
+				}
+			}
+		}
+	} while (loop);
+}
+
+int TIMInterpreter::execCommand(int cmd, const uint16 *param) {
+	if (cmd < 0 || cmd >= _commandsSize) {
+		warning("Calling unimplemented TIM command %d", cmd);
+		return 0;
+	}
+
+	if (_commands[cmd].proc == 0) {
+		warning("Calling unimplemented TIM command %d", cmd);
+		return 0;
+	}
+
+	debugC(5, kDebugLevelScript, "TIMInterpreter::%s(%p)", _commands[cmd].desc, (const void*)param);
+	return (this->*_commands[cmd].proc)(param);
+}
+
+int TIMInterpreter::cmd_restartFunc0(const uint16 *param) {
+	_currentTim->func[0].ip = _currentTim->func[0].avtl;
+	_currentTim->func[0].lastTime = _system->getMillis();
+	return 1;
+}
+
+int TIMInterpreter::cmd_stopCurFunc(const uint16 *param) {
+	if (_currentFunc < 10)
+		_currentTim->func[_currentFunc].ip = 0;
+	if (!_currentFunc)
+		_finished = true;
+	return -2;
+}
+
+int TIMInterpreter::cmd_initFunc(const uint16 *param) {
+	uint16 func = *param;
+	if (_currentTim->func[func].avtl)
+		_currentTim->func[func].ip = _currentTim->func[func].avtl;
+	else
+		_currentTim->func[func].avtl = _currentTim->func[func].ip = _currentTim->avtl + _currentTim->avtl[func];
+	return 1;
+}
+
+int TIMInterpreter::cmd_stopFunc(const uint16 *param) {
+	uint16 func = *param;
+	_currentTim->func[func].ip = 0;
+	return 1;
+}
+
+int TIMInterpreter::cmd_resetAllNextTime(const uint16 *param) {
+	for (int i = 0; i < 10; ++i) {
+		if (_currentTim->func[i].ip)
+			_currentTim->func[i].nextTime = _system->getMillis();
+	}
+	return 1;
+}
+
+int TIMInterpreter::cmd_execOpcode(const uint16 *param) {
+	if (!_currentTim->opcodes) {
+		warning("Trying to execute TIM opcode without opcode list");
+		return 0;
+	}
+
+	uint16 opcode = *param++;
+	if (opcode > _currentTim->opcodes->size()) {
+		warning("calling unimplemented opcode(0x%.02X/%d)", opcode, opcode);
+		return 0;
+	}
+
+	return (*(*_currentTim->opcodes)[opcode])(_currentTim, param);
+}
+
+int TIMInterpreter::cmd_initFuncNow(const uint16 *param) {
+	uint16 func = *param;
+	_currentTim->func[func].ip = _currentTim->func[func].avtl;
+	_currentTim->func[func].lastTime = _currentTim->func[func].nextTime = _system->getMillis();
+	return 1;
+}
+
+int TIMInterpreter::cmd_stopFuncNow(const uint16 *param) {
+	uint16 func = *param;
+	_currentTim->func[func].ip = 0;
+	_currentTim->func[func].lastTime = _currentTim->func[func].nextTime = _system->getMillis();
+	return 1;
+}
+
+} // end of namespace Kyra
+


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

Added: scummvm/trunk/engines/kyra/script_tim.h
===================================================================
--- scummvm/trunk/engines/kyra/script_tim.h	                        (rev 0)
+++ scummvm/trunk/engines/kyra/script_tim.h	2008-04-19 13:52:09 UTC (rev 31569)
@@ -0,0 +1,104 @@
+/* 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$
+ *
+ */
+
+#ifndef KYRA_SCRIPT_TIM_H
+#define KYRA_SCRIPT_TIM_H
+
+#include "kyra/kyra.h"
+#include "kyra/util.h"
+
+#include "common/array.h"
+
+namespace Kyra {
+
+struct TIM {
+	int16 procFunc;
+	uint16 unkFlag;
+
+	struct Function {
+		const uint16 *ip;
+
+		uint32 lastTime;
+		uint32 nextTime;
+
+		const uint16 *avtl;
+	} func[10];
+
+	uint16 *avtl;
+	uint8 *text;
+
+	const Common::Array<const TIMOpcode*> *opcodes;
+};
+
+class TIMInterpreter {
+public:
+	TIMInterpreter(KyraEngine *vm, OSystem *system);
+
+	TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes);
+	void unload(TIM *&tim) const;
+
+	void resetFinishedFlag() { _finished = false; }
+	bool finished() const { return _finished; }
+
+	void exec(TIM *tim, bool loop);
+	void stopCurFunc() { if (_currentTim) cmd_stopCurFunc(0); }
+
+	void play(const char *filename);
+private:
+	KyraEngine *_vm;
+	OSystem *_system;
+
+	TIM *_currentTim;
+	int _currentFunc;
+
+	bool _finished;
+	
+	int execCommand(int cmd, const uint16 *param);
+
+	typedef int (TIMInterpreter::*CommandProc)(const uint16 *);
+	struct CommandEntry {
+		CommandProc proc;
+		const char *desc;
+	};
+
+	const CommandEntry *_commands;
+	int _commandsSize;
+
+	int cmd_restartFunc0(const uint16 *param);
+	int cmd_stopCurFunc(const uint16 *param);
+	int cmd_initFunc(const uint16 *param);
+	int cmd_stopFunc(const uint16 *param);
+	int cmd_resetAllNextTime(const uint16 *param);
+	int cmd_execOpcode(const uint16 *param);
+	int cmd_initFuncNow(const uint16 *param);
+	int cmd_stopFuncNow(const uint16 *param);
+	template<int T>
+	int cmd_return(const uint16 *) { return T; }
+};
+
+} // end of namespace Kyra
+
+#endif
+


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

Modified: scummvm/trunk/engines/kyra/script_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_v2.cpp	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/script_v2.cpp	2008-04-19 13:52:09 UTC (rev 31569)
@@ -28,6 +28,7 @@
 #include "kyra/wsamovie.h"
 #include "kyra/sound.h"
 #include "kyra/timer.h"
+#include "kyra/script_tim.h"
 
 #include "common/endian.h"
 
@@ -1426,7 +1427,7 @@
 
 int KyraEngine_v2::o2_playTimSequence(ScriptState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_playTimSequence(%p) ('%s')", (const void *)script, stackPosString(0));
-	tim_playFullSequence(stackPosString(0));
+	playTim(stackPosString(0));
 	return 0;
 }
 
@@ -1833,9 +1834,52 @@
 
 #pragma mark -
 
+int KyraEngine_v2::t2_initChat(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_initChat(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
+	_chatText = (const char*)tim->text + READ_LE_UINT16(tim->text + (param[0] << 1));
+	_chatObject = param[1];
+
+	if (_flags.lang == Common::JA_JPN) {
+		for (int i = 0; i < _ingameTimJpStrSize; i += 2) {
+			if (!scumm_stricmp(_chatText, _ingameTimJpStr[i]))
+				_chatText = _ingameTimJpStr[i + 1];
+		}
+	}
+
+	objectChatInit(_chatText, _chatObject);
+	return 0;
+}
+
+int KyraEngine_v2::t2_updateSceneAnim(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_updateSceneAnim(%p, %p) (%d, %d)", (const void*)tim, (const void*)param, param[0], param[1]);
+	updateSceneAnim(param[1], param[0]);
+	return 0;
+}
+
+int KyraEngine_v2::t2_resetChat(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_resetChat(%p, %p) ()", (const void*)tim, (const void*)param);
+	_text->restoreScreen();
+	_chatText = 0;
+	_chatObject = -1;
+	return 0;
+}
+
+int KyraEngine_v2::t2_playSoundEffect(const TIM *tim, const uint16 *param) {
+	debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::t2_playSoundEffect(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
+	snd_playSoundEffect(*param);
+	return 0;
+}
+
+#pragma mark -
+
 typedef Functor1Mem<ScriptState*, int, KyraEngine_v2> OpcodeV2;
 #define Opcode(x) OpcodeV2(this, &KyraEngine_v2::x)
 #define OpcodeUnImpl() OpcodeV2(this, 0)
+
+typedef Functor2Mem<const TIM*, const uint16*, int, KyraEngine_v2> TIMOpcodeV2;
+#define OpcodeTim(x) TIMOpcodeV2(this, &KyraEngine_v2::x)
+#define OpcodeTimUnImpl() TIMOpcodeV2(this, 0)
+
 void KyraEngine_v2::setupOpcodeTable() {
 	static const OpcodeV2 opcodeTable[] = {
 		// 0x00
@@ -2075,6 +2119,16 @@
 
 	for (int i = 0; i < ARRAYSIZE(opcodeTemporaryTable); ++i)
 		_opcodesTemporary.push_back(&opcodeTemporaryTable[i]);
+
+	static const TIMOpcodeV2 timOpcodeTable[] = {
+		OpcodeTim(t2_initChat),
+		OpcodeTim(t2_updateSceneAnim),
+		OpcodeTim(t2_resetChat),
+		OpcodeTim(t2_playSoundEffect)
+	};
+
+	for (int i = 0; i <  ARRAYSIZE(timOpcodeTable); ++i)
+		_timOpcodes.push_back(&timOpcodeTable[i]);
 }
 
 } // end of namespace Kyra

Deleted: scummvm/trunk/engines/kyra/sequences_tim.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sequences_tim.cpp	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/sequences_tim.cpp	2008-04-19 13:52:09 UTC (rev 31569)
@@ -1,335 +0,0 @@
-/* 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 "kyra/text_v2.h"
-#include "kyra/kyra_v2.h"
-#include "kyra/sound.h"
-#include "kyra/resource.h"
-
-#include "common/endian.h"
-
-namespace Kyra {
-
-uint8 *KyraEngine_v2::tim_loadFile(const char *filename, byte *buffer, int32 bufferSize) {
-	ScriptFileParser file(filename, _res);
-	if (!file) {
-		error("Couldn't open script file '%s'", filename);
-		return NULL;
-	}
-
-	int32 formBlockSize = file.getFORMBlockSize();
-	if (formBlockSize == -1) {
-		error("No FORM chunk found in file: '%s'", filename);
-		return NULL;
-	}
-
-	if (formBlockSize < 20) {
-		return NULL;
-	}
-
-	formBlockSize += sizeof(TIMHeader) +  10 * (sizeof(Cmds) + 120);
-
-	TIMHeader *timHeader;
-	if (buffer == NULL || bufferSize < formBlockSize) {
-		buffer = new byte[formBlockSize];
-		timHeader = (TIMHeader *)buffer;
-		timHeader->deleteBufferFlag = 0xBABE;
-	} else {
-		timHeader = (TIMHeader *)buffer;
-		timHeader->deleteBufferFlag = 0x0;
-	}
-
-	int32 chunkSize = file.getIFFBlockSize(AVTL_CHUNK);
-	timHeader->unkFlag = -1;
-	timHeader->unkFlag2 = 0;
-	timHeader->cmdsOffset = sizeof(TIMHeader);
-	timHeader->unkOffset2 = timHeader->cmdsOffset + 10 * sizeof(Cmds);
-	timHeader->AVTLOffset = timHeader->unkOffset2 + 120;
-	timHeader->TEXTOffset = timHeader->AVTLOffset + chunkSize;
-
-	_TIMBuffers.AVTLChunk = buffer + timHeader->AVTLOffset;
-	_TIMBuffers.TEXTChunk = buffer + timHeader->TEXTOffset;
-
-	if (!file.loadIFFBlock(AVTL_CHUNK, _TIMBuffers.AVTLChunk, chunkSize)) {
-		error("Couldn't load AVTL chunk from file: '%s'", filename);
-		return NULL;
-	}
-
-	_TIMBuffers.currentCommandSet = (Cmds *)(buffer + timHeader->cmdsOffset);
-
-	for (int i = 0; i < 10; i++) {
-		_TIMBuffers.currentCommandSet[i].dataPtr = 0;
-		_TIMBuffers.currentCommandSet[i].unk_2 = 0;
-		_TIMBuffers.currentCommandSet[i].AVTLSubChunk = &_TIMBuffers.AVTLChunk[READ_LE_UINT16(&_TIMBuffers.AVTLChunk[i << 1]) << 1];
-		_TIMBuffers.currentCommandSet[i].timer1 = 0;
-		_TIMBuffers.currentCommandSet[i].timer2 = 0;
-	}
-
-	chunkSize = file.getIFFBlockSize(TEXT_CHUNK);
-	if (chunkSize > 0) {
-		if (!file.loadIFFBlock(TEXT_CHUNK, _TIMBuffers.TEXTChunk, chunkSize)) {
-			error("Couldn't load TEXT chunk from file: '%s'", filename);
-			return NULL;
-		}
-	}
-
-	return buffer;
-}
-
-void KyraEngine_v2::tim_releaseBuffer(byte *buffer) {
-	TIMHeader *timHeader = (TIMHeader *)buffer;
-	if (timHeader->deleteBufferFlag == 0xBABE)
-		delete[] buffer;
-}
-
-void KyraEngine_v2::tim_processSequence(uint8 *timBuffer, int loop) {
-	if (!timBuffer)
-		return;
-
-	TIMHeader *hdr = (TIMHeader*) timBuffer;
-	_TIMBuffers.offsUnkFlag = (uint8*) &hdr->unkFlag;
-	_TIMBuffers.offsUnkFlag2 = (uint8*) &hdr->unkFlag2;
-	_TIMBuffers.currentCommandSet = (Cmds*) (timBuffer + hdr->cmdsOffset);
-	_TIMBuffers.unkCmds = timBuffer + hdr->unkOffset2;
-	_TIMBuffers.AVTLChunk = timBuffer + hdr->AVTLOffset;
-	_TIMBuffers.TEXTChunk = timBuffer + hdr->TEXTOffset;
-
-	if (!_TIMBuffers.currentCommandSet->dataPtr) {
-		_TIMBuffers.currentCommandSet->dataPtr = _TIMBuffers.currentCommandSet->AVTLSubChunk;
-		_TIMBuffers.currentCommandSet->timer1 = _system->getMillis();
-		_TIMBuffers.currentCommandSet->timer2 = _system->getMillis();
-	}
-
-	do {
-		_TIMBuffers.currentEntry = 0;
-
-		while (_TIMBuffers.currentEntry < 10) {
-			Cmds *s = &_TIMBuffers.currentCommandSet[_TIMBuffers.currentEntry];
-			if ((int16)READ_LE_UINT16(_TIMBuffers.offsUnkFlag) !=  -1)
-				(this->*_timOpcodes[28])(_TIMBuffers.offsUnkFlag2);
-
-			bool running = true;
-
-			while (s->dataPtr && s->timer2 <= _system->getMillis() && running) {
-				uint8 cmd = s->dataPtr[4];
-				hdr->unkFlag2 = cmd;
-				uint8 *para = &s->dataPtr[6];
-
-				switch((this->*_timOpcodes[cmd])(para)) {
-					case -3:
-						WRITE_LE_UINT16(_TIMBuffers.offsUnkFlag, _TIMBuffers.currentEntry);
-						_TIMBuffers.unk_12 = -1;
-						break;
-
-					case -2:
-						running = false;
-						break;
-
-					case -1:
-						loop = 0;
-						running = false;
-						_TIMBuffers.currentEntry = 11;
-						break;
-
-					case 22:
-						s->backupPtr = 0;
-						break;
-
-					default:
-						break;
-				}
-
-				if (s) {
-					if (s->dataPtr) {
-						s->dataPtr += (READ_LE_UINT16(s->dataPtr) * 2);
-						s->timer1 = s->timer2;
-						s->timer2 += (READ_LE_UINT16(s->dataPtr + 2) * _tickLength);
-					}
-				}
-			}
-
-			_TIMBuffers.currentEntry++;
-		}
-	} while (loop);
-
-}
-
-void KyraEngine_v2::tim_playFullSequence(const char *filename) {
-	uint8 *ptr = tim_loadFile(filename, 0, 0);
-	if (!ptr)
-		return;
-
-	_objectChatFinished = 0;
-
-	while (ptr && !_objectChatFinished) {
-		if (ptr)
-			tim_processSequence(ptr, 0);
-		if (_timChatText)
-			updateWithText();
-		else
-			update();
-	}
-
-	if (ptr)
-		tim_releaseBuffer(ptr);
-}
-
-int KyraEngine_v2::tim_o_dummy_r0(uint8 *ptr) {
-	return 0;
-}
-
-int KyraEngine_v2::tim_o_dummy_r1(uint8 *ptr) {
-	return 1;
-}
-
-int KyraEngine_v2::tim_o_clearCmds2(uint8 *ptr) {
-	for (int i = 1; i < 10; i++)
-		memset(&_TIMBuffers.unkCmds[i], 0, 12);
-	_TIMBuffers.currentCommandSet[0].dataPtr = _TIMBuffers.currentCommandSet[0].AVTLSubChunk;
-	_TIMBuffers.currentCommandSet[0].timer1 = _system->getMillis();
-	return 1;
-}
-
-int KyraEngine_v2::tim_o_abort(uint8 *ptr) {
-	_TIMBuffers.currentCommandSet[_TIMBuffers.currentEntry].dataPtr = 0;
-	if(!_TIMBuffers.currentEntry)
-		_objectChatFinished = true;
-	return -2;
-}
-
-
-int KyraEngine_v2::tim_o_selectcurrentCommandSet(uint8 *ptr) {
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].AVTLSubChunk ?
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].AVTLSubChunk : &_TIMBuffers.AVTLChunk[_TIMBuffers.AVTLChunk[READ_LE_UINT16(ptr) << 1] << 1];
-	return 1;
-}
-
-int KyraEngine_v2::tim_o_deleteBuffer(uint8 *ptr) {
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = 0;
-	return 1;
-}
-
-int KyraEngine_v2::tim_o_refreshTimers(uint8 *ptr) {
-	for (int i = 1; i < 10; i++) {
-		if (_TIMBuffers.currentCommandSet[i].dataPtr)
-			_TIMBuffers.currentCommandSet[i].timer2 = _system->getMillis();
-	}
-
-	return 1;
-}
-
-int KyraEngine_v2::tim_o_execSubOpcode(uint8 *ptr) {
-	return (this->*_timOpcodes[30 + READ_LE_UINT16(ptr)])(ptr + 2);
-}
-
-int KyraEngine_v2::tim_o_initActiveSub(uint8 *ptr) {
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].AVTLSubChunk;
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer1 = _TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer2 = _system->getMillis();
-	return 1;
-}
-
-int KyraEngine_v2::tim_o_resetActiveSub(uint8 *ptr) {
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].dataPtr = 0;
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer2 = 0;
-	_TIMBuffers.currentCommandSet[READ_LE_UINT16(ptr)].timer1 = 0;
-	return 1;
-}
-
-int KyraEngine_v2::tim_o_printTalkText(uint8 *ptr) {
-	_chatText = _timChatText = (const char*) _TIMBuffers.TEXTChunk + READ_LE_UINT16(_TIMBuffers.TEXTChunk + (READ_LE_UINT16(ptr) << 1));
-	_chatObject = _timChatObject = READ_LE_UINT16(ptr + 2);
-
-	if (_flags.lang == Common::JA_JPN) {
-		for (int i = 0; i < _ingameTimJpStrSize; i += 2) {
-			if (!scumm_stricmp(_timChatText, _ingameTimJpStr[i]))
-				_chatText = _ingameTimJpStr[i + 1];
-		}
-	}
-	objectChatInit(_chatText, _timChatObject);
-	return 0;
-}
-
-int KyraEngine_v2::tim_o_updateSceneAnim(uint8 *ptr) {
-	updateSceneAnim(READ_LE_UINT16(ptr + 2), READ_LE_UINT16(ptr));
-	return 0;
-}
-
-int KyraEngine_v2::tim_o_resetChat(uint8 *ptr) {
-	_text->restoreScreen();
-	_chatText = 0;
-	_chatObject = -1;
-	_timChatText = 0;
-	_timChatObject = -1;
-	return 0;
-}
-
-int KyraEngine_v2::tim_o_playSoundEffect(uint8 *ptr) {
-	snd_playSoundEffect(READ_LE_UINT16(ptr));
-	return 0;
-}
-
-void KyraEngine_v2::tim_setupOpcodes() {
-	static const TimOpc Opcodes[] = {
-		&KyraEngine_v2::tim_o_clearCmds2,
-		&KyraEngine_v2::tim_o_abort,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_selectcurrentCommandSet,
-		&KyraEngine_v2::tim_o_deleteBuffer,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_dummy_r0,
-		&KyraEngine_v2::tim_o_refreshTimers,
-		&KyraEngine_v2::tim_o_dummy_r1,
-		&KyraEngine_v2::tim_o_execSubOpcode,
-		&KyraEngine_v2::tim_o_initActiveSub,
-		&KyraEngine_v2::tim_o_resetActiveSub,
-		&KyraEngine_v2::tim_o_dummy_r1,
-		&KyraEngine_v2::tim_o_dummy_r1,
-		&KyraEngine_v2::tim_o_printTalkText,
-		&KyraEngine_v2::tim_o_updateSceneAnim,
-		&KyraEngine_v2::tim_o_resetChat,
-		&KyraEngine_v2::tim_o_playSoundEffect,
-	};
-
-	_timOpcodes = (const TimOpc*) Opcodes;
-}
-
-} // end of namespace Kyra
-

Modified: scummvm/trunk/engines/kyra/text_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/text_v2.cpp	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/text_v2.cpp	2008-04-19 13:52:09 UTC (rev 31569)
@@ -25,6 +25,7 @@
 
 #include "kyra/text_v2.h"
 #include "kyra/kyra_v2.h"
+#include "kyra/script_tim.h"
 #include "kyra/resource.h"
 
 #include "common/endian.h"
@@ -574,13 +575,13 @@
 	strcpy(_TLKFilename, object.filename);
 	strcpy(ENDFilename, object.filename);
 
-	strcpy(STAFilename + 4, "_STA.TIM");
-	strcpy(_TLKFilename + 4, "_TLK.TIM");
-	strcpy(ENDFilename + 4, "_END.TIM");
+	strcat(STAFilename + 4, "_STA.TIM");
+	strcat(_TLKFilename + 4, "_TLK.TIM");
+	strcat(ENDFilename + 4, "_END.TIM");
 
-	_currentTalkSections.STATim = tim_loadFile(STAFilename, NULL, 0);
-	_currentTalkSections.TLKTim = tim_loadFile(_TLKFilename, NULL, 0);
-	_currentTalkSections.ENDTim = tim_loadFile(ENDFilename, NULL, 0);
+	_currentTalkSections.STATim = _tim->load(STAFilename, &_timOpcodes);
+	_currentTalkSections.TLKTim = _tim->load(_TLKFilename, &_timOpcodes);
+	_currentTalkSections.ENDTim = _tim->load(ENDFilename, &_timOpcodes);
 
 	if (object.scriptId != -1) {
 		_specialSceneScriptStateBackup[object.scriptId] = _specialSceneScriptState[object.scriptId];
@@ -588,13 +589,14 @@
 	}
 
 	if (_currentTalkSections.STATim) {
-		_objectChatFinished = false;
-		while (!_objectChatFinished) {
-			tim_processSequence(_currentTalkSections.STATim, 0);
+		_tim->resetFinishedFlag();
+		while (!_quitFlag && !_tim->finished()) {
+			_tim->exec(_currentTalkSections.STATim, false);
 			if (_chatText)
 				updateWithText();
 			else
 				update();
+			delay(10);
 		}
 	}
 }
@@ -603,34 +605,23 @@
 	TalkObject &object = _talkObjectList[index];
 
 	if (_currentTalkSections.ENDTim) {
-		_objectChatFinished = false;
-		while (!_objectChatFinished) {
-			tim_processSequence(_currentTalkSections.ENDTim, 0);
+		_tim->resetFinishedFlag();
+		while (!_quitFlag && !_tim->finished()) {
+			_tim->exec(_currentTalkSections.ENDTim, false);
 			if (_chatText)
 				updateWithText();
 			else
 				update();
+			delay(10);
 		}
 	}
 
-	if (object.scriptId != -1) {
+	if (object.scriptId != -1)
 		_specialSceneScriptState[object.scriptId] = _specialSceneScriptStateBackup[object.scriptId];
-	}
 
-	if (_currentTalkSections.STATim != NULL) {
-		tim_releaseBuffer(_currentTalkSections.STATim);
-		_currentTalkSections.STATim = NULL;
-	}
-
-	if (_currentTalkSections.TLKTim != NULL) {
-		tim_releaseBuffer(_currentTalkSections.TLKTim);
-		_currentTalkSections.TLKTim = NULL;
-	}
-
-	if (_currentTalkSections.ENDTim != NULL) {
-		tim_releaseBuffer(_currentTalkSections.ENDTim);
-		_currentTalkSections.ENDTim = NULL;
-	}
+	_tim->unload(_currentTalkSections.STATim);
+	_tim->unload(_currentTalkSections.TLKTim);
+	_tim->unload(_currentTalkSections.ENDTim);
 }
 
 void KyraEngine_v2::npcChatSequence(const char *str, int objectId, int vocHigh, int vocLow) {
@@ -639,7 +630,7 @@
 	objectChatInit(str, objectId, vocHigh, vocLow);
 
 	if (!_currentTalkSections.TLKTim)
-		_currentTalkSections.TLKTim = tim_loadFile(_TLKFilename, 0, 0);
+		_currentTalkSections.TLKTim = _tim->load(_TLKFilename, &_timOpcodes);
 
 	setNextIdleAnimTimer();
 
@@ -655,29 +646,26 @@
 
 	while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || skipFlag())) {
 		if (!speechEnabled() && chatAnimEndTime > _system->getMillis() || speechEnabled() && snd_voiceIsPlaying()) {
-			_objectChatFinished = false;
-
-			while (!_objectChatFinished && !skipFlag()) {
+			_tim->resetFinishedFlag();
+			while (!_tim->finished() && !skipFlag() && !_quitFlag) {
 				if (_currentTalkSections.TLKTim)
-					tim_processSequence(_currentTalkSections.TLKTim, 0);
+					_tim->exec(_currentTalkSections.TLKTim, false);
 				else
-					_objectChatFinished = false;
+					_tim->resetFinishedFlag();
 
 				updateWithText();
 				delay(10);
 			}
+
 			if (_currentTalkSections.TLKTim)
-				tim_o_abort(0);
+				_tim->stopCurFunc();
 		}
 		updateWithText();
 	}
 
 	resetSkipFlag();
 
-	if (_currentTalkSections.TLKTim) {
-		tim_releaseBuffer(_currentTalkSections.TLKTim);
-		_currentTalkSections.TLKTim = 0;
-	}
+	_tim->unload(_currentTalkSections.TLKTim);
 
 	_text->restoreScreen();
 	_chatText = 0;

Modified: scummvm/trunk/engines/kyra/util.h
===================================================================
--- scummvm/trunk/engines/kyra/util.h	2008-04-19 00:34:02 UTC (rev 31568)
+++ scummvm/trunk/engines/kyra/util.h	2008-04-19 13:52:09 UTC (rev 31569)
@@ -78,10 +78,37 @@
 	Res (T::*_func)(Arg);
 };
 
+template<class Arg1, class Arg2, class Res>
+struct Functor2 : public Common::BinaryFunction<Arg1, Arg2, Res> {
+	virtual ~Functor2() {}
+
+	virtual bool isValid() const = 0;
+	virtual Res operator()(Arg1, Arg2) const = 0;
+};
+
+template<class Arg1, class Arg2, class Res, class T>
+class Functor2Mem : public Functor2<Arg1, Arg2, Res> {
+public:
+	typedef Res (T::*FuncType)(Arg1, Arg2);
+
+	Functor2Mem(T *t, const FuncType &func) : _t(t), _func(func) {}
+
+	bool isValid() const { return _func != 0; }
+	Res operator()(Arg1 v1, Arg2 v2) const {
+		return (_t->*_func)(v1, v2);
+	}
+private:
+	mutable T *_t;
+	Res (T::*_func)(Arg1, Arg2);
+};
+
 struct ScriptState;
-
 typedef Functor1<ScriptState*, int> Opcode;
 
+struct TIM;
+typedef Functor2<const TIM*, const uint16*, int> TIMOpcode;
+
 } // end of namespace Kyra
 
 #endif
+


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