Mercurial > touhou
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 |