comparison pytouhou/vm/eclrunner.py @ 291:f6b8483a990d

Refactor a bit and fix Rumia's disparition.
author Thibaut Girka <thib@sitedethib.com>
date Wed, 15 Feb 2012 19:20:06 +0100
parents 981d1893d564
children 2a60642e8892
comparison
equal deleted inserted replaced
290:18e4ed141dd8 291:f6b8483a990d
147 self.instruction_pointer = 0 147 self.instruction_pointer = 0
148 148
149 self.stack = [] 149 self.stack = []
150 150
151 151
152 def switch_to_sub(self, sub):
153 self.frame = 0
154 self.sub = sub
155 self.instruction_pointer = 0
156
157
152 def handle_callbacks(self): 158 def handle_callbacks(self):
153 #TODO: implement missing callbacks and clean up! 159 #TODO: implement missing callbacks and clean up!
154 enm = self._enemy 160 enm = self._enemy
155 if enm.life <= 0 and enm.touchable: 161 if enm.life <= 0 and enm.touchable:
156 death_flags = enm.death_flags & 7 162 death_flags = enm.death_flags & 7
157 163
158 enm.die_anim() 164 enm.die_anim()
159 165
160 if death_flags < 4: 166 if death_flags < 4:
161 if enm._bonus_dropped >= 0: 167 if enm._bonus_dropped > -1:
162 enm.drop_particles(7, 0) 168 enm.drop_particles(7, 0)
163 self._game.drop_bonus(enm.x, enm.y, enm._bonus_dropped) 169 self._game.drop_bonus(enm.x, enm.y, enm._bonus_dropped)
164 elif enm._bonus_dropped == -1: 170 elif enm._bonus_dropped == -1:
165 if self._game.deaths_count % 3 == 0: 171 if self._game.deaths_count % 3 == 0:
166 enm.drop_particles(10, 0) 172 enm.drop_particles(10, 0)
184 #TODO: disable boss mode 190 #TODO: disable boss mode
185 enm.damageable = False 191 enm.damageable = False
186 enm.life = 1 192 enm.life = 1
187 enm.death_flags = 0 193 enm.death_flags = 0
188 194
189 if death_flags != 0 and enm.death_callback >= 0: 195 if death_flags != 0 and enm.death_callback > -1:
190 self.frame = 0 196 self.switch_to_sub(enm.death_callback)
191 self.sub = enm.death_callback
192 self.instruction_pointer = 0
193 enm.death_callback = -1 197 enm.death_callback = -1
194 elif enm.life <= enm.low_life_trigger and enm.low_life_callback >= 0: 198 elif enm.life <= enm.low_life_trigger and enm.low_life_callback > -1:
195 self.frame = 0 199 self.switch_to_sub(enm.low_life_callback)
196 self.sub = enm.low_life_callback
197 self.instruction_pointer = 0
198 enm.low_life_callback = -1 200 enm.low_life_callback = -1
199 elif enm.timeout and enm.frame == enm.timeout: 201 elif enm.timeout != -1 and enm.frame == enm.timeout:
200 enm.frame = 0 202 enm.frame = 0
201 if enm.timeout_callback >= 0: 203 if enm.timeout_callback > -1:
202 self.frame = 0 204 self.switch_to_sub(enm.timeout_callback)
203 self.sub = enm.timeout_callback
204 self.instruction_pointer = 0
205 enm.timeout_callback = -1 205 enm.timeout_callback = -1
206 elif enm.touchable: 206 elif enm.touchable:
207 enm.life = 0 207 enm.life = 0
208 elif enm.death_callback >= 0: 208 elif enm.death_callback > -1:
209 self.frame = 0 209 self.switch_to_sub(enm.death_callback)
210 self.sub = enm.death_callback
211 self.instruction_pointer = 0
212 enm.death_callback = -1 210 enm.death_callback = -1
213 enm.timeout = -1 #TODO: check 211 enm.timeout = -1 #TODO: check
214 else: 212 else:
215 raise Exception('What the hell, man!') 213 raise Exception('What the hell, man!')
216
217 214
218 def run_iteration(self): 215 def run_iteration(self):
219 # First, if enemy is dead, return 216 # First, if enemy is dead, return
220 if self._enemy._removed: 217 if self._enemy._removed:
221 return False 218 return False
233 if frame > self.frame: 230 if frame > self.frame:
234 break 231 break
235 else: 232 else:
236 self.instruction_pointer += 1 233 self.instruction_pointer += 1
237 234
238
239 #TODO: skip bad ranks
240 if not rank_mask & (0x100 << self._game.rank): 235 if not rank_mask & (0x100 << self._game.rank):
241 continue 236 continue
242
243 237
244 if frame == self.frame: 238 if frame == self.frame:
245 try: 239 try:
246 callback = self._handlers[instr_type] 240 callback = self._handlers[instr_type]
247 except KeyError: 241 except KeyError:
479 473
480 @instruction(35) 474 @instruction(35)
481 def call(self, sub, param1, param2): 475 def call(self, sub, param1, param2):
482 self.stack.append((self.sub, self.frame, self.instruction_pointer, 476 self.stack.append((self.sub, self.frame, self.instruction_pointer,
483 list(self.variables), self.comparison_reg)) 477 list(self.variables), self.comparison_reg))
484 self.sub = sub
485 self.frame = 0
486 self.instruction_pointer = 0
487 self.variables[0] = param1 478 self.variables[0] = param1
488 self.variables[4] = param2 479 self.variables[4] = param2
480 self.switch_to_sub(sub)
489 481
490 482
491 @instruction(36) 483 @instruction(36)
492 def ret(self): 484 def ret(self):
493 self.sub, self.frame, self.instruction_pointer, self.variables, self.comparison_reg = self.stack.pop() 485 self.sub, self.frame, self.instruction_pointer, self.variables, self.comparison_reg = self.stack.pop()
918 self._enemy.death_callback = sub 910 self._enemy.death_callback = sub
919 911
920 912
921 @instruction(109) 913 @instruction(109)
922 def memory_write(self, value, index): 914 def memory_write(self, value, index):
923 #TODO
924 #XXX: this is a hack to display bosses although we don't handle MSG :)
925 if index == 0: 915 if index == 0:
926 self._enemy.boss_callback = value 916 self._enemy.boss_callback = value
927 else: 917 else:
928 raise Exception #TODO 918 raise Exception #TODO
929 919
942 self._enemy.frame = value 932 self._enemy.frame = value
943 933
944 934
945 @instruction(113) 935 @instruction(113)
946 def set_low_life_trigger(self, value): 936 def set_low_life_trigger(self, value):
947 #XXX: this instruction takes 100 frames to fill the enemy's life bar 937 #TODO: the enemy's life bar fills in 100 frames.
948 self.frame -= 100 938 # During those frames, the ECL doesn't seem to be executed.
939 # However, the ECL isn't directly paused by this instruction itself.
949 self._enemy.low_life_trigger = value 940 self._enemy.low_life_trigger = value
950 941
951 942
952 @instruction(114) 943 @instruction(114)
953 def set_low_life_callback(self, sub): 944 def set_low_life_callback(self, sub):