Mercurial > touhou
annotate pytouhou/formats/ecl.py @ 612:73f134f84c7f
Request a RGB888 context, since SDL2’s default of RGB332 sucks.
On X11/GLX, it will select the first config available, that is the best
one, while on EGL it will iterate over them to select the one closest
to what the application requested.
Of course, anything lower than RGB888 looks bad and we really don’t
want that.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 26 Mar 2015 20:20:37 +0100 |
parents | eef492100f4c |
children | d1f0bb0b7a17 |
rev | line source |
---|---|
52
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
51
diff
changeset
|
1 # -*- encoding: utf-8 -*- |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
51
diff
changeset
|
2 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
51
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:
51
diff
changeset
|
4 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
51
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:
51
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:
51
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:
51
diff
changeset
|
8 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
51
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:
51
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:
51
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:
51
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:
51
diff
changeset
|
13 ## |
ab826bc29aa2
Add some documentation, GPLv3 headers, README and COPYING file.
Thibaut Girka <thib@sitedethib.com>
parents:
51
diff
changeset
|
14 |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
15 """ECL files handling. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
16 |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
17 This module provides classes for handling the ECL file format. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
18 The ECL format is a format used in Touhou 6: EoSD to script most of the gameplay |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
19 aspects of the game, such as enemy movements, attacks, and so on. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
20 """ |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
21 |
113 | 22 import struct |
95
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
23 from struct import pack, unpack, calcsize |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
24 |
58 | 25 from pytouhou.utils.helpers import get_logger |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
26 |
58 | 27 logger = get_logger(__name__) |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
28 |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
29 class ECL(object): |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
30 """Handle Touhou 6 ECL files. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
31 |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
32 ECL files are binary script files used to describe the behavior of enemies. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
33 They are basically composed of a header and two additional sections. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
34 The first section is a list of subroutines, each composed of a list of timed |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
35 instructions. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
36 The second section is a list of a different set of instructions describing |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
37 enemy waves, triggering dialogs and level completion. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
38 |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
39 Instance variables: |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
40 mains -- list of lists of instructions describing waves and triggering dialogs |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
41 subs -- list of subroutines |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
42 """ |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
43 |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
44 _instructions = {0: ('', 'noop?'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
45 1: ('I', 'delete?'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
46 2: ('Ii', 'relative_jump'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
47 3: ('Iii', 'relative_jump_ex'), |
46 | 48 4: ('ii', 'set_int'), |
49 5: ('if', 'set_float'), | |
50 6: ('ii', 'set_random_int'), | |
51 8: ('if', 'set_random_float'), | |
59
4fe37a620b22
Handle set_random_angle properly! At last!
Thibaut Girka <thib@sitedethib.com>
parents:
58
diff
changeset
|
52 9: ('iff', 'set_random_float2'), |
75
b3bd421bb895
Handle a few more ECL instructions
Thibaut Girka <thib@sitedethib.com>
parents:
70
diff
changeset
|
53 10: ('i', 'store_x'), |
87 | 54 13: ('iii', 'add_int'), |
63
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
55 14: ('iii', 'substract_int'), |
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
56 15: ('iii', 'multiply_int'), |
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
57 16: ('iii', 'divide_int'), |
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
58 17: ('iii', 'modulo'), |
96
54929d495654
Handle ECL instruction 18
Thibaut Girka <thib@sitedethib.com>
parents:
95
diff
changeset
|
59 18: ('i', 'increment'), |
63
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
60 20: ('iff', 'add_float'), |
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
61 21: ('iff', 'substract_float'), |
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
62 23: ('iff', 'divide_float'), |
77
6fa6d74a049a
Handle a new ECL instruction, and add some names.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
76
diff
changeset
|
63 25: ('iffff', 'get_direction'), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
64 26: ('i', 'float_to_unit_circle'), #TODO: find a better name |
46 | 65 27: ('ii', 'compare_ints'), |
63
8527fe640844
Implement simple arithmetic instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
59
diff
changeset
|
66 28: ('ff', 'compare_floats'), |
64
d469012368b3
Implement conditional jumps.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
63
diff
changeset
|
67 29: ('ii', 'relative_jump_if_lower_than'), |
d469012368b3
Implement conditional jumps.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
63
diff
changeset
|
68 30: ('ii', 'relative_jump_if_lower_or_equal'), |
46 | 69 31: ('ii', 'relative_jump_if_equal'), |
64
d469012368b3
Implement conditional jumps.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
63
diff
changeset
|
70 32: ('ii', 'relative_jump_if_greater_than'), |
d469012368b3
Implement conditional jumps.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
63
diff
changeset
|
71 33: ('ii', 'relative_jump_if_greater_or_equal'), |
d469012368b3
Implement conditional jumps.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
63
diff
changeset
|
72 34: ('ii', 'relative_jump_if_not_equal'), |
46 | 73 35: ('iif', 'call'), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
74 36: ('', 'return'), |
46 | 75 39: ('iifii', 'call_if_equal'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
76 43: ('fff', 'set_position'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
77 45: ('ff', 'set_angle_and_speed'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
78 46: ('f', 'set_rotation_speed'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
79 47: ('f', 'set_speed'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
80 48: ('f', 'set_acceleration'), |
70
7c1f20407b3e
Add set_random_angle support
Thibaut Girka <thib@sitedethib.com>
parents:
67
diff
changeset
|
81 49: ('ff', 'set_random_angle'), |
7c1f20407b3e
Add set_random_angle support
Thibaut Girka <thib@sitedethib.com>
parents:
67
diff
changeset
|
82 50: ('ff', 'set_random_angle_ex'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
83 51: ('ff', 'set_speed_towards_player'), |
77
6fa6d74a049a
Handle a new ECL instruction, and add some names.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
76
diff
changeset
|
84 52: ('iff', 'move_in_decel'), |
76
f305c0e406d6
Handle all move_to_* ECL instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
75
diff
changeset
|
85 56: ('ifff', 'move_to_linear'), |
f305c0e406d6
Handle all move_to_* ECL instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
75
diff
changeset
|
86 57: ('ifff', 'move_to_decel'), |
f305c0e406d6
Handle all move_to_* ECL instructions.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
75
diff
changeset
|
87 59: ('iffi', 'move_to_accel'), |
46 | 88 61: ('i', 'stop_in'), |
75
b3bd421bb895
Handle a few more ECL instructions
Thibaut Girka <thib@sitedethib.com>
parents:
70
diff
changeset
|
89 63: ('i', 'stop_in_accel'), |
50
811cefefb5c8
Fix a few bugs and add support for a few instructions
Thibaut Girka <thib@sitedethib.com>
parents:
46
diff
changeset
|
90 65: ('ffff', 'set_screen_box'), |
811cefefb5c8
Fix a few bugs and add support for a few instructions
Thibaut Girka <thib@sitedethib.com>
parents:
46
diff
changeset
|
91 66: ('', 'clear_screen_box'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
92 67: ('hhiiffffi', 'set_bullet_attributes'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
93 68: ('hhiiffffi', 'set_bullet_attributes2'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
94 69: ('hhiiffffi', 'set_bullet_attributes3'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
95 70: ('hhiiffffi', 'set_bullet_attributes4'), |
46 | 96 71: ('hhiiffffi', 'set_bullet_attributes5'), |
97 74: ('hhiiffffi', 'set_bullet_attributes6'), | |
98 75: ('hhiiffffi', 'set_bullet_attributes7'), | |
78
bcf965ede96c
Fix/rename/comment a few things
Thibaut Girka <thib@sitedethib.com>
parents:
77
diff
changeset
|
99 76: ('i', 'set_bullet_interval'), |
bcf965ede96c
Fix/rename/comment a few things
Thibaut Girka <thib@sitedethib.com>
parents:
77
diff
changeset
|
100 77: ('i', 'set_bullet_interval_ex'), |
46 | 101 78: ('', 'delay_attack'), |
102 79: ('', 'no_delay_attack'), | |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
103 81: ('fff', 'set_bullet_launch_offset'), |
78
bcf965ede96c
Fix/rename/comment a few things
Thibaut Girka <thib@sitedethib.com>
parents:
77
diff
changeset
|
104 82: ('iiiiffff', 'set_extended_bullet_attributes'), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
105 83: ('', 'change_bullets_in_star_bonus'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
106 84: ('i', None), |
46 | 107 85: ('hhffffffiiiiii', 'laser'), |
108 86: ('hhffffffiiiiii', 'laser2'), | |
109 87: ('i', 'set_upcoming_id'), | |
110 88: ('if','alter_laser_angle'), | |
274
f037bca24f2d
Partially implement lasers.
Thibaut Girka <thib@sitedethib.com>
parents:
204
diff
changeset
|
111 90: ('ifff', 'reposition_laser'), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
112 92: ('i', 'cancel_laser'), |
95
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
113 93: ('hhs', 'set_spellcard'), |
67
e2cb9d434dc2
Add support for a few opcodes.
Thibaut Girka <thib@sitedethib.com>
parents:
66
diff
changeset
|
114 94: ('', 'end_spellcard'), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
115 95: ('ifffhhi', 'spawn_enemy'), |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
116 96: ('', 'kill_all_enemies'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
117 97: ('i', 'set_anim'), |
46 | 118 98: ('hhhhhxx', 'set_multiple_anims'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
119 99: ('ii', None), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
120 100: ('i', 'set_death_anim'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
121 101: ('i', 'set_boss_mode?'), |
77
6fa6d74a049a
Handle a new ECL instruction, and add some names.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
76
diff
changeset
|
122 102: ('iffff', 'create_squares'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
123 103: ('fff', 'set_enemy_hitbox'), |
79
ffe2c2b9912c
Handle a few more ECL instructions. Prepare for bullet handling \o/
Thibaut Girka <thib@sitedethib.com>
parents:
78
diff
changeset
|
124 104: ('i', 'set_collidable'), |
67
e2cb9d434dc2
Add support for a few opcodes.
Thibaut Girka <thib@sitedethib.com>
parents:
66
diff
changeset
|
125 105: ('i', 'set_damageable'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
126 106: ('i', 'play_sound'), |
75
b3bd421bb895
Handle a few more ECL instructions
Thibaut Girka <thib@sitedethib.com>
parents:
70
diff
changeset
|
127 107: ('i', 'set_death_flags'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
128 108: ('i', 'set_death_callback?'), |
46 | 129 109: ('ii', 'memory_write_int'), |
130 111: ('i', 'set_life'), | |
67
e2cb9d434dc2
Add support for a few opcodes.
Thibaut Girka <thib@sitedethib.com>
parents:
66
diff
changeset
|
131 112: ('i', 'set_ellapsed_time'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
132 113: ('i', 'set_low_life_trigger'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
133 114: ('i', 'set_low_life_callback'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
134 115: ('i', 'set_timeout'), |
67
e2cb9d434dc2
Add support for a few opcodes.
Thibaut Girka <thib@sitedethib.com>
parents:
66
diff
changeset
|
135 116: ('i', 'set_timeout_callback'), |
e2cb9d434dc2
Add support for a few opcodes.
Thibaut Girka <thib@sitedethib.com>
parents:
66
diff
changeset
|
136 117: ('i', 'set_touchable'), |
389
eef492100f4c
Add "explosion", instruction 118.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
372
diff
changeset
|
137 118: ('iIbbbb', 'drop_particles'), |
46 | 138 119: ('i', 'drop_bonus'), |
75
b3bd421bb895
Handle a few more ECL instructions
Thibaut Girka <thib@sitedethib.com>
parents:
70
diff
changeset
|
139 120: ('i', 'set_automatic_orientation'), |
107
5d9052b9a4e8
(almost) implement Cirno's freezing spellcard
Thibaut Girka <thib@sitedethib.com>
parents:
96
diff
changeset
|
140 121: ('ii', 'call_special_function'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
141 122: ('i', None), |
75
b3bd421bb895
Handle a few more ECL instructions
Thibaut Girka <thib@sitedethib.com>
parents:
70
diff
changeset
|
142 123: ('i', 'skip_frames'), |
77
6fa6d74a049a
Handle a new ECL instruction, and add some names.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
76
diff
changeset
|
143 124: ('i', 'drop_specific_bonus'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
144 125: ('', None), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
145 126: ('i', 'set_remaining_lives'), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
146 127: ('i', None), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
147 128: ('i', 'set_smooth_disappear'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
148 129: ('ii', None), |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
149 130: ('i', None), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
150 131: ('ffiiii', 'set_difficulty_coeffs'), |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
151 132: ('i', 'set_invisible'), |
362
3be4c1078095
(partially?) implement ECL's instruction 133
Thibaut Girka <thib@sitedethib.com>
parents:
286
diff
changeset
|
152 133: ('', 'copy_callbacks?'), |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
153 134: ('', None), |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
154 135: ('i', 'enable_spellcard_bonus')} #TODO |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
155 |
171
2f3665a77f11
Add support for the last unknown value of the enemy spawning.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
165
diff
changeset
|
156 _main_instructions = {0: ('fffhhI', 'spawn_enemy'), |
2f3665a77f11
Add support for the last unknown value of the enemy spawning.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
165
diff
changeset
|
157 2: ('fffhhI', 'spawn_enemy_mirrored'), |
2f3665a77f11
Add support for the last unknown value of the enemy spawning.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
165
diff
changeset
|
158 4: ('fffhhI', 'spawn_enemy_random'), |
2f3665a77f11
Add support for the last unknown value of the enemy spawning.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
165
diff
changeset
|
159 6: ('fffhhI', 'spawn_enemy_mirrored_random'), |
286
4838e9bab0f9
Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
283
diff
changeset
|
160 8: ('', 'call_msg'), |
4838e9bab0f9
Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
283
diff
changeset
|
161 9: ('', 'wait_msg'), |
4838e9bab0f9
Implement dialogs (MSG files).
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
283
diff
changeset
|
162 10: ('II', 'resume_ecl'), |
283
b6c068c8f7f2
Fix ECL time flow. Spellcard do not stop time. Instruction 0xc does.
Thibaut Girka <thib@sitedethib.com>
parents:
274
diff
changeset
|
163 12: ('', 'stop_time')} |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
164 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
165 _parameters = {6: {'main_count': 1, |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
166 'nb_main_offsets': 3, |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
167 'jumps_list': {2: 1, 3: 1, 29: 1, 30: 1, 31: 1, 32: 1, 33: 1, 34: 1}}} |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
168 |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
169 |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
170 def __init__(self): |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
171 self.mains = [] |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
172 self.subs = [] |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
173 |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
174 |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
175 @classmethod |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
176 def read(cls, file, version=6): |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
177 """Read an ECL file. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
178 |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
179 Raise an exception if the file is invalid. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
180 Return a ECL instance otherwise. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
181 """ |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
182 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
183 parameters = cls._parameters[version] |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
184 |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
185 sub_count, main_count = unpack('<HH', file.read(4)) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
186 |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
187 main_offsets = unpack('<%dI' % parameters['nb_main_offsets'], file.read(4 * parameters['nb_main_offsets'])) |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
188 sub_offsets = unpack('<%dI' % sub_count, file.read(4 * sub_count)) |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
189 |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
190 ecl = cls() |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
191 |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
192 # Read subs |
43
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
193 for sub_offset in sub_offsets: |
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
194 file.seek(sub_offset) |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
195 ecl.subs.append([]) |
43
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
196 |
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
197 instruction_offsets = [] |
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
198 |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
199 while True: |
43
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
200 instruction_offsets.append(file.tell() - sub_offset) |
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
201 |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
202 time, opcode = unpack('<IH', file.read(6)) |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
203 if time == 0xffffffff or opcode == 0xffff: |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
204 break |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
205 |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
206 size, rank_mask, param_mask = unpack('<HHH', file.read(6)) |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
207 data = file.read(size - 12) |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
208 if opcode in cls._instructions: |
95
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
209 fmt = '<%s' % cls._instructions[opcode][0] |
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
210 if fmt.endswith('s'): |
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
211 fmt = fmt[:-1] |
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
212 fmt = '%s%ds' % (fmt, size - 12 - calcsize(fmt)) |
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
213 args = unpack(fmt, data) |
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
214 if fmt.endswith('s'): |
e2d8f2a56ea4
Handle ECL opcodes with string.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
87
diff
changeset
|
215 args = args[:-1] + (args[-1].decode('shift_jis'),) |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
216 else: |
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
217 args = (data, ) |
58 | 218 logger.warn('unknown opcode %d', opcode) |
43
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
219 |
42
1b0ca2fb89f9
Refactor ECL parsing/etc.
Thibaut Girka <thib@sitedethib.com>
parents:
20
diff
changeset
|
220 ecl.subs[-1].append((time, opcode, rank_mask, param_mask, args)) |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
221 |
43
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
222 |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
223 # Translate offsets to instruction pointers. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
224 # Indeed, jump instructions are relative and byte-based. |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
225 # Since our representation doesn't conserve offsets, we have to |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
226 # keep trace of where the jump is supposed to end up. |
43
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
227 for instr_offset, (i, instr) in zip(instruction_offsets, enumerate(ecl.subs[-1])): |
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
228 time, opcode, rank_mask, param_mask, args = instr |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
229 if opcode in parameters['jumps_list']: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
230 num = parameters['jumps_list'][opcode] |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
231 args = list(args) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
232 args[num] = instruction_offsets.index(instr_offset + args[num]) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
233 ecl.subs[-1][i] = time, opcode, rank_mask, param_mask, tuple(args) |
43
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
234 |
7195aaf95f6e
Fix set_counter, and relative_jump(_ex)
Thibaut Girka <thib@sitedethib.com>
parents:
42
diff
changeset
|
235 |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
236 # Read main |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
237 for main_offset in main_offsets: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
238 if main_offset == 0: |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
239 break |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
240 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
241 file.seek(main_offset) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
242 ecl.mains.append([]) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
243 while True: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
244 time, sub = unpack('<HH', file.read(4)) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
245 if time == 0xffff and sub == 4: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
246 break |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
247 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
248 opcode, size = unpack('<HH', file.read(4)) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
249 data = file.read(size - 8) |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
250 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
251 if opcode in cls._main_instructions: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
252 args = unpack('<%s' % cls._main_instructions[opcode][0], data) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
253 else: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
254 args = (data,) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
255 logger.warn('unknown main opcode %d', opcode) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
256 |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
257 ecl.mains[-1].append((time, sub, opcode, args)) |
18
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
258 |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
259 return ecl |
ca26a84916cb
Add preliminary ECL viewer/interpreter.
Thibaut Girka <thib@sitedethib.com>
parents:
diff
changeset
|
260 |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
261 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
262 def write(self, file, version=6): |
204
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
263 """Write to an ECL file.""" |
88361534c77e
Add some documentation (argh, so much left to document!)
Thibaut Girka <thib@sitedethib.com>
parents:
171
diff
changeset
|
264 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
265 parameters = self._parameters[version] |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
266 |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
267 sub_count = len(self.subs) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
268 sub_offsets = [] |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
269 main_offset = 0 |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
270 |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
271 # Skip header, it will be written later |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
272 file.seek(8+8+4*sub_count) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
273 |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
274 # Write subs |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
275 for sub in self.subs: |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
276 sub_offsets.append(file.tell()) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
277 |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
278 instruction_offsets = [] |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
279 instruction_datas = [] |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
280 for time, opcode, rank_mask, param_mask, args in sub: |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
281 format = self._instructions[opcode][0] |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
282 if format.endswith('s'): |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
283 args = list(args) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
284 args[-1] = args[-1].encode('shift_jis') |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
285 format = '%s%ds' % (format[:-1], len(args[-1])) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
286 format = '<IHHHH%s' % format |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
287 size = calcsize(format) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
288 instruction_offsets.append((instruction_offsets[-1] + len(instruction_datas[-1])) if instruction_offsets else 0) |
113 | 289 try: |
290 instruction_datas.append(pack(format, time, opcode, size, rank_mask, param_mask, *args)) | |
291 except struct.error: | |
292 logger.error('Failed to assemble opcode %d' % opcode) | |
293 raise | |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
294 |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
295 #TODO: clean up this mess |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
296 for instruction, data, offset in zip(sub, instruction_datas, instruction_offsets): |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
297 time, opcode, rank_mask, param_mask, args = instruction |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
298 if opcode in parameters['jumps_list']: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
299 num = parameters['jumps_list'][opcode] |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
300 args = list(args) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
301 args[num] = instruction_offsets[args[num]] - offset |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
302 format = '<IHHHH%s' % self._instructions[opcode][0] |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
303 size = calcsize(format) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
304 data = pack(format, time, opcode, size, rank_mask, param_mask, *args) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
305 file.write(data) |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
306 file.write(b'\xff' * 6 + b'\x0c\x00\x00\xff\xff\x00') |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
307 |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
308 # Write main |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
309 main_offsets = [0] * parameters['nb_main_offsets'] |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
310 for i, main in enumerate(self.mains): |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
311 main_offsets[i] = file.tell() |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
312 for time, sub, opcode, args in main: |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
313 format = '<HHHH%s' % self._main_instructions[opcode][0] |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
314 size = calcsize(format) |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
315 |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
316 file.write(pack(format, time, sub, opcode, size, *args)) |
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
317 file.write(b'\xff\xff\x04\x00') |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
318 |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
319 # Patch header |
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
320 file.seek(0) |
372
704bea2e4360
Use a future-proof ECL parser.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
362
diff
changeset
|
321 file.write(pack('<I%dI%dI' % (parameters['nb_main_offsets'], sub_count), sub_count, *(main_offsets + sub_offsets))) |
112
e544f9a7966d
Add writing support to pytouhou.formats.ecl!
Thibaut Girka <thib@sitedethib.com>
parents:
107
diff
changeset
|
322 |