Mercurial > touhou
annotate pytouhou/formats/std.py @ 110:3ac41b966fed
Add writing support to pytouhou.formats.std!
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Tue, 06 Sep 2011 16:40:32 +0200 |
parents | ac2e5e1c2c3c |
children | 340fcda8e64a |
rev | line source |
---|---|
52
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
1 # -*- encoding: utf-8 -*- |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
2 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com> |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
4 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
5 ## This program is free software; you can redistribute it and/or modify |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
6 ## it under the terms of the GNU General Public License as published |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
7 ## by the Free Software Foundation; version 3 only. |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
8 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
9 ## This program is distributed in the hope that it will be useful, |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
12 ## GNU General Public License for more details. |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
13 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
14 |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
15 |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
16 from struct import pack, unpack, calcsize |
58 | 17 from pytouhou.utils.helpers import read_string, get_logger |
0 | 18 |
58 | 19 logger = get_logger(__name__) |
0 | 20 |
21 | |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
22 class Model(object): |
0 | 23 def __init__(self): |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
24 self.unknown = 0 |
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
25 self.bounding_box = (0., 0., 0., |
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
26 0., 0., 0.) |
0 | 27 self.quads = [] |
28 | |
29 | |
30 | |
31 class Stage(object): | |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
32 _instructions = {0: ('fff', 'set_viewpos'), |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
33 1: ('BBBBff', 'set_fog'), |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
34 2: ('fff', 'set_viewpos2'), |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
35 3: ('III', 'start_interpolating_viewpos2'), |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
36 4: ('III', 'start_interpolating_fog')} |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
37 |
97 | 38 def __init__(self): |
0 | 39 self.name = '' |
40 self.bgms = (('', ''), ('', ''), ('', '')) | |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
41 self.models = [] |
0 | 42 self.object_instances = [] |
43 self.script = [] | |
44 | |
45 | |
46 @classmethod | |
97 | 47 def read(cls, file): |
48 stage = Stage() | |
0 | 49 |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
50 nb_models, nb_faces = unpack('<HH', file.read(4)) |
0 | 51 object_instances_offset, script_offset = unpack('<II', file.read(8)) |
52 if file.read(4) != b'\x00\x00\x00\x00': | |
53 raise Exception #TODO | |
54 | |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
55 stage.name = read_string(file, 128, 'shift_jis') |
0 | 56 |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
57 bgm_a = read_string(file, 128, 'shift_jis') |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
58 bgm_b = read_string(file, 128, 'shift_jis') |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
59 bgm_c = read_string(file, 128, 'shift_jis') |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
60 bgm_d = read_string(file, 128, 'shift_jis') |
0 | 61 |
62 bgm_a_path = read_string(file, 128, 'ascii') | |
63 bgm_b_path = read_string(file, 128, 'ascii') | |
64 bgm_c_path = read_string(file, 128, 'ascii') | |
65 bgm_d_path = read_string(file, 128, 'ascii') | |
66 | |
67 stage.bgms = [(bgm_a, bgm_a_path), (bgm_b, bgm_b_path), (bgm_c, bgm_c_path), (bgm_d, bgm_d_path)] #TODO: handle ' ' | |
68 | |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
69 # Read model definitions |
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
70 offsets = unpack('<%s' % ('I' * nb_models), file.read(4 * nb_models)) |
0 | 71 for offset in offsets: |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
72 model = Model() |
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
73 id_, unknown, x, y, z, width, height, depth = unpack('<HHffffff', file.read(28)) |
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
74 model.unknown = unknown |
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
75 model.bounding_box = x, y, z, width, height, depth #TODO: check |
0 | 76 while True: |
77 unknown, size = unpack('<HH', file.read(4)) | |
78 if unknown == 0xffff: | |
79 break | |
80 if size != 0x1c: | |
81 raise Exception #TODO | |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
82 script_index, x, y, z, width, height = unpack('<Hxxfffff', file.read(24)) |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
83 model.quads.append((script_index, x, y, z, width, height)) |
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
84 stage.models.append(model) |
0 | 85 |
86 | |
87 # Read object usages | |
88 file.seek(object_instances_offset) | |
89 while True: | |
90 obj_id, unknown, x, y, z = unpack('<HHfff', file.read(16)) | |
91 if (obj_id, unknown) == (0xffff, 0xffff): | |
92 break | |
93 if unknown != 256: | |
94 raise Exception #TODO | |
94
ca571697ec83
Various minor optimisations and refactoring
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
95 stage.object_instances.append((obj_id, x, y, z)) |
0 | 96 |
97 | |
98 # Read other funny things (script) | |
99 file.seek(script_offset) | |
100 while True: | |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
101 frame, opcode, size = unpack('<IHH', file.read(8)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
102 if (frame, opcode, size) == (0xffffffff, 0xffff, 0xffff): |
0 | 103 break |
104 if size != 0x0c: | |
105 raise Exception #TODO | |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
106 data = file.read(size) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
107 if opcode in cls._instructions: |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
108 args = unpack('<%s' % cls._instructions[opcode][0], data) |
13 | 109 else: |
110 args = (data,) | |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
111 logger.warn('unknown opcode %d', opcode) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
112 stage.script.append((frame, opcode, args)) |
0 | 113 |
114 return stage | |
115 | |
110
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
116 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
117 def write(self, file): |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
118 model_offsets = [] |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
119 second_section_offset = 0 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
120 third_section_offset = 0 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
121 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
122 nb_faces = sum(len(model.quads) for model in self.models) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
123 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
124 # Write header |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
125 file.write(pack('<HH', len(self.models), nb_faces)) #TODO: nb_faces |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
126 file.write(pack('<II', 0, 0)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
127 file.write(pack('<I', 0)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
128 file.write(pack('<128s', self.name.encode('shift_jis'))) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
129 for bgm_name, bgm_path in self.bgms: |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
130 file.write(pack('<128s', bgm_name.encode('shift_jis'))) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
131 for bgm_name, bgm_path in self.bgms: |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
132 file.write(pack('<128s', bgm_path.encode('ascii'))) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
133 file.write(b'\x00\x00\x00\x00' * len(self.models)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
134 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
135 # Write first section |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
136 for i, model in enumerate(self.models): |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
137 model_offsets.append(file.tell()) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
138 file.write(pack('<HHffffff', i, model.unknown, *model.bounding_box)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
139 for quad in model.quads: |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
140 file.write(pack('<HH', 0x00, 0x1c)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
141 file.write(pack('<Hxxfffff', *quad)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
142 file.write(pack('<HH', 0xffff, 4)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
143 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
144 # Write second section |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
145 second_section_offset = file.tell() |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
146 for obj_id, x, y, z in self.object_instances: |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
147 file.write(pack('<HHfff', obj_id, 256, x, y, z)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
148 file.write(b'\xff' * 16) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
149 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
150 # Write third section |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
151 third_section_offset = file.tell() |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
152 for frame, opcode, args in self.script: |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
153 size = calcsize(self._instructions[opcode][0]) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
154 file.write(pack('<IHH%s' % self._instructions[opcode][0], frame, opcode, size, *args)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
155 file.write(b'\xff' * 20) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
156 |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
157 # Fix offsets |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
158 file.seek(4) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
159 file.write(pack('<II', second_section_offset, third_section_offset)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
160 file.seek(16+128+128*2*4) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
161 file.write(pack('<%sI' % len(self.models), *model_offsets)) |
3ac41b966fed
Add writing support to pytouhou.formats.std!
Thibaut Girka <thib@sitedethib.com>
parents:
97
diff
changeset
|
162 |