changeset 71:a03d7a94b997

Add support for a few ANM instructions
author Thibaut Girka <thib@sitedethib.com>
date Sat, 27 Aug 2011 20:42:16 +0200
parents 7c1f20407b3e
children 6a08f44fa01b
files pytouhou/formats/anm0.py pytouhou/game/sprite.py pytouhou/vm/anmrunner.py
diffstat 3 files changed, 79 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/formats/anm0.py
+++ b/pytouhou/formats/anm0.py
@@ -33,12 +33,24 @@ class Animations(object):
                      10: ('fff', 'set_3d_rotations_speed'),
                      11: ('ff', 'set_scale_speed'),
                      12: ('ii', 'fade'),
+                     13: ('', None),
+                     14: ('', None),
                      15: ('', 'keep_still'),
                      16: ('i', 'set_random_sprite'),
+                     17: ('fff', None),
+                     18: ('ffii', None),
+                     19: ('ffii', None),
+                     20: ('fffi', None),
+                     21: ('', None),
+                     22: ('i', None),
                      23: ('', 'set_corner_relative_placement'),
+                     24: ('', None),
+                     25: ('i', 'set_allow_offset'), #TODO: better name
+                     26: ('i', None),
                      27: ('f', 'shift_texture_x'),
                      28: ('f', 'shift_texture_y'),
-                     30: ('ffi', 'scale_in')}
+                     30: ('ffi', 'scale_in'),
+                     31: ('i', None)}
 
 
     def __init__(self):
--- a/pytouhou/game/sprite.py
+++ b/pytouhou/game/sprite.py
@@ -14,6 +14,7 @@
 
 
 from pytouhou.utils.matrix import Matrix
+from pytouhou.utils.interpolator import Interpolator
 
 
 class AnmWrapper(object):
@@ -42,7 +43,13 @@ class Sprite(object):
         self._removed = False
         self._changed = False
 
+        self.scale_interpolator = None
+        self.fade_interpolator = None
+        self.offset_interpolator = None
+
         self.texcoords = (0, 0, 0, 0) # x, y, width, height
+        self.dest_offset = (0., 0., 0.)
+        self.allow_dest_offset = False
         self.texoffsets = (0., 0.)
         self.mirrored = False
         self.rescale = (1., 1.)
@@ -58,7 +65,41 @@ class Sprite(object):
         self._colors = []
 
 
+    def fade(self, duration, alpha, formula):
+        if not self.fade_interpolator:
+            self.fade_interpolator = Interpolator((self.alpha,), formula)
+            self.fade_interpolator.set_interpolation_start(self.frame, (self.alpha,))
+            self.fade_interpolator.set_interpolation_end(self.frame + duration - 1, (alpha,))
+
+
+    def scale_in(self, duration, sx, sy, formula):
+        if not self.scale_interpolator:
+            self.scale_interpolator = Interpolator(self.rescale, formula)
+            self.scale_interpolator.set_interpolation_start(self.frame, self.rescale)
+            self.scale_interpolator.set_interpolation_end(self.frame + duration - 1, (sx, sy))
+
+
+    def move_in(self, duration, x, y, z, formula):
+        if not self.offset_interpolator:
+            self.offset_interpolator = Interpolator(self.dest_offset, formula)
+            self.offset_interpolator.set_interpolation_start(self.frame, self.dest_offset)
+            self.offset_interpolator.set_interpolation_end(self.frame + duration - 1, (x, y, z))
+
+
     def update_vertices_uvs_colors(self, override_width=0, override_height=0):
+        if self.fade_interpolator:
+            self.fade_interpolator.update(self.frame)
+            self.alpha = int(self.fade_interpolator.values[0])
+
+        if self.scale_interpolator:
+            self.scale_interpolator.update(self.frame)
+            self.rescale = self.scale_interpolator.values
+
+        if self.offset_interpolator:
+            self.offset_interpolator.update(self.frame)
+            self.dest_offset = self.offset_interpolator.values
+
+
         vertmat = Matrix([[-.5,     .5,     .5,    -.5],
                           [-.5,    -.5,     .5,     .5],
                           [ .0,     .0,     .0,     .0],
@@ -82,6 +123,8 @@ class Sprite(object):
                 vertmat.rotate_z(-rz) #TODO: minus, really?
         if self.corner_relative_placement: # Reposition
             vertmat.translate(width / 2., height / 2., 0.)
+        if self.allow_dest_offset:
+            vertmat.translate(*self.dest_offset)
 
         x_1 = 1. / self.anm.size[0]
         y_1 = 1. / self.anm.size[1]
@@ -104,4 +147,5 @@ class Sprite(object):
             self.rotations_3d = ax + sax, ay + say, az + saz
             self.rescale = self.rescale[0] + self.scale_speed[0], self.rescale[1] + self.scale_speed[1]
             self._changed = True
+        self.frame += 1
 
--- a/pytouhou/vm/anmrunner.py
+++ b/pytouhou/vm/anmrunner.py
@@ -118,17 +118,36 @@ class ANMRunner(object):
         self._sprite.scale_speed = ssx, ssy
 
 
+    @instruction(12)
+    def fade(self, new_alpha, duration):
+        self._sprite.fade(duration, new_alpha, lambda x: x) #TODO: formula
+
+    @instruction(15)
+    @instruction(21) #TODO
+    def keep_still(self):
+        self._running = False
+
     @instruction(16)
     def load_random_sprite(self, min_idx, amp):
         #TODO: use the game's PRNG?
         self.load_sprite(min_idx + randrange(amp))
 
 
+    @instruction(19)
+    def move_in(self, x, y, z, duration):
+        self._sprite.move_in(duration, x, y, z, lambda x: x) #TODO: formula
+
+
     @instruction(23)
     def set_corner_relative_placement(self):
         self._sprite.corner_relative_placement = True #TODO
 
 
+    @instruction(25)
+    def set_allow_dest_offset(self, value):
+        self._sprite.allow_dest_offset = bool(value)
+
+
     @instruction(27)
     def shift_texture_x(self, dx):
         tox, toy = self._sprite.texoffsets
@@ -141,8 +160,7 @@ class ANMRunner(object):
         self._sprite.texoffsets = tox, toy + dy
 
 
-    @instruction(15)
-    @instruction(21) #TODO
-    def keep_still(self):
-        self._running = False
+    @instruction(30)
+    def scale_in(self, sx, sy, duration):
+        self._sprite.scale_in(duration, sx, sy, lambda x: x) #TODO: formula