diff pytouhou/game/eclrunner.py @ 23:444ac7bca7bc

Refacto ECL stuff, add support for a few instructions, and add some culling
author Thibaut Girka <thib@sitedethib.com>
date Fri, 12 Aug 2011 19:13:43 +0200
parents
children 93aa1b55d97c
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/pytouhou/game/eclrunner.py
@@ -0,0 +1,57 @@
+from struct import unpack
+
+
+class ECLRunner(object):
+    def __init__(self, ecl, sub, frame=0, instruction_pointer=0, implementation=None):
+        self.ecl = ecl
+
+        self.labels = {}
+        self.implementation = {4: ('HHI', self.set_label),
+                               3: ('IHHHH', self.goto)}
+        if implementation:
+            self.implementation.update(implementation)
+
+        self.sub = sub
+        self.frame = frame
+        self.instruction_pointer = instruction_pointer
+
+
+    def set_label(self, label, unknown, count):
+        assert unknown == 0xffff
+        self.labels[label] = (self.sub, self.instruction_pointer, count)
+
+
+    def goto(self, frame, unknown1, unknown2, label, unknown3):
+        try:
+            sub, instruction_pointer, count = self.labels[label]
+        except KeyError:
+            pass
+        else:
+            count -= 1
+            if count:
+                self.labels[label] = sub, instruction_pointer, count
+            else:
+                del self.labels[label]
+            self.frame = frame
+            self.sub, self.instruction_pointer = sub, instruction_pointer
+
+
+    def update(self):
+        frame = self.frame
+        while frame <= self.frame:
+            try:
+                frame, instr_type, rank_mask, param_mask, args = self.ecl.subs[self.sub][self.instruction_pointer]
+            except IndexError:
+                break #TODO: script ended, destroy enemy
+
+            if frame == self.frame:
+                try:
+                    format, callback = self.implementation[instr_type]
+                except KeyError:
+                    print('Warning: unhandled opcode %d!' % instr_type) #TODO
+                else:
+                    callback(*unpack('<' + format, args))
+                self.instruction_pointer += 1
+
+        self.frame += 1
+