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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
732c64662f87 Minor changes
Thibaut Girka <thib@sitedethib.com>
parents: 112
diff changeset
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
3da4de9decd0 Use logging module
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
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
3da4de9decd0 Use logging module
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
48 4: ('ii', 'set_int'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
49 5: ('if', 'set_float'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
50 6: ('ii', 'set_random_int'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
fda176f07d6d Fix add_int
Thibaut Girka <thib@sitedethib.com>
parents: 79
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
96 71: ('hhiiffffi', 'set_bullet_attributes5'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
97 74: ('hhiiffffi', 'set_bullet_attributes6'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
101 78: ('', 'delay_attack'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
107 85: ('hhffffffiiiiii', 'laser'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
108 86: ('hhffffffiiiiii', 'laser2'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
109 87: ('i', 'set_upcoming_id'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
129 109: ('ii', 'memory_write_int'),
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
25ca15f714ad Add/fix a few opcodes
Thibaut Girka <thib@sitedethib.com>
parents: 43
diff changeset
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
3da4de9decd0 Use logging module
Thibaut Girka <thib@sitedethib.com>
parents: 52
diff changeset
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
732c64662f87 Minor changes
Thibaut Girka <thib@sitedethib.com>
parents: 112
diff changeset
289 try:
732c64662f87 Minor changes
Thibaut Girka <thib@sitedethib.com>
parents: 112
diff changeset
290 instruction_datas.append(pack(format, time, opcode, size, rank_mask, param_mask, *args))
732c64662f87 Minor changes
Thibaut Girka <thib@sitedethib.com>
parents: 112
diff changeset
291 except struct.error:
732c64662f87 Minor changes
Thibaut Girka <thib@sitedethib.com>
parents: 112
diff changeset
292 logger.error('Failed to assemble opcode %d' % opcode)
732c64662f87 Minor changes
Thibaut Girka <thib@sitedethib.com>
parents: 112
diff changeset
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