changeset 43:7195aaf95f6e

Fix set_counter, and relative_jump(_ex)
author Thibaut Girka <thib@sitedethib.com>
date Thu, 18 Aug 2011 22:24:32 +0200
parents 1b0ca2fb89f9
children c435e83a8e70
files pytouhou/formats/ecl.py pytouhou/game/eclrunner.py
diffstat 2 files changed, 35 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/formats/ecl.py
+++ b/pytouhou/formats/ecl.py
@@ -133,10 +133,15 @@ class ECL(object):
         ecl.main = []
 
         # Read subs
-        for offset in sub_offsets:
-            file.seek(offset)
+        for sub_offset in sub_offsets:
+            file.seek(sub_offset)
             ecl.subs.append([])
+
+            instruction_offsets = []
+
             while True:
+                instruction_offsets.append(file.tell() - sub_offset)
+
                 time, opcode = unpack('<IH', file.read(6))
                 if time == 0xffffffff or opcode == 0xffff:
                     break
@@ -147,8 +152,22 @@ class ECL(object):
                 else:
                     args = (data, )
                     print('Warning: unknown opcode %d' % opcode) #TODO
+
                 ecl.subs[-1].append((time, opcode, rank_mask, param_mask, args))
 
+
+            # Translate offsets to instruction pointers
+            for instr_offset, (i, instr) in zip(instruction_offsets, enumerate(ecl.subs[-1])):
+                time, opcode, rank_mask, param_mask, args = instr
+                if opcode == 2: # relative_jump
+                    frame, relative_offset = args
+                    args = frame, instruction_offsets.index(instr_offset + relative_offset)
+                elif opcode == 3: # relative_jump_ex
+                    frame, relative_offset, counter_id = args
+                    args = frame, instruction_offsets.index(instr_offset + relative_offset), counter_id
+                ecl.subs[-1][i] = time, opcode, rank_mask, param_mask, args
+
+
         # Read main
         file.seek(main_offset)
         while True:
--- a/pytouhou/game/eclrunner.py
+++ b/pytouhou/game/eclrunner.py
@@ -2,9 +2,10 @@ class ECLRunner(object):
     def __init__(self, ecl, sub, frame=0, instruction_pointer=0, implementation=None):
         self.ecl = ecl
 
-        self.labels = {}
-        self.implementation = {4: (self.set_label),
-                               3: (self.goto)}
+        self.counters = {}
+        self.implementation = {4: (self.set_counter),
+                               2: (self.relative_jump),
+                               3: (self.relative_jump_ex)}
         if implementation:
             self.implementation.update(implementation)
 
@@ -13,23 +14,18 @@ class ECLRunner(object):
         self.instruction_pointer = instruction_pointer
 
 
-    def set_label(self, label, count):
-        self.labels[label & 0xffff] = (self.sub, self.instruction_pointer, count)
+    def set_counter(self, counter_id, count):
+        self.counters[counter_id & 0xffff] = count
 
 
-    def goto(self, frame, instruction_pointer, label):
-        try:
-            sub, instruction_pointer, count = self.labels[label & 0xffff]
-        except KeyError:
-            pass
-        else:
-            count -= 1
-            if count:
-                self.labels[label & 0xffff] = sub, instruction_pointer, count
-            else:
-                del self.labels[label & 0xffff]
-            self.frame = frame
-            self.sub, self.instruction_pointer = sub, instruction_pointer
+    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
+            self.frame, self.instruction_pointer = frame, instruction_pointer
 
 
     def update(self):