[Scummvm-cvs-logs] SF.net SVN: scummvm:[54904] tools/branches/gsoc2010-decompiler
pidgeot at users.sourceforge.net
pidgeot at users.sourceforge.net
Tue Dec 14 04:14:12 CET 2010
Revision: 54904
http://scummvm.svn.sourceforge.net/scummvm/?rev=54904&view=rev
Author: pidgeot
Date: 2010-12-14 03:14:11 +0000 (Tue, 14 Dec 2010)
Log Message:
-----------
DECOMPILER: Objectify Instruction
*Major* restructuring in this revision.
All other disassemblers will require updates.
Documentation for all of this is coming soon.
Modified Paths:
--------------
tools/branches/gsoc2010-decompiler/Makefile.common
tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp
tools/branches/gsoc2010-decompiler/decompiler/disassembler.h
tools/branches/gsoc2010-decompiler/decompiler/engine.h
tools/branches/gsoc2010-decompiler/decompiler/instruction.h
tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp
tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp
tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h
tools/branches/gsoc2010-decompiler/decompiler/simple_disassembler.h
tools/branches/gsoc2010-decompiler/decompiler/stack.h
tools/branches/gsoc2010-decompiler/decompiler/test/disassembler/pasc.cpp
tools/branches/gsoc2010-decompiler/decompiler/test/disassembler/pasc.h
tools/branches/gsoc2010-decompiler/decompiler/test/disassembler/subopcode.cpp
tools/branches/gsoc2010-decompiler/decompiler/test/module.mk
tools/branches/gsoc2010-decompiler/decompiler/value.h
Added Paths:
-----------
tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
tools/branches/gsoc2010-decompiler/decompiler/wrongtype.h
Removed Paths:
-------------
tools/branches/gsoc2010-decompiler/decompiler/engine.cpp
Modified: tools/branches/gsoc2010-decompiler/Makefile.common
===================================================================
--- tools/branches/gsoc2010-decompiler/Makefile.common 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/Makefile.common 2010-12-14 03:14:11 UTC (rev 54904)
@@ -230,9 +230,9 @@
common/file.o \
decompiler/decompiler.o \
decompiler/value.o \
+ decompiler/instruction.o \
decompiler/disassembler.o \
decompiler/simple_disassembler.o \
- decompiler/engine.o \
decompiler/unknown_opcode.o \
decompiler/graph.o \
decompiler/control_flow.o \
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -171,70 +171,40 @@
}
void CodeGenerator::processInst(const InstPtr inst) {
- switch (inst->_type) {
- // We handle plain dups here because their behavior should be identical across instruction sets and this prevents implementation error.
- case kDupInstType:
- {
- std::stringstream s;
- ValuePtr p = _stack.pop()->dup(s);
- if (s.str().length() > 0)
- addOutputLine(s.str());
- _stack.push(p);
- _stack.push(p);
+ inst->processInst(_stack, _engine, this);
+ if (inst->isCondJump()) {
+ std::stringstream s;
+ switch (_curGroup->_type) {
+ case kIfCondGroupType:
+ if (_curGroup->_startElse && _curGroup->_code.size() == 1) {
+ OutEdgeRange oer = boost::out_edges(_curVertex, _g);
+ bool coalesceElse = false;
+ for (OutEdgeIterator oe = oer.first; oe != oer.second; ++oe) {
+ GroupPtr oGr = GET(boost::target(*oe, _g))->_prev;
+ if (std::find(oGr->_endElse.begin(), oGr->_endElse.end(), _curGroup.get()) != oGr->_endElse.end())
+ coalesceElse = true;
+ }
+ if (coalesceElse) {
+ _curGroup->_code.clear();
+ _curGroup->_coalescedElse = true;
+ s << "} else ";
+ }
+ }
+ s << "if (" << _stack.pop()->negate() << ") {";
+ addOutputLine(s.str(), _curGroup->_coalescedElse, true);
break;
- }
- case kUnaryOpPreInstType:
- case kUnaryOpPostInstType:
- _stack.push(new UnaryOpValue(_stack.pop(), inst->_codeGenData, inst->_type == kUnaryOpPostInstType));
- break;
- case kBinaryOpInstType:
- {
- ValuePtr op1 = _stack.pop();
- ValuePtr op2 = _stack.pop();
- if (_binOrder == kFIFOArgOrder)
- _stack.push(new BinaryOpValue(op2, op1, inst->_codeGenData));
- else if (_binOrder == kLIFOArgOrder)
- _stack.push(new BinaryOpValue(op1, op2, inst->_codeGenData));
+ case kWhileCondGroupType:
+ s << "while (" << _stack.pop()->negate() << ") {";
+ addOutputLine(s.str(), false, true);
break;
+ case kDoWhileCondGroupType:
+ s << "} while (" << _stack.pop() << ")";
+ addOutputLine(s.str(), true, false);
+ break;
+ default:
+ break;
}
- case kCondJumpInstType:
- case kCondJumpRelInstType:
- {
- std::stringstream s;
- switch (_curGroup->_type) {
- case kIfCondGroupType:
- if (_curGroup->_startElse && _curGroup->_code.size() == 1) {
- OutEdgeRange oer = boost::out_edges(_curVertex, _g);
- bool coalesceElse = false;
- for (OutEdgeIterator oe = oer.first; oe != oer.second; ++oe) {
- GroupPtr oGr = GET(boost::target(*oe, _g))->_prev;
- if (std::find(oGr->_endElse.begin(), oGr->_endElse.end(), _curGroup.get()) != oGr->_endElse.end())
- coalesceElse = true;
- }
- if (coalesceElse) {
- _curGroup->_code.clear();
- _curGroup->_coalescedElse = true;
- s << "} else ";
- }
- }
- s << "if (" << _stack.pop()->negate() << ") {";
- addOutputLine(s.str(), _curGroup->_coalescedElse, true);
- break;
- case kWhileCondGroupType:
- s << "while (" << _stack.pop()->negate() << ") {";
- addOutputLine(s.str(), false, true);
- break;
- case kDoWhileCondGroupType:
- s << "} while (" << _stack.pop() << ")";
- addOutputLine(s.str(), true, false);
- break;
- default:
- break;
- }
- }
- break;
- case kJumpInstType:
- case kJumpRelInstType:
+ } else if (inst->isUncondJump()) {
switch (_curGroup->_type) {
case kBreakGroupType:
addOutputLine("break;");
@@ -269,39 +239,12 @@
}
if (printJump) {
std::stringstream s;
- s << boost::format("jump 0x%X;") % _engine->getDestAddress(inst);
+ s << boost::format("jump 0x%X;") % inst->getDestAddress();
addOutputLine(s.str());
}
}
break;
}
- break;
- case kReturnInstType:
- // TODO: Allow specification of return value as part of return statement
- addOutputLine("return;");
- break;
- case kSpecialCallInstType:
- {
- _argList.clear();
- bool returnsValue = (inst->_codeGenData.find("r") == 0);
- std::string metadata = (!returnsValue ? inst->_codeGenData : inst->_codeGenData.substr(1));
- for (size_t i = 0; i < metadata.length(); i++)
- processSpecialMetadata(inst, metadata[i], i);
- _stack.push(new CallValue(inst->_name, _argList));
- if (!returnsValue) {
- std::stringstream stream;
- stream << _stack.pop() << ";";
- addOutputLine(stream.str());
- }
- break;
- }
- default:
- {
- std::stringstream s;
- s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst->_opcode % inst->_address;
- addOutputLine(s.str());
- }
- break;
}
}
Modified: tools/branches/gsoc2010-decompiler/decompiler/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.h 2010-12-14 03:14:11 UTC (rev 54904)
@@ -21,7 +21,6 @@
*/
#include "graph.h"
-#include "stack.h"
#include "value.h"
#include <ostream>
@@ -36,11 +35,6 @@
class Function;
-/**
- * Type representing a stack.
- */
-typedef Stack<ValuePtr> ValueStack;
-
const int kIndentAmount = 2; ///< How many spaces to use for each indent.
/**
@@ -57,8 +51,6 @@
class CodeGenerator {
private:
Graph _g; ///< The annotated graph of the script.
- const ArgOrder _binOrder; ///< Order of operands for binary operations.
- const ArgOrder _callOrder; ///< Order of operands for call arguments.
/**
* Processes a GraphVertex.
@@ -73,8 +65,6 @@
ValueStack _stack; ///< The stack currently being processed.
uint _indentLevel; ///< Indentation level.
GraphVertex _curVertex; ///< Graph vertex currently being processed.
- GroupPtr _curGroup; ///< Pointer to the group currently being processed.
- ValueList _argList; ///< Storage for lists of arguments to be built when processing function calls.
/**
* Processes an instruction. Called by process() for each instruction.
@@ -83,7 +73,7 @@
*
* @param inst The instruction to process.
*/
- virtual void processInst(const InstPtr inst);
+ void processInst(const InstPtr inst);
/**
* Indents a string according to the current indentation level.
@@ -94,6 +84,38 @@
std::string indentString(std::string s);
/**
+ * Construct the signature for a function.
+ *
+ * @param func Reference to the function to construct the signature for.
+ */
+ virtual std::string constructFuncSignature(const Function &func);
+
+public:
+ const ArgOrder _binOrder; ///< Order of operands for binary operations.
+ const ArgOrder _callOrder; ///< Order of operands for call arguments.
+ ValueList _argList; ///< Storage for lists of arguments to be built when processing function calls.
+ GroupPtr _curGroup; ///< Pointer to the group currently being processed.
+
+ virtual ~CodeGenerator() { }
+
+ /**
+ * Constructor for CodeGenerator.
+ *
+ * @param engine Pointer to the Engine used for the script.
+ * @param output The std::ostream to output the code to.
+ * @param binOrder Order of arguments for binary operators.
+ * @param callOrder Order of arguments for function calls.
+ */
+ CodeGenerator(Engine *engine, std::ostream &output, ArgOrder binOrder, ArgOrder callOrder);
+
+ /**
+ * Generates code from the provided graph and outputs it to stdout.
+ *
+ * @param g The annotated graph of the script.
+ */
+ void generate(const Graph &g);
+
+ /**
* Adds a line of code to the current group.
*
* @param s The line to add.
@@ -111,15 +133,6 @@
void writeAssignment(ValuePtr dst, ValuePtr src);
/**
- * Process a single character of metadata.
- *
- * @param inst The instruction being processed.
- * @param c The character signifying the action to be taken.
- * @param pos The position at which c occurred in the metadata.
- */
- virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
-
- /**
* Add an argument to the argument list.
*
* @param p The argument to add.
@@ -127,31 +140,14 @@
void addArg(ValuePtr p);
/**
- * Construct the signature for a function.
+ * Process a single character of metadata.
*
- * @param func Reference to the function to construct the signature for.
+ * @param inst The instruction being processed.
+ * @param c The character signifying the action to be taken.
+ * @param pos The position at which c occurred in the metadata.
*/
- virtual std::string constructFuncSignature(const Function &func);
+ virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
-public:
- virtual ~CodeGenerator() { }
-
- /**
- * Constructor for CodeGenerator.
- *
- * @param engine Pointer to the Engine used for the script.
- * @param output The std::ostream to output the code to.
- * @param binOrder Order of arguments for binary operators.
- * @param callOrder Order of arguments for function calls.
- */
- CodeGenerator(Engine *engine, std::ostream &output, ArgOrder binOrder, ArgOrder callOrder);
-
- /**
- * Generates code from the provided graph and outputs it to stdout.
- *
- * @param g The annotated graph of the script.
- */
- void generate(const Graph &g);
};
#endif
Modified: tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/control_flow.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -77,24 +77,16 @@
}
last = cur;
- addEdge = ((*it)->_type != kJumpInstType && (*it)->_type != kJumpRelInstType && (*it)->_type != kReturnInstType);
+ addEdge = !((*it)->isUncondJump() || (*it)->isReturn());
prev = GET(cur);
}
// Add jump edges
for (ConstInstIterator it = insts.begin(); it != insts.end(); ++it) {
- switch((*it)->_type) {
- case kJumpInstType:
- case kCondJumpInstType:
- case kJumpRelInstType:
- case kCondJumpRelInstType: {
- GraphEdge e = boost::add_edge(find(it), find(_engine->getDestAddress(it)), _g).first;
+ if ((*it)->isJump()) {
+ GraphEdge e = boost::add_edge(find(it), find((*it)->getDestAddress()), _g).first;
PUT_EDGE(e, true);
- break;
- }
- default:
- break;
}
}
}
@@ -296,19 +288,19 @@
stackLevel += (*curInst)->_stackChange;
// For stack operations, the new stack level becomes the expected stack level starting from the next group
- if ((*curInst)->_type == kStackInstType) {
+ if ((*curInst)->isStackOp()) {
expectedStackLevel = stackLevel;
grNext->_stackLevel = stackLevel;
}
// Group ends after a jump
- if ((*curInst)->_type == kJumpInstType || (*curInst)->_type == kJumpRelInstType || (*curInst)->_type == kCondJumpInstType || (*curInst)->_type == kCondJumpRelInstType) {
+ if ((*curInst)->isJump()) {
stackLevel = grNext->_stackLevel;
continue;
}
// Group ends with a return
- if ((*curInst)->_type == kReturnInstType) {
+ if ((*curInst)->isReturn()) {
stackLevel = grNext->_stackLevel;
continue;
}
@@ -329,7 +321,7 @@
} while (grCur->_start != grCur->_end && it != grCur->_end);
// Group ends when stack is balanced, unless just before conditional jump
- if (stackLevel == expectedStackLevel && !forceMerge && (*nextInst)->_type != kCondJumpInstType && (*nextInst)->_type != kCondJumpRelInstType) {
+ if (stackLevel == expectedStackLevel && !forceMerge && !(*nextInst)->isCondJump()) {
continue;
}
@@ -433,7 +425,7 @@
for (VertexIterator v = vr.first; v != vr.second; ++v) {
GroupPtr gr = GET(*v);
// Undetermined block with unconditional jump...
- if (gr->_type == kNormalGroupType && ((*gr->_end)->_type == kJumpInstType || (*gr->_end)->_type == kJumpRelInstType) && out_degree(*v, _g) == 1) {
+ if (gr->_type == kNormalGroupType && ((*gr->_end)->isUncondJump()) && out_degree(*v, _g) == 1) {
OutEdgeIterator oe = boost::out_edges(*v, _g).first;
GraphVertex target = boost::target(*oe, _g);
GroupPtr targetGr = GET(target);
@@ -458,7 +450,7 @@
for (VertexIterator v = vr.first; v != vr.second; ++v) {
GroupPtr gr = GET(*v);
// Undetermined block with unconditional jump...
- if (gr->_type == kNormalGroupType && ((*gr->_end)->_type == kJumpInstType || (*gr->_end)->_type == kJumpRelInstType) && out_degree(*v, _g) == 1) {
+ if (gr->_type == kNormalGroupType && ((*gr->_end)->isUncondJump()) && out_degree(*v, _g) == 1) {
OutEdgeIterator oe = boost::out_edges(*v, _g).first;
GraphVertex target = boost::target(*oe, _g);
GroupPtr targetGr = GET(target);
@@ -527,7 +519,7 @@
for (VertexIterator v = vr.first; v != vr.second; ++v) {
GroupPtr gr = GET(*v);
// if: Undetermined block with conditional jump
- if (gr->_type == kNormalGroupType && ((*gr->_end)->_type == kCondJumpInstType || (*gr->_end)->_type == kCondJumpRelInstType)) {
+ if (gr->_type == kNormalGroupType && ((*gr->_end)->isCondJump())) {
gr->_type = kIfCondGroupType;
}
}
@@ -552,7 +544,7 @@
}
targetGr = GET(target);
// else: Jump target of if immediately preceded by an unconditional jump...
- if ((*targetGr->_prev->_end)->_type != kJumpInstType && (*targetGr->_prev->_end)->_type != kJumpRelInstType)
+ if (!(*targetGr->_prev->_end)->isUncondJump())
continue;
// ...which is not a break or a continue...
if (targetGr->_prev->_type == kContinueGroupType || targetGr->_prev->_type == kBreakGroupType)
@@ -592,7 +584,7 @@
}
// Unless group is a simple unconditional jump...
- if ((*cursor->_start)->_type == kJumpInstType || (*cursor->_start)->_type == kJumpRelInstType)
+ if ((*cursor->_start)->isUncondJump())
continue;
// ...validate ingoing edges
@@ -606,7 +598,7 @@
// ...must not come from outside the range [start, end]...
if ((*start->_start)->_address > (*sourceGr->_start)->_address || (*sourceGr->_start)->_address > (*end->_start)->_address) {
// ...unless source is simple unconditional jump...
- if ((*sourceGr->_start)->_type == kJumpInstType || (*sourceGr->_start)->_type == kJumpRelInstType)
+ if ((*sourceGr->_start)->isUncondJump())
continue;
// ...or the edge is from the if condition associated with this else
if (ifGroup == sourceGr)
Modified: tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/disassembler.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -24,6 +24,13 @@
Disassembler::Disassembler(InstVec &insts) : _insts(insts) {
_addressBase = 0;
+ _instFactory.addEntry<BinaryOpInstruction>(kBinaryOpInst);
+ _instFactory.addEntry<BoolNegateInstruction>(kBoolNegateInst);
+ _instFactory.addEntry<DupInstruction>(kDupInst);
+ _instFactory.addEntry<KernelCallInstruction>(kKernelCallInst);
+ _instFactory.addEntry<ReturnInstruction>(kReturnInst);
+ _instFactory.addEntry<UnaryOpPrefixInstruction>(kUnaryOpPreInst);
+ _instFactory.addEntry<UnaryOpPostfixInstruction>(kUnaryOpPostInst);
}
void Disassembler::open(const char *filename) {
Modified: tools/branches/gsoc2010-decompiler/decompiler/disassembler.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/disassembler.h 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/disassembler.h 2010-12-14 03:14:11 UTC (rev 54904)
@@ -29,15 +29,17 @@
#include "instruction.h"
#include "common/file.h"
#include "unknown_opcode.h"
+#include "objectFactory.h"
/**
* Base class for disassemblers.
*/
class Disassembler {
protected:
- Common::File _f; ///< Used to perform file I/O.
- InstVec &_insts; ///< Container for disassembled instructions.
- uint32 _addressBase; ///< Base address where the script starts.
+ Common::File _f; ///< Used to perform file I/O.
+ InstVec &_insts; ///< Container for disassembled instructions.
+ uint32 _addressBase; ///< Base address where the script starts.
+ ObjectFactory<int, Instruction> _instFactory; ///< Factory for Instruction and subclasses
/**
* Performs disassembly.
Deleted: tools/branches/gsoc2010-decompiler/decompiler/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/engine.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/engine.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -1,27 +0,0 @@
-/* ScummVM Tools
- * Copyright (C) 2010 The ScummVM project
- *
- * 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 "engine.h"
-
-uint32 Engine::getDestAddress(ConstInstIterator it) const {
- return getDestAddress(*it);
-}
Modified: tools/branches/gsoc2010-decompiler/decompiler/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/engine.h 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/engine.h 2010-12-14 03:14:11 UTC (rev 54904)
@@ -81,14 +81,6 @@
/**
* Decode a jump instruction to get the destination address.
*
- * @param inst Instruction to decode.
- * @return The destination address of the jump instruction.
- */
- virtual uint32 getDestAddress(const InstPtr inst) const = 0;
-
- /**
- * Decode a jump instruction to get the destination address.
- *
* @param it Iterator pointing to the instruction to decode.
* @return The destination address of the jump instruction.
*/
Added: tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp (rev 0)
+++ tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -0,0 +1,164 @@
+/* ScummVM Tools
+ * Copyright (C) 2010 The ScummVM project
+ *
+ * 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 "instruction.h"
+#include "codegen.h"
+#include "engine.h"
+
+bool Instruction::isJump() const {
+ return false;
+}
+
+bool Instruction::isCondJump() const {
+ return false;
+}
+
+bool Instruction::isUncondJump() const {
+ return false;
+}
+
+bool Instruction::isStackOp() const {
+ return false;
+}
+
+bool Instruction::isFuncCall() const {
+ return false;
+}
+
+bool Instruction::isReturn() const {
+ return false;
+}
+
+bool Instruction::isKernelCall() const {
+ return false;
+}
+
+bool Instruction::isLoad() const {
+ return false;
+}
+
+bool Instruction::isStore() const {
+ return false;
+}
+
+uint32 Instruction::getDestAddress() const {
+ throw WrongTypeException();
+}
+
+std::ostream &Instruction::print(std::ostream &output) const {
+ output << boost::format("%08x: %s") % _address % _name;
+ std::vector<ValuePtr>::const_iterator param;
+ for (param = _params.begin(); param != _params.end(); ++param) {
+ if (param != _params.begin())
+ output << ",";
+ output << " " << *param;
+ }
+ output << boost::format(" (%d)") % _stackChange << "\n";
+ return output;
+}
+
+bool JumpInstruction::isJump() const {
+ return true;
+}
+
+bool CondJumpInstruction::isCondJump() const {
+ return true;
+}
+
+bool UncondJumpInstruction::isUncondJump() const {
+ return true;
+}
+
+void UncondJumpInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+}
+
+bool StackInstruction::isStackOp() const {
+ return true;
+}
+
+bool CallInstruction::isFuncCall() const {
+ return true;
+}
+
+bool LoadInstruction::isLoad() const {
+ return true;
+}
+
+bool StoreInstruction::isStore() const {
+ return true;
+}
+
+void DupInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ std::stringstream s;
+ ValuePtr p = stack.pop()->dup(s);
+ if (s.str().length() > 0)
+ codeGen->addOutputLine(s.str());
+ stack.push(p);
+ stack.push(p);
+}
+
+void BoolNegateInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ stack.push(stack.pop()->negate());
+}
+
+void BinaryOpInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ ValuePtr op1 = stack.pop();
+ ValuePtr op2 = stack.pop();
+ if (codeGen->_binOrder == kFIFOArgOrder)
+ stack.push(new BinaryOpValue(op2, op1, _codeGenData));
+ else if (codeGen->_binOrder == kLIFOArgOrder)
+ stack.push(new BinaryOpValue(op1, op2, _codeGenData));
+}
+
+bool ReturnInstruction::isReturn() const {
+ return true;
+}
+
+void ReturnInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ codeGen->addOutputLine("return;");
+}
+
+void UnaryOpPrefixInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ stack.push(new UnaryOpValue(stack.pop(), _codeGenData, false));
+}
+
+void UnaryOpPostfixInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ stack.push(new UnaryOpValue(stack.pop(), _codeGenData, true));
+}
+
+void KernelCallInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ codeGen->_argList.clear();
+ bool returnsValue = (_codeGenData.find("r") == 0);
+ std::string metadata = (!returnsValue ? _codeGenData : _codeGenData.substr(1));
+ for (size_t i = 0; i < metadata.length(); i++)
+ codeGen->processSpecialMetadata(this, metadata[i], i);
+ stack.push(new CallValue(_name, codeGen->_argList));
+ if (!returnsValue) {
+ std::stringstream stream;
+ stream << stack.pop() << ";";
+ codeGen->addOutputLine(stream.str());
+ }
+}
+
+bool KernelCallInstruction::isKernelCall() const {
+ return true;
+}
Property changes on: tools/branches/gsoc2010-decompiler/decompiler/instruction.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Date Rev Author URL Id
Added: svn:eol-style
+ native
Modified: tools/branches/gsoc2010-decompiler/decompiler/instruction.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/instruction.h 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/instruction.h 2010-12-14 03:14:11 UTC (rev 54904)
@@ -32,42 +32,52 @@
#include "common/scummsys.h"
#include "refcounted.h"
#include "value.h"
+#include "wrongtype.h"
+class CodeGenerator;
+class Engine;
+
/**
- * Enumeration for categorizing the different kinds of instructions.
+ * Constants for categorizing the different kinds of instructions.
*/
-enum InstType {
- kBinaryOpInstType, ///< Binary operation (e.g. +, &&, etc.), including comparisons.
- kCallInstType, ///< Regular function call.
- kCondJumpInstType, ///< Conditional jump (absolute address).
- kCondJumpRelInstType, ///< Conditional jump (relative address).
- kDupInstType, ///< Instruction duplicates the most recent stack entry.
- kJumpInstType, ///< Unconditional jump (absolute address).
- kJumpRelInstType, ///< Unconditional jump (relative address).
- kLoadInstType, ///< Load value to stack.
- kReturnInstType, ///< Return from regular function call.
- kSpecialCallInstType, ///< Special functions.
- kStackInstType, ///< Stack allocation or deallocation (altering stack pointer).
- kStoreInstType, ///< Store value from stack in memory.
- kUnaryOpPreInstType, ///< Unary operation (e.g. !) with operator placed before the operator.
- kUnaryOpPostInstType ///< Unary operation with operator placed after the operator.
-};
+const int kBinaryOpInst = 0; ///< Binary operation (e.g. +, &&, etc.), including comparisons.
+const int kBoolNegateInst = 1; ///< Boolean negation.
+const int kCallInst = 2; ///< Regular function call.
+const int kCondJumpInst = 3; ///< Conditional jump.
+const int kDupInst = 4; ///< Instruction duplicates the most recent stack entry.
+const int kJumpInst = 5; ///< Unconditional jump.
+const int kKernelCallInst = 6; ///< Kernel functions.
+const int kLoadInst = 7; ///< Load value to stack.
+const int kReturnInst = 8; ///< Return from regular function call.
+const int kStackInst = 9; ///< Stack allocation or deallocation (altering stack pointer)
+const int kStoreInst = 10; ///< Store value from stack in memory.
+const int kUnaryOpPreInst = 11; ///< Unary operation (e.g. !) with operator placed before the operator.
+const int kUnaryOpPostInst = 12; ///< Unary operation with operator placed after the operator.
+const int kFirstCustomInst = kUnaryOpPostInst + 1; ///< First unused key. Add your custom type keys starting with this value.
+
+struct Instruction;
+
/**
+ * Pointer to an Instruction.
+ */
+typedef boost::intrusive_ptr<Instruction> InstPtr;
+
+/**
* Structure for representing an instruction.
*/
struct Instruction : public RefCounted {
+public:
uint32 _opcode; ///< The instruction opcode.
uint32 _address; ///< The instruction address.
std::string _name; ///< The instruction name (opcode name).
- InstType _type; ///< The instruction type.
int16 _stackChange; ///< How much this instruction changes the stack pointer by.
std::vector<ValuePtr> _params; ///< Array of parameters used for the instruction.
std::string _codeGenData; ///< String containing metadata for code generation. See the extended documentation for details.
Instruction(uint32 opcode = 0, uint32 address = 0,
- std::string name = "", InstType type = kSpecialCallInstType, int16 stackChange = 0) :
- _opcode(opcode), _address(address), _name(name), _type(type), _stackChange(stackChange) {}
+ std::string name = "", int16 stackChange = 0) :
+ _opcode(opcode), _address(address), _name(name), _stackChange(stackChange) {}
/**
* Operator overload to output an Instruction to a std::ostream.
@@ -77,34 +87,99 @@
* @return The std::ostream used for output.
*/
friend std::ostream &operator<<(std::ostream &output, const Instruction *inst) {
- return output << *inst;
+ return inst->print(output);
}
- /**
- * Operator overload to output an Instruction to a std::ostream.
- *
- * @param output The std::ostream to output to.
- * @param inst The Instruction to output.
- * @return The std::ostream used for output.
- */
- friend std::ostream &operator<<(std::ostream &output, const Instruction &inst) {
- output << boost::format("%08x: %s") % inst._address % inst._name;
- std::vector<ValuePtr>::const_iterator param;
- for (param = inst._params.begin(); param != inst._params.end(); ++param) {
- if (param != inst._params.begin())
- output << ",";
- output << " " << *param;
- }
- output << boost::format(" (%d)") % inst._stackChange << "\n";
- return output;
- }
+ virtual std::ostream &print(std::ostream &output) const;
+
+ virtual bool isJump() const;
+ virtual bool isCondJump() const;
+ virtual bool isUncondJump() const;
+ virtual bool isStackOp() const;
+ virtual bool isFuncCall() const;
+ virtual bool isReturn() const;
+ virtual bool isKernelCall() const;
+ virtual bool isLoad() const;
+ virtual bool isStore() const;
+ virtual uint32 getDestAddress() const;
+
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) = 0;
+
};
-/**
- * Pointer to an Instruction.
- */
-typedef boost::intrusive_ptr<Instruction> InstPtr;
+struct JumpInstruction : public Instruction {
+public:
+ virtual bool isJump() const;
+};
+struct CondJumpInstruction : public JumpInstruction {
+public:
+ virtual bool isCondJump() const;
+};
+
+struct UncondJumpInstruction : public JumpInstruction {
+public:
+ virtual bool isUncondJump() const;
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct StackInstruction : public Instruction {
+public:
+ virtual bool isStackOp() const;
+};
+
+struct CallInstruction : public Instruction {
+public:
+ virtual bool isFuncCall() const;
+};
+
+struct LoadInstruction : public Instruction {
+public:
+ virtual bool isLoad() const;
+};
+
+struct StoreInstruction : public Instruction {
+public:
+ virtual bool isStore() const;
+};
+
+struct DupInstruction : public Instruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct BoolNegateInstruction : public Instruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct BinaryOpInstruction : public Instruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct ReturnInstruction : public Instruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+ virtual bool isReturn() const;
+};
+
+struct UnaryOpPrefixInstruction : public Instruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct UnaryOpPostfixInstruction : public Instruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+struct KernelCallInstruction : public Instruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+ virtual bool isKernelCall() const;
+};
+
/**
* Type representing a vector of InstPtrs.
*/
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -35,147 +35,10 @@
return s.str();
}
-void Kyra::Kyra2CodeGenerator::processInst(const InstPtr inst) {
- switch (inst->_type) {
- case kLoadInstType:
- switch (inst->_opcode) {
- case 2:
- // If something has been called previously in this group, don't output retval variable
- if (inst->_address <= findFirstCall()->_address)
- _stack.push(new VarValue("retval"));
- break;
- case 3:
- case 4:
- _stack.push(inst->_params[0]);
- break;
- case 5:
- {
- std::stringstream s;
- s << boost::format("var%d") % inst->_params[0]->getSigned();
- _stack.push(new VarValue(s.str()));
- }
- break;
- case 6:
- {
- std::stringstream s;
- s << boost::format("localvar%d") % inst->_params[0]->getSigned();
- _stack.push(new VarValue(s.str()));
- }
- break;
- case 7:
- {
- std::stringstream s;
- s << boost::format("param%d") % inst->_params[0]->getSigned();
- _stack.push(new VarValue(s.str()));
- }
- break;
- }
- break;
- case kStoreInstType:
- switch (inst->_opcode) {
- case 8:
- {
- ValuePtr p = new VarValue("retval");
- writeAssignment(p, _stack.pop());
- }
- break;
- case 9:
- {
- std::stringstream s;
- s << boost::format("var%d") % inst->_params[0]->getSigned();
- ValuePtr p = new VarValue(s.str());
- writeAssignment(p, _stack.pop());
- }
- break;
- case 10:
- {
- std::stringstream s;
- s << boost::format("localvar%d") % inst->_params[0]->getSigned();
- ValuePtr p = new VarValue(s.str());
- writeAssignment(p, _stack.pop());
- }
- break;
- case 11:
- {
- std::stringstream s;
- s << boost::format("param%d") % inst->_params[0]->getSigned();
- ValuePtr p = new VarValue(s.str());
- writeAssignment(p, _stack.pop());
- }
- break;
- }
- break;
- case kStackInstType:
- if (inst->_opcode == 12) {
- for (int i = inst->_params[0]->getSigned(); i != 0; --i) {
- if (!_stack.empty())
- _stack.pop();
- }
- } else if (inst->_opcode == 13) {
- for (int i = 0; i != inst->_params[0]->getSigned(); ++i) {
- std::stringstream s;
- s << boost::format("localvar%d") % i;
- _stack.push(new VarValue(s.str()));
- }
- }
- break;
- case kCondJumpInstType:
- _stack.push(_stack.pop()->negate());
- CodeGenerator::processInst(inst);
- break;
- case kCallInstType:
- {
- _argList.clear();
- Function f = _engine->_functions.find(inst->_params[0]->getUnsigned())->second;
- for (size_t i = 0; i < f._metadata.length(); i++)
- processSpecialMetadata(inst, f._metadata[i], i);
- _stack.push(new CallValue(f._name, _argList));
- // Leave call on stack if this is a condition, or other calls follow in same group
- if (_curGroup->_type == kIfCondGroupType || _curGroup->_type == kWhileCondGroupType || _curGroup->_type == kDoWhileCondGroupType || inst->_address != findLastCall()->_address) {
- break;
- } else if (!f._retVal) {
- std::stringstream stream;
- stream << _stack.pop() << ";";
- addOutputLine(stream.str());
- } else {
- ValuePtr p = new VarValue("retval");
- writeAssignment(p, _stack.pop());
- }
- break;
- }
- case kSpecialCallInstType:
- {
- if (inst->_opcode != 14)
- return;
- _argList.clear();
- bool returnsValue = (inst->_codeGenData.find("r") == 0);
- std::string metadata = (!returnsValue ? inst->_codeGenData : inst->_codeGenData.substr(1));
- for (size_t i = 0; i < metadata.length(); i++)
- processSpecialMetadata(inst, metadata[i], i);
- _stack.push(new CallValue(inst->_name, _argList));
- // Leave call on stack if this is a condition, or other calls follow in same group
- if (_curGroup->_type == kIfCondGroupType || _curGroup->_type == kWhileCondGroupType || _curGroup->_type == kDoWhileCondGroupType || inst->_address != findLastCall()->_address) {
- break;
- } else if (!returnsValue) {
- std::stringstream stream;
- stream << _stack.pop() << ";";
- addOutputLine(stream.str());
- } else {
- ValuePtr p = new VarValue("retval");
- writeAssignment(p, _stack.pop());
- }
- break;
- }
- default:
- CodeGenerator::processInst(inst);
- break;
- }
-}
-
const InstPtr Kyra::Kyra2CodeGenerator::findFirstCall() {
ConstInstIterator it = _curGroup->_start;
do {
- if ((*it)->_type == kCallInstType || ((*it)->_type == kSpecialCallInstType && (*it)->_opcode == 14))
+ if ((*it)->isFuncCall() || ((*it)->isKernelCall() && (*it)->_opcode == 14))
return *it;
} while (it++ != _curGroup->_end);
@@ -185,7 +48,7 @@
const InstPtr Kyra::Kyra2CodeGenerator::findLastCall() {
ConstInstIterator it = _curGroup->_end;
do {
- if ((*it)->_type == kCallInstType || ((*it)->_type == kSpecialCallInstType && (*it)->_opcode == 14))
+ if ((*it)->isFuncCall() || ((*it)->isKernelCall() && (*it)->_opcode == 14))
return *it;
} while (it-- != _curGroup->_start);
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h 2010-12-14 03:14:11 UTC (rev 54904)
@@ -31,10 +31,18 @@
* KYRA code generator.
*/
class Kyra2CodeGenerator : public CodeGenerator {
-private:
+public:
/**
+ * Constructor for Kyra2CodeGenerator.
+ *
+ * @param engine Pointer to the Engine used for the script.
+ * @param output The std::ostream to output the code to.
+ */
+ Kyra2CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kLIFOArgOrder) {}
+
+ /**
* Finds the first call instruction in the current group and returns it.
- * The call may either be a kCallInstType or kSpecialCallInstType.
+ * The call may either be a kCallInst or kKernelCallInst.
* Used to check whether retVal should be output by pushRet.
*
* @return The first call instruction in the current group. If no calls are found, returns the first instruction.
@@ -43,23 +51,16 @@
/**
* Finds the last call instruction in the current group and returns it.
- * The call may either be a kCallInstType or kSpecialCallInstType.
+ * The call may either be a kCallInst or kKernelCallInst.
* Used to check whether retVal should be output by calls.
*
* @return The last call instruction in the current group. If no calls are found, returns the last instruction.
*/
const InstPtr findLastCall();
-public:
- /**
- * Constructor for Kyra2CodeGenerator.
- *
- * @param engine Pointer to the Engine used for the script.
- * @param output The std::ostream to output the code to.
- */
- Kyra2CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kLIFOArgOrder) {}
+
+ virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
+
protected:
- void processInst(const InstPtr inst);
- virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
std::string constructFuncSignature(const Function &func);
};
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -266,6 +266,13 @@
Kyra::Kyra2Disassembler::Kyra2Disassembler(Kyra2Engine *engine, InstVec &insts) : Disassembler(insts), _engine(engine) {
setupKyra2Funcs();
+ _instFactory.addEntry<Kyra2CallInstruction>(kCallInst);
+ _instFactory.addEntry<Kyra2CondJumpInstruction>(kCondJumpInst);
+ _instFactory.addEntry<Kyra2UncondJumpInstruction>(kJumpInst);
+ _instFactory.addEntry<Kyra2KernelCallInstruction>(kKernelCallInst);
+ _instFactory.addEntry<Kyra2LoadInstruction>(kLoadInst);
+ _instFactory.addEntry<Kyra2StackInstruction>(kStackInst);
+ _instFactory.addEntry<Kyra2StoreInstruction>(kStoreInst);
}
Kyra::Kyra2Disassembler::~Kyra2Disassembler() {
@@ -388,15 +395,14 @@
parameter = 0;
}
-#define ADD_INST _insts.insert(_insts.end(), new Instruction());
+#define ADD_INST(category) _insts.push_back(_instFactory.create(category));
#define LAST_INST (_insts.back())
#define OPCODE_MD(name, category, stackChange, hasParam, isSigned, isAddress, codeGenData) \
- ADD_INST; \
+ ADD_INST(category); \
LAST_INST->_opcode = opcode; \
LAST_INST->_address = address; \
LAST_INST->_stackChange = stackChange; \
LAST_INST->_name = name; \
- LAST_INST->_type = category; \
LAST_INST->_codeGenData = codeGenData; \
if (hasParam) { \
ValuePtr p; \
@@ -416,16 +422,16 @@
parameter *= 2;
if (parameter < minFuncAddr)
jumpTargets.insert(_insts.size());
- OPCODE("jumpTo", kJumpInstType, 0, true, false, true);
+ OPCODE("jumpTo", kJumpInst, 0, true, false, true);
break;
case 1:
- OPCODE("setRetValue", kStoreInstType, 0, true, true, false);
+ OPCODE("setRetValue", kStoreInst, 0, true, true, false);
break;
case 2:
if (parameter == 0) {
- OPCODE("pushRet", kLoadInstType, 1, false, false, false);
+ OPCODE("pushRet", kLoadInst, 1, false, false, false);
} else if (parameter == 1) {
- OPCODE("pushPos", kSpecialCallInstType, 0, false, false, false); // Sets up function call
+ OPCODE("pushPos", kKernelCallInst, 0, false, false, false); // Sets up function call
} else {
// Error: invalid parameter halts execution
throw UnknownOpcodeException(address, opcode);
@@ -433,41 +439,41 @@
break;
case 3:
case 4:
- OPCODE("push", kLoadInstType, 1, true, true, false);
+ OPCODE("push", kLoadInst, 1, true, true, false);
break;
case 5:
- OPCODE("pushVar", kLoadInstType, 1, true, true, false);
+ OPCODE("pushVar", kLoadInst, 1, true, true, false);
break;
case 6:
- OPCODE("pushBPNeg", kLoadInstType, 1, true, true, false);
+ OPCODE("pushBPNeg", kLoadInst, 1, true, true, false);
break;
case 7:
- OPCODE("pushBPAdd", kLoadInstType, 1, true, true, false);
+ OPCODE("pushBPAdd", kLoadInst, 1, true, true, false);
break;
case 8:
if (parameter == 0) {
- OPCODE("popRet", kStoreInstType, -1, false, false, false);
+ OPCODE("popRet", kStoreInst, -1, false, false, false);
} else if (parameter == 1) {
- OPCODE("popPos", kReturnInstType, 0, false, false, false); // Returns from function call
+ OPCODE("popPos", kReturnInst, 0, false, false, false); // Returns from function call
} else {
// Error: invalid parameter halts execution
throw UnknownOpcodeException(address, opcode);
}
break;
case 9:
- OPCODE("popVar", kStoreInstType, -1, true, true, false);
+ OPCODE("popVar", kStoreInst, -1, true, true, false);
break;
case 10:
- OPCODE("popBPNeg", kStoreInstType, -1, true, true, false);
+ OPCODE("popBPNeg", kStoreInst, -1, true, true, false);
break;
case 11:
- OPCODE("popBPAdd", kStoreInstType, -1, true, true, false);
+ OPCODE("popBPAdd", kStoreInst, -1, true, true, false);
break;
case 12:
- OPCODE("addSP", kStackInstType, -parameter, true, true, false);
+ OPCODE("addSP", kStackInst, -parameter, true, true, false);
break;
case 13:
- OPCODE("subSP", kStackInstType, parameter, true, true, false);
+ OPCODE("subSP", kStackInst, parameter, true, true, false);
break;
case 14:
parameter = (uint8)parameter;
@@ -475,21 +481,21 @@
// Error: unknown function
throw UnknownOpcodeException(address, opcode);
}
- OPCODE_MD(_funcs[parameter]._name, kSpecialCallInstType, 0, false, false, false, _funcs[parameter]._metadata)
+ OPCODE_MD(_funcs[parameter]._name, kKernelCallInst, 0, false, false, false, _funcs[parameter]._metadata)
break;
case 15:
parameter *= 2;
if (parameter < minFuncAddr)
jumpTargets.insert(_insts.size());
- OPCODE("ifNotJmp", kCondJumpInstType, -1, true, false, true);
+ OPCODE("ifNotJmp", kCondJumpInst, -1, true, false, true);
break;
case 16:
if (parameter == 0) {
- OPCODE_MD("boolNegate", kUnaryOpPreInstType, 0, false, false, false, "!");
+ OPCODE("boolNegate", kBoolNegateInst, 0, false, false, false);
} else if (parameter == 1) {
- OPCODE_MD("arithmeticNegate", kUnaryOpPreInstType, 0, false, false, false,"-");
+ OPCODE_MD("arithmeticNegate", kUnaryOpPreInst, 0, false, false, false,"-");
} else if (parameter == 2) {
- OPCODE_MD("bitwiseNegate", kUnaryOpPreInstType, 0, false, false, false, "~");
+ OPCODE_MD("bitwiseNegate", kUnaryOpPreInst, 0, false, false, false, "~");
} else {
// Error: invalid parameter halts execution
throw UnknownOpcodeException(address, opcode);
@@ -498,58 +504,58 @@
case 17:
switch (parameter) {
case 0:
- OPCODE_MD("eval_band", kBinaryOpInstType, -1, false, false, false, "&&");
+ OPCODE_MD("eval_band", kBinaryOpInst, -1, false, false, false, "&&");
break;
case 1:
- OPCODE_MD("eval_bor", kBinaryOpInstType, -1, false, false, false, "||");
+ OPCODE_MD("eval_bor", kBinaryOpInst, -1, false, false, false, "||");
break;
case 2:
- OPCODE_MD("eval_eq", kBinaryOpInstType, -1, false, false, false, "==");
+ OPCODE_MD("eval_eq", kBinaryOpInst, -1, false, false, false, "==");
break;
case 3:
- OPCODE_MD("eval_neq", kBinaryOpInstType, -1, false, false, false, "!=");
+ OPCODE_MD("eval_neq", kBinaryOpInst, -1, false, false, false, "!=");
break;
case 4:
- OPCODE_MD("eval_leq", kBinaryOpInstType, -1, false, false, false, "<=");
+ OPCODE_MD("eval_leq", kBinaryOpInst, -1, false, false, false, "<=");
break;
case 5:
- OPCODE_MD("eval_lt", kBinaryOpInstType, -1, false, false, false, "<");
+ OPCODE_MD("eval_lt", kBinaryOpInst, -1, false, false, false, "<");
break;
case 6:
- OPCODE_MD("eval_geq", kBinaryOpInstType, -1, false, false, false, ">=");
+ OPCODE_MD("eval_geq", kBinaryOpInst, -1, false, false, false, ">=");
break;
case 7:
- OPCODE_MD("eval_gt", kBinaryOpInstType, -1, false, false, false, ">");
+ OPCODE_MD("eval_gt", kBinaryOpInst, -1, false, false, false, ">");
break;
case 8:
- OPCODE_MD("eval_add", kBinaryOpInstType, -1, false, false, false, "+");
+ OPCODE_MD("eval_add", kBinaryOpInst, -1, false, false, false, "+");
break;
case 9:
- OPCODE_MD("eval_sub", kBinaryOpInstType, -1, false, false, false, "-");
+ OPCODE_MD("eval_sub", kBinaryOpInst, -1, false, false, false, "-");
break;
case 10:
- OPCODE_MD("eval_mult", kBinaryOpInstType, -1, false, false, false, "*");
+ OPCODE_MD("eval_mult", kBinaryOpInst, -1, false, false, false, "*");
break;
case 11:
- OPCODE_MD("eval_div", kBinaryOpInstType, -1, false, false, false, "/");
+ OPCODE_MD("eval_div", kBinaryOpInst, -1, false, false, false, "/");
break;
case 12:
- OPCODE_MD("eval_shr", kBinaryOpInstType, -1, false, false, false, ">>");
+ OPCODE_MD("eval_shr", kBinaryOpInst, -1, false, false, false, ">>");
break;
case 13:
- OPCODE_MD("eval_shl", kBinaryOpInstType, -1, false, false, false, "<<");
+ OPCODE_MD("eval_shl", kBinaryOpInst, -1, false, false, false, "<<");
break;
case 14:
- OPCODE_MD("eval_land", kBinaryOpInstType, -1, false, false, false, "&");
+ OPCODE_MD("eval_land", kBinaryOpInst, -1, false, false, false, "&");
break;
case 15:
- OPCODE_MD("eval_lor", kBinaryOpInstType, -1, false, false, false, "|");
+ OPCODE_MD("eval_lor", kBinaryOpInst, -1, false, false, false, "|");
break;
case 16:
- OPCODE_MD("eval_mod", kBinaryOpInstType, -1, false, false, false, "%");
+ OPCODE_MD("eval_mod", kBinaryOpInst, -1, false, false, false, "%");
break;
case 17:
- OPCODE_MD("eval_xor", kBinaryOpInstType, -1, false, false, false, "^");
+ OPCODE_MD("eval_xor", kBinaryOpInst, -1, false, false, false, "^");
break;
default:
// Error: invalid parameter halts execution
@@ -558,7 +564,7 @@
}
break;
case 18:
- OPCODE("setRetAndJmp", kSpecialCallInstType, -2, false, false, false);
+ OPCODE("setRetAndJmp", kKernelCallInst, -2, false, false, false);
break;
default:
throw UnknownOpcodeException(i*2, code);
@@ -585,9 +591,16 @@
// Correct jumps to functions so they're treated as calls
bool lastWasPushPos = false;
for (InstIterator it = _insts.begin(); it != _insts.end(); ++it) {
- if ((*it)->_type == kJumpInstType || (*it)->_type == kCondJumpInstType) {
+ if ((*it)->isJump()) {
if (lastWasPushPos || _engine->_functions.find((*it)->_params[0]->getUnsigned()) != _engine->_functions.end()) {
- (*it)->_type = kCallInstType;
+ InstPtr p = _instFactory.create(kCallInst);
+ p->_opcode = (*it)->_opcode;
+ p->_address = (*it)->_address;
+ p->_stackChange = (*it)->_stackChange;
+ p->_name = (*it)->_name;
+ p->_codeGenData = (*it)->_codeGenData;
+ p->_params = (*it)->_params;
+ *it = p;
}
}
lastWasPushPos = ((*it)->_name.compare("pushPos") == 0);
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -32,10 +32,6 @@
return new Kyra2Disassembler(this, insts);
}
-uint32 Kyra::Kyra2Engine::getDestAddress(const InstPtr inst) const {
- return inst->_params[0]->getUnsigned();
-}
-
CodeGenerator *Kyra::Kyra2Engine::getCodeGenerator(std::ostream &output) {
return new Kyra2CodeGenerator(this, output);
}
@@ -63,3 +59,145 @@
bool Kyra::Kyra2Engine::detectMoreFuncs() const {
return true;
}
+
+void Kyra::Kyra2LoadInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+ switch (_opcode) {
+ case 2:
+ // If something has been called previously in this group, don't output retval variable
+ if (_address <= cg->findFirstCall()->_address)
+ stack.push(new VarValue("retval"));
+ break;
+ case 3:
+ case 4:
+ stack.push(_params[0]);
+ break;
+ case 5:
+ {
+ std::stringstream s;
+ s << boost::format("var%d") % _params[0]->getSigned();
+ stack.push(new VarValue(s.str()));
+ }
+ break;
+ case 6:
+ {
+ std::stringstream s;
+ s << boost::format("localvar%d") % _params[0]->getSigned();
+ stack.push(new VarValue(s.str()));
+ }
+ break;
+ case 7:
+ {
+ std::stringstream s;
+ s << boost::format("param%d") % _params[0]->getSigned();
+ stack.push(new VarValue(s.str()));
+ }
+ break;
+ }
+}
+
+void Kyra::Kyra2StoreInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+ switch (_opcode) {
+ case 8:
+ {
+ ValuePtr p = new VarValue("retval");
+ cg->writeAssignment(p, stack.pop());
+ }
+ break;
+ case 9:
+ {
+ std::stringstream s;
+ s << boost::format("var%d") % _params[0]->getSigned();
+ ValuePtr p = new VarValue(s.str());
+ cg->writeAssignment(p, stack.pop());
+ }
+ break;
+ case 10:
+ {
+ std::stringstream s;
+ s << boost::format("localvar%d") % _params[0]->getSigned();
+ ValuePtr p = new VarValue(s.str());
+ cg->writeAssignment(p, stack.pop());
+ }
+ break;
+ case 11:
+ {
+ std::stringstream s;
+ s << boost::format("param%d") % _params[0]->getSigned();
+ ValuePtr p = new VarValue(s.str());
+ cg->writeAssignment(p, stack.pop());
+ }
+ break;
+ }
+}
+
+void Kyra::Kyra2StackInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ if (_opcode == 12) {
+ for (int i = _params[0]->getSigned(); i != 0; --i) {
+ if (!stack.empty())
+ stack.pop();
+ }
+ } else if (_opcode == 13) {
+ for (int i = 0; i != _params[0]->getSigned(); ++i) {
+ std::stringstream s;
+ s << boost::format("localvar%d") % i;
+ stack.push(new VarValue(s.str()));
+ }
+ }
+}
+
+void Kyra::Kyra2CondJumpInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ stack.push(stack.pop()->negate());
+}
+
+uint32 Kyra::Kyra2CondJumpInstruction::getDestAddress() const {
+ return _params[0]->getUnsigned();
+}
+
+uint32 Kyra::Kyra2UncondJumpInstruction::getDestAddress() const {
+ return _params[0]->getUnsigned();
+}
+
+void Kyra::Kyra2CallInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+ cg->_argList.clear();
+ Function f = engine->_functions.find(_params[0]->getUnsigned())->second;
+ for (size_t i = 0; i < f._metadata.length(); i++)
+ cg->processSpecialMetadata(this, f._metadata[i], i);
+ stack.push(new CallValue(f._name, cg->_argList));
+ // Leave call on stack if this is a condition, or other calls follow in same group
+ if (cg->_curGroup->_type == kIfCondGroupType || cg->_curGroup->_type == kWhileCondGroupType || cg->_curGroup->_type == kDoWhileCondGroupType || _address != cg->findLastCall()->_address) {
+ return;
+ } else if (!f._retVal) {
+ std::stringstream stream;
+ stream << stack.pop() << ";";
+ cg->addOutputLine(stream.str());
+ } else {
+ ValuePtr p = new VarValue("retval");
+ cg->writeAssignment(p, stack.pop());
+ }
+}
+
+void Kyra::Kyra2KernelCallInstruction::processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen) {
+ Kyra2CodeGenerator* cg = (Kyra2CodeGenerator *)codeGen;
+ if (_opcode != 14)
+ return;
+ cg->_argList.clear();
+ bool returnsValue = (_codeGenData.find("r") == 0);
+ std::string metadata = (!returnsValue ? _codeGenData : _codeGenData.substr(1));
+ for (size_t i = 0; i < metadata.length(); i++)
+ cg->processSpecialMetadata(this, metadata[i], i);
+ stack.push(new CallValue(_name, cg->_argList));
+ // Leave call on stack if this is a condition, or other calls follow in same group
+ if (cg->_curGroup->_type == kIfCondGroupType || cg->_curGroup->_type == kWhileCondGroupType || cg->_curGroup->_type == kDoWhileCondGroupType || _address != cg->findLastCall()->_address) {
+ return;
+ } else if (!returnsValue) {
+ std::stringstream stream;
+ stream << stack.pop() << ";";
+ cg->addOutputLine(stream.str());
+ } else {
+ ValuePtr p = new VarValue("retval");
+ cg->writeAssignment(p, stack.pop());
+ }
+}
Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h 2010-12-14 03:14:11 UTC (rev 54904)
@@ -36,7 +36,6 @@
class Kyra2Engine : public Engine {
public:
Disassembler *getDisassembler(InstVec &insts);
- uint32 getDestAddress(const InstPtr inst) const;
CodeGenerator *getCodeGenerator(std::ostream &output);
void postCFG(InstVec &insts, Graph g);
bool detectMoreFuncs() const;
@@ -44,6 +43,42 @@
std::vector<std::string> _textStrings; ///< Container for strings from the TEXT chunk.
};
+class Kyra2LoadInstruction : public LoadInstruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2StoreInstruction : public StoreInstruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2StackInstruction : public StackInstruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2CondJumpInstruction : public CondJumpInstruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+ virtual uint32 getDestAddress() const;
+};
+
+class Kyra2UncondJumpInstruction : public UncondJumpInstruction {
+public:
+ virtual uint32 getDestAddress() const;
+};
+
+class Kyra2CallInstruction : public CallInstruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
+class Kyra2KernelCallInstruction : public KernelCallInstruction {
+public:
+ virtual void processInst(ValueStack &stack, Engine *engine, CodeGenerator *codeGen);
+};
+
} // End of namespace Kyra
#endif
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -45,164 +45,6 @@
return new ListValue(list);
}
-void Scumm::v6::Scummv6CodeGenerator::processInst(const InstPtr inst) {
- // This is just to keep some order in this code and have related
- // opcodes near each other. It's not strictly necessary, because we
- // can just look directly at the opcode, but this should be easier
- // to read.
- switch (inst->_type) {
- case kLoadInstType:
- switch (inst->_opcode) {
- case 0x00: // pushByte
- case 0x01: // pushWord
- _stack.push(inst->_params[0]);
- break;
- case 0x02: // pushByteVar
- case 0x03: // pushWordVar
- _stack.push(new VarValue(decodeVarName(inst->_params[0]->getUnsigned())));
- break;
- case 0x06: // byteArrayRead
- case 0x07: // wordArrayRead
- {
- ValueList idxs;
- idxs.push_front(_stack.pop());
- _stack.push(new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs));
- break;
- }
- case 0x0A: // byteArrayIndexedRead
- case 0x0B: // wordArrayIndexedRead
- {
- ValueList idxs;
- idxs.push_front(_stack.pop());
- idxs.push_front(_stack.pop());
- _stack.push(new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs));
- break;
- }
- }
- break;
- case kStoreInstType:
- switch (inst->_opcode) {
- case 0x42: // writeByteVar
- case 0x43: // writeWordVar
- {
- ValuePtr p = new VarValue(decodeVarName(inst->_params[0]->getUnsigned()));
- writeAssignment(p, _stack.pop());
- }
- break;
- case 0x46: // byteArrayWrite
- case 0x47: // wordArrayWrite
- {
- ValuePtr value = _stack.pop();
- ValueList idxs;
- idxs.push_back(_stack.pop());
- ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
- writeAssignment(p, value);
- }
- break;
- case 0x4A: // byteArrayIndexedWrite
- case 0x4B: // wordArrayIndexedWrite
- {
- ValuePtr value = _stack.pop();
- ValueList idxs;
- idxs.push_front(_stack.pop());
- idxs.push_front(_stack.pop());
- ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
- writeAssignment(p, value);
- }
- break;
- default:
- {
- std::stringstream s;
- s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst->_opcode % inst->_address;
- addOutputLine(s.str());
- }
- break;
- }
- break;
- case kStackInstType:
- // Only two opcodes in SCUMMv6, 0x1A and 0xA7: both are single item pop
- _stack.pop();
- //addOutputLine("// pop();");
- break;
- case kCondJumpRelInstType:
- if (inst->_opcode == 0x5D) // jumpFalse
- _stack.push(_stack.pop()->negate());
- CodeGenerator::processInst(inst);
- break;
- case kUnaryOpPostInstType:
- switch (inst->_opcode) {
- case 0x4E: // byteVarInc
- case 0x4F: // wordVarInc
- case 0x56: // byteVarDec
- case 0x57: // wordVarDec
- {
- std::stringstream s;
- ValuePtr p = new UnaryOpValue(new VarValue(decodeVarName(inst->_params[0]->getUnsigned())), inst->_codeGenData, true);
- s << p << ";";
- addOutputLine(s.str());
- }
- break;
- case 0x52: // byteArrayInc
- case 0x53: // wordArrayInc
- case 0x5A: // byteArrayDec
- case 0x5B: // wordArrayDec
- {
- std::stringstream s;
- ValueList idxs;
- idxs.push_front(_stack.pop());
- ValuePtr p = new UnaryOpValue(new ArrayValue(decodeVarName(inst->_params[0]->getUnsigned()), idxs), inst->_codeGenData, true);
- s << p << ";";
- addOutputLine(s.str());
- }
- break;
- default:
- CodeGenerator::processInst(inst);
- break;
- }
- break;
- case kSpecialCallInstType:
- switch (inst->_opcode) {
- case 0xA4CD: // arrayOp_assignString
- {
- ValuePtr value = new StringValue(inst->_params[1]->getString());
- ValueList idxs;
- idxs.push_front(_stack.pop());
- ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
- writeAssignment(p, value);
- }
- break;
- case 0xA4D0: // arrayOp_assignIntList
- {
- ValueList idxs;
- idxs.push_front(_stack.pop());
- ValuePtr value = createListValue();
- ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
- writeAssignment(p, value);
- }
-
- break;
- case 0xA4D4: // arrayOp_assign2DimList
- {
- ValueList idxs;
- idxs.push_front(_stack.pop());
- ValuePtr value = createListValue();
- idxs.push_front(_stack.pop());
- ValuePtr p = new ArrayValue(decodeArrayName(inst->_params[0]->getUnsigned()), idxs);
- writeAssignment(p, value);
- }
-
- break;
- default:
- CodeGenerator::processInst(inst);
- break;
- }
- break;
- default:
- CodeGenerator::processInst(inst);
- break;
- }
-}
-
const char *var_names[] = {
/* 0 */
NULL,
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.h 2010-12-14 03:14:11 UTC (rev 54904)
@@ -48,8 +48,16 @@
* SCUMMv6 code generator.
*/
class Scummv6CodeGenerator : public CodeGenerator {
-private:
+public:
/**
+ * Constructor for Scumm::v6::CodeGenerator.
+ *
+ * @param engine Pointer to the Engine used for the script.
+ * @param output The std::ostream to output the code to.
+ */
+ Scummv6CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kFIFOArgOrder) {}
+
+ /**
* Get the name associated with a variable ID.
*
* @param varID The ID to get the name for.
@@ -79,16 +87,7 @@
* @return The ListValue created from the stack.
*/
ValuePtr createListValue();
-public:
- /**
- * Constructor for Scumm::v6::CodeGenerator.
- *
- * @param engine Pointer to the Engine used for the script.
- * @param output The std::ostream to output the code to.
- */
- Scummv6CodeGenerator(Engine *engine, std::ostream &output) : CodeGenerator(engine, output, kFIFOArgOrder, kFIFOArgOrder) {}
-protected:
- void processInst(const InstPtr inst);
+
virtual void processSpecialMetadata(const InstPtr inst, char c, int pos);
};
Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp 2010-12-14 02:36:04 UTC (rev 54903)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp 2010-12-14 03:14:11 UTC (rev 54904)
@@ -28,6 +28,13 @@
#include "disassembler.h"
Scumm::v6::Scummv6Disassembler::Scummv6Disassembler(InstVec &insts) : SimpleDisassembler(insts) {
+ _instFactory.addEntry<Scummv6CondJumpInstruction>(kCondJumpInst);
+ _instFactory.addEntry<Scummv6JumpInstruction>(kJumpInst);
+ _instFactory.addEntry<Scummv6LoadInstruction>(kLoadInst);
+ _instFactory.addEntry<Scummv6StackInstruction>(kStackInst);
+ _instFactory.addEntry<Scummv6StoreInstruction>(kStoreInst);
+ _instFactory.addEntry<Scummv6ArrayOpInstruction>(kArrayOpInst);
+ _instFactory.addEntry<Scummv6IncDecInstruction>(kIncDecInst);
}
void Scumm::v6::Scummv6Disassembler::doDisassemble() throw(std::exception) {
@@ -63,114 +70,114 @@
}
START_OPCODES;
- OPCODE(0x00, "pushByte", kLoadInstType, 1, "B");
- OPCODE(0x01, "pushWord", kLoadInstType, 1, "s");
- OPCODE(0x02, "pushByteVar", kLoadInstType, 1, "B");
- OPCODE(0x03, "pushWordVar", kLoadInstType, 1, "w");
- OPCODE(0x06, "byteArrayRead", kLoadInstType, 0, "B");
- OPCODE(0x07, "wordArrayRead", kLoadInstType, 0, "w");
- OPCODE(0x0A, "byteArrayIndexedRead", kLoadInstType, -1, "B");
- OPCODE(0x0B, "wordArrayIndexedRead", kLoadInstType, -1, "w");
- OPCODE(0x0C, "dup", kDupInstType, 1, "");
- OPCODE_MD(0x0D, "not", kUnaryOpPreInstType, 0, "", "!");
- OPCODE_MD(0x0E, "eq", kBinaryOpInstType, -1, "", "==");
- OPCODE_MD(0x0F, "neq", kBinaryOpInstType, -1, "", "!=");
- OPCODE_MD(0x10, "gt", kBinaryOpInstType, -1, "", ">");
- OPCODE_MD(0x11, "lt", kBinaryOpInstType, -1, "", "<");
- OPCODE_MD(0x12, "le", kBinaryOpInstType, -1, "", "<=");
- OPCODE_MD(0x13, "ge", kBinaryOpInstType, -1, "", ">=");
- OPCODE_MD(0x14, "add", kBinaryOpInstType, -1, "", "+");
- OPCODE_MD(0x15, "sub", kBinaryOpInstType, -1, "", "-");
- OPCODE_MD(0x16, "mul", kBinaryOpInstType, -1, "", "*");
- OPCODE_MD(0x17, "div", kBinaryOpInstType, -1, "", "/");
- OPCODE_MD(0x18, "land", kBinaryOpInstType, -1, "", "&&");
- OPCODE_MD(0x19, "lor", kBinaryOpInstType, -1, "", "||");
- OPCODE(0x1A, "pop", kStackInstType, -1, "");
- OPCODE(0x42, "writeByteVar", kStoreInstType, -1, "B");
- OPCODE(0x43, "writeWordVar", kStoreInstType, -1, "w");
- OPCODE(0x46, "byteArrayWrite", kStoreInstType, -2, "B");
- OPCODE(0x47, "wordArrayWrite", kStoreInstType, -2, "w");
- OPCODE(0x4A, "byteArrayIndexedWrite", kStoreInstType, -3, "B");
- OPCODE(0x4B, "wordArrayIndexedWrite", kStoreInstType, -3, "w");
- OPCODE_MD(0x4E, "byteVarInc", kUnaryOpPostInstType, 0, "B", "++");
- OPCODE_MD(0x4F, "wordVarInc", kUnaryOpPostInstType, 0, "w", "++");
- OPCODE_MD(0x52, "byteArrayInc", kUnaryOpPostInstType, -1, "B", "++");
- OPCODE_MD(0x53, "wordArrayInc", kUnaryOpPostInstType, -1, "w", "++");
- OPCODE_MD(0x56, "byteVarDec", kUnaryOpPostInstType, 0, "B", "--");
- OPCODE_MD(0x57, "wordVarDec", kUnaryOpPostInstType, 0, "w", "--");
- OPCODE_MD(0x5A, "byteArrayDec", kUnaryOpPostInstType, -1, "B", "--");
- OPCODE_MD(0x5B, "wordArrayDec", kUnaryOpPostInstType, -1, "w", "--");
- OPCODE(0x5C, "jumpTrue", kCondJumpRelInstType, -1, "a");
- OPCODE(0x5D, "jumpFalse", kCondJumpRelInstType, -1, "a");
- OPCODE_MD(0x5E, "startScript", kSpecialCallInstType, 0x1020, "", "lpp"); // Variable stack arguments
- OPCODE_MD(0x5F, "startScriptQuick", kSpecialCallInstType, 0x1010, "", "lp"); // Variable stack arguments
- OPCODE_MD(0x60, "startObject", kSpecialCallInstType, 0x1030, "", "lppp"); // Variable stack arguments
- OPCODE_MD(0x61, "drawObject", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x62, "drawObjectAt", kSpecialCallInstType, -3, "", "ppp");
- OPCODE_MD(0x63, "drawBlastObject", kSpecialCallInstType, -5, "", "ppppp");
- OPCODE_MD(0x64, "setBlastObjectWindow", kSpecialCallInstType, -4, "", "pppp");
- OPCODE(0x65, "stopObjectCodeA", kSpecialCallInstType, 0, "");
- OPCODE(0x66, "stopObjectCodeB", kSpecialCallInstType, 0, "");
- OPCODE(0x67, "endCutscene", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x68, "beginCutscene", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
- OPCODE(0x69, "stopMusic", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x6A, "freezeUnfreeze", kSpecialCallInstType, -1, "", "p");
+ OPCODE(0x00, "pushByte", kLoadInst, 1, "B");
+ OPCODE(0x01, "pushWord", kLoadInst, 1, "s");
+ OPCODE(0x02, "pushByteVar", kLoadInst, 1, "B");
+ OPCODE(0x03, "pushWordVar", kLoadInst, 1, "w");
+ OPCODE(0x06, "byteArrayRead", kLoadInst, 0, "B");
+ OPCODE(0x07, "wordArrayRead", kLoadInst, 0, "w");
+ OPCODE(0x0A, "byteArrayIndexedRead", kLoadInst, -1, "B");
+ OPCODE(0x0B, "wordArrayIndexedRead", kLoadInst, -1, "w");
+ OPCODE(0x0C, "dup", kDupInst, 1, "");
+ OPCODE(0x0D, "not", kBoolNegateInst, 0, "");
+ OPCODE_MD(0x0E, "eq", kBinaryOpInst, -1, "", "==");
+ OPCODE_MD(0x0F, "neq", kBinaryOpInst, -1, "", "!=");
+ OPCODE_MD(0x10, "gt", kBinaryOpInst, -1, "", ">");
+ OPCODE_MD(0x11, "lt", kBinaryOpInst, -1, "", "<");
+ OPCODE_MD(0x12, "le", kBinaryOpInst, -1, "", "<=");
+ OPCODE_MD(0x13, "ge", kBinaryOpInst, -1, "", ">=");
+ OPCODE_MD(0x14, "add", kBinaryOpInst, -1, "", "+");
+ OPCODE_MD(0x15, "sub", kBinaryOpInst, -1, "", "-");
+ OPCODE_MD(0x16, "mul", kBinaryOpInst, -1, "", "*");
+ OPCODE_MD(0x17, "div", kBinaryOpInst, -1, "", "/");
+ OPCODE_MD(0x18, "land", kBinaryOpInst, -1, "", "&&");
+ OPCODE_MD(0x19, "lor", kBinaryOpInst, -1, "", "||");
+ OPCODE(0x1A, "pop", kStackInst, -1, "");
+ OPCODE(0x42, "writeByteVar", kStoreInst, -1, "B");
+ OPCODE(0x43, "writeWordVar", kStoreInst, -1, "w");
+ OPCODE(0x46, "byteArrayWrite", kStoreInst, -2, "B");
+ OPCODE(0x47, "wordArrayWrite", kStoreInst, -2, "w");
+ OPCODE(0x4A, "byteArrayIndexedWrite", kStoreInst, -3, "B");
+ OPCODE(0x4B, "wordArrayIndexedWrite", kStoreInst, -3, "w");
+ OPCODE_MD(0x4E, "byteVarInc", kIncDecInst, 0, "B", "++");
+ OPCODE_MD(0x4F, "wordVarInc", kIncDecInst, 0, "w", "++");
+ OPCODE_MD(0x52, "byteArrayInc", kIncDecInst, -1, "B", "++");
+ OPCODE_MD(0x53, "wordArrayInc", kIncDecInst, -1, "w", "++");
+ OPCODE_MD(0x56, "byteVarDec", kIncDecInst, 0, "B", "--");
+ OPCODE_MD(0x57, "wordVarDec", kIncDecInst, 0, "w", "--");
+ OPCODE_MD(0x5A, "byteArrayDec", kIncDecInst, -1, "B", "--");
+ OPCODE_MD(0x5B, "wordArrayDec", kIncDecInst, -1, "w", "--");
+ OPCODE(0x5C, "jumpTrue", kCondJumpInst, -1, "a");
+ OPCODE(0x5D, "jumpFalse", kCondJumpInst, -1, "a");
+ OPCODE_MD(0x5E, "startScript", kKernelCallInst, 0x1020, "", "lpp"); // Variable stack arguments
+ OPCODE_MD(0x5F, "startScriptQuick", kKernelCallInst, 0x1010, "", "lp"); // Variable stack arguments
+ OPCODE_MD(0x60, "startObject", kKernelCallInst, 0x1030, "", "lppp"); // Variable stack arguments
+ OPCODE_MD(0x61, "drawObject", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x62, "drawObjectAt", kKernelCallInst, -3, "", "ppp");
+ OPCODE_MD(0x63, "drawBlastObject", kKernelCallInst, -5, "", "ppppp");
+ OPCODE_MD(0x64, "setBlastObjectWindow", kKernelCallInst, -4, "", "pppp");
+ OPCODE(0x65, "stopObjectCodeA", kKernelCallInst, 0, "");
+ OPCODE(0x66, "stopObjectCodeB", kKernelCallInst, 0, "");
+ OPCODE(0x67, "endCutscene", kKernelCallInst, 0, "");
+ OPCODE_MD(0x68, "beginCutscene", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+ OPCODE(0x69, "stopMusic", kKernelCallInst, 0, "");
+ OPCODE_MD(0x6A, "freezeUnfreeze", kKernelCallInst, -1, "", "p");
START_SUBOPCODE_WITH_PREFIX(0x6B, "cursorCommand");
- OPCODE(0x90, "cursorOn", kSpecialCallInstType, 0, "");
- OPCODE(0x91, "cursorOff", kSpecialCallInstType, 0, "");
- OPCODE(0x92, "userputOn", kSpecialCallInstType, 0, "");
- OPCODE(0x93, "userputOff", kSpecialCallInstType, 0, "");
- OPCODE(0x94, "softCursorOn", kSpecialCallInstType, 0, "");
- OPCODE(0x95, "softCursorOff", kSpecialCallInstType, 0, "");
- OPCODE(0x96, "softUserputOn", kSpecialCallInstType, 0, "");
- OPCODE(0x97, "softUserputOff", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x99, "setCursorImg", kSpecialCallInstType, -2, "", "z");
- OPCODE_MD(0x9A, "setCursorHotspot", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x9C, "initCharset", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x9D, "charsetColors", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
- OPCODE_MD(0xD6, "setCursorTransparency", kSpecialCallInstType, -1, "", "p");
+ OPCODE(0x90, "cursorOn", kKernelCallInst, 0, "");
+ OPCODE(0x91, "cursorOff", kKernelCallInst, 0, "");
+ OPCODE(0x92, "userputOn", kKernelCallInst, 0, "");
+ OPCODE(0x93, "userputOff", kKernelCallInst, 0, "");
+ OPCODE(0x94, "softCursorOn", kKernelCallInst, 0, "");
+ OPCODE(0x95, "softCursorOff", kKernelCallInst, 0, "");
+ OPCODE(0x96, "softUserputOn", kKernelCallInst, 0, "");
+ OPCODE(0x97, "softUserputOff", kKernelCallInst, 0, "");
+ OPCODE_MD(0x99, "setCursorImg", kKernelCallInst, -2, "", "z");
+ OPCODE_MD(0x9A, "setCursorHotspot", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x9C, "initCharset", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x9D, "charsetColors", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+ OPCODE_MD(0xD6, "setCursorTransparency", kKernelCallInst, -1, "", "p");
END_SUBOPCODE;
- OPCODE(0x6C, "breakHere", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x6D, "ifClassOfIs", kSpecialCallInstType, 0x1011, "", "rlp"); // Variable stack arguments
- OPCODE_MD(0x6E, "setClass", kSpecialCallInstType, 0x1010, "", "lp"); // Variable stack arguments
- OPCODE_MD(0x6F, "getState", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x70, "setState", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x71, "setOwner", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x72, "getOwner", kSpecialCallInstType, 0, "", "rp");
- OPCODE(0x73, "jump", kJumpRelInstType, 0, "a");
- OPCODE_MD(0x74, "startSound", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x75, "stopSound", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x76, "startMusic", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x77, "stopObjectScript", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x78, "panCameraTo", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x79, "actorFollowCamera", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x7A, "setCameraAt", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x7B, "loadRoom", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x7C, "stopScript", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x7D, "walkActorToObj", kSpecialCallInstType, -3, "", "ppp");
- OPCODE_MD(0x7E, "walkActorTo", kSpecialCallInstType, -3, "", "ppp");
- OPCODE_MD(0x7F, "putActorAtXY", kSpecialCallInstType, -4, "", "pppp");
- OPCODE_MD(0x80, "putActorAtObject", kSpecialCallInstType, -3, "", "zp");
- OPCODE_MD(0x81, "faceActor", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x82, "animateActor", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x83, "doSentence", kSpecialCallInstType, -4, "", "pppp");
- OPCODE_MD(0x84, "pickupObject", kSpecialCallInstType, -2, "", "z");
- OPCODE_MD(0x85, "loadRoomWithEgo", kSpecialCallInstType, -4, "", "ppz");
- OPCODE_MD(0x87, "getRandomNumber", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x88, "getRandomNumberRange", kSpecialCallInstType, -1, "", "rpp");
- OPCODE_MD(0x8A, "getActorMoving", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x8B, "isScriptRunning", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x8C, "getActorRoom", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x8D, "getObjectX", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x8E, "getObjectY", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x8F, "getObjectDir", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x90, "getActorWalkBox", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x91, "getActorCostume", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x92, "findInventory", kSpecialCallInstType, -1, "", "rpp");
- OPCODE_MD(0x93, "getInventoryCount", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x94, "getVerbFromXY", kSpecialCallInstType, -1, "", "rpp");
+ OPCODE(0x6C, "breakHere", kKernelCallInst, 0, "");
+ OPCODE_MD(0x6D, "ifClassOfIs", kKernelCallInst, 0x1011, "", "rlp"); // Variable stack arguments
+ OPCODE_MD(0x6E, "setClass", kKernelCallInst, 0x1010, "", "lp"); // Variable stack arguments
+ OPCODE_MD(0x6F, "getState", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x70, "setState", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x71, "setOwner", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x72, "getOwner", kKernelCallInst, 0, "", "rp");
+ OPCODE(0x73, "jump", kJumpInst, 0, "a");
+ OPCODE_MD(0x74, "startSound", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x75, "stopSound", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x76, "startMusic", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x77, "stopObjectScript", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x78, "panCameraTo", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x79, "actorFollowCamera", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x7A, "setCameraAt", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x7B, "loadRoom", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x7C, "stopScript", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x7D, "walkActorToObj", kKernelCallInst, -3, "", "ppp");
+ OPCODE_MD(0x7E, "walkActorTo", kKernelCallInst, -3, "", "ppp");
+ OPCODE_MD(0x7F, "putActorAtXY", kKernelCallInst, -4, "", "pppp");
+ OPCODE_MD(0x80, "putActorAtObject", kKernelCallInst, -3, "", "zp");
+ OPCODE_MD(0x81, "faceActor", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x82, "animateActor", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x83, "doSentence", kKernelCallInst, -4, "", "pppp");
+ OPCODE_MD(0x84, "pickupObject", kKernelCallInst, -2, "", "z");
+ OPCODE_MD(0x85, "loadRoomWithEgo", kKernelCallInst, -4, "", "ppz");
+ OPCODE_MD(0x87, "getRandomNumber", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x88, "getRandomNumberRange", kKernelCallInst, -1, "", "rpp");
+ OPCODE_MD(0x8A, "getActorMoving", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x8B, "isScriptRunning", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x8C, "getActorRoom", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x8D, "getObjectX", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x8E, "getObjectY", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x8F, "getObjectDir", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x90, "getActorWalkBox", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x91, "getActorCostume", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x92, "findInventory", kKernelCallInst, -1, "", "rpp");
+ OPCODE_MD(0x93, "getInventoryCount", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x94, "getVerbFromXY", kKernelCallInst, -1, "", "rpp");
OPCODE_BASE(0x95)
- OPCODE_BODY("beginOverride", kSpecialCallInstType, 0, "", "");
+ OPCODE_BODY("beginOverride", kKernelCallInst, 0, "", "");
// FIXME/TODO: beginOverride skips the following jump - that jump is instead to a "finally" handler
// To simulate this, we simply skip the jump instruction, so the sequential order appears the same.
// Semantically, it would probably be more correct to model this as a conditional jump,
@@ -179,262 +186,262 @@
_f.seek(3, SEEK_CUR);
_address += 3;
OPCODE_END;
- OPCODE(0x96, "endOverride", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x97, "setObjectName", kSpecialCallInstType, -1, "c", "ps");
- OPCODE_MD(0x98, "isSoundRunning", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0x99, "setBoxFlags", kSpecialCallInstType, 0x1100, "", "pl"); // Variable stack arguments
- OPCODE(0x9A, "createBoxMatrix", kSpecialCallInstType, 0, "");
+ OPCODE(0x96, "endOverride", kKernelCallInst, 0, "");
+ OPCODE_MD(0x97, "setObjectName", kKernelCallInst, -1, "c", "ps");
+ OPCODE_MD(0x98, "isSoundRunning", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0x99, "setBoxFlags", kKernelCallInst, 0x1100, "", "pl"); // Variable stack arguments
+ OPCODE(0x9A, "createBoxMatrix", kKernelCallInst, 0, "");
START_SUBOPCODE_WITH_PREFIX(0x9B, "resourceRoutines");
- OPCODE_MD(0x64, "loadScript", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x65, "loadSound", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x66, "loadCostume", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x67, "loadRoom", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x68, "nukeScript", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x69, "nukeSound", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x6A, "nukeCostume", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x6B, "nukeRoom", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x6C, "lockScript", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x6D, "lockSound", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x6E, "lockCostume", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x6F, "lockRoom", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x70, "unlockScript", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x71, "unlockSound", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x72, "unlockCostume", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x73, "unlockRoom", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x75, "loadCharset", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x76, "nukeCharset", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x77, "loadFlObject", kSpecialCallInstType, -2, "", "pp");
+ OPCODE_MD(0x64, "loadScript", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x65, "loadSound", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x66, "loadCostume", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x67, "loadRoom", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x68, "nukeScript", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x69, "nukeSound", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x6A, "nukeCostume", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x6B, "nukeRoom", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x6C, "lockScript", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x6D, "lockSound", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x6E, "lockCostume", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x6F, "lockRoom", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x70, "unlockScript", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x71, "unlockSound", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x72, "unlockCostume", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x73, "unlockRoom", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x75, "loadCharset", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x76, "nukeCharset", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x77, "loadFlObject", kKernelCallInst, -2, "", "pp");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0x9C, "roomOps");
- OPCODE_MD(0xAC, "roomScroll", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0xAE, "setScreen", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0xAF, "setPalColor", kSpecialCallInstType, -4, "", "pppp");
- OPCODE(0xB0, "shakeOn", kSpecialCallInstType, 0, "");
- OPCODE(0xB1, "shakeOff", kSpecialCallInstType, 0, "");
- OPCODE_MD(0xB3, "darkenPalette", kSpecialCallInstType, -3, "", "ppp");
- OPCODE_MD(0xB4, "saveLoadRoom", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0xB5, "screenEffect", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xB6, "darkenPaletteRGB", kSpecialCallInstType, -5, "", "ppppp");
- OPCODE_MD(0xB7, "setupShadowPalette", kSpecialCallInstType, -5, "", "ppppp");
- OPCODE_MD(0xBA, "palManipulate", kSpecialCallInstType, -4, "", "pppp");
- OPCODE_MD(0xBB, "colorCycleDelay", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0xD5, "setPalette", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xDC, "copyPalColor", kSpecialCallInstType, -2, "", "pp");
+ OPCODE_MD(0xAC, "roomScroll", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0xAE, "setScreen", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0xAF, "setPalColor", kKernelCallInst, -4, "", "pppp");
+ OPCODE(0xB0, "shakeOn", kKernelCallInst, 0, "");
+ OPCODE(0xB1, "shakeOff", kKernelCallInst, 0, "");
+ OPCODE_MD(0xB3, "darkenPalette", kKernelCallInst, -3, "", "ppp");
+ OPCODE_MD(0xB4, "saveLoadRoom", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0xB5, "screenEffect", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xB6, "darkenPaletteRGB", kKernelCallInst, -5, "", "ppppp");
+ OPCODE_MD(0xB7, "setupShadowPalette", kKernelCallInst, -5, "", "ppppp");
+ OPCODE_MD(0xBA, "palManipulate", kKernelCallInst, -4, "", "pppp");
+ OPCODE_MD(0xBB, "colorCycleDelay", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0xD5, "setPalette", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xDC, "copyPalColor", kKernelCallInst, -2, "", "pp");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0x9D, "actorOps");
- OPCODE_MD(0x4C, "setCostume", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x4D, "setWalkSpeed", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x4E, "setSound", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
- OPCODE_MD(0x4F, "setWalkFrame", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x50, "setTalkFrame", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x51, "setStandFrame", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x52, "82?", kSpecialCallInstType, -3, "", "ppp");
- OPCODE(0x53, "init", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x54, "setElevation", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x55, "setDefAnim", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x56, "setPalette", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x57, "setTalkColor", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x58, "setName", kSpecialCallInstType, 0, "c", "s");
- OPCODE_MD(0x59, "setInitFrame", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x5B, "setWidth", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x5C, "setScale", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x5D, "setNeverZClip", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x5E, "setAlwaysZClip", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x5F, "setIgnoreBoxes", kSpecialCallInstType, 0, "");
- OPCODE(0x60, "setFollowBoxes", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x61, "setAnimSpeed", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x62, "setShadowMode", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x63, "setTalkPos", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0xC5, "setCurActor", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xC6, "setAnimVar", kSpecialCallInstType, -2, "", "pp");
- OPCODE(0xD7, "setIgnoreTurnsOn", kSpecialCallInstType, 0, "");
- OPCODE(0xD8, "setIgnoreTurnsOff", kSpecialCallInstType, 0, "");
- OPCODE(0xD9, "initLittle", kSpecialCallInstType, 0, "");
- OPCODE_MD(0xE1, "setAlwaysZClip?", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xE3, "setLayer", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xE4, "setWalkScript", kSpecialCallInstType, -1, "", "p");
- OPCODE(0xE5, "setStanding", kSpecialCallInstType, 0, "");
- OPCODE_MD(0xE6, "setDirection", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xE7, "turnToDirection", kSpecialCallInstType, -1, "", "p");
- OPCODE(0xE9, "freeze", kSpecialCallInstType, 0, "");
- OPCODE(0xEA, "unfreeze", kSpecialCallInstType, 0, "");
- OPCODE_MD(0xEB, "setTalkScript", kSpecialCallInstType, -1, "", "p");
+ OPCODE_MD(0x4C, "setCostume", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x4D, "setWalkSpeed", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x4E, "setSound", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+ OPCODE_MD(0x4F, "setWalkFrame", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x50, "setTalkFrame", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x51, "setStandFrame", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x52, "82?", kKernelCallInst, -3, "", "ppp");
+ OPCODE(0x53, "init", kKernelCallInst, 0, "");
+ OPCODE_MD(0x54, "setElevation", kKernelCallInst, -1, "", "p");
+ OPCODE(0x55, "setDefAnim", kKernelCallInst, 0, "");
+ OPCODE_MD(0x56, "setPalette", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x57, "setTalkColor", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x58, "setName", kKernelCallInst, 0, "c", "s");
+ OPCODE_MD(0x59, "setInitFrame", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x5B, "setWidth", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x5C, "setScale", kKernelCallInst, -1, "", "p");
+ OPCODE(0x5D, "setNeverZClip", kKernelCallInst, 0, "");
+ OPCODE_MD(0x5E, "setAlwaysZClip", kKernelCallInst, -1, "", "p");
+ OPCODE(0x5F, "setIgnoreBoxes", kKernelCallInst, 0, "");
+ OPCODE(0x60, "setFollowBoxes", kKernelCallInst, 0, "");
+ OPCODE_MD(0x61, "setAnimSpeed", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x62, "setShadowMode", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x63, "setTalkPos", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0xC5, "setCurActor", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xC6, "setAnimVar", kKernelCallInst, -2, "", "pp");
+ OPCODE(0xD7, "setIgnoreTurnsOn", kKernelCallInst, 0, "");
+ OPCODE(0xD8, "setIgnoreTurnsOff", kKernelCallInst, 0, "");
+ OPCODE(0xD9, "initLittle", kKernelCallInst, 0, "");
+ OPCODE_MD(0xE1, "setAlwaysZClip?", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xE3, "setLayer", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xE4, "setWalkScript", kKernelCallInst, -1, "", "p");
+ OPCODE(0xE5, "setStanding", kKernelCallInst, 0, "");
+ OPCODE_MD(0xE6, "setDirection", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xE7, "turnToDirection", kKernelCallInst, -1, "", "p");
+ OPCODE(0xE9, "freeze", kKernelCallInst, 0, "");
+ OPCODE(0xEA, "unfreeze", kKernelCallInst, 0, "");
+ OPCODE_MD(0xEB, "setTalkScript", kKernelCallInst, -1, "", "p");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0x9E, "verbOps");
- OPCODE_MD(0x7C, "loadImg", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x7D, "loadString", kSpecialCallInstType, 0, "c", "s");
- OPCODE_MD(0x7E, "setColor", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x7F, "setHiColor", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x80, "setXY", kSpecialCallInstType, -2, "", "pp");
- OPCODE(0x81, "setOn", kSpecialCallInstType, 0, "");
- OPCODE(0x82, "setOff", kSpecialCallInstType, 0, "");
- OPCODE(0x83, "kill", kSpecialCallInstType, 0, "");
- OPCODE(0x84, "init", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x85, "setDimColor", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x86, "setDimmed", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x87, "setKey", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x88, "setCenter", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x89, "setToString", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x8B, "setToObject", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x8C, "setBkColor", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xC4, "setCurVerb", kSpecialCallInstType, -1, "", "p");
- OPCODE(0xFF, "redraw", kSpecialCallInstType, 0, "");
+ OPCODE_MD(0x7C, "loadImg", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x7D, "loadString", kKernelCallInst, 0, "c", "s");
+ OPCODE_MD(0x7E, "setColor", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x7F, "setHiColor", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x80, "setXY", kKernelCallInst, -2, "", "pp");
+ OPCODE(0x81, "setOn", kKernelCallInst, 0, "");
+ OPCODE(0x82, "setOff", kKernelCallInst, 0, "");
+ OPCODE(0x83, "kill", kKernelCallInst, 0, "");
+ OPCODE(0x84, "init", kKernelCallInst, 0, "");
+ OPCODE_MD(0x85, "setDimColor", kKernelCallInst, -1, "", "p");
+ OPCODE(0x86, "setDimmed", kKernelCallInst, 0, "");
+ OPCODE_MD(0x87, "setKey", kKernelCallInst, -1, "", "p");
+ OPCODE(0x88, "setCenter", kKernelCallInst, 0, "");
+ OPCODE_MD(0x89, "setToString", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x8B, "setToObject", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x8C, "setBkColor", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xC4, "setCurVerb", kKernelCallInst, -1, "", "p");
+ OPCODE(0xFF, "redraw", kKernelCallInst, 0, "");
END_SUBOPCODE;
- OPCODE_MD(0x9F, "getActorFromXY", kSpecialCallInstType, -1, "", "rpp");
- OPCODE_MD(0xA0, "findObject", kSpecialCallInstType, -1, "", "rpp");
- OPCODE_MD(0xA1, "pseudoRoom", kSpecialCallInstType, 0x1010, "", "lp"); // Variable stack arguments
- OPCODE_MD(0xA2, "getActorElevation", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0xA3, "getVerbEntrypoint", kSpecialCallInstType, -1, "", "rpp");
+ OPCODE_MD(0x9F, "getActorFromXY", kKernelCallInst, -1, "", "rpp");
+ OPCODE_MD(0xA0, "findObject", kKernelCallInst, -1, "", "rpp");
+ OPCODE_MD(0xA1, "pseudoRoom", kKernelCallInst, 0x1010, "", "lp"); // Variable stack arguments
+ OPCODE_MD(0xA2, "getActorElevation", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0xA3, "getVerbEntrypoint", kKernelCallInst, -1, "", "rpp");
START_SUBOPCODE_WITH_PREFIX(0xA4, "arrayOps");
- OPCODE_MD(0xCD, "assignString", kSpecialCallInstType, -1, "wc", "");
- OPCODE_MD(0xD0, "assignIntList", kSpecialCallInstType, 0x1100, "w", ""); // Variable stack arguments
- OPCODE_MD(0xD4, "assign2DimList", kSpecialCallInstType, 0x1100, "w", ""); // Variable stack arguments
+ OPCODE_MD(0xCD, "assignString", kArrayOpInst, -1, "wc", "");
+ OPCODE_MD(0xD0, "assignIntList", kArrayOpInst, 0x1100, "w", ""); // Variable stack arguments
+ OPCODE_MD(0xD4, "assign2DimList", kArrayOpInst, 0x1100, "w", ""); // Variable stack arguments
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0xA5, "saveRestoreVerbs");
- OPCODE_MD(0x8D, "saveVerbs", kSpecialCallInstType, -3, "", "ppp");
- OPCODE_MD(0x8E, "restoreVerbs", kSpecialCallInstType, -3, "", "ppp");
- OPCODE_MD(0x8F, "deleteVerbs", kSpecialCallInstType, -3, "", "ppp");
+ OPCODE_MD(0x8D, "saveVerbs", kKernelCallInst, -3, "", "ppp");
+ OPCODE_MD(0x8E, "restoreVerbs", kKernelCallInst, -3, "", "ppp");
+ OPCODE_MD(0x8F, "deleteVerbs", kKernelCallInst, -3, "", "ppp");
END_SUBOPCODE;
- OPCODE_MD(0xA6, "drawBox", kSpecialCallInstType, -5, "", "ppppp");
- OPCODE(0xA7, "pop", kStackInstType, -1, "");
- OPCODE_MD(0xA8, "getActorWidth", kSpecialCallInstType, 0, "", "rp");
+ OPCODE_MD(0xA6, "drawBox", kKernelCallInst, -5, "", "ppppp");
+ OPCODE(0xA7, "pop", kStackInst, -1, "");
+ OPCODE_MD(0xA8, "getActorWidth", kKernelCallInst, 0, "", "rp");
START_SUBOPCODE(0xA9); // wait
- OPCODE_MD(0xA8, "waitForActor", kSpecialCallInstType, -1, "s", "pj");
- OPCODE(0xA9, "waitForMessage", kSpecialCallInstType, 0, "");
- OPCODE(0xAA, "waitForCamera", kSpecialCallInstType, 0, "");
- OPCODE(0xAB, "waitForSentence", kSpecialCallInstType, 0, "");
- OPCODE_MD(0xE2, "waitUntilActorDrawn", kSpecialCallInstType, -1, "s", "pj");
- OPCODE_MD(0xE8, "waitUntilActorTurned", kSpecialCallInstType, -1, "s", "pj");
+ OPCODE_MD(0xA8, "waitForActor", kKernelCallInst, -1, "s", "pj");
+ OPCODE(0xA9, "waitForMessage", kKernelCallInst, 0, "");
+ OPCODE(0xAA, "waitForCamera", kKernelCallInst, 0, "");
+ OPCODE(0xAB, "waitForSentence", kKernelCallInst, 0, "");
+ OPCODE_MD(0xE2, "waitUntilActorDrawn", kKernelCallInst, -1, "s", "pj");
+ OPCODE_MD(0xE8, "waitUntilActorTurned", kKernelCallInst, -1, "s", "pj");
END_SUBOPCODE;
- OPCODE_MD(0xAA, "getActorScaleX", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0xAB, "getActorAnimCounter", kSpecialCallInstType, 0, "", "rp");
- OPCODE_MD(0xAC, "soundKludge", kSpecialCallInstType, 0x1000, "", "l"); // Variable stack arguments
- OPCODE_MD(0xAD, "isAnyOf", kSpecialCallInstType, 0x1011, "", "rlp"); // Variable stack arguments
+ OPCODE_MD(0xAA, "getActorScaleX", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0xAB, "getActorAnimCounter", kKernelCallInst, 0, "", "rp");
+ OPCODE_MD(0xAC, "soundKludge", kKernelCallInst, 0x1000, "", "l"); // Variable stack arguments
+ OPCODE_MD(0xAD, "isAnyOf", kKernelCallInst, 0x1011, "", "rlp"); // Variable stack arguments
START_SUBOPCODE_WITH_PREFIX(0xAE, "systemOps");
- OPCODE(0x9E, "restartGame", kSpecialCallInstType, 0, "");
- OPCODE(0x9F, "pauseGame", kSpecialCallInstType, 0, "");
- OPCODE(0xA0, "shutDown", kSpecialCallInstType, 0, "");
+ OPCODE(0x9E, "restartGame", kKernelCallInst, 0, "");
+ OPCODE(0x9F, "pauseGame", kKernelCallInst, 0, "");
+ OPCODE(0xA0, "shutDown", kKernelCallInst, 0, "");
END_SUBOPCODE;
- OPCODE_MD(0xAF, "isActorInBox", kSpecialCallInstType, -1, "", "rpp");
- OPCODE_MD(0xB0, "delay", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xB1, "delaySeconds", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0xB2, "delayMinutes", kSpecialCallInstType, -1, "", "p");
- OPCODE(0xB3, "stopSentence", kSpecialCallInstType, 0, "");
+ OPCODE_MD(0xAF, "isActorInBox", kKernelCallInst, -1, "", "rpp");
+ OPCODE_MD(0xB0, "delay", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xB1, "delaySeconds", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0xB2, "delayMinutes", kKernelCallInst, -1, "", "p");
+ OPCODE(0xB3, "stopSentence", kKernelCallInst, 0, "");
START_SUBOPCODE_WITH_PREFIX(0xB4, "printLine");
- OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
- OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
- OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
- OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
- OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
- OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+ OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+ OPCODE(0x45, "center", kKernelCallInst, 0, "");
+ OPCODE(0x47, "left", kKernelCallInst, 0, "");
+ OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+ OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+ OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+ OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+ OPCODE(0xFF, "end", kKernelCallInst, 0, "");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0xB5, "printText");
- OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
- OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
- OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
- OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
- OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
- OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+ OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+ OPCODE(0x45, "center", kKernelCallInst, 0, "");
+ OPCODE(0x47, "left", kKernelCallInst, 0, "");
+ OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+ OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+ OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+ OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+ OPCODE(0xFF, "end", kKernelCallInst, 0, "");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0xB6, "printDebug");
- OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
- OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
- OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
- OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
- OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
- OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+ OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+ OPCODE(0x45, "center", kKernelCallInst, 0, "");
+ OPCODE(0x47, "left", kKernelCallInst, 0, "");
+ OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+ OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+ OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+ OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+ OPCODE(0xFF, "end", kKernelCallInst, 0, "");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0xB7, "printSystem");
- OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
- OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
- OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
- OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
- OPCODE(0xFE, "begin", kSpecialCallInstType, 0, "");
- OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+ OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+ OPCODE(0x45, "center", kKernelCallInst, 0, "");
+ OPCODE(0x47, "left", kKernelCallInst, 0, "");
+ OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+ OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+ OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+ OPCODE(0xFE, "begin", kKernelCallInst, 0, "");
+ OPCODE(0xFF, "end", kKernelCallInst, 0, "");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0xB8, "printActor");
- OPCODE_MD(0x41, "XY", kSpecialCallInstType, -2, "", "pp");
- OPCODE_MD(0x42, "color", kSpecialCallInstType, -1, "", "p");
- OPCODE_MD(0x43, "right", kSpecialCallInstType, -1, "", "p");
- OPCODE(0x45, "center", kSpecialCallInstType, 0, "");
- OPCODE(0x47, "left", kSpecialCallInstType, 0, "");
- OPCODE(0x48, "overhead", kSpecialCallInstType, 0, "");
- OPCODE(0x4A, "mumble", kSpecialCallInstType, 0, "");
- OPCODE_MD(0x4B, "msg", kSpecialCallInstType, 0, "c", "s");
- OPCODE_MD(0xFE, "begin", kSpecialCallInstType, -1, "", "p");
- OPCODE(0xFF, "end", kSpecialCallInstType, 0, "");
+ OPCODE_MD(0x41, "XY", kKernelCallInst, -2, "", "pp");
+ OPCODE_MD(0x42, "color", kKernelCallInst, -1, "", "p");
+ OPCODE_MD(0x43, "right", kKernelCallInst, -1, "", "p");
+ OPCODE(0x45, "center", kKernelCallInst, 0, "");
+ OPCODE(0x47, "left", kKernelCallInst, 0, "");
+ OPCODE(0x48, "overhead", kKernelCallInst, 0, "");
+ OPCODE(0x4A, "mumble", kKernelCallInst, 0, "");
+ OPCODE_MD(0x4B, "msg", kKernelCallInst, 0, "c", "s");
+ OPCODE_MD(0xFE, "begin", kKernelCallInst, -1, "", "p");
+ OPCODE(0xFF, "end", kKernelCallInst, 0, "");
END_SUBOPCODE;
START_SUBOPCODE_WITH_PREFIX(0xB9, "printEgo");
@@ Diff output truncated at 100000 characters. @@
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