annotate pytouhou/formats/msg.py @ 136:d3005ebe797a

Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 23 Sep 2011 10:05:20 -0700
parents 2cad2e84a49e
children df8b2ab54639
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
1 # -*- encoding: utf-8 -*-
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2 ##
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 ## Copyright (C) 2011 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
4 ##
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
5 ## This program is free software; you can redistribute it and/or modify
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 ## it under the terms of the GNU General Public License as published
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7 ## by the Free Software Foundation; version 3 only.
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8 ##
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9 ## This program is distributed in the hope that it will be useful,
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 ## GNU General Public License for more details.
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
13 ##
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
15 import struct
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
16 from struct import pack, unpack, calcsize
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17 from pytouhou.utils.helpers import read_string
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
18
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19 from pytouhou.utils.helpers import get_logger
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
20
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
21 logger = get_logger(__name__)
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23 class MSG(object):
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24 _instructions = {0: ('', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
25 1: ('hh', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26 2: ('hh', 'change_face'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27 3: ('hhs', 'display_dialog_line'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28 4: ('I', 'pause'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29 5: ('hh', 'switch'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30 6: ('', 'add_enemy_sprite'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
31 7: ('I', 'change_music'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
32 8: ('hhs', 'display_character_line'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
33 9: ('I', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34 10: ('', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 11: ('', 'next_level'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36 12: ('', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37 13: ('I', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
38 14: ('', None)} #TODO
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
39
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
40
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
41 def __init__(self):
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
42 self.msgs = [[]]
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
43
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
44
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
45 @classmethod
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
46 def read(cls, file):
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
47 entry_count, = unpack('<I', file.read(4))
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 entry_offsets = unpack('<%dI' % entry_count, file.read(4 * entry_count))
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
49
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50 msg = cls()
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
51 msg.msgs = []
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
52
136
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
53 for offset in entry_offsets:
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
54 if msg.msgs and offset == entry_offsets[0]: # In EoSD, Reimu’s scripts start at 0, and Marisa’s ones at 10.
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
55 continue # If Reimu has less than 10 scripts, the remaining offsets are equal to her first.
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
56
136
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
57 msg.msgs.append([])
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
58 file.seek(offset)
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
59
136
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
60 while True:
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
61 time, opcode, size = unpack('<HBB', file.read(4))
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
62 if time == 0 and opcode == 0:
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
63 break
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
64 data = file.read(size)
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
65 if opcode in cls._instructions:
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
66 fmt = '<%s' % cls._instructions[opcode][0]
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
67 if fmt.endswith('s'):
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
68 fmt = fmt[:-1]
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
69 fmt = '%s%ds' % (fmt, size - calcsize(fmt))
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
70 args = unpack(fmt, data)
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
71 if fmt.endswith('s'):
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
72 args = args[:-1] + (args[-1].decode('shift_jis'),)
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
73 else:
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
74 args = (data, )
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
75 logger.warn('unknown msg opcode %d', opcode)
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
76
136
d3005ebe797a Fix MSG parsing, use the offsets instead of trying to relate them to the actual data.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 133
diff changeset
77 msg.msgs[-1].append((time, opcode, args))
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
79
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
80 return msg
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
81