changeset 47:1f1793e7ec8e

Handle a few more opcodes
author Thibaut Girka <thib@sitedethib.com>
date Mon, 22 Aug 2011 10:49:59 +0200
parents 25ca15f714ad
children 8353c33d53d4
files pytouhou/game/eclrunner.py
diffstat 1 files changed, 46 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/eclrunner.py
+++ b/pytouhou/game/eclrunner.py
@@ -2,29 +2,62 @@ class ECLRunner(object):
     def __init__(self, ecl, sub, frame=0, instruction_pointer=0, implementation=None):
         self.ecl = ecl
 
-        self.counters = {}
-        self.implementation = {4: (self.set_counter),
-                               2: (self.relative_jump),
-                               3: (self.relative_jump_ex)}
-        if implementation:
-            self.implementation.update(implementation)
-
+        self.variables = [0,  0,  0,  0,
+                          0., 0., 0., 0.,
+                          0,  0,  0,  0]
         self.sub = sub
         self.frame = frame
         self.instruction_pointer = instruction_pointer
 
+        self.stack = []
 
-    def set_counter(self, counter_id, count):
-        self.counters[counter_id & 0xffff] = count
+        self.implementation = {4: self.set_variable,
+                               2: self.relative_jump,
+                               3: self.relative_jump_ex,
+                               35: self.call,
+                               36: self.ret,
+                               109: self.memory_write}
+        if implementation:
+            self.implementation.update(implementation)
+
+
+    def memory_write(self, value, index):
+        #TODO
+        #XXX: this is a hack to display bosses although we don't handle MSG :)
+        if index == 0:
+            self.sub = value
+            self.frame = 0
+            self.instruction_pointer = 0
+
+
+    def call(self, sub, param1, param2):
+        self.stack.append((self.sub, self.frame, self.instruction_pointer,
+                           self.variables))
+        self.sub = sub
+        self.frame = 0
+        self.instruction_pointer = 0
+        self.variables = [param1, 0,  0,  0,
+                          param2, 0., 0., 0.,
+                          0,      0,  0,  0]
+
+
+    def ret(self):
+        self.sub, self.frame, self.instruction_pointer, self.variables = self.stack.pop()
+
+
+
+    def set_variable(self, variable_id, value):
+        #TODO: -10013 and beyond!
+        self.variables[-10000-variable_id] = value
 
 
     def relative_jump(self, frame, instruction_pointer):
         self.frame, self.instruction_pointer = frame, instruction_pointer
 
 
-    def relative_jump_ex(self, frame, instruction_pointer, counter_id):
-        if self.counters[counter_id & 0xffff]:
-            self.counters[counter_id & 0xffff] -= 1
+    def relative_jump_ex(self, frame, instruction_pointer, variable_id):
+        if self.variables[-10000-variable_id]:
+            self.variables[-10000-variable_id] -= 1
             self.frame, self.instruction_pointer = frame, instruction_pointer
 
 
@@ -41,6 +74,7 @@ class ECLRunner(object):
                         print('Warning: unhandled opcode %d!' % instr_type) #TODO
                     else:
                         callback(*args)
+                        frame, instr_type, rank_mask, param_mask, args = self.ecl.subs[self.sub][self.instruction_pointer]
                 if frame <= self.frame:
                     self.instruction_pointer += 1
         except IndexError: