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

pidgeot at users.sourceforge.net pidgeot at users.sourceforge.net
Sat Aug 14 23:29:46 CEST 2010


Revision: 52093
          http://scummvm.svn.sourceforge.net/scummvm/?rev=52093&view=rev
Author:   pidgeot
Date:     2010-08-14 21:29:45 +0000 (Sat, 14 Aug 2010)

Log Message:
-----------
DECOMPILER: Refactor instruction processing

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/doc/codegen.tex
    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/disassembler.cpp
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp
    tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h
    tools/branches/gsoc2010-decompiler/decompiler/test/module.mk

Modified: tools/branches/gsoc2010-decompiler/Makefile.common
===================================================================
--- tools/branches/gsoc2010-decompiler/Makefile.common	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/Makefile.common	2010-08-14 21:29:45 UTC (rev 52093)
@@ -231,6 +231,7 @@
 	decompiler/decompiler.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-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.cpp	2010-08-14 21:29:45 UTC (rev 52093)
@@ -211,6 +211,7 @@
 }
 
 void CodeGenerator::process(GraphVertex v) {
+	_curVertex = v;
 	_curGroup = GET(v);
 
 	// Check if we should add else start
@@ -242,144 +243,147 @@
 
 	ConstInstIterator it = _curGroup->_start;
 	do {
-		if (it->_codeGenData.find("\xC0") == 0)
-			processInst(*it);
-		else {
-			switch (it->_type) {
-			// We handle plain dups here because their behavior should be identical across instruction sets and this prevents implementation error.
-			case kDup:
-				{
-					std::stringstream s;
-					EntryPtr p = _stack.pop()->dup(s);
-					if (s.str().length() > 0)
-						addOutputLine(s.str());
-					_stack.push(p);
-					_stack.push(p);
-					break;
+		processInst(*it);
+	} while (it++ != _curGroup->_end);
+
+	// Add else end if necessary
+	for (ElseEndIterator elseIt = _curGroup->_endElse.begin(); elseIt != _curGroup->_endElse.end(); ++elseIt) {
+		if (!(*elseIt)->_coalescedElse)
+			addOutputLine("}", true, false);
+	}
+}
+
+void CodeGenerator::processInst(const Instruction inst) {
+	switch (inst._type) {
+		// We handle plain dups here because their behavior should be identical across instruction sets and this prevents implementation error.
+	case kDup:
+		{
+			std::stringstream s;
+			EntryPtr p = _stack.pop()->dup(s);
+			if (s.str().length() > 0)
+				addOutputLine(s.str());
+			_stack.push(p);
+			_stack.push(p);
+			break;
+		}
+	case kUnaryOpPre:
+	case kUnaryOpPost:
+		_stack.push(new UnaryOpEntry(_stack.pop(), inst._codeGenData, inst._type == kUnaryOpPost));
+		break;
+	case kBinaryOp:
+		{
+			EntryPtr op1 = _stack.pop();
+			EntryPtr op2 = _stack.pop();
+			if (_binOrder == kFIFO)
+				_stack.push(new BinaryOpEntry(op2, op1, inst._codeGenData));
+			else if (_binOrder == kLIFO)
+				_stack.push(new BinaryOpEntry(op1, op2, inst._codeGenData));
+			break;
+		}
+	case kCondJump:
+	case kCondJumpRel:
+		{
+			std::stringstream s;
+			switch (_curGroup->_type) {
+			case kIfCond:
+				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 ";
+					}
 				}
-			case kUnaryOpPre:
-			case kUnaryOpPost:
-				_stack.push(new UnaryOpEntry(_stack.pop(), it->_codeGenData, it->_type == kUnaryOpPost));
+				s << "if (" << _stack.pop() << ") {";
+				addOutputLine(s.str(), _curGroup->_coalescedElse, true);
 				break;
-			case kBinaryOp:
-				{
-					EntryPtr op1 = _stack.pop();
-					EntryPtr op2 = _stack.pop();
-					if (_binOrder == kFIFO)
-						_stack.push(new BinaryOpEntry(op2, op1, it->_codeGenData));
-					else if (_binOrder == kLIFO)
-						_stack.push(new BinaryOpEntry(op1, op2, it->_codeGenData));
-					break;
-				}
-			case kCondJump:
-			case kCondJumpRel:
-				{
-					processInst(*it);
-					std::stringstream s;
-					switch (_curGroup->_type) {
-					case kIfCond:
-						if (_curGroup->_startElse && _curGroup->_code.size() == 1) {
-							OutEdgeRange oer = boost::out_edges(v, _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() << ") {";
-						addOutputLine(s.str(), _curGroup->_coalescedElse, true);
+			case kWhileCond:
+				s << "while (" << _stack.pop() << ") {";
+				addOutputLine(s.str(), false, true);
+				break;
+			case kDoWhileCond:
+				s << "} while (" << _stack.pop() << ")";
+				addOutputLine(s.str(), true, false);
+				break;
+			default:
+				break;
+			}
+		}
+		break;
+	case kJump:
+	case kJumpRel:
+		switch (_curGroup->_type) {
+		case kBreak:
+			addOutputLine("break;");
+			break;
+		case kContinue:
+			addOutputLine("continue;");
+			break;
+		default:
+			{
+				bool printJump = true;
+				OutEdgeRange r = boost::out_edges(_curVertex, _g);
+				for (OutEdgeIterator e = r.first; e != r.second && printJump; ++e) {
+					// Don't output jump to next vertex
+					if (boost::target(*e, _g) == _curGroup->_next->_vertex) {
+						printJump = false;
 						break;
-					case kWhileCond:
-						s << "while (" << _stack.pop() << ") {";
-						addOutputLine(s.str(), false, true);
+					}
+
+					// Don't output jump if next vertex starts an else block
+					if (_curGroup->_next->_startElse) {
+						printJump = false;
 						break;
-					case kDoWhileCond:
-						s << "} while (" << _stack.pop() << ")";
-						addOutputLine(s.str(), true, false);
-						break;
-					default:
-						break;
 					}
-				}
-				break;
-			case kJump:
-			case kJumpRel:
-				switch (_curGroup->_type) {
-				case kBreak:
-					addOutputLine("break;");
-					break;
-				case kContinue:
-					addOutputLine("continue;");
-					break;
-				default:
-					{
-						bool printJump = true;
-						OutEdgeRange r = boost::out_edges(v, _g);
-						for (OutEdgeIterator e = r.first; e != r.second && printJump; ++e) {
-							// Don't output jump to next vertex
-							if (boost::target(*e, _g) == _curGroup->_next->_vertex) {
-								printJump = false;
-								break;
-							}
 
-							// Don't output jump if next vertex starts an else block
-							if (_curGroup->_next->_startElse) {
-								printJump = false;
-								break;
-							}
-
-							OutEdgeRange targetR = boost::out_edges(boost::target(*e, _g), _g);
-							for (OutEdgeIterator targetE = targetR.first; targetE != targetR.second; ++targetE) {
-								// Don't output jump to while loop that has jump to next vertex
-								if (boost::target(*targetE, _g) == _curGroup->_next->_vertex)
-									printJump = false;
-							}
-						}
-						if (printJump) {
-							std::stringstream s;
-							s << boost::format("jump 0x%X;") % _engine->getDestAddress(it);
-							addOutputLine(s.str());
-						}
+					OutEdgeRange targetR = boost::out_edges(boost::target(*e, _g), _g);
+					for (OutEdgeIterator targetE = targetR.first; targetE != targetR.second; ++targetE) {
+						// Don't output jump to while loop that has jump to next vertex
+						if (boost::target(*targetE, _g) == _curGroup->_next->_vertex)
+							printJump = false;
 					}
-					break;
 				}
-				break;
-			case kReturn:
-				// TODO: Allow specification of return value as part of return statement
-				addOutputLine("return;");
-				break;
-			case kSpecial:
-				{
-					_argList.clear();
-					bool returnsValue = (it->_codeGenData.find("r") == 0);
-					std::string metadata = (!returnsValue ? it->_codeGenData : it->_codeGenData.substr(1));
-					for (size_t i = 0; i < metadata.length(); i++)
-						processSpecialMetadata(*it, metadata[i], i);
-					_stack.push(new CallEntry(it->_name, _argList));
-					if (!returnsValue) {
-						std::stringstream stream;
-						stream << _stack.pop() << ";";
-						addOutputLine(stream.str());
-					}
-					break;
+				if (printJump) {
+					std::stringstream s;
+					s << boost::format("jump 0x%X;") % _engine->getDestAddress(inst);
+					addOutputLine(s.str());
 				}
-			default:
-				processInst(*it);
-				break;
 			}
+			break;
 		}
-	} while (it++ != _curGroup->_end);
-
-	// Add else end if necessary
-	for (ElseEndIterator elseIt = _curGroup->_endElse.begin(); elseIt != _curGroup->_endElse.end(); ++elseIt) {
-		if (!(*elseIt)->_coalescedElse)
-			addOutputLine("}", true, false);
+		break;
+	case kReturn:
+		// TODO: Allow specification of return value as part of return statement
+		addOutputLine("return;");
+		break;
+	case kSpecial:
+		{
+			_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 CallEntry(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-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/codegen.h	2010-08-14 21:29:45 UTC (rev 52093)
@@ -369,18 +369,18 @@
 	void process(GraphVertex v);
 
 protected:
-	Engine *_engine;       ///< Pointer to the Engine used for the script.
-	std::ostream &_output; ///< The std::ostream to output the code to.
-	EntryStack _stack;     ///< The stack currently being processed.
-	uint _indentLevel;     ///< Indentation level.
-	GroupPtr _curGroup;    ///< Pointer to the group currently being processed.
-	EntryList _argList;    ///< Storage for lists of arguments to be built when processing function calls.
+	Engine *_engine;        ///< Pointer to the Engine used for the script.
+	std::ostream &_output;  ///< The std::ostream to output the code to.
+	EntryStack _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.
+	EntryList _argList;     ///< Storage for lists of arguments to be built when processing function calls.
 
 	/**
-	 * Processes an instruction in an engine-specific manner.
-	 * Called by process() to preprocess conditional jumps, process instructions
-	 * where engine-specific handling is explicitly requested, or the type is not one
-	 * of kBinaryOp, kDup, kJump(Rel), kReturn, kSpecial, kUnaryOpPre, or kUnaryOpPost.
+	 * Processes an instruction. Called by process() for each instruction.
+	 * Call the base class implementation for opcodes you cannot handle yourself,
+	 * or where the base class implementation is preferable.
 	 *
 	 * @param inst The instruction to process.
 	 */

Modified: tools/branches/gsoc2010-decompiler/decompiler/doc/codegen.tex
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/doc/codegen.tex	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/doc/codegen.tex	2010-08-14 21:29:45 UTC (rev 52093)
@@ -48,7 +48,7 @@
 Binary operations stores the two stack entries used as operands, and a string containing the operator. Parenthesis are automatically added around all binary operations to preserve the proper evaluation order.
 
 \paragraph{Unary operations (UnaryOpEntry)}
-Just like binary operations, except only a single operand is stored. Note: Currently, the operator will always be output on the left side of the operand.
+Just like binary operations, except only a single operand is stored. The operator can be placed before (prefix) or after (postfix) the operand.
 
 \paragraph{Duplicated entries (DupEntry)}
 Stores an index to distinguish between multiple duplicated entries. This index is automatically assigned and determined when calling the \code{dup} function to duplicate a stack entry.
@@ -79,8 +79,7 @@
 \subsection{Default instruction handling and instruction metadata}
 When disassembling, you can store metadata for a given instruction to be used during code generation.
 
-Default handling exists for a number of instruction types, described below. If the default handling does not work for a particular instruction, you can force the instruction to be processed by your engine-specific \code{processInst} by placing the hexadecimal byte 0xC0 at the start of the metadata string. This character was chosen for two reasons: it is unlikely to be used as a byte in a script, and the byte is invalid in UTF-8, avoiding potential encoding conflicts. Note that if you do this, it is your own responsibility to strip off that character during processing.
-
+Default handling exists for a number of instruction types, described below. To get the default handling, simply call the base class implementation of \code{processInst} from your code.
 \paragraph{kDup}
 The topmost stack entry is popped, and two duplicated copies are pushed to the stack. If the entry being duplicated was not already a duplicate, an assignment will be output to assign the original stack entry to a special dup variable, to show that the original entry is not being recalculated.
 
@@ -91,7 +90,7 @@
 The two topmost stack entries are popped, and a BinaryOpEntry is created and pushed to the stack, using the codegen metadata as the operator and the previously popped entries as the operands. The order of the operands is determined by the value of the field \code{\_binOrder}, as described in Section~\vref{sec:argOrder}.
 
 \paragraph{kCondJump and kCondJumpRel}
-The instruction is first sent for processing in the engine-specific \code{processInst} method, so you can add any information provided by the specific opcode. The information on the stack is then read by the default code, and an if, while or do-while condition is output using the topmost stack entry.
+The information on the stack is then read, and an if, while or do-while condition is output using the topmost stack entry. In general, you will want to call the base class method after handling one of these opcodes.
 
 \paragraph{kJump and kJumpRel}
 If the current group has been detected as a break or a continue, a break or continue statement is output. Otherwise, the jump is analyzed and output unless it is a jump back to the condition of a while-loop that ends there, or it is determined that the jump is unnecessary due to an else block following immediately after.
@@ -99,7 +98,7 @@
 \paragraph{kReturn}
 This simply adds a line \code{return;} to the output.
 
-\emph{Note:} The default handling does not currently allow specifying a return value as part of the statement, as in \code{return 0;}.
+\emph{Note:} The default handling does not currently allow specifying a return value as part of the statement, as in \code{return 0;}. You will have to handle that yourself.
 
 \paragraph{kSpecial}
 The metadata is treated similar to parameter specifications in \code{SimpleDisassembler} (see Section~\vref{sec:simpledisasm}). If the specification string starts with the character \code{r}, this signifies that the call returns a value, and processing starts at the next character.
@@ -111,9 +110,9 @@
 Due to the conflict with the specification of a return value, it is recommended that you do not adopt \code{r} as a metadata character.
 
 \paragraph{Other types}
-No default handling exists for types other than those mentioned above. These instructions will be sent to the \code{processInst} method of your subclass, where you must handle them appropriately. This includes types like \code{kLoad} and \code{kStore}.
+No default handling exists for types other than those mentioned above, so you must handle them yourself in the \code{processInst} method of your subclass. This includes types like \code{kLoad} and \code{kStore}.
 
-Note that this also includes \code{kCall}. Although many engines might want to handle this in a manner similar to kSpecial opcodes, this is left to the engine-specific code so they can fully make sense of the metadata they choose to add to the function.
+Note that this also includes \code{kCall}. Although many engines might want to handle this in a manner similar to \code{kSpecial} opcodes, this is left to the engine-specific code so they can fully make sense of the metadata they choose to add to the function.
 
 \subsection{Order of arguments}
 \label{sec:argOrder}

Modified: tools/branches/gsoc2010-decompiler/decompiler/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/engine.h	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/engine.h	2010-08-14 21:29:45 UTC (rev 52093)
@@ -81,10 +81,18 @@
 	/**
 	 * 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 Instruction &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
+	 * @return The destination address of the jump instruction.
 	 */
-	virtual uint32 getDestAddress(ConstInstIterator it) const = 0;
+	uint32 getDestAddress(ConstInstIterator it) const;
 
 	/**
 	 * Retrieve the code generator for the engine.

Modified: tools/branches/gsoc2010-decompiler/decompiler/instruction.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/instruction.h	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/instruction.h	2010-08-14 21:29:45 UTC (rev 52093)
@@ -109,7 +109,7 @@
 	InstType _type;                 ///< The instruction type.
 	int16 _stackChange;             ///< How much this instruction changes the stack pointer by.
 	std::vector<Parameter> _params; ///< Array of parameters used for the instruction.
-	std::string _codeGenData;       ///< String containing metadata for code generation. Start with 0xC0 to force custom handling. See the extended documentation for details.
+	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 = kSpecial, int16 stackChange = 0) :

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.cpp	2010-08-14 21:29:45 UTC (rev 52093)
@@ -133,8 +133,9 @@
 				s << boost::format("WARNING: Couldn't handle conditional jump at address %08X") % inst._address;
 				addOutputLine(s.str());
 			}
-			break;
+			return;
 		}
+		CodeGenerator::processInst(inst);
 		break;
 	case kCall:
 		{
@@ -161,8 +162,8 @@
 			if (inst._opcode != 14)
 				return;
 			_argList.clear();
-			bool returnsValue = (inst._codeGenData.find("r") == 1);
-			std::string metadata = (!returnsValue ? inst._codeGenData.substr(1) : inst._codeGenData.substr(2));
+			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 CallEntry(inst._name, _argList));
@@ -180,11 +181,7 @@
 			break;
 		}
 	default:
-		{
-			std::stringstream s;
-			s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst._opcode % inst._address;
-			addOutputLine(s.str());
-		}
+		CodeGenerator::processInst(inst);	
 		break;
 	}
 }
@@ -211,15 +208,12 @@
 
 void Kyra::Kyra2CodeGenerator::processSpecialMetadata(const Instruction &inst, char c, int pos) {
 	switch (c) {
-	case '0':
-		_stackOffset = 0;
-		break;
 	case 'p':
-		addArg(_stack.peekPos(_stackOffset++));
+		addArg(_stack.peekPos(pos));
 		break;
 	case 's':
 		{
-			EntryPtr p = _stack.peekPos(_stackOffset++);
+			EntryPtr p = _stack.peekPos(pos);
 			if (p->_type == seInt) {
 				IntEntry *ie = (IntEntry *)p.get();
 				addArg(new StringEntry(((Kyra::Kyra2Engine *)_engine)->_textStrings[ie->getValue()]));

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/codegen.h	2010-08-14 21:29:45 UTC (rev 52093)
@@ -32,8 +32,6 @@
  */
 class Kyra2CodeGenerator : public CodeGenerator {
 private:
-	int _stackOffset; ///< Running count of where in the stack to look for the next argument.
-
 	/**
 	 * Finds the first call instruction in the current group and returns it.
 	 * The call may either be a kCall or kSpecial.

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/disassembler.cpp	2010-08-14 21:29:45 UTC (rev 52093)
@@ -37,225 +37,225 @@
 	int i = 0;
 #define FUNC(name, metadata) _funcs[i++] = FunctionData(name, metadata);
 	// 0x00
-	FUNC("o2_setCharacterFacingRefresh", "\xC0r0ppp");
-	FUNC("o2_setCharacterPos", "\xC0r0ppp");
-	FUNC("o2_defineObject", "\xC0r0pspppp");
-	FUNC("o2_refreshCharacter", "\xC0r0pppp");
+	FUNC("o2_setCharacterFacingRefresh", "rppp");
+	FUNC("o2_setCharacterPos", "rppp");
+	FUNC("o2_defineObject", "rpspppp");
+	FUNC("o2_refreshCharacter", "rpppp");
 	// 0x04
-	FUNC("o2_getCharacterX", "\xC0r");
-	FUNC("o2_getCharacterY", "\xC0r");
-	FUNC("o2_getCharacterFacing", "\xC0r");
-	FUNC("o2_getCharacterScene", "\xC0r");
+	FUNC("o2_getCharacterX", "r");
+	FUNC("o2_getCharacterY", "r");
+	FUNC("o2_getCharacterFacing", "r");
+	FUNC("o2_getCharacterScene", "r");
 	// 0x08
-	FUNC("o2_setSceneComment", "\xC0r0s");
-	FUNC("unk09", "\xC0r0p");
-	FUNC("unk0A", "\xC0r0p");
-	FUNC("o2_setCharacterAnimFrame", "\xC0r0ppp");
+	FUNC("o2_setSceneComment", "rs");
+	FUNC("unk09", "rp");
+	FUNC("unk0A", "rp");
+	FUNC("o2_setCharacterAnimFrame", "rppp");
 	// 0x0c
-	FUNC("o2_setCharacterFacingOverwrite", "\xC0r0p");
-	FUNC("o2_trySceneChange", "\xC0r0pppp");
-	FUNC("o2_moveCharacter", "\xC0r0ppp");
-	FUNC("o2_customCharacterChat", "\xC0r0spppp");
+	FUNC("o2_setCharacterFacingOverwrite", "rp");
+	FUNC("o2_trySceneChange", "rpppp");
+	FUNC("o2_moveCharacter", "rppp");
+	FUNC("o2_customCharacterChat", "rspppp");
 	// 0x10
-	FUNC("o2_soundFadeOut", "\xC0r");
-	FUNC("o2_showChapterMessage", "\xC0r0pp");
-	FUNC("o2_restoreTalkTextMessageBkgd", "\xC0r");
-	FUNC("o2_printString", "\xC0r0spppp");
+	FUNC("o2_soundFadeOut", "r");
+	FUNC("o2_showChapterMessage", "rpp");
+	FUNC("o2_restoreTalkTextMessageBkgd", "r");
+	FUNC("o2_printString", "rspppp");
 	// 0x14
-	FUNC("o2_wsaClose", "\xC0r0p");
-	FUNC("o2_backUpScreen", "\xC0r0p");
-	FUNC("o2_restoreScreen", "\xC0r0p");
-	FUNC("o2_displayWsaFrame", "\xC0r0ppppppppp");
+	FUNC("o2_wsaClose", "rp");
+	FUNC("o2_backUpScreen", "rp");
+	FUNC("o2_restoreScreen", "rp");
+	FUNC("o2_displayWsaFrame", "rppppppppp");
 	// 0x18
-	FUNC("o2_displayWsaSequentialFramesLooping", "\xC0r0pppppppp");
-	FUNC("o2_wsaOpen", "\xC0r0sp");
-	FUNC("o2_displayWsaSequentialFrames", "\xC0r0ppppppp");
-	FUNC("o2_displayWsaSequence", "\xC0r0pppppp");
+	FUNC("o2_displayWsaSequentialFramesLooping", "rpppppppp");
+	FUNC("o2_wsaOpen", "rsp");
+	FUNC("o2_displayWsaSequentialFrames", "rppppppp");
+	FUNC("o2_displayWsaSequence", "rpppppp");
 	// 0x1c
-	FUNC("o2_addItemToInventory", "\xC0r0ppp");
-	FUNC("o2_drawShape", "\xC0r0ppppp");
-	FUNC("o2_addItemToCurScene", "\xC0r0ppp");
-	FUNC("o2_limitMouseRange", "\xC0r0pppp");
+	FUNC("o2_addItemToInventory", "rppp");
+	FUNC("o2_drawShape", "rppppp");
+	FUNC("o2_addItemToCurScene", "rppp");
+	FUNC("o2_limitMouseRange", "rpppp");
 	// 0x20
-	FUNC("o2_checkForItem", "\xC0r0pp");
-	FUNC("o2_loadSoundFile", "\xC0r0p");
-	FUNC("o2_removeSlotFromInventory", "\xC0r0p");
-	FUNC("o2_defineItem", "\xC0r0pppp");
+	FUNC("o2_checkForItem", "rpp");
+	FUNC("o2_loadSoundFile", "rp");
+	FUNC("o2_removeSlotFromInventory", "rp");
+	FUNC("o2_defineItem", "rpppp");
 	// 0x24
-	FUNC("o2_removeItemFromInventory", "\xC0r0p");
-	FUNC("o2_countItemInInventory", "\xC0r0pp");
-	FUNC("o2_countItemsInScene", "\xC0r0p");
-	FUNC("o1_queryGameFlag", "\xC0r0p");
+	FUNC("o2_removeItemFromInventory", "rp");
+	FUNC("o2_countItemInInventory", "rpp");
+	FUNC("o2_countItemsInScene", "rp");
+	FUNC("o1_queryGameFlag", "rp");
 	// 0x28
-	FUNC("o1_resetGameFlag", "\xC0r0p");
-	FUNC("o1_setGameFlag", "\xC0r0p");
-	FUNC("o1_setHandItem", "\xC0r0p");
-	FUNC("o1_removeHandItem", "\xC0r");
+	FUNC("o1_resetGameFlag", "rp");
+	FUNC("o1_setGameFlag", "rp");
+	FUNC("o1_setHandItem", "rp");
+	FUNC("o1_removeHandItem", "r");
 	// 0x2c
-	FUNC("o1_getMouseState", "\xC0r");
-	FUNC("o1_hideMouse", "\xC0r");
-	FUNC("o2_addSpecialExit", "\xC0r0ppppp");
-	FUNC("o1_setMousePos", "\xC0r0pp");
+	FUNC("o1_getMouseState", "r");
+	FUNC("o1_hideMouse", "r");
+	FUNC("o2_addSpecialExit", "rppppp");
+	FUNC("o1_setMousePos", "rpp");
 	// 0x30
-	FUNC("o1_showMouse", "\xC0r");
-	FUNC("o2_drawBox", "\xC0r0ppppp");
-	FUNC("o2_wipeDownMouseItem", "\xC0r0ppp");
-	FUNC("o2_getElapsedSecs", "\xC0r");
+	FUNC("o1_showMouse", "r");
+	FUNC("o2_drawBox", "rppppp");
+	FUNC("o2_wipeDownMouseItem", "rppp");
+	FUNC("o2_getElapsedSecs", "r");
 	// 0x34
-	FUNC("o2_getTimerDelay", "\xC0r0p");
-	FUNC("o1_playSoundEffect", "\xC0r0p");
-	FUNC("o2_delaySecs", "\xC0r0p");
-	FUNC("o2_delay", "\xC0r0pp");
+	FUNC("o2_getTimerDelay", "rp");
+	FUNC("o1_playSoundEffect", "rp");
+	FUNC("o2_delaySecs", "rp");
+	FUNC("o2_delay", "rpp");
 	// 0x38
-	FUNC("o2_dummy38", "\xC0r");
-	FUNC("o2_setTimerDelay", "\xC0r0pp");
-	FUNC("o2_setScaleTableItem", "\xC0r0pp");
-	FUNC("o2_setDrawLayerTableItem", "\xC0r0pp");
+	FUNC("o2_dummy38", "r");
+	FUNC("o2_setTimerDelay", "rpp");
+	FUNC("o2_setScaleTableItem", "rpp");
+	FUNC("o2_setDrawLayerTableItem", "rpp");
 	// 0x3c
-	FUNC("o2_setCharPalEntry", "\xC0r0pp");
-	FUNC("o2_loadZShapes", "\xC0r0p");
-	FUNC("o2_drawSceneShape", "\xC0r0pppp");
-	FUNC("o2_drawSceneShapeOnPage", "\xC0r0ppppp");
+	FUNC("o2_setCharPalEntry", "rpp");
+	FUNC("o2_loadZShapes", "rp");
+	FUNC("o2_drawSceneShape", "rpppp");
+	FUNC("o2_drawSceneShapeOnPage", "rppppp");
 	// 0x40
-	FUNC("o2_disableAnimObject", "\xC0r0p");
-	FUNC("o2_enableAnimObject", "\xC0r0p");
-	FUNC("o2_dummy42", "\xC0r");
-	FUNC("o2_loadPalette384", "\xC0r0s");
+	FUNC("o2_disableAnimObject", "rp");
+	FUNC("o2_enableAnimObject", "rp");
+	FUNC("o2_dummy42", "r");
+	FUNC("o2_loadPalette384", "rs");
 	// 0x44
-	FUNC("o2_setPalette384", "\xC0r");
-	FUNC("o2_restoreBackBuffer", "\xC0r0p");
-	FUNC("o2_backUpInventoryGfx", "\xC0r");
-	FUNC("o2_disableSceneAnim", "\xC0r0p");
+	FUNC("o2_setPalette384", "r");
+	FUNC("o2_restoreBackBuffer", "rp");
+	FUNC("o2_backUpInventoryGfx", "r");
+	FUNC("o2_disableSceneAnim", "rp");
 	// 0x48
-	FUNC("o2_enableSceneAnim", "\xC0r0p");
-	FUNC("o2_restoreInventoryGfx", "\xC0r");
-	FUNC("o2_setSceneAnimPos2", "\xC0r0ppp");
-	FUNC("o2_update", "\xC0r0p");
+	FUNC("o2_enableSceneAnim", "rp");
+	FUNC("o2_restoreInventoryGfx", "r");
+	FUNC("o2_setSceneAnimPos2", "rppp");
+	FUNC("o2_update", "rp");
 	// 0x4c
-	FUNC("unk4C_palFade?", "\xC0r0pp");
-	FUNC("o2_fadeScenePal", "\xC0r0pp");
-	FUNC("o2_dummy4E", "\xC0r");
-	FUNC("o2_dummy4F", "\xC0r");
+	FUNC("unk4C_palFade?", "rpp");
+	FUNC("o2_fadeScenePal", "rpp");
+	FUNC("o2_dummy4E", "r");
+	FUNC("o2_dummy4F", "r");
 	// 0x50
-	FUNC("o2_enterNewScene", "\xC0r0ppppp");
-	FUNC("o2_switchScene", "\xC0r0p");
-	FUNC("o2_getShapeFlag1", "\xC0r0pp");
-	FUNC("o2_setPathfinderFlag", "\xC0r0p");
+	FUNC("o2_enterNewScene", "rppppp");
+	FUNC("o2_switchScene", "rp");
+	FUNC("o2_getShapeFlag1", "rpp");
+	FUNC("o2_setPathfinderFlag", "rp");
 	// 0x54
-	FUNC("o2_getSceneExitToFacing", "\xC0r0pp");
-	FUNC("o2_setLayerFlag", "\xC0r0p");
-	FUNC("o2_setZanthiaPos", "\xC0r0pp");
-	FUNC("o2_loadMusicTrack", "\xC0r0p");
+	FUNC("o2_getSceneExitToFacing", "rpp");
+	FUNC("o2_setLayerFlag", "rp");
+	FUNC("o2_setZanthiaPos", "rpp");
+	FUNC("o2_loadMusicTrack", "rp");
 	// 0x58
-	FUNC("o1_playWanderScoreViaMap", "\xC0r0pp");
-	FUNC("o1_playSoundEffect", "\xC0r0p");
-	FUNC("o2_setSceneAnimPos", "\xC0r0ppp");
-	FUNC("o1_blockInWalkableRegion", "\xC0r0pppp");
+	FUNC("o1_playWanderScoreViaMap", "rpp");
+	FUNC("o1_playSoundEffect", "rp");
+	FUNC("o2_setSceneAnimPos", "rppp");
+	FUNC("o1_blockInWalkableRegion", "rpppp");
 	// 0x5c
-	FUNC("o1_blockOutWalkableRegion", "\xC0r0pppp");
-	FUNC("unk5D", "\xC0r0ppppp");
-	FUNC("o2_setCauldronState", "\xC0r0pp");
-	FUNC("o2_showItemString", "\xC0r0pp");
+	FUNC("o1_blockOutWalkableRegion", "rpppp");
+	FUNC("unk5D", "rppppp");
+	FUNC("o2_setCauldronState", "rpp");
+	FUNC("o2_showItemString", "rpp");
 	// 0x60
-	FUNC("o1_getRand", "\xC0r0pp");
-	FUNC("o2_isAnySoundPlaying", "\xC0r");
-	FUNC("o1_setDeathHandler", "\xC0r0p");
-	FUNC("o2_setDrawNoShapeFlag", "\xC0r0p");
+	FUNC("o1_getRand", "rpp");
+	FUNC("o2_isAnySoundPlaying", "r");
+	FUNC("o1_setDeathHandler", "rp");
+	FUNC("o2_setDrawNoShapeFlag", "rp");
 	// 0x64
-	FUNC("o2_setRunFlag", "\xC0r0p");
-	FUNC("o2_showLetter", "\xC0r0p");
-	FUNC("o1_shakeScreen", "\xC0r0pp");
-	FUNC("o1_fillRect", "\xC0r0pppppp");
+	FUNC("o2_setRunFlag", "rp");
+	FUNC("o2_showLetter", "rp");
+	FUNC("o1_shakeScreen", "rpp");
+	FUNC("o1_fillRect", "rpppppp");
 	// 0x68
-	FUNC("o2_getKey", "\xC0r");
-	FUNC("unk69", "\xC0r0pppp");
-	FUNC("o2_playFireflyScore", "\xC0r");
-	FUNC("o2_waitForConfirmationClick", "\xC0r0p");
+	FUNC("o2_getKey", "r");
+	FUNC("unk69", "rpppp");
+	FUNC("o2_playFireflyScore", "r");
+	FUNC("o2_waitForConfirmationClick", "rp");
 	// 0x6c
-	FUNC("o2_encodeShape", "\xC0r0ppppp");
-	FUNC("o2_defineRoomEntrance", "\xC0r0ppp");
-	FUNC("o2_runAnimationScript", "\xC0r0sppp");
-	FUNC("o2_setSpecialSceneScriptRunTime", "\xC0r0pp");
+	FUNC("o2_encodeShape", "rppppp");
+	FUNC("o2_defineRoomEntrance", "rppp");
+	FUNC("o2_runAnimationScript", "rsppp");
+	FUNC("o2_setSpecialSceneScriptRunTime", "rpp");
 	// 0x70
-	FUNC("o2_defineSceneAnim", "\xC0r0pppppppppppps");
-	FUNC("o2_updateSceneAnim", "\xC0r0pp");
-	FUNC("o2_updateSceneAnim", "\xC0r0pp");
-	FUNC("o2_addToSceneAnimPosAndUpdate", "\xC0r0ppp");
+	FUNC("o2_defineSceneAnim", "rpppppppppppps");
+	FUNC("o2_updateSceneAnim", "rpp");
+	FUNC("o2_updateSceneAnim", "rpp");
+	FUNC("o2_addToSceneAnimPosAndUpdate", "rppp");
 	// 0x74
-	FUNC("o2_useItemOnMainChar", "\xC0r");
-	FUNC("o2_startDialogue", "\xC0r0p");
-	FUNC("o2_randomSceneChat", "\xC0r");
-	FUNC("o2_setDlgIndex", "\xC0r0p");
+	FUNC("o2_useItemOnMainChar", "r");
+	FUNC("o2_startDialogue", "rp");
+	FUNC("o2_randomSceneChat", "r");
+	FUNC("o2_setDlgIndex", "rp");
 	// 0x78
-	FUNC("o2_getDlgIndex", "\xC0r");
-	FUNC("o2_defineScene", "\xC0r0pspppppp");
-	FUNC("o2_addCauldronStateTableEntry", "\xC0r0pp");
-	FUNC("o2_setCountDown", "\xC0r0p");
+	FUNC("o2_getDlgIndex", "r");
+	FUNC("o2_defineScene", "rpspppppp");
+	FUNC("o2_addCauldronStateTableEntry", "rpp");
+	FUNC("o2_setCountDown", "rp");
 	// 0x7c
-	FUNC("o2_getCountDown", "\xC0r");
-	FUNC("o2_dummy7D", "\xC0r");
-	FUNC("o2_dummy7E", "\xC0r");
-	FUNC("o2_pressColorKey", "\xC0r0p");
+	FUNC("o2_getCountDown", "r");
+	FUNC("o2_dummy7D", "r");
+	FUNC("o2_dummy7E", "r");
+	FUNC("o2_pressColorKey", "rp");
 	// 0x80
-	FUNC("o2_objectChat", "\xC0r0sp");
-	FUNC("o2_changeChapter", "\xC0r0pp");
-	FUNC("o2_getColorCodeFlag1", "\xC0r");
-	FUNC("o2_setColorCodeFlag1", "\xC0r0p");
+	FUNC("o2_objectChat", "rsp");
+	FUNC("o2_changeChapter", "rpp");
+	FUNC("o2_getColorCodeFlag1", "r");
+	FUNC("o2_setColorCodeFlag1", "rp");
 	// 0x84
-	FUNC("o2_getColorCodeFlag2", "\xC0r");
-	FUNC("o2_setColorCodeFlag2", "\xC0r0p");
-	FUNC("o2_getColorCodeValue", "\xC0r0p");
-	FUNC("o2_setColorCodeValue", "\xC0r0pp");
+	FUNC("o2_getColorCodeFlag2", "r");
+	FUNC("o2_setColorCodeFlag2", "rp");
+	FUNC("o2_getColorCodeValue", "rp");
+	FUNC("o2_setColorCodeValue", "rpp");
 	// 0x88
-	FUNC("o2_countItemInstances", "\xC0r0p");
-	FUNC("o2_removeItemFromScene", "\xC0r0pp");
-	FUNC("o2_initObject", "\xC0r0p");
-	FUNC("o2_npcChat", (_engine->_isTalkie ? "\xC0r0spp": "\xC0r0sp"));
+	FUNC("o2_countItemInstances", "rp");
+	FUNC("o2_removeItemFromScene", "rpp");
+	FUNC("o2_initObject", "rp");
+	FUNC("o2_npcChat", (_engine->_isTalkie ? "rspp": "rsp"));
 	// 0x8c
-	FUNC("o2_deinitObject", "\xC0r0p");
-	FUNC("o2_playTimSequence", "\xC0r0s");
-	FUNC("o2_makeBookOrCauldronAppear", "\xC0r0p");
-	FUNC("o2_setSpecialSceneScriptState", "\xC0r0p");
+	FUNC("o2_deinitObject", "rp");
+	FUNC("o2_playTimSequence", "rs");
+	FUNC("o2_makeBookOrCauldronAppear", "rp");
+	FUNC("o2_setSpecialSceneScriptState", "rp");
 	// 0x90
-	FUNC("o2_clearSpecialSceneScriptState", "\xC0r0p");
-	FUNC("o2_querySpecialSceneScriptState", "\xC0r0p");
-	FUNC("o2_resetInputColorCode", "\xC0r");
-	FUNC("o2_setHiddenItemsEntry", "\xC0r0pp");
+	FUNC("o2_clearSpecialSceneScriptState", "rp");
+	FUNC("o2_querySpecialSceneScriptState", "rp");
+	FUNC("o2_resetInputColorCode", "r");
+	FUNC("o2_setHiddenItemsEntry", "rpp");
 	// 0x94
-	FUNC("o2_getHiddenItemsEntry", "\xC0r0p");
-	FUNC("o2_mushroomEffect", "\xC0r");
-	FUNC("o2_wsaClose", "\xC0r0p");
-	FUNC("o2_meanWhileScene", "\xC0r0p");
+	FUNC("o2_getHiddenItemsEntry", "rp");
+	FUNC("o2_mushroomEffect", "r");
+	FUNC("o2_wsaClose", "rp");
+	FUNC("o2_meanWhileScene", "rp");
 	// 0x98
-	FUNC("o2_customChat", "\xC0r0spp");
-	FUNC("o2_customChatFinish", "\xC0r");
-	FUNC("o2_setupSceneAnimation", "\xC0r0pppppppppppps");
-	FUNC("o2_stopSceneAnimation", "\xC0r0pp");
+	FUNC("o2_customChat", "rspp");
+	FUNC("o2_customChatFinish", "r");
+	FUNC("o2_setupSceneAnimation", "rpppppppppppps");
+	FUNC("o2_stopSceneAnimation", "rpp");
 	// 0x9c
-	FUNC("o2_disableTimer", "\xC0r0p");
-	FUNC("o2_enableTimer", "\xC0r0p");
-	FUNC("o2_setTimerCountdown", "\xC0r0pp");
-	FUNC("o2_processPaletteIndex", "\xC0r0pppppp");
+	FUNC("o2_disableTimer", "rp");
+	FUNC("o2_enableTimer", "rp");
+	FUNC("o2_setTimerCountdown", "rpp");
+	FUNC("o2_processPaletteIndex", "rpppppp");
 	// 0xa0
-	FUNC("o2_updateTwoSceneAnims", "\xC0r0pppp");
-	FUNC("o2_getRainbowRoomData", "\xC0r0p");
-	FUNC("o2_drawSceneShapeEx", "\xC0r0pppp");
-	FUNC("o2_midiSoundFadeout", "\xC0r");
+	FUNC("o2_updateTwoSceneAnims", "rpppp");
+	FUNC("o2_getRainbowRoomData", "rp");
+	FUNC("o2_drawSceneShapeEx", "rpppp");
+	FUNC("o2_midiSoundFadeout", "r");
 	// 0xa4
-	FUNC("o2_getSfxDriver", "\xC0r");
-	FUNC("o2_getVocSupport", "\xC0r");
-	FUNC("o2_getMusicDriver", "\xC0r");
-	FUNC("o2_setVocHigh", "\xC0r0p");
+	FUNC("o2_getSfxDriver", "r");
+	FUNC("o2_getVocSupport", "r");
+	FUNC("o2_getMusicDriver", "r");
+	FUNC("o2_setVocHigh", "rp");
 	// 0xa8
-	FUNC("o2_getVocHigh", "\xC0r");
-	FUNC("o2_zanthiaChat", "\xC0r0sp");
-	FUNC("o2_isVoiceEnabled", "\xC0r");
-	FUNC("o2_isVoicePlaying", "\xC0r");
+	FUNC("o2_getVocHigh", "r");
+	FUNC("o2_zanthiaChat", "rsp");
+	FUNC("o2_isVoiceEnabled", "r");
+	FUNC("o2_isVoicePlaying", "r");
 	// 0xac
-	FUNC("o2_stopVoicePlaying", "\xC0r");
-	FUNC("o2_getGameLanguage", "\xC0r");
-	FUNC("o2_demoFinale", "\xC0r");
-	FUNC("o2_dummyAF", "\xC0r" );
+	FUNC("o2_stopVoicePlaying", "r");
+	FUNC("o2_getGameLanguage", "r");
+	FUNC("o2_demoFinale", "r");
+	FUNC("o2_dummyAF", "r" );
 #undef FUNC
 }
 
@@ -425,7 +425,7 @@
 			if (parameter == 0) {
 				OPCODE("pushRet", kLoad, 1, false, false);
 			} else if (parameter == 1) {
-				OPCODE_MD("pushPos", kSpecial, 0, false, false, "\xC0"); // Sets up function call
+				OPCODE("pushPos", kSpecial, 0, false, false); // Sets up function call
 			} else {
 				// Error: invalid parameter halts execution
 				throw UnknownOpcodeException(address, opcode);

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.cpp	2010-08-14 21:29:45 UTC (rev 52093)
@@ -32,8 +32,8 @@
 	return new Kyra2Disassembler(this, insts);
 }
 
-uint32 Kyra::Kyra2Engine::getDestAddress(ConstInstIterator it) const {
-	return it->_params[0].getUnsigned();
+uint32 Kyra::Kyra2Engine::getDestAddress(const Instruction &inst) const {
+	return inst._params[0].getUnsigned();
 }
 
 CodeGenerator *Kyra::Kyra2Engine::getCodeGenerator(std::ostream &output) {
@@ -56,9 +56,7 @@
 		}
 		it->second._args = maxArg;
 		it->second._retVal = true;
-		std::stringstream md;
-		md << "0" << std::string(maxArg, 'p');
-		it->second._metadata = md.str();
+		it->second._metadata = std::string(maxArg, 'p');
 	}
 }
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/kyra/engine.h	2010-08-14 21:29:45 UTC (rev 52093)
@@ -36,7 +36,7 @@
 class Kyra2Engine : public Engine {
 public:
 	Disassembler *getDisassembler(std::vector<Instruction> &insts);
-	uint32 getDestAddress(ConstInstIterator it) const;
+	uint32 getDestAddress(const Instruction &inst) const;
 	CodeGenerator *getCodeGenerator(std::ostream &output);
 	void postCFG(std::vector<Instruction> &insts, Graph g);
 	bool detectMoreFuncs() const;

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/codegen.cpp	2010-08-14 21:29:45 UTC (rev 52093)
@@ -132,8 +132,9 @@
 				s << boost::format("WARNING: Couldn't handle conditional jump at address %08X") % inst._address;
 				addOutputLine(s.str());
 			}
-			break;
+			return;
 		}
+		CodeGenerator::processInst(inst);
 		break;
 	case kUnaryOpPost:
 		switch (inst._opcode) {
@@ -143,7 +144,7 @@
 		case 0x57: // wordVarDec
 			{
 				std::stringstream s;
-				EntryPtr p = new UnaryOpEntry(new VarEntry(decodeVarName(inst._params[0].getUnsigned())), inst._codeGenData.substr(1), true);
+				EntryPtr p = new UnaryOpEntry(new VarEntry(decodeVarName(inst._params[0].getUnsigned())), inst._codeGenData, true);
 				s << p << ";";
 				addOutputLine(s.str());
 			}
@@ -156,17 +157,13 @@
 				std::stringstream s;
 				EntryList idxs;
 				idxs.push_front(_stack.pop());
-				EntryPtr p = new UnaryOpEntry(new ArrayEntry(decodeVarName(inst._params[0].getUnsigned()), idxs), inst._codeGenData.substr(1), true);
+				EntryPtr p = new UnaryOpEntry(new ArrayEntry(decodeVarName(inst._params[0].getUnsigned()), idxs), inst._codeGenData, true);
 				s << p << ";";
 				addOutputLine(s.str());
 			}
 			break;
 		default:
-			{
-				std::stringstream s;
-				s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst._opcode % inst._address;
-				addOutputLine(s.str());
-			}
+			CodeGenerator::processInst(inst);
 			break;
 		}
 		break;
@@ -203,20 +200,12 @@
 
 			break;
 		default:
-			{
-				std::stringstream s;
-				s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst._opcode % inst._address;
-				addOutputLine(s.str());
-			}
+			CodeGenerator::processInst(inst);
 			break;
 		}
 		break;
 	default:
-		{
-			std::stringstream s;
-			s << boost::format("WARNING: Unknown opcode %X at address %08X") % inst._opcode % inst._address;
-			addOutputLine(s.str());
-		}
+		CodeGenerator::processInst(inst);
 		break;
 	}
 }

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/disassembler.cpp	2010-08-14 21:29:45 UTC (rev 52093)
@@ -92,14 +92,14 @@
 		OPCODE(0x47, "wordArrayWrite", kStore, -2, "w");
 		OPCODE(0x4A, "byteArrayIndexedWrite", kStore, -3, "B");
 		OPCODE(0x4B, "wordArrayIndexedWrite", kStore, -3, "w");
-		OPCODE_MD(0x4E, "byteVarInc", kUnaryOpPost, 0, "B", "\xC0++");
-		OPCODE_MD(0x4F, "wordVarInc", kUnaryOpPost, 0, "w", "\xC0++");
-		OPCODE_MD(0x52, "byteArrayInc", kUnaryOpPost, -1, "B", "\xC0++");
-		OPCODE_MD(0x53, "wordArrayInc", kUnaryOpPost, -1, "w", "\xC0++");
-		OPCODE_MD(0x56, "byteVarDec", kUnaryOpPost, 0, "B", "\xC0--");
-		OPCODE_MD(0x57, "wordVarDec", kUnaryOpPost, 0, "w", "\xC0--");
-		OPCODE_MD(0x5A, "byteArrayDec", kUnaryOpPost, -1, "B", "\xC0--");
-		OPCODE_MD(0x5B, "wordArrayDec", kUnaryOpPost, -1, "w", "\xC0--");
+		OPCODE_MD(0x4E, "byteVarInc", kUnaryOpPost, 0, "B", "++");
+		OPCODE_MD(0x4F, "wordVarInc", kUnaryOpPost, 0, "w", "++");
+		OPCODE_MD(0x52, "byteArrayInc", kUnaryOpPost, -1, "B", "++");
+		OPCODE_MD(0x53, "wordArrayInc", kUnaryOpPost, -1, "w", "++");
+		OPCODE_MD(0x56, "byteVarDec", kUnaryOpPost, 0, "B", "--");
+		OPCODE_MD(0x57, "wordVarDec", kUnaryOpPost, 0, "w", "--");
+		OPCODE_MD(0x5A, "byteArrayDec", kUnaryOpPost, -1, "B", "--");
+		OPCODE_MD(0x5B, "wordArrayDec", kUnaryOpPost, -1, "w", "--");
 		OPCODE(0x5C, "jumpTrue", kCondJumpRel, -1, "s");
 		OPCODE(0x5D, "jumpFalse", kCondJumpRel, -1, "s");
 		OPCODE_MD(0x5E, "startScript", kSpecial, 0x1020, "", "lpp"); // Variable stack arguments
@@ -286,9 +286,9 @@
 		OPCODE_MD(0xA2, "getActorElevation", kSpecial, 0, "", "rp");
 		OPCODE_MD(0xA3, "getVerbEntrypoint", kSpecial, -1, "", "rpp");
 		START_SUBOPCODE_WITH_PREFIX(0xA4, "arrayOps");
-			OPCODE_MD(0xCD, "assignString", kSpecial, -1, "wc", "\xC0");
-			OPCODE_MD(0xD0, "assignIntList", kSpecial, 0x1100, "w", "\xC0"); // Variable stack arguments
-			OPCODE_MD(0xD4, "assign2DimList", kSpecial, 0x1100, "w", "\xC0"); // Variable stack arguments
+			OPCODE_MD(0xCD, "assignString", kSpecial, -1, "wc", "");
+			OPCODE_MD(0xD0, "assignIntList", kSpecial, 0x1100, "w", ""); // Variable stack arguments
+			OPCODE_MD(0xD4, "assign2DimList", kSpecial, 0x1100, "w", ""); // Variable stack arguments
 		END_SUBOPCODE;
 		START_SUBOPCODE_WITH_PREFIX(0xA5, "saveRestoreVerbs");
 			OPCODE_MD(0x8D, "saveVerbs", kSpecial, -3, "", "ppp");

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.cpp	2010-08-14 21:29:45 UTC (rev 52093)
@@ -28,14 +28,11 @@
 	return new Scummv6Disassembler(insts);
 }
 
-uint32 Scumm::v6::Scummv6Engine::getDestAddress(ConstInstIterator it) const {
-	switch(it->_type) {
-	case kJump:
-	case kCondJump:
-		return it->_params[0].getUnsigned();
+uint32 Scumm::v6::Scummv6Engine::getDestAddress(const Instruction &inst) const {
+	switch(inst._type) {
 	case kJumpRel:
 	case kCondJumpRel:
-		return it->_params[0].getSigned() + it->_address + 3;
+		return inst._params[0].getSigned() + inst._address + 3;
 	default:
 		return 0;
 	}

Modified: tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/scummv6/engine.h	2010-08-14 21:29:45 UTC (rev 52093)
@@ -35,7 +35,7 @@
 class Scummv6Engine : public Engine {
 public:
 	Disassembler *getDisassembler(std::vector<Instruction> &insts);
-	uint32 getDestAddress(ConstInstIterator it) const;
+	uint32 getDestAddress(const Instruction &inst) const;
 	CodeGenerator *getCodeGenerator(std::ostream &output);
 };
 

Modified: tools/branches/gsoc2010-decompiler/decompiler/test/module.mk
===================================================================
--- tools/branches/gsoc2010-decompiler/decompiler/test/module.mk	2010-08-14 20:13:25 UTC (rev 52092)
+++ tools/branches/gsoc2010-decompiler/decompiler/test/module.mk	2010-08-14 21:29:45 UTC (rev 52093)
@@ -11,6 +11,7 @@
 	decompiler/codegen.o \
 	decompiler/control_flow.o \
 	decompiler/disassembler.o \
+	decompiler/engine.o \
 	decompiler/simple_disassembler.o \
 	decompiler/scummv6/disassembler.o \
 	decompiler/scummv6/codegen.o \


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