changeset 526:0b2a92a25245

Store data in C arrays in Sprite, and add an interface to access them as tuples.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Wed, 18 Dec 2013 18:15:45 +0100
parents 43ecf0f98f4d
children db28538cd399
files pytouhou/game/sprite.pxd pytouhou/game/sprite.py pytouhou/game/sprite.pyx
diffstat 3 files changed, 235 insertions(+), 169 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/sprite.pxd	Wed Dec 18 18:15:45 2013 +0100
+++ b/pytouhou/game/sprite.pxd	Wed Dec 18 18:15:45 2013 +0100
@@ -10,12 +10,18 @@
     cdef public Interpolator scale_interpolator, fade_interpolator
     cdef public Interpolator offset_interpolator, rotation_interpolator
     cdef public Interpolator color_interpolator
-    cdef public tuple texcoords, dest_offset, texoffsets, rescale, scale_speed
-    cdef public tuple rotations_3d, rotations_speed_3d, color
-    cdef public unsigned char alpha
     cdef public ANM anm
     cdef public object _rendering_data
 
+    cdef float _dest_offset[3]
+    cdef double _texcoords[4]
+    cdef double _texoffsets[2]
+    cdef double _rescale[2]
+    cdef double _scale_speed[2]
+    cdef double _rotations_3d[3]
+    cdef double _rotations_speed_3d[3]
+    cdef unsigned char _color[4]
+
     cpdef fade(self, unsigned long duration, alpha, formula=*)
     cpdef scale_in(self, unsigned long duration, sx, sy, formula=*)
     cpdef move_in(self, unsigned long duration, x, y, z, formula=*)
--- a/pytouhou/game/sprite.py	Wed Dec 18 18:15:45 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-# -*- encoding: utf-8 -*-
-##
-## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com>
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published
-## by the Free Software Foundation; version 3 only.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-## GNU General Public License for more details.
-##
-
-class Sprite(object):
-    def __init__(self, width_override=0, height_override=0):
-        self.anm = None
-        self.removed = False
-        self.changed = True
-        self.visible = True
-
-        self.width_override = width_override
-        self.height_override = height_override
-        self.angle = 0
-        self.force_rotation = False
-
-        self.scale_interpolator = None
-        self.fade_interpolator = None
-        self.offset_interpolator = None
-        self.rotation_interpolator = None
-        self.color_interpolator = None
-
-        self.automatic_orientation = False
-
-        self.blendfunc = 0 # 0 = Normal, 1 = saturate #TODO: proper constants
-
-        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.)
-        self.scale_speed = (0., 0.)
-        self.rotations_3d = (0., 0., 0.)
-        self.rotations_speed_3d = (0., 0., 0.)
-        self.corner_relative_placement = False
-        self.frame = 0
-        self.color = (255, 255, 255)
-        self.alpha = 255
-
-        self._rendering_data = None
-
-
-    def fade(self, duration, alpha, formula=None):
-        self.fade_interpolator = Interpolator((self.alpha,), self.frame,
-                                              (alpha,), self.frame + duration,
-                                              formula)
-
-
-    def scale_in(self, duration, sx, sy, formula=None):
-        self.scale_interpolator = Interpolator(self.rescale, self.frame,
-                                               (sx, sy), self.frame + duration,
-                                               formula)
-
-
-    def move_in(self, duration, x, y, z, formula=None):
-        self.offset_interpolator = Interpolator(self.dest_offset, self.frame,
-                                                (x, y, z), self.frame + duration,
-                                                formula)
-
-
-    def rotate_in(self, duration, rx, ry, rz, formula=None):
-        self.rotation_interpolator = Interpolator(self.rotations_3d, self.frame,
-                                                  (rx, ry, rz), self.frame + duration,
-                                                  formula)
-
-
-    def change_color_in(self, duration, r, g, b, formula=None):
-        self.color_interpolator = Interpolator(self.color, self.frame,
-                                               (r, g, b), self.frame + duration,
-                                               formula)
-
-
-    def update_orientation(self, angle_base=0., force_rotation=False):
-        if (self.angle != angle_base or self.force_rotation != force_rotation):
-            self.angle = angle_base
-            self.force_rotation = force_rotation
-            self.changed = True
-
-
-    def copy(self):
-        sprite = Sprite(self.width_override, self.height_override)
-
-        sprite.blendfunc = self.blendfunc
-        sprite.frame = self.frame
-        sprite.angle = self.angle
-
-        sprite.removed = self.removed
-        sprite.changed = self.changed
-        sprite.visible = self.visible
-        sprite.force_rotation = self.force_rotation
-        sprite.automatic_orientation = self.automatic_orientation
-        sprite.allow_dest_offset = self.allow_dest_offset
-        sprite.mirrored = self.mirrored
-        sprite.corner_relative_placement = self.corner_relative_placement
-
-        sprite.scale_interpolator = self.scale_interpolator
-        sprite.fade_interpolator = self.fade_interpolator
-        sprite.offset_interpolator = self.offset_interpolator
-        sprite.rotation_interpolator = self.rotation_interpolator
-        sprite.color_interpolator = self.color_interpolator
-
-        sprite.texcoords = self.texcoords
-        sprite.dest_offset = self.dest_offset
-        sprite.texoffsets = self.texoffsets
-        sprite.rescale = self.rescale
-        sprite.scale_speed = self.scale_speed
-        sprite.rotations_3d = self.rotations_3d
-        sprite.rotations_speed_3d = self.rotations_speed_3d
-        sprite.color = self.color
-
-        sprite.alpha = self.alpha
-        sprite.anm = self.anm
-        sprite._rendering_data = self._rendering_data
-
-        return sprite
-
-
-    def update(self):
-        self.frame += 1
-
-        if self.rotations_speed_3d != (0., 0., 0.):
-            ax, ay, az = self.rotations_3d
-            sax, say, saz = self.rotations_speed_3d
-            self.rotations_3d = ax + sax, ay + say, az + saz
-            self.changed = True
-        elif self.rotation_interpolator:
-            self.rotation_interpolator.update(self.frame)
-            self.rotations_3d = self.rotation_interpolator.values
-            self.changed = True
-
-        if self.scale_speed != (0., 0.):
-            rx, ry = self.rescale
-            rsx, rsy = self.scale_speed
-            self.rescale = rx + rsx, ry + rsy
-            self.changed = True
-
-        if self.fade_interpolator:
-            self.fade_interpolator.update(self.frame)
-            self.alpha = self.fade_interpolator.values[0]
-            self.changed = True
-
-        if self.scale_interpolator:
-            self.scale_interpolator.update(self.frame)
-            self.rescale = self.scale_interpolator.values
-            self.changed = True
-
-        if self.offset_interpolator:
-            self.offset_interpolator.update(self.frame)
-            self.dest_offset = self.offset_interpolator.values
-            self.changed = True
-
-        if self.color_interpolator:
-            self.color_interpolator.update(self.frame)
-            self.color = self.color_interpolator.values
-            self.changed = True
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pytouhou/game/sprite.pyx	Wed Dec 18 18:15:45 2013 +0100
@@ -0,0 +1,226 @@
+# -*- encoding: utf-8 -*-
+##
+## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published
+## by the Free Software Foundation; version 3 only.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+
+cdef class Sprite:
+    def __init__(self, width_override=0, height_override=0):
+        self.anm = None
+        self.removed = False
+        self.changed = True
+        self.visible = True
+
+        self.width_override = width_override
+        self.height_override = height_override
+        self.angle = 0
+        self.force_rotation = False
+
+        self.scale_interpolator = None
+        self.fade_interpolator = None
+        self.offset_interpolator = None
+        self.rotation_interpolator = None
+        self.color_interpolator = None
+
+        self.automatic_orientation = False
+
+        self.blendfunc = 0 # 0 = Normal, 1 = saturate #TODO: proper constants
+
+        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.]
+        self._scale_speed[:] = [0., 0.]
+        self._rotations_3d[:] = [0., 0., 0.]
+        self._rotations_speed_3d[:] = [0., 0., 0.]
+        self.corner_relative_placement = False
+        self.frame = 0
+
+        # Cython treats unsigned char* variables as bytes, so we can’t use
+        # slicing here.
+        for i in xrange(4):
+            self._color[i] = 255
+
+        self._rendering_data = None
+
+
+    property scale_speed:
+        def __get__(self):
+            return (self._scale_speed[0], self._scale_speed[1])
+        def __set__(self, value):
+            self._scale_speed[:] = [value[0], value[1]]
+
+    property texoffsets:
+        def __get__(self):
+            return (self._texoffsets[0], self._texoffsets[1])
+        def __set__(self, value):
+            self._texoffsets[:] = [value[0], value[1]]
+
+    property rescale:
+        def __get__(self):
+            return (self._rescale[0], self._rescale[1])
+        def __set__(self, value):
+            self._rescale[:] = [value[0], value[1]]
+
+    property dest_offset:
+        def __get__(self):
+            return (self._dest_offset[0], self._dest_offset[1], self._dest_offset[2])
+        def __set__(self, value):
+            self._dest_offset[:] = [value[0], value[1], value[2]]
+
+    property rotations_speed_3d:
+        def __get__(self):
+            return (self._rotations_speed_3d[0], self._rotations_speed_3d[1], self._rotations_speed_3d[2])
+        def __set__(self, value):
+            self._rotations_speed_3d[:] = [value[0], value[1], value[2]]
+
+    property rotations_3d:
+        def __get__(self):
+            return (self._rotations_3d[0], self._rotations_3d[1], self._rotations_3d[2])
+        def __set__(self, value):
+            self._rotations_3d[:] = [value[0], value[1], value[2]]
+
+    property color:
+        def __get__(self):
+            return (self._color[0], self._color[1], self._color[2])
+        def __set__(self, value):
+            self._color[0] = value[0]
+            self._color[1] = value[1]
+            self._color[2] = value[2]
+
+    property alpha:
+        def __get__(self):
+            return self._color[3]
+        def __set__(self, value):
+            self._color[3] = value
+
+    property texcoords:
+        def __get__(self):
+            return (self._texcoords[0], self._texcoords[1], self._texcoords[2], self._texcoords[3])
+        def __set__(self, value):
+            self._texcoords[:] = [value[0], value[1], value[2], value[3]]
+
+
+    cpdef fade(self, unsigned long duration, alpha, formula=None):
+        self.fade_interpolator = Interpolator((self._color[3],), self.frame,
+                                              (alpha,), self.frame + duration,
+                                              formula)
+
+
+    cpdef scale_in(self, unsigned long duration, sx, sy, formula=None):
+        self.scale_interpolator = Interpolator(self.rescale, self.frame,
+                                               (sx, sy), self.frame + duration,
+                                               formula)
+
+
+    cpdef move_in(self, unsigned long duration, x, y, z, formula=None):
+        self.offset_interpolator = Interpolator(self.dest_offset, self.frame,
+                                                (x, y, z), self.frame + duration,
+                                                formula)
+
+
+    cpdef rotate_in(self, unsigned long duration, rx, ry, rz, formula=None):
+        self.rotation_interpolator = Interpolator(self.rotations_3d, self.frame,
+                                                  (rx, ry, rz), self.frame + duration,
+                                                  formula)
+
+
+    cpdef change_color_in(self, unsigned long duration, r, g, b, formula=None):
+        self.color_interpolator = Interpolator(self.color, self.frame,
+                                               (r, g, b), self.frame + duration,
+                                               formula)
+
+
+    cpdef update_orientation(self, double angle_base=0., bint force_rotation=False):
+        if (self.angle != angle_base or self.force_rotation != force_rotation):
+            self.angle = angle_base
+            self.force_rotation = force_rotation
+            self.changed = True
+
+
+    cpdef Sprite copy(self):
+        sprite = Sprite(self.width_override, self.height_override)
+
+        sprite.blendfunc = self.blendfunc
+        sprite.frame = self.frame
+        sprite.angle = self.angle
+
+        sprite.removed = self.removed
+        sprite.changed = self.changed
+        sprite.visible = self.visible
+        sprite.force_rotation = self.force_rotation
+        sprite.automatic_orientation = self.automatic_orientation
+        sprite.allow_dest_offset = self.allow_dest_offset
+        sprite.mirrored = self.mirrored
+        sprite.corner_relative_placement = self.corner_relative_placement
+
+        sprite.scale_interpolator = self.scale_interpolator
+        sprite.fade_interpolator = self.fade_interpolator
+        sprite.offset_interpolator = self.offset_interpolator
+        sprite.rotation_interpolator = self.rotation_interpolator
+        sprite.color_interpolator = self.color_interpolator
+
+        sprite.texcoords = self.texcoords
+        sprite.dest_offset = self.dest_offset
+        sprite.texoffsets = self.texoffsets
+        sprite.rescale = self.rescale
+        sprite.scale_speed = self.scale_speed
+        sprite.rotations_3d = self.rotations_3d
+        sprite.rotations_speed_3d = self.rotations_speed_3d
+        sprite.color = self.color
+
+        sprite.alpha = self.alpha
+        sprite.anm = self.anm
+        sprite._rendering_data = self._rendering_data
+
+        return sprite
+
+
+    cpdef update(self):
+        self.frame += 1
+
+        sax, say, saz = self._rotations_speed_3d[0], self._rotations_speed_3d[1], self._rotations_speed_3d[2] #XXX
+        if sax or say or saz:
+            ax, ay, az = self._rotations_3d[0], self._rotations_3d[1], self._rotations_3d[2] #XXX
+            self._rotations_3d[:] = [ax + sax, ay + say, az + saz]
+            self.changed = True
+        elif self.rotation_interpolator:
+            self.rotation_interpolator.update(self.frame)
+            self.rotations_3d = self.rotation_interpolator.values
+            self.changed = True
+
+        rsx, rsy = self._scale_speed[0], self._scale_speed[1] #XXX
+        if rsx or rsy:
+            rx, ry = self._rescale[0], self._rescale[1] #XXX
+            self._rescale[:] = [rx + rsx, ry + rsy]
+            self.changed = True
+
+        if self.fade_interpolator:
+            self.fade_interpolator.update(self.frame)
+            self._color[3] = self.fade_interpolator.values[0]
+            self.changed = True
+
+        if self.scale_interpolator:
+            self.scale_interpolator.update(self.frame)
+            self.rescale = self.scale_interpolator.values
+            self.changed = True
+
+        if self.offset_interpolator:
+            self.offset_interpolator.update(self.frame)
+            self.dest_offset = self.offset_interpolator.values
+            self.changed = True
+
+        if self.color_interpolator:
+            self.color_interpolator.update(self.frame)
+            self.color = self.color_interpolator.values
+            self.changed = True