[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