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

kjdf at users.sourceforge.net kjdf at users.sourceforge.net
Sun Jun 7 20:07:16 CEST 2009


Revision: 41347
          http://scummvm.svn.sourceforge.net/scummvm/?rev=41347&view=rev
Author:   kjdf
Date:     2009-06-07 18:07:16 +0000 (Sun, 07 Jun 2009)

Log Message:
-----------
decompiler: reworked scumm6parser to make use of reader dispatching, added some opcodes to test
disassembly

Modified Paths:
--------------
    tools/branches/gsoc2009-decompiler/decompiler/Makefile
    tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc
    tools/branches/gsoc2009-decompiler/decompiler/parser.h

Added Paths:
-----------
    tools/branches/gsoc2009-decompiler/decompiler/reader.h

Modified: tools/branches/gsoc2009-decompiler/decompiler/Makefile
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/Makefile	2009-06-07 17:18:11 UTC (rev 41346)
+++ tools/branches/gsoc2009-decompiler/decompiler/Makefile	2009-06-07 18:07:16 UTC (rev 41347)
@@ -8,7 +8,7 @@
 decompiler: decompiler.o $(DEPS)
 	g++ -Wall -g $^ -o $@
 
-decompiler.o: decompiler.cc misc.h instruction.h parser.h
+decompiler.o: decompiler.cc misc.h instruction.h parser.h reader.h
 	g++ -Wall -g -c decompiler.cc -o decompiler.o
 
 clean:

Modified: tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc	2009-06-07 17:18:11 UTC (rev 41346)
+++ tools/branches/gsoc2009-decompiler/decompiler/decompiler.cc	2009-06-07 18:07:16 UTC (rev 41347)
@@ -1,4 +1,4 @@
-#include <iostream>
+#include <cstdio>
 #include <vector>
 
 using namespace std;
@@ -10,6 +10,6 @@
 int main(int argc, char **argv) {
 	vector<Instruction*> v = Scumm6Parser().parseFile(argv[1]);
 	for (unsigned i = 0; i < v.size(); i++)
-		cout << v[i]->_addr << ": " << v[i]->_description << endl;
+		printf("%04x: %s\n", v[i]->_addr-8, v[i]->_description.c_str());
 	return 0;
 }

Modified: tools/branches/gsoc2009-decompiler/decompiler/parser.h
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/parser.h	2009-06-07 17:18:11 UTC (rev 41346)
+++ tools/branches/gsoc2009-decompiler/decompiler/parser.h	2009-06-07 18:07:16 UTC (rev 41347)
@@ -1,5 +1,5 @@
-#ifndef READER_H
-#define READER_H
+#ifndef PARSER_H
+#define PARSER_H
 
 
 #include <fstream>
@@ -13,69 +13,57 @@
 
 
 #include "misc.h"
+#include "reader.h"
 #include "instruction.h"
 
 
-using namespace std;
-
-
-struct Reader {
-	virtual void readInstruction(ifstream &f, vector<Instruction*> &v, uint32 addr) = 0;
-};
-
-
-struct SimpleReader : public Reader {
-
-	string _description;
-	int _skip;
-
-	SimpleReader(string description, int skip=0) : _description(description), _skip(skip) {};
-
-	virtual void readInstruction(ifstream &f, vector<Instruction*> &v, uint32 addr) {
-		for (int i = 0; i < _skip; i++) {
-			char c = f.get();
-			printf("SKIPPED: 0x%x\n", (unsigned int) c);
-		}
-		v.push_back(new Instruction(_description, addr));
-	}
-};
-
-
-struct SubopcodeReader : public Reader {
-
-	Reader *_dispatchTable[256];
-
-	SubopcodeReader() {
-		memset(_dispatchTable, 0, sizeof(_dispatchTable));
-	}
-
-	void registerOpcode(uint8 opcode, Reader *reader) {
-		_dispatchTable[opcode] = reader;
-	}
-
-	void readInstruction(ifstream& f, vector<Instruction*> &v, uint32 addr) {
-		uint8 opcode = f.get();
-		Reader* reader = _dispatchTable[opcode];
-		assert(reader);
-		reader->readInstruction(f, v, addr);
-	}
-};
-
-
 struct Scumm6Parser {
 
-	Reader *_dispatchTable[256];
+	SubopcodeReader *_reader;
 
 	Scumm6Parser() {
-		memset(_dispatchTable, 0, sizeof(_dispatchTable));
-		_dispatchTable[0] = new SimpleReader("zero", 0);
-		_dispatchTable[1] = new SimpleReader("one", 1);
-		_dispatchTable[2] = new SimpleReader("two", 2);
-		SubopcodeReader *three = new SubopcodeReader();
-		three->registerOpcode(1, new SimpleReader("three/1", 1));
-		three->registerOpcode(2, new SimpleReader("three/2", 2));
-		_dispatchTable[3] = three;
-		_dispatchTable[4] = new SimpleReader("four", 4);
+		_reader = new SubopcodeReader();
+		_reader->registerOpcode(0x01, new SimpleReader("push", "w"));
+		_reader->registerOpcode(0x03, new SimpleReader("pushVar(v->s)", "w"));
+		_reader->registerOpcode(0x07, new SimpleReader("arrayRead", "w"));
+		_reader->registerOpcode(0x0e, new SimpleReader("=="));
+		_reader->registerOpcode(0x0f, new SimpleReader("!="));
+		_reader->registerOpcode(0x10, new SimpleReader(">"));
+		_reader->registerOpcode(0x12, new SimpleReader("<"));
+		_reader->registerOpcode(0x13, new SimpleReader(">="));
+		_reader->registerOpcode(0x14, new SimpleReader("+"));
+		_reader->registerOpcode(0x43, new SimpleReader("writeVar(s->v)", "w"));
+		_reader->registerOpcode(0x4f, new SimpleReader("varInc", "w"));
+		_reader->registerOpcode(0x5d, new SimpleReader("jumpIfNot", "w"));
+		_reader->registerOpcode(0x5e, new SimpleReader("startScript"));
+		_reader->registerOpcode(0x60, new SimpleReader("startObject"));
+		_reader->registerOpcode(0x66, new SimpleReader("stopObjectCode"));
+		_reader->registerOpcode(0x67, new SimpleReader("endCutscene"));
+		_reader->registerOpcode(0x68, new SimpleReader("cutscene"));
+		_reader->registerOpcode(0x6d, new SimpleReader("classOfIs"));
+		_reader->registerOpcode(0x72, new SimpleReader("getOwner"));
+		_reader->registerOpcode(0x73, new SimpleReader("jump", "w"));
+		_reader->registerOpcode(0x7c, new SimpleReader("stopScript"));
+		_reader->registerOpcode(0x7d, new SimpleReader("walkActorToObj"));
+		_reader->registerOpcode(0x7e, new SimpleReader("walkActorTo"));
+		_reader->registerOpcode(0x81, new SimpleReader("faceCutscene"));
+		_reader->registerOpcode(0x82, new SimpleReader("animateActor"));
+		_reader->registerOpcode(0x83, new SimpleReader("doSentence"));
+		_reader->registerOpcode(0x8d, new SimpleReader("getObjectX"));
+		_reader->registerOpcode(0x8e, new SimpleReader("getObjectY"));
+		_reader->registerOpcode(0xa3, new SimpleReader("getVerbEntryPoint"));
+		SubopcodeReader *wait = new SubopcodeReader();
+		wait->registerOpcode(168, new SimpleReader("wait_forActor", "w"));
+		_reader->registerOpcode(0xa9, wait);
+		_reader->registerOpcode(0xad, new SimpleReader("isAnyOf"));
+		_reader->registerOpcode(0xb0, new SimpleReader("delay"));
+		_reader->registerOpcode(0xb3, new SimpleReader("stopSentence"));
+
+		//		SubopcodeReader *three = new SubopcodeReader();
+		//		three->registerOpcode(1, new SimpleReader("three/1", 1));
+		//		three->registerOpcode(2, new SimpleReader("three/2", 2));
+		//		_reader->registerOpcode(3, three);
+		//		_reader->registerOpcode(4, new SimpleReader("four", 4));
 	}
 
 	void parseHeader(ifstream &f) {
@@ -98,7 +86,7 @@
 			uint16 minOffset = 65535;
 			for (uint8 code = f.get(); code != 0; code = f.get()) {
 				uint16 offset = read_le_uint16(f);
-				printf("%2X - %.4X\n", code, offset);
+				printf("%2x - %.4x\n", code, offset);
 				if (offset < minOffset)
 					minOffset = offset;
 			}
@@ -112,15 +100,9 @@
 		ifstream f;
 		f.open(filename, ios::binary);
 		parseHeader(f);
-		while (true) {
-			uint8 addr = f.tellg();
-			uint8 opcode = f.get();
-			if (f.eof())
-				return v;
-			Reader* reader = _dispatchTable[opcode];
-			assert(reader);
-			reader->readInstruction(f, v, addr);
-		}
+		while (_reader->readInstruction(f, v, f.tellg()))
+			;
+		return v;
 	}
 
 };

Added: tools/branches/gsoc2009-decompiler/decompiler/reader.h
===================================================================
--- tools/branches/gsoc2009-decompiler/decompiler/reader.h	                        (rev 0)
+++ tools/branches/gsoc2009-decompiler/decompiler/reader.h	2009-06-07 18:07:16 UTC (rev 41347)
@@ -0,0 +1,77 @@
+#ifndef READER_H
+#define READER_H
+
+
+#include <fstream>
+#include <vector>
+#include <sstream>
+#include <iomanip>
+
+#include <cassert>
+#include <cstring>
+#include <cstdio>
+
+using namespace std;
+
+
+#include "misc.h"
+#include "instruction.h"
+
+
+struct Reader {
+	// return true if all went ok and we can safely read next afterwards
+	virtual bool readInstruction(ifstream &f, vector<Instruction*> &v, uint32 addr) = 0;
+};
+
+
+struct SimpleReader : public Reader {
+
+	string _description;
+	string _format;
+
+	SimpleReader(string description, string format="") : _description(description), _format(format) {
+	};
+
+	bool readInstruction(ifstream &f, vector<Instruction*> &v, uint32 addr) {
+		stringstream description(stringstream::out);
+		description << _description;
+		for (uint32 i = 0; i < _format.size(); i++)
+			switch (_format[i]) {
+			case 'w':
+				uint16 w = read_le_uint16(f);
+				description.setf(ios::hex, ios::basefield);
+				description << "_0x" << setfill('0') << setw(4) << w;
+				break;
+			}
+		v.push_back(new Instruction(description.str(), addr));
+		return true;
+	}
+};
+
+
+struct SubopcodeReader : public Reader {
+
+	Reader *_dispatchTable[256];
+
+	SubopcodeReader() {
+		memset(_dispatchTable, 0, sizeof(_dispatchTable));
+	}
+
+	void registerOpcode(uint8 opcode, Reader *reader) {
+		_dispatchTable[opcode] = reader;
+	}
+
+	bool readInstruction(ifstream& f, vector<Instruction*> &v, uint32 addr) {
+		uint8 opcode = f.get();
+		if (f.eof())
+			return false;
+		else if (!_dispatchTable[opcode]) {
+			printf("! unhandled opcode 0x%02x (%d) at address 0x%02x (%d)\n", opcode, opcode, addr, addr);
+			return false;
+		} else
+			return _dispatchTable[opcode]->readInstruction(f, v, addr);
+	}
+};
+
+
+#endif


Property changes on: tools/branches/gsoc2009-decompiler/decompiler/reader.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native


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