Mercurial > touhou
view pytouhou/formats/msg.py @ 261:2876c267be00
Add heuristics to extract character data from the demo .exe.
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Mon, 23 Jan 2012 00:03:06 +0100 |
parents | df8b2ab54639 |
children | 4838e9bab0f9 |
line wrap: on
line source
# -*- encoding: utf-8 -*- ## ## Copyright (C) 2011 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published ## by the Free Software Foundation; version 3 only. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## from struct import pack, unpack, calcsize from pytouhou.utils.helpers import read_string from pytouhou.utils.helpers import get_logger logger = get_logger(__name__) class MSG(object): _instructions = {0: ('', None), 1: ('hh', None), 2: ('hh', 'change_face'), 3: ('hhs', 'display_dialog_line'), 4: ('I', 'pause'), 5: ('hh', 'switch'), 6: ('', 'add_enemy_sprite'), 7: ('I', 'change_music'), 8: ('hhs', 'display_character_line'), 9: ('I', None), 10: ('', None), 11: ('', 'next_level'), 12: ('', None), 13: ('I', None), 14: ('', None)} #TODO def __init__(self): self.msgs = [[]] @classmethod def read(cls, file): entry_count, = unpack('<I', file.read(4)) entry_offsets = unpack('<%dI' % entry_count, file.read(4 * entry_count)) msg = cls() msg.msgs = [] for offset in entry_offsets: if msg.msgs and offset == entry_offsets[0]: # In EoSD, Reimu’s scripts start at 0, and Marisa’s ones at 10. continue # If Reimu has less than 10 scripts, the remaining offsets are equal to her first. msg.msgs.append([]) file.seek(offset) while True: time, opcode, size = unpack('<HBB', file.read(4)) if time == 0 and opcode == 0: break data = file.read(size) if opcode in cls._instructions: fmt = '<%s' % cls._instructions[opcode][0] if fmt.endswith('s'): fmt = fmt[:-1] fmt = '%s%ds' % (fmt, size - calcsize(fmt)) args = unpack(fmt, data) if fmt.endswith('s'): args = args[:-1] + (args[-1].decode('shift_jis'),) else: args = (data, ) logger.warn('unknown msg opcode %d', opcode) msg.msgs[-1].append((time, opcode, args)) return msg