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