Mercurial > touhou-doc
changeset 13:2925b0e246c6 default tip
Fix a lot of things, and add a TODO.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 17 Feb 2012 12:54:08 +0100 |
parents | 79dfd9765a67 |
children | |
files | 06/anm.xml 06/cfg.txt 06/ecl.xhtml 06/ecl.xml 06/msg.xml 06/pbg3.xhtml 06/std.xhtml 06/t6rp.xhtml 07/sht.xhtml 10/ecl.xml TODO.txt html.xsl index.xhtml |
diffstat | 13 files changed, 352 insertions(+), 215 deletions(-) [+] |
line wrap: on
line diff
--- a/06/anm.xml +++ b/06/anm.xml @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="../html.xsl"?> <?xml-stylesheet type="text/css" href="../style.css"?> -<!DOCTYPE html> <opcodes xmlns="urn:opcodes:description"> <title>ANM opcodes</title> <op> <num>0</num> + <name>delete</name> </op> <op> @@ -96,17 +96,19 @@ <num>12</num> <name>fade</name> <params> - <param type="f" name="new_alpha"/> + <param type="S" name="new_alpha"/> <param type="S" name="duration" unit="frames"/> </params> </op> <op> <num>13</num> + <name>set_blendfunc_alphablend</name> </op> <op> <num>14</num> + <name>set_blendfunc_add</name> </op> <op> @@ -127,6 +129,7 @@ <op> <num>17</num> + <name>set_3d_translation</name> <params> <param type="f"/> <param type="f"/> @@ -136,43 +139,53 @@ <op> <num>18</num> + <name>move_to_linear</name> <params> - <param type="f"/> - <param type="f"/> - <param type="S"/> - <param type="S"/> + <param type="f" name="x"/> + <param type="f" name="y"/> + <param type="f" name="y"/> + <param type="S" name="duration"/> </params> + <desc>Move the sprite in the indicated coordinates in `duration` seconds.</desc> </op> <op> <num>19</num> + <name>move_to_decel</name> <params> - <param type="f"/> - <param type="f"/> - <param type="S"/> - <param type="S"/> + <param type="f" name="x"/> + <param type="f" name="y"/> + <param type="f" name="z"/> + <param type="S" name="duration"/> </params> + <desc>Move the sprite in the indicated coordinates in `duration` seconds.</desc> </op> <op> <num>20</num> + <name>move_to_accel</name> <params> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="S"/> + <param type="f" name="x"/> + <param type="f" name="y"/> + <param type="f" name="z"/> + <param type="S" name="duration"/> </params> + <desc>Move the sprite in the indicated coordinates in `duration` seconds.</desc> </op> <op> <num>21</num> + <name>wait_event</name> + <desc>Wait for an event.</desc> </op> <op> <num>22</num> + <name>set_event</name> <params> <param type="S"/> </params> + <desc>Set the event number to wait for.</desc> </op> <op> @@ -184,13 +197,17 @@ <op> <num>24</num> + <name>?_event</name> + <desc>Has something to do with events.</desc> </op> <op> <num>25</num> + <name>set_allow_dest_offset</name> <params> <param type="S"/> </params> + <desc></desc> </op> <op> @@ -222,9 +239,11 @@ <op> <num>29</num> + <name></name> <params> <param type="S"/> </params> + <desc></desc> </op> <op> @@ -240,8 +259,10 @@ <op> <num>31</num> + <name></name> <params> <param type="S"/> </params> + <desc></desc> </op> </opcodes>
new file mode 100644 --- /dev/null +++ b/06/cfg.txt @@ -0,0 +1,54 @@ +0: 00 +1: 00 +2: 01 +3: 00 +4: 00 +5: 00 +6: ff +7: ff +8: ff +9: ff +a: ff +b: ff +c: ff +d: ff +e: ff +f: ff +10: ff +11: ff +12: 00 +13: 00 +14: 02 +15: 01 +16: 00 +17: 00 +18: 02 +19: 03 +1a: 00 = 32 bits, 01 = 16 bits +1b: 02 +1c: 01 +1d: 01 +1e: 00 = fullscreen, 01 = windowed +1f: 00 = 1/1, 01 = 1/2, 02 = 1/3 +20-21: uint16_t, Pad X Axis +22-23: uint16_t, Pad Y Axis +24: 00 +25: 00 +26: 00 +27: 00 +28: 00 +29: 00 +2a: 00 +2b: 00 +2c: 00 +2d: 00 +2e: 00 +2f: 00 +30: 00 +31: 00 +32: 00 +33: 00 +34: 01 = nothing, 02 = No Vertex buffer, 04 = 16 Bits textures, 08 = Clear back buffer on refresh, 10 = Display minimum graphics needed, 20 = Controlled use of gouraud shading, 40 = No Depth Test, 80 = Force 60 fps +35: 00 = nothing, 01 = Color composition is not applied to textures, 02 = Start in reference rasterized mode, 04 = No fog, 08 = No DirectInput Pad +36: 00 +37: 00
--- a/06/ecl.xhtml +++ b/06/ecl.xhtml @@ -59,13 +59,12 @@ typedef struct { float x; float y; float z; // Unused, always 0. - int16_t resistance; // From 0 to 0x7fff; greater is equal to 0. + int16_t life; // From 0 to 0x7fff; lower than 0 is equal to 1. int16_t object_dropped; // Between -2 and 2. - // 0000 to 00ff: power - // ff00 to ffff: random + // 0 to 6: <a href="ecl.xml#i124">corresponding bonus</a> + // -1: random // other: nothing - uint16_t unknown1; - uint16_t unknown2; // 0 for normal enemies; 1 for mid-boss; 3 or 4 for boss. + uint32_t die_score; } thecl_enemy_t; </pre> @@ -103,9 +102,9 @@ typedef struct { <li>normal enemy</li> <li class="used">mirrored enemy</li> <li>mirrored enemy</li> - <li class="used">normal enemy</li> + <li class="used">normal enemy (random placement)</li> <li>normal enemy (random placement)</li> - <li class="used">mirrored enemy</li> + <li class="used">mirrored enemy (random placement)</li> <li>mirrored enemy (random placement)</li> <li class="used">starts the msg (which?)</li> <li class="used">nothing?</li>
--- a/06/ecl.xml +++ b/06/ecl.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="../html.xsl"?> <?xml-stylesheet type="text/css" href="../style.css"?> -<!DOCTYPE html> <opcodes xmlns="urn:opcodes:description"> <title>ECL Sub format</title> @@ -50,13 +49,13 @@ else <tr><td>-10014</td><td>int</td> <td>difficulty</td> <td>ro</td> <td>Unused.</td></tr> <tr><td>-10015</td><td>float</td> <td>x</td> <td>rw</td> <td></td></tr> <tr><td>-10016</td><td>float</td> <td>y</td> <td>rw</td> <td></td></tr> - <tr><td>-10017</td><td>float</td> <td>z</td> <td>rw</td> <td></td></tr> + <tr><td>-10017</td><td>float</td> <td>z</td> <td>rw</td> <td>Actually used by Flandre. Warning!</td></tr> <tr><td>-10018</td><td>float</td> <td>player_x</td> <td>ro</td> <td></td></tr> <tr><td>-10019</td><td>float</td> <td>player_y</td> <td>ro</td> <td></td></tr> <tr><td>-10020</td><td>float</td> <td></td> <td>ro</td> <td>Unused.</td></tr> - <tr><td>-10021</td><td>float</td> <td>enemy_player_angle</td> <td>ro</td> <td></td></tr> + <tr><td>-10021</td><td>float</td> <td>player_angle</td> <td>ro</td> <td></td></tr> <tr><td>-10022</td><td>int</td> <td>last_frame</td> <td>rw</td> <td></td></tr> - <tr><td>-10023</td><td>float</td> <td>enemy_player_distance</td><td>ro</td><td>Unused.</td></tr> + <tr><td>-10023</td><td>float</td> <td>player_distance</td><td>ro</td> <td>Unused.</td></tr> <tr><td>-10024</td><td>int</td> <td>life</td> <td>rw</td> <td></td></tr> <tr><td>-10025</td><td>int</td> <td>player</td> <td>ro</td> <td>0 = ReimuA, 1 = ReimuB, 2 = MarisaA, 3 = MarisaB</td></tr> </table> @@ -337,7 +336,7 @@ else <param type="S" name="new_frame" unit="frame" values="120"/> <param type="S" name="relative_offset" unit="bytes" values="64"/> </params> - <desc>Like <ref>2</ref> but only when the comparison register equals to 1. Used only one time in <stage>4</stage>.</desc> + <desc>Like <ref>2</ref> but only when the comparison register equals to 1.</desc> </op> <op> @@ -445,7 +444,7 @@ else <param type="f" name="min" unit="radian" values="0.7853982f"/> <param type="f" name="max" unit="radian" values="2.3561945f"/> </params> - <desc>Set the enemy angle in the [min, max-min) range. Used only five times, in <stage>2</stage>.</desc> + <desc>Set the enemy angle in the [min, max-min) range.</desc> </op> <op> @@ -465,7 +464,7 @@ else <param type="S" value="0">Ignored</param> <param type="f" name="speed" unit="pixels/frame"/> </params> - <desc>Sets the speed of the enemy, and change its direction to where the player is at that frame. Used only one time in <stage>2</stage>.</desc> + <desc>Sets the speed of the enemy, and change its direction to where the player is at that frame.</desc> </op> <op> @@ -488,7 +487,7 @@ else <param type="f" name="y" unit="pixels"/> <param type="f" name="z" unit="pixels" values="0.0f">Ignored</param> </params> - <desc>Move the enemy to the new position in `duration` amount of frames, using the <code>x↦x</code> function. Used only two times in <stage>7</stage>.</desc> + <desc>Move the enemy to the new position in `duration` amount of frames, using the <code>x↦x</code> function.</desc> </op> <op> @@ -571,102 +570,42 @@ else <op> <num>68</num> <name>set_bullet_attributes_to_the_right</name> - <params> - <param type="s"/> - <param type="s"/> - <param type="S"/> - <param type="S"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="S"/> - </params> + <params ref="67"/> <desc>The same as <ref>67</ref>, except the 0.0f launch angle is to the right of the enemy, instead of towards the player.</desc> </op> <op> <num>69</num> <name>set_bullet_attributes_towards_player_equally_distributed</name> - <params> - <param type="s"/> - <param type="s"/> - <param type="S"/> - <param type="S"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="S"/> - </params> + <params ref="67"/> <desc>Like <ref>67</ref>, except bullets of a shot are distributed equally all around the enemy, computing the angle by itself.</desc> </op> <op> <num>70</num> <name>set_bullet_attributes_to_the_right_equally_distributed</name> - <params> - <param type="s"/> - <param type="s"/> - <param type="S"/> - <param type="S"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="S"/> - </params> + <params ref="67"/> <desc>Like <ref>68</ref>, except bullets of a shot are distributed equally all around the enemy, computing the angle by itself.</desc> </op> <op> <num>71</num> <name>set_bullet_attributes_towards_player_equally_distributed_and_rotated</name> - <params> - <param type="s"/> - <param type="s"/> - <param type="S"/> - <param type="S"/> - <param type="f"/> - <param type="f"/> - <param type="f" values="0.0f"/> - <param type="f" values="0.0f"/> - <param type="S"/> - </params> + <params ref="67"/> <desc>Like <ref>69</ref>, but with a rotation of pi/bullets_per_shot.</desc> </op> <op> <num>74</num> <name>set_bullet_attributes_towards_player_randomly_distributed</name> - <params> - <param type="s"/> - <param type="s"/> - <param type="S"/> - <param type="S"/> - <param type="f"/> - <param type="f"/> - <param type="f" values="0.0f"/> - <param type="f" values="0.0f"/> - <param type="S"/> - </params> - <desc>Used only one time, in <stage>3</stage>. Like <ref>70</ref> but with some alea (?) in the angle.</desc> + <params ref="67"/> + <desc>Like <ref>70</ref> but with some alea (?) in the angle.</desc> </op> <op> <num>75</num> <name>set_bullet_attributes_to_the_right_with_some_random_angle</name> - <params> - <param type="s"/> - <param type="s"/> - <param type="S"/> - <param type="S"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="f"/> - <param type="S"/> - </params> + <params ref="67"/> <desc>Like <ref>68</ref>, but with some random angle.</desc> </op> @@ -752,7 +691,7 @@ else <dt>1024: <code><ref>82</ref>(int nb_bounces,,,, float speed,,,)</code></dt> <dd>Bullets “bounce”, reentering the screen as soon as they leave it, with a new speed set.</dd> <dt>2048:</dt> - <dd>Like 1024, except it only bounces when colliding with the left and right edges.</dd></dl></desc> + <dd>Like 1024, except it only bounces when colliding with the left, upper and right edges.</dd></dl></desc> </op> <op> @@ -774,13 +713,13 @@ else <num>85</num> <name>laser</name> <params> - <param type="s"/> - <param type="s"/> - <param type="f" name="angle" unit="radian">clockwise, from the +x axis</param> + <param type="s" name="laser_type" unit="script"/> + <param type="s" name="sprite_index_offset" unit="script"/> + <param type="f" name="angle" unit="radian">clockwise</param> <param type="S" name="speed" unit="pixels/frame">speed of the laser along its axis</param> <param type="f" name="start_offset" unit="pixels">offset along the laser axis, relative to the enemy. If negative, it is considered as 0.</param> <param type="f" name="end_offset" unit="pixels">offset along the laser axis, relative to the enemy. Can be negative. In case end_offset < start_offset, the laser will be in the oposite direction.</param> - <param type="f" name="length" unit="pixels">TODO: Not really a length, something really odd. The laser starts at max(start_offset, end_offset - length) and ends at end_offset.</param> + <param type="f" name="max_length" unit="pixels">TODO: Not really a length, something really odd. The laser starts at max(start_offset, end_offset - length) and ends at end_offset.</param> <param type="f" name="width" unit="pixels"/> <param type="S" name="start_duration" unit="frames"/> <param type="S" name="duration" unit="frames"/> @@ -795,22 +734,7 @@ else <op> <num>86</num> <name>laser_towards_player</name> - <params> - <param type="s"/> - <param type="s"/> - <param type="f" name="angle" unit="radian">clockwise, from the enemy->player axis</param> - <param type="S" name="speed" unit="pixels/frame">speed of the laser along its axis</param> - <param type="f" name="start_offset" unit="pixels">offset along the laser axis, relative to the enemy. If negative, it is considered as 0.</param> - <param type="f" name="end_offset" unit="pixels">offset along the laser axis, relative to the enemy. Can be negative. In case end_offset < start_offset, the laser will be in the oposite direction.</param> - <param type="f" name="length" unit="pixels">TODO: Not really a length, something really odd. The laser starts at max(start_offset, end_offset - length) and ends at end_offset.</param> - <param type="f" name="width" unit="pixels"/> - <param type="S" name="start_duration" unit="frames"/> - <param type="S" name="duration" unit="frames"/> - <param type="S" name="stop_duration" unit="frames"/> - <param type="S" name="grazing_dealy" unit="frames">how long to wait before allowing grazing</param> - <param type="S" name="grazing_extra_duration" unit="frames">how long to allow grazing after the laser started to disappear</param> - <param type="S" values="0"/> - </params> + <params ref="85"/> <desc>Like <ref>85</ref>, with the default direction towards the player.</desc> </op> @@ -835,40 +759,56 @@ else <op> <num>90</num> - <name></name> + <name>translate_laser</name> <params> - <param type="S" values="0 to 3"/> - <param type="S" values="0">Perhaps a float?</param> - <param type="S" values="0">Perhaps a float?</param> - <param type="S" values="0">Perhaps a float?</param> + <param type="S" values="0 to 3" name="laser" unit="laser_id"/> + <param type="f" values="0.0f" name="x" unit="pixels"/> + <param type="f" values="0.0f" name="y" unit="pixels"/> + <param type="f" values="0.0f" name="z" unit="pixels">Ignored</param> </params> - <desc>Used only in <stage>7</stage>.</desc> + <desc>Translate a laser with the current position of the launching enemy as origin, but don’t follow her after that.</desc> </op> <op> <num>92</num> - <name></name> + <name>cancel_laser</name> <params> - <param type="S" values="0 to 3"/> + <param type="S" values="0 to 3" name="laser" unit="laser_id"/> </params> - <desc>Used only in <stage>7</stage>.</desc> + <desc>Cancel a laser before its normal duration.</desc> </op> <op> <num>93</num> <name>set_spellcard</name> <params> - <param type="s" value="0 to 3"/> + <param type="s" name="face" value="0 to 3">If greater than 3, it’s the character faces that are used.</param> <param type="s" name="number">As in the captured spellcards screen, minus 1.</param> <param type="z" name="name">In SHIFT_JIS</param> </params> - <desc></desc> + <desc> + <p>Start a spellcard and</p> + <ul> + <li>Display the name of the spellcard in the screen.</li> + <li>Change the background to the eff one.</li> + <li>Make the enemies more resistant or the attacks weaker. The damage caused by a bullet is reduced to 6 instead of 48.</li> + <li>Clear all the bullets and transform them in star bonus.</li> + </ul> + </desc> </op> <op> <num>94</num> <name>end_spellcard</name> - <desc>Finish the current spellcard.</desc> + <desc> + <p>Finish the current spellcard and</p> + <ul> + <li>Remove its name.</li> + <li>Put back the normal background.</li> + <li>Return the damages to the normal.</li> + <li>Clear all the bullets and transform them in star bonus.</li> + </ul> + </desc> </op> <op> @@ -881,8 +821,7 @@ else <param type="f" name="z" unit="pixels" var="can" values="-10017.0f, -1.5707964f to 3.3379421f, 160.0f, 288.0f"/> <param type="s" name="resistance" values="-5536, 2 to 2000"/> <param type="s" name="drop_type" values="-2, 0, 1, 2"/> - <param type="s" name="unknown1" values="0, 10, 2000"/> - <param type="s" name="unknown2" values="0"/> + <param type="S" name="die_score" values="0, 10, 2000"/> </params> <desc>Spawns an enemy, see <a href="ecl.xhtml#enemy_sub">the main creation of an enemy</a>.</desc> </op> @@ -890,7 +829,7 @@ else <op> <num>96</num> <name>kill_all_enemies</name> - <desc>Instantly kill all enemies presents in the screen, dropping their bonus as if they were killed by the player. Seems to not kill if the enemy is not touchable (see <ref>117</ref>).</desc> + <desc>Instantly kill all enemies presents in the screen, dropping their bonus as if they were killed by the player. Seems to not kill if the enemy is not touchable (see <ref>117</ref>) or a boss (see <ref>101</ref>).</desc> </op> <op> @@ -918,12 +857,12 @@ else <op> <num>99</num> - <name></name> + <name>set_aux_anim</name> <params> - <param type="S" values="0, 4"/> - <param type="S" values="16 to 18, 66"/> + <param type="S" name="number" values="0, 4"/> + <param type="S" name="animation" unit="script" values="16 to 18, 66"/> </params> - <desc></desc> + <desc>Add an auxiliary animation (up to 8) with always the same coordinates as the enemy.</desc> </op> <op> @@ -939,9 +878,9 @@ else <num>101</num> <name>set_boss_mode</name> <params> - <param type="S" values="-1, 0">Unknown meaning, seems to be 0 for mid-boss and -1 for real boss.</param> + <param type="S" name="x" values="-1, 0">0 is activate, -1 is deactivate.</param> </params> - <desc>Activates the boss mode, with her life bar and lives number displayed on the top. Doesn't do anything before calling <ref>126</ref>.</desc> + <desc>Activates the boss mode, with her life bar and lives number displayed on the top. Doesn't do anything before calling <ref>126</ref> (TODO: really?). If there are multiple boss, spawned by a <ref>95</ref>, only the last one has her life displayed, but standard enemies are blocked only until any of them is killed.</desc> </op> <op> @@ -1005,7 +944,14 @@ else <params> <param type="S"/> </params> - <desc>Control what to do when life falls to zero. 0 = normal, 1 = don't clean the sprite, 2 = don't die, 4 (unused) = don't die and don't drop bonus. These are flags that can be combined.</desc> + <desc> + <p>Control what to do when life falls to zero, only in the [0, 7] interval:</p> + <p>0 = normal;<br/> + 1 = die once and unset touchable/collidable;<br/> + 2 = die in loop (drop an item each time, start a new die animation), but keep being here, touchable/collidable;<br/> + 3 = die once and keep being touchable/collidable if killed by the normal attack, else die as in normal (with a bomb, a collision, a <ref>96</ref>…), even after dying once from a normal attack;<br/> + 4-7 (unused) = die in loop, with lot of sparks, but don't drop bonus.</p> + </desc> </op> <op> @@ -1014,7 +960,7 @@ else <params> <param type="S" name="function" unit="sub"/> </params> - <desc>Specify the subroutine to call when the enemy is killed.</desc> + <desc>Specify the subroutine to call when the enemy is killed. Only if the death flag is not null.</desc> </op> <op> @@ -1140,16 +1086,19 @@ memory[offset] = value;</pre> <tr><th>Function</th><th>Description</th></tr> <tr><td>0</td><td>Freeze all the bullets in the screen if the parameter is 0, else unfreeze them. Do an explosion animation too.</td></tr> <tr><td>1</td><td>Launch a bullet immediately, with a launch_offset of [-param, param] for each coordinate.</td></tr> - <tr><td>3</td><td>Do nothing?</td></tr> + <tr><td>3</td><td>Change the -10002, -10003 and -10004 variables according to the character. [0, 3, 1] for ReimuA, [2, 3, 4] for ReimuB, [1, 4, 0] for MarisaA and [4, 2, 3] for MarisaB. Used to choose the dual-sign spellcards of Patchouli. The parameter is unused.</td></tr> <tr><td>4</td><td>If 0, unfreeze time and do an explosion animation. If 1, freeze time for the player, the bullets, the texts, but let the ECL run normally, also do an explosion animation. Else do nothing.</td></tr> <tr><td>7</td><td>If 0, make a lasers web, and remove any previous. Else, a crapload of bullets directed towards the player (TODO: find their origin).</td></tr> <tr><td>8</td><td>Do nothing?</td></tr> <tr><td>9</td><td>Do an explosion animation.</td></tr> <tr><td>11</td><td>Do an explosion animation.</td></tr> <tr><td>12</td><td>Do nothing?</td></tr> - <tr><td>13</td><td>Launch `param` bullets in circle towards the player with the launch point being the center of the screen.</td></tr> + <tr><td>13</td><td>Fire `param` times the configured attack in circle, as if the enemy was at the center of the screen with:<ul> + <li>-10006 that overrides the launch_angle set in 67-75;</li> + <li>-10007 the rotation of the launch points with the center of the screen as origin;</li> + <li>-10008 the distance between the center of the screen and the launch points.</li></ul>Seems to be launched only each 6 frames, even if the call is each frame.</td></tr> <tr><td>14</td><td>Do nothing?</td></tr> - <tr><td>16</td><td>Do nothing?</td></tr> + <tr><td>16</td><td>Used in QED: Ripples of 495 Years and probably do a temporization and modify launch_offset.</td></tr> </table> </desc> </op> @@ -1167,9 +1116,9 @@ memory[offset] = value;</pre> <tr><td>-1</td><td>Stop</td></tr> <tr><td>2</td><td>Do nothing?</td></tr> <tr><td>5</td><td>Sakuya’s knives, each 12 frames.</td></tr> - <tr><td>6</td><td>Some graphic animation.</td></tr> + <tr><td>6</td><td>Add a wings flapping animation. Used by the Scarlet sisters.</td></tr> <tr><td>10</td><td>Some graphic animation.</td></tr> - <tr><td>15</td><td>Some graphic animation.</td></tr> + <tr><td>15</td><td>The bullets 6, 7, 8 and 9 push the 1, 2, 3, 4 and 5 bullets. Also do some graphic animation.</td></tr> </table> </desc> </op> @@ -1187,7 +1136,7 @@ memory[offset] = value;</pre> <num>124</num> <name>drop_specific_bonus</name> <params> - <param type="S" name="type">0 = power, 1 = point, 2 = big power, 3 = bomb, 4 = full power, 5 = 1up, 6 = star bonus, greater drop nothing.</param> + <param type="S" name="type" var="no">0 = power, 1 = point, 2 = big power, 3 = bomb, 4 = full power, 5 = 1up, 6 = star bonus, greater drop nothing.</param> </params> <desc>Drop a bonus vertically. Can be called multiple times to drop more items, but they'll be superposed.</desc> </op> @@ -1218,11 +1167,11 @@ memory[offset] = value;</pre> <op> <num>128</num> - <name>set_smooth_disappear</name> + <name>interrupt_anm</name> <params> - <param type="S" values="1">Bitfield</param> + <param type="S" name="interruption" values="1"/> </params> - <desc>If <code>x & 1</code>, make the enemy sprite diseappear in a fade out now, not abruptly at <ref>1</ref>. TODO: check the duration.</desc> + <desc>Send this interruption to the anm.</desc> </op> <op> @@ -1246,25 +1195,27 @@ memory[offset] = value;</pre> <op> <num>131</num> - <name></name> + <name>set_difficulty_influence</name> <params> - <param type="f" values="-1.0f, -0.5f, -0.3f, 0.0f"/> - <param type="f" values="0.0f, 0.3f, 0.8f, 1.0f"/> - <param type="S" values="-3, -2, -1, 0"/> - <param type="S" values="0, 2, 4, 5, 6"/> - <param type="S" values="0"/> - <param type="S" values="0"/> + <param type="f" name="speed_low" values="-1.0f, -0.5f, -0.3f, 0.0f"/> + <param type="f" name="speed_high" values="0.0f, 0.3f, 0.8f, 1.0f"/> + <param type="S" name="delay_low" values="-3, -2, -1, 0"/> + <param type="S" name="delay_high" values="0, 2, 4, 5, 6"/> + <param type="S" name="shots_low" values="0"/> + <param type="S" name="shots_high" values="0"/> </params> - <desc></desc> + <desc>Change the influence of the difficulty on the attacks. The defaults are (-0.5f, 0.5f, 0, 0, 0, 0).</desc> </op> <op> <num>132</num> - <name>set_visible</name> + <name>set_invisible</name> <params> <param type="S" values="0, 1">Bitfield</param> </params> - <desc>If <code>x & 1</code>, disable drawing of the sprite <strong>and</strong> destroy it. While it isn’t set to 0, loading a new sprite won’t make it reappear.</desc> + <desc><div xmlns="http://www.w3.org/1999/xhtml"> + If <code>x & 1</code>, disable drawing of the sprite <strong>and</strong> destroy it. While it isn’t set to 0, loading a new sprite won’t make it reappear. + </div></desc> </op> <op> @@ -1281,10 +1232,10 @@ memory[offset] = value;</pre> <op> <num>135</num> - <name></name> + <name>enable_spellcard_bonus</name> <params> <param type="S" values="0, 1">Bitfield</param> </params> - <desc></desc> + <desc>If <code>x & 1</code>, FIXME. Enabled is the default.</desc> </op> </opcodes>
--- a/06/msg.xml +++ b/06/msg.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="../html.xsl"?> <?xml-stylesheet type="text/css" href="../style.css"?> -<!DOCTYPE html> <opcodes xmlns="urn:opcodes:description"> <title>MSG opcodes</title> @@ -13,10 +12,10 @@ <op> <num>1</num> - <name></name> + <name>enter</name> <params> - <param type="s"></param> - <param type="s"></param> + <param type="s" name="side">0 is left, 1 is right.</param> + <param type="s" name="effect"/> </params> <desc></desc> </op> @@ -25,8 +24,8 @@ <num>2</num> <name>change_face</name> <params> - <param type="s" values="1, 0">Affected girl (0 is left, 1 is right)</param> - <param type="s">Sprite to use.</param> + <param type="s" name="side"/> + <param type="s" name="sprite"/> </params> <desc></desc> </op> @@ -35,9 +34,9 @@ <num>3</num> <name>display</name> <params> - <param type="s" values="0, 1">Girl speaking (0 is left, 1 is right)</param> - <param type="s" values="0, 1">Line to which display.</param> - <param type="z">The text to display.</param> + <param type="s" name="side"/> + <param type="s" name="line">0 is top, 1 is bottom.</param> + <param type="z" name="text">Only one line.</param> </params> <desc>Displays a line of text.</desc> </op> @@ -46,7 +45,7 @@ <num>4</num> <name>pause</name> <params> - <param type="S">Number of frames to wait.</param> + <param type="S" name="duration" unit="frames"/> </params> <desc>Wait for the user to provide an input, or timeout.</desc> </op> @@ -55,8 +54,8 @@ <num>5</num> <name>switch</name> <params> - <param type="s" values="1, 0">Affected girl (0 is left, 1 is right)</param> - <param type="s" min="0" max="5">Animation to use (0=?; 1=appear; 2=unused (leave too?); 3=front; 4=back; 5=leave)</param> + <param type="s" name="side"/> + <param type="s" values="0 to 5">Animation to use (0=?; 1=appear; 2=unused (leave too?); 3=front; 4=back; 5=leave)</param> </params> <desc>Makes one of the two girls come to or leave the screen.</desc> </op> @@ -71,7 +70,7 @@ <num>7</num> <name>music</name> <params> - <param type="S">Music number.</param> + <param type="S" name="music_id"/> </params> <desc>Plays the selected music.</desc> </op> @@ -80,26 +79,26 @@ <num>8</num> <name>display2</name> <params> - <param type="s" values="0, 1">Girl speaking (0 is left, 1 is right)</param> - <param type="s" values="0, 1">Line to which display.</param> - <param type="z">The text to display.</param> + <param type="s" name="side"/> + <param type="s" name="line">0 is top, 1 is bottom.</param> + <param type="z" name="text">Only one line.</param> </params> <desc>Displays a line of text on a character. Always used to introduce her.</desc> </op> <op> <num>9</num> - <name></name> + <name>show_scores</name> <params> - <param type="S"></param> + <param type="S">Unused?</param> </params> - <desc></desc> + <desc>Display the score panel.</desc> </op> <op> <num>10</num> - <name></name> - <desc></desc> + <name>freeze</name> + <desc>Disable the input and fige the pause.</desc> </op> <op> @@ -116,11 +115,11 @@ <op> <num>13</num> - <name></name> + <name>allow_skip</name> <params> - <param type="S"></param> + <param type="S">boolean</param> </params> - <desc></desc> + <desc>If 0 disallow, if 1 allow.</desc> </op> <op>
--- a/06/pbg3.xhtml +++ b/06/pbg3.xhtml @@ -44,7 +44,7 @@ It consists of a sequence of entries.<br/> Each entry is composed of five fields:</p> <ul> - <li>unknown1 (int) #TODO</li> + <li>unknown1 (int): the same for every entry of an archive, and without much change between two archives #TODO</li> <li>unknown2 (int) #TODO</li> <li>checksum (int): simple checksum of compressed data</li> <li>size (int): size of uncompressed data</li>
--- a/06/std.xhtml +++ b/06/std.xhtml @@ -32,16 +32,18 @@ typedef struct { <h2>First section</h2> <p>This section is responsible for creating objects from the stgxbg.anm file.</p> <pre> -struct object_header { +typedef struct { uint16_t id; // Always equal to the object's number. Not used by the game. - uint16_t unknown1; //TODO - float unknown2; //TODO - uint32_t unknown3; //TODO - float unknown4; //TODO - float unknown5; //TODO - float unknown6; //TODO - float unknown7; //TODO -}; + uint16_t unknown; //TODO + + // The bounding box. + float x; + float y; + float z; + float width; + float height; + float depth; +} object_header_t; typedef struct { uint16_t unknown; // 0 means a quad, 0xffff means the end. @@ -55,10 +57,10 @@ typedef struct { float height; // If not 0, override the sprite's height (else, use anm info) } thstd_object_t; -struct object { +typedef struct { struct object_header header; struct object_quad quads[]; // Stop when quads.unknown == 0x0004ff -}; +} object_t; </pre> @@ -146,7 +148,7 @@ typedef struct { list_t objects; list_t faces; list_t messages; -} PACK_ATTRIBUTE thstd_t; +} thstd_t; </pre> </body> </html>
--- a/06/t6rp.xhtml +++ b/06/t6rp.xhtml @@ -9,15 +9,14 @@ <h1>T6RP format</h1> <p>The T6RP format is the replay format used by EoSD.</p> - <p>It is composed of a header and an "encrypted" data section, which is itself composed of a header, per-stage structures and lists of keystates.</p> + <p>It is composed of a header and an “encrypted” data section, which is itself composed of a header, per-stage structures and lists of keystates.</p> <h2>Header</h2> <pre> typedef struct { char magic[4]; // T6RP - uint16_t unknown; //TODO: always 0x0102 - // Seems to be a switch, if 0x0102 do something, else (whatever the value is), do something else + uint16_t version; // 0x0102 for 1.02h uint8_t player; // 0 = ReimuA, 1 = ReimuB, 2 = MarisaA, 3 = MarisaB uint8_t rank; // 0 = Easy, 3 = Lunatic, 4 = Extra uint32_t checksum; // (0x3f000318 + key + sum(c for c in decrypted_data)) % (2 ** 32) @@ -69,9 +68,9 @@ typedef struct { int8_t lives; int8_t bombs; uint8_t difficulty; //TODO: WARNING: This has a huge effect on the game! - // It is also called rank (but we use the term "difficulty" because "rank" is the official name for Easy/Normal/Hard/Lunatic/Extra) + // It is also called rank (but we use the term “difficulty” because “rank” is the official name for Easy/Normal/Hard/Lunatic/Extra) // See: http://en.touhouwiki.net/wiki/Embodiment_of_Scarlet_Devil/Gameplay#Rank - uint8_t unknown3[3]; //TODO: seems to be ignored by the game. Padding? + uint32_t unknown3; //TODO: seems to be ignored by the game. Padding? thrpy6_keystate_t keystates[]; } thrpy6_stage_t; </pre>
new file mode 100644 --- /dev/null +++ b/07/sht.xhtml @@ -0,0 +1,73 @@ +<?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>SHT format</title> + </head> + <body> + <h1>SHT format</h1> + <p>The SHT format defines a character and its shots in PCB.</p> + + + <h2>Header</h2> +<pre> +typedef struct { + uint16_t unknown1; // Seems ignored + uint16_t level_count; + + // All hitboxes have only one value, the same for the width and the height. + float bombs; // Why is it a float? + float unknown2; //TODO + float hitbox; + float graze_hitbox; + float autocollected_item_speed; // Applies to all items going towards us + float item_hitbox; + float percentage_of_cherry_loss_on_die; //TODO: verify the formula + float point_of_collection; + float horizontal_vertical_speed; + float horizontal_vertical_focused_speed; + float diagonal_speed; + float diagonal_focused_speed; + + thsht_offset_t offsets[level_count]; + + thsht_shot_type_t shots[]; +} thsht_header_t; +</pre> + +<pre> +typedef struct { + uint32_t offset; + uint32_t power; +} thsht_offset_t; +</pre> + + <h2>Shot type</h2> +<pre> +typedef struct { + // If these 2 are 0xffff, then end the parsing. + uint16_t interval; + uint16_t unknown1; + + float x; + float y; + float hitbox_x; + float hitbox_y; + float angle; + float speed; + uint16_t damage; + uint8_t orb; // 0 = character, 1 = left orb, 2 = right orb + uint8_t unknown2; + uint16_t sprite; + uint16_t unknown3; + + // These 4 are actually booleans. + uint32_t unknown4; + uint32_t homing; // accelerates too + uint32_t unknown5; + uint32_t unknown6; +} thsht_shot_type_t; +</pre> + </body> +</html>
--- a/10/ecl.xml +++ b/10/ecl.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="../html.xsl"?> <?xml-stylesheet type="text/css" href="../style.css"?> -<!DOCTYPE html> <opcodes xmlns="urn:opcodes:description"> <title>ECL opcodes</title>
new file mode 100644 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,19 @@ +Documentation +- 10 instructions ECL restantes +- des fonctions hardcodées +- 3 instructions ANM restantes +- 4 instructions MSG restantes +- instructions END + +Moteur +- vm END +- homing de ReimuA, lasers de MarisaB +- les textes, OSD +- les effets genre explosions, carrés +- les bombes +- changement de niveau +- interface +- MUSIC! + +Plus tard +- Perfect Cherry Blossom
--- a/html.xsl +++ b/html.xsl @@ -33,7 +33,13 @@ </x:if> </h3> + <x:variable name="ref" select="o:params/@ref"/> <x:choose> + <x:when test="o:params/@ref"> + <x:call-template name="params"> + <x:with-param name="params" select="/o:opcodes/o:op[o:num = $ref]/o:params/o:param"/> + </x:call-template> + </x:when> <x:when test="o:params"> <x:apply-templates select="o:params"/> </x:when> @@ -45,17 +51,18 @@ <x:apply-templates select="o:desc"/> </x:template> - <x:template match="o:params"> + <x:template name="params" match="o:params"> + <x:param name="params" select="o:param"/> <table> <tr> <th>Type</th> - <x:if test="o:param/@name"><th>Name</th></x:if> - <x:if test="o:param/@unit"><th>Unit</th></x:if> - <x:if test="o:param/@var"><th>Variable</th></x:if> - <x:if test="o:param != ''"><th>Notes</th></x:if> - <x:if test="o:param/@values"><th>Values</th></x:if> + <x:if test="$params/@name"><th>Name</th></x:if> + <x:if test="$params/@unit"><th>Unit</th></x:if> + <x:if test="$params/@var"><th>Variable</th></x:if> + <x:if test="$params != ''"><th>Notes</th></x:if> + <x:if test="$params/@values"><th>Values</th></x:if> </tr> - <x:apply-templates select="o:param"/> + <x:apply-templates select="$params"/> </table> </x:template> @@ -97,14 +104,18 @@ </x:template> <x:template match="o:desc"> + <p> <x:choose> - <x:when test="count(*) > 1"> - <x:apply-templates/> + <x:when test="h:div"> + <x:for-each select="h:div/*"> + <x:call-template name="xhtml"/> + </x:for-each> </x:when> <x:otherwise> - <p><x:apply-templates/></p> + <x:apply-templates/> </x:otherwise> </x:choose> + </p> </x:template> <x:template name="xhtml" match="node() | @*">
--- a/index.xhtml +++ b/index.xhtml @@ -13,6 +13,7 @@ <li><a href="06/std.xhtml">STD</a> (stages)</li> <li><a href="06/ecl.xhtml">ECL</a> (enemies and patterns)</li> <li><a href="06/t6rp.xhtml">T6RP</a> (replays)</li> + <li><a href="06/cfg.txt">CFG</a> (configuration)</li> </ul> <h3>Opcodes</h3> <ul> @@ -21,16 +22,25 @@ <li><a href="06/msg.xml">MSG</a> (dialogs)</li> </ul> + + <h2>Perfect Cherry Blossom</h2> + <h3>Formats</h3> + <ul> + <li><a href="07/sht.xhtml">SHT</a> (characters)</li> + </ul> + + <h2>Mountain of Faith</h2> <ul> <li><a href="10/ecl.xml">ECL</a> (<a href="//code.google.com/p/thtk/wiki/Ecl10Reference">original</a>)</li> </ul> + <h2>Subterranean Animism</h2> <ul> <li><a href="//code.google.com/p/thtk/wiki/Ecl11Reference">ECL</a></li> </ul> - <p>The sources are <a href="//hg.linkmauve.fr/touhou-doc">here</a></p> + <p>The sources are <a href="//hg.linkmauve.fr/touhou-doc">here</a>, and a reimplementation in python is <a href="//hg.linkmauve.fr/touhou/">here</a>.</p> </body> </html>