Mercurial > touhou
diff pytouhou/formats/msg.py @ 133:2cad2e84a49e
Add reading support for the MSG format.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sun, 11 Sep 2011 07:34:34 -0700 |
parents | |
children | d3005ebe797a |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/pytouhou/formats/msg.py @@ -0,0 +1,90 @@ +# -*- 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. +## + +import struct +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 = [] + + new_entry = True + while True: + offset = file.tell() + + try: + time, opcode, size = unpack('<HBB', file.read(4)) + except: + return + + if time == 0 and opcode == 0: + new_entry = True + + if new_entry and opcode != 0: + new_entry = False + time = -1 + if offset in entry_offsets: + #print(entry_offsets.index(offset)) + msg.msgs.append([]) + + 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 +