comparison pytouhou/game/eclrunner.py @ 47:1f1793e7ec8e

Handle a few more opcodes
author Thibaut Girka <thib@sitedethib.com>
date Mon, 22 Aug 2011 10:49:59 +0200
parents 7195aaf95f6e
children 8353c33d53d4
comparison
equal deleted inserted replaced
46:25ca15f714ad 47:1f1793e7ec8e
1 class ECLRunner(object): 1 class ECLRunner(object):
2 def __init__(self, ecl, sub, frame=0, instruction_pointer=0, implementation=None): 2 def __init__(self, ecl, sub, frame=0, instruction_pointer=0, implementation=None):
3 self.ecl = ecl 3 self.ecl = ecl
4 4
5 self.counters = {} 5 self.variables = [0, 0, 0, 0,
6 self.implementation = {4: (self.set_counter), 6 0., 0., 0., 0.,
7 2: (self.relative_jump), 7 0, 0, 0, 0]
8 3: (self.relative_jump_ex)}
9 if implementation:
10 self.implementation.update(implementation)
11
12 self.sub = sub 8 self.sub = sub
13 self.frame = frame 9 self.frame = frame
14 self.instruction_pointer = instruction_pointer 10 self.instruction_pointer = instruction_pointer
15 11
12 self.stack = []
16 13
17 def set_counter(self, counter_id, count): 14 self.implementation = {4: self.set_variable,
18 self.counters[counter_id & 0xffff] = count 15 2: self.relative_jump,
16 3: self.relative_jump_ex,
17 35: self.call,
18 36: self.ret,
19 109: self.memory_write}
20 if implementation:
21 self.implementation.update(implementation)
22
23
24 def memory_write(self, value, index):
25 #TODO
26 #XXX: this is a hack to display bosses although we don't handle MSG :)
27 if index == 0:
28 self.sub = value
29 self.frame = 0
30 self.instruction_pointer = 0
31
32
33 def call(self, sub, param1, param2):
34 self.stack.append((self.sub, self.frame, self.instruction_pointer,
35 self.variables))
36 self.sub = sub
37 self.frame = 0
38 self.instruction_pointer = 0
39 self.variables = [param1, 0, 0, 0,
40 param2, 0., 0., 0.,
41 0, 0, 0, 0]
42
43
44 def ret(self):
45 self.sub, self.frame, self.instruction_pointer, self.variables = self.stack.pop()
46
47
48
49 def set_variable(self, variable_id, value):
50 #TODO: -10013 and beyond!
51 self.variables[-10000-variable_id] = value
19 52
20 53
21 def relative_jump(self, frame, instruction_pointer): 54 def relative_jump(self, frame, instruction_pointer):
22 self.frame, self.instruction_pointer = frame, instruction_pointer 55 self.frame, self.instruction_pointer = frame, instruction_pointer
23 56
24 57
25 def relative_jump_ex(self, frame, instruction_pointer, counter_id): 58 def relative_jump_ex(self, frame, instruction_pointer, variable_id):
26 if self.counters[counter_id & 0xffff]: 59 if self.variables[-10000-variable_id]:
27 self.counters[counter_id & 0xffff] -= 1 60 self.variables[-10000-variable_id] -= 1
28 self.frame, self.instruction_pointer = frame, instruction_pointer 61 self.frame, self.instruction_pointer = frame, instruction_pointer
29 62
30 63
31 def update(self): 64 def update(self):
32 frame = self.frame 65 frame = self.frame
39 callback = self.implementation[instr_type] 72 callback = self.implementation[instr_type]
40 except KeyError: 73 except KeyError:
41 print('Warning: unhandled opcode %d!' % instr_type) #TODO 74 print('Warning: unhandled opcode %d!' % instr_type) #TODO
42 else: 75 else:
43 callback(*args) 76 callback(*args)
77 frame, instr_type, rank_mask, param_mask, args = self.ecl.subs[self.sub][self.instruction_pointer]
44 if frame <= self.frame: 78 if frame <= self.frame:
45 self.instruction_pointer += 1 79 self.instruction_pointer += 1
46 except IndexError: 80 except IndexError:
47 pass #TODO: script ended, destroy enemy 81 pass #TODO: script ended, destroy enemy
48 82