# HG changeset patch # User Emmanuel Gil Peyrot # Date 1379349732 -7200 # Node ID 1c891c71cf223724a83b2a8103c5cc2a24ceba37 # Parent 8038f1957b713cb8c854272e5d775910494099d3 Cythonize pytouhou.game.text. diff --git a/pytouhou/game/game.pxd b/pytouhou/game/game.pxd --- a/pytouhou/game/game.pxd +++ b/pytouhou/game/game.pxd @@ -1,5 +1,6 @@ from pytouhou.game.effect cimport Effect from pytouhou.game.player cimport Player +from pytouhou.game.text cimport Text, NativeText cdef class Game: cdef public long width, height, nb_bullets_max, stage, rank, difficulty, difficulty_counter, difficulty_min, difficulty_max, frame, last_keystate @@ -29,9 +30,9 @@ cdef class Game: cpdef new_particle(self, pos, long anim, long amp, long number=*, bint reverse=*, long duration=*) cpdef new_enemy(self, pos, life, instr_type, bonus_dropped, die_score) cpdef new_msg(self, sub) - cdef new_label(self, pos, str text) - cpdef new_native_text(self, pos, text, align=*) - cpdef new_hint(self, hint) + cdef Text new_label(self, tuple pos, bytes text) + cpdef NativeText new_native_text(self, tuple pos, unicode text, align=*) + cpdef Text new_hint(self, hint) cpdef new_face(self, side, effect) cpdef run_iter(self, long keystate) cdef void update_background(self) except * diff --git a/pytouhou/game/game.pyx b/pytouhou/game/game.pyx --- a/pytouhou/game/game.pyx +++ b/pytouhou/game/game.pyx @@ -20,7 +20,6 @@ from pytouhou.game.enemy cimport Enemy from pytouhou.game.item cimport Item from pytouhou.game.effect cimport Particle from pytouhou.game.laser cimport Laser, PlayerLaser -from pytouhou.game.text import Text, NativeText from pytouhou.game.face import Face @@ -229,19 +228,19 @@ cdef class Game: self.msg_runner.run_iteration() - cdef new_label(self, pos, str text): + cdef Text new_label(self, tuple pos, bytes text): label = Text(pos, self.interface.ascii_anm, text=text, xspacing=8, shift=48) label.set_timeout(60, effect='move') self.labels.append(label) return label - cpdef new_native_text(self, pos, text, align='left'): + cpdef NativeText new_native_text(self, tuple pos, unicode text, align='left'): label = NativeText(pos, text, shadow=True, align=align) return label - cpdef new_hint(self, hint): + cpdef Text new_hint(self, hint): pos = hint['Pos'] #TODO: Scale @@ -249,7 +248,7 @@ cdef class Game: label = Text(pos, self.interface.ascii_anm, text=hint['Text'], align=hint['Align']) label.set_timeout(hint['Time']) label.set_alpha(hint['Alpha']) - label.set_color(hint['Color'], text=False) + label.set_color(None, hint['Color']) #XXX self.labels.append(label) return label diff --git a/pytouhou/game/item.pyx b/pytouhou/game/item.pyx --- a/pytouhou/game/item.pyx +++ b/pytouhou/game/item.pyx @@ -94,7 +94,7 @@ cdef class Item(Element): player_state.power = 128 for level in (8, 16, 32, 48, 64, 96): if old_power < level and player_state.power >= level: - label = self._game.new_label((self.x, self.y), ':') # Actually a “PowerUp” character. + label = self._game.new_label((self.x, self.y), b':') # Actually a “PowerUp” character. color = 'blue' label.set_color(color) labeled = True diff --git a/pytouhou/game/text.pxd b/pytouhou/game/text.pxd new file mode 100644 --- /dev/null +++ b/pytouhou/game/text.pxd @@ -0,0 +1,81 @@ +from pytouhou.game.element cimport Element +from pytouhou.game.sprite cimport Sprite +from pytouhou.utils.interpolator cimport Interpolator + +cdef class Glyph(Element): + pass + + +cdef class Widget(Element): + cdef public object update + cdef public bint changed + + cdef unsigned long frame + cdef object back_anm + + #def update(self) + + +cdef class GlyphCollection(Widget): + cdef Sprite ref_sprite + cdef object anm + cdef list glyphes + cdef long xspacing + + cpdef set_length(self, unsigned long length) + cpdef set_sprites(self, list sprite_indexes) + cpdef set_color(self, text=*, color=*) + cpdef set_alpha(self, unsigned char alpha) + + +cdef class Text(GlyphCollection): + cdef bytes text + cdef long shift, timeout, duration, start + cdef Interpolator fade_interpolator + cdef unsigned char alpha + + cpdef set_text(self, bytes text) + #def timeout_update(self) + #def move_timeout_update(self) + #def fadeout_timeout_update(self) + cdef void fade(self, unsigned long duration, unsigned char alpha, formula=*) except * + cpdef set_timeout(self, long timeout, str effect=*, long duration=*, long start=*) + + +cdef class Counter(GlyphCollection): + cdef long value + + cpdef set_value(self, long value) + + +cdef class Gauge(Element): + cdef public long value, max_length, maximum + + cpdef set_value(self, long value) + cpdef update(self) + + +cdef class NativeText(Element): + cdef public object update + + cdef unicode text + cdef long width, height + cdef unsigned char alpha + cdef bint shadow + cdef bytes align #TODO: use a proper enum. + cdef unsigned long frame, timeout, duration + cdef long start + cdef double to[2], end[2] + cdef list gradient + cdef Interpolator fade_interpolator, offset_interpolator + cdef object texture + + #def normal_update(self) + #def timeout_update(self) + #def move_timeout_update(self) + #def move_ex_timeout_update(self) + #def fadeout_timeout_update(self) + + cdef void fade(self, unsigned long duration, unsigned char alpha, formula=*) except * + cdef void move_in(self, unsigned long duration, double x, double y, formula=*) except * + cpdef set_timeout(self, long timeout, str effect=*, long duration=*, long start=*, to=*, end=*) diff --git a/pytouhou/game/text.py b/pytouhou/game/text.py --- a/pytouhou/game/text.py +++ b/pytouhou/game/text.py @@ -36,12 +36,12 @@ class Widget(Element): self.sprite = Sprite() self.anmrunner = ANMRunner(back_anm, back_script, self.sprite) - def update(self): - self.frame += 1 + def normal_update(self): if self.changed: - if self.anmrunner and not self.anmrunner.run_frame(): + if self.anmrunner is not None and not self.anmrunner.run_frame(): self.anmrunner = None self.changed = False + self.frame += 1 @@ -60,19 +60,16 @@ class GlyphCollection(Widget): self.ref_sprite.corner_relative_placement = True #TODO: perhaps not right - @property - def objects(self): - return [self] + self.glyphes - - def set_length(self, length): current_length = len(self.glyphes) if length > current_length: - self.glyphes.extend(Glyph(self.ref_sprite.copy(), - (self.x + self.xspacing * i, self.y)) - for i in range(current_length, length)) + self.glyphes.extend([Glyph(self.ref_sprite.copy(), + (self.x + self.xspacing * i, self.y)) + for i in range(current_length, length)]) + self.objects = [self] + self.glyphes elif length < current_length: self.glyphes[:] = self.glyphes[:length] + self.objects = [self] + self.glyphes def set_sprites(self, sprite_indexes): @@ -83,12 +80,14 @@ class GlyphCollection(Widget): glyph.sprite.changed = True - def set_color(self, color, text=True): - if text: + def set_color(self, text=None, color=None): + if text is not None: colors = {'white': (255, 255, 255), 'yellow': (255, 255, 0), 'blue': (192, 192, 255), 'darkblue': (160, 128, 255), 'purple': (224, 128, 255), 'red': (255, 64, 0)} - color = colors[color] + color = colors[text] + else: + assert color is not None self.ref_sprite.color = color for glyph in self.glyphes: glyph.sprite.color = color @@ -106,7 +105,7 @@ class Text(GlyphCollection): xspacing=14, shift=21, back_script=22, align='left'): GlyphCollection.__init__(self, pos, ascii_anm, back_anm, xspacing=xspacing, back_script=back_script) - self.text = '' + self.text = b'' self.shift = shift if align == 'center': @@ -129,7 +128,7 @@ class Text(GlyphCollection): def timeout_update(self): - GlyphCollection.update(self) + GlyphCollection.normal_update(self) if self.frame == self.timeout: self.removed = True @@ -144,9 +143,9 @@ class Text(GlyphCollection): def fadeout_timeout_update(self): if self.frame >= self.start: if self.frame == self.start: - self.fade(self.duration, 255, lambda x: x) + self.fade(self.duration, 255) elif self.frame == self.timeout - self.duration: - self.fade(self.duration, 0, lambda x: x) + self.fade(self.duration, 0) self.fade_interpolator.update(self.frame) self.alpha = int(self.fade_interpolator.values[0]) for glyph in self.glyphes: @@ -155,7 +154,7 @@ class Text(GlyphCollection): self.timeout_update() - def fade(self, duration, alpha, formula): + def fade(self, duration, alpha, formula=None): self.fade_interpolator = Interpolator((self.alpha,), self.frame, (alpha,), self.frame + duration, formula) @@ -225,12 +224,12 @@ class Gauge(Element): self.sprite.visible = False else: self.sprite.visible = True - if self.anmrunner and not self.anmrunner.run_frame(): + if self.anmrunner is not None and not self.anmrunner.run_frame(): self.anmrunner = None -class NativeText(object): +class NativeText(Element): def __init__(self, pos, text, gradient=None, alpha=255, shadow=False, align='left'): self.removed = False self.x, self.y = pos @@ -265,9 +264,9 @@ class NativeText(object): def move_ex_timeout_update(self): if self.frame >= self.start: if self.frame == self.start: - self.move_in(self.duration, self.to[0], self.to[1], lambda x: x) + self.move_in(self.duration, self.to[0], self.to[1]) elif self.frame == self.timeout - self.duration: - self.move_in(self.duration, self.end[0], self.end[1], lambda x: x) + self.move_in(self.duration, self.end[0], self.end[1]) if self.offset_interpolator: self.offset_interpolator.update(self.frame) self.x, self.y = self.offset_interpolator.values @@ -277,21 +276,21 @@ class NativeText(object): def fadeout_timeout_update(self): if self.frame >= self.start: if self.frame == self.start: - self.fade(self.duration, 255, lambda x: x) + self.fade(self.duration, 255) elif self.frame == self.timeout - self.duration: - self.fade(self.duration, 0, lambda x: x) + self.fade(self.duration, 0) self.fade_interpolator.update(self.frame) self.alpha = int(self.fade_interpolator.values[0]) self.timeout_update() - def fade(self, duration, alpha, formula): + def fade(self, duration, alpha, formula=None): self.fade_interpolator = Interpolator((self.alpha,), self.frame, (alpha,), self.frame + duration, formula) - def move_in(self, duration, x, y, formula): + def move_in(self, duration, x, y, formula=None): self.offset_interpolator = Interpolator((self.x, self.y), self.frame, (x, y), self.frame + duration, formula) @@ -305,8 +304,8 @@ class NativeText(object): self.update = self.move_ex_timeout_update self.duration = duration self.start = start - self.to = to - self.end = end + self.to[:] = [to[0], to[1]] + self.end[:] = [end[0], end[1]] elif effect == 'fadeout': self.alpha = 0 self.update = self.fadeout_timeout_update diff --git a/pytouhou/ui/gamerenderer.pyx b/pytouhou/ui/gamerenderer.pyx --- a/pytouhou/ui/gamerenderer.pyx +++ b/pytouhou/ui/gamerenderer.pyx @@ -22,6 +22,7 @@ from pytouhou.lib.opengl cimport \ GL_SCISSOR_TEST, GL_DEPTH_BUFFER_BIT) from pytouhou.utils.maths cimport perspective, setup_camera, ortho_2d +from pytouhou.game.text cimport NativeText, GlyphCollection from .shaders.eosd import GameShader, BackgroundShader, PassthroughShader from collections import namedtuple @@ -177,6 +178,8 @@ cdef class GameRenderer(Renderer): cdef void render_text(self, texts): + cdef NativeText label + if self.font_manager is None: return @@ -201,6 +204,8 @@ cdef class GameRenderer(Renderer): cdef void render_interface(self, interface, game_boss): + cdef GlyphCollection label + elements = [] if self.use_fixed_pipeline: diff --git a/pytouhou/ui/texture.pyx b/pytouhou/ui/texture.pyx --- a/pytouhou/ui/texture.pyx +++ b/pytouhou/ui/texture.pyx @@ -21,6 +21,7 @@ from pytouhou.lib.opengl cimport \ from pytouhou.lib.sdl cimport load_png, create_rgb_surface, Font from pytouhou.formats.thtx import Texture #TODO: perhaps define that elsewhere? +from pytouhou.game.text cimport NativeText import os @@ -60,8 +61,10 @@ cdef class FontManager: def load(self, label_list): + cdef NativeText label + for label in label_list: - if not hasattr(label, 'texture'): + if label.texture is None: surface = self.font.render(label.text) label.width, label.height = surface.surface.w, surface.surface.h