Mercurial > touhou
comparison pytouhou/game/eclrunner.py @ 42:1b0ca2fb89f9
Refactor ECL parsing/etc.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Thu, 18 Aug 2011 22:11:39 +0200 |
parents | e3ba2fa966f6 |
children | 7195aaf95f6e |
comparison
equal
deleted
inserted
replaced
41:93c8dc2de923 | 42:1b0ca2fb89f9 |
---|---|
1 from struct import unpack | |
2 | |
3 | |
4 class ECLRunner(object): | 1 class ECLRunner(object): |
5 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): |
6 self.ecl = ecl | 3 self.ecl = ecl |
7 | 4 |
8 self.labels = {} | 5 self.labels = {} |
9 self.implementation = {4: ('HHI', self.set_label), | 6 self.implementation = {4: (self.set_label), |
10 3: ('IHHHH', self.goto)} | 7 3: (self.goto)} |
11 if implementation: | 8 if implementation: |
12 self.implementation.update(implementation) | 9 self.implementation.update(implementation) |
13 | 10 |
14 self.sub = sub | 11 self.sub = sub |
15 self.frame = frame | 12 self.frame = frame |
16 self.instruction_pointer = instruction_pointer | 13 self.instruction_pointer = instruction_pointer |
17 | 14 |
18 | 15 |
19 def set_label(self, label, unknown, count): | 16 def set_label(self, label, count): |
20 assert unknown == 0xffff | 17 self.labels[label & 0xffff] = (self.sub, self.instruction_pointer, count) |
21 self.labels[label] = (self.sub, self.instruction_pointer, count) | |
22 | 18 |
23 | 19 |
24 def goto(self, frame, unknown1, unknown2, label, unknown3): | 20 def goto(self, frame, instruction_pointer, label): |
25 try: | 21 try: |
26 sub, instruction_pointer, count = self.labels[label] | 22 sub, instruction_pointer, count = self.labels[label & 0xffff] |
27 except KeyError: | 23 except KeyError: |
28 pass | 24 pass |
29 else: | 25 else: |
30 count -= 1 | 26 count -= 1 |
31 if count: | 27 if count: |
32 self.labels[label] = sub, instruction_pointer, count | 28 self.labels[label & 0xffff] = sub, instruction_pointer, count |
33 else: | 29 else: |
34 del self.labels[label] | 30 del self.labels[label & 0xffff] |
35 self.frame = frame | 31 self.frame = frame |
36 self.sub, self.instruction_pointer = sub, instruction_pointer | 32 self.sub, self.instruction_pointer = sub, instruction_pointer |
37 | 33 |
38 | 34 |
39 def update(self): | 35 def update(self): |
42 while frame <= self.frame: | 38 while frame <= self.frame: |
43 frame, instr_type, rank_mask, param_mask, args = self.ecl.subs[self.sub][self.instruction_pointer] | 39 frame, instr_type, rank_mask, param_mask, args = self.ecl.subs[self.sub][self.instruction_pointer] |
44 | 40 |
45 if frame == self.frame: | 41 if frame == self.frame: |
46 try: | 42 try: |
47 format, callback = self.implementation[instr_type] | 43 callback = self.implementation[instr_type] |
48 except KeyError: | 44 except KeyError: |
49 print('Warning: unhandled opcode %d!' % instr_type) #TODO | 45 print('Warning: unhandled opcode %d!' % instr_type) #TODO |
50 else: | 46 else: |
51 callback(*unpack('<' + format, args)) | 47 callback(*args) |
52 if frame <= self.frame: | 48 if frame <= self.frame: |
53 self.instruction_pointer += 1 | 49 self.instruction_pointer += 1 |
54 except IndexError: | 50 except IndexError: |
55 pass #TODO: script ended, destroy enemy | 51 pass #TODO: script ended, destroy enemy |
56 | 52 |