view 06/ecl.xhtml @ 7:2a7b9d62c0c4

Fix details, and details and documentation for a few instructions
author Thibaut Girka <thib@sitedethib.com>
date Tue, 23 Aug 2011 11:58:03 +0200
parents b3644dff344c
children 79dfd9765a67
line wrap: on
line source

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="../style.css"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
	<head>
		<title>ECL format</title>
	</head>
	<body>
		<h1>ECL format</h1>

		<h2>Header</h2>
<pre>
typedef struct {
    uint32_t sub_count;
    uint32_t main_offset;
    uint32_t padding[2]; // Always 0.
    uint32_t subs_offsets[sub_count];
} thecl06_header_t;
</pre>


		<h2>Sub</h2>
		<p>Starting at 0x10.<br/>They describe the appearance and comportment of a certain type of enemy</p>
		<p>Ends with frame_num = 0xffffffff and opcode = 0xffff, for a size of 0xc (the minimum) and default masks.</p>
		<p>Parameters are dependants of the opcode.</p>
<pre>
typedef struct {
    uint32_t frame_num;
    uint16_t <a href="ecl.xml">opcode</a>;
    uint16_t size; // Never less than 0xc.
    uint16_t rank_mask; // the first byte is always 0xff, and the second the mask of the ranks to which the instruction applies, 1 for easy, 8 for lunatic.
    uint16_t param_mask; // Unused in EoSD, always 255. It is used in other Touhou games to indicate whether an argument is an "address" or not, though.
    unsigned char params[size-0xc];
} thecl06_sub_t;
</pre>


		<h2>Main</h2>
		<p>Each instruction contains its size (which is always greater than 8, or else the game crashs). The only values encountered in the game are 0x1c, 0x10 and 8, but values of 0x38 work (skip the next instruction).<br/>
		The frame_num must greater than or equal to the previous, or the instruction will be skipped.<br/>
		The parsing ends when frame_num is 0xffff.</p>
<pre>
typedef struct {
    uint16_t frame_num;
    uint16_t unused1;
    uint16_t unused2;
    uint16_t size;
    uint8_t arguments[size-8];
} thecl_main_instr_t;
</pre>

		<p>Most present instruction, that pops an enemy.</p>
<pre>
typedef struct {
    uint16_t time;
    uint16_t sub; // Sub function to use.
    uint16_t <a href="#type">type</a>;
    uint16_t size; // Really the size of the instruction. NOT ignored by the game.
    float x;
    float y;
    float z; // Unused, always 0.
    int16_t resistance; // From 0 to 0x7fff; greater is equal to 0.
    int16_t object_dropped; // Between -2 and 2.
			    // 0000 to 00ff: power
			    // ff00 to ffff: random
			    // other: nothing
    uint16_t unknown1;
    uint16_t unknown2; // 0 for normal enemies; 1 for mid-boss; 3 or 4 for boss.
} thecl_enemy_t;
</pre>

		<p>Unknown, used only at the end of each stage.</p>
<pre>
typedef struct {
    uint16_t time;
    uint16_t sub; // always 0.
    uint16_t <a href="#type">type</a>; // always 0xa.
    uint16_t size;
    float unused1; // always 0.
    float unused2; // always 0.
} thecl_other1_t;
</pre>

		<p>Unknown, used only at the end of each stage. Always in group of 1, 2 or 3, with a sequence of (9), (8, 9) or (0xc, 8, 9).</p>
<pre>
typedef struct {
    uint16_t time;
    uint16_t sub; // always 0.
    uint16_t <a href="#type">type</a>;
    uint16_t size;
} thecl_other2_t;
</pre>

		<h3 id="type">Type</h3>
		<p>Used in the game are: 0, 2, 4, 6 for the enemies (0x1c-long), 0xa for the 0x10-long instruction, and 8, 9 and 0xc for the 8-long one. Type might be quite a misnomer since those are pretty much flags.</p>
		<style type="text/css">
			li.used {
				font-weight: bold;
			}
		</style>
		<ol start="0">
			<li class="used">normal enemy</li>
			<li>normal enemy</li>
			<li class="used">mirrored enemy</li>
			<li>mirrored enemy</li>
			<li class="used">normal enemy</li>
			<li>normal enemy (random placement)</li>
			<li class="used">mirrored enemy</li>
			<li>mirrored enemy (random placement)</li>
			<li class="used">starts the msg (which?)</li>
			<li class="used">nothing?</li>
			<li class="used">crash!?</li>
			<li>nothing?</li>
			<li class="used">nothing?</li>
			etc.
		</ol>
	</body>
</html>