annotate pytouhou/formats/msg.py @ 316:f0be7ea62330

Fix a bug with ECL instruction 96, and fix overall ECL handling. The issue with instruction 96 was about death callbacks, being executed on the caller of instruction 96 instead of the dying enemies. This was introduced by changeset 5930b33a0370. Additionnaly, ECL processes are now an attribute of the Enemy, and death/timeout conditions are checked right after the ECL frame, even if the ECL script has already ended, just like in the original game.
author Thibaut Girka <thib@sitedethib.com>
date Thu, 29 Mar 2012 21:18:35 +0200
parents 5492472963b0
children d1f0bb0b7a17
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 from struct import pack, unpack, calcsize
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
16
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17 from pytouhou.utils.helpers import get_logger
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 logger = get_logger(__name__)
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 class MSG(object):
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22 _instructions = {0: ('', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23 1: ('hh', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24 2: ('hh', 'change_face'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
25 3: ('hhs', 'display_dialog_line'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26 4: ('I', 'pause'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27 5: ('hh', 'switch'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28 6: ('', 'add_enemy_sprite'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29 7: ('I', 'change_music'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30 8: ('hhs', 'display_character_line'),
286
4838e9bab0f9 Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 203
diff changeset
31 9: ('I', 'show_scores'),
4838e9bab0f9 Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 203
diff changeset
32 10: ('', 'freeze'),
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
33 11: ('', 'next_level'),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34 12: ('', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 13: ('I', None),
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36 14: ('', None)} #TODO
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
38
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
39 def __init__(self):
286
4838e9bab0f9 Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 203
diff changeset
40 self.msgs = {}
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
41
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
42
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
43 @classmethod
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
44 def read(cls, file):
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
45 entry_count, = unpack('<I', file.read(4))
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
46 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
47
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 msg = cls()
286
4838e9bab0f9 Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 203
diff changeset
49 msg.msgs = {}
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50
286
4838e9bab0f9 Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 203
diff changeset
51 for i, offset in enumerate(entry_offsets):
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
52 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
53 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
54
286
4838e9bab0f9 Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 203
diff changeset
55 msg.msgs[i] = []
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
56 file.seek(offset)
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
57
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
58 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
59 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
60 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
61 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
62 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
63 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
64 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
65 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
66 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
67 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
68 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
69 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
70 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
71 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
72 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
73 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
74
286
4838e9bab0f9 Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 203
diff changeset
75 msg.msgs[i].append((time, opcode, args))
133
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
76
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
77
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78 return msg
2cad2e84a49e Add reading support for the MSG format.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
79