[Scummvm-cvs-logs] SF.net SVN: scummvm: [32202] scummvm/trunk/engines/made

john_doe at users.sourceforge.net john_doe at users.sourceforge.net
Tue May 20 22:00:14 CEST 2008


Revision: 32202
          http://scummvm.svn.sourceforge.net/scummvm/?rev=32202&view=rev
Author:   john_doe
Date:     2008-05-20 13:00:10 -0700 (Tue, 20 May 2008)

Log Message:
-----------
- Implemented "stand-alone" script dumper/disassembler; it can be enabled by defining DUMP_SCRIPTS in script.h and starting with at least debug level 1.
- Commented which script opcodes and extended functions are actually used or not.

Modified Paths:
--------------
    scummvm/trunk/engines/made/database.h
    scummvm/trunk/engines/made/made.cpp
    scummvm/trunk/engines/made/script.cpp
    scummvm/trunk/engines/made/script.h
    scummvm/trunk/engines/made/scriptfuncs.cpp
    scummvm/trunk/engines/made/scriptfuncs.h

Modified: scummvm/trunk/engines/made/database.h
===================================================================
--- scummvm/trunk/engines/made/database.h	2008-05-20 19:56:49 UTC (rev 32201)
+++ scummvm/trunk/engines/made/database.h	2008-05-20 20:00:10 UTC (rev 32202)
@@ -95,6 +95,8 @@
 			return NULL;
 	}
 
+	uint getObjectCount() const { return _objects.size(); }
+
 	int16 getMainCodeObjectIndex() const { return _mainCodeObjectIndex; }
 
 	int16 getVar(int16 index);

Modified: scummvm/trunk/engines/made/made.cpp
===================================================================
--- scummvm/trunk/engines/made/made.cpp	2008-05-20 19:56:49 UTC (rev 32201)
+++ scummvm/trunk/engines/made/made.cpp	2008-05-20 20:00:10 UTC (rev 32202)
@@ -206,7 +206,12 @@
 	}
 
 	_eventKey = _eventMouseX = _eventMouseY = 0;
+	
+#ifdef DUMP_SCRIPTS
+	_script->dumpAllScripts();
+#else
 	_script->runScript(_dat->getMainCodeObjectIndex());
+#endif
 
 	return 0;
 }

Modified: scummvm/trunk/engines/made/script.cpp
===================================================================
--- scummvm/trunk/engines/made/script.cpp	2008-05-20 19:56:49 UTC (rev 32201)
+++ scummvm/trunk/engines/made/script.cpp	2008-05-20 20:00:10 UTC (rev 32202)
@@ -91,83 +91,87 @@
 /* ScriptInterpreter */
 
 ScriptInterpreter::ScriptInterpreter(MadeEngine *vm) : _vm(vm) {
-#define COMMAND(x) { &ScriptInterpreter::x, #x }
+#ifdef DUMP_SCRIPTS
+#define COMMAND(x, sig) { &ScriptInterpreter::x, #x, sig }
+#else
+#define COMMAND(x, sig) { &ScriptInterpreter::x, #x}
+#endif
 	static CommandEntry commandProcs[] = {
 		/* 01 */
-		COMMAND(cmd_branchTrue),
-		COMMAND(cmd_branchFalse),
-		COMMAND(cmd_branch),
-		COMMAND(cmd_true),
+		COMMAND(cmd_branchTrue, "W"),
+		COMMAND(cmd_branchFalse, "W"),
+		COMMAND(cmd_branch, "W"),
+		COMMAND(cmd_true, ""),
 		/* 05 */
-		COMMAND(cmd_false),
-		COMMAND(cmd_push),
-		COMMAND(cmd_not),
-		COMMAND(cmd_add),
+		COMMAND(cmd_false, ""),
+		COMMAND(cmd_push, ""),
+		COMMAND(cmd_not, ""),
+		COMMAND(cmd_add, ""),
 		/* 09 */
-		COMMAND(cmd_sub),
-		COMMAND(cmd_mul),
-		COMMAND(cmd_div),
-		COMMAND(cmd_mod),
+		COMMAND(cmd_sub, ""),
+		COMMAND(cmd_mul, ""),
+		COMMAND(cmd_div, ""),
+		COMMAND(cmd_mod, ""),
 		/* 13 */
-		COMMAND(cmd_band),
-		COMMAND(cmd_bor),
-		COMMAND(cmd_bnot),
-		COMMAND(cmd_lt),
+		COMMAND(cmd_band, ""),
+		COMMAND(cmd_bor, ""),
+		COMMAND(cmd_bnot, ""),
+		COMMAND(cmd_lt, ""),
 		/* 17 */
-		COMMAND(cmd_eq),
-		COMMAND(cmd_gt),
-		COMMAND(cmd_loadConstant),
-		COMMAND(cmd_loadVariable),
+		COMMAND(cmd_eq, ""),
+		COMMAND(cmd_gt, ""),
+		COMMAND(cmd_loadConstant, "w"),
+		COMMAND(cmd_loadVariable, "w"),
 		/* 21 */
-		COMMAND(cmd_getObjectProperty),
-		COMMAND(cmd_setObjectProperty),
-		COMMAND(cmd_set),
-		COMMAND(cmd_print),
+		COMMAND(cmd_getObjectProperty, ""),
+		COMMAND(cmd_setObjectProperty, ""),
+		COMMAND(cmd_set, "w"),
+		COMMAND(cmd_print, ""),
 		/* 25 */
-		COMMAND(cmd_terpri),
-		COMMAND(cmd_printNumber),
-		COMMAND(cmd_vref),
-		COMMAND(cmd_vset),
+		COMMAND(cmd_terpri, ""),
+		COMMAND(cmd_printNumber, ""),
+		COMMAND(cmd_vref, ""),
+		COMMAND(cmd_vset, ""),
 		/* 29 */
-		COMMAND(cmd_vsize),
-		COMMAND(cmd_exit),
-		COMMAND(cmd_return),
-		COMMAND(cmd_call),
+		COMMAND(cmd_vsize, ""),
+		COMMAND(cmd_exit, ""),
+		COMMAND(cmd_return, ""),
+		COMMAND(cmd_call, "b"),
 		/* 33 */
-		COMMAND(cmd_svar),
-		COMMAND(cmd_sset),
-		COMMAND(cmd_split),
-		COMMAND(cmd_snlit),
+		COMMAND(cmd_svar, ""),
+		COMMAND(cmd_sset, ""),
+		COMMAND(cmd_split, ""),
+		COMMAND(cmd_snlit, ""),
 		/* 37 */
-		COMMAND(cmd_yorn),
-		COMMAND(cmd_save),
-		COMMAND(cmd_restore),
-		COMMAND(cmd_arg),
+		COMMAND(cmd_yorn, ""),
+		COMMAND(cmd_save, ""),
+		COMMAND(cmd_restore, ""),
+		COMMAND(cmd_arg, "b"),
 		/* 41 */
-		COMMAND(cmd_aset),
-		COMMAND(cmd_tmp),
-		COMMAND(cmd_tset),
-		COMMAND(cmd_tspace),
+		COMMAND(cmd_aset, "b"),
+		COMMAND(cmd_tmp, "b"),
+		COMMAND(cmd_tset, "b"),
+		COMMAND(cmd_tspace, "b"),
 		/* 45 */
-		COMMAND(cmd_class),
-		COMMAND(cmd_objectp),
-		COMMAND(cmd_vectorp),
-		COMMAND(cmd_restart),
+		COMMAND(cmd_class, ""),
+		COMMAND(cmd_objectp, ""),
+		COMMAND(cmd_vectorp, ""),
+		COMMAND(cmd_restart, ""),
 		/* 49 */
-		COMMAND(cmd_rand),
-		COMMAND(cmd_randomize),
-		COMMAND(cmd_send),
-		COMMAND(cmd_extend),
+		COMMAND(cmd_rand, ""),
+		COMMAND(cmd_randomize, ""),
+		COMMAND(cmd_send, "b"),
+		COMMAND(cmd_extend, "Eb"),
 		/* 53 */
-		COMMAND(cmd_catch),
-		COMMAND(cmd_cdone),
-		COMMAND(cmd_throw),
-		COMMAND(cmd_functionp),
+		COMMAND(cmd_catch, ""),
+		COMMAND(cmd_cdone, ""),
+		COMMAND(cmd_throw, ""),
+		COMMAND(cmd_functionp, ""),
 		/* 57 */
-		COMMAND(cmd_le),
-		COMMAND(cmd_ge),
-		COMMAND(cmd_varx),
-		COMMAND(cmd_setx)
+		COMMAND(cmd_le, ""),
+		COMMAND(cmd_ge, ""),
+		COMMAND(cmd_varx, ""),
+		COMMAND(cmd_setx, "")
 	};
 	_commands = commandProcs;
 	_commandsMax = ARRAYSIZE(commandProcs) + 1;
@@ -175,9 +179,6 @@
 	_functions = new ScriptFunctions(_vm);
 	_functions->setupExternalsTable();
 	
-	// set to true to dump scripts instead of parsing them
-	_dumpScripts = false;
-
 #undef COMMAND
 }
 
@@ -217,27 +218,18 @@
 }
 
 void ScriptInterpreter::cmd_branchTrue() {
-	if (_dumpScripts)
-		return;
-
 	int16 ofs = readInt16();
 	if (_stack.top() != 0)
 		_codeIp = _codeBase + ofs;
 }
 
 void ScriptInterpreter::cmd_branchFalse() {
-	if (_dumpScripts)
-		return;
-
 	int16 ofs = readInt16();
 	if (_stack.top() == 0)
 		_codeIp = _codeBase + ofs;
 }
 
 void ScriptInterpreter::cmd_branch() {
-	if (_dumpScripts)
-		return;
-
 	int16 ofs = readInt16();
 	_codeIp = _codeBase + ofs;
 }
@@ -459,29 +451,31 @@
 }
 
 void ScriptInterpreter::cmd_svar() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_svar");
 }
 
 void ScriptInterpreter::cmd_sset() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_sset");
 }
 
 void ScriptInterpreter::cmd_split() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_split");
 }
 
 void ScriptInterpreter::cmd_snlit() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_snlit");
 }
 
 void ScriptInterpreter::cmd_yorn() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_yorn");
 }
 
 void ScriptInterpreter::cmd_save() {
-	if (_dumpScripts)
-		return;
-
 	int16 result = 0;
 	int16 stringOfs = _stack.top();
 	const char *filename = _vm->_dat->getString(stringOfs);
@@ -490,9 +484,6 @@
 }
 
 void ScriptInterpreter::cmd_restore() {
-	if (_dumpScripts)
-		return;
-
 	int16 result = 0;
 	int16 stringOfs = _stack.top();
 	const char *filename = _vm->_dat->getString(stringOfs);
@@ -531,6 +522,7 @@
 }
 
 void ScriptInterpreter::cmd_class() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_class");
 }
 
@@ -543,10 +535,12 @@
 }
 
 void ScriptInterpreter::cmd_vectorp() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_vectorp");
 }
 
 void ScriptInterpreter::cmd_restart() {
+	// TODO: Used in RTZ
 	warning("Unimplemented command: cmd_restart");
 }
 
@@ -613,9 +607,6 @@
 	for (int i = 0; i < argc; i++)
 		debug(2, "argv[%02d] = %04X (%d)", i, argv[i], argv[i]);
 
-	if (_dumpScripts)
-		return;
-
 	int16 result = _functions->callFunction(func, argc, argv);
 	debug(2, "result = %04X (%d)", result, result);
 	
@@ -626,18 +617,22 @@
 }
 
 void ScriptInterpreter::cmd_catch() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_catch");
 }
 
 void ScriptInterpreter::cmd_cdone() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_cdone");
 }
 
 void ScriptInterpreter::cmd_throw() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_throw");
 }
 
 void ScriptInterpreter::cmd_functionp() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_functionp");
 }
 
@@ -658,11 +653,133 @@
 }
 
 void ScriptInterpreter::cmd_varx() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_varx");
 }
 
 void ScriptInterpreter::cmd_setx() {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented command: cmd_setx");
 }
 
+#ifdef DUMP_SCRIPTS
+void ScriptInterpreter::dumpScript(int16 objectIndex, int *opcodeStats, int *externStats) {
+
+	debug(1, "Dumping code for object %04X", objectIndex);
+
+	Object *obj = _vm->_dat->getObject(objectIndex);
+	byte *code = obj->getData(), *codeEnd = code + obj->getSize();
+	
+	while (code < codeEnd) {
+		byte opcode = *code++;
+		if (opcode >= 1 && opcode <= _commandsMax) {
+			Common::String codeLine;
+			const char *desc = _commands[opcode - 1].desc;
+			const char *sig = _commands[opcode - 1].sig;
+			int valueType; /* 0: dec; 1: hex; 2: extended function */
+			int16 value;
+			char tempStr[32];
+			if (opcodeStats)
+				opcodeStats[opcode - 1]++;
+			codeLine += desc;
+			for (; *sig != '\0'; sig++) {
+				codeLine += " ";
+				// Fallthroughs are intended
+				switch (*sig) {
+				case 'b':
+					valueType = 0;
+	 				value = *code++;
+					break;
+				case 'B':
+	 				valueType = 1;
+	 				value = *code++;
+					break;
+				case 'w':
+					valueType = 0;
+	 				value = READ_LE_UINT16(code);
+	 				code += 2;
+					break;
+				case 'W':
+	 				valueType = 1;
+	 				value = READ_LE_UINT16(code);
+	 				code += 2;
+					break;
+				case 'E':
+	 				valueType = 2;
+	 				value = *code++;
+					break;
+				}
+				switch (valueType) {
+				case 0:
+					snprintf(tempStr, 32, "%d", value);
+					break;
+				case 1:
+					snprintf(tempStr, 32, "0x%X", value);
+					break;
+				case 2:
+					if (value < _functions->getCount()) {
+						snprintf(tempStr, 32, "%s", _functions->getFuncName(value));
+						externStats[value]++;
+					} else {
+						snprintf(tempStr, 32, "invalid: %d", value);
+	 				}
+					break;
+				}
+				codeLine += tempStr;
+			}
+			debug(1, "%s", codeLine.c_str());
+		} else {
+			error("ScriptInterpreter::dumpScript(%d) Unknown opcode %02X", objectIndex, opcode);
+		}
+	}
+	debug(1, "-------------------------------------------");
+}
+
+void ScriptInterpreter::dumpAllScripts() {
+	int *opcodeStats = new int[_commandsMax - 1];
+	int *externStats = new int[_functions->getCount()];
+
+	for (int i = 0; i < _commandsMax; i++)
+		opcodeStats[i] = 0;
+	for (int i = 0; i < _functions->getCount(); i++)
+		externStats[i] = 0;
+
+	for (uint objectIndex = 1; objectIndex <= _vm->_dat->getObjectCount(); objectIndex++) {
+		Object *obj = _vm->_dat->getObject(objectIndex);
+		// Check if it's a byte array which might contain code
+		if (obj->getClass() != 0x7FFF)
+			continue;
+		// Code objects aren't excplicitly marked as such, we need to check if
+		// the last byte is a cmd_return opcode.
+		byte *retByte = obj->getData() + obj->getSize() - 1;
+		if (*retByte == 0x1F) {
+			dumpScript(objectIndex, opcodeStats, externStats);
+		}
+	}
+
+	debug(1, "OPCODE statistics:");
+	for (int i = 0; i < _commandsMax - 1; i++)
+		if (opcodeStats[i] > 0)
+			debug(1, "%-30s: %d", _commands[i].desc, opcodeStats[i]);
+	debug(1, "UNUSED OPCODE statistics:");
+	for (int i = 0; i < _commandsMax - 1; i++)
+		if (opcodeStats[i] == 0)
+			debug(1, "%-30s: %d", _commands[i].desc, opcodeStats[i]);
+	debug(1, ".");
+
+	debug(1, "EXTERN statistics (%d):", _functions->getCount());
+	for (int i = 0; i < _functions->getCount(); i++)
+		if (externStats[i] > 0)
+			debug(1, "%-30s: %d", _functions->getFuncName(i), externStats[i]);
+	debug(1, "UNUSED EXTERN statistics (%d):", _functions->getCount());
+	for (int i = 0; i < _functions->getCount(); i++)
+		if (externStats[i] == 0)
+			debug(1, "%-30s: %d", _functions->getFuncName(i), externStats[i]);
+	debug(1, ".");
+
+	delete[] opcodeStats;
+	delete[] externStats;
+}
+#endif
+
 } // End of namespace Made

Modified: scummvm/trunk/engines/made/script.h
===================================================================
--- scummvm/trunk/engines/made/script.h	2008-05-20 19:56:49 UTC (rev 32201)
+++ scummvm/trunk/engines/made/script.h	2008-05-20 20:00:10 UTC (rev 32202)
@@ -32,6 +32,11 @@
 
 namespace Made {
 
+// Define this to dump all game scripts and a usage statistic of all
+// opcodes/extended functions instead of running the actual game.
+// Then run ScummVM with debuglevel 1.
+//#define DUMP_SCRIPTS
+
 class MadeEngine;
 class ScriptFunctions;
 
@@ -63,6 +68,8 @@
 	ScriptInterpreter(MadeEngine *vm);
 	~ScriptInterpreter();
 	void runScript(int16 scriptObjectIndex);
+	void dumpScript(int16 objectIndex, int *opcodeStats, int *externStats);
+	void dumpAllScripts();
 protected:
 	MadeEngine *_vm;
 
@@ -71,7 +78,6 @@
 	int16 _runningScriptObjectIndex;
 	byte *_codeBase, *_codeIp;
 	bool _terminated;
-	bool _dumpScripts;
 
 	ScriptFunctions *_functions;
 
@@ -82,6 +88,9 @@
 	struct CommandEntry {
 		CommandProc proc;
 		const char *desc;
+#ifdef DUMP_SCRIPTS
+		const char *sig;
+#endif
 	};
 
 	const CommandEntry *_commands;

Modified: scummvm/trunk/engines/made/scriptfuncs.cpp
===================================================================
--- scummvm/trunk/engines/made/scriptfuncs.cpp	2008-05-20 19:56:49 UTC (rev 32201)
+++ scummvm/trunk/engines/made/scriptfuncs.cpp	2008-05-20 20:00:10 UTC (rev 32202)
@@ -319,6 +319,7 @@
 }
 
 int16 ScriptFunctions::sfSetTextPos(int16 argc, int16 *argv) {
+	// TODO: Used in Manhole:NE
 	warning("Unimplemented opcode: sfSetTextPos");
 	// This seems to be some kind of low-level opcode.
 	// The original engine calls int 10h to set the VGA cursor position.
@@ -331,21 +332,25 @@
 }
 
 int16 ScriptFunctions::sfPlayNote(int16 argc, int16 *argv) {
+	// TODO: Used in Manhole:NE
 	warning("Unimplemented opcode: sfPlayNote");
 	return 0;
 }
 
 int16 ScriptFunctions::sfStopNote(int16 argc, int16 *argv) {
+	// TODO: Used in Manhole:NE
 	warning("Unimplemented opcode: sfStopNote");
 	return 0;
 }
 
 int16 ScriptFunctions::sfPlayTele(int16 argc, int16 *argv) {
+	// TODO: Used in Manhole:NE
 	warning("Unimplemented opcode: sfPlayTele");
 	return 0;
 }
 
 int16 ScriptFunctions::sfStopTele(int16 argc, int16 *argv) {
+	// TODO: Used in Manhole:NE
 	warning("Unimplemented opcode: sfStopTele");
 	return 0;
 }
@@ -374,7 +379,7 @@
 
 int16 ScriptFunctions::sfAddSprite(int16 argc, int16 *argv) {
 	if (_vm->getGameID() == GID_RTZ) {
-		warning("Unimplemented opcode: sfAddSprite");
+		// Unused in RTZ
 		return 0;
 	} if (_vm->getGameID() == GID_LGOP2 || _vm->getGameID() == GID_MANHOLE) {
 		return argv[2];
@@ -483,6 +488,7 @@
 }
 
 int16 ScriptFunctions::sfHomeText(int16 argc, int16 *argv) {
+	// TODO: Used in LGOP2
 	warning("Unimplemented opcode: sfHomeText");
 	return 0;
 }
@@ -542,6 +548,7 @@
 }
 
 int16 ScriptFunctions::sfLoadResText(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfLoadResText");
 	return 0;
 }
@@ -611,6 +618,7 @@
 }
 
 int16 ScriptFunctions::sfPlayCdSegment(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfPlayCdSegment");
 	return 0;
 }
@@ -623,6 +631,7 @@
 }
 
 int16 ScriptFunctions::sfClearMono(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfClearMono");
 	return 0;
 }
@@ -637,11 +646,13 @@
 }
 
 int16 ScriptFunctions::sfClearText(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfClearText");
 	return 1;
 }
 
 int16 ScriptFunctions::sfAnimText(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfAnimText");
 	return 0;
 }
@@ -692,11 +703,13 @@
 }
 
 int16 ScriptFunctions::sfSetMusicVolume(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfSetMusicVolume");
 	return 0;
 }
 
 int16 ScriptFunctions::sfRestartEvents(int16 argc, int16 *argv) {
+	// TODO: Used in RTZ
 	warning("Unimplemented opcode: sfRestartEvents");
 	return 0;
 }
@@ -724,11 +737,13 @@
 }
 
 int16 ScriptFunctions::sfSetChannelLocation(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfSetChannelLocation");
 	return 0;
 }
 
 int16 ScriptFunctions::sfSetChannelContent(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfSetChannelContent");
 	return 0;
 }
@@ -796,6 +811,7 @@
 }
 
 int16 ScriptFunctions::sfDrawAnimPic(int16 argc, int16 *argv) {
+	// TODO: Used in RTZ
 	warning("Unimplemented opcode: sfDrawAnimPic");
 	return 0;
 }
@@ -810,6 +826,7 @@
 }
 
 int16 ScriptFunctions::sfReadText(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfReadText");
 	return 0;
 }
@@ -913,11 +930,13 @@
 }
 
 int16 ScriptFunctions::sfShakeScreen(int16 argc, int16 *argv) {
+	// TODO: Used in RTZ
 	warning("Unimplemented opcode: sfShakeScreen");
 	return 0;
 }
 
 int16 ScriptFunctions::sfPlaceMenu(int16 argc, int16 *argv) {
+	// Never used in LGOP2, RTZ, Manhole:NE
 	warning("Unimplemented opcode: sfPlaceMenu");
 	return 0;
 }

Modified: scummvm/trunk/engines/made/scriptfuncs.h
===================================================================
--- scummvm/trunk/engines/made/scriptfuncs.h	2008-05-20 19:56:49 UTC (rev 32201)
+++ scummvm/trunk/engines/made/scriptfuncs.h	2008-05-20 20:00:10 UTC (rev 32202)
@@ -54,6 +54,7 @@
 	}
 	void setupExternalsTable();
 	const char* getFuncName(int index) { return _externalFuncNames[index]; }
+	int getCount() const { return _externalFuncs.size(); }
 protected:
 	MadeEngine *_vm;
 	Audio::SoundHandle _audioStreamHandle;


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