[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