comparison 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
comparison
equal deleted inserted replaced
132:fba45c37ec99 133:2cad2e84a49e
1 # -*- encoding: utf-8 -*-
2 ##
3 ## Copyright (C) 2011 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
4 ##
5 ## This program is free software; you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published
7 ## by the Free Software Foundation; version 3 only.
8 ##
9 ## This program is distributed in the hope that it will be useful,
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ## GNU General Public License for more details.
13 ##
14
15 import struct
16 from struct import pack, unpack, calcsize
17 from pytouhou.utils.helpers import read_string
18
19 from pytouhou.utils.helpers import get_logger
20
21 logger = get_logger(__name__)
22
23 class MSG(object):
24 _instructions = {0: ('', None),
25 1: ('hh', None),
26 2: ('hh', 'change_face'),
27 3: ('hhs', 'display_dialog_line'),
28 4: ('I', 'pause'),
29 5: ('hh', 'switch'),
30 6: ('', 'add_enemy_sprite'),
31 7: ('I', 'change_music'),
32 8: ('hhs', 'display_character_line'),
33 9: ('I', None),
34 10: ('', None),
35 11: ('', 'next_level'),
36 12: ('', None),
37 13: ('I', None),
38 14: ('', None)} #TODO
39
40
41 def __init__(self):
42 self.msgs = [[]]
43
44
45 @classmethod
46 def read(cls, file):
47 entry_count, = unpack('<I', file.read(4))
48 entry_offsets = unpack('<%dI' % entry_count, file.read(4 * entry_count))
49
50 msg = cls()
51 msg.msgs = []
52
53 new_entry = True
54 while True:
55 offset = file.tell()
56
57 try:
58 time, opcode, size = unpack('<HBB', file.read(4))
59 except:
60 return
61
62 if time == 0 and opcode == 0:
63 new_entry = True
64
65 if new_entry and opcode != 0:
66 new_entry = False
67 time = -1
68 if offset in entry_offsets:
69 #print(entry_offsets.index(offset))
70 msg.msgs.append([])
71
72 data = file.read(size)
73
74 if opcode in cls._instructions:
75 fmt = '<%s' % cls._instructions[opcode][0]
76 if fmt.endswith('s'):
77 fmt = fmt[:-1]
78 fmt = '%s%ds' % (fmt, size - calcsize(fmt))
79 args = unpack(fmt, data)
80 if fmt.endswith('s'):
81 args = args[:-1] + (args[-1].decode('shift_jis'),)
82 else:
83 args = (data, )
84 logger.warn('unknown msg opcode %d', opcode)
85
86 msg.msgs[-1].append((time, opcode, args))
87
88
89 return msg
90