Mercurial > touhou
diff pytouhou/vm/anmrunner.py @ 69:a142e57218a0
Refactor. Move VMs to pytouhou.vm.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Sat, 27 Aug 2011 10:58:54 +0200 |
parents | |
children | a03d7a94b997 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/pytouhou/vm/anmrunner.py @@ -0,0 +1,148 @@ +# -*- 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. +## + + +from random import randrange + +from pytouhou.utils.helpers import get_logger +from pytouhou.vm.common import MetaRegistry, instruction + +logger = get_logger(__name__) + + +class ANMRunner(object): + __metaclass__ = MetaRegistry + __slots__ = ('_anm_wrapper', '_sprite', '_running', + 'script', 'instruction_pointer', 'frame') + + + def __init__(self, anm_wrapper, script_id, sprite): + self._anm_wrapper = anm_wrapper + self._sprite = sprite + self._running = True + + anm, self.script = anm_wrapper.get_script(script_id) + self.frame = 0 + self.instruction_pointer = 0 + pass + + + def run_frame(self): + if self._sprite._removed: + return False + + while self._running: + try: + frame, instr_type, args = self.script[self.instruction_pointer] + except IndexError: + return False + + if frame > self.frame: + break + else: + self.instruction_pointer += 1 + + if frame == self.frame: + try: + callback = self._handlers[instr_type] + except KeyError: + logger.warn('unhandled opcode %d (args: %r)', instr_type, args) + else: + callback(self, *args) + self._sprite._changed = True + self.frame += 1 + return self._running + + + @instruction(0) + def remove(self): + self._sprite._removed = True + self._running = True + + + @instruction(1) + def load_sprite(self, sprite_index): + self._sprite.anm, self._sprite.texcoords = self._anm_wrapper.get_sprite(sprite_index) + + + @instruction(2) + def set_scale(self, sx, sy): + self._sprite.rescale = sx, sy + + + @instruction(3) + def set_alpha(self, alpha): + self._sprite.alpha = alpha % 256 #TODO + + + @instruction(4) + def set_color(self, b, g, r): + self._sprite.color = (r, g, b) + + + @instruction(5) + def jump(self, instruction_pointer): + #TODO: is that really how it works? + self.instruction_pointer = instruction_pointer + self.frame = self.script[self.instruction_pointer][0] + + + @instruction(7) + def toggle_mirrored(self): + self._sprite.mirrored = not self._sprite.mirrored + + + @instruction(9) + def set_rotations_3d(self, rx, ry, rz): + self._sprite.rotations_3d = rx, ry, rz + + + @instruction(10) + def set_rotations_speed_3d(self, srx, sry, srz): + self._sprite.rotations_speed_3d = srx, sry, srz + + + @instruction(11) + def set_scale_speed(self, ssx, ssy): + self._sprite.scale_speed = ssx, ssy + + + @instruction(16) + def load_random_sprite(self, min_idx, amp): + #TODO: use the game's PRNG? + self.load_sprite(min_idx + randrange(amp)) + + + @instruction(23) + def set_corner_relative_placement(self): + self._sprite.corner_relative_placement = True #TODO + + + @instruction(27) + def shift_texture_x(self, dx): + tox, toy = self._sprite.texoffsets + self._sprite.texoffsets = tox + dx, toy + + + @instruction(28) + def shift_texture_y(self, dy): + tox, toy = self._sprite.texoffsets + self._sprite.texoffsets = tox, toy + dy + + + @instruction(15) + @instruction(21) #TODO + def keep_still(self): + self._running = False +