[Scummvm-cvs-logs] SF.net SVN: scummvm: [23533] tools/trunk

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Thu Jul 20 22:52:23 CEST 2006


Revision: 23533
          http://svn.sourceforge.net/scummvm/?rev=23533&view=rev
Author:   lordhoto
Date:     2006-07-17 18:44:49 -0700 (Mon, 17 Jul 2006)

Log Message:
-----------
Rewrite of dekyra (still WIP):
- supports EMC files without TEXT chunks
- basic function chunk detection
- should be compatible with (most) Kyra1 and Kyra2 files (needs some more testing though, e.g. checks for special Kyra2 commands)
- script parser/execution taken from the ScummVM Kyrandia engine

Modified Paths:
--------------
    tools/trunk/Makefile
    tools/trunk/dekyra.cpp
    tools/trunk/dekyra.h

Added Paths:
-----------
    tools/trunk/dekyra_v1.cpp

Modified: tools/trunk/Makefile
===================================================================
--- tools/trunk/Makefile	2006-07-17 12:22:29 UTC (rev 23532)
+++ tools/trunk/Makefile	2006-07-18 01:44:49 UTC (rev 23533)
@@ -56,7 +56,7 @@
 desword2$(EXEEXT): desword2.o util.o
 	$(CXX) $(LDFLAGS) -o $@ $+
 
-dekyra$(EXEEXT): dekyra.o util.o
+dekyra$(EXEEXT): dekyra.o dekyra_v1.o util.o
 	$(CXX) $(LDFLAGS) -o $@ $+
 
 extract_kyra$(EXEEXT): extract_kyra.o util.o
@@ -123,6 +123,7 @@
 compress_kyra.o \
 descumm.o descumm6.o descumm-common.o descumm-tool.o \
 dekyra.o \
+dekyra_v1.o \
 desword2.o \
 encode_dxa.o \
 extract_kyra.o \

Modified: tools/trunk/dekyra.cpp
===================================================================
--- tools/trunk/dekyra.cpp	2006-07-17 12:22:29 UTC (rev 23532)
+++ tools/trunk/dekyra.cpp	2006-07-18 01:44:49 UTC (rev 23533)
@@ -23,211 +23,515 @@
 
 #include "dekyra.h"
 
-int main(int argc, char** argv) {
+#include <stdio.h>
 
+void printCommandsV1Ref();
+void setupCommandsV1(Script *myScript);
+void setupTraceCommandsV1(Script *myScript);
+
+void getOpcodesV1(OpcodeEntry *&opcodes, int &opcodesSize);
+void getOpcodesV2(OpcodeEntry *&opcodes, int &opcodesSize);
+
+FILE *outputFile = NULL;
+
+int main(int argc, char** argv) {
 	if (argc < 2) {
 		printf("Use:\n"
 			   "%s filename\n"
-			   "-t   displays text segment\n"
-			   "-n   display only function 'n'. n should be a integer\n"
-			   "-e   set engine version (1 for kyra1 (default), 2 for kyra2)\n",
+			   "-t   displays only the text segment\n"
+			   "-e   set engine version (1 for kyra1 (default), 2 for kyra2)\n"
+			   "-o   set optional outputfilename (default: stdout)\n",
 			   argv[0]);
 			   
-		return false;
+		return -1;
 	}
 	
-	uint32 file = 0xFFFFFFFE;
+	int file = -1;
+	int outputfile = -1;
 	bool displayText = false;
-	bool displayOnlyOneScript = false;
-	int32 scriptnum = 0, engine = 1;
+	int32 engine = 1;
 	
 	// search for some parameters
 	for (int param = 1; param < argc; ++param) {
-		if (*argv[param] != '-' && file == 0xFFFFFFFE)
+		if (*argv[param] != '-' && file == -1)
 			file = param;
 		else {
-			if(argv[param][1] == 't')
+			if(argv[param][1] == 't') {
 				displayText = true;
-			else if (argv[param][1] == 'n') {
-				scriptnum = atoi(argv[param+1]);
-				if (scriptnum >= 0 && scriptnum < 256)
-					displayOnlyOneScript = true;
-				param++;
 			} else if (argv[param][1] == 'e') {
 				engine = atoi(argv[param+1]);
-				param++;
-				
+				++param;				
+			} else if (argv[param][1] == 'o' && outputfile == -1) {
+				outputfile = ++param;
 			}
 		}
 	}
 	
-	if (file == 0xFFFFFFFE) {
+	if (file == -1) {
 		printf("Use:\n"
 			   "%s filename\n"
-			   "-t   displays text segment\n"
-			   "-n   display only function 'n'\n"
-			   "-e   set engine version (1 for kyra1 (default), 2 for kyra2)\n",
+			   "-t   displays only the text segment\n"
+			   "-e   set engine version (1 for kyra1 (default), 2 for kyra2)\n"
+			   "-o   set optional outputfilename (default: stdout)\n",
 			   argv[0]);
 			   
-		return false;
+		return -1;
+	} else if (engine != 1 && engine != 2) {
+		printf("-e (engine version) must be set to 1 or 2!\n");
+		return -1;
 	}
 	
-	Script myscript(argv[file]);
+	// currently output goes to stdout
+	if (outputfile == -1 || outputfile >= argc) {
+		outputFile = stdout;
+	} else {
+		outputFile = fopen(argv[outputfile], "w");
+	}
+	
+	Script myScript;
+	ScriptData scriptData;
+	memset(&scriptData, 0, sizeof(ScriptData));
+	
+	OpcodeEntry *opcodes;
+	int opcodesSize;
+	
+	if (engine == 1) {
+		getOpcodesV1(opcodes, opcodesSize);
+	} else if (engine == 2) {
+		getOpcodesV2(opcodes, opcodesSize);
+	}
 
+	if (!myScript.loadScript(argv[file], &scriptData, opcodes, opcodesSize)) {
+		printf("ERROR: script loading failed!\n");
+		return -1;
+	}
 	
-	if (myscript.isOpen()) {
-		if (displayText) {
-			myscript.decodeTextArea();
-			printf("\n\n");
-			return true;
+	myScript.setEngineVersion(engine);
+	if (!displayText) {
+		if (engine == 1) {
+			setupTraceCommandsV1(&myScript);
+		} else if (engine == 2) {
+			// TODO: maybe kyra2 has other commands?
+			setupTraceCommandsV1(&myScript);
 		}
 		
-		if (!displayOnlyOneScript) {
-			myscript.decodeScript(engine);
-		} else {
-			if (!myscript.decodeSpecialScript(scriptnum, engine)) {
-				error("No script with number %d", scriptnum);
-			}
+		myScript.processScriptTrace(&scriptData);
+	}
+	
+	fprintf(outputFile, "/-----------------------------------\\\n");
+	fprintf(outputFile, "|                                   |\n");
+	fprintf(outputFile, "|  Dekyra output for file:          |\n");
+	fprintf(outputFile, "|  %-31s  |\n", argv[file]);
+	fprintf(outputFile, "|-----------------------------------|\n");
+	fprintf(outputFile, "|  General information:             |\n");
+	fprintf(outputFile, "|  Engine version: %1d                |\n", engine);
+	fprintf(outputFile, "|  Filesize: %15d bytes  |\n", scriptData.fileSize);
+	if (scriptData.text) {
+		fprintf(outputFile, "|-----------------------------------|\n");
+		fprintf(outputFile, "|  TEXT chunk information:          |\n");
+		fprintf(outputFile, "|  Strings: %-22d  |\n", scriptData.numStrings);
+		fprintf(outputFile, "|  Text chunk size: %8d bytes  |\n", scriptData.textChunkSize);
+	}
+	if (!displayText) {
+		fprintf(outputFile, "|-----------------------------------|\n");
+		fprintf(outputFile, "|  ORDR chunk information:          |\n");
+		fprintf(outputFile, "|  Ordr chunk size: %8d bytes  |\n", scriptData.ordrChunkSize);
+		fprintf(outputFile, "|  Max scriptfunctions: %-10d  |\n", scriptData.ordrChunkSize / 2);
+		fprintf(outputFile, "|  Valid scriptfunctions: %-8d  |\n", scriptData.validORDRFunctions);
+		fprintf(outputFile, "|-----------------------------------|\n");
+		fprintf(outputFile, "|  DATA chunk information:          |\n");
+		fprintf(outputFile, "|  Code chunk size: %8d bytes  |\n", scriptData.dataChunkSize);
+		fprintf(outputFile, "|  Detected functionchunks: %-6d  |\n", scriptData.numFunctions);
+	}
+	fprintf(outputFile, "|                                   |\n");
+	fprintf(outputFile, "\\-----------------------------------/\n\n");
+	
+	myScript.setEngineVersion(engine);
+	myScript.printTextArea(&scriptData, argv[file]);
+	if (!displayText) {
+		if (engine == 1) {
+			printCommandsV1Ref();
+			setupCommandsV1(&myScript);
+		} else if (engine == 2) {
+			// TODO: maybe kyra2 has other commands?
+			printCommandsV1Ref();
+			setupCommandsV1(&myScript);
 		}
-		
-	} else {
-		error("Couldn't find file '%s'", argv[1]);
-	}	
+
+		myScript.decodeScript(&scriptData);
+	}
 	
+	myScript.unloadScript(&scriptData);
+	
+	if (outputFile != stdout)
+		fclose(outputFile);
+	
+	return 0;
+}
+
+Script::Script() : _commands(0), _commandsSize(0) {
+}
+
+Script::~Script() {
+}
+
+bool Script::setCommands(CommandProc *commands, int commandsSize) {
+	_commands = commands;
+	_commandsSize = commandsSize;
 	return true;
 }
 
-Script::Script(const char* filename) {
-	_scriptFile = 0;
-	_stackPos = 0;
-	FILE* script = fopen(filename, "rb");
+bool Script::loadScript(const char *filename, ScriptData *scriptData, OpcodeEntry *opcodes, int opcodeSize) {
+	FILE *scriptFile = fopen(filename, "rb");
+
+	if (scriptFile == NULL) {
+		error("couldn't load file '%s'", filename);
+		return false;
+	}
+
+	uint32 size = fileSize(scriptFile);
+	scriptData->fileSize = size;
+	uint8 *data = new uint8[size];
+	assert(data);
+	if (size != fread(data, sizeof(uint8), size, scriptFile)) {
+		delete [] data;
+		error("couldn't read all bytes from file '%s'", filename);
+		return false;
+	}
+	fclose(scriptFile);
+	scriptFile = NULL;
+
+	byte *curData = data;
 	
-	if (!script)
-		return;
+	uint32 formBlockSize = Script::getFORMBlockSize(curData);
+	if (formBlockSize == (uint32)-1) {
+		delete [] data;
+		error("No FORM chunk found in file: '%s'", filename);
+		return false;
+	}
+	
+	uint32 chunkSize = Script::getIFFBlockSize(data, curData, size, TEXT_CHUNK);
+	if (chunkSize != (uint32)-1) {
+		scriptData->text = new byte[chunkSize];
+		scriptData->textChunkSize = chunkSize;
+		assert(scriptData->text);
+
+		if (!Script::loadIFFBlock(data, curData, size, TEXT_CHUNK, scriptData->text, chunkSize)) {
+			delete [] data;
+			unloadScript(scriptData);
+			error("Couldn't load TEXT chunk from file: '%s'", filename);
+			return false;
+		}
 		
-	_scriptSize = fileSize(script);
-  	_scriptFile = new uint8[_scriptSize];
-	assert(_scriptFile); 
-	fread(_scriptFile, sizeof(uint8) * _scriptSize, 1, script);
-	fseek(script, 0, SEEK_SET);
- 	
-	uint8 chunkName[sizeof("EMC2ORDR") + 1];
+		uint16 minTextOffset = 0xFFFF;
+		for (int i = 0; i < scriptData->textChunkSize / 2; ++i, ++scriptData->numStrings) {
+			if (minTextOffset > READ_BE_UINT16(&((uint16 *)scriptData->text)[i])) {
+				minTextOffset = READ_BE_UINT16(&((uint16 *)scriptData->text)[i]);
+			}
+			if (minTextOffset <= i*2)
+				break;
+		}
+	}
 	
-	// so lets look for our chunks :)
-	while(true) {
-		if ((uint32)ftell(script) >= _scriptSize) {
-			break;
-		}		
-		// lets read only the first 4 chars
-		fread(chunkName, sizeof(uint8) * 4, 1, script);
-		chunkName[4] = '\0';
-		// check name of chunk
-		if (!strcmp((char*)chunkName, "FORM")) {			
-			// FreeKyra swaps the size I only read it in BigEndian :)
-			_chunks[kForm]._size = readUint32BE(script);				
-		} else if (!strcmp((char*)chunkName, "TEXT")) {
-			uint32 text_size = readUint32BE(script);
-			text_size += text_size % 2 != 0 ? 1 : 0;
-			
-			_chunks[kText]._data = _scriptFile + ftell(script);
-			_chunks[kText]._size = READ_BE_UINT16(_chunks[kText]._data) >> 1;
-			_chunks[kText]._additional = _chunks[kText]._data + (_chunks[kText]._size << 1);				
-			fseek(script, text_size, SEEK_CUR);
-		} else if (!strcmp((char*)chunkName, "DATA")) {
-			_chunks[kData]._size = readUint32BE(script);
-			_chunks[kData]._data = _scriptFile + ftell(script);
-			// mostly it will be the end of the file because all files should end with a 'DATA' chunk
-			fseek(script, _chunks[kData]._size, SEEK_CUR);
-		} else {
-			// read next 4 chars
-			fread(&chunkName[4], sizeof(uint8) * 4, 1, script);
-			chunkName[8] = '\0';
-			if (!strcmp((char*)chunkName, "EMC2ORDR")) {
-				_chunks[kEmc2Ordr]._size = readUint32BE(script) >> 1;
-				_chunks[kEmc2Ordr]._data = _scriptFile + ftell(script);					
-				fseek(script, _chunks[kEmc2Ordr]._size * 2, SEEK_CUR);
-			} else {
-				// any unkown chunk or problems with seeking through the file
-				error("unknown chunk '%s'", chunkName);
+	chunkSize = Script::getIFFBlockSize(data, curData, size, ORDR_CHUNK);
+	if (chunkSize == (uint32)-1) {
+		delete [] data;
+		unloadScript(scriptData);
+		error("No ORDR chunk found in file: '%s'", filename);
+		return false;
+	}
+
+	scriptData->ordr = new byte[chunkSize];
+	scriptData->ordrChunkSize = chunkSize;
+	assert(scriptData->ordr);
+
+	if (!Script::loadIFFBlock(data, curData, size, ORDR_CHUNK, scriptData->ordr, chunkSize)) {
+		delete [] data;
+		unloadScript(scriptData);
+		error("Couldn't load ORDR chunk from file: '%s'", filename);
+		return false;
+	}
+	chunkSize = chunkSize / 2;
+	while (chunkSize--) {
+		((uint16*)scriptData->ordr)[chunkSize] = READ_BE_UINT16(&((uint16*)scriptData->ordr)[chunkSize]);
+	}
+	
+	chunkSize = Script::getIFFBlockSize(data, curData, size, DATA_CHUNK);
+	if (chunkSize == (uint32)-1) {
+		delete [] data;
+		unloadScript(scriptData);
+		error("No DATA chunk found in file: '%s'", filename);
+		return false;
+	}
+
+	scriptData->data = new byte[chunkSize];
+	assert(scriptData->data);
+
+	if (!Script::loadIFFBlock(data, curData, size, DATA_CHUNK, scriptData->data, chunkSize)) {
+		delete [] data;
+		unloadScript(scriptData);
+		error("Couldn't load DATA chunk from file: '%s'", filename);
+		return false;
+	}
+	
+	scriptData->dataChunkSize = chunkSize;
+	scriptData->opcodes = opcodes;
+	scriptData->opcodeSize = opcodeSize;
+	
+	delete [] data;
+	return true;
+}
+
+void Script::unloadScript(ScriptData *data) {
+	if (!data)
+		return;
+
+	delete [] data->text;
+	delete [] data->ordr;
+	delete [] data->data;
+	data->text = data->ordr = data->data = 0;
+}
+
+// decoding
+void Script::printTextArea(ScriptData *dataPtr, const char *filename) {
+	if (!dataPtr->textChunkSize)
+		return;
+
+#define posString(x) (char*)&dataPtr->text[READ_BE_UINT16(&((uint16 *)dataPtr->text)[(x)])]
+	fprintf(outputFile, "------------ Text Segment of '%s' --------------\n\n", filename);
+	for (int i = 0; i < dataPtr->numStrings; ++i) {
+		fprintf(outputFile, "0x%.04X '%s'\n", i, posString(i));
+	}
+	fprintf(outputFile, "\n");
+#undef posString
+}
+
+void Script::processScriptTrace(ScriptData *dataPtr) {
+	uint8 *ip = dataPtr->data;
+
+	for (int i = 0; i < dataPtr->ordrChunkSize / 2; ++i) {
+		if (dataPtr->numFunctions < MAX_FUNCTIONS) {
+			dataPtr->functions[dataPtr->numFunctions].id = i;
+			dataPtr->functions[dataPtr->numFunctions].startOffset = (((uint16*)dataPtr->ordr)[i]);
+			if (dataPtr->functions[dataPtr->numFunctions].startOffset != (uint16)-1) {
+				++dataPtr->validORDRFunctions;
+				dataPtr->functions[dataPtr->numFunctions].startOffset <<= 1;
+				++dataPtr->numFunctions;
 			}
+		} else {
+			warning("losing function");
 		}
 	}
+
+	for (; ip && ip < (dataPtr->data + dataPtr->dataChunkSize);) {
+		dataPtr->curOffset = (uint16)(ip - dataPtr->data);
+		int16 parameter = 0;
+		int16 code = READ_BE_UINT16(ip); ip += 2;
+		int16 opcode = (code >> 8) & 0x1F;
+
+		if (code & 0x8000) {
+			opcode = 0;
+			parameter = code & 0x7FFF;
+		} else if (code & 0x4000) {
+			parameter = (int8)(code);
+		} else if (code & 0x2000) {
+			parameter = READ_BE_UINT16(ip); ip += 2;
+		} else {
+			parameter = 0;
+		}
+		
+		if (opcode < _commandsSize) {
+			if (_commands[(uint)opcode])
+				_commands[(uint)opcode](dataPtr, parameter);
+		}
+	}
 	
-	fclose(script);
+	// TODO: sort the 'function' list (except for the functions with id != -1) after start address
 }
 
-void Script::decodeTextArea(void) {
-	printf("TEXT chunk:\n");
-	// first is size
-	for (uint32 pos = 1; pos < (_chunks[kText]._size << 1); ++pos) {
-		if (READ_BE_UINT16(_chunks[kText]._data + 2*pos) >= _scriptSize) {
+int Script::findFunction(ScriptData *dataPtr, uint16 offset) {
+	int bestStartOffset = -1;
+	int functionFittingBest = -1;
+
+	for (int i = 0; i < dataPtr->numFunctions; ++i) {
+		if (dataPtr->functions[i].startOffset == offset)
+			return i;
+
+		int temp = (dataPtr->functions[i].startOffset < offset) ? dataPtr->functions[i].startOffset : offset;
+		if (temp == offset)
+			continue;
+		
+		int temp2 = (bestStartOffset > temp) ? bestStartOffset : temp;
+		if (temp2 == bestStartOffset)
+			continue;
+		
+		bestStartOffset = temp2;
+		functionFittingBest = i;
+	}
+
+	return functionFittingBest;
+}
+
+void Script::outputFunctionInfo(ScriptData *dataPtr, uint16 curOffset, bool list) {
+	for (int i = 0; i < dataPtr->numFunctions; ++i) {
+		if (dataPtr->functions[i].startOffset != curOffset && !list)
+			continue;
+
+		if (!list) {
+			fprintf(outputFile, "\n------------------------------------------------\n");
+			fprintf(outputFile, "Function(chunk) start: ");
+		}
+
+		fprintf(outputFile, "num: %d, ID: %d startOffset: 0x%.04X\n", i, dataPtr->functions[i].id, dataPtr->functions[i].startOffset);
+		if (dataPtr->functions[i].refs) {
+			fprintf(outputFile, "refs:\n");
+			for (int i2 = 0; i2 < dataPtr->functions[i].refs; ++i2) {
+				uint16 tmpOffset = dataPtr->functions[i].refOffs[i2];
+				fprintf(outputFile, "0x%.04X (funcnum: %d) ", dataPtr->functions[i].refOffs[i2], findFunction(dataPtr, tmpOffset));
+				if ((i2 % 3) == 2)
+					fprintf(outputFile, "\n");
+			}
+			if (((dataPtr->functions[i].refs - 1)% 3) != 2)
+				fprintf(outputFile, "\n");
+		}
+
+		if (!list) {
+			fprintf(outputFile, "------------------------------------------------\n\n");
 			break;
+		} else if (i + 1 != dataPtr->numFunctions)  {
+			fprintf(outputFile, "------------------------------------------------\n");
 		}
-		uint32 startoffset = READ_BE_UINT16(_chunks[kText]._data + 2*pos);
-		printf("%d(at %d) : %s\n", pos, startoffset, (char*)(_chunks[kText]._data + startoffset));
 	}
-}
 
-void Script::decodeScript(int8 engine) {
-	decodeSpecialScript(-1, engine);
+	if (list)
+		fprintf(outputFile, "\n");
 }
 
-struct CommandDesc {
-	uint16 command;	// normally uint8
-	const char* description;
-	bool usesArgument;	
-};
+void Script::decodeScript(ScriptData *dataPtr) {
+	uint8 *ip = dataPtr->data;
+	
+	fprintf(outputFile, "\n");
+	fprintf(outputFile, "---------- scriptfunction list ----------------\n\n");
+	for (int i = 0; i < dataPtr->ordrChunkSize / 2; ++i) {
+		uint16 offset = ((uint16*)dataPtr->ordr)[i];
+		if (offset != (uint16)-1)
+			fprintf(outputFile, "Scriptfunction %d starts at 0x%.04X\n", i, offset << 1);
+	}
+	fprintf(outputFile, "\n");
+	
+	fprintf(outputFile, "--------- detected functionchunk list ----------\n\n");
+	outputFunctionInfo(dataPtr, 0, true);
 
-struct ScriptDesc {
-	int32 script;	// normally uint8
-	const char* description;
-};
+	fprintf(outputFile, "---------- 'disassembled' output ---------------\n");
+	for (; ip < (dataPtr->data + dataPtr->dataChunkSize);) {
+		uint16 curOffset = (uint16)(ip - dataPtr->data);
 
-struct OpcodeDesc {
-	uint16 opcode;	// normally uint8
-	const char* description;
-};
+		outputFunctionInfo(dataPtr, curOffset);
+		
+		fprintf(outputFile, "0x%.04X: ", curOffset);
 
-// function which calls opcode procs
-const uint16 OPCODE_CALLER = 0x0E;
+		int16 parameter = 0;
+		int16 code = READ_BE_UINT16(ip); ip += 2;
+		int16 opcode = (code >> 8) & 0x1F;
 
-bool Script::decodeSpecialScript(int32 script, int8 engineVersion) {
-	static CommandDesc commandDesc[] = {
-		{ 0x00, "goToLine", true },
-		{ 0x01, "setReturn", true },
-		{ 0x02, "pushRetRec", true },
-		{ 0x03, "push", true },
-		{ 0x04, "push", true },
-		{ 0x05, "pushVar", true },
-		{ 0x06, "pushFrameNeg", true },
-		{ 0x07, "pushFramePos", true },
-		{ 0x08, "popRetRec", true },
-		{ 0x09, "popVar", true },
-		{ 0x0A, "popFrameNeg", true },
-		{ 0x0B, "popFramePos", true },
-		{ 0x0C, "addToSP", true },
-		{ 0x0D, "subFromSP", true },
-		{ 0x0E, "execOpcode", true },
-		{ 0x0F, "ifNotGoTo", true },
-		{ 0x10, "negate", true },
-		{ 0x11, "evaluate", true },
-		// normally only until 0xFF
-		{ 0xFFFF, 0, 0 }
-	};
+		if (code & 0x8000) {
+			opcode = 0;
+			parameter = code & 0x7FFF;
+		} else if (code & 0x4000) {
+			parameter = (int8)(code);
+		} else if (code & 0x2000) {
+			parameter = READ_BE_UINT16(ip); ip += 2;
+		} else {
+			parameter = 0;
+		}
+		
+		fprintf(outputFile, "0x%.02X ", opcode);
+		if (opcode >= _commandsSize) {
+			fprintf(outputFile, "unknown command\n");
+		} else {
+			if (_commands[(uint)opcode]) {
+				_commands[(uint)opcode](dataPtr, parameter);
+			} else {
+				fprintf(outputFile, "no valid command\n");
+			}
+		}
+	}
+}
+
+// block loading
+uint32 Script::getFORMBlockSize(byte *&data) {
+	static const uint32 chunkName = FORM_CHUNK;
+	if (READ_LE_UINT32(data) != chunkName) {
+		return (uint32)-1;
+	}
+	data += 4;
+	uint32 retValue = READ_BE_UINT32(data); data += 4;
+	return retValue;
+}
+
+uint32 Script::getIFFBlockSize(byte *start, byte *&data, uint32 maxSize, const uint32 chunkName) {
+	uint32 size = (uint32)-1;
+	bool special = false;
 	
-	static ScriptDesc scriptDesc[] = {
-		{ 0, "kSetupScene" },
-		{ 1, "kClickEvent" },
-		{ 2, "kInitScreenEvent" },
-		{ 3, "kInitDataEvent" },
-		{ 4, "kEnterEvent" },
-		{ 5, "kExitEvent" },
-		{ 6, "kClick2Event" },
-		{ 7, "kLoadResources" },
-		{ 0xFFFF, "unknown script" }
-	};
+	if (data == (start + maxSize)) {
+		data = start + 0x0C;
+	}
+	while (data < (start + maxSize)) {
+		uint32 chunk = READ_LE_UINT32(data); data += 4;
+		uint32 size_temp = READ_BE_UINT32(data); data += 4;
+		if (chunk != chunkName) {
+			if (special) {
+				data += (size_temp + 1) & 0xFFFFFFFE;
+			} else {
+				data = start + 0x0C;
+				special = true;
+			}
+		} else {
+			// kill our data
+			data = start;
+			size = size_temp;
+			break;
+		}
+	}
+	return size;
+}
+
+bool Script::loadIFFBlock(byte *start, byte *&data, uint32 maxSize, const uint32 chunkName, byte *loadTo, uint32 ptrSize) {
+	bool special = false;
 	
-	static OpcodeDesc kyra2OpcodeDesc[] = {
+	if (data == (start + maxSize)) {
+		data = start + 0x0C;
+	}
+	while (data < (start + maxSize)) {
+		uint32 chunk = READ_LE_UINT32(data); data += 4;
+		uint32 chunkSize = READ_BE_UINT32(data); data += 4;
+		if (chunk != chunkName) {
+			if (special) {
+				data += (chunkSize + 1) & 0xFFFFFFFE;
+			} else {
+				data = start + 0x0C;
+				special = true;
+			}
+		} else {
+			uint32 loadSize = 0;
+			if (chunkSize < ptrSize)
+				loadSize = chunkSize;
+			else
+				loadSize = ptrSize;
+			memcpy(loadTo, data, loadSize);
+			chunkSize = (chunkSize + 1) & 0xFFFFFFFE;
+			if (chunkSize > loadSize) {
+				data += (chunkSize - loadSize);
+			}
+			return true;
+		}
+	}
+	return false;
+}
+
+// TODO: move to own file dekyra_v2.cpp if there are special kyra2 commands!
+void getOpcodesV2(OpcodeEntry *&opcodes, int &opcodesSize) {
+	static OpcodeEntry kyra2OpcodeDesc[] = {
 		{ 0x0, "o2_setCharacterShape" },
 		{ 0x1, "o2_drawShapeFrame" },
 		{ 0x2, "o2_defineObject" },
@@ -397,478 +701,7 @@
 		{ 0xa6, "o2_unk0xA6" },
 		{ 0xa7, "o2_dummy" }
 	};
- 	 
-	static OpcodeDesc kyra1OpcodeDesc[] = {
-		{ 0x00 ,"o1_Magic_In_Mouse_Item" },
-		{ 0x01 ,"o1_Character_Says" },
-		{ 0x02 ,"o1_Pause_Ticks" },
-		{ 0x03 ,"o1_Draw_Scene_Anim_Shape" },
-		{ 0x04 ,"o1_Query_Game_Flag" },
-		{ 0x05 ,"o1_Set_Game_Flag" },
-		{ 0x06 ,"o1_Reset_Game_Flag" },
-		{ 0x07 ,"o1_Run_NPC_Script" },
-		{ 0x08 ,"o1_Set_Special_Exit_List" },
-		{ 0x09 ,"o1_Block_In_Walkable_Region" },
-		{ 0x0A ,"o1_Block_Out_Walkable_Region" },
-		{ 0x0B ,"o1_Walk_Player_To_Point" },
-		{ 0x0C ,"o1_Drop_Item_In_Scene" },
-		{ 0x0D ,"o1_Draw_Anim_Shape_Into_Scene" },
-		{ 0x0E ,"o1_Create_Mouse_Item" },
-		{ 0x0F ,"o1_Save_Page_To_Disk" },
-		{ 0x10 ,"o1_Scene_Anim_On" },
-		{ 0x11 ,"o1_Scene_Anim_Off" },
-		{ 0x12 ,"o1_Elapsed_Seconds" },
-		{ 0x13 ,"o1_Mouse_Is_Pointer" },
-		{ 0x14 ,"o1_Destroy_Mouse_Item" },
-		{ 0x15 ,"o1_Run_Scene_Anim_Until_Done" },
-		{ 0x16 ,"o1_Fade_Special_Palette" },
-		{ 0x17 ,"o1_Play_AdLib_Sound" },
-		{ 0x18 ,"o1_Play_AdLib_Score" },
-		{ 0x19 ,"o1_Phase_In_Same_Scene" },
-		{ 0x1a ,"o1_Set_Scene_Phasing_Flag" },
-		{ 0x1b ,"o1_Reset_Scene_Phasing_Flag" },
-		{ 0x1c ,"o1_Query_Scene_Phasing_Flag" },
-		{ 0x1d ,"o1_Scene_To_Direction" },
-		{ 0x1e ,"o1_Set_Birthstone_Gem" },
-		{ 0x1f ,"o1_Place_Item_In_Generic_Map_Scene" },
-		{ 0x20 ,"o1_Set_Brandon_Status_Bit" },
-		{ 0x21 ,"o1_Pause_Seconds" },
-		{ 0x22 ,"o1_Get_Characters_Location" },
-		{ 0x23 ,"o1_Run_NPC_Subscript" },
-		{ 0x24 ,"o1_Magic_Out_Mouse_Item" },
-		{ 0x25 ,"o1_Internal_Anim_On" },
-		{ 0x26 ,"o1_Force_Brandon_To_Normal" },
-		{ 0x27 ,"o1_Poison_Death_Now" },
-		{ 0x28 ,"o1_Set_Scale_Mode" },
-		{ 0x29 ,"o1_Open_WSA_File" },
-		{ 0x2a ,"o1_Close_WSA_File" },
-		{ 0x2b ,"o1_Run_WSA_From_Beginning_To_End" },
-		{ 0x2c ,"o1_Display_WSA_Frame" },
-		{ 0x2d ,"o1_Enter_New_Scene" },
-		{ 0x2e ,"o1_Set_Special_Enter_X_And_Y" },
-		{ 0x2f ,"o1_Run_WSA_Frames" },
-		{ 0x30 ,"o1_Pop_Brandon_Into_Scene" },
-		{ 0x31 ,"o1_Restore_All_Object_Backgrounds" },
-		{ 0x32 ,"o1_Set_Custom_Palette_Range" },
-		{ 0x33 ,"o1_Load_Page_From_Disk" },		
-		{ 0x34 ,"o1_Custom_Print_Talk_String" },
-		{ 0x35 ,"o1_Restore_Custom_Print_Background" },
-		{ 0x36 ,"o1_Hide_Mouse" },
-		{ 0x37 ,"o1_Show_Mouse" },
-		{ 0x38 ,"o1_Get_Character_X" },
-		{ 0x39 ,"o1_Get_Character_Y" },
-		{ 0x3A ,"o1_Change_Characters_Facing" },
-		{ 0x3B ,"o1_Copy_WSA_Region" },
-		{ 0x3C ,"o1_Text_Print" },
-		{ 0x3D ,"o1_Random" },
-		{ 0x3E ,"o1_Load_Sound_File" },
-		{ 0x3F ,"o1_Display_WSA_Frame_On_HidPage" },
-		{ 0x40 ,"o1_Display_WSA_Sequential_Frames" },
-		{ 0x41 ,"o1_Draw_Character_Standing" },
-		{ 0x42 ,"o1_Internal_Anim_Off" },
-		{ 0x43 ,"o1_Change_Characters_X_And_Y" },
-		{ 0x44 ,"o1_Clear_Scene_Animator_Beacon" },
-		{ 0x45 ,"o1_Query_Scene_Animator_Beacon" },
-		{ 0x46 ,"o1_Refresh_Scene_Animator" },
-		{ 0x47 ,"o1_Place_Item_In_Off_Scene" },
-		{ 0x48 ,"o1_Wipe_Down_Mouse_Item" },
-		{ 0x49 ,"o1_Place_Character_In_Other_Scene" },
-		{ 0x4A ,"o1_Get_Key" },
-		{ 0x4B ,"o1_Specific_Item_In_Inventory" },
-		{ 0x4C ,"o1_Pop_Mobile_NPC_Into_Scene" },
-		{ 0x4D ,"o1_Mobile_Character_In_Scene" },
-		{ 0x4E ,"o1_Hide_Mobile_Character" },
-		{ 0x4F ,"o1_Unhide_Mobile_Character" },
-		{ 0x50 ,"o1_Set_Characters_Location" },
-		{ 0x51 ,"o1_Walk_Character_To_Point" },
-		{ 0x52 ,"o1_Special_Event_Display_Brynns_Note" },
-		{ 0x53 ,"o1_Special_Event_Remove_Brynns_Note" },
-		{ 0x54 ,"o1_Set_Logic_Page" },
-		{ 0x55 ,"o1_Fat_Print" },
-		{ 0x56 ,"o1_Preserve_All_Object_Backgrounds" },
-		{ 0x57 ,"o1_Update_Scene_Animations" },
-		{ 0x58 ,"o1_Scene_Animation_Active" },
-		{ 0x59 ,"o1_Set_Characters_Movement_Delay" },
-		{ 0x5A ,"o1_Get_Characters_Facing" },
-		{ 0x5B ,"o1_Bkgd_Scroll_Scene_And_Masks_Right" },
-		{ 0x5C ,"o1_Dispel_Magic_Animation" },
-		{ 0x5d ,"o1_Find_Brightest_Fireberry" },
-		{ 0x5e ,"o1_Set_Fireberry_Glow_Palette" },
-		{ 0x5f ,"o1_Set_Death_Handler_Flag" },
-		{ 0x60 ,"o1_Drink_Potion_Animation" },
-		{ 0x61 ,"o1_Make_Amulet_Appear" },
-		{ 0x62 ,"o1_Draw_Item_Shape_Into_Scene" },
-		{ 0x63 ,"o1_Set_Characters_Current_Frame" },
-		{ 0x64 ,"o1_Wait_For_Confirmation_Mouse_Click" },
-		{ 0x65 ,"o1_Page_Flip" },
-		{ 0x66 ,"o1_Set_Scene_File" },
-		{ 0x67 ,"o1_What_Item_In_Marble_Vase" },
-		{ 0x68 ,"o1_Set_Item_In_Marble_Vase" },
-		{ 0x69 ,"o1_Add_Item_To_Inventory" },
-		{ 0x6a ,"o1_Int_Print" },
-		{ 0x6b ,"o1_Shake_Screen" },
-		{ 0x6c ,"o1_Create_Amulet_Jewel" },
-		{ 0x6d ,"o1_Set_Scene_Anim_Curr_XY" },
-		{ 0x6e ,"o1_Poison_Brandon_And_Remaps" },
-		{ 0x6f ,"o1_Fill_Flask_With_Water" },
-		{ 0x70 ,"o1_Get_Characters_Movement_Delay" },
-		{ 0x71 ,"o1_Get_Birthstone_Gem" },
-		{ 0x72 ,"o1_Query_Brandon_Status_Bit" },
-		{ 0x73 ,"o1_Play_Flute_Animation" },
-		{ 0x74 ,"o1_Play_Winter_Scroll_Sequence" },
-		{ 0x75 ,"o1_Get_Idol_Gem" },
-		{ 0x76 ,"o1_Set_Idol_Gem" },
-		{ 0x77 ,"o1_Total_Items_In_Scene" },
-		{ 0x78 ,"o1_Restore_Brandons_Movement_Delay" },
-		{ 0x79 ,"o1_Set_Mouse_Pos" },
-		{ 0x7a ,"o1_Get_Mouse_State" },
-		{ 0x7b ,"o1_Set_Entrance_Mouse_Cursor_Track" },
-		{ 0x7c ,"o1_Item_Appears_On_Ground" },
-		{ 0x7d ,"o1_Set_No_Draw_Shapes_Flag" },
-		{ 0x7e ,"o1_Fade_Entire_Palette" },
-		{ 0x7f ,"o1_Item_On_Ground_Here" },
-		{ 0x80 ,"o1_Query_Cauldron_State" },
-		{ 0x81 ,"o1_Set_Cauldron_State" },
-		{ 0x82 ,"o1_Query_Crystal_State" },
-		{ 0x83 ,"o1_Set_Crystal_State" },
-		{ 0x84 ,"o1_Set_Palette_Range" },
-		{ 0x85 ,"o1_Shrink_Brandon_Down" },
-		{ 0x86 ,"o1_Grow_Brandon_Up" },
-		{ 0x87 ,"o1_Set_Brandon_Scale_X_And_Y" },
-		{ 0x88 ,"o1_Reset_Scale_Mode" },
-		{ 0x89 ,"o1_Get_Scale_Depth_Table_Value" },
-		{ 0x8a ,"o1_Set_Scale_Depth_Table_Value" },
-		{ 0x8b ,"o1_Message" },
-		{ 0x8c ,"o1_Check_Click_On_NPC" },
-		{ 0x8d ,"o1_Get_Foyer_Item" },
-		{ 0x8e ,"o1_Set_Foyer_Item" },
-		{ 0x8F ,"o1_Set_No_Item_Drop_Region" },
-		{ 0x90 ,"o1_Walk_Malcolm_On" },
-		{ 0x91 ,"o1_Passive_Protection" },
-		{ 0x92 ,"o1_Set_Playing_Loop" },
-		{ 0x93 ,"o1_Brandon_To_Stone_Sequence" },
-		{ 0x94 ,"o1_Brandon_Healing_Sequence" },
-		{ 0x95 ,"o1_Protect_Command_Line" },
-		{ 0x96 ,"o1_Pause_Music_Seconds" },
-		{ 0x97 ,"o1_Reset_Mask_Region" },
-		{ 0x98 ,"o1_Set_Palette_Change_Flag" },
-		{ 0x99 ,"o1_Fill_Rect" },
-		{ 0x9a ,"o1_Voc_Unload" },
-		{ 0x9b ,"o1_Voc_Load" },
-		{ 0x9c ,"o1_Dummy" }
-	};
-	
-	if (script > -1) {
-		_instructionPos = (READ_BE_UINT16(_chunks[kEmc2Ordr]._data + 2 * script) << 1);	
-	} else
-		_instructionPos = 0;	
-	
-	memset(_stack, 0, sizeof(_stack));
-	memset(_registers, 0, sizeof(_registers));
-	
-	_stackPos = 0;
 
-	uint8* script_start = _chunks[kData]._data;
-	bool gotArgument = true;
-	
-	// uint32 nextScriptStartsAt = getNextScriptPos(_instructionPos);
-	
-	while(true) {
-		if ((uint32)_instructionPos > _chunks[kData]._size /*|| (uint32)_instructionPos >= nextScriptStartsAt*/) {
-			break;
-		}
-		
-		for (uint32 pos = 0; pos < ARRAYSIZE(scriptDesc) - 1; ++pos) {
-			if ((READ_BE_UINT16(_chunks[kEmc2Ordr]._data + 2*pos) << 1) == _instructionPos) {
-				printf("\nScript %i: %s:\n", pos, scriptDesc[pos].description);
-				break;
-			}
-		}
-
-		// prints the offset
-		printf("0x%04x:\t\t" , _instructionPos);
-			
-		gotArgument = true;
-		_currentCommand = *(script_start + _instructionPos++);
-			
-		// gets out 
-		if (_currentCommand & 0x80) {
-			_argument = ((_currentCommand & 0x0F) << 8) | *(script_start + _instructionPos++);
-			_currentCommand &= 0xF0;
-		} else if (_currentCommand & 0x40) {
-			_argument = *(script_start + _instructionPos++);
-		} else if (_currentCommand & 0x20) {
-			_instructionPos++;
-			
-			// FIXME: I am not 100% sure if this code is correct (after my
-			// 'endian macro' changes), somebody please double check.
-			uint16 tmp = READ_BE_UINT16(script_start + _instructionPos);
-			tmp &= 0xFF7F;
-			
-			_argument = tmp;
-			_instructionPos += 2;
-		} else {
-			gotArgument = false;
-		}
-			
-		_currentCommand &= 0x1f;
-
-		
-		bool gotCommand = false;
-		
-		// lets get out what the command means
-		for (uint32 pos = 0; pos < ARRAYSIZE(commandDesc) - 1; ++pos) {
-			if (commandDesc[pos].command == _currentCommand) {
-				gotCommand = true;
-				if (commandDesc[pos].command != OPCODE_CALLER)
-					printf("\t%s" , commandDesc[pos].description);
-					
-				if (commandDesc[pos].usesArgument && commandDesc[pos].command != OPCODE_CALLER) {
-					if (commandDesc[pos].command == 0x3 || commandDesc[pos].command == 0x4)
-						printf("(0x%x | %s)" , _argument, stringAtIndex(_argument));
-					else
-						printf("(0x%x)\t" , _argument);
-					
-				} else if(commandDesc[pos].usesArgument && commandDesc[pos].command == OPCODE_CALLER) {
-					bool gotOpcode = false;
-					// lets look for our opcodes
-					if (engineVersion == 1) 
-						for (uint32 pos2 = 0; pos2 < ARRAYSIZE(kyra1OpcodeDesc); ++pos2) {
-							if (kyra1OpcodeDesc[pos2].opcode == _argument) {
-								printf("%s()", kyra1OpcodeDesc[pos2].description);
-								gotOpcode = true;
-								break;
-							}
-						}
-					else if (engineVersion == 2)
-						for (uint32 pos2 = 0; pos2 < ARRAYSIZE(kyra2OpcodeDesc); ++pos2) {
-							if (kyra2OpcodeDesc[pos2].opcode == _argument) {
-								printf("%s()", kyra2OpcodeDesc[pos2].description);
-								gotOpcode = true;
-								break;
-							}
-						}
-					if (!gotOpcode)
-						printf("UNKNOWN OPCODE: 0x%x", _argument);
-				}
-				
-				break;
-			}
-		}
-		execCommand(_currentCommand);
-		
-		// prints our command number + arg
-		if (!gotCommand) {
-			printf("0x%x(0x%x)", _currentCommand, _argument);
-		}
-		
-		if (!gotArgument) {
-			printf("\t; couldn't get argument! maybe command is wrong.");
-		}
-		
-		printf("\n");
-	}
-	
-	printf("\n-------------\n");
-	
-	return true;
+	opcodes = kyra2OpcodeDesc;
+	opcodesSize = ARRAYSIZE(kyra2OpcodeDesc);
 }
-
-uint32 Script::getNextScriptPos(uint32 current_start) {
-	uint32 pos = 0xFFFFFFFE;
-	
-	for (uint32 tmp = 0; tmp < _chunks[kEmc2Ordr]._size; ++tmp) {
-		uint32 tmp2 = READ_BE_UINT16(_chunks[kEmc2Ordr]._data + tmp);
-		tmp2 = (tmp2 << 1) + 2;
-		if (tmp2 > current_start && tmp2 < pos) {
-			pos = tmp2;
-		}
-	}
-	
-	if (pos > _scriptSize) {
-		pos = _scriptSize;
-	}
-	
-	return pos;
-}
-	
-const char* Script::stringAtIndex(int32 index) {
-	if (index < 0 || (uint32)index >= _chunks[kText]._size)
-		return 0;
-	
-	uint16 offset = READ_BE_UINT16(_chunks[kText]._data + 2*index);
-	return (const char *)(_chunks[kText]._data + offset);
-}
-
-void Script::execCommand(uint32 command) {
-#define COMMAND(x) { &Script::x }
-	typedef void (Script::*CommandProc)();
-	struct CommandEntry {
-		CommandProc proc;
-	};
-
-	// now we create a list of all Command/Opcode procs and so
-	static CommandEntry commandProcs[] = {
-		// 0x00
-		COMMAND(goToLine),
-		COMMAND(setReturn),
-		COMMAND(pushRetRec),
-		COMMAND(push),
-		// 0x04
-		COMMAND(push),			
-		COMMAND(pushVar),
-		COMMAND(pushFrameNeg),
-		COMMAND(pushFramePos),
-		// 0x08
-		COMMAND(popRetRec),
-		COMMAND(popVar),
-		COMMAND(popFrameNeg),
-		COMMAND(popFramePos),
-		// 0x0C
-		COMMAND(addToSP),
-		COMMAND(subFromSP),
-		COMMAND(execOpcode),
-		COMMAND(ifNotGoTo),
-		// 0x10
-		COMMAND(negate),
-		COMMAND(evaluate)
-	};
-
-	static uint16 _numCommands = ARRAYSIZE(commandProcs);
-	static CommandEntry* _commands = commandProcs;
-	
-	if (command < _numCommands) {
-		CommandProc currentProc = _commands[command].proc;
-		(this->*currentProc)();
-	}
-}
-
-void Script::goToLine(void) {
-}
-
-void Script::setReturn(void) {
-}
-
-void Script::pushRetRec(void) {
-}
-
-void Script::push(void) {
-}
-
-void Script::pushVar(void) {
-}
-
-void Script::pushFrameNeg(void) {
-}
-
-void Script::pushFramePos(void) {
-}
-
-void Script::popRetRec(void) {
-}
-
-void Script::popVar(void) {
-}
-
-void Script::popFrameNeg(void) {
-}
-
-void Script::popFramePos(void) {
-}
-
-void Script::addToSP(void) {
-}
-
-void Script::subFromSP(void) {
-}
-
-void Script::execOpcode(void) {
-}
-
-void Script::ifNotGoTo(void) {
-}
-
-void Script::negate(void) {
-}
-
-void Script::evaluate(void) {		
-	switch(_argument) {
-	case 0:
-		printf("x && y");
-		break;
-	
-	case 1:
-		printf("x || y");
-		break;
-
-	case 2:
-		printf("x == y");
-		break;
-	
-	case 3:
-		printf("x != y");
-		break;
-
-	case 4:
-		printf("x < y");
-		break;
-
-	case 5:
-		printf("x <= y");
-		break;
-		
-	case 6:
-		printf("x > y");
-		break;
-	
-	case 7:
-		printf("x >= y");
-		break;
-	
-	case 8:
-		printf("x + y");
-		break;
-		
-	case 9:
-		printf("x - y");
-		break;
-	
-	case 10:
-		printf("x * y");
-		break;
-		
-	case 11:
-		printf("x / y");
-		break;
-	
-	case 12:
-		printf("x >> y");
-		break;
-	
-	case 13:
-		printf("x << y");
-		break;
-	
-	case 14:
-		printf("x & y");
-		break;
-	
-	case 15:
-		printf("x | y");
-		break;
-	
-	case 16:
-		printf("x %% y");
-		break;
-	
-	case 17:
-		printf("x ^ y");
-		break;
-	
-	default:
-		printf("ERROR: unknown evaluate command %d\n", _argument);
-		break;
-	};
-	
-}
-

Modified: tools/trunk/dekyra.h
===================================================================
--- tools/trunk/dekyra.h	2006-07-17 12:22:29 UTC (rev 23532)
+++ tools/trunk/dekyra.h	2006-07-18 01:44:49 UTC (rev 23533)
@@ -26,83 +26,88 @@
 
 #include "util.h"
 
-class Script {
-	public:
-		Script(const char* filename);
-		~Script() { delete _scriptFile; }
-		
-		void decodeTextArea(void);
-		void decodeScript(int8 engine);		
-		bool decodeSpecialScript(int32 script, int8 engine);
-		bool isOpen(void) { return (_scriptFile != 0); }
-		
-		uint32 getNextScriptPos(uint32 current_start);
+typedef unsigned int uint;
 
-	protected:
-		const char* getParamsOnStack(void);
-		const char* stringAtIndex(int32 index);
+struct OpcodeEntry {
+	uint16 opcode;	
+	const char *name;
+};
 
-		void pushStack(int32 value) { _stack[_stackPos++] = value; }
-		void registerValue(int16 reg, int16 value) { _registers[reg] = value; }
-		int32 checkReg(int16 reg) { return _registers[reg]; }
+#define MAX_REFS 30
+struct Function {
+	int id;
+	uint16 startOffset;
 
-		int32 popStack(void) { return _stack[--_stackPos]; }
-		int32& topStack(void) { return _stack[_stackPos]; }
+	int refs;
+	uint16 refOffs[MAX_REFS];
+};
 
-		int32 param(int32 index);
-		const char* paramString(int32 index) { return stringAtIndex(param(index)); }
-		
-		enum ScriptChunkTypes {
-			kForm = 0,
-			kEmc2Ordr = 1,
-			kText = 2,
-			kData = 3,
-			kCountChunkTypes
-		};
-		
-		struct ScriptChunk {
-			uint32 _size;
-			uint8* _data; // by TEXT used for count of texts, by EMC2ODRD it is used for a count of somewhat
-			uint8* _additional; // currently only used for TEXT
-		};
-		
-		ScriptChunk _chunks[kCountChunkTypes];
-		
-		uint32 _scriptSize;
-		uint8* _scriptFile;
+#define MAX_FUNCTIONS 400
 
-		int32 _nextScriptPos;
-		int32 _instructionPos;
-		int32 _stackPos;
-		int32 _tempPos;
+struct ScriptData {
+	int fileSize;
 
-		uint32 _returnValue;
-		uint16 _argument;
-		uint8 _currentCommand;
-		uint32 _currentOpcode;
-		
-		int32 _stack[128];	// the stack
-		int32 _registers[32];   // registers of the interpreter
+	byte *text;
+	int numStrings;
+	int textChunkSize;
+	
+	byte *data;
+	int dataChunkSize;
+	
+	byte *ordr;
+	int validORDRFunctions;
+	int ordrChunkSize;
+	
+	OpcodeEntry *opcodes;
+	int opcodeSize;
+	
+	// trace information
+	uint16 curOffset;
 
-		void execCommand(uint32 command);
+	int numFunctions;
+	Function functions[MAX_FUNCTIONS];
+	
+	Function *getFunction(uint16 startOff) {
+		for (int i = 0; i < numFunctions; ++i) {
+			if (functions[i].startOffset == startOff)
+				return &functions[i];
+		}
+		return 0;
+	}
+};
 
-		void goToLine(void);		// 0x00
-		void setReturn(void);		// 0x01
-		void pushRetRec(void);		// 0x02
-		void push(void);		// 0x03 & 0x04
-		void pushVar(void);		// 0x05
-		void pushFrameNeg(void);	// 0x06
-		void pushFramePos(void);	// 0x07
-		void popRetRec(void);		// 0x08
-		void popVar(void);		// 0x09
-		void popFrameNeg(void);		// 0x0A
-		void popFramePos(void);		// 0x0B
-		void addToSP(void);		// 0x0C
-		void subFromSP(void);		// 0x0D
-		void execOpcode(void);		// 0x0E
-		void ifNotGoTo(void);		// 0x0F
-		void negate(void);		// 0x10
-		void evaluate(void);		// 0x11
+#define FORM_CHUNK 0x4D524F46
+#define TEXT_CHUNK 0x54584554
+#define DATA_CHUNK 0x41544144
+#define ORDR_CHUNK 0x5244524F
+
+typedef void (*CommandProc)(ScriptData *script, int argument);
+
+class Script {
+public:
+	Script();
+	~Script();
+
+	bool setCommands(CommandProc *commands, int commandsSize);
+	void setEngineVersion(int ver) { _engine = ver; }
+
+	bool loadScript(const char *filename, ScriptData *data, OpcodeEntry *opcodes, int opcodeSize);
+	void unloadScript(ScriptData *data);
+	
+	void printTextArea(ScriptData *dataPtr, const char *filename);
+	void processScriptTrace(ScriptData *dataPtr);
+	void decodeScript(ScriptData *dataPtr);
+private:
+	int findFunction(ScriptData *dataPtr, uint16 offset);
+	void outputFunctionInfo(ScriptData *dataPtr, uint16 curOffset, bool list = false);
+
+	static uint32 getFORMBlockSize(byte *&data);
+	static uint32 getIFFBlockSize(byte *start, byte *&data, uint32 maxSize, const uint32 chunk);
+	static bool loadIFFBlock(byte *start, byte *&data, uint32 maxSize, const uint32 chunk, byte *loadTo, uint32 ptrSize);
+
+	int _engine;
+	CommandProc *_commands;
+	int _commandsSize;
 };
 
 #endif

Added: tools/trunk/dekyra_v1.cpp
===================================================================
--- tools/trunk/dekyra_v1.cpp	2006-07-17 12:22:29 UTC (rev 23532)
+++ tools/trunk/dekyra_v1.cpp	2006-07-18 01:44:49 UTC (rev 23533)
@@ -0,0 +1,547 @@
+/* DeKyra - Basic Kyrandia script disassembler
+ * Copyright (C) 2006  The ScummVM Team
+ *
+ * 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 "dekyra.h"
+
+extern FILE *outputFile;
+
+// command help
+void printCommandsV1Ref() {
+	fprintf(outputFile, "------------- Command Reference ----------------\n\n");
+	fprintf(outputFile, "c1_jumpTo             - jumps to the given param\n\n");
+	fprintf(outputFile, "c1_setRetValue        - sets the return value\n\n");
+	fprintf(outputFile, "c1_pushRetOrPos       - dependent on param:\n");
+	fprintf(outputFile, "                      - 0: pushes return value\n");
+	fprintf(outputFile, "                      - 1: pushes the next instruction address and the bp and updates the bp to sp+2\n");
+	fprintf(outputFile, "                      - else: breaks execution\n\n");
+	fprintf(outputFile, "c1_push               - push an integer to the stack (is also be used for string indexes)\n\n");
+	fprintf(outputFile, "c1_pushVar            - pushes var[param] to the stack\n\n");
+	fprintf(outputFile, "c1_pushBPNeg          - pushes the value at stack[(-(param + 2))+ bp] to the stack\n\n");
+	fprintf(outputFile, "c1_pushBPAdd          - pushes the value at stack[(param - 1) + bp] to the stack\n\n");
+	fprintf(outputFile, "c1_popRetOrPos        - dependent on param:\n");
+	fprintf(outputFile, "                      - 0: pops return value\n");
+	fprintf(outputFile, "                      - 1: pops the bp and after it the ip from the stack\n");
+	fprintf(outputFile, "                      - else: breaks execution\n\n");
+	fprintf(outputFile, "c1_popVar             - pops the stack top to var[param]\n\n");
+	fprintf(outputFile, "c1_popBPNeg           - pops the stack top to stack[-(param + 2) + bp]\n\n");
+	fprintf(outputFile, "c1_popBPAdd           - pops the stack top to stack[(param - 1) + bp]\n\n");
+	fprintf(outputFile, "c1_execOpcode         - executes a function and sets the return value to the return value of the called function\n\n");
+	fprintf(outputFile, "c1_ifNotJmp           - jumps to address param if the stack top is zero\n\n");
+	fprintf(outputFile, "c1_negate             - dependent on param:\n");
+	fprintf(outputFile, "                      - 0: sets the stack top to 1 if the stack top is non-zero, if the stack top is zero it doesn't do anything\n");
+	fprintf(outputFile, "                      - 1: sets the stack top to -(stack top)\n");
+	fprintf(outputFile, "                      - 2: sets the stack top to ~(stack top)\n");
+	fprintf(outputFile, "                      - else: breaks execution\n\n");
+	fprintf(outputFile, "c1_eval               - pops val1 and val2 from the stack and does the given evaulation and pushes the result of it to the stack\n\n");
+	fprintf(outputFile, "c1_setRetAndJmp       - pops the return value from the stack, after that pops the new ip from the stack and jumps to that position\n\n");
+}
+
+// commands
+void c1_jumpTo(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_jumpTo 0x%.04X\n", (((uint)argument) << 1) & 0xFFFF);
+}
+
+void c1_setRetValue(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_setRetValue %d\n", argument);
+}
+
+void c1_pushRetOrPos(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_pushRetOrPos %d ", argument);
+	switch (argument) {
+	case 0:
+	case 1:
+		break;
+	
+	default:
+		fprintf(outputFile, "; called with illegal param! breaks execution!");
+		break;
+	}
+	fprintf(outputFile, "\n");
+}
+
+void c1_push(ScriptData *dataPtr, int argument) {
+#define posString(x) (char*)&dataPtr->text[READ_BE_UINT16(&((uint16 *)dataPtr->text)[(x)])]
+	if (argument < dataPtr->numStrings && argument > 0) {
+		fprintf(outputFile, "c1_push %d ; could be string '%s'\n", argument, posString(argument));
+	} else {
+		fprintf(outputFile, "c1_push %d\n", argument);
+	}
+#undef posString
+}
+
+void c1_pushVar(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_pushVar %d\n", argument);
+}
+
+void c1_pushBPNeg(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_pushBPNeg %d\n", argument);
+}
+
+void c1_pushBPAdd(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_pushBPAdd %d\n", argument);
+}
+
+void c1_popRetOrPos(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_popRetOrPos %d ", argument);
+	switch (argument) {
+	case 0:
+	case 1:
+		break;
+	
+	default:
+		fprintf(outputFile, "; called with illegal param! breaks execution!");
+		break;
+	}
+	fprintf(outputFile, "\n");
+}
+
+void c1_popVar(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_popVar %d\n", argument);
+}
+
+void c1_popBPNeg(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_popBPNeg %d\n", argument);
+}
+
+void c1_popBPAdd(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_popBPAdd %d\n", argument);
+}
+
+void c1_addSP(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_addSP %d\n", argument);
+}
+
+void c1_subSP(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_subSP %d\n", argument);
+}
+
+void c1_execOpcode(ScriptData *script, int argument) {
+	if ((uint8)argument >= (uint8)script->opcodeSize) {
+		fprintf(outputFile, "c1_execOpcode %d ; tries to call illegal opcode param and breaks exectuion\n", (uint8)argument);
+	} else {
+		fprintf(outputFile, "c1_execOpcode %d ; functionname: '%s'\n", (uint8)argument, script->opcodes[(uint8)argument].name);
+	}
+}
+
+void c1_ifNotJmp(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_ifNotJmp 0x%.04X\n", (((uint)argument) << 1) & 0xFFFF);
+}
+
+void c1_negate(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_negate %d ", argument);
+	switch (argument) {
+	case 0:
+	case 1:
+	case 2:
+		break;
+	
+	default:
+		fprintf(outputFile, "; called with illegal param! breaks execution");
+		break;
+	}
+	fprintf(outputFile, "\n");
+}
+
+void c1_eval(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_eval %d ; (C syntax): '", argument);
+	
+	switch (argument) {
+	case 0:
+		fprintf(outputFile, "(val2 && val1)");
+		break;
+	
+	case 1:
+		fprintf(outputFile, "(val2 || val1)");
+		break;
+	
+	case 2:
+		fprintf(outputFile, "(val1 == val2)");
+		break;
+	
+	case 3:
+		fprintf(outputFile, "(val1 != val2)");
+		break;
+	
+	case 4:
+		fprintf(outputFile, "(val1 > val2)");
+		break;
+	
+	case 5:
+		fprintf(outputFile, "(val1 >= val2)");
+		break;
+	
+	case 6:
+		fprintf(outputFile, "(val1 < val2)");
+		break;
+	
+	case 7:
+		fprintf(outputFile, "(val1 <= val2)");
+		break;
+	
+	case 8:
+		fprintf(outputFile, "val1 + val2");
+		break;
+	
+	case 9:
+		fprintf(outputFile, "val2 - val1");
+		break;
+	
+	case 10:
+		fprintf(outputFile, "val1 * val2");
+		break;
+	
+	case 11:
+		fprintf(outputFile, "val2 / val1");
+		break;
+	
+	case 12:
+		fprintf(outputFile, "val2 >> val1");
+		break;
+	
+	case 13:
+		fprintf(outputFile, "val2 << val1");
+		break;
+	
+	case 14:
+		fprintf(outputFile, "val1 & val2");
+		break;
+	
+	case 15:
+		fprintf(outputFile, "val1 | val2");
+		break;
+	
+	case 16:
+		fprintf(outputFile, "val2 %% val1");
+		break;
+	
+	case 17:
+		fprintf(outputFile, "val1 ^ val2");
+		break;
+	
+	default:
+		fprintf(outputFile, "!error breaking exectution!");
+		break;
+	}
+	
+	fprintf(outputFile, "'\n");
+}
+
+void c1_setRetAndJmp(ScriptData *script, int argument) {
+	fprintf(outputFile, "c1_setRetAndJmp %d\n", argument);
+}
+
+void setupCommandsV1(Script *myScript) {
+	static CommandProc commands[] = {
+		&c1_jumpTo,
+		&c1_setRetValue,
+		&c1_pushRetOrPos,
+		&c1_push,
+		&c1_push,
+		&c1_pushVar,
+		&c1_pushBPNeg,
+		&c1_pushBPAdd,
+		&c1_popRetOrPos,
+		&c1_popVar,
+		&c1_popBPNeg,
+		&c1_popBPAdd,
+		&c1_addSP,
+		&c1_subSP,
+		&c1_execOpcode,
+		&c1_ifNotJmp,
+		&c1_negate,
+		&c1_eval,
+		&c1_setRetAndJmp
+	};
+	
+	myScript->setCommands(commands, ARRAYSIZE(commands));
+}
+
+// trace commands
+void c1_traceJumpTo(ScriptData *script, int argument) {
+	Function *call = script->getFunction(((uint)argument) << 1);
+	if (call) {
+		for (int i = 0; i < call->refs; ++i) {
+			if (call->refOffs[i] == script->curOffset)
+				return;
+		}
+		
+		if (call->refs < MAX_REFS) {
+			call->refOffs[call->refs++] = script->curOffset;
+		} else {
+			warning("losing ref");
+		}
+	} else {
+		if (script->numFunctions < MAX_FUNCTIONS) {
+			call = &script->functions[script->numFunctions];
+			call->id = -1;
+			call->startOffset = ((uint)argument) << 1;
+			call->refOffs[call->refs++] = script->curOffset;
+			++script->numFunctions;
+		} else {
+			warning("losing function");
+		}
+	}
+}
+
+void c1_traceIfNotJmp(ScriptData *script, int argument) {
+	Function *call = script->getFunction(((uint)argument) << 1);
+	if (call) {
+		for (int i = 0; i < call->refs; ++i) {
+			if (call->refOffs[i] == script->curOffset)
+				return;
+		}
+		
+		if (call->refs < MAX_REFS) {
+			call->refOffs[call->refs++] = script->curOffset;
+		} else {
+			warning("losing ref");
+		}
+	} else {
+		if (script->numFunctions < MAX_FUNCTIONS) {
+			call = &script->functions[script->numFunctions];
+			call->id = -1;
+			call->startOffset = ((uint)argument) << 1;
+			call->refOffs[call->refs++] = script->curOffset;
+			++script->numFunctions;
+		} else {
+			warning("losing function");
+		}
+	}
+}
+
+void c1_traceSetRetAndJmp(ScriptData *script, int argument) {
+	Function *call = script->getFunction(((uint)argument) << 1);
+	if (call) {
+		for (int i = 0; i < call->refs; ++i) {
+			if (call->refOffs[i] == script->curOffset)
+				return;
+		}
+		
+		if (call->refs < MAX_REFS) {
+			call->refOffs[call->refs++] = script->curOffset;
+		} else {
+			warning("losing ref");
+		}
+	} else {
+		if (script->numFunctions < MAX_FUNCTIONS) {
+			call = &script->functions[script->numFunctions];
+			call->id = -1;
+			call->startOffset = ((uint)argument) << 1;
+			call->refOffs[call->refs++] = script->curOffset;
+			++script->numFunctions;
+		} else {
+			warning("losing function");
+		}
+	}
+}
+
+void setupTraceCommandsV1(Script *myScript) {
+	static CommandProc commands[] = {
+		&c1_traceJumpTo,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		0,
+		&c1_traceIfNotJmp,
+		0,
+		0,
+		&c1_traceSetRetAndJmp
+	};
+	
+	myScript->setCommands(commands, ARRAYSIZE(commands));
+}
+
+// opcode tables
+void getOpcodesV1(OpcodeEntry *&opcodes, int &opcodesSize) {
+	static OpcodeEntry kyra1OpcodeDesc[] = {
+		{ 0x00 ,"o1_magicInMouseItem" },
+		{ 0x01 ,"o1_characterSays" },
+		{ 0x02 ,"o1_pauseTicks" },
+		{ 0x03 ,"o1_drawSceneAnimShape" },
+		{ 0x04 ,"o1_queryGameFlag" },
+		{ 0x05 ,"o1_setGameFlag" },
+		{ 0x06 ,"o1_resetGameFlag" },
+		{ 0x07 ,"o1_runNPCScript" },
+		{ 0x08 ,"o1_setSpecialExitList" },
+		{ 0x09 ,"o1_blockInWalkableRegion" },
+		{ 0x0A ,"o1_blockOutWalkableRegion" },
+		{ 0x0B ,"o1_walkPlayerToPoint" },
+		{ 0x0C ,"o1_dropItemInScene" },
+		{ 0x0D ,"o1_drawAnimShapeIntoScene" },
+		{ 0x0E ,"o1_createMouseItem" },
+		{ 0x0F ,"o1_savePageToDisk" },
+		{ 0x10 ,"o1_sceneAnimOn" },
+		{ 0x11 ,"o1_sceneAnimOff" },
+		{ 0x12 ,"o1_elapsedSeconds" },
+		{ 0x13 ,"o1_mouseIsPointer" },
+		{ 0x14 ,"o1_destroyMouseItem" },
+		{ 0x15 ,"o1_runSceneAnimUntilDone" },
+		{ 0x16 ,"o1_fadeSpecialPalette" },
+		{ 0x17 ,"o1_playAdLibSound" },
+		{ 0x18 ,"o1_playAdLibScore" },
+		{ 0x19 ,"o1_phaseInSameScene" },
+		{ 0x1a ,"o1_setScenePhasingFlag" },
+		{ 0x1b ,"o1_resetScenePhasingFlag" },
+		{ 0x1c ,"o1_queryScenePhasingFlag" },
+		{ 0x1d ,"o1_sceneToDirection" },
+		{ 0x1e ,"o1_setBirthstoneGem" },
+		{ 0x1f ,"o1_rlaceItemInGenericMapScene" },
+		{ 0x20 ,"o1_setBrandonStatusBit" },
+		{ 0x21 ,"o1_pauseSeconds" },
+		{ 0x22 ,"o1_getCharactersLocation" },
+		{ 0x23 ,"o1_runNPCSubscript" },
+		{ 0x24 ,"o1_magicOutMouseItem" },
+		{ 0x25 ,"o1_internalAnimOn" },
+		{ 0x26 ,"o1_forceBrandonToNormal" },
+		{ 0x27 ,"o1_poisonDeathNow" },
+		{ 0x28 ,"o1_setScaleMode" },
+		{ 0x29 ,"o1_openWSAFile" },
+		{ 0x2a ,"o1_closeWSAFile" },
+		{ 0x2b ,"o1_runWSAFromBeginningToEnd" },
+		{ 0x2c ,"o1_displayWSAFrame" },
+		{ 0x2d ,"o1_enterNewScene" },
+		{ 0x2e ,"o1_setSpecialEnterXAndY" },
+		{ 0x2f ,"o1_runWSAFrames" },
+		{ 0x30 ,"o1_popBrandonIntoScene" },
+		{ 0x31 ,"o1_restoreAllObjectBackgrounds" },
+		{ 0x32 ,"o1_setCustomPaletteRange" },
+		{ 0x33 ,"o1_loadPageFromDisk" },		
+		{ 0x34 ,"o1_customPrintTalkString" },
+		{ 0x35 ,"o1_restoreCustomPrintBackground" },
+		{ 0x36 ,"o1_hideMouse" },
+		{ 0x37 ,"o1_showMouse" },
+		{ 0x38 ,"o1_getCharacterX" },
+		{ 0x39 ,"o1_getCharacterY" },
+		{ 0x3A ,"o1_changeCharactersFacing" },
+		{ 0x3B ,"o1_copyWSARegion" },
+		{ 0x3C ,"o1_textPrint" },
+		{ 0x3D ,"o1_random" },
+		{ 0x3E ,"o1_loadSoundFile" },
+		{ 0x3F ,"o1_displayWSAFrameOnHidPage" },
+		{ 0x40 ,"o1_displayWSASequentialFrames" },
+		{ 0x41 ,"o1_drawCharacterStanding" },
+		{ 0x42 ,"o1_internalAnimOff" },
+		{ 0x43 ,"o1_changeCharactersXAndY" },
+		{ 0x44 ,"o1_clearSceneAnimatorBeacon" },
+		{ 0x45 ,"o1_querySceneAnimatorBeacon" },
+		{ 0x46 ,"o1_refreshSceneAnimator" },
+		{ 0x47 ,"o1_placeItemInOffScene" },
+		{ 0x48 ,"o1_wipeDownMouseItem" },
+		{ 0x49 ,"o1_placeCharacterInOtherScene" },
+		{ 0x4A ,"o1_getKey" },
+		{ 0x4B ,"o1_specificItemInInventory" },
+		{ 0x4C ,"o1_popMobileNPCIntoScene" },
+		{ 0x4D ,"o1_mobileCharacterInScene" },
+		{ 0x4E ,"o1_hideMobileCharacter" },
+		{ 0x4F ,"o1_unhideMobileCharacter" },
+		{ 0x50 ,"o1_setCharactersLocation" },
+		{ 0x51 ,"o1_walkCharacterToPoint" },
+		{ 0x52 ,"o1_specialEventDisplayBrynnsNote" },
+		{ 0x53 ,"o1_specialEventRemoveBrynnsNote" },
+		{ 0x54 ,"o1_setLogicPage" },
+		{ 0x55 ,"o1_fatPrint" },
+		{ 0x56 ,"o1_preserveAllObjectBackgrounds" },
+		{ 0x57 ,"o1_updateSceneAnimations" },
+		{ 0x58 ,"o1_sceneAnimationActive" },
+		{ 0x59 ,"o1_setCharactersMovementDelay" },
+		{ 0x5A ,"o1_getCharactersFacing" },
+		{ 0x5B ,"o1_bkgdScrollSceneAndMasksRight" },
+		{ 0x5C ,"o1_dispelMagicAnimation" },
+		{ 0x5d ,"o1_findBrightestFireberry" },
+		{ 0x5e ,"o1_setFireberryGlowPalette" },
+		{ 0x5f ,"o1_setDeathHandlerFlag" },
+		{ 0x60 ,"o1_drinkPotionAnimation" },
+		{ 0x61 ,"o1_makeAmuletAppear" },
+		{ 0x62 ,"o1_drawItemShapeIntoScene" },
+		{ 0x63 ,"o1_setCharactersCurrentFrame" },
+		{ 0x64 ,"o1_waitForConfirmationMouseClick" },
+		{ 0x65 ,"o1_pageFlip" },
+		{ 0x66 ,"o1_setSceneFile" },
+		{ 0x67 ,"o1_whatItemInMarbleVase" },
+		{ 0x68 ,"o1_setItemInMarbleVase" },
+		{ 0x69 ,"o1_addItemToInventory" },
+		{ 0x6a ,"o1_intPrint" },
+		{ 0x6b ,"o1_shakeScreen" },
+		{ 0x6c ,"o1_createAmuletJewel" },
+		{ 0x6d ,"o1_setSceneAnimCurrXY" },
+		{ 0x6e ,"o1_poisonBrandonAndRemaps" },
+		{ 0x6f ,"o1_fillFlaskWithWater" },
+		{ 0x70 ,"o1_getCharactersMovementDelay" },
+		{ 0x71 ,"o1_getBirthstoneGem" },
+		{ 0x72 ,"o1_queryBrandonStatusBit" },
+		{ 0x73 ,"o1_playFluteAnimation" },
+		{ 0x74 ,"o1_playWinterScrollSequence" },
+		{ 0x75 ,"o1_getIdolGem" },
+		{ 0x76 ,"o1_setIdolGem" },
+		{ 0x77 ,"o1_totalItemsInScene" },
+		{ 0x78 ,"o1_restoreBrandonsMovementDelay" },
+		{ 0x79 ,"o1_setMousePos" },
+		{ 0x7a ,"o1_getMouseState" },
+		{ 0x7b ,"o1_setEntranceMouseCursorTrack" },
+		{ 0x7c ,"o1_itemAppearsOnGround" },
+		{ 0x7d ,"o1_setNoDrawShapesFlag" },
+		{ 0x7e ,"o1_fadeEntirePalette" },
+		{ 0x7f ,"o1_itemOnGroundHere" },
+		{ 0x80 ,"o1_queryCauldronState" },
+		{ 0x81 ,"o1_setCauldronState" },
+		{ 0x82 ,"o1_queryCrystalState" },
+		{ 0x83 ,"o1_setCrystalState" },
+		{ 0x84 ,"o1_setPaletteRange" },
+		{ 0x85 ,"o1_shrinkBrandonDown" },
+		{ 0x86 ,"o1_growBrandonUp" },
+		{ 0x87 ,"o1_setBrandonScaleXAndY" },
+		{ 0x88 ,"o1_resetScaleMode" },
+		{ 0x89 ,"o1_getScaleDepthTableValue" },
+		{ 0x8a ,"o1_setScaleDepthTableValue" },
+		{ 0x8b ,"o1_message" },
+		{ 0x8c ,"o1_checkClickOnNPC" },
+		{ 0x8d ,"o1_getFoyerItem" },
+		{ 0x8e ,"o1_setFoyerItem" },
+		{ 0x8F ,"o1_setNoItemDropRegion" },
+		{ 0x90 ,"o1_walkMalcolmOn" },
+		{ 0x91 ,"o1_passiveProtection" },
+		{ 0x92 ,"o1_setPlayingLoop" },
+		{ 0x93 ,"o1_brandonToStoneSequence" },
+		{ 0x94 ,"o1_brandonHealingSequence" },
+		{ 0x95 ,"o1_protectCommandLine" },
+		{ 0x96 ,"o1_pauseMusicSeconds" },
+		{ 0x97 ,"o1_resetMaskRegion" },
+		{ 0x98 ,"o1_setPaletteChangeFlag" },
+		{ 0x99 ,"o1_fillRect" },
+		{ 0x9a ,"o1_vocUnload" },
+		{ 0x9b ,"o1_vocLoad" },
+		{ 0x9c ,"o1_dummy" }
+	};
+	
+	opcodes = kyra1OpcodeDesc;
+	opcodesSize = ARRAYSIZE(kyra1OpcodeDesc);
+}


Property changes on: tools/trunk/dekyra_v1.cpp
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id,URL
Name: svn:eol-style
   + native






More information about the Scummvm-git-logs mailing list