Mercurial > touhou
diff pytouhou/game/eclrunner.py @ 23:444ac7bca7bc
Refacto ECL stuff, add support for a few instructions, and add some culling
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Fri, 12 Aug 2011 19:13:43 +0200 |
parents | |
children | 93aa1b55d97c |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/pytouhou/game/eclrunner.py @@ -0,0 +1,57 @@ +from struct import unpack + + +class ECLRunner(object): + def __init__(self, ecl, sub, frame=0, instruction_pointer=0, implementation=None): + self.ecl = ecl + + self.labels = {} + self.implementation = {4: ('HHI', self.set_label), + 3: ('IHHHH', self.goto)} + if implementation: + self.implementation.update(implementation) + + self.sub = sub + self.frame = frame + self.instruction_pointer = instruction_pointer + + + def set_label(self, label, unknown, count): + assert unknown == 0xffff + self.labels[label] = (self.sub, self.instruction_pointer, count) + + + def goto(self, frame, unknown1, unknown2, label, unknown3): + try: + sub, instruction_pointer, count = self.labels[label] + except KeyError: + pass + else: + count -= 1 + if count: + self.labels[label] = sub, instruction_pointer, count + else: + del self.labels[label] + self.frame = frame + self.sub, self.instruction_pointer = sub, instruction_pointer + + + def update(self): + frame = self.frame + while frame <= self.frame: + try: + frame, instr_type, rank_mask, param_mask, args = self.ecl.subs[self.sub][self.instruction_pointer] + except IndexError: + break #TODO: script ended, destroy enemy + + if frame == self.frame: + try: + format, callback = self.implementation[instr_type] + except KeyError: + print('Warning: unhandled opcode %d!' % instr_type) #TODO + else: + callback(*unpack('<' + format, args)) + self.instruction_pointer += 1 + + self.frame += 1 +