disassembler.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /* ScummVM Tools
  2. *
  3. * ScummVM Tools is the legal property of its developers, whose
  4. * names are too numerous to list here. Please refer to the
  5. * COPYRIGHT file distributed with this source distribution.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  20. */
  21. #include <iostream>
  22. #include <sstream>
  23. #include <boost/format.hpp>
  24. #include "disassembler.h"
  25. Scumm::v6::Scummv6Disassembler::Scummv6Disassembler(InstVec &insts) : SimpleDisassembler(insts) {
  26. }
  27. void Scumm::v6::Scummv6Disassembler::doDisassemble(){
  28. std::string blockName;
  29. for (int i = 0; i < 4; i++) {
  30. blockName += mStream->ReadS8();
  31. }
  32. if (blockName == "SCRP") {
  33. //std::clog << "Input is global script\n";
  34. mStream->Seek(8);
  35. } else if (blockName == "LSCR") {
  36. //std::clog << "Input is local script\n";
  37. mStream->Seek(9);
  38. } else if (blockName == "ENCD") {
  39. //std::clog << "Input is room entry script\n";
  40. mStream->Seek(8);
  41. } else if (blockName == "EXCD") {
  42. //std::clog << "Input is room exit script\n";
  43. mStream->Seek(8);
  44. } else if (blockName == "VERB") {
  45. //std::clog << "Input is object script\n";
  46. mStream->Seek(8);
  47. //std::clog << "Offset table:\n";
  48. uint32 verb = mStream->ReadU8();
  49. while (verb != 0) {
  50. /*std::clog << boost::format("%02x - %04x\n") % verb %*/ mStream->ReadU16();
  51. verb = mStream->ReadU8();
  52. }
  53. } else {
  54. std::stringstream s;
  55. s << "Unknown block name " << blockName;
  56. throw std::runtime_error(s.str());
  57. }
  58. START_OPCODES;
  59. OPCODE(0x00, "pushByte", Scummv6LoadInstruction, 1, "B");
  60. OPCODE(0x01, "pushWord", Scummv6LoadInstruction, 1, "s");
  61. OPCODE(0x02, "pushByteVar", Scummv6LoadInstruction, 1, "B");
  62. OPCODE(0x03, "pushWordVar", Scummv6LoadInstruction, 1, "w");
  63. OPCODE(0x06, "byteArrayRead", Scummv6LoadInstruction, 0, "B");
  64. OPCODE(0x07, "wordArrayRead", Scummv6LoadInstruction, 0, "w");
  65. OPCODE(0x0A, "byteArrayIndexedRead", Scummv6LoadInstruction, -1, "B");
  66. OPCODE(0x0B, "wordArrayIndexedRead", Scummv6LoadInstruction, -1, "w");
  67. OPCODE(0x0C, "dup", DupStackInstruction, 1, "");
  68. OPCODE(0x0D, "not", BoolNegateStackInstruction, 0, "");
  69. OPCODE_MD(0x0E, "eq", BinaryOpStackInstruction, -1, "", "==");
  70. OPCODE_MD(0x0F, "neq", BinaryOpStackInstruction, -1, "", "!=");
  71. OPCODE_MD(0x10, "gt", BinaryOpStackInstruction, -1, "", ">");
  72. OPCODE_MD(0x11, "lt", BinaryOpStackInstruction, -1, "", "<");
  73. OPCODE_MD(0x12, "le", BinaryOpStackInstruction, -1, "", "<=");
  74. OPCODE_MD(0x13, "ge", BinaryOpStackInstruction, -1, "", ">=");
  75. OPCODE_MD(0x14, "add", BinaryOpStackInstruction, -1, "", "+");
  76. OPCODE_MD(0x15, "sub", BinaryOpStackInstruction, -1, "", "-");
  77. OPCODE_MD(0x16, "mul", BinaryOpStackInstruction, -1, "", "*");
  78. OPCODE_MD(0x17, "div", BinaryOpStackInstruction, -1, "", "/");
  79. OPCODE_MD(0x18, "land", BinaryOpStackInstruction, -1, "", "&&");
  80. OPCODE_MD(0x19, "lor", BinaryOpStackInstruction, -1, "", "||");
  81. OPCODE(0x1A, "pop", Scummv6StackInstruction, -1, "");
  82. OPCODE(0x42, "writeByteVar", Scummv6StoreInstruction, -1, "B");
  83. OPCODE(0x43, "writeWordVar", Scummv6StoreInstruction, -1, "w");
  84. OPCODE(0x46, "byteArrayWrite", Scummv6StoreInstruction, -2, "B");
  85. OPCODE(0x47, "wordArrayWrite", Scummv6StoreInstruction, -2, "w");
  86. OPCODE(0x4A, "byteArrayIndexedWrite", Scummv6StoreInstruction, -3, "B");
  87. OPCODE(0x4B, "wordArrayIndexedWrite", Scummv6StoreInstruction, -3, "w");
  88. OPCODE_MD(0x4E, "byteVarInc", Scummv6IncDecInstruction, 0, "B", "++");
  89. OPCODE_MD(0x4F, "wordVarInc", Scummv6IncDecInstruction, 0, "w", "++");
  90. OPCODE_MD(0x52, "byteArrayInc", Scummv6IncDecInstruction, -1, "B", "++");
  91. OPCODE_MD(0x53, "wordArrayInc", Scummv6IncDecInstruction, -1, "w", "++");
  92. OPCODE_MD(0x56, "byteVarDec", Scummv6IncDecInstruction, 0, "B", "--");
  93. OPCODE_MD(0x57, "wordVarDec", Scummv6IncDecInstruction, 0, "w", "--");
  94. OPCODE_MD(0x5A, "byteArrayDec", Scummv6IncDecInstruction, -1, "B", "--");
  95. OPCODE_MD(0x5B, "wordArrayDec", Scummv6IncDecInstruction, -1, "w", "--");
  96. OPCODE(0x5C, "jumpTrue", Scummv6CondJumpInstruction, -1, "a");
  97. OPCODE(0x5D, "jumpFalse", Scummv6CondJumpInstruction, -1, "a");
  98. OPCODE_MD(0x5E, "startScript", KernelCallStackInstruction, 0x1020, "", "lpp"); // Variable stack arguments
  99. OPCODE_MD(0x5F, "startScriptQuick", KernelCallStackInstruction, 0x1010, "", "lp"); // Variable stack arguments
  100. OPCODE_MD(0x60, "startObject", KernelCallStackInstruction, 0x1030, "", "lppp"); // Variable stack arguments
  101. OPCODE_MD(0x61, "drawObject", KernelCallStackInstruction, -2, "", "pp");
  102. OPCODE_MD(0x62, "drawObjectAt", KernelCallStackInstruction, -3, "", "ppp");
  103. OPCODE_MD(0x63, "drawBlastObject", KernelCallStackInstruction, -5, "", "ppppp");
  104. OPCODE_MD(0x64, "setBlastObjectWindow", KernelCallStackInstruction, -4, "", "pppp");
  105. OPCODE(0x65, "stopObjectCodeA", KernelCallStackInstruction, 0, "");
  106. OPCODE(0x66, "stopObjectCodeB", KernelCallStackInstruction, 0, "");
  107. OPCODE(0x67, "endCutscene", KernelCallStackInstruction, 0, "");
  108. OPCODE_MD(0x68, "beginCutscene", KernelCallStackInstruction, 0x1000, "", "l"); // Variable stack arguments
  109. OPCODE(0x69, "stopMusic", KernelCallStackInstruction, 0, "");
  110. OPCODE_MD(0x6A, "freezeUnfreeze", KernelCallStackInstruction, -1, "", "p");
  111. START_SUBOPCODE_WITH_PREFIX(0x6B, "cursorCommand");
  112. OPCODE(0x90, "cursorOn", KernelCallStackInstruction, 0, "");
  113. OPCODE(0x91, "cursorOff", KernelCallStackInstruction, 0, "");
  114. OPCODE(0x92, "userputOn", KernelCallStackInstruction, 0, "");
  115. OPCODE(0x93, "userputOff", KernelCallStackInstruction, 0, "");
  116. OPCODE(0x94, "softCursorOn", KernelCallStackInstruction, 0, "");
  117. OPCODE(0x95, "softCursorOff", KernelCallStackInstruction, 0, "");
  118. OPCODE(0x96, "softUserputOn", KernelCallStackInstruction, 0, "");
  119. OPCODE(0x97, "softUserputOff", KernelCallStackInstruction, 0, "");
  120. OPCODE_MD(0x99, "setCursorImg", KernelCallStackInstruction, -2, "", "z");
  121. OPCODE_MD(0x9A, "setCursorHotspot", KernelCallStackInstruction, -2, "", "pp");
  122. OPCODE_MD(0x9C, "initCharset", KernelCallStackInstruction, -1, "", "p");
  123. OPCODE_MD(0x9D, "charsetColors", KernelCallStackInstruction, 0x1000, "", "l"); // Variable stack arguments
  124. OPCODE_MD(0xD6, "setCursorTransparency", KernelCallStackInstruction, -1, "", "p");
  125. END_SUBOPCODE;
  126. OPCODE(0x6C, "breakHere", KernelCallStackInstruction, 0, "");
  127. OPCODE_MD(0x6D, "ifClassOfIs", KernelCallStackInstruction, 0x1011, "", "rlp"); // Variable stack arguments
  128. OPCODE_MD(0x6E, "setClass", KernelCallStackInstruction, 0x1010, "", "lp"); // Variable stack arguments
  129. OPCODE_MD(0x6F, "getState", KernelCallStackInstruction, 0, "", "rp");
  130. OPCODE_MD(0x70, "setState", KernelCallStackInstruction, -2, "", "pp");
  131. OPCODE_MD(0x71, "setOwner", KernelCallStackInstruction, -2, "", "pp");
  132. OPCODE_MD(0x72, "getOwner", KernelCallStackInstruction, 0, "", "rp");
  133. OPCODE(0x73, "jump", Scummv6JumpInstruction, 0, "a");
  134. OPCODE_MD(0x74, "startSound", KernelCallStackInstruction, -1, "", "p");
  135. OPCODE_MD(0x75, "stopSound", KernelCallStackInstruction, -1, "", "p");
  136. OPCODE_MD(0x76, "startMusic", KernelCallStackInstruction, -1, "", "p");
  137. OPCODE_MD(0x77, "stopObjectScript", KernelCallStackInstruction, -1, "", "p");
  138. OPCODE_MD(0x78, "panCameraTo", KernelCallStackInstruction, -1, "", "p");
  139. OPCODE_MD(0x79, "actorFollowCamera", KernelCallStackInstruction, -1, "", "p");
  140. OPCODE_MD(0x7A, "setCameraAt", KernelCallStackInstruction, -1, "", "p");
  141. OPCODE_MD(0x7B, "loadRoom", KernelCallStackInstruction, -1, "", "p");
  142. OPCODE_MD(0x7C, "stopScript", KernelCallStackInstruction, -1, "", "p");
  143. OPCODE_MD(0x7D, "walkActorToObj", KernelCallStackInstruction, -3, "", "ppp");
  144. OPCODE_MD(0x7E, "walkActorTo", KernelCallStackInstruction, -3, "", "ppp");
  145. OPCODE_MD(0x7F, "putActorAtXY", KernelCallStackInstruction, -4, "", "pppp");
  146. OPCODE_MD(0x80, "putActorAtObject", KernelCallStackInstruction, -3, "", "zp");
  147. OPCODE_MD(0x81, "faceActor", KernelCallStackInstruction, -2, "", "pp");
  148. OPCODE_MD(0x82, "animateActor", KernelCallStackInstruction, -2, "", "pp");
  149. OPCODE_MD(0x83, "doSentence", KernelCallStackInstruction, -4, "", "pppp");
  150. OPCODE_MD(0x84, "pickupObject", KernelCallStackInstruction, -2, "", "z");
  151. OPCODE_MD(0x85, "loadRoomWithEgo", KernelCallStackInstruction, -4, "", "ppz");
  152. OPCODE_MD(0x87, "getRandomNumber", KernelCallStackInstruction, 0, "", "rp");
  153. OPCODE_MD(0x88, "getRandomNumberRange", KernelCallStackInstruction, -1, "", "rpp");
  154. OPCODE_MD(0x8A, "getActorMoving", KernelCallStackInstruction, 0, "", "rp");
  155. OPCODE_MD(0x8B, "isScriptRunning", KernelCallStackInstruction, 0, "", "rp");
  156. OPCODE_MD(0x8C, "getActorRoom", KernelCallStackInstruction, 0, "", "rp");
  157. OPCODE_MD(0x8D, "getObjectX", KernelCallStackInstruction, 0, "", "rp");
  158. OPCODE_MD(0x8E, "getObjectY", KernelCallStackInstruction, 0, "", "rp");
  159. OPCODE_MD(0x8F, "getObjectDir", KernelCallStackInstruction, 0, "", "rp");
  160. OPCODE_MD(0x90, "getActorWalkBox", KernelCallStackInstruction, 0, "", "rp");
  161. OPCODE_MD(0x91, "getActorCostume", KernelCallStackInstruction, 0, "", "rp");
  162. OPCODE_MD(0x92, "findInventory", KernelCallStackInstruction, -1, "", "rpp");
  163. OPCODE_MD(0x93, "getInventoryCount", KernelCallStackInstruction, 0, "", "rp");
  164. OPCODE_MD(0x94, "getVerbFromXY", KernelCallStackInstruction, -1, "", "rpp");
  165. OPCODE_BASE(0x95)
  166. OPCODE_BODY("beginOverride", KernelCallStackInstruction, 0, "", "");
  167. // FIXME/TODO: beginOverride skips the following jump - that jump is instead to a "finally" handler
  168. // To simulate this, we simply skip the jump instruction, so the sequential order appears the same.
  169. // Semantically, it would probably be more correct to model this as a conditional jump,
  170. // but since precious little time remains of GSoC and that might not play very nice with the rest of the code,
  171. // this is the simplest way to handle the issue right now. Eventually, it should probably be fixed more properly.
  172. mStream->Seek(3);
  173. _address += 3;
  174. OPCODE_END;
  175. OPCODE(0x96, "endOverride", KernelCallStackInstruction, 0, "");
  176. OPCODE_MD(0x97, "setObjectName", KernelCallStackInstruction, -1, "c", "ps");
  177. OPCODE_MD(0x98, "isSoundRunning", KernelCallStackInstruction, 0, "", "rp");
  178. OPCODE_MD(0x99, "setBoxFlags", KernelCallStackInstruction, 0x1100, "", "pl"); // Variable stack arguments
  179. OPCODE(0x9A, "createBoxMatrix", KernelCallStackInstruction, 0, "");
  180. START_SUBOPCODE_WITH_PREFIX(0x9B, "resourceRoutines");
  181. OPCODE_MD(0x64, "loadScript", KernelCallStackInstruction, -1, "", "p");
  182. OPCODE_MD(0x65, "loadSound", KernelCallStackInstruction, -1, "", "p");
  183. OPCODE_MD(0x66, "loadCostume", KernelCallStackInstruction, -1, "", "p");
  184. OPCODE_MD(0x67, "loadRoom", KernelCallStackInstruction, -1, "", "p");
  185. OPCODE_MD(0x68, "nukeScript", KernelCallStackInstruction, -1, "", "p");
  186. OPCODE_MD(0x69, "nukeSound", KernelCallStackInstruction, -1, "", "p");
  187. OPCODE_MD(0x6A, "nukeCostume", KernelCallStackInstruction, -1, "", "p");
  188. OPCODE_MD(0x6B, "nukeRoom", KernelCallStackInstruction, -1, "", "p");
  189. OPCODE_MD(0x6C, "lockScript", KernelCallStackInstruction, -1, "", "p");
  190. OPCODE_MD(0x6D, "lockSound", KernelCallStackInstruction, -1, "", "p");
  191. OPCODE_MD(0x6E, "lockCostume", KernelCallStackInstruction, -1, "", "p");
  192. OPCODE_MD(0x6F, "lockRoom", KernelCallStackInstruction, -1, "", "p");
  193. OPCODE_MD(0x70, "unlockScript", KernelCallStackInstruction, -1, "", "p");
  194. OPCODE_MD(0x71, "unlockSound", KernelCallStackInstruction, -1, "", "p");
  195. OPCODE_MD(0x72, "unlockCostume", KernelCallStackInstruction, -1, "", "p");
  196. OPCODE_MD(0x73, "unlockRoom", KernelCallStackInstruction, -1, "", "p");
  197. OPCODE_MD(0x75, "loadCharset", KernelCallStackInstruction, -1, "", "p");
  198. OPCODE_MD(0x76, "nukeCharset", KernelCallStackInstruction, -1, "", "p");
  199. OPCODE_MD(0x77, "loadFlObject", KernelCallStackInstruction, -2, "", "pp");
  200. END_SUBOPCODE;
  201. START_SUBOPCODE_WITH_PREFIX(0x9C, "roomOps");
  202. OPCODE_MD(0xAC, "roomScroll", KernelCallStackInstruction, -2, "", "pp");
  203. OPCODE_MD(0xAE, "setScreen", KernelCallStackInstruction, -2, "", "pp");
  204. OPCODE_MD(0xAF, "setPalColor", KernelCallStackInstruction, -4, "", "pppp");
  205. OPCODE(0xB0, "shakeOn", KernelCallStackInstruction, 0, "");
  206. OPCODE(0xB1, "shakeOff", KernelCallStackInstruction, 0, "");
  207. OPCODE_MD(0xB3, "darkenPalette", KernelCallStackInstruction, -3, "", "ppp");
  208. OPCODE_MD(0xB4, "saveLoadRoom", KernelCallStackInstruction, -2, "", "pp");
  209. OPCODE_MD(0xB5, "screenEffect", KernelCallStackInstruction, -1, "", "p");
  210. OPCODE_MD(0xB6, "darkenPaletteRGB", KernelCallStackInstruction, -5, "", "ppppp");
  211. OPCODE_MD(0xB7, "setupShadowPalette", KernelCallStackInstruction, -5, "", "ppppp");
  212. OPCODE_MD(0xBA, "palManipulate", KernelCallStackInstruction, -4, "", "pppp");
  213. OPCODE_MD(0xBB, "colorCycleDelay", KernelCallStackInstruction, -2, "", "pp");
  214. OPCODE_MD(0xD5, "setPalette", KernelCallStackInstruction, -1, "", "p");
  215. OPCODE_MD(0xDC, "copyPalColor", KernelCallStackInstruction, -2, "", "pp");
  216. END_SUBOPCODE;
  217. START_SUBOPCODE_WITH_PREFIX(0x9D, "actorOps");
  218. OPCODE_MD(0x4C, "setCostume", KernelCallStackInstruction, -1, "", "p");
  219. OPCODE_MD(0x4D, "setWalkSpeed", KernelCallStackInstruction, -2, "", "pp");
  220. OPCODE_MD(0x4E, "setSound", KernelCallStackInstruction, 0x1000, "", "l"); // Variable stack arguments
  221. OPCODE_MD(0x4F, "setWalkFrame", KernelCallStackInstruction, -1, "", "p");
  222. OPCODE_MD(0x50, "setTalkFrame", KernelCallStackInstruction, -2, "", "pp");
  223. OPCODE_MD(0x51, "setStandFrame", KernelCallStackInstruction, -1, "", "p");
  224. OPCODE_MD(0x52, "82?", KernelCallStackInstruction, -3, "", "ppp");
  225. OPCODE(0x53, "init", KernelCallStackInstruction, 0, "");
  226. OPCODE_MD(0x54, "setElevation", KernelCallStackInstruction, -1, "", "p");
  227. OPCODE(0x55, "setDefAnim", KernelCallStackInstruction, 0, "");
  228. OPCODE_MD(0x56, "setPalette", KernelCallStackInstruction, -2, "", "pp");
  229. OPCODE_MD(0x57, "setTalkColor", KernelCallStackInstruction, -1, "", "p");
  230. OPCODE_MD(0x58, "setName", KernelCallStackInstruction, 0, "c", "s");
  231. OPCODE_MD(0x59, "setInitFrame", KernelCallStackInstruction, -1, "", "p");
  232. OPCODE_MD(0x5B, "setWidth", KernelCallStackInstruction, -1, "", "p");
  233. OPCODE_MD(0x5C, "setScale", KernelCallStackInstruction, -1, "", "p");
  234. OPCODE(0x5D, "setNeverZClip", KernelCallStackInstruction, 0, "");
  235. OPCODE_MD(0x5E, "setAlwaysZClip", KernelCallStackInstruction, -1, "", "p");
  236. OPCODE(0x5F, "setIgnoreBoxes", KernelCallStackInstruction, 0, "");
  237. OPCODE(0x60, "setFollowBoxes", KernelCallStackInstruction, 0, "");
  238. OPCODE_MD(0x61, "setAnimSpeed", KernelCallStackInstruction, -1, "", "p");
  239. OPCODE_MD(0x62, "setShadowMode", KernelCallStackInstruction, -1, "", "p");
  240. OPCODE_MD(0x63, "setTalkPos", KernelCallStackInstruction, -2, "", "pp");
  241. OPCODE_MD(0xC5, "setCurActor", KernelCallStackInstruction, -1, "", "p");
  242. OPCODE_MD(0xC6, "setAnimVar", KernelCallStackInstruction, -2, "", "pp");
  243. OPCODE(0xD7, "setIgnoreTurnsOn", KernelCallStackInstruction, 0, "");
  244. OPCODE(0xD8, "setIgnoreTurnsOff", KernelCallStackInstruction, 0, "");
  245. OPCODE(0xD9, "initLittle", KernelCallStackInstruction, 0, "");
  246. OPCODE_MD(0xE1, "setAlwaysZClip?", KernelCallStackInstruction, -1, "", "p");
  247. OPCODE_MD(0xE3, "setLayer", KernelCallStackInstruction, -1, "", "p");
  248. OPCODE_MD(0xE4, "setWalkScript", KernelCallStackInstruction, -1, "", "p");
  249. OPCODE(0xE5, "setStanding", KernelCallStackInstruction, 0, "");
  250. OPCODE_MD(0xE6, "setDirection", KernelCallStackInstruction, -1, "", "p");
  251. OPCODE_MD(0xE7, "turnToDirection", KernelCallStackInstruction, -1, "", "p");
  252. OPCODE(0xE9, "freeze", KernelCallStackInstruction, 0, "");
  253. OPCODE(0xEA, "unfreeze", KernelCallStackInstruction, 0, "");
  254. OPCODE_MD(0xEB, "setTalkScript", KernelCallStackInstruction, -1, "", "p");
  255. END_SUBOPCODE;
  256. START_SUBOPCODE_WITH_PREFIX(0x9E, "verbOps");
  257. OPCODE_MD(0x7C, "loadImg", KernelCallStackInstruction, -1, "", "p");
  258. OPCODE_MD(0x7D, "loadString", KernelCallStackInstruction, 0, "c", "s");
  259. OPCODE_MD(0x7E, "setColor", KernelCallStackInstruction, -1, "", "p");
  260. OPCODE_MD(0x7F, "setHiColor", KernelCallStackInstruction, -1, "", "p");
  261. OPCODE_MD(0x80, "setXY", KernelCallStackInstruction, -2, "", "pp");
  262. OPCODE(0x81, "setOn", KernelCallStackInstruction, 0, "");
  263. OPCODE(0x82, "setOff", KernelCallStackInstruction, 0, "");
  264. OPCODE(0x83, "kill", KernelCallStackInstruction, 0, "");
  265. OPCODE(0x84, "init", KernelCallStackInstruction, 0, "");
  266. OPCODE_MD(0x85, "setDimColor", KernelCallStackInstruction, -1, "", "p");
  267. OPCODE(0x86, "setDimmed", KernelCallStackInstruction, 0, "");
  268. OPCODE_MD(0x87, "setKey", KernelCallStackInstruction, -1, "", "p");
  269. OPCODE(0x88, "setCenter", KernelCallStackInstruction, 0, "");
  270. OPCODE_MD(0x89, "setToString", KernelCallStackInstruction, -1, "", "p");
  271. OPCODE_MD(0x8B, "setToObject", KernelCallStackInstruction, -2, "", "pp");
  272. OPCODE_MD(0x8C, "setBkColor", KernelCallStackInstruction, -1, "", "p");
  273. OPCODE_MD(0xC4, "setCurVerb", KernelCallStackInstruction, -1, "", "p");
  274. OPCODE(0xFF, "redraw", KernelCallStackInstruction, 0, "");
  275. END_SUBOPCODE;
  276. OPCODE_MD(0x9F, "getActorFromXY", KernelCallStackInstruction, -1, "", "rpp");
  277. OPCODE_MD(0xA0, "findObject", KernelCallStackInstruction, -1, "", "rpp");
  278. OPCODE_MD(0xA1, "pseudoRoom", KernelCallStackInstruction, 0x1010, "", "lp"); // Variable stack arguments
  279. OPCODE_MD(0xA2, "getActorElevation", KernelCallStackInstruction, 0, "", "rp");
  280. OPCODE_MD(0xA3, "getVerbEntrypoint", KernelCallStackInstruction, -1, "", "rpp");
  281. START_SUBOPCODE_WITH_PREFIX(0xA4, "arrayOps");
  282. OPCODE_MD(0xCD, "assignString", Scummv6ArrayOpInstruction, -1, "wc", "");
  283. OPCODE_MD(0xD0, "assignIntList", Scummv6ArrayOpInstruction, 0x1100, "w", ""); // Variable stack arguments
  284. OPCODE_MD(0xD4, "assign2DimList", Scummv6ArrayOpInstruction, 0x1100, "w", ""); // Variable stack arguments
  285. END_SUBOPCODE;
  286. START_SUBOPCODE_WITH_PREFIX(0xA5, "saveRestoreVerbs");
  287. OPCODE_MD(0x8D, "saveVerbs", KernelCallStackInstruction, -3, "", "ppp");
  288. OPCODE_MD(0x8E, "restoreVerbs", KernelCallStackInstruction, -3, "", "ppp");
  289. OPCODE_MD(0x8F, "deleteVerbs", KernelCallStackInstruction, -3, "", "ppp");
  290. END_SUBOPCODE;
  291. OPCODE_MD(0xA6, "drawBox", KernelCallStackInstruction, -5, "", "ppppp");
  292. OPCODE(0xA7, "pop", Scummv6StackInstruction, -1, "");
  293. OPCODE_MD(0xA8, "getActorWidth", KernelCallStackInstruction, 0, "", "rp");
  294. START_SUBOPCODE(0xA9); // wait
  295. OPCODE_MD(0xA8, "waitForActor", KernelCallStackInstruction, -1, "s", "pj");
  296. OPCODE(0xA9, "waitForMessage", KernelCallStackInstruction, 0, "");
  297. OPCODE(0xAA, "waitForCamera", KernelCallStackInstruction, 0, "");
  298. OPCODE(0xAB, "waitForSentence", KernelCallStackInstruction, 0, "");
  299. OPCODE_MD(0xE2, "waitUntilActorDrawn", KernelCallStackInstruction, -1, "s", "pj");
  300. OPCODE_MD(0xE8, "waitUntilActorTurned", KernelCallStackInstruction, -1, "s", "pj");
  301. END_SUBOPCODE;
  302. OPCODE_MD(0xAA, "getActorScaleX", KernelCallStackInstruction, 0, "", "rp");
  303. OPCODE_MD(0xAB, "getActorAnimCounter", KernelCallStackInstruction, 0, "", "rp");
  304. OPCODE_MD(0xAC, "soundKludge", KernelCallStackInstruction, 0x1000, "", "l"); // Variable stack arguments
  305. OPCODE_MD(0xAD, "isAnyOf", KernelCallStackInstruction, 0x1011, "", "rlp"); // Variable stack arguments
  306. START_SUBOPCODE_WITH_PREFIX(0xAE, "systemOps");
  307. OPCODE(0x9E, "restartGame", KernelCallStackInstruction, 0, "");
  308. OPCODE(0x9F, "pauseGame", KernelCallStackInstruction, 0, "");
  309. OPCODE(0xA0, "shutDown", KernelCallStackInstruction, 0, "");
  310. END_SUBOPCODE;
  311. OPCODE_MD(0xAF, "isActorInBox", KernelCallStackInstruction, -1, "", "rpp");
  312. OPCODE_MD(0xB0, "delay", KernelCallStackInstruction, -1, "", "p");
  313. OPCODE_MD(0xB1, "delaySeconds", KernelCallStackInstruction, -1, "", "p");
  314. OPCODE_MD(0xB2, "delayMinutes", KernelCallStackInstruction, -1, "", "p");
  315. OPCODE(0xB3, "stopSentence", KernelCallStackInstruction, 0, "");
  316. START_SUBOPCODE_WITH_PREFIX(0xB4, "printLine");
  317. OPCODE_MD(0x41, "XY", KernelCallStackInstruction, -2, "", "pp");
  318. OPCODE_MD(0x42, "color", KernelCallStackInstruction, -1, "", "p");
  319. OPCODE_MD(0x43, "right", KernelCallStackInstruction, -1, "", "p");
  320. OPCODE(0x45, "center", KernelCallStackInstruction, 0, "");
  321. OPCODE(0x47, "left", KernelCallStackInstruction, 0, "");
  322. OPCODE(0x48, "overhead", KernelCallStackInstruction, 0, "");
  323. OPCODE(0x4A, "mumble", KernelCallStackInstruction, 0, "");
  324. OPCODE_MD(0x4B, "msg", KernelCallStackInstruction, 0, "c", "s");
  325. OPCODE(0xFE, "begin", KernelCallStackInstruction, 0, "");
  326. OPCODE(0xFF, "end", KernelCallStackInstruction, 0, "");
  327. END_SUBOPCODE;
  328. START_SUBOPCODE_WITH_PREFIX(0xB5, "printText");
  329. OPCODE_MD(0x41, "XY", KernelCallStackInstruction, -2, "", "pp");
  330. OPCODE_MD(0x42, "color", KernelCallStackInstruction, -1, "", "p");
  331. OPCODE_MD(0x43, "right", KernelCallStackInstruction, -1, "", "p");
  332. OPCODE(0x45, "center", KernelCallStackInstruction, 0, "");
  333. OPCODE(0x47, "left", KernelCallStackInstruction, 0, "");
  334. OPCODE(0x48, "overhead", KernelCallStackInstruction, 0, "");
  335. OPCODE(0x4A, "mumble", KernelCallStackInstruction, 0, "");
  336. OPCODE_MD(0x4B, "msg", KernelCallStackInstruction, 0, "c", "s");
  337. OPCODE(0xFE, "begin", KernelCallStackInstruction, 0, "");
  338. OPCODE(0xFF, "end", KernelCallStackInstruction, 0, "");
  339. END_SUBOPCODE;
  340. START_SUBOPCODE_WITH_PREFIX(0xB6, "printDebug");
  341. OPCODE_MD(0x41, "XY", KernelCallStackInstruction, -2, "", "pp");
  342. OPCODE_MD(0x42, "color", KernelCallStackInstruction, -1, "", "p");
  343. OPCODE_MD(0x43, "right", KernelCallStackInstruction, -1, "", "p");
  344. OPCODE(0x45, "center", KernelCallStackInstruction, 0, "");
  345. OPCODE(0x47, "left", KernelCallStackInstruction, 0, "");
  346. OPCODE(0x48, "overhead", KernelCallStackInstruction, 0, "");
  347. OPCODE(0x4A, "mumble", KernelCallStackInstruction, 0, "");
  348. OPCODE_MD(0x4B, "msg", KernelCallStackInstruction, 0, "c", "s");
  349. OPCODE(0xFE, "begin", KernelCallStackInstruction, 0, "");
  350. OPCODE(0xFF, "end", KernelCallStackInstruction, 0, "");
  351. END_SUBOPCODE;
  352. START_SUBOPCODE_WITH_PREFIX(0xB7, "printSystem");
  353. OPCODE_MD(0x41, "XY", KernelCallStackInstruction, -2, "", "pp");
  354. OPCODE_MD(0x42, "color", KernelCallStackInstruction, -1, "", "p");
  355. OPCODE_MD(0x43, "right", KernelCallStackInstruction, -1, "", "p");
  356. OPCODE(0x45, "center", KernelCallStackInstruction, 0, "");
  357. OPCODE(0x47, "left", KernelCallStackInstruction, 0, "");
  358. OPCODE(0x48, "overhead", KernelCallStackInstruction, 0, "");
  359. OPCODE(0x4A, "mumble", KernelCallStackInstruction, 0, "");
  360. OPCODE_MD(0x4B, "msg", KernelCallStackInstruction, 0, "c", "s");
  361. OPCODE(0xFE, "begin", KernelCallStackInstruction, 0, "");
  362. OPCODE(0xFF, "end", KernelCallStackInstruction, 0, "");
  363. END_SUBOPCODE;
  364. START_SUBOPCODE_WITH_PREFIX(0xB8, "printActor");
  365. OPCODE_MD(0x41, "XY", KernelCallStackInstruction, -2, "", "pp");
  366. OPCODE_MD(0x42, "color", KernelCallStackInstruction, -1, "", "p");
  367. OPCODE_MD(0x43, "right", KernelCallStackInstruction, -1, "", "p");
  368. OPCODE(0x45, "center", KernelCallStackInstruction, 0, "");
  369. OPCODE(0x47, "left", KernelCallStackInstruction, 0, "");
  370. OPCODE(0x48, "overhead", KernelCallStackInstruction, 0, "");
  371. OPCODE(0x4A, "mumble", KernelCallStackInstruction, 0, "");
  372. OPCODE_MD(0x4B, "msg", KernelCallStackInstruction, 0, "c", "s");
  373. OPCODE_MD(0xFE, "begin", KernelCallStackInstruction, -1, "", "p");
  374. OPCODE(0xFF, "end", KernelCallStackInstruction, 0, "");
  375. END_SUBOPCODE;
  376. START_SUBOPCODE_WITH_PREFIX(0xB9, "printEgo");
  377. OPCODE_MD(0x41, "XY", KernelCallStackInstruction, -2, "", "pp");
  378. OPCODE_MD(0x42, "color", KernelCallStackInstruction, -1, "", "p");
  379. OPCODE_MD(0x43, "right", KernelCallStackInstruction, -1, "", "p");
  380. OPCODE(0x45, "center", KernelCallStackInstruction, 0, "");
  381. OPCODE(0x47, "left", KernelCallStackInstruction, 0, "");
  382. OPCODE(0x48, "overhead", KernelCallStackInstruction, 0, "");
  383. OPCODE(0x4A, "mumble", KernelCallStackInstruction, 0, "");
  384. OPCODE_MD(0x4B, "msg", KernelCallStackInstruction, 0, "c", "s");
  385. OPCODE(0xFE, "begin", KernelCallStackInstruction, 0, "");
  386. OPCODE(0xFF, "end", KernelCallStackInstruction, 0, "");
  387. END_SUBOPCODE;
  388. OPCODE_MD(0xBA, "talkActor", KernelCallStackInstruction, -1, "c", "ps");
  389. OPCODE_MD(0xBB, "talkEgo", KernelCallStackInstruction, 0, "c", "s");
  390. START_SUBOPCODE(0xBC); // dimArray
  391. OPCODE_MD(0xC7, "dimArrayInt", KernelCallStackInstruction, -1, "w", "pv");
  392. OPCODE_MD(0xC8, "dimArrayBit", KernelCallStackInstruction, -1, "w", "pv");
  393. OPCODE_MD(0xC9, "dimArrayNibble", KernelCallStackInstruction, -1, "w", "pv");
  394. OPCODE_MD(0xCA, "dimArrayByte", KernelCallStackInstruction, -1, "w", "pv");
  395. OPCODE_MD(0xCB, "dimArrayString", KernelCallStackInstruction, -1, "w", "pv");
  396. OPCODE_MD(0xCC, "dimArray_nukeArray", KernelCallStackInstruction, 0, "w", "v");
  397. END_SUBOPCODE;
  398. OPCODE_MD(0xBE, "startObjectQuick", KernelCallStackInstruction, 0x1020, "", "lpp"); // Variable stack arguments
  399. OPCODE_MD(0xBF, "startScriptQuick2", KernelCallStackInstruction, 0x1010, "", "lp"); // Variable stack arguments
  400. START_SUBOPCODE(0xC0); // dim2DimArray
  401. OPCODE_MD(0xC7, "dim2DimArrayInt", KernelCallStackInstruction, -2, "w", "ppv");
  402. OPCODE_MD(0xC8, "dim2DimArrayBit", KernelCallStackInstruction, -2, "w", "ppv");
  403. OPCODE_MD(0xC9, "dim2DimArrayNibble", KernelCallStackInstruction, -2, "w", "ppv");
  404. OPCODE_MD(0xCA, "dim2DimArrayByte", KernelCallStackInstruction, -2, "w", "ppv");
  405. OPCODE_MD(0xCB, "dim2DimArrayString", KernelCallStackInstruction, -2, "w", "ppv");
  406. END_SUBOPCODE;
  407. OPCODE_MD(0xC4, "abs", KernelCallStackInstruction, 0, "", "rp");
  408. OPCODE_MD(0xC5, "getDistObjObj", KernelCallStackInstruction, -1, "", "rpp");
  409. OPCODE_MD(0xC6, "getDistObjPt", KernelCallStackInstruction, -2, "", "rppp");
  410. OPCODE_MD(0xC7, "getDistPtPt", KernelCallStackInstruction, -3, "", "rpppp");
  411. OPCODE_MD(0xC8, "kernelGetFunctions", KernelCallStackInstruction, 0x1000, "", "l"); // Variable stack arguments
  412. OPCODE_MD(0xC9, "kernelSetFunctions", KernelCallStackInstruction, 0x1000, "", "l"); // Variable stack arguments
  413. OPCODE_MD(0xCA, "delayFrames", KernelCallStackInstruction, -1, "", "p");
  414. OPCODE_MD(0xCB, "pickOneOf", KernelCallStackInstruction, 0x1011, "", "rlp"); // Variable stack arguments
  415. OPCODE_MD(0xCC, "pickOneOfDefault", KernelCallStackInstruction, 0x111, "", "rplp"); // Variable stack arguments
  416. OPCODE_MD(0xCD, "stampObject", KernelCallStackInstruction, -4, "", "pppp");
  417. OPCODE(0xD0, "getDateTime", KernelCallStackInstruction, 0, "");
  418. OPCODE(0xD1, "stopTalking", KernelCallStackInstruction, 0, "");
  419. OPCODE_MD(0xD2, "getAnimateVariable", KernelCallStackInstruction, -1, "", "rpp");
  420. OPCODE_MD(0xD4, "shuffle", KernelCallStackInstruction, -2, "w", "vpp");
  421. OPCODE_MD(0xD5, "jumpToScript", KernelCallStackInstruction, 0x1020, "", "lpp"); // Variable stack arguments
  422. OPCODE_MD(0xD6, "band", BinaryOpStackInstruction, -1, "", "&");
  423. OPCODE_MD(0xD7, "bor", BinaryOpStackInstruction, -1, "", "|");
  424. OPCODE_MD(0xD8, "isRoomScriptRunning", KernelCallStackInstruction, 0, "", "rp");
  425. OPCODE_MD(0xDD, "findAllObjects", KernelCallStackInstruction, 0, "", "rp");
  426. OPCODE_MD(0xE1, "getPixel", KernelCallStackInstruction, -1, "", "rpp");
  427. OPCODE_MD(0xE3, "pickVarRandom", KernelCallStackInstruction, 0x1001, "w", "rlw"); // Variable stack arguments
  428. OPCODE_MD(0xE4, "setBoxSet", KernelCallStackInstruction, -1, "", "p");
  429. OPCODE_MD(0xEC, "getActorLayer", KernelCallStackInstruction, 0, "", "rp");
  430. OPCODE_MD(0xED, "getObjectNewDir", KernelCallStackInstruction, 0, "", "rp");
  431. END_OPCODES;
  432. InstIterator it;
  433. for (it = _insts.begin(); it != _insts.end(); ++it)
  434. if ((*it)->_stackChange >= 0x1000)
  435. fixStackEffect(it, ((*it)->_stackChange >> 8) & 0xF, ((*it)->_stackChange >> 4) & 0xF, (*it)->_stackChange & 0xF);
  436. }
  437. void Scumm::v6::Scummv6Disassembler::fixStackEffect(InstIterator &it, int popBefore, int popAfter, int pushTotal) {
  438. (*it)->_stackChange = static_cast<int16>(-popBefore - popAfter + pushTotal);
  439. InstIterator it2 = it;
  440. for (--it2; popBefore != 0; --it2)
  441. if ((*it2)->isLoad())
  442. --popBefore;
  443. (*it)->_stackChange -= static_cast<int16>((*it2)->_params[0]->getSigned() + 1);
  444. }
  445. ValuePtr Scumm::v6::Scummv6Disassembler::readParameter(InstPtr inst, std::string type) {
  446. ValuePtr retval = NULL;
  447. assert(type.length() == 1);
  448. switch (type.at(0)) {
  449. case 'a':
  450. retval = new RelAddressValue(inst->_address + 3, mStream->ReadS16());
  451. _address += 2;
  452. break;
  453. case 'c': { // Character string
  454. byte cmd;
  455. bool inStr = false;
  456. std::stringstream s;
  457. while ((cmd = mStream->ReadU8()) != 0) {
  458. if (cmd == 0xFF || cmd == 0xFE) {
  459. if (inStr) {
  460. s << '"';
  461. inStr = false;
  462. }
  463. cmd = mStream->ReadU8();
  464. switch (cmd) {
  465. case 1:
  466. s << ":newline:";
  467. _address += 2;
  468. break;
  469. case 2:
  470. s << ":keeptext:";
  471. _address += 2;
  472. break;
  473. case 3:
  474. s << ":wait:";
  475. _address += 2;
  476. break;
  477. case 4: // addIntToStack
  478. case 5: // addVerbToStack
  479. case 6: // addNameToStack
  480. case 7: { // addStringToStack
  481. uint16 var = mStream->ReadU16();
  482. // TODO: Clean output similar to descumm
  483. s << ":addToStack=" << var << ":";
  484. _address += 4;
  485. }
  486. break;
  487. case 9:
  488. s << ":startanim=" << mStream->ReadU16() << ":";
  489. _address += 4;
  490. break;
  491. case 10:
  492. s << ":sound:";
  493. mStream->Seek(14);
  494. _address += 16;
  495. break;
  496. case 12:
  497. s << ":setcolor=" << mStream->ReadU16() << ":";
  498. _address += 4;
  499. break;
  500. case 13:
  501. s << ":unk2=" << mStream->ReadU16() << ":";
  502. _address += 4;
  503. break;
  504. case 14:
  505. s << ":setfont=" << mStream->ReadU16() << ":";
  506. _address += 4;
  507. break;
  508. default:
  509. s << ":unk" << cmd << "=" << mStream->ReadU16() << ":";
  510. _address += 4;
  511. break;
  512. }
  513. } else {
  514. if (!inStr) {
  515. s << '"';
  516. inStr = true;
  517. }
  518. s << cmd;
  519. _address++;
  520. }
  521. }
  522. _address++;
  523. if (inStr)
  524. s << '"';
  525. retval = new Scummv6StringValue(s.str());
  526. }
  527. break;
  528. default: // Defer handling to parent implementation
  529. retval = SimpleDisassembler::readParameter(inst, type);
  530. break;
  531. }
  532. return retval;
  533. }