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

athrxx at users.sourceforge.net athrxx at users.sourceforge.net
Sun Feb 17 03:06:05 CET 2008


Revision: 30886
          http://scummvm.svn.sourceforge.net/scummvm/?rev=30886&view=rev
Author:   athrxx
Date:     2008-02-16 18:06:04 -0800 (Sat, 16 Feb 2008)

Log Message:
-----------
committing patch 1891492 : dialogue (dlg/tim) support for HoF

- talking to NPCs is now possible.
- Zanthia's talks when entering a new scene for the first time now work
- using items on Zanthia is now possible.

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/resource.h
    scummvm/trunk/engines/kyra/scene_v2.cpp
    scummvm/trunk/engines/kyra/script_v2.cpp
    scummvm/trunk/engines/kyra/sound.cpp
    scummvm/trunk/engines/kyra/sound.h
    scummvm/trunk/engines/kyra/sound_towns.cpp
    scummvm/trunk/engines/kyra/staticres.cpp
    scummvm/trunk/engines/kyra/text_v2.cpp

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

Modified: scummvm/trunk/engines/kyra/kyra_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v2.cpp	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/kyra_v2.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -86,13 +86,27 @@
 	_chatObject = -1;
 	_lastIdleScript = -1;
 
+	_timChatText = 0;
+	_timChatObject = -1;
+
 	_currentTalkSections.STATim = NULL;
 	_currentTalkSections.TLKTim = NULL;
 	_currentTalkSections.ENDTim = NULL;
 
 	_invWsa.wsa = 0;
 
+	_colorCodeFlag1 = 0;
+	_colorCodeFlag2 = -1;
+
 	memset(&_sceneScriptData, 0, sizeof(_sceneScriptData));
+
+	_dlgBuffer = 0;
+	_conversationState = new int8*[19];
+	for (int i = 0; i < 19; i++)
+		_conversationState[i] = new int8[14];
+	_npcTalkChpIndex = _npcTalkDlgIndex = -1;
+	_mainCharacter.dlgIndex = 0;
+	setNewDlgIndex(-1);
 }
 
 KyraEngine_v2::~KyraEngine_v2() {
@@ -109,6 +123,12 @@
 	_text = 0;
 	delete _debugger;
 	delete _invWsa.wsa;
+
+	if (_dlgBuffer)
+		delete [] _dlgBuffer;
+	for (int i = 0; i < 19; i++)
+		delete [] _conversationState[i];
+	delete [] _conversationState;
 }
 
 Movie *KyraEngine_v2::createWSAMovie() {
@@ -155,6 +175,8 @@
 	if (_flags.isDemo)
 		return 0;
 
+	tim_setupOpcodes();
+
 	_mouseSHPBuf = _res->fileData("PWGMOUSE.SHP", 0);
 	assert(_mouseSHPBuf);
 
@@ -1877,12 +1899,12 @@
 		Opcode(o2_updateSceneAnim),
 		OpcodeUnImpl(),
 		// 0x74
+		Opcode(o2_useItemOnMainChar),
+		Opcode(o2_startDialogue),
 		OpcodeUnImpl(),
-		OpcodeUnImpl(),
-		OpcodeUnImpl(),
-		OpcodeUnImpl(),
+		Opcode(o2_setupDialogue),
 		// 0x78
-		OpcodeUnImpl(),
+		Opcode(o2_getDlgIndex),
 		Opcode(o2_defineRoom),
 		OpcodeUnImpl(),
 		OpcodeUnImpl(),
@@ -1894,18 +1916,18 @@
 		// 0x80
 		Opcode(o2_objectChat),
 		OpcodeUnImpl(),
-		OpcodeUnImpl(),
-		OpcodeUnImpl(),
+		Opcode(o2_getColorCodeFlag1),
+		Opcode(o2_setColorCodeFlag1),
 		// 0x84
+		Opcode(o2_getColorCodeFlag2),
+		Opcode(o2_setColorCodeFlag2),
 		OpcodeUnImpl(),
 		OpcodeUnImpl(),
-		OpcodeUnImpl(),
-		OpcodeUnImpl(),
 		// 0x88
 		Opcode(o2_countItemInstances),
 		OpcodeUnImpl(),
 		Opcode(o2_initObject),
-		OpcodeUnImpl(),
+		Opcode(o2_npcChat),
 		// 0x8c
 		Opcode(o2_deinitObject),
 		OpcodeUnImpl(),
@@ -1972,3 +1994,4 @@
 } // end of namespace Kyra
 
 
+

Modified: scummvm/trunk/engines/kyra/kyra_v2.h
===================================================================
--- scummvm/trunk/engines/kyra/kyra_v2.h	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/kyra_v2.h	2008-02-17 02:06:04 UTC (rev 30886)
@@ -495,6 +495,8 @@
 	void runSceneScript6();
 	void runSceneScript7();
 
+	void sceneStartupChat();
+
 	void initSceneAnims(int unk1);
 	void initSceneScreen(int unk1);
 
@@ -589,7 +591,7 @@
 	// character
 	struct Character {
 		uint16 sceneId;
-		uint16 unk2;
+		uint16 dlgIndex;
 		uint8 height;
 		uint8 facing;
 		uint16 animFrame;
@@ -652,9 +654,101 @@
 	void objectChatPrintText(const char *text, int object);
 	void objectChatProcess(const char *script);
 	void objectChatWaitToFinish();
-	void initTalkObject(int initObject);
-	void deinitTalkObject(int initObject);
 
+	void startDialogue(int dlgIndex);
+	void updateDlgBuffer();
+	void loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2);
+	void processDialogue(int dlgOffset, int vocH = 0, int csEntry = 0);
+	void npcChatSequence(const char *str, int objectId, int vocHigh = -1, int vocLow = -1);
+	void setNewDlgIndex(int dlgIndex);
+
+	int _npcTalkChpIndex;
+	int _npcTalkDlgIndex;
+	uint8 _newSceneDlgState[32];
+	int8 **_conversationState;
+	uint8 _npcTalkUNK;
+	uint8 *_dlgBuffer;
+
+	// 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);
+
+	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);
+
+	typedef int (KyraEngine_v2::*TimOpc)(uint8 *ptr);
+	const TimOpc * _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;
+
+	// Talk object handling
+	void initTalkObject(int index);
+	void deinitTalkObject(int index);
+
+	struct TalkObject {
+		char filename[13];
+		int8 scriptId;
+		int16 x, y;
+		int8 color;
+	};
+	TalkObject *_talkObjectList;
+
+	struct TalkSections {
+		uint8 *STATim;
+		uint8 *TLKTim;
+		uint8 *ENDTim;
+	};
+	TalkSections _currentTalkSections;
+
+	char _TLKFilename[13];
+	bool _objectChatFinished;
+
 	// sound
 	int _oldTalkFile;
 	int _currentTalkFile;
@@ -688,51 +782,6 @@
 	// delay
 	void delay(uint32 millis, bool updateGame = false, bool isMainLoop = false);
 
-	// Talk object handling
-	struct TalkObject {
-		char filename[13];
-		int8 scriptId;
-		int16 x, y;
-		int8 color;
-	};
-	TalkObject *_talkObjectList;
-
-	struct TIMHeader {
-		uint16 deleteBufferFlag;
-		int16 unkFlag;
-		int16 unkFlag2;
-		int16 unkOffset;
-		int16 unkOffset2;
-		int16 AVTLOffset;
-		int16 TEXTOffset;
-	};
-
-	struct TIMStructUnk1 {
-		uint16 unk_0;
-		uint16 unk_2;
-		uint16 unk_4;
-		uint16 unk_8;
-		uint16 *unk_20;
-	};
-
-	struct TIMBuffers {
-		uint16 *AVTLChunk;
-		byte *TEXTChunk;
-		TIMStructUnk1 *UnkChunk;
-	};
-	TIMBuffers _TIMBuffers;
-
-	struct TalkSections {
-		byte *STATim;
-		byte *TLKTim;
-		byte *ENDTim;
-	};
-	TalkSections _currentTalkSections;
-
-	bool _objectChatFinished;
-	byte *loadTIMFile(const char *filename, byte *buffer, int32 bufferSize);
-	void freeTIM(byte *buffer);
-
 	// ingame static sequence handling
 	void seq_makeBookOrCauldronAppear(int type);
 	void seq_makeBookAppear();
@@ -809,10 +858,19 @@
 	int o2_setSpecialSceneScriptRunTime(ScriptState *script);
 	int o2_defineSceneAnim(ScriptState *script);
 	int o2_updateSceneAnim(ScriptState *script);
+	int o2_useItemOnMainChar(ScriptState *script);
+	int o2_startDialogue(ScriptState *script);
+	int o2_setupDialogue(ScriptState *script);
+	int o2_getDlgIndex(ScriptState *script);
 	int o2_defineRoom(ScriptState *script);
 	int o2_objectChat(ScriptState *script);
+	int o2_getColorCodeFlag1(ScriptState *script);
+	int o2_setColorCodeFlag1(ScriptState *script);
+	int o2_getColorCodeFlag2(ScriptState *script);
+	int o2_setColorCodeFlag2(ScriptState *script);
 	int o2_countItemInstances(ScriptState *script);
 	int o2_initObject(ScriptState *script);
+	int o2_npcChat(ScriptState *script);
 	int o2_deinitObject(ScriptState *script);
 	int o2_makeBookOrCauldronAppear(ScriptState *script);
 	int o2_setSpecialSceneScriptState(ScriptState *script);
@@ -896,6 +954,10 @@
 	int _ingameSoundIndexSize;
 	const char *const *_sequenceStrings;
 	int _sequenceStringsSize;
+	const uint16 *_ingameTalkObjIndex;
+	int _ingameTalkObjIndexSize;
+	const char *const *_ingameTimJpStr;
+	int _ingameTimJpStrSize;
 	uint8 *_demoShapeDefs;
 	int _sequenceStringsDuration[33];
 
@@ -919,6 +981,10 @@
 
 	Sequence *_sequences;
 	NestedSequence *_nSequences;
+
+	// these are used whenever the color code has to be entered
+	int _colorCodeFlag1;
+	int _colorCodeFlag2;
 };
 
 } // end of namespace Kyra
@@ -926,3 +992,4 @@
 #endif
 
 
+

Modified: scummvm/trunk/engines/kyra/module.mk
===================================================================
--- scummvm/trunk/engines/kyra/module.mk	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/module.mk	2008-02-17 02:06:04 UTC (rev 30886)
@@ -25,6 +25,7 @@
 	script_v2.o \
 	script.o \
 	seqplayer.o \
+	sequences_tim.o \
 	sequences_v1.o \
 	sequences_v2.o \
 	sound_adlib.o \

Modified: scummvm/trunk/engines/kyra/resource.h
===================================================================
--- scummvm/trunk/engines/kyra/resource.h	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/resource.h	2008-02-17 02:06:04 UTC (rev 30886)
@@ -218,6 +218,8 @@
 	k2IngameSfxIndex,
 	k2IngameTracks,
 	k2IngameCDA,
+	k2IngameTalkObjIndex,
+	k2IngameTimJpStrings,
 
 	kMaxResIDs
 };
@@ -328,3 +330,4 @@
 
 #endif
 
+

Modified: scummvm/trunk/engines/kyra/scene_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/scene_v2.cpp	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/scene_v2.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -243,7 +243,7 @@
 
 	if (!unk1) {
 		runSceneScript4(0);
-		//XXX sub_27158
+		sceneStartupChat();
 	}
 
 	_unk4 = 0;
@@ -499,6 +499,22 @@
 	_screen->_curPage = oldPage;
 }
 
+void KyraEngine_v2::sceneStartupChat() {
+	int tableIndex = _mainCharacter.sceneId - READ_LE_UINT16(&_ingameTalkObjIndex[5 + _newChapterFile]);
+	if (queryGameFlag(0x159) || _newSceneDlgState[tableIndex])
+		return;
+
+	int csEntry, vocH, scIndex1, scIndex2;
+	updateDlgBuffer();
+	loadDlgHeader(csEntry, vocH, scIndex1, scIndex2);
+
+	uint8 bufferIndex = 8 + scIndex1 * 6 + scIndex2 * 4 + tableIndex * 2;
+	int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex);
+	processDialogue(offs, vocH, csEntry);
+
+	_newSceneDlgState[tableIndex] = 1;
+}
+
 void KyraEngine_v2::initSceneAnims(int unk1) {
 	for (int i = 0; i < ARRAYSIZE(_animObjects); ++i)
 		_animObjects[i].enabled = 0;
@@ -908,5 +924,4 @@
 	_screen->fadePalette(_screen->getPalette(0), delayTime, &_updateFunctor);
 }
 
-} // end of namespace Kyra
-
+} // end of namespace Kyra
\ No newline at end of file

Modified: scummvm/trunk/engines/kyra/script_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/script_v2.cpp	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/script_v2.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -622,6 +622,41 @@
 	return 0;
 }
 
+int KyraEngine_v2::o2_useItemOnMainChar(ScriptState *script) {
+	ScriptState tmpScript;
+	_scriptInterpreter->initScript(&tmpScript, &_npcScriptData);
+	_scriptInterpreter->startScript(&tmpScript, 0);
+	tmpScript.regs[4] = _itemInHand;
+	tmpScript.regs[0] = _mainCharacter.sceneId;
+
+	int oldVocH = _vocHigh;
+	_vocHigh = 0x5a;
+
+	while(_scriptInterpreter->validScript(&tmpScript))
+		_scriptInterpreter->runScript(&tmpScript);
+
+	_vocHigh = oldVocH;
+
+	return 0;
+}
+
+int KyraEngine_v2::o2_startDialogue(ScriptState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "o2_startDialogue(%p) (%d)", (const void *)script, stackPos(0));
+	startDialogue(stackPos(0));
+	return 0;
+}
+
+int KyraEngine_v2::o2_setupDialogue(ScriptState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "o2_setupDialogue(%p) (%d)", (const void *)script, stackPos(0));
+	setNewDlgIndex(stackPos(0));
+	return 0;
+}
+
+int KyraEngine_v2::o2_getDlgIndex(ScriptState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "o2_setNewDlgIndex(%p) (%d)", (const void *)script, stackPos(0));
+	return _mainCharacter.dlgIndex;
+}
+
 int KyraEngine_v2::o2_defineRoom(ScriptState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "o2_defineRoom(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)", (const void *)script,
 			stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
@@ -653,6 +688,28 @@
 	return 0;
 }
 
+int KyraEngine_v2::o2_getColorCodeFlag1(ScriptState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag1(%p)", (const void *)script);
+	return _colorCodeFlag1;
+}
+
+int KyraEngine_v2::o2_setColorCodeFlag1(ScriptState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag1(%p) (%d)", (const void *)script, stackPos(0));
+	_colorCodeFlag1 = stackPos(0);
+	return 0;
+}
+
+int KyraEngine_v2::o2_getColorCodeFlag2(ScriptState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag2(%p)", (const void *)script);
+	return _colorCodeFlag2;
+}
+
+int KyraEngine_v2::o2_setColorCodeFlag2(ScriptState *script) {
+	debugC(3, kDebugLevelScriptFuncs, "o2_getColorCodeFlag2(%p) (%d)", (const void *)script, stackPos(0));
+	_colorCodeFlag2 = stackPos(0);
+	return 0;
+}
+
 int KyraEngine_v2::o2_countItemInstances(ScriptState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "o2_countItemInstances(%p) (%d)", (const void *)script, stackPos(0));
 	uint16 item = stackPos(0);
@@ -691,6 +748,17 @@
 	return 0;
 }
 
+int KyraEngine_v2::o2_npcChat(ScriptState *script) {
+	if (_flags.isTalkie) {
+		debugC(3, kDebugLevelScriptFuncs, "o2_npcChat(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), _vocHigh, stackPos(2));
+		npcChatSequence(stackPosString(0), stackPos(1), _vocHigh, stackPos(2));
+	} else {
+		debugC(3, kDebugLevelScriptFuncs, "o2_npcChat(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1));
+		npcChatSequence(stackPosString(0), stackPos(1));
+	}
+	return 0;
+}
+
 int KyraEngine_v2::o2_deinitObject(ScriptState *script) {
 	debugC(3, kDebugLevelScriptFuncs, "o2_deinitObject(%p) (%d)", (const void *)script, stackPos(0));
 	deinitTalkObject(stackPos(0));
@@ -840,3 +908,4 @@
 } // end of namespace Kyra
 
 
+

Added: scummvm/trunk/engines/kyra/sequences_tim.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sequences_tim.cpp	                        (rev 0)
+++ scummvm/trunk/engines/kyra/sequences_tim.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -0,0 +1,315 @@
+/* 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);
+
+}
+
+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(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
+


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

Modified: scummvm/trunk/engines/kyra/sound.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound.cpp	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/sound.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -39,7 +39,7 @@
 namespace Kyra {
 
 Sound::Sound(KyraEngine *vm, Audio::Mixer *mixer)
-	: _vm(vm), _mixer(mixer), _currentVocFile(0), _vocHandle(),
+	: _vm(vm), _mixer(mixer), _currentVocFile(0), _vocHandles(),
 	_musicEnabled(1), _sfxEnabled(true), _soundDataList(0) {
 }
 
@@ -52,6 +52,14 @@
 	bool found = false;
 	char filenamebuffer[25];
 
+	int h = 0;
+	if (_currentVocFile) {
+		while (_mixer->isSoundHandleActive(_vocHandles[h]))
+			h++;
+		if (h >= kNumVocHandles)
+			return;
+	}
+
 	for (int i = 0; _supportedCodes[i].fileext; ++i) {
 		strcpy(filenamebuffer, file);
 		strcat(filenamebuffer, _supportedCodes[i].fileext);
@@ -76,21 +84,26 @@
 		_currentVocFile = Audio::makeVOCStream(vocStream);
 	}
 
-	if (_currentVocFile) {
-		//_mixer->stopHandle(_vocHandle);
-		_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandle, _currentVocFile);
-	}
+	_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_vocHandles[h], _currentVocFile);
+
 	delete [] fileData;
 	fileSize = 0;
 }
 
 void Sound::voiceStop() {
-	if (_mixer->isSoundHandleActive(_vocHandle))
-		_mixer->stopHandle(_vocHandle);
+	for (int h = 0; h < kNumVocHandles; h++) {
+		if (_mixer->isSoundHandleActive(_vocHandles[h]))
+			_mixer->stopHandle(_vocHandles[h]);
+	}
 }
 
 bool Sound::voiceIsPlaying() {
-	return _mixer->isSoundHandleActive(_vocHandle);
+	bool res = false;
+	for (int h = 0; h < kNumVocHandles; h++) {
+		if (_mixer->isSoundHandleActive(_vocHandles[h]))
+			res = true;
+	}
+	return res;
 }
 
 #pragma mark -
@@ -522,3 +535,4 @@
 
 } // end of namespace Kyra
 
+

Modified: scummvm/trunk/engines/kyra/sound.h
===================================================================
--- scummvm/trunk/engines/kyra/sound.h	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/sound.h	2008-02-17 02:06:04 UTC (rev 30886)
@@ -180,6 +180,10 @@
 	const void *cdaData() const { return _soundDataList != 0 ? _soundDataList->_cdaTracks : 0; }
 	const int cdaTrackNum() const { return _soundDataList != 0 ? _soundDataList->_cdaNumTracks : 0; }
 
+	enum {
+		kNumVocHandles = 4
+	};
+
 	int _musicEnabled;
 	bool _sfxEnabled;
 
@@ -191,7 +195,7 @@
 private:
 	const AudioDataStruct *_soundDataList;
 	Audio::AudioStream *_currentVocFile;
-	Audio::SoundHandle _vocHandle;
+	Audio::SoundHandle _vocHandles[kNumVocHandles];
 
 	struct SpeechCodecs {
 		const char *fileext;
@@ -425,10 +429,10 @@
 	int _lastTrack;
 
 	Audio::AudioStream *_currentSFX;
-	Audio::SoundHandle _sfxHandle;
+	Audio::SoundHandle _sfxHandles[kNumVocHandles];
 
-	//SoundTowns_v2_TwnDriver * _driver;
-	uint8 * _twnTrackData;
+	//SoundTowns_v2_TwnDriver *_driver;
+	uint8 *_twnTrackData;
 };
 
 class MixedSoundDriver : public Sound {

Modified: scummvm/trunk/engines/kyra/sound_towns.cpp
===================================================================
--- scummvm/trunk/engines/kyra/sound_towns.cpp	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/sound_towns.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -1435,6 +1435,14 @@
 void SoundTowns_v2::voicePlay(const char *file) {
 	static const uint16 rates[] =	{ 0x10E1, 0x0CA9, 0x0870, 0x0654, 0x0438, 0x032A, 0x021C, 0x0194 };
 
+	int h = 0;
+	if (_currentSFX) {
+		while (_mixer->isSoundHandleActive(_sfxHandles[h]))
+			h++;
+		if (h >= kNumVocHandles)
+			return;
+	}
+
 	uint8 * data = _vm->resource()->fileData(file, 0);
 	uint8 * src = data;
 
@@ -1482,7 +1490,7 @@
 
 	_currentSFX = Audio::makeLinearInputStream(sfx, outsize, outputRate,
 		Audio::Mixer::FLAG_UNSIGNED | Audio::Mixer::FLAG_LITTLE_ENDIAN | Audio::Mixer::FLAG_AUTOFREE, 0, 0);
-	_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandle, _currentSFX);
+	_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_sfxHandles[h], _currentSFX);
 
 	delete [] data;
 }

Modified: scummvm/trunk/engines/kyra/staticres.cpp
===================================================================
--- scummvm/trunk/engines/kyra/staticres.cpp	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/staticres.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -35,7 +35,7 @@
 
 namespace Kyra {
 
-#define RESFILE_VERSION 20
+#define RESFILE_VERSION 21
 
 bool StaticResource::checkKyraDat() {
 	Common::File kyraDat;
@@ -241,10 +241,12 @@
 
 		// Ingame
 		{ k2IngamePakFiles, kStringList, "I_PAKFILES.TXT" },
-		{ k2IngameSfxFiles, kStringList, "I_SFXFILES.TXT" },
-		{ k2IngameSfxIndex, kRawData, "I_SFXINDEX.TRA" },
+		{ k2IngameSfxFiles, kStringList, "I_SFXFILES.TRA" },
+		{ k2IngameSfxIndex, kRawData, "I_SFXINDEX.MAP" },
 		{ k2IngameTracks, kStringList, "I_TRACKS.TRA" },
 		{ k2IngameCDA, kRawData, "I_TRACKS.CDA" },
+		{ k2IngameTalkObjIndex, kRawData, "I_TALKOBJECTS.MAP" },
+		{ k2IngameTimJpStrings, kStringList, "I_TIMJPSTR.TXT" },
 
 		{ 0, 0, 0 }
 	};
@@ -926,6 +928,8 @@
 	_cdaTrackTableIntro = _staticres->loadRawData(k2SeqplayIntroCDA, _cdaTrackTableIntroSize);
 	_cdaTrackTableIngame = _staticres->loadRawData(k2IngameCDA, _cdaTrackTableIngameSize);
 	_cdaTrackTableFinale = _staticres->loadRawData(k2SeqplayFinaleCDA, _cdaTrackTableFinaleSize);
+	_ingameTalkObjIndex = (const uint16*) _staticres->loadRawData(k2IngameTalkObjIndex, _ingameTalkObjIndexSize);
+	_ingameTimJpStr = _staticres->loadStrings(k2IngameTimJpStrings, _ingameTimJpStrSize);
 
 	// replace sequence talkie files with localized versions and cut off .voc
 	// suffix from voc files so as to allow compression specific file extensions
@@ -934,7 +938,7 @@
 	// of _sequenceSoundList instead of casting away const.
 	const char* const* tlkfiles = _staticres->loadStrings(k2SeqplayTlkFiles, tmp);
 	for (int i = 0; i < _sequenceSoundListSize; i++) {
-		uint32 len = strlen(_sequenceSoundList[i]);
+		int len = strlen(_sequenceSoundList[i]);
 		if (_flags.platform == Common::kPlatformPC)
 			len -= 4;
 
@@ -1494,3 +1498,4 @@
 } // End of namespace Kyra
 
 
+

Modified: scummvm/trunk/engines/kyra/text_v2.cpp
===================================================================
--- scummvm/trunk/engines/kyra/text_v2.cpp	2008-02-16 22:33:11 UTC (rev 30885)
+++ scummvm/trunk/engines/kyra/text_v2.cpp	2008-02-17 02:06:04 UTC (rev 30886)
@@ -27,6 +27,8 @@
 #include "kyra/kyra_v2.h"
 #include "kyra/resource.h"
 
+#include "common/endian.h"
+
 namespace Kyra {
 
 TextDisplayer_v2::TextDisplayer_v2(KyraEngine_v2 *vm, Screen_v2 *screen)
@@ -325,7 +327,7 @@
 			}
 
 			const uint32 curTime = _system->getMillis();
-			if ((textEnabled() && curTime > endTime) || (speechEnabled() && !snd_voiceIsPlaying()) || _skipFlag) {
+			if ((textEnabled() && curTime > endTime) || (speechEnabled() && !textEnabled() && !snd_voiceIsPlaying()) || _skipFlag) {
 				_skipFlag = false;
 				nextFrame = curTime;
 				running = false;
@@ -340,150 +342,308 @@
 	resetCharacterAnimDim();
 }
 
-void KyraEngine_v2::initTalkObject(int initObject) {
-	TalkObject &object = _talkObjectList[initObject];
+void KyraEngine_v2::startDialogue(int dlgIndex) {
+	updateDlgBuffer();
+	int csEntry, vocH, unused1, unused2;
+	loadDlgHeader(csEntry, vocH, unused1, unused2);
+	int s = _conversationState[dlgIndex][csEntry];
+	uint8 bufferIndex = 8;
 
+	if (s == -1) {
+		bufferIndex += (dlgIndex * 6);
+		_conversationState[dlgIndex][csEntry] = 0;
+	} else if (!s || s == 2) {
+		bufferIndex += (dlgIndex * 6 + 2);
+		_conversationState[dlgIndex][csEntry] = 1;
+	} else {
+		bufferIndex += (dlgIndex * 6 + 4);
+		_conversationState[dlgIndex][csEntry] = 2;
+	}
+
+	int offs = READ_LE_UINT16(_dlgBuffer + bufferIndex);
+	processDialogue(offs, vocH, csEntry);
+}
+
+void KyraEngine_v2::updateDlgBuffer() {
+	static const char DlgFileTemplate[] = "CH**-S**.DLG";
+	char filename[13];
+	filename[12] = 0;
+	memcpy(filename, DlgFileTemplate, 12);
+
+	static const char suffixTalkie[] = "EFG";
+	static const char suffixTowns[] = "G  J";
+	const char * suffix = _flags.isTalkie ? suffixTalkie : suffixTowns;
+
+	filename[2] = (char)((_currentChapter / 10 + 48) & 0xFF);
+	filename[3] = (char)((_currentChapter % 10 + 48) & 0xFF);
+
+	if (!(_flags.platform == Common::kPlatformPC && !_flags.isTalkie))
+		filename[11] = suffix[_lang];
+
+	if (_currentChapter == _npcTalkChpIndex && _mainCharacter.dlgIndex == _npcTalkDlgIndex)
+		return;
+
+	_npcTalkChpIndex = _currentChapter;
+	_npcTalkDlgIndex = _mainCharacter.dlgIndex;
+
+	filename[6] = (char)((_npcTalkDlgIndex / 10 + 48) & 0xFF);
+	filename[7] = (char)((_npcTalkDlgIndex % 10 + 48) & 0xFF);
+
+	if (_dlgBuffer)
+		delete [] _dlgBuffer;
+
+	_dlgBuffer = _res->fileData(filename, 0);
+}
+
+void KyraEngine_v2::loadDlgHeader(int &csEntry, int &vocH, int &scIndex1, int &scIndex2) {
+	csEntry = READ_LE_UINT16(_dlgBuffer);
+	vocH = READ_LE_UINT16(_dlgBuffer + 2);
+	scIndex1 = READ_LE_UINT16(_dlgBuffer + 4);
+	scIndex2 = READ_LE_UINT16(_dlgBuffer + 6);
+}
+
+void KyraEngine_v2::processDialogue(int dlgOffset, int vocH, int csEntry) {
+	int activeTimSequence = -1;
+	int nextTimSequence = -1;
+	int cmd = 0;
+	int vocHi = -1;
+	int vocLo = -1;
+	bool loop = true;
+	int offs = dlgOffset;
+
+	_screen->hideMouse();
+
+	while (loop) {
+		cmd = READ_LE_UINT16(_dlgBuffer + offs);
+		offs += 2;
+
+		nextTimSequence = READ_LE_UINT16(&_ingameTalkObjIndex[cmd]);
+
+		if (nextTimSequence == 10) {
+			if (queryGameFlag(0x3e))
+				nextTimSequence = 14;
+			if (queryGameFlag(0x3f))
+				nextTimSequence = 15;
+			if (queryGameFlag(0x40))
+				nextTimSequence = 16;
+		}
+
+		if (nextTimSequence == 27 && _mainCharacter.sceneId == 34)
+			nextTimSequence = 41;
+
+		if (queryGameFlag(0x72)) {
+			if (nextTimSequence == 18)
+				nextTimSequence = 43;
+			else if (nextTimSequence == 19)
+				nextTimSequence = 44;
+		}
+
+		if (_mainCharacter.x1 > 160) {
+			if (nextTimSequence == 4)
+				nextTimSequence = 46;
+			else if (nextTimSequence == 5)
+				nextTimSequence = 47;
+		}
+
+		if (cmd == 10) {
+			loop = false;
+
+		} else if (cmd == 4) {
+			csEntry = READ_LE_UINT16(_dlgBuffer + offs);
+			setNewDlgIndex(csEntry);
+			offs += 2;
+
+		} else {
+			if (!_flags.isTalkie || cmd == 11) {
+				int len = READ_LE_UINT16(_dlgBuffer + offs);
+				offs += 2;
+				if (_flags.isTalkie) {
+					vocLo = READ_LE_UINT16(_dlgBuffer + offs);
+					offs += 2;
+				}
+				memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len);
+				_unkBuf500Bytes[len] = 0;
+				offs += len;
+				if (_flags.isTalkie)
+					continue;
+
+			} else if (_flags.isTalkie) {
+				int len = READ_LE_UINT16(_dlgBuffer + offs);
+				offs += 2;
+				static const int irnv[] = { 91, 105, 110, 114, 118 };
+				vocHi = irnv[vocH - 1] + csEntry;
+				vocLo = READ_LE_UINT16(_dlgBuffer + offs);
+				offs += 2;
+				memcpy(_unkBuf500Bytes, _dlgBuffer + offs, len);
+				_unkBuf500Bytes[len] = 0;
+				offs += len;
+			}
+
+			if (_unkBuf500Bytes[0]) {
+				if ((!_flags.isTalkie && cmd == 11) || (_flags.isTalkie && cmd == 12)) {
+					if (activeTimSequence > -1) {
+						deinitTalkObject(activeTimSequence);
+						activeTimSequence = -1;
+					}
+					objectChat((const char*) _unkBuf500Bytes, 0, vocHi, vocLo);
+				} else {
+					if (activeTimSequence != nextTimSequence ) {
+						if (activeTimSequence > -1) {
+							deinitTalkObject(activeTimSequence);
+							activeTimSequence = -1;
+						}
+						initTalkObject(nextTimSequence);
+						activeTimSequence = nextTimSequence;
+					}
+					npcChatSequence((const char *)_unkBuf500Bytes, nextTimSequence, vocHi, vocLo);
+				}
+			}
+		}
+	}
+
+	if (activeTimSequence > -1)
+		deinitTalkObject(activeTimSequence);
+
+	_screen->showMouse();
+}
+
+void KyraEngine_v2::initTalkObject(int index) {
+	TalkObject &object = _talkObjectList[index];
+
 	char STAFilename[13];
-	char TLKFilename[13];
 	char ENDFilename[13];
 
 	strcpy(STAFilename, object.filename);
-	strcpy(TLKFilename, object.filename);
+	strcpy(_TLKFilename, object.filename);
 	strcpy(ENDFilename, object.filename);
 
 	strcpy(STAFilename + 4, "_STA.TIM");
-	strcpy(TLKFilename + 4, "_TLK.TIM");
+	strcpy(_TLKFilename + 4, "_TLK.TIM");
 	strcpy(ENDFilename + 4, "_END.TIM");
 
-	_currentTalkSections.STATim = loadTIMFile(STAFilename, NULL, 0);
-	_currentTalkSections.TLKTim = loadTIMFile(TLKFilename, NULL, 0);
-	_currentTalkSections.ENDTim = loadTIMFile(ENDFilename, NULL, 0);
+	_currentTalkSections.STATim = tim_loadFile(STAFilename, NULL, 0);
+	_currentTalkSections.TLKTim = tim_loadFile(_TLKFilename, NULL, 0);
+	_currentTalkSections.ENDTim = tim_loadFile(ENDFilename, NULL, 0);
 
 	if (object.scriptId != -1) {
 		_specialSceneScriptStateBackup[object.scriptId] = _specialSceneScriptState[object.scriptId];
 		_specialSceneScriptState[object.scriptId] = 1;
 	}
 
-	/*if (_currentTalkObject.STATim) {
+	if (_currentTalkSections.STATim) {
 		_objectChatFinished = false;
 		while (!_objectChatFinished) {
-			processTalkObject(_currentTalkObject.STATim, 0);
+			tim_processSequence(_currentTalkSections.STATim, 0);
 			if (_chatText)
 				updateWithText();
 			else
 				update();
 		}
-	}*/
+	}
 }
 
-void KyraEngine_v2::deinitTalkObject(int initObject) {
-	TalkObject &object = _talkObjectList[initObject];
+void KyraEngine_v2::deinitTalkObject(int index) {
+	TalkObject &object = _talkObjectList[index];
 
-	/*if (_currentTalkObject.ENDTim) {
+	if (_currentTalkSections.ENDTim) {
 		_objectChatFinished = false;
 		while (!_objectChatFinished) {
-			processTalkObject(_currentTalkObject.ENDTim, 0);
+			tim_processSequence(_currentTalkSections.ENDTim, 0);
 			if (_chatText)
 				updateWithText();
 			else
 				update();
 		}
-	}*/
+	}
 
 	if (object.scriptId != -1) {
 		_specialSceneScriptState[object.scriptId] = _specialSceneScriptStateBackup[object.scriptId];
 	}
 
 	if (_currentTalkSections.STATim != NULL) {
-		freeTIM(_currentTalkSections.STATim);
+		tim_releaseBuffer(_currentTalkSections.STATim);
 		_currentTalkSections.STATim = NULL;
 	}
 
 	if (_currentTalkSections.TLKTim != NULL) {
-		freeTIM(_currentTalkSections.TLKTim);
+		tim_releaseBuffer(_currentTalkSections.TLKTim);
 		_currentTalkSections.TLKTim = NULL;
 	}
 
 	if (_currentTalkSections.ENDTim != NULL) {
-		freeTIM(_currentTalkSections.ENDTim);
+		tim_releaseBuffer(_currentTalkSections.ENDTim);
 		_currentTalkSections.ENDTim = NULL;
 	}
 }
 
-byte *KyraEngine_v2::loadTIMFile(const char *filename, byte *buffer, int32 bufferSize) {
-	ScriptFileParser file(filename, _res);
-	if (!file) {
-		error("Couldn't open script file '%s'", filename);
-		return NULL;
-	}
+void KyraEngine_v2::npcChatSequence(const char *str, int objectId, int vocHigh, int vocLow) {
+	_chatText = str;
+	_chatObject = objectId;
+	objectChatInit(str, objectId, vocHigh, vocLow);
 
-	int32 formBlockSize = file.getFORMBlockSize();
-	if (formBlockSize == -1) {
-		error("No FORM chunk found in file: '%s'", filename);
-		return NULL;
-	}
+	if (!_currentTalkSections.TLKTim)
+		_currentTalkSections.TLKTim = tim_loadFile(_TLKFilename, 0, 0);
 
-	if (formBlockSize < 20) {
-		return NULL;
-	}
+	setNextIdleAnimTimer();
 
-	formBlockSize += sizeof(TIMHeader) + 120 + sizeof(TIMStructUnk1) * 10;
+	uint32 ct = chatCalcDuration(str);
+	uint32 time = _system->getMillis();
+	_chatEndTime =  time + (3 + ct) * _tickLength;
+	uint32 chatAnimEndTime = time + (3 + (ct >> 1)) * _tickLength;
 
-	TIMHeader *timHeader;
-	if (buffer == NULL || bufferSize < formBlockSize) {
-		buffer = new byte[formBlockSize];
-		timHeader = (TIMHeader *)buffer;
-		timHeader->deleteBufferFlag = 0xBABE;
-	} else {
-		timHeader = (TIMHeader *)buffer;
-		timHeader->deleteBufferFlag = 0x0;
+	if (_chatVocHigh >= 0) {
+		playVoice(_chatVocHigh, _chatVocLow);
+		_chatVocHigh = _chatVocLow = -1;
 	}
 
-	int32 chunkSize = file.getIFFBlockSize(AVTL_CHUNK);
-	timHeader->unkFlag = -1;
-	timHeader->unkFlag2 = 0;
-	timHeader->unkOffset = sizeof(TIMHeader);
-	timHeader->unkOffset2 = timHeader->unkOffset + sizeof(TIMStructUnk1) * 10;
-	timHeader->AVTLOffset = timHeader->unkOffset2 + 120;
-	timHeader->TEXTOffset = timHeader->AVTLOffset + chunkSize;
+	while (((textEnabled() && _chatEndTime > _system->getMillis()) || (speechEnabled() && snd_voiceIsPlaying())) && !(_quitFlag || _skipFlag)) {
+		if (!speechEnabled() && chatAnimEndTime > _system->getMillis() || speechEnabled() && snd_voiceIsPlaying()) {
+			_objectChatFinished = false;
 
-	_TIMBuffers.AVTLChunk = (uint16 *)(buffer + timHeader->AVTLOffset);
-	_TIMBuffers.TEXTChunk = buffer + timHeader->TEXTOffset;
+			while (!_objectChatFinished && !_skipFlag) {
+				if (_currentTalkSections.TLKTim)
+					tim_processSequence(_currentTalkSections.TLKTim, 0);
+				else
+					_objectChatFinished = false;
 
-	if (!file.loadIFFBlock(AVTL_CHUNK, _TIMBuffers.AVTLChunk, chunkSize)) {
-		error("Couldn't load AVTL chunk from file: '%s'", filename);
-		return NULL;
+				updateWithText();
+
+				int inputFlag = checkInput(0);
+				removeInputTop();
+				if (inputFlag == 198 || inputFlag == 199) {
+					//XXX
+					_skipFlag = true;
+					snd_stopVoice();
+				}
+				delay(10);
+			}
+			if (_currentTalkSections.TLKTim)
+				tim_o_abort(0);
+		}
+		updateWithText();
 	}
 
-	_TIMBuffers.UnkChunk = (TIMStructUnk1 *)(buffer + timHeader->unkOffset);
+	_skipFlag = false;
 
-	for (int i = 0; i < 10; i++) {
-		_TIMBuffers.UnkChunk[i].unk_0 = 0;
-		_TIMBuffers.UnkChunk[i].unk_2 = 0;
-		_TIMBuffers.UnkChunk[i].unk_20 = &_TIMBuffers.AVTLChunk[ _TIMBuffers.AVTLChunk[i] ];
-		_TIMBuffers.UnkChunk[i].unk_4 = 0;
-		_TIMBuffers.UnkChunk[i].unk_8 = 0;
+	if (_currentTalkSections.TLKTim) {
+		tim_releaseBuffer(_currentTalkSections.TLKTim);
+		_currentTalkSections.TLKTim = 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;
+	_text->restoreScreen();
+	_chatText = 0;
+	_chatObject = -1;
+	setNextIdleAnimTimer();
 }
 
-void KyraEngine_v2::freeTIM(byte *buffer) {
-	TIMHeader *timHeader = (TIMHeader *)buffer;
-
-	if (timHeader->deleteBufferFlag == 0xBABE) {
-		delete[] buffer;
-	}
+void KyraEngine_v2::setNewDlgIndex(int dlgIndex) {
+	if (dlgIndex == _mainCharacter.dlgIndex)
+		return;
+	memset(_newSceneDlgState, 0, 32);
+	for (int i = 0; i < 19; i++)
+		memset(_conversationState[i], -1, 14);
+	_npcTalkUNK = 0;
+	_mainCharacter.dlgIndex = dlgIndex;
 }
 
 } // end of namespace Kyra
-
-


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