[Scummvm-cvs-logs] SF.net SVN: scummvm:[51481] tools/branches/gsoc2010-decompiler/decompiler

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Thu Jul 29 23:09:47 CEST 2010


Revision: 51481
          http://scummvm.svn.sourceforge.net/scummvm/?rev=51481&view=rev
Author:   pidgeot
Date:     2010-07-29 21:09:47 +0000 (Thu, 29 Jul 2010)

Log Message:
-----------
Finish disassembly of KYRA opcodes

Only Hand of Fate is handled, so change engine identifier accordingly
Still need to do function detection - metadata will be added later

Modified Paths:
--------------
    tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp

Modified: tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp	2010-07-29 20:37:56 UTC (rev 51480)
+++ tools/branches/gsoc2010-decompiler/decompiler/decompiler.cpp	2010-07-29 21:09:47 UTC (rev 51481)
@@ -44,7 +44,7 @@
 		std::map<std::string, std::string> engines;
 		ObjectFactory<Engine> engineFactory;
 
-		ENGINE("kyra", "Kyrandia", Kyra::Engine);
+		ENGINE("kyra2", "Legend of Kyrandia: Hand of Fate", Kyra::Engine);
 		ENGINE("scummv6", "SCUMM v6", Scumm::v6::Engine);
 
 		po::options_description visible("Options");

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-07-29 20:37:56 UTC (rev 51480)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-07-29 21:09:47 UTC (rev 51481)
@@ -25,6 +25,235 @@
 #include <iostream>
 #include <boost/format.hpp>
 
+struct FunctionData {
+  std::string _name;
+	std::string _metadata;
+};
+
+static FunctionData kyra2FuncDesc[] = {
+	// 0x00
+	{ "setCharacterFacingRefresh", "" },
+	{ "setCharacterPos", "" },
+	{ "defineObject", "" },
+	{ "refreshCharacter", "" },
+	// 0x04
+	{ "getCharacterX", "" },
+	{ "getCharacterY", "" },
+	{ "getCharacterFacing", "" },
+	{ "getCharacterScene", "" },
+	// 0x08
+	{ "setSceneComment", "" },
+	{ "", "" },
+	{ "", "" },
+	{ "setCharacterAnimFrame", "" },
+	// 0x0c
+	{ "setCharacterFacingOverwrite", "" },
+	{ "trySceneChange", "" },
+	{ "moveCharacter", "" },
+	{ "customCharacterChat", "" },
+	// 0x10
+	{ "soundFadeOut", "" },
+	{ "showChapterMessage", "" },
+	{ "restoreTalkTextMessageBkgd", "" },
+	{ "", "" },
+	// 0x14
+	{ "wsaClose", "" },
+	{ "backUpScreen", "" },
+	{ "restoreScreen", "" },
+	{ "displayWsaFrame", "" },
+	// 0x18
+	{ "displayWsaSequentialFramesLooping", "" },
+	{ "wsaOpen", "" },
+	{ "displayWsaSequentialFrames", "" },
+	{ "displayWsaSequence", "" },
+	// 0x1c
+	{ "addItemToInventory", "" },
+	{ "drawShape", "" },
+	{ "addItemToCurScene", "" },
+	{ "dummy1F", "" },	// the original used this opcode to limit the mouse range temporary,
+						// since that is of no use and not really important we just use a dummy here
+	// 0x20
+	{ "checkForItem", "" },
+	{ "loadSoundFile", "" },
+	{ "removeSlotFromInventory", "" },
+	{ "defineItem", "" },
+	// 0x24
+	{ "removeItemFromInventory", "" },
+	{ "countItemInInventory", "" },
+	{ "countItemsInScene", "" },
+	{ "queryGameFlag", "" },
+	// 0x28
+	{ "resetGameFlag", "" },
+	{ "setGameFlag", "" },
+	{ "setHandItem", "" },
+	{ "removeHandItem", "" },
+	// 0x2c
+	{ "getMouseState", "" },
+	{ "hideMouse", "" },
+	{ "addSpecialExit", "" },
+	{ "setMousePos", "" },
+	// 0x30
+	{ "showMouse", "" },
+	{ "", "" },
+	{ "wipeDownMouseItem", "" },
+	{ "getElapsedSecs", "" },
+	// 0x34
+	{ "getTimerDelay", "" },
+	{ "playSoundEffect", "" },
+	{ "delaySecs", "" },
+	{ "delay", "" },
+	// 0x38
+	{ "dummy38", "" },
+	{ "setTimerDelay", "" },
+	{ "setScaleTableItem", "" },
+	{ "setDrawLayerTableItem", "" },
+	// 0x3c
+	{ "setCharPalEntry", "" },
+	{ "loadZShapes", "" },
+	{ "drawSceneShape", "" },
+	{ "drawSceneShapeOnPage", "" },
+	// 0x40
+	{ "disableAnimObject", "" },
+	{ "enableAnimObject", "" },
+	{ "dummy42", "" },
+	{ "loadPalette384", "" },
+	// 0x44
+	{ "setPalette384", "" },
+	{ "restoreBackBuffer", "" },
+	{ "backUpInventoryGfx", "" },
+	{ "disableSceneAnim", "" },
+	// 0x48
+	{ "enableSceneAnim", "" },
+	{ "restoreInventoryGfx", "" },
+	{ "setSceneAnimPos2", "" },
+	{ "update", "" },
+	// 0x4c
+	{ "", "" },
+	{ "fadeScenePal", "" },
+	{ "dummy4E", "" },
+	{ "dummy4F", "" },
+	// 0x50
+	{ "enterNewScene", "" },
+	{ "switchScene", "" },
+	{ "getShapeFlag1", "" },
+	{ "setPathfinderFlag", "" },
+	// 0x54
+	{ "getSceneExitToFacing", "" },
+	{ "setLayerFlag", "" },
+	{ "setZanthiaPos", "" },
+	{ "loadMusicTrack", "" },
+	// 0x58
+	{ "playWanderScoreViaMap", "" },
+	{ "playSoundEffect", "" },
+	{ "setSceneAnimPos", "" },
+	{ "blockInWalkableRegion", "" },
+	// 0x5c
+	{ "blockOutWalkableRegion", "" },
+	{ "", "" },
+	{ "setCauldronState", "" },
+	{ "showItemString", "" },
+	// 0x60
+	{ "getRand", "" },
+	{ "isAnySoundPlaying", "" },
+	{ "setDeathHandler", "" },
+	{ "setDrawNoShapeFlag", "" },
+	// 0x64
+	{ "setRunFlag", "" },
+	{ "showLetter", "" },
+	{ "", "" },
+	{ "fillRect", "" },
+	// 0x68
+	{ "", "" },
+	{ "", "" },
+	{ "playFireflyScore", "" },
+	{ "waitForConfirmationClick", "" },
+	// 0x6c
+	{ "encodeShape", "" },
+	{ "defineRoomEntrance", "" },
+	{ "runAnimationScript", "" },
+	{ "setSpecialSceneScriptRunTime", "" },
+	// 0x70
+	{ "defineSceneAnim", "" },
+	{ "updateSceneAnim", "" },
+	{ "updateSceneAnim", "" },
+	{ "addToSceneAnimPosAndUpdate", "" },
+	// 0x74
+	{ "useItemOnMainChar", "" },
+	{ "startDialogue", "" },
+	{ "randomSceneChat", "" },
+	{ "setDlgIndex", "" },
+	// 0x78
+	{ "getDlgIndex", "" },
+	{ "defineScene", "" },
+	{ "addCauldronStateTableEntry", "" },
+	{ "setCountDown", "" },
+	// 0x7c
+	{ "getCountDown", "" },
+	{ "dummy7D", "" },
+	{ "dummy7E", "" },
+	{ "pressColorKey", "" },
+	// 0x80
+	{ "objectChat", "" },
+	{ "changeChapter", "" },
+	{ "getColorCodeFlag1", "" },
+	{ "setColorCodeFlag1", "" },
+	// 0x84
+	{ "getColorCodeFlag2", "" },
+	{ "setColorCodeFlag2", "" },
+	{ "getColorCodeValue", "" },
+	{ "setColorCodeValue", "" },
+	// 0x88
+	{ "countItemInstances", "" },
+	{ "removeItemFromScene", "" },
+	{ "initObject", "" },
+	{ "npcChat", "" },
+	// 0x8c
+	{ "deinitObject", "" },
+	{ "playTimSequence", "" },
+	{ "makeBookOrCauldronAppear", "" },
+	{ "setSpecialSceneScriptState", "" },
+	// 0x90
+	{ "clearSpecialSceneScriptState", "" },
+	{ "querySpecialSceneScriptState", "" },
+	{ "resetInputColorCode", "" },
+	{ "setHiddenItemsEntry", "" },
+	// 0x94
+	{ "getHiddenItemsEntry", "" },
+	{ "mushroomEffect", "" },
+	{ "wsaClose", "" },
+	{ "meanWhileScene", "" },
+	// 0x98
+	{ "customChat", "" },
+	{ "customChatFinish", "" },
+	{ "setupSceneAnimation", "" },
+	{ "stopSceneAnimation", "" },
+	// 0x9c
+	{ "disableTimer", "" },
+	{ "enableTimer", "" },
+	{ "setTimerCountdown", "" },
+	{ "processPaletteIndex", "" },
+	// 0xa0
+	{ "updateTwoSceneAnims", "" },
+	{ "getRainbowRoomData", "" },
+	{ "drawSceneShapeEx", "" },
+	{ "midiSoundFadeout", "" },
+	// 0xa4
+	{ "getSfxDriver", "" },
+	{ "getVocSupport", "" },
+	{ "getMusicDriver", "" },
+	{ "setVocHigh", "" },
+	// 0xa8
+	{ "getVocHigh", "" },
+	{ "zanthiaChat", "" },
+	{ "isVoiceEnabled", "" },
+	{ "isVoicePlaying", "" },
+	// 0xac
+	{ "stopVoicePlaying", "" },
+	{ "getGameLanguage", "" },
+	{ "demoFinale", "" },
+	{ "dummyAF", "" }
+};
+
 IFFChunk::IFFChunk() {
 	_data = NULL;
 }
@@ -120,7 +349,7 @@
 
 #define ADD_INST _insts.push_back(Instruction());
 #define LAST_INST (_insts[_insts.size()-1])
-#define OPCODE_MD(name, category, stackChange, codeGenData) \
+#define OPCODE_MD(name, category, stackChange, hasParam, codeGenData) \
 		ADD_INST; \
 		LAST_INST._opcode = opcode; \
 		LAST_INST._address = address; \
@@ -128,90 +357,151 @@
 		LAST_INST._name = name; \
 		LAST_INST._type = category; \
 		LAST_INST._codeGenData = codeGenData; \
-		{ \
+		if (hasParam) { \
 			Parameter p; \
 			p._type = kShort; \
 			p._value = parameter; \
 			LAST_INST._params.push_back(p);\
 		}
-#define OPCODE(name, category, stackChange) OPCODE_MD(name, category, stackChange, "");
+#define OPCODE(name, category, stackChange, hasParam) OPCODE_MD(name, category, stackChange, hasParam, "");
 
 		// TOOD: Add metadata where applicable
 		switch(opcode) {
 		case 0:
-			OPCODE("jumpTo", kJump, 0);
+			OPCODE("jumpTo", kJump, 0, true);
 			break;
 		case 1:
-			OPCODE("setRetValue", kStore, 0);
+			OPCODE("setRetValue", kStore, 0, true);
 			break;
 		case 2:
 			if (parameter == 0) {
-				OPCODE("pushRet", kLoad, 1);
+				OPCODE("pushRet", kLoad, 1, false);
 			} else if (parameter == 1) {
-				OPCODE("pushPos", kSpecial, 2); // Sets up function call?
+				OPCODE("pushPos", kSpecial, 2, false); // Sets up function call?
 			} else {
 				// Error: invalid parameter halts execution
 			}
 			break;
 		case 3:
 		case 4:
-			OPCODE("push", kLoad, 1);
+			OPCODE("push", kLoad, 1, true);
 			break;
 		case 5:
-			OPCODE("pushVar", kLoad, 1);
+			OPCODE("pushVar", kLoad, 1, true);
 			break;
 		case 6:
-			OPCODE("pushBPNeg", kLoad, 1);
+			OPCODE("pushBPNeg", kLoad, 1, true);
 			break;
 		case 7:
-			OPCODE("pushBPAdd", kLoad, 1);
+			OPCODE("pushBPAdd", kLoad, 1, true);
 			break;
 		case 8:
 			if (parameter == 0) {
-				OPCODE("popRet", kStore, -1);
+				OPCODE("popRet", kStore, -1, false);
 			} else if (parameter == 1) {
-				OPCODE("popPos", kSpecial, -2); // Returns from function call?
+				OPCODE("popPos", kSpecial, -2, false); // Returns from function call?
 			} else {
 				// Error: invalid parameter halts execution
 			}
 			break;
 		case 9:
-			OPCODE("popVar", kStore, 1);
+			OPCODE("popVar", kStore, 1, true);
 			break;
 		case 10:
-			OPCODE("popBPNeg", kStore, 1);
+			OPCODE("popBPNeg", kStore, 1, true);
 			break;
 		case 11:
-			OPCODE("popBPAdd", kStore, 1);
+			OPCODE("popBPAdd", kStore, 1, true);
 			break;
 		case 12:
-			OPCODE("addSP", kStack, -parameter);
+			OPCODE("addSP", kStack, -parameter, true);
 			break;
 		case 13:
-			OPCODE("subSP", kStack, parameter);
+			OPCODE("subSP", kStack, parameter, true);
 			break;
 		case 14:
-			OPCODE("execOpcode", kSpecial, 0); // TODO: Full details of opcode
+			if ((uint16)parameter >= sizeof(kyra2FuncDesc) / sizeof(kyra2FuncDesc[0]) || kyra2FuncDesc[parameter]._name.length() == 0) {
+				// Error: unknown function
+			}
+			OPCODE_MD(kyra2FuncDesc[parameter]._name, kSpecial, 0, false, kyra2FuncDesc[parameter]._metadata)
 			break;
 		case 15:
-			OPCODE("ifNotJmp", kCondJump, -1);
+			OPCODE("ifNotJmp", kCondJump, -1, true);
 			break;
 		case 16:
 			if (parameter == 0) {
-				OPCODE_MD("boolCast", kUnaryOp, 0, "(bool)");
+				OPCODE_MD("boolCast", kUnaryOp, 0, false, "(bool)");
 			} else if (parameter == 1) {
-				OPCODE_MD("arithmeticNegate", kUnaryOp, 0, "-");
+				OPCODE_MD("arithmeticNegate", kUnaryOp, 0, false,"-");
 			} else if (parameter == 2) {
-				OPCODE_MD("bitwiseNegate", kUnaryOp, 0, "~");
+				OPCODE_MD("bitwiseNegate", kUnaryOp, 0, false, "~");
 			} else {
 				// Error: invalid parameter halts execution
 			}
 			break;
 		case 17:
-			OPCODE("eval", kBinaryOp, -1); // TODO: Full details of opcode
+			switch (parameter) {
+				case 0:
+					OPCODE_MD("eval_band", kBinaryOp, -1, false, "&&");
+					break;
+				case 1:
+					OPCODE_MD("eval_bor", kBinaryOp, -1, false, "||");
+					break;
+				case 2:
+					OPCODE_MD("eval_eq", kBinaryOp, -1, false, "==");
+					break;
+				case 3:
+					OPCODE_MD("eval_neq", kBinaryOp, -1, false, "!=");
+					break;
+				case 4:
+					OPCODE_MD("eval_leq", kBinaryOp, -1, false, "<=");
+					break;
+				case 5:
+					OPCODE_MD("eval_lt", kBinaryOp, -1, false, "<");
+					break;
+				case 6:
+					OPCODE_MD("eval_geq", kBinaryOp, -1, false, ">=");
+					break;
+				case 7:
+					OPCODE_MD("eval_gt", kBinaryOp, -1, false, ">");
+					break;
+				case 8:
+					OPCODE_MD("eval_add", kBinaryOp, -1, false, "+");
+					break;
+				case 9:
+					OPCODE_MD("eval_sub", kBinaryOp, -1, false, "-");
+					break;
+				case 10:
+					OPCODE_MD("eval_mult", kBinaryOp, -1, false, "*");
+					break;
+				case 11:
+					OPCODE_MD("eval_div", kBinaryOp, -1, false, "/");
+					break;
+				case 12:
+					OPCODE_MD("eval_shr", kBinaryOp, -1, false, ">>");
+					break;
+				case 13:
+					OPCODE_MD("eval_shl", kBinaryOp, -1, false, "<<");
+					break;
+				case 14:
+					OPCODE_MD("eval_land", kBinaryOp, -1, false, "&");
+					break;
+				case 15:
+					OPCODE_MD("eval_lor", kBinaryOp, -1, false, "|");
+					break;
+				case 16:
+					OPCODE_MD("eval_mod", kBinaryOp, -1, false, "%");
+					break;
+				case 17:
+					OPCODE_MD("eval_xor", kBinaryOp, -1, false, "^");
+					break;
+				default:
+					// Error: Invalid parameter
+					break;
+			}
 			break;
 		case 18:
-			OPCODE("setRetAndJmp", kSpecial, -2); // Returns from function call?
+			OPCODE("setRetAndJmp", kSpecial, -2, false); // Returns from function call?
 			break;
 		default:
 			throw UnknownOpcodeException(i*2, code);


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