diff pytouhou/vm/anmrunner.py @ 236:741860192b56

Implement ANM0 interrupts “Instruction” 22 is used as a label for interrupts. If the normal animation is interrupted, it goes straight to the matched instruction. Interrupt -1 matches all interrupts.
author Thibaut Girka <thib@sitedethib.com>
date Sun, 01 Jan 2012 19:47:34 +0100
parents e7902309305c
children 0e1762b1ab9f
line wrap: on
line diff
--- a/pytouhou/vm/anmrunner.py
+++ b/pytouhou/vm/anmrunner.py
@@ -25,13 +25,15 @@ class ANMRunner(object):
     __metaclass__ = MetaRegistry
     __slots__ = ('_anm_wrapper', '_sprite', '_running',
                  'sprite_index_offset',
-                 'script', 'instruction_pointer', 'frame')
+                 'script', 'instruction_pointer', 'frame',
+                 'waiting')
 
 
     def __init__(self, anm_wrapper, script_id, sprite, sprite_index_offset=0):
         self._anm_wrapper = anm_wrapper
         self._sprite = sprite
         self._running = True
+        self.waiting = False
 
         anm, self.script = anm_wrapper.get_script(script_id)
         self.frame = 0
@@ -40,10 +42,25 @@ class ANMRunner(object):
         self.sprite_index_offset = sprite_index_offset
 
 
+    def interrupt(self, interrupt):
+        new_ip = self.script.interrupts.get(interrupt, None)
+        if new_ip is None:
+            new_ip = self.script.interrupts.get(-1, None)
+        if new_ip is None:
+            return False
+        else:
+            self.instruction_pointer = new_ip
+            self.frame, opcode, args = self.script[self.instruction_pointer]
+            return True
+
+
     def run_frame(self):
         if not self._running:
             return False
 
+        if self.waiting:
+            return True
+
         sprite = self._sprite
 
         while self._running:
@@ -166,7 +183,6 @@ class ANMRunner(object):
 
 
     @instruction(15)
-    @instruction(21) #TODO
     def keep_still(self):
         self._running = False
 
@@ -196,6 +212,19 @@ class ANMRunner(object):
         self._sprite.move_in(duration, x, y, z, lambda x: x ** 2)
 
 
+    @instruction(21)
+    def wait(self):
+        """Wait for an interrupt.
+        """
+        self.waiting = True
+
+
+    @instruction(22)
+    def interrupt_label(self, interrupt):
+        """Noop"""
+        pass
+
+
     @instruction(23)
     def set_corner_relative_placement(self):
         self._sprite.corner_relative_placement = True #TODO