Mercurial > touhou
changeset 42:1b0ca2fb89f9
Refactor ECL parsing/etc.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Thu, 18 Aug 2011 22:11:39 +0200 |
parents | 93c8dc2de923 |
children | 7195aaf95f6e |
files | pytouhou/formats/ecl.py pytouhou/game/eclrunner.py pytouhou/game/enemymanager.py |
diffstat | 3 files changed, 139 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/pytouhou/formats/ecl.py +++ b/pytouhou/formats/ecl.py @@ -5,6 +5,117 @@ from collections import namedtuple class ECL(object): + _instructions = {0: ('', 'noop?'), + 1: ('I', 'delete?'), + 2: ('Ii', 'relative_jump'), + 3: ('Iii', 'relative_jump_ex'), + 4: ('ii', 'set_counter'), + 5: ('if', None), + 6: ('ii', None), + 8: ('if', None), + 9: ('iff', None), + 10: ('i', None), + 13: ('iii', None), + 14: ('iii', None), + 15: ('iii', None), + 16: ('iii', None), + 17: ('iii', None), + 18: ('i', None), + 20: ('iff', None), + 21: ('iff', None), + 23: ('iff', None), + 25: ('iffff', None), + 26: ('i', None), + 27: ('ii', None), + 28: ('ff', None), + 29: ('ii', None), + 30: ('ii', None), + 31: ('ii', None), + 32: ('ii', None), + 33: ('ii', None), + 34: ('ii', None), + 35: ('iif', None), + 36: ('', 'return?'), + 39: ('iiiii', None), + 43: ('fff', 'set_position'), + 45: ('ff', 'set_angle_and_speed'), + 46: ('f', 'set_rotation_speed'), + 47: ('f', 'set_speed'), + 48: ('f', 'set_acceleration'), + 49: ('ff', None), + 50: ('ff', None), + 51: ('ff', 'set_speed_towards_player'), + 52: ('iff', None), + 56: ('iffi', None), + 57: ('ifff', 'move_to'), + 59: ('iffi', None), + 61: ('i', None), + 63: ('i', None), + 65: ('ffff', None), + 66: ('', None), + 67: ('hhiiffffi', 'set_bullet_attributes'), + 68: ('hhiiffffi', 'set_bullet_attributes2'), + 69: ('hhiiffffi', 'set_bullet_attributes3'), + 70: ('hhiiffffi', 'set_bullet_attributes4'), + 74: ('hhiiffffi', 'set_bullet_attributes5'), + 75: ('hhiiffffi', 'set_bullet_attributes6'), + 76: ('i', None), + 77: ('i', 'set_bullet_interval'), + 78: ('', None), + 79: ('', None), + 81: ('fff', 'set_bullet_launch_offset'), + 82: ('iiiiffff', None), + 83: ('', None), + 84: ('i', None), + 85: ('hhfiffffiiiiii', None), + 86: ('hhffifffiiiiii', None), + 87: ('i', None), + 88: ('if', None), + 90: ('iiii', None), + 92: ('i', None), + #93: set_spellcard, a string is there + 94: ('', None), + 95: ('ifffhhi', None), + 96: ('', None), + 97: ('i', 'set_anim'), + 98: ('hhhhhh', 'set_multiple_anims'), + 99: ('ii', None), + 100: ('i', 'set_death_anim'), + 101: ('i', 'set_boss_mode?'), + 102: ('iffff', None), + 103: ('fff', 'set_enemy_hitbox'), + 104: ('i', None), + 105: ('i', 'set_vulnerable'), + 106: ('i', 'play_sound'), + 107: ('i', None), + 108: ('i', 'set_death_callback?'), + 109: ('ii', None), + 111: ('i', None), + 112: ('i', None), + 113: ('i', 'set_low_life_trigger'), + 114: ('i', 'set_low_life_callback'), + 115: ('i', 'set_timeout'), + 116: ('i', None), + 117: ('i', None), + 118: ('iihh', None), + 119: ('i', None), + 120: ('i', None), + 121: ('ii', None), + 122: ('i', None), + 123: ('i', None), + 124: ('i', None), + 125: ('', None), + 126: ('i', 'set_remaining_lives'), + 127: ('i', None), + 128: ('i', None), + 129: ('ii', None), + 130: ('i', None), + 131: ('ffiiii', None), + 132: ('i', None), + 133: ('', None), + 134: ('', None), + 135: ('i', None)} #TODO + def __init__(self): self.main = [] self.subs = [[]] @@ -31,8 +142,12 @@ class ECL(object): break size, rank_mask, param_mask = unpack('<HHH', file.read(6)) data = file.read(size - 12) - #TODO: unpack data - ecl.subs[-1].append((time, opcode, rank_mask, param_mask, data)) + if opcode in cls._instructions: + args = unpack('<%s' % cls._instructions[opcode][0], data) + else: + args = (data, ) + print('Warning: unknown opcode %d' % opcode) #TODO + ecl.subs[-1].append((time, opcode, rank_mask, param_mask, args)) # Read main file.seek(main_offset)
--- a/pytouhou/game/eclrunner.py +++ b/pytouhou/game/eclrunner.py @@ -1,13 +1,10 @@ -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)} + self.implementation = {4: (self.set_label), + 3: (self.goto)} if implementation: self.implementation.update(implementation) @@ -16,22 +13,21 @@ class ECLRunner(object): 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 set_label(self, label, count): + self.labels[label & 0xffff] = (self.sub, self.instruction_pointer, count) - def goto(self, frame, unknown1, unknown2, label, unknown3): + def goto(self, frame, instruction_pointer, label): try: - sub, instruction_pointer, count = self.labels[label] + sub, instruction_pointer, count = self.labels[label & 0xffff] except KeyError: pass else: count -= 1 if count: - self.labels[label] = sub, instruction_pointer, count + self.labels[label & 0xffff] = sub, instruction_pointer, count else: - del self.labels[label] + del self.labels[label & 0xffff] self.frame = frame self.sub, self.instruction_pointer = sub, instruction_pointer @@ -44,11 +40,11 @@ class ECLRunner(object): if frame == self.frame: try: - format, callback = self.implementation[instr_type] + callback = self.implementation[instr_type] except KeyError: print('Warning: unhandled opcode %d!' % instr_type) #TODO else: - callback(*unpack('<' + format, args)) + callback(*args) if frame <= self.frame: self.instruction_pointer += 1 except IndexError:
--- a/pytouhou/game/enemymanager.py +++ b/pytouhou/game/enemymanager.py @@ -39,17 +39,17 @@ class Enemy(object): self.hitbox = (0, 0) self.ecl_runner.implementation.update({#67: ('HHIIffffI', self.set_bullet_attributes), - 97: ('I', self.set_sprite), - 98: ('HHHHHH', self.set_multiple_sprites), - 45: ('ff', self.set_angle_speed), - 43: ('fff', self.set_pos), - 46: ('f', self.set_rotation_speed), - 47: ('f', self.set_speed), - 48: ('f', self.set_acceleration), - 51: ('If', self.target_player), - 57: ('Ifff', self.move_to), - 100: ('I', self.set_death_sprite), - 103: ('fff', self.set_hitbox)}) #TODO + 97: (self.set_sprite), + 98: (self.set_multiple_sprites), + 45: (self.set_angle_speed), + 43: (self.set_pos), + 46: (self.set_rotation_speed), + 47: (self.set_speed), + 48: (self.set_acceleration), + 51: (self.target_player), + 57: (self.move_to), + 100: (self.set_death_sprite), + 103: (self.set_hitbox)}) #TODO @@ -221,7 +221,7 @@ class EnemyManager(object): y = random.rand_double() * 800 #102h.exe@0x411881 ecl_runner = ECLRunner(self.ecl, sub) enemy = Enemy((x, y), life, instr_type, ecl_runner, self.anm_wrapper) - ecl_runner.implementation[1] = ('I', self.make_enemy_deleter(enemy)) + ecl_runner.implementation[1] = self.make_enemy_deleter(enemy) self.enemies.append(enemy)