comparison 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
comparison
equal deleted inserted replaced
68:a2459defd4b6 69:a142e57218a0
1 # -*- encoding: utf-8 -*-
2 ##
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com>
4 ##
5 ## This program is free software; you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published
7 ## by the Free Software Foundation; version 3 only.
8 ##
9 ## This program is distributed in the hope that it will be useful,
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ## GNU General Public License for more details.
13 ##
14
15
16 from random import randrange
17
18 from pytouhou.utils.helpers import get_logger
19 from pytouhou.vm.common import MetaRegistry, instruction
20
21 logger = get_logger(__name__)
22
23
24 class ANMRunner(object):
25 __metaclass__ = MetaRegistry
26 __slots__ = ('_anm_wrapper', '_sprite', '_running',
27 'script', 'instruction_pointer', 'frame')
28
29
30 def __init__(self, anm_wrapper, script_id, sprite):
31 self._anm_wrapper = anm_wrapper
32 self._sprite = sprite
33 self._running = True
34
35 anm, self.script = anm_wrapper.get_script(script_id)
36 self.frame = 0
37 self.instruction_pointer = 0
38 pass
39
40
41 def run_frame(self):
42 if self._sprite._removed:
43 return False
44
45 while self._running:
46 try:
47 frame, instr_type, args = self.script[self.instruction_pointer]
48 except IndexError:
49 return False
50
51 if frame > self.frame:
52 break
53 else:
54 self.instruction_pointer += 1
55
56 if frame == self.frame:
57 try:
58 callback = self._handlers[instr_type]
59 except KeyError:
60 logger.warn('unhandled opcode %d (args: %r)', instr_type, args)
61 else:
62 callback(self, *args)
63 self._sprite._changed = True
64 self.frame += 1
65 return self._running
66
67
68 @instruction(0)
69 def remove(self):
70 self._sprite._removed = True
71 self._running = True
72
73
74 @instruction(1)
75 def load_sprite(self, sprite_index):
76 self._sprite.anm, self._sprite.texcoords = self._anm_wrapper.get_sprite(sprite_index)
77
78
79 @instruction(2)
80 def set_scale(self, sx, sy):
81 self._sprite.rescale = sx, sy
82
83
84 @instruction(3)
85 def set_alpha(self, alpha):
86 self._sprite.alpha = alpha % 256 #TODO
87
88
89 @instruction(4)
90 def set_color(self, b, g, r):
91 self._sprite.color = (r, g, b)
92
93
94 @instruction(5)
95 def jump(self, instruction_pointer):
96 #TODO: is that really how it works?
97 self.instruction_pointer = instruction_pointer
98 self.frame = self.script[self.instruction_pointer][0]
99
100
101 @instruction(7)
102 def toggle_mirrored(self):
103 self._sprite.mirrored = not self._sprite.mirrored
104
105
106 @instruction(9)
107 def set_rotations_3d(self, rx, ry, rz):
108 self._sprite.rotations_3d = rx, ry, rz
109
110
111 @instruction(10)
112 def set_rotations_speed_3d(self, srx, sry, srz):
113 self._sprite.rotations_speed_3d = srx, sry, srz
114
115
116 @instruction(11)
117 def set_scale_speed(self, ssx, ssy):
118 self._sprite.scale_speed = ssx, ssy
119
120
121 @instruction(16)
122 def load_random_sprite(self, min_idx, amp):
123 #TODO: use the game's PRNG?
124 self.load_sprite(min_idx + randrange(amp))
125
126
127 @instruction(23)
128 def set_corner_relative_placement(self):
129 self._sprite.corner_relative_placement = True #TODO
130
131
132 @instruction(27)
133 def shift_texture_x(self, dx):
134 tox, toy = self._sprite.texoffsets
135 self._sprite.texoffsets = tox + dx, toy
136
137
138 @instruction(28)
139 def shift_texture_y(self, dy):
140 tox, toy = self._sprite.texoffsets
141 self._sprite.texoffsets = tox, toy + dy
142
143
144 @instruction(15)
145 @instruction(21) #TODO
146 def keep_still(self):
147 self._running = False
148