<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://www.metroid2002.com/retromodding/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jackoalan</id>
		<title>Retro Modding Wiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://www.metroid2002.com/retromodding/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jackoalan"/>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/wiki/Special:Contributions/Jackoalan"/>
		<updated>2026-05-02T17:48:33Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AROT_(MREA_Section)&amp;diff=1951</id>
		<title>AROT (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AROT_(MREA_Section)&amp;diff=1951"/>
				<updated>2018-10-19T05:59:56Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Octree2.svg|thumb|right|400px|Left: Recursive subdivision of a cube into [[wikipedia:octant (solid geometry)|octant]]s. Right: The corresponding octree.]]&lt;br /&gt;
&lt;br /&gt;
Within [[MREA (File Format)|MREA]] resources, the '''AROT section''' stores an [[wikipedia:Octree|octree]] which&lt;br /&gt;
is used to accelerate rendering of areas in back-to-front order. &lt;br /&gt;
&lt;br /&gt;
Octrees are a form of [[wikipedia:Binary Space Partitioning|BSP tree]] that subdivide an area in 3-dimensions.&lt;br /&gt;
They are structured recursively, starting with a ''root'' node and traversing their way to individual ''leaf'' nodes.&lt;br /&gt;
A full-branch octant will split sub-octants across 3-tiers, one for each dimension of euclidean space.&lt;br /&gt;
Retro uses a Z-major convention with (up to) 8 child-nodes subdivided as: 2 nodes along Z, 4 nodes along Y,&lt;br /&gt;
and 8 nodes along X. A set of three bit-flags in each node determines which dimensions are subdivided. &lt;br /&gt;
Nodes that do not subdivide all 3 dimensions will parent less child nodes as a result. &lt;br /&gt;
&lt;br /&gt;
Within each octant is an index to a [[wikipedia:Bit array|bitmap]] relating that AABB-volume to a set of meshes within the MREA; they&lt;br /&gt;
are sorted and frustum-culled accordingly. Actors, particle effects, and other visual entities are also sorted and&lt;br /&gt;
frustum-culled according to which octant(s) they intersect.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Element Count&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| [[#Header|Header]]&lt;br /&gt;
| 1&lt;br /&gt;
| Octree Header&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| long&lt;br /&gt;
| round_up(bitmap_bit_count / 32) * bitmap_count&lt;br /&gt;
| Mesh Bitmap Array&lt;br /&gt;
| An array of word-packed bitmaps relating octant nodes to sets of MREA meshes&lt;br /&gt;
|-&lt;br /&gt;
| long&lt;br /&gt;
| node_count&lt;br /&gt;
| Node Indirection Table&lt;br /&gt;
| Since nodes use variable-length-encoding, there is an indirection table with byte-offsets (relative to first node)&lt;br /&gt;
|-&lt;br /&gt;
| [[#Node Entry|Node Entry]]&lt;br /&gt;
| node_count&lt;br /&gt;
| Node Entry Table&lt;br /&gt;
| Tightly-packed blob of nodes&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| long&lt;br /&gt;
| Magic&lt;br /&gt;
| &amp;lt;code&amp;gt;AROT&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| long&lt;br /&gt;
| Version&lt;br /&gt;
| Always 0x1&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| long&lt;br /&gt;
| Mesh-Bitmap Count&lt;br /&gt;
| Count of mesh-bitmaps&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| long&lt;br /&gt;
| Mesh-Bitmap Bit-Count&lt;br /&gt;
| Count of bits in each mesh-bitmap (matches MREA's mesh count)&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| long&lt;br /&gt;
| Node Count&lt;br /&gt;
| Number of octant nodes&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 24&lt;br /&gt;
| float2x3&lt;br /&gt;
| AABB&lt;br /&gt;
| AABB that fully-encloses area and serves as the octree's root-shape&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| 20&lt;br /&gt;
|&lt;br /&gt;
| Alignment Padding&lt;br /&gt;
| Allows the following bitmaps to be data-cached with guaranteed 32-byte alignment&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Node Entry ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| short&lt;br /&gt;
| Bitmap Index&lt;br /&gt;
| Index of the mesh bitmap defining a set of MREA meshes for this octant node&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| short&lt;br /&gt;
| Dimensional Flags&lt;br /&gt;
| If non-zero, this half-word contains 3-bits specifying which dimensions are subdivided using the children specified (using Z-major convention)&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;0x4 — Z subdivided&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;0x2 — Y subdivided&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;0x1 — X subdivided&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
'''If zero, this node-entry ends here'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| Varies&lt;br /&gt;
| short[]&lt;br /&gt;
| Node Child Indices&lt;br /&gt;
| Variable-length array of node-entry indices that are children of this node-entry (Z-major layout)&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1950</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1950"/>
				<updated>2018-09-04T05:32:27Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Region Info */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data when positive; -1 value terminates track; -2 value loops jumps to ''Loop Region Index'' at this region's tick&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop Region Index'''; index of region to jump to if ''Region Data Index'' set to -2&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 3 types of commands&lt;br /&gt;
in SNG: ''note'', ''control change'', and ''program change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time Encoding=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a fixed 16-bit&lt;br /&gt;
value to store the delta times. In case of a delta time greater than 65535, no-op commands&lt;br /&gt;
with a 65535 delta time are inserted into the command stream until the target time is attained.&lt;br /&gt;
&lt;br /&gt;
In a theoretical Python streaming API, the delta time can be decoded with no-ops automatically consumed like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTime(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        next = streamIn.PeekU16()&lt;br /&gt;
        if next == 0:&lt;br /&gt;
            # Automatically consume no-op and continue accumulating time value&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            streamIn.seekAhead(2)&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====No-Op Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time are both zero, this is a no-op command.&lt;br /&gt;
&lt;br /&gt;
As mentioned before, no-ops are useful for accumulating delta times greater than 65535.&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Program Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''program change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/gm-level-1-sound-set standard MIDI program numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always zero&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of program change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of&lt;br /&gt;
(delta-tick, delta-value) pairs. The delta times are encoded as unsigned 7/15 bit values&lt;br /&gt;
and the delta values are signed 7/15-bit values. The values are promoted to 15-bit if they&lt;br /&gt;
exceed their 7-bit range. In this case, the highest bit is set on the first byte in the pair&lt;br /&gt;
(0x80). The decoder must track the absolute time and value, summing each consecutive update&lt;br /&gt;
for the current time/values.&lt;br /&gt;
&lt;br /&gt;
The byte sequence 0x80 0x00 is a special case that signals the end of the stream.&lt;br /&gt;
&lt;br /&gt;
Similar to the command stream, when the delta time exceeds 15 bit range (&amp;gt;32767), extra pairs&lt;br /&gt;
with a zeroed value delta are inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def SignExtend7(value):&lt;br /&gt;
    return (value &amp;amp; 0x3f) - (value &amp;amp; 0x40)&lt;br /&gt;
&lt;br /&gt;
def SignExtend15(value):&lt;br /&gt;
    return (value &amp;amp; 0x3fff) - (value &amp;amp; 0x4000)&lt;br /&gt;
&lt;br /&gt;
def DecodeSignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return SignExtend15(byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8))&lt;br /&gt;
    else:&lt;br /&gt;
        return SignExtend7(byte0)&lt;br /&gt;
&lt;br /&gt;
def DecodeUnsignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8)&lt;br /&gt;
    else:&lt;br /&gt;
        return byte0&lt;br /&gt;
&lt;br /&gt;
def DecodeDeltaPair(streamIn):&lt;br /&gt;
    ret = [0,0]&lt;br /&gt;
    while ret[1] == 0:&lt;br /&gt;
        if streamIn.PeekU16() == 0x8000:&lt;br /&gt;
            # The stream has ended&lt;br /&gt;
            break&lt;br /&gt;
        ret[0] += DecodeUnsignedValue(streamIn)&lt;br /&gt;
        ret[1] = DecodeSignedValue(streamIn)&lt;br /&gt;
    return ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1947</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1947"/>
				<updated>2018-08-16T21:08:13Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Continuous Pitch / Modulation Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data via the ''region data index''; value is negative on a dummy ''region info'' to terminate track regions&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 3 types of commands&lt;br /&gt;
in SNG: ''note'', ''control change'', and ''program change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time Encoding=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a fixed 16-bit&lt;br /&gt;
value to store the delta times. In case of a delta time greater than 65535, no-op commands&lt;br /&gt;
with a 65535 delta time are inserted into the command stream until the target time is attained.&lt;br /&gt;
&lt;br /&gt;
In a theoretical Python streaming API, the delta time can be decoded with no-ops automatically consumed like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTime(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        next = streamIn.PeekU16()&lt;br /&gt;
        if next == 0:&lt;br /&gt;
            # Automatically consume no-op and continue accumulating time value&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            streamIn.seekAhead(2)&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====No-Op Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time are both zero, this is a no-op command.&lt;br /&gt;
&lt;br /&gt;
As mentioned before, no-ops are useful for accumulating delta times greater than 65535.&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Program Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''program change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/gm-level-1-sound-set standard MIDI program numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always zero&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of program change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of&lt;br /&gt;
(delta-tick, delta-value) pairs. The delta times are encoded as unsigned 7/15 bit values&lt;br /&gt;
and the delta values are signed 7/15-bit values. The values are promoted to 15-bit if they&lt;br /&gt;
exceed their 7-bit range. In this case, the highest bit is set on the first byte in the pair&lt;br /&gt;
(0x80). The decoder must track the absolute time and value, summing each consecutive update&lt;br /&gt;
for the current time/values.&lt;br /&gt;
&lt;br /&gt;
The byte sequence 0x80 0x00 is a special case that signals the end of the stream.&lt;br /&gt;
&lt;br /&gt;
Similar to the command stream, when the delta time exceeds 15 bit range (&amp;gt;32767), extra pairs&lt;br /&gt;
with a zeroed value delta are inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def SignExtend7(value):&lt;br /&gt;
    return (value &amp;amp; 0x3f) - (value &amp;amp; 0x40)&lt;br /&gt;
&lt;br /&gt;
def SignExtend15(value):&lt;br /&gt;
    return (value &amp;amp; 0x3fff) - (value &amp;amp; 0x4000)&lt;br /&gt;
&lt;br /&gt;
def DecodeSignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return SignExtend15(byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8))&lt;br /&gt;
    else:&lt;br /&gt;
        return SignExtend7(byte0)&lt;br /&gt;
&lt;br /&gt;
def DecodeUnsignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8)&lt;br /&gt;
    else:&lt;br /&gt;
        return byte0&lt;br /&gt;
&lt;br /&gt;
def DecodeDeltaPair(streamIn):&lt;br /&gt;
    ret = [0,0]&lt;br /&gt;
    while ret[1] == 0:&lt;br /&gt;
        if streamIn.PeekU16() == 0x8000:&lt;br /&gt;
            # The stream has ended&lt;br /&gt;
            break&lt;br /&gt;
        ret[0] += DecodeUnsignedValue(streamIn)&lt;br /&gt;
        ret[1] = DecodeSignedValue(streamIn)&lt;br /&gt;
    return ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1946</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1946"/>
				<updated>2018-08-16T20:56:54Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Normal / Drum Page Entry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/&amp;quot;. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID'''.&lt;br /&gt;
&lt;br /&gt;
Factor5 designed ObjectIDs to used in a polymorphic manner. The top 2 bits of the ID are used&lt;br /&gt;
to differentiate between SoundMacros, Keymaps, and Layers. If the ID passes a mask of 0x4000,&lt;br /&gt;
the object is a ''Keymap''. If the ID passes a mask of 0x8000, the object is a ''Layer''.&lt;br /&gt;
Otherwise, the object is assumed to be a ''SoundMacro''. ''Tables'' don't require this type of&lt;br /&gt;
polymorphism due to the context in which they are accessed.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x65&lt;br /&gt;
| SET_VAR&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Attack time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Decay time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values (although typically in MIDI range [0,127])&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Keymap and Layer IDs in these tables have their top 2 bits (indicating their type) masked off.&lt;br /&gt;
Keymaps must be OR'd with 0x4000 and Layers must be OR'd with 0x8000 in order to reconstruct the actual IDs.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' The drum table is accessed when the MIDI channel is 10, otherwise the normal table is accessed.&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Key'''; The default pitch - usually 0x3C (MIDI C4)&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Aruki will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1945</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1945"/>
				<updated>2018-08-16T20:56:43Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Normal / Drum Page Entry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/&amp;quot;. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID'''.&lt;br /&gt;
&lt;br /&gt;
Factor5 designed ObjectIDs to used in a polymorphic manner. The top 2 bits of the ID are used&lt;br /&gt;
to differentiate between SoundMacros, Keymaps, and Layers. If the ID passes a mask of 0x4000,&lt;br /&gt;
the object is a ''Keymap''. If the ID passes a mask of 0x8000, the object is a ''Layer''.&lt;br /&gt;
Otherwise, the object is assumed to be a ''SoundMacro''. ''Tables'' don't require this type of&lt;br /&gt;
polymorphism due to the context in which they are accessed.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x65&lt;br /&gt;
| SET_VAR&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Attack time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Decay time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values (although typically in MIDI range [0,127])&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Keymap and Layer IDs in these tables have their top 2 bits (indicating their type) masked off.&lt;br /&gt;
Keymaps must be OR'd with 0x4000 and Layers must be OR'd with 0x8000 in order to reconstruct the actual IDs.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
''Note:'' The drum table is accessed when the MIDI channel is 10, otherwise the normal table is accessed.&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Key'''; The default pitch - usually 0x3C (MIDI C4)&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Aruki will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1944</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1944"/>
				<updated>2018-08-16T20:54:09Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* SFX Entry */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/&amp;quot;. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID'''.&lt;br /&gt;
&lt;br /&gt;
Factor5 designed ObjectIDs to used in a polymorphic manner. The top 2 bits of the ID are used&lt;br /&gt;
to differentiate between SoundMacros, Keymaps, and Layers. If the ID passes a mask of 0x4000,&lt;br /&gt;
the object is a ''Keymap''. If the ID passes a mask of 0x8000, the object is a ''Layer''.&lt;br /&gt;
Otherwise, the object is assumed to be a ''SoundMacro''. ''Tables'' don't require this type of&lt;br /&gt;
polymorphism due to the context in which they are accessed.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x65&lt;br /&gt;
| SET_VAR&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Attack time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Decay time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values (although typically in MIDI range [0,127])&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Keymap and Layer IDs in these tables have their top 2 bits (indicating their type) masked off.&lt;br /&gt;
Keymaps must be OR'd with 0x4000 and Layers must be OR'd with 0x8000 in order to reconstruct the actual IDs.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Key'''; The default pitch - usually 0x3C (MIDI C4)&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Aruki will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1943</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1943"/>
				<updated>2018-08-16T20:48:51Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Sample ID / Table / Keymap / Layer Tables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/&amp;quot;. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID'''.&lt;br /&gt;
&lt;br /&gt;
Factor5 designed ObjectIDs to used in a polymorphic manner. The top 2 bits of the ID are used&lt;br /&gt;
to differentiate between SoundMacros, Keymaps, and Layers. If the ID passes a mask of 0x4000,&lt;br /&gt;
the object is a ''Keymap''. If the ID passes a mask of 0x8000, the object is a ''Layer''.&lt;br /&gt;
Otherwise, the object is assumed to be a ''SoundMacro''. ''Tables'' don't require this type of&lt;br /&gt;
polymorphism due to the context in which they are accessed.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x65&lt;br /&gt;
| SET_VAR&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Attack time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Decay time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values (although typically in MIDI range [0,127])&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
'''Note:''' Keymap and Layer IDs in these tables have their top 2 bits (indicating their type) masked off.&lt;br /&gt;
Keymaps must be OR'd with 0x4000 and Layers must be OR'd with 0x8000 in order to reconstruct the actual IDs.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Definite Key'''; The default pitch (usually 0x3C00... the second byte may possibly be the MIDI channel)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Aruki will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1942</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1942"/>
				<updated>2018-08-16T20:44:41Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* ObjectID */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/&amp;quot;. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID'''.&lt;br /&gt;
&lt;br /&gt;
Factor5 designed ObjectIDs to used in a polymorphic manner. The top 2 bits of the ID are used&lt;br /&gt;
to differentiate between SoundMacros, Keymaps, and Layers. If the ID passes a mask of 0x4000,&lt;br /&gt;
the object is a ''Keymap''. If the ID passes a mask of 0x8000, the object is a ''Layer''.&lt;br /&gt;
Otherwise, the object is assumed to be a ''SoundMacro''. ''Tables'' don't require this type of&lt;br /&gt;
polymorphism due to the context in which they are accessed.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x39&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x65&lt;br /&gt;
| SET_VAR&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Attack time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Decay time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values (although typically in MIDI range [0,127])&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Definite Key'''; The default pitch (usually 0x3C00... the second byte may possibly be the MIDI channel)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Aruki will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1941</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1941"/>
				<updated>2018-08-16T20:36:07Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Delta Time RLE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data via the ''region data index''; value is negative on a dummy ''region info'' to terminate track regions&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 3 types of commands&lt;br /&gt;
in SNG: ''note'', ''control change'', and ''program change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time Encoding=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a fixed 16-bit&lt;br /&gt;
value to store the delta times. In case of a delta time greater than 65535, no-op commands&lt;br /&gt;
with a 65535 delta time are inserted into the command stream until the target time is attained.&lt;br /&gt;
&lt;br /&gt;
In a theoretical Python streaming API, the delta time can be decoded with no-ops automatically consumed like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTime(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        next = streamIn.PeekU16()&lt;br /&gt;
        if next == 0:&lt;br /&gt;
            # Automatically consume no-op and continue accumulating time value&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            streamIn.seekAhead(2)&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====No-Op Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time are both zero, this is a no-op command.&lt;br /&gt;
&lt;br /&gt;
As mentioned before, no-ops are useful for accumulating delta times greater than 65535.&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Program Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''program change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/gm-level-1-sound-set standard MIDI program numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always zero&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of program change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of&lt;br /&gt;
(delta-tick, delta-value) pairs. The delta times are encoded as unsigned 7/15 bit values&lt;br /&gt;
and the delta values are signed 7/15-bit values. The values are promoted to 15-bit if they&lt;br /&gt;
exceed their 7-bit range. In this case, the highest bit is set on the first byte in the pair&lt;br /&gt;
(0x80). The decoder must track the absolute time and value, summing each consecutive update&lt;br /&gt;
for the current time/values.&lt;br /&gt;
&lt;br /&gt;
Similar to the command stream, when the delta time exceeds 15 bit range (&amp;gt;32767), extra pairs&lt;br /&gt;
with a zeroed value delta are inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def SignExtend7(value):&lt;br /&gt;
    return (value &amp;amp; 0x3f) - (value &amp;amp; 0x40)&lt;br /&gt;
&lt;br /&gt;
def SignExtend15(value):&lt;br /&gt;
    return (value &amp;amp; 0x3fff) - (value &amp;amp; 0x4000)&lt;br /&gt;
&lt;br /&gt;
def DecodeSignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return SignExtend15(byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8))&lt;br /&gt;
    else:&lt;br /&gt;
        return SignExtend7(byte0)&lt;br /&gt;
&lt;br /&gt;
def DecodeUnsignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8)&lt;br /&gt;
    else:&lt;br /&gt;
        return byte0&lt;br /&gt;
&lt;br /&gt;
def DecodeDeltaPair(streamIn):&lt;br /&gt;
    ret = [0,0]&lt;br /&gt;
    while ret[1] == 0:&lt;br /&gt;
        ret[0] += DecodeUnsignedValue(streamIn)&lt;br /&gt;
        ret[1] = DecodeSignedValue(streamIn)&lt;br /&gt;
    return ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1940</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1940"/>
				<updated>2018-08-16T20:31:45Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Continuous Pitch / Modulation Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data via the ''region data index''; value is negative on a dummy ''region info'' to terminate track regions&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 3 types of commands&lt;br /&gt;
in SNG: ''note'', ''control change'', and ''program change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time RLE=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a fixed 16-bit&lt;br /&gt;
value to store the delta times. In case of a delta time greater than 65535, no-op commands&lt;br /&gt;
with a 65535 delta time are inserted into the command stream until the target time is attained.&lt;br /&gt;
&lt;br /&gt;
In a theoretical Python streaming API, the delta time can be decoded with no-ops automatically consumed like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTime(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        next = streamIn.PeekU16()&lt;br /&gt;
        if next == 0:&lt;br /&gt;
            # Automatically consume no-op and continue accumulating time value&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            streamIn.seekAhead(2)&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====No-Op Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time are both zero, this is a no-op command.&lt;br /&gt;
&lt;br /&gt;
As mentioned before, no-ops are useful for accumulating delta times greater than 65535.&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Program Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''program change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/gm-level-1-sound-set standard MIDI program numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always zero&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of program change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of&lt;br /&gt;
(delta-tick, delta-value) pairs. The delta times are encoded as unsigned 7/15 bit values&lt;br /&gt;
and the delta values are signed 7/15-bit values. The values are promoted to 15-bit if they&lt;br /&gt;
exceed their 7-bit range. In this case, the highest bit is set on the first byte in the pair&lt;br /&gt;
(0x80). The decoder must track the absolute time and value, summing each consecutive update&lt;br /&gt;
for the current time/values.&lt;br /&gt;
&lt;br /&gt;
Similar to the command stream, when the delta time exceeds 15 bit range (&amp;gt;32767), extra pairs&lt;br /&gt;
with a zeroed value delta are inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def SignExtend7(value):&lt;br /&gt;
    return (value &amp;amp; 0x3f) - (value &amp;amp; 0x40)&lt;br /&gt;
&lt;br /&gt;
def SignExtend15(value):&lt;br /&gt;
    return (value &amp;amp; 0x3fff) - (value &amp;amp; 0x4000)&lt;br /&gt;
&lt;br /&gt;
def DecodeSignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return SignExtend15(byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8))&lt;br /&gt;
    else:&lt;br /&gt;
        return SignExtend7(byte0)&lt;br /&gt;
&lt;br /&gt;
def DecodeUnsignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8)&lt;br /&gt;
    else:&lt;br /&gt;
        return byte0&lt;br /&gt;
&lt;br /&gt;
def DecodeDeltaPair(streamIn):&lt;br /&gt;
    ret = [0,0]&lt;br /&gt;
    while ret[1] == 0:&lt;br /&gt;
        ret[0] += DecodeUnsignedValue(streamIn)&lt;br /&gt;
        ret[1] = DecodeSignedValue(streamIn)&lt;br /&gt;
    return ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1939</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1939"/>
				<updated>2018-08-16T20:30:01Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: Fix pitch/mod encoding scheme&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data via the ''region data index''; value is negative on a dummy ''region info'' to terminate track regions&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 3 types of commands&lt;br /&gt;
in SNG: ''note'', ''control change'', and ''program change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time RLE=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a fixed 16-bit&lt;br /&gt;
value to store the delta times. In case of a delta time greater than 65535, no-op commands&lt;br /&gt;
with a 65535 delta time are inserted into the command stream until the target time is attained.&lt;br /&gt;
&lt;br /&gt;
In a theoretical Python streaming API, the delta time can be decoded with no-ops automatically consumed like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTime(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        next = streamIn.PeekU16()&lt;br /&gt;
        if next == 0:&lt;br /&gt;
            # Automatically consume no-op and continue accumulating time value&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            streamIn.seekAhead(2)&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====No-Op Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time are both zero, this is a no-op command.&lt;br /&gt;
&lt;br /&gt;
As mentioned before, no-ops are useful for accumulating delta times greater than 65535.&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Program Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''program change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/gm-level-1-sound-set standard MIDI program numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always zero&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of program change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of&lt;br /&gt;
(delta-tick, delta-value) pairs. The delta times are encoded as unsigned 7/15 bit values&lt;br /&gt;
and the delta values are signed 7/15-bit values. The values are promoted to 15-bit if they&lt;br /&gt;
exceed their 7-bit range. In this case, the highest bit is set on the first byte in the pair&lt;br /&gt;
(0x80). The decoder must track the absolute time and value, summing each consecutive update&lt;br /&gt;
for the current time/values.&lt;br /&gt;
&lt;br /&gt;
Similar to the command stream, when the delta time exceeds 15 bit range (&amp;gt;32767), extra pairs&lt;br /&gt;
with a value delta are inserted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def SignExtend7(value):&lt;br /&gt;
    return (value &amp;amp; 0x3f) - (value &amp;amp; 0x40)&lt;br /&gt;
&lt;br /&gt;
def SignExtend15(value):&lt;br /&gt;
    return (value &amp;amp; 0x3fff) - (value &amp;amp; 0x4000)&lt;br /&gt;
&lt;br /&gt;
def DecodeSignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return SignExtend15(byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8))&lt;br /&gt;
    else:&lt;br /&gt;
        return SignExtend7(byte0)&lt;br /&gt;
&lt;br /&gt;
def DecodeUnsignedValue(streamIn):&lt;br /&gt;
    byte0 = streamIn.ReadU8()&lt;br /&gt;
    if byte0 &amp;amp; 0x80:&lt;br /&gt;
        byte1 = streamIn.ReadU8()&lt;br /&gt;
        return byte1 | ((byte0 &amp;amp; 0x7f) &amp;lt;&amp;lt; 8)&lt;br /&gt;
    else:&lt;br /&gt;
        return byte0&lt;br /&gt;
&lt;br /&gt;
def DecodeDeltaPair(streamIn):&lt;br /&gt;
    ret = [0,0]&lt;br /&gt;
    while ret[1] == 0:&lt;br /&gt;
        ret[0] += DecodeUnsignedValue(streamIn)&lt;br /&gt;
        ret[1] = DecodeSignedValue(streamIn)&lt;br /&gt;
    return ret&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1938</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1938"/>
				<updated>2018-08-16T20:04:55Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: Clarify nature of delta time encoding&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data via the ''region data index''; value is negative on a dummy ''region info'' to terminate track regions&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 3 types of commands&lt;br /&gt;
in SNG: ''note'', ''control change'', and ''program change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time RLE=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a fixed 16-bit&lt;br /&gt;
value to store the delta times. In case of a delta time greater than 65535, no-op commands&lt;br /&gt;
with a 65535 delta time are inserted into the command stream until the target time is attained.&lt;br /&gt;
&lt;br /&gt;
In a theoretical Python streaming API, the delta time can be decoded with no-ops automatically consumed like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTime(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        next = streamIn.PeekU16()&lt;br /&gt;
        if next == 0:&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            streamIn.seekAhead(2)&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Program Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''program change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/gm-level-1-sound-set standard MIDI program numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always zero&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of program change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of RLE-compressed&lt;br /&gt;
(delta-tick, delta-value) pairs, decoding to signed 16-bit precision. The decoder must track&lt;br /&gt;
the absolute time and value, summing each consecutive update for the current time/values.&lt;br /&gt;
&lt;br /&gt;
The algorithm for this RLE is different than the delta-time one for commands. It may&lt;br /&gt;
scale down to a single byte if able.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeRLE(streamIn):&lt;br /&gt;
    # high-bit shift-trigger RLE, limited to 2 bytes&lt;br /&gt;
    term = streamIn.ReadU8()&lt;br /&gt;
    total = term &amp;amp; 0x7f&lt;br /&gt;
    if term &amp;amp; 0x80:&lt;br /&gt;
        total = total * 256 + streamIn.ReadU8()&lt;br /&gt;
    return total&lt;br /&gt;
&lt;br /&gt;
def DecodeContinuousRLE(streamIn, isValue):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        # 1-2 byte RLE accumulated within continuable RLE&lt;br /&gt;
        term = DecodeRLE(streamIn)&lt;br /&gt;
        if term == 0x8000:&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            dummy = streamIn.ReadU8()&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
&lt;br /&gt;
        # values are signed deltas;&lt;br /&gt;
        # extending into the high-half of 15-bit precision&lt;br /&gt;
        if isValue:&lt;br /&gt;
            if total &amp;gt;= 0x4000:&lt;br /&gt;
                return total - 0xffff&lt;br /&gt;
            else:&lt;br /&gt;
                return total&lt;br /&gt;
&lt;br /&gt;
        # times are always forward-deltas&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1933</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1933"/>
				<updated>2018-06-28T03:31:45Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Has Actors&lt;br /&gt;
| If set, the game will resolve script entity IDs for the PVS lookup&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Total number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| 2nd Layer Light Count&lt;br /&gt;
| Lights within total that are in the 2nd BABEDEAD layer.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective. 2nd layer lights are listed first.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree. '''Note:''' the coordinates of the AABB are in local area space (i.e. inverse-transformed with the matrix in the MREA header).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility object count&lt;br /&gt;
| Number of objects per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light object count&lt;br /&gt;
| Number of objects within total that are lights.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA sections. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. The 2nd layer lights are related first. Each light encodes 2-bits apiece,&lt;br /&gt;
with the following enum represented:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Not Visible&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Visible&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Outside Octree Bounds&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=PART_(File_Format)&amp;diff=1925</id>
		<title>PART (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=PART_(File_Format)&amp;diff=1925"/>
				<updated>2018-05-13T01:51:31Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: RSOP description&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''PART''' [[Particle Script|particle script]] format is used to configure ''particle effects''.&lt;br /&gt;
&lt;br /&gt;
Particles are the most widely-used effect in ''Metroid Prime'', with approximately&lt;br /&gt;
3,500 unique scripts across the [[PAK_(Metroid_Prime)|PAK archives]]. &lt;br /&gt;
Each script configures a complete ''particle system'' that may draw into the scene.&lt;br /&gt;
&lt;br /&gt;
The particle system is configurable to generate many visual effects:&lt;br /&gt;
&lt;br /&gt;
* Flames and smoke&lt;br /&gt;
* Floating embers&lt;br /&gt;
* Water splashes/drips&lt;br /&gt;
* Dust and dirt in windy conditions&lt;br /&gt;
* Volumetric light &amp;quot;shimmers&amp;quot;&lt;br /&gt;
* Energy/plasma discharges&lt;br /&gt;
* Many others&lt;br /&gt;
&lt;br /&gt;
The concept behind the particle system is quite simple: lots of &lt;br /&gt;
view-aligned (camera-facing) quads with a texture-image&lt;br /&gt;
are emitted, positioned, rotated, sized, colored, etc... according to the&lt;br /&gt;
parameters in the particle script.&lt;br /&gt;
&lt;br /&gt;
== Particle System ==&lt;br /&gt;
&lt;br /&gt;
The ''particle system'' ties together all procedures necessary to host an ''emitter''&lt;br /&gt;
and specifies the rate at which new particles should be created. New particles have a predetermined&lt;br /&gt;
''lifetime'' (in frames) set by the system, and the emitter initializes the position and velocity of these particles.&lt;br /&gt;
The system continuously updates all currently-living particles that it's created. This includes updating&lt;br /&gt;
properties like ''position'', ''velocity'', ''color'', ''size'' and ''view-rotation''. &lt;br /&gt;
&lt;br /&gt;
=== Child Systems ===&lt;br /&gt;
&lt;br /&gt;
Particle systems may also host ''child systems'' which are timed and positioned within the parent's reference. &lt;br /&gt;
Not only does this include other PART systems, but [[SWHC (File Format)|SWHC]] and [[ELSC (File Format)|ELSC]]&lt;br /&gt;
systems may be parented as well. &lt;br /&gt;
&lt;br /&gt;
A good example of this is the ''flamethrower's'' system, which composes flame&lt;br /&gt;
particles with a trailing SWHC and small cinders from a separate PART.&lt;br /&gt;
&lt;br /&gt;
=== Line Mode ===&lt;br /&gt;
&lt;br /&gt;
When the &amp;lt;code&amp;gt;LINE&amp;lt;/code&amp;gt; property is activated, particles are rendered as ''lines'' rather than quads.&lt;br /&gt;
&lt;br /&gt;
The usual 3D particle position is used as the ''trailing-point'' of the line, with the ''leading-point'' computed&lt;br /&gt;
via positional-differential, scaled by other parameters. Lines sample textures diagonally as a single-texel strip, &lt;br /&gt;
allowing for gradients to be applied via spherical or diagonal ramp-textures.&lt;br /&gt;
&lt;br /&gt;
=== Model Mode ===&lt;br /&gt;
&lt;br /&gt;
When the &amp;lt;code&amp;gt;PMDL&amp;lt;/code&amp;gt; property is provided with a [[CMDL (File Format)|CMDL]], particles are rendered&lt;br /&gt;
using that ''model'', in addition to the quad. Alternatively, &amp;lt;code&amp;gt;PMUS&amp;lt;/code&amp;gt; generates a quad transformed&lt;br /&gt;
as if it were a model (non view aligned).&lt;br /&gt;
&lt;br /&gt;
Model-based particles have a whole separate suite of properties for controlling local-transformation and color.&lt;br /&gt;
Most of the properties involving positioning and transforms from the client systems are shared from the&lt;br /&gt;
normal quad-mode.&lt;br /&gt;
&lt;br /&gt;
Many weapon effects, notably the &amp;quot;sphere&amp;quot; of the charge-beam, are accomplished using particle models.&lt;br /&gt;
&lt;br /&gt;
== Particle Instance ==&lt;br /&gt;
&lt;br /&gt;
For each frame, each particle does the following primary tasks:&lt;br /&gt;
&lt;br /&gt;
* Determines if particle's lifetime has finished, removing it from the scene and releasing its resources for newly created particles to use&lt;br /&gt;
* Invokes all [[Particle Script#Mod_Vector_Elements|velocity/position sources]]; advancing position 1/60th of a second&lt;br /&gt;
* Evaluates local transforms&lt;br /&gt;
** Size&lt;br /&gt;
** View-aligned rotation&lt;br /&gt;
** View-aligned offset&lt;br /&gt;
* Evaluates particle color (shader-multiplied with texture-image)&lt;br /&gt;
&lt;br /&gt;
== Emitter ==&lt;br /&gt;
&lt;br /&gt;
''Main article: [[Particle Script#Emitter_Elements|Emitter Elements]]''&lt;br /&gt;
&lt;br /&gt;
Each particle-system employs a single ''emitter'' context.&lt;br /&gt;
The system generates a specified number of particles each frame; &lt;br /&gt;
the emitter initializing the position and velocity-vector for each.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;GPSM&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|PSIV|VectorElement|System Initial Velocity|System Init|Defines the initial velocity vector which moves the entire system in local orientation (may be overridden by &amp;lt;code&amp;gt;PSVM&amp;lt;/code&amp;gt;)|{{maybe|Demo}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|PSVM|ModVectorElement|System Velocity Mod|Post Particles Update|Mod Vector which influences the position and velocity of the entire system in local space|{{maybe|Demo}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|PSOV|VectorElement|System Orientation Velocity|Post Particles Update|Angular velocity (in degrees/frame) of the system's orientation|{{maybe|Demo}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|PSLT|IntElement|System Lifetime|System Init|Count of frames that the system generates new particles|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PSWT|IntElement|System Warmup Time|Warmup-Phase Update|Count of frames that the particle system virtually updates itself within one initial frame; exiting the warmup phase afterwards|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PSTS|RealElement|System Time Scale|Pre Particles Update|Factor that redefines the second for the system, including the rate at which the system's frame count is incremented. 1.0 is native 60-fps. 0.5 causes every other frame to skip updates, slowing down and making the motion &amp;quot;choppy&amp;quot;. 2.0 causes 2 updates every frame, speeding up.|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|POFS|VectorElement|Particle Offset|System Init, Post Particles Update|Vector that offsets all particles in world space|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SEED|IntElement|Random Seed|System Init|Value used to initialize the [[wikipedia:Linear congruential generator|LCG]] seed state used within the system's update and render cycles (default 99)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LENG|RealElement|Line Length|Line Particle Creation, Line Particle Update|Length of &amp;lt;code&amp;gt;LINE&amp;lt;/code&amp;gt; particles, scaled according to &amp;lt;code&amp;gt;FXLL&amp;lt;/code&amp;gt;|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|WIDT|RealElement|Line Width|Line Particle Render|Width of &amp;lt;code&amp;gt;LINE&amp;lt;/code&amp;gt; particles in viewport pixels|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|MAXP|IntElement|Max Particles|System Init, Pre Particles Update|Max count of particles allowed to live at once. No new particles created if there are already this many active particles.|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|GRTE|RealElement|Generation Rate|Pre Particles Update|Count of particles to create each frame. Remainder value is accumulated for the next update cycle.|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Color|Particle Creation, Particle Update|Color to multiply with particle's texture|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LTME|IntElement|Lifetime|Particle Creation|Count of frames the about-to-be-created particle lives|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|ILOC|VectorElement|Particle Emit Location|Particle Creation|Position to initialize particle in local space (replaced by &amp;lt;code&amp;gt;EMTR&amp;lt;/code&amp;gt;)|{{maybe|Demo}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IVEC|VectorElement|Particle Emit Velocity|Particle Creation|Velocity to initialize particle in local space (replaced by &amp;lt;code&amp;gt;EMTR&amp;lt;/code&amp;gt;)|{{maybe|Demo}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|EMTR|EmitterElement|Emitter|Particle Creation|[[Particle Script#Emitter Elements|Modular data source]] for initializing position and velocity of new particles|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LINE|bool|Line Mode|System Init|Render particles as lines instead of quads|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|FXLL|bool|Line Mode|System Init|Scale leading point of line as the exact value of &amp;lt;code&amp;gt;LENG&amp;lt;/code&amp;gt;, rather than multiplying &amp;lt;code&amp;gt;LENG&amp;lt;/code&amp;gt; with the position-differential|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|AAPH|bool|Additive Alpha|System Init|Set up blending of quads and lines with source factor of &amp;lt;code&amp;gt;GX_BL_SRCALPHA&amp;lt;/code&amp;gt; and destination factor of &amp;lt;code&amp;gt;GX_BL_ONE&amp;lt;/code&amp;gt; as opposed to &amp;lt;code&amp;gt;GX_BL_SRCALPHA&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GX_BL_INVSRCALPHA&amp;lt;/code&amp;gt;|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZBUF|bool|Z-buffer Write|System Init|Perform rendering while writing into the z-buffer to ensure later-drawn objects don't occlude particles if positioned behind them|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SORT|bool|View-space Sort|System Init|Sort particles by their z-coordinate in view-space before drawing, which is essential for proper alpha blending (although mathematically unnecessary when &amp;lt;code&amp;gt;AAPH&amp;lt;/code&amp;gt; is active)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LIT_|bool|{{unknown|Unknown}}|System Init|Unused in demo|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|ORNT|bool|Orient To Origin|System Init|''New in retail'' - Simultaneously orients particle instances toward the local origin and view-point via cross-product. &amp;lt;code&amp;gt;ROTA&amp;lt;/code&amp;gt; is used to control the width of quads in this mode, while &amp;lt;code&amp;gt;SIZE&amp;lt;/code&amp;gt; controls the length.|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|RSOP|bool|Right Vector Scaled on Particle|System Init|''New in retail'' - The right vector (particle width) is proportionally scaled with length|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|MBLR|bool|Motion Blur|System Init|Enables sub-positional overdraw of each particle instance between its previous position and new position each frame; draw count controlled by &amp;lt;code&amp;gt;MBSP&amp;lt;/code&amp;gt;|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMAB|bool|Model Additive Alpha|System Init|Equivalent of &amp;lt;code&amp;gt;AAPH&amp;lt;/code&amp;gt; for models and &amp;lt;code&amp;gt;PMUS&amp;lt;/code&amp;gt; quads|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMUS|bool|Model Unoriented Square|System Init|Draws a 1x1 quad in the XZ-plane in place of a &amp;lt;code&amp;gt;PMDL&amp;lt;/code&amp;gt; model|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMOO|bool|Model Object Orientation|System Init|Includes client-supplied orientation in model's transform chain (after &amp;lt;code&amp;gt;PMRT&amp;lt;/code&amp;gt;). Unlike other &amp;lt;code&amp;gt;bool&amp;lt;/code&amp;gt; properties, this property is enabled by default|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|VMDn|bool|Local Vector Mod [1-4]|System Init|Applies mod vectors &amp;lt;code&amp;gt;VELn&amp;lt;/code&amp;gt; in system local-space rather than world-space|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|CIND|bool|Colored Indirect Texture|System Init|When &amp;lt;code&amp;gt;TIND&amp;lt;/code&amp;gt; is active, texels copied from the underlying framebuffer are multiplied with the texels in &amp;lt;code&amp;gt;TEXR&amp;lt;/code&amp;gt; (rather than added). The alpha component is ''always'' multiplied.|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|OPTS|bool|Optional System|System Init|When a client system constructs a generator instance, it has the option to filter out child systems at any level that aren't essential to the effect. The exclusion is a mutual decision between the client and the particle description via this property.|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|MBSP|IntElement|Motion Blur Samples|Pre Particles Update|When &amp;lt;code&amp;gt;MBLR&amp;lt;/code&amp;gt; is active, this is the number of times the position differential of each particle instance is subdivided for overdraw|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SIZE|RealElement|Particle Size|Particle Creation, Particle Update|Proportional scale (length and width) of particle quads|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|ROTA|RealElement|Particle View-Rotation|Particle Creation, Particle Update|View-aligned counterclockwise-rotation of particle instances|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXR|UVElement|Particle Texture|Particle Creation, Particle Update|Particle texture map and UV coordinate source|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|TIND|UVElement|Indirect Particle Texture|Particle Creation, Particle Update|Indirect texture map and UV coordinate source. Setting this property enables framebuffer-&amp;gt;texture copies of the rectangular region behind particle instances. These texels are warped using coordinates defined in the texels of the IA texture in this property.|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMDL|[[CMDL (File Format)|CMDL]]|Particle Model|System Init|Render particle instances using this model, in addition to quads|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMOP|VectorElement|Particle Model Pre-Offset|Particle Model Render|Translate models using this vector ''before'' transforming normally|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMRT|VectorElement|Particle Model Rotate|Particle Model Render|Rotate models using these euler angles (in degrees, ZYX order)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMSC|VectorElement|Particle Model Scale|Particle Model Render|Scale models using this (potentially non-proportional) vector|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PMCL|ColorElement|Particle Model Color|Particle Model Render|Multiply textured model color with this color|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|VELn|ModVectorElement|Particle Mod Vectors [1-4]|Particle Update|Up to 4 [[Particle Script#Mod Vector Elements|mod vectors]] invoked (in order) on each particle instance for each frame; influencing position and velocity|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|ICTS|PART|Counted Child System|System Init|Child particle system to spawn multiple instances of|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|NCSY|IntElement|Counted Child System Count|System Init|Count of &amp;lt;code&amp;gt;ICTS&amp;lt;/code&amp;gt; systems to spawn (default 1)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|CSSD|IntElement|Counted Child System Frame|System Init|Frame index to spawn &amp;lt;code&amp;gt;ICTS&amp;lt;/code&amp;gt; instances|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|IDTS|PART|Done Child System|System Init|Child particle system to spawn multiple instances of when parent system's lifetime finishes|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|NDSY|IntElement|Done Child System Count|System Init|Count of &amp;lt;code&amp;gt;IDTS&amp;lt;/code&amp;gt; systems to spawn (default 1)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|IITS|PART|Interval Child System|System Init|Child particle system to spawn at regular intervals|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|PISY|IntElement|Interval Child System Frame Interval|System Init|Frame interval to emit &amp;lt;code&amp;gt;IITS&amp;lt;/code&amp;gt; instances|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SISY|IntElement|Interval Child System Start Frame|System Init|Frame index to start emitting &amp;lt;code&amp;gt;IITS&amp;lt;/code&amp;gt; instances|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|KSSM|[[#SpawnSystemKeyframeData|SpawnSystemKeyframeData]]|Timed-Spawn Particle Systems|System Init|List of start-frame events and corresponding child systems to spawn|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSWH|[[SWHC (File Format)|SWHC]]|Child Swoosh System|System Init|Child swoosh system parented to this system|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSSD|IntElement|Child Swoosh System Start Frame|System Init|Frame index to start emitting &amp;lt;code&amp;gt;SSWH&amp;lt;/code&amp;gt;|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSPO|VectorElement|Child Swoosh System Offset|System Init|Offset supplied as swoosh system's translation|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SELC|[[ELSC (File Format)|ELSC]]|Child Electric System|System Init|Child electric system parented to this system|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SESD|IntElement|Child Electric System Start Frame|System Init|Frame index to start emitting &amp;lt;code&amp;gt;SELC&amp;lt;/code&amp;gt;|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|SEPO|VectorElement|Child Electric System Offset|System Init|Offset supplied as electric system's translation|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
|-&lt;br /&gt;
| '''LTYP'''&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | IntElement&lt;br /&gt;
| System Light Type&lt;br /&gt;
| System Init&lt;br /&gt;
| Type of GX light to parent to system &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;None (no light)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Custom (point)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Directional&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Spot&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
{{ParticlePropertyRow|LCLR|ColorElement|System Light Color|Post Particles Update|Diffuse color of GX light|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LINT|RealElement|System Light Intensity|Post Particles Update|Light intensity factor used for calculating falloff|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LOFF|VectorElement|System Light Offset|Post Particles Update|Light offset (not applicable to directional lights)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LDIR|VectorElement|System Light Direction|Post Particles Update|Light direction (not applicable to custom lights)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
|-&lt;br /&gt;
| '''LFOT'''&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | IntElement&lt;br /&gt;
| System Light Falloff Type&lt;br /&gt;
| System Init&lt;br /&gt;
| Type of linear-attenuation equation to use for light &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Constant&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Linear&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Quadratic&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
{{ParticlePropertyRow|LFOR|RealElement|System Light Falloff Radius|Post Particles Update|Falloff radius for linear-attenuation (not applicable to constant)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|LSLA|RealElement|System Light Cutoff Angle|Post Particles Update|Cutoff angle for angular-attenuation (only applicable to spot)|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
{{ParticlePropertyRow|ADVn|RealElement|Advance Parameters [1-8]|Pre Particles Update|Parameters to compute per system update, values shared across all particle instances via &amp;lt;code&amp;gt;PAPn&amp;lt;/code&amp;gt; real elements|{{check}}|{{check}}|{{check}}|{{check}}|{{check}}}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SpawnSystemKeyframeData ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| End Frame&lt;br /&gt;
| Final frame index where a system is spawned&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| List Count&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | {u32&amp;amp;nbsp;''frame'', u32&amp;amp;nbsp;''infoCount'', [[#SpawnSystemKeyframeInfo|SpawnSystemKeyframeInfo]][infoCount]}[listCount]&lt;br /&gt;
| Lists&lt;br /&gt;
| Pairs of ''frame index'' and sequence of ''SpawnSystemKeyframeInfo'' for grouping systems that start on the same frame&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== SpawnSystemKeyframeInfo ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | PART&lt;br /&gt;
| Child System ID&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;font-family:monospace;&amp;quot; | u32&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;br /&gt;
[[Category:Donkey Kong Country Returns]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=UV_Animations&amp;diff=1920</id>
		<title>UV Animations</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=UV_Animations&amp;diff=1920"/>
				<updated>2018-01-15T01:56:43Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: Minor Mode6 translation scale fix&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''UV animations''' are used to animate texture coordinates. They're present in the material data of the Metroid Prime trilogy and Donkey Kong Country Returns. There are 13 animation types across those four games.&lt;br /&gt;
&lt;br /&gt;
{{research|moderate|Modes 8/10/11/12/13 are unknown}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
UV animations generally contain an int indicating what animation type they are, followed by float parameters. The number of parameters depends on the animation mode; some modes don't have any parameters while some have as many as 9.&lt;br /&gt;
&lt;br /&gt;
=== Metroid Prime 1/2 ===&lt;br /&gt;
&lt;br /&gt;
At the end of the material data, there's a 32-bit animations size value, then an animation count. Each animation is structured as:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Type&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| u32&lt;br /&gt;
| 4&lt;br /&gt;
| '''Animation type'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| float[]&lt;br /&gt;
| -&lt;br /&gt;
| '''Parameters'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Metroid Prime 3/Donkey Kong Country Returns ===&lt;br /&gt;
&lt;br /&gt;
Animations are located at the end of each PASS section. There's no animation count; instead, one animation can be supplied per pass and can be directly associated with that pass. Like Prime 1, the animation data follows a 32-bit animations size value.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Type&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| u16&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| u16&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| u32&lt;br /&gt;
| 4&lt;br /&gt;
| '''Animation Mode'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| float[]&lt;br /&gt;
| -&lt;br /&gt;
| '''Parameters'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Animation Modes ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Mode&lt;br /&gt;
! Name&lt;br /&gt;
! Params&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| [[#Mode_0:_Inverse ModelView Matrix (No Translation)|Inverse ModelView Matrix (No Translation)]]&lt;br /&gt;
| 0&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| [[#Mode_1:_Inverse ModelView Matrix|Inverse ModelView Matrix]]&lt;br /&gt;
| 0&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| [[#Mode_2:_UV Scroll|UV Scroll]]&lt;br /&gt;
| 4&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| [[#Mode_3:_Rotation|Rotation]]&lt;br /&gt;
| 2&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| [[#Mode_4/5:_Horizontal/Vertical_Filmstrip|Horizontal Filmstrip]]&lt;br /&gt;
| 4&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| [[#Mode_4/5:_Horizontal/Vertical_Filmstrip|Vertical Filmstrip]]&lt;br /&gt;
| 4&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| [[#Mode_6:_Model Matrix|Model Matrix]]&lt;br /&gt;
| 0&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| [[#Mode_7:_Cylinder Environment|Cylinder Environment]]&lt;br /&gt;
| 2&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| {{unknown|Unknown mode}}&lt;br /&gt;
| 9&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| {{unknown|[[#Mode_10:_Another_reflection_mode|Another reflection mode]]}}&lt;br /&gt;
| 0&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 11&lt;br /&gt;
| {{unknown|Unknown mode}}&lt;br /&gt;
| 2&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 12&lt;br /&gt;
| {{unknown|Unknown mode}}&lt;br /&gt;
| 2&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
| 13&lt;br /&gt;
| {{unknown|Unknown mode}}&lt;br /&gt;
| 2&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{nocheck}}&lt;br /&gt;
| {{check}}&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For all of the following modes, ''s'' refers to ''seconds mod 900''.&lt;br /&gt;
&lt;br /&gt;
==== Mode 0: Inverse ModelView Matrix (No Translation) ====&lt;br /&gt;
&lt;br /&gt;
This mode is commonly used with vertex normals to simulate reflective surfaces using spheremaps that move with the camera. It takes no parameters, and will generate both a texture matrix and a post-transform matrix. Translation is ignored.&lt;br /&gt;
&lt;br /&gt;
The texture matrix is calculated like this. Note that the multiplication of the view matrix by the model matrix should be modified slightly rather than being a straight multiplication to ignore translation on the model matrix. (The game uses a function called MultiplyIgnoreTranslation for this.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;texmtx = inverse(ViewMatrix) * ModelMatrix;&lt;br /&gt;
texmtx[0][3] = texmtx[1][3] = texmtx[2][3] = 0;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The post-transform matrix is a constant value. The purpose of it is to adjust the normalized texture coordinates so that they range from 0 to 1.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;0.5, 0.0, 0.0, 0.5,&lt;br /&gt;
0.0, 0.0, 0.5, 0.5,&lt;br /&gt;
0.0, 0.0, 0.0, 1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Mode 1: Inverse ModelView Matrix ====&lt;br /&gt;
&lt;br /&gt;
This mode is nearly identical to mode 0; the only difference is that translation is left as-is. The multiplication of the view matrix by the model matrix actually is a straight multiplication in this mode, and the translation values on the texture matrix aren't set to 0.&lt;br /&gt;
&lt;br /&gt;
==== Mode 2: UV Scroll ====&lt;br /&gt;
&lt;br /&gt;
This mode is used to scroll both U and V at the same time. It will only generate a texture matrix. It has four float parameters: ''offsetA'', ''offsetB'', ''scaleA'', and ''scaleB''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;uOffset = (s * scaleA) + offsetA;&lt;br /&gt;
vOffset = (s * scaleB) + offsetB;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Mode 3: Rotation ====&lt;br /&gt;
&lt;br /&gt;
This mode rotates the texture. It will only generate a texture matrix. It has two float parameters: ''offset'' and ''scale''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float angle = (s * scale) + offset;&lt;br /&gt;
float acos = cos(angle);&lt;br /&gt;
float asin = sin(angle);&lt;br /&gt;
float translateX = (1.0 - (acos - asin)) * 0.5;&lt;br /&gt;
float translateY = (1.0 - (asin + acos)) * 0.5;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting texture matrix is laid out as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;acos, -asin, 0.0, translateX,&lt;br /&gt;
asin,  acos, 0.0, translateY,&lt;br /&gt;
 0.0,   0.0, 1.0,        0.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Mode 4/5: Horizontal/Vertical Filmstrip ====&lt;br /&gt;
&lt;br /&gt;
These modes can be used to create a filmstrip-like effect. The texture steps a set distance each animation frame, rather than the scroll being smoothly interpolated every game frame. The same calculation is done for both modes, with the only difference being whether the calculated offset is applied to the U or V coordinate. It will only generate a texture matrix. There are four float parameters: ''scale'', ''numFrames'', ''step'', and ''offset''.&lt;br /&gt;
&lt;br /&gt;
The animation is made up of a number of pseudo-frames, where ''step'' controls the amount that the texture scrolls by each frame, and ''numFrames'' sets how many frames are iterated through before resetting back to 0. ''scale'' roughly controls animation playback speed, and ''offset'' modifies the time input value.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float value = step * scale * (offset + s);&lt;br /&gt;
float uv_offset = (float)(short)(float)(numFrames * fmod(value, 1.0f)) * step;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Mode 6: Model Matrix ====&lt;br /&gt;
&lt;br /&gt;
This mode is similar to modes 0 and 1 in that it simulates reflective surfaces, but it only takes the model matrix into account, which means camera movement doesn't affect the reflection. It takes no parameters and it generates both a texture matrix and a post-transform matrix.&lt;br /&gt;
&lt;br /&gt;
The texture matrix is simply the model matrix, with the translation values set to 0. The post-transform matrix is set to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;0.5, 0.0, 0.0, ModelMatrix[0][3] * 0.050000001,&lt;br /&gt;
0.0, 0.0, 0.5, ModelMatrix[1][3] * 0.050000001&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Mode 7: Cylinder Environment ====&lt;br /&gt;
&lt;br /&gt;
Mode 7 takes two parameters and generates both a texture matrix and a post-transform matrix, projecting the UVs onto the surface of a cylinder, used almost exclusively on pipes.&lt;br /&gt;
&lt;br /&gt;
The texture matrix is generated the same way as in mode 0; translation is ignored.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;texmtx = inverse(ViewMatrix) * ModelMatrix;&lt;br /&gt;
texmtx[0][3] = texmtx[1][3] = texmtx[2][3] = 0;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The post-transform matrix is where it gets a little complicated. A little math is required to calculate some values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;float xy = ((ViewMatrix[0][3] + ViewMatrix[1][3]) * 0.025f * ParamB;&lt;br /&gt;
xy = (xy - (int) xy); // This truncates the integer portion of the value, leaving only the fractional part (mantissa).&lt;br /&gt;
&lt;br /&gt;
float z = ViewMatrix[2][3] * 0.05f * ParamB;&lt;br /&gt;
z = (z - (int) z);&lt;br /&gt;
&lt;br /&gt;
float halfA = ParamA * 0.5f;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The post-transform matrix is then constructed as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;halfA, 0.0f,  0.0f,  xy,&lt;br /&gt;
 0.0f, 0.0f, halfA,   z,&lt;br /&gt;
 0.0f, 0.0f,  0.0f, 1.0f&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Mode 10: Another reflection mode ====&lt;br /&gt;
&lt;br /&gt;
This one needs more research done, but the only thing the game does with this mode is load this post-transform matrix:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;0.5, 0.0, 0.0, 0.5,&lt;br /&gt;
0.0, 0.0, 0.5, 0.5,&lt;br /&gt;
0.0, 0.0, 0.0, 1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function of this matrix is to transform normalized texture coords so that they range from 0 to 1, instead of from -1 to 1. This mode seems to work well with mode 0's settings, though, so it's possible that the game is creating a texture matrix somewhere else. This needs some looking into.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;br /&gt;
[[Category:Donkey Kong Country Returns]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1892</id>
		<title>ELSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1892"/>
				<updated>2017-06-11T06:08:55Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''ELSC''' [[Particle Script|particle script]] format is used to build electrical effects in the ''Metroid Prime'' series.&lt;br /&gt;
Electrical effects are commonly used to dynamically draw lightning and electrical arcs.&lt;br /&gt;
&lt;br /&gt;
Whenever a new ''particle instance'' is generated, a [[wikipedia:Bézier curve|Bézier curve]] is subdivided into segments. &lt;br /&gt;
The central vertices are then displaced using a [[wikipedia:Fractal|random fractal algorithm]]. &lt;br /&gt;
The instance's color and line-width is updated over its lifetime.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;ELSM&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|LIFE|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SLIF|IntElement|Segment Lifetime|Particle Creation|Count of frames for newly generated instance to last|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GRAT|RealElement|Generation Rate|System Update|Count of particles to generate per frame; remainder is accumulated across updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SCNT|IntElement|Instance Count|System Init|Maximum count of particle instances and child generators for system|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSEG|IntElement|Segment Count|System Init|Maximum count of line segments per instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Swoosh Color|Particle Creation and Update|Modulation color evaluated for swoosh-based instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IEMT|EmitterElement|Initial Emitter|Particle Creation|Position source for instance start-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|FEMT|EmitterElement|Final Emitter|Particle Creation|Position source for instance end-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPL|RealElement|Length Amplitude|Particle Creation|Randomized coefficient of fractal displacement as product of recursive segment length|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPD|RealElement|Direct Amplitude|Particle Creation|Separately randomized coefficient of fractal displacement|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD1|RealElement|Line Width 1|Particle Creation and Update|Enables line 1 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD2|RealElement|Line Width 2|Particle Creation and Update|Enables line 2 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD3|RealElement|Line Width 3|Particle Creation and Update|Enables line 3 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL1|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 1's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL2|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 2's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL3|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 3's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSWH|[[SWHC (File Format)|SWHC]]|Child Swoosh|System Init|Use swoosh system to draw effect; computed fractal points are set into swoosh's history; Omitting LWD* properties will only draw the swoosh|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GPSM|[[PART (File Format)|PART]]|Start Child Particle|System Init|Draw particle system positioned at instance's start-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|EPSM|[[PART (File Format)|PART]]|End Child Particle|System Init|Draw particle system positioned at instance's end-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZERY|bool|Zero Y|Particle Creation|Zero Y component of newly created particle vertices|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1891</id>
		<title>ELSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1891"/>
				<updated>2017-06-11T05:55:29Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''ELSC''' [[Particle Script|particle script]] format is used to build electrical effects in the ''Metroid Prime'' series.&lt;br /&gt;
Electrical effects are commonly used to dynamically draw lightning and electrical arcs.&lt;br /&gt;
&lt;br /&gt;
Whenever a new ''particle instance'' is generated, a [[wikipedia:Bézier curve|Bézier curve]] is subdivided into segments. &lt;br /&gt;
The central vertices are then displaced using a [[wikipedia:Fractal|random fractal algorithm]]. &lt;br /&gt;
The instance's color and line-width is updated over its lifetime.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;ELSM&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|LIFE|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SLIF|IntElement|Segment Lifetime|Particle Creation|Count of frames for newly generated instance to last|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GRAT|RealElement|Generation Rate|System Update|Count of particles to generate per frame; remainder is accumulated across updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SCNT|IntElement|Instance Count|System Init|Maximum count of particle instances and child generators for system|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSEG|IntElement|Segment Count|System Init|Maximum count of line segments per instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Swoosh Color|Particle Creation and Update|Modulation color evaluated for swoosh-based instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IEMT|EmitterElement|Initial Emitter|Particle Creation|Position source for instance start-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|FEMT|EmitterElement|Final Emitter|Particle Creation|Position source for instance end-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPL|RealElement|Length Amplitude|Particle Creation|Randomized coefficient of fractal displacement as product of segment count|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPD|RealElement|Direct Amplitude|Particle Creation|Separately randomized coefficient of fractal displacement|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD1|RealElement|Line Width 1|Particle Creation and Update|Enables line 1 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD2|RealElement|Line Width 2|Particle Creation and Update|Enables line 2 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD3|RealElement|Line Width 3|Particle Creation and Update|Enables line 3 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL1|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 1's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL2|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 2's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL3|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 3's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSWH|[[SWHC (File Format)|SWHC]]|Child Swoosh|System Init|Use swoosh system to draw effect; computed fractal points are set into swoosh's history; Omitting LWD* properties will only draw the swoosh|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GPSM|[[PART (File Format)|PART]]|Start Child Particle|System Init|Draw particle system positioned at instance's start-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|EPSM|[[PART (File Format)|PART]]|End Child Particle|System Init|Draw particle system positioned at instance's end-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZERY|bool|Zero Y|Particle Creation|Zero Y component of newly created particle vertices|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1890</id>
		<title>ELSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1890"/>
				<updated>2017-06-11T04:05:57Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''ELSC''' [[Particle Script|particle script]] format is used to build electrical effects in the ''Metroid Prime'' series.&lt;br /&gt;
Electrical effects are commonly used to dynamically draw lightning and electrical arcs.&lt;br /&gt;
&lt;br /&gt;
An electrical ''particle instance'' is a single line subdivided into ''segments''. Whenever a new instance is generated, a&lt;br /&gt;
[[wikipedia:Bézier curve|Bézier curve]] is subdivided into segments. The central vertices are displaced using &lt;br /&gt;
a [[wikipedia:Fractal|random fractal algorithm]]. The instance's color and line-width is updated over its lifetime.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;ELSM&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|LIFE|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SLIF|IntElement|Segment Lifetime|Particle Creation|Count of frames for newly generated instance to last|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GRAT|RealElement|Generation Rate|System Update|Count of particles to generate per frame; remainder is accumulated across updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SCNT|IntElement|Instance Count|System Init|Maximum count of particle instances and child generators for system|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSEG|IntElement|Segment Count|System Init|Maximum count of line segments per instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Swoosh Color|Particle Creation and Update|Modulation color evaluated for swoosh-based instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IEMT|EmitterElement|Initial Emitter|Particle Creation|Position source for instance start-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|FEMT|EmitterElement|Final Emitter|Particle Creation|Position source for instance end-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPL|RealElement|Length Amplitude|Particle Creation|Randomized coefficient of fractal displacement as product of segment count|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPD|RealElement|Direct Amplitude|Particle Creation|Separately randomized coefficient of fractal displacement|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD1|RealElement|Line Width 1|Particle Creation and Update|Enables line 1 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD2|RealElement|Line Width 2|Particle Creation and Update|Enables line 2 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD3|RealElement|Line Width 3|Particle Creation and Update|Enables line 3 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL1|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 1's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL2|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 2's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL3|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 3's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSWH|[[SWHC (File Format)|SWHC]]|Child Swoosh|System Init|Use swoosh system to draw effect; computed fractal points are set into swoosh's history; Omitting LWD* properties will only draw the swoosh|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GPSM|[[PART (File Format)|PART]]|Start Child Particle|System Init|Draw particle system positioned at instance's start-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|EPSM|[[PART (File Format)|PART]]|End Child Particle|System Init|Draw particle system positioned at instance's end-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZERY|bool|Zero Y|Particle Creation|Zero Y component of newly created particle vertices|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1889</id>
		<title>ELSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1889"/>
				<updated>2017-06-11T04:01:59Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''ELSC''' [[Particle Script|particle script]] format is used to build electrical effects in the ''Metroid Prime'' series.&lt;br /&gt;
Electrical effects are commonly used to dynamically draw lightning and electrical arcs.&lt;br /&gt;
&lt;br /&gt;
An electrical ''particle instance'' is a single line subdivided into ''segments''. Whenever a new instance is generated, a&lt;br /&gt;
[[wikipedia:Bézier curve|Bézier curve]] is subdivided into segments. The segment's central vertices are displaced using &lt;br /&gt;
a [[wikipedia:Fractal|random fractal algorithm]]. The instance's color and line-width is updated over its lifetime.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;ELSM&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|LIFE|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SLIF|IntElement|Segment Lifetime|Particle Creation|Count of frames for newly generated instance to last|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GRAT|RealElement|Generation Rate|System Update|Count of particles to generate per frame; remainder is accumulated across updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SCNT|IntElement|Instance Count|System Init|Maximum count of particle instances and child generators for system|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSEG|IntElement|Segment Count|System Init|Maximum count of line segments per instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Swoosh Color|Particle Creation and Update|Modulation color evaluated for swoosh-based instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IEMT|EmitterElement|Initial Emitter|Particle Creation|Position source for instance start-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|FEMT|EmitterElement|Final Emitter|Particle Creation|Position source for instance end-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPL|RealElement|Length Amplitude|Particle Creation|Randomized coefficient of fractal displacement as product of segment count|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPD|RealElement|Direct Amplitude|Particle Creation|Separately randomized coefficient of fractal displacement|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD1|RealElement|Line Width 1|Particle Creation and Update|Enables line 1 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD2|RealElement|Line Width 2|Particle Creation and Update|Enables line 2 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD3|RealElement|Line Width 3|Particle Creation and Update|Enables line 3 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL1|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 1's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL2|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 2's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL3|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 3's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSWH|[[SWHC (File Format)|SWHC]]|Child Swoosh|System Init|Use swoosh system to draw effect; computed fractal points are set into swoosh's history; Omitting LWD* properties will only draw the swoosh|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GPSM|[[PART (File Format)|PART]]|Start Child Particle|System Init|Draw particle system positioned at instance's start-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|EPSM|[[PART (File Format)|PART]]|End Child Particle|System Init|Draw particle system positioned at instance's end-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZERY|bool|Zero Y|Particle Creation|Zero Y component of newly created particle vertices|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1888</id>
		<title>ELSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1888"/>
				<updated>2017-06-11T04:01:26Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''ELSC''' [[Particle Script|particle script]] format is used to build electrical effects in the ''Metroid Prime'' series.&lt;br /&gt;
Electrical effects are commonly used to dynamically draw lightning and electrical arcs.&lt;br /&gt;
&lt;br /&gt;
An electrical ''particle instance'' is a single line subdivided into ''segments''. Whenever a new instance is generated, a&lt;br /&gt;
 [[wikipedia:Bézier curve|Bézier curve]] is subdivided into segments. The segment's central vertices are displaced using &lt;br /&gt;
a [[wikipedia:Fractal|random fractal algorithm]]. The instance's color and line-width is updated over its lifetime.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;ELSM&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|LIFE|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SLIF|IntElement|Segment Lifetime|Particle Creation|Count of frames for newly generated instance to last|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GRAT|RealElement|Generation Rate|System Update|Count of particles to generate per frame; remainder is accumulated across updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SCNT|IntElement|Instance Count|System Init|Maximum count of particle instances and child generators for system|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSEG|IntElement|Segment Count|System Init|Maximum count of line segments per instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Swoosh Color|Particle Creation and Update|Modulation color evaluated for swoosh-based instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IEMT|EmitterElement|Initial Emitter|Particle Creation|Position source for instance start-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|FEMT|EmitterElement|Final Emitter|Particle Creation|Position source for instance end-point; Velocity is used to form Bézier points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPL|RealElement|Length Amplitude|Particle Creation|Randomized coefficient of fractal displacement as product of segment count|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPD|RealElement|Direct Amplitude|Particle Creation|Separately randomized coefficient of fractal displacement|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD1|RealElement|Line Width 1|Particle Creation and Update|Enables line 1 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD2|RealElement|Line Width 2|Particle Creation and Update|Enables line 2 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD3|RealElement|Line Width 3|Particle Creation and Update|Enables line 3 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL1|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 1's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL2|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 2's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL3|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 3's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSWH|[[SWHC (File Format)|SWHC]]|Child Swoosh|System Init|Use swoosh system to draw effect; computed fractal points are set into swoosh's history; Omitting LWD* properties will only draw the swoosh|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GPSM|[[PART (File Format)|PART]]|Start Child Particle|System Init|Draw particle system positioned at instance's start-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|EPSM|[[PART (File Format)|PART]]|End Child Particle|System Init|Draw particle system positioned at instance's end-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZERY|bool|Zero Y|Particle Creation|Zero Y component of newly created particle vertices|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1887</id>
		<title>ELSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ELSC_(File_Format)&amp;diff=1887"/>
				<updated>2017-06-11T03:58:33Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''ELSC''' [[Particle Script|particle script]] format is used to build electrical effects in the ''Metroid Prime'' series.&lt;br /&gt;
Electrical effects are commonly used to dynamically draw lightning and electrical arcs.&lt;br /&gt;
&lt;br /&gt;
An electrical ''particle instance'' is a single line subdivided into ''segments''. Whenever a new instance is generated, its central&lt;br /&gt;
vertices are displaced using a [[wikipedia:Fractal|random fractal algorithm]]. The instance's color and line-width is updated&lt;br /&gt;
over its lifetime.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;ELSM&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|LIFE|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SLIF|IntElement|Segment Lifetime|Particle Creation|Count of frames for newly generated instance to last|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GRAT|RealElement|Generation Rate|System Update|Count of particles to generate per frame; remainder is accumulated across updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SCNT|IntElement|Instance Count|System Init|Maximum count of particle instances and child generators for system|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSEG|IntElement|Segment Count|System Init|Maximum count of line segments per instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Swoosh Color|Particle Creation and Update|Modulation color evaluated for swoosh-based instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IEMT|EmitterElement|Initial Emitter|Particle Creation|Position source for instance start-point; Velocity is used to form beziér points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|FEMT|EmitterElement|Final Emitter|Particle Creation|Position source for instance end-point; Velocity is used to form beziér points to curve instance|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPL|RealElement|Length Amplitude|Particle Creation|Randomized coefficient of fractal displacement as product of segment count|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AMPD|RealElement|Direct Amplitude|Particle Creation|Separately randomized coefficient of fractal displacement|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD1|RealElement|Line Width 1|Particle Creation and Update|Enables line 1 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD2|RealElement|Line Width 2|Particle Creation and Update|Enables line 2 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LWD3|RealElement|Line Width 3|Particle Creation and Update|Enables line 3 (overdrawn with same verts) and specifies its width in 480p pixels|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL1|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 1's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL2|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 2's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LCL3|ColorElement|Line Color 1|Particle Creation and Update|Specifies line 3's color|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SSWH|[[SWHC (File Format)|SWHC]]|Child Swoosh|System Init|Use swoosh system to draw effect; computed fractal points are set into swoosh's history; Omitting LWD* properties will only draw the swoosh|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|GPSM|[[PART (File Format)|PART]]|Start Child Particle|System Init|Draw particle system positioned at instance's start-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|EPSM|[[PART (File Format)|PART]]|End Child Particle|System Init|Draw particle system positioned at instance's end-point|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZERY|bool|Zero Y|Particle Creation|Zero Y component of newly created particle vertices|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1886</id>
		<title>SWHC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1886"/>
				<updated>2017-06-08T06:24:25Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''SWHC''' [[Particle Script|particle script]] format is used to build swoosh effects in the ''Metroid Prime'' series.&lt;br /&gt;
Swooshes are characterized as dynamically-generated triangles &amp;quot;brushed&amp;quot; into space.&lt;br /&gt;
&lt;br /&gt;
Each swoosh system emits ''particle instances'' once per frame, connecting each new instance with the previous instance.&lt;br /&gt;
The system will not render until it has a history of ''at least'' 2 swoosh particles (2 frames of updates). Swoosh cross-sections may&lt;br /&gt;
form simple planes through space (&amp;lt;code&amp;gt;SIDE==2&amp;lt;/code&amp;gt;) or extruded prism shapes (&amp;lt;code&amp;gt;SIDE&amp;gt;=3&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
To smooth out intra-frame geometry, vertices connecting particle instances may be calculated using [[wikipedia:Tricubic interpolation|tricubic interpolation]].&lt;br /&gt;
SPLN defines the number of subdivisions with which to perform interpolation.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;SWSH&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|PSLT|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TIME|RealElement|Time Multiplier|Pre Particles Update|Factor that defines number of evaluation frames per real frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LRAD|RealElement|Left Radius|Particle Update|Radius of swoosh cross-section's left side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|RRAD|RealElement|Right Radius|Particle Update|Radius of swoosh cross-section's right side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LENG|IntElement|Length|System Init|Maximum history of swoosh sections to retain (must be at least 2)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Color|Particle Creation and Update|Modulation color of swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SIDE|IntElement|Side Count|System Init|Count of swoosh cross-section sides (2 for plane, 3+ for extruded prism)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IROT|FloatElement|Initial Rotation|Particle Creation|Rotation bias evaluated for new particle instances (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ROTM|FloatElement|Rotation Master|Particle Update|Rotation bias evaluated per particle instance, per frame (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|POFS|VectorElement|Particle Offset|Particle Creation|Local translation bias evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IVEL|VectorElement|Initial Velocity|Particle Creation|Relative velocity evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|NPOS|VectorElement|Next Position|Particle Update|Local translation bias updated per particle instance, per frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VELM|ModVectorElement|Velocity 1|Particle Update|Continuous position and velocity source of particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLM2|ModVectorElement|Velocity 2|Particle Update|Second position and velocity source evaluated after VELM|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SPLN|IntElement|Spline Segments|System Init|Count of intra-frame faces to draw per particle connection, using tricubic spline interpolation|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXR|UVElement|Texture|System Render|Texture and UV source for swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TSPN|IntElement|Texture Span|System Render|Count of particle instances over which to scale UV coordinate cycle|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LLRD|bool|Left Radius for Right|System Init|Use LRAD value for RRAD|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CROS|bool|Cross|System Init|Intersect surfaces across cross-section verts, as opposed to a non-intersecting prism|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS1|bool|Local Velocity 1|System Init|Evaluate VELM in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS2|bool|Local Velocity 2|System Init|Evaluate VLM2 in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SROT|bool|Single Rotation|System Init|Update IROT per particle instance, per frame and ignore ROTM, otherwise once per system update|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|WIRE|bool|Wireframe|System Init|Render surfaces as triangle wireframe|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXW|bool|{{unknown}}|System Init|Unused|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AALP|bool|Additive Alpha|System Init|Draw using additive alpha blending|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZBUF|bool|Z-buffer Update|System Init|Enable Z-buffer updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ORNT|bool|View Orient|System Init|Render surface facing view (2-SIDE only, no SPLN)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CRND|bool|Clock Random|System Init|Use current CPU time for random seed, rather than 99|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1885</id>
		<title>SWHC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1885"/>
				<updated>2017-06-08T06:23:03Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''SWHC''' [[Particle Script|particle script]] format is used to build swoosh effects in the ''Metroid Prime'' series.&lt;br /&gt;
Swooshes are characterized as dynamically-generated triangles &amp;quot;brushed&amp;quot; into space.&lt;br /&gt;
&lt;br /&gt;
Each swoosh system emits ''particle instances'' once per frame, connecting each new instance with the previous instance.&lt;br /&gt;
The system will not render until it has a history of ''at least'' 2 swoosh particles (2 frames of updates). Swoosh cross-sections may&lt;br /&gt;
form simple planes through space (&amp;lt;code&amp;gt;SIDE==2&amp;lt;/code&amp;gt;) or extruded prism shapes (&amp;lt;code&amp;gt;SIDE&amp;gt;=3&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
To smooth out intra-frame geometry, vertices connecting particle instances may be calculated using [[wikipedia:Tricubic interpolation|tricubic interpolation]].&lt;br /&gt;
SPLN defines the number of subdivisions with which to perform interpolation.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;SWSH&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|PSLT|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TIME|RealElement|Time Multiplier|Pre Particles Update|Factor that defines number of evaluation frames per real frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LRAD|RealElement|Left Radius|Particle Update|Radius of swoosh cross-section's left side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|RRAD|RealElement|Right Radius|Particle Update|Radius of swoosh cross-section's right side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LENG|IntElement|Length|System Init|Maximum history of swoosh sections to retain (must be at least 2)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Color|Particle Creation and Update|Modulation color of swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SIDE|IntElement|Side Count|System Init|Count of swoosh cross-section sides (2 for plane, 3+ for extruded prism)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IROT|FloatElement|Initial Rotation|Particle Creation|Rotation bias evaluated for new particle instances (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ROTM|FloatElement|Rotation Master|Particle Update|Rotation bias evaluated per particle instance, per frame (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|POFS|VectorElement|Particle Offset|Particle Creation|Local translation bias evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IVEL|VectorElement|Initial Velocity|Particle Creation|Relative velocity evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|NPOS|VectorElement|Next Position|Particle Update|Local translation bias updated per particle instance, per frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VELM|ModVectorElement|Velocity 1|Particle Update|Continuous position and velocity source of particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLM2|ModVectorElement|Velocity 2|Particle Update|Second position and velocity source evaluated after VELM|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SPLN|IntElement|Spline Segments|System Init|Count of intra-frame faces to draw per particle connection, using tricubic spline interpolation|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXR|UVElement|Texture|System Render|Texture and UV source for swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TSPN|IntElement|Texture Span|System Render|Count of particle instances over which to scale UV coordinate cycle|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LLRD|BoolElement|Left Radius for Right|System Init|Use LRAD value for RRAD|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CROS|BoolElement|Cross|System Init|Intersect surfaces across cross-section verts, as opposed to a non-intersecting prism|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS1|BoolElement|Local Velocity 1|System Init|Evaluate VELM in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS2|BoolElement|Local Velocity 2|System Init|Evaluate VLM2 in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SROT|BoolElement|Single Rotation|System Init|Update IROT per particle instance, per frame and ignore ROTM, otherwise once per system update|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|WIRE|BoolElement|Wireframe|System Init|Render surfaces as triangle wireframe|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXW|BoolElement|{{unknown}}|System Init|Unused|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AALP|BoolElement|Additive Alpha|System Init|Draw using additive alpha blending|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZBUF|BoolElement|Z-buffer Update|System Init|Enable Z-buffer updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ORNT|BoolElement|View Orient|System Init|Render surface facing view (2-SIDE only, no SPLN)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CRND|BoolElement|Clock Random|System Init|Use current CPU time for random seed, rather than 99|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1884</id>
		<title>SWHC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1884"/>
				<updated>2017-06-04T23:47:07Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|1|Properties beyond MP1 need to be discovered and documented}}&lt;br /&gt;
The '''SWHC''' [[Effect Script|effect script]] format is used to build swoosh effects in the ''Metroid Prime'' series.&lt;br /&gt;
Swooshes are characterized as dynamically-generated triangles &amp;quot;brushed&amp;quot; into space.&lt;br /&gt;
&lt;br /&gt;
Each swoosh system emits ''particle instances'' once per frame, connecting each new instance with the previous instance.&lt;br /&gt;
The system will not render until it has a history of ''at least'' 2 swoosh particles (2 frames of updates). Swoosh cross-sections may&lt;br /&gt;
form simple planes through space (&amp;lt;code&amp;gt;SIDE==2&amp;lt;/code&amp;gt;) or extruded prism shapes (&amp;lt;code&amp;gt;SIDE&amp;gt;=3&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
To smooth out intra-frame geometry, vertices connecting particle instances may be calculated using [[wikipedia:Tricubic interpolation|tricubic interpolation]].&lt;br /&gt;
SPLN defines the number of subdivisions with which to perform interpolation.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;SWSH&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|PSLT|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TIME|RealElement|Time Multiplier|Pre Particles Update|Factor that defines number of evaluation frames per real frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LRAD|RealElement|Left Radius|Particle Update|Radius of swoosh cross-section's left side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|RRAD|RealElement|Right Radius|Particle Update|Radius of swoosh cross-section's right side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LENG|IntElement|Length|System Init|Maximum history of swoosh sections to retain (must be at least 2)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Color|Particle Creation and Update|Modulation color of swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SIDE|IntElement|Side Count|System Init|Count of swoosh cross-section sides (2 for plane, 3+ for extruded prism)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IROT|FloatElement|Instance Rotation|Particle Creation|Rotation bias evaluated for new particle instances (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ROTM|FloatElement|Rotation Master|Particle Update|Rotation bias evaluated per particle instance, per frame (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|POFS|VectorElement|Particle Offset|Particle Creation|Local translation bias evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IVEL|VectorElement|Particle Offset|Particle Creation|Relative velocity evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|NPOS|VectorElement|Particle Offset|Particle Update|Local translation bias updated per particle instance, per frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VELM|ModVectorElement|Velocity 1|Particle Update|Continuous position and velocity source of particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLM2|ModVectorElement|Velocity 2|Particle Update|Second position and velocity source evaluated after VELM|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SPLN|IntElement|Spline Segments|System Init|Count of intra-frame faces to draw per particle connection, using tricubic spline interpolation|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXR|UVElement|Texture|System Render|Texture and UV source for swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TSPN|IntElement|Texture Span|System Render|Count of particle instances over which to scale UV coordinate cycle|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LLRD|BoolElement|Left Radius for Right|System Init|Use LRAD value for RRAD|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CROS|BoolElement|Cross|System Init|Intersect surfaces across cross-section verts, as opposed to a non-intersecting prism|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS1|BoolElement|Local Velocity 1|System Init|Evaluate VELM in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS2|BoolElement|Local Velocity 2|System Init|Evaluate VLM2 in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SROT|BoolElement|Single Rotation|System Init|Update IROT per particle instance, per frame and ignore ROTM, otherwise once per system update|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|WIRE|BoolElement|Single Rotation|System Init|Render surfaces as triangle wireframe|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXW|BoolElement|{{unknown}}|System Init|Unused|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AALP|BoolElement|Additive Alpha|System Init|Draw using additive alpha blending|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZBUF|BoolElement|Z-buffer Update|System Init|Enable Z-buffer updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ORNT|BoolElement|View Orient|System Init|Render surface facing view (2-SIDE only, no SPLN)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CRND|BoolElement|View Orient|System Init|Use current CPU time for random seed, rather than 99|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1883</id>
		<title>SWHC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=SWHC_(File_Format)&amp;diff=1883"/>
				<updated>2017-06-04T23:34:15Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* SWHC Keys */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{research|2|Key parameters need reverse-engineering}}&lt;br /&gt;
The '''SWHC''' [[Effect Script|effect script]] format is used to build swoosh effects in the ''Metroid Prime'' series.&lt;br /&gt;
Swooshes are characterized as dynamically-generated, trailing ''triangle-strips'' &amp;quot;brushed&amp;quot; into space.&lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
Particle generator properties are assembled into a [[Particle Script|particle script]]&lt;br /&gt;
file tagged with &amp;lt;code&amp;gt;SWSH&amp;lt;/code&amp;gt;. Any of the following properties are loaded into a&lt;br /&gt;
''description'' class for constructing an arbitrary number of ''particle generators''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! FourCC&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
! Scope&lt;br /&gt;
! Notes&lt;br /&gt;
! MP1&lt;br /&gt;
! MP2&lt;br /&gt;
! MP3&lt;br /&gt;
! DKCR&lt;br /&gt;
! DKCTF&lt;br /&gt;
|-&lt;br /&gt;
{{ParticlePropertyRow|PSLT|IntElement|Particle System Lifetime|System Init|Count of frames to emit new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TIME|RealElement|Time Multiplier|Pre Particles Update|Factor that defines number of evaluation frames per real frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LRAD|RealElement|Left Radius|Particle Update|Radius of swoosh cross-section's left side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|RRAD|RealElement|Right Radius|Particle Update|Radius of swoosh cross-section's right side|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LENG|IntElement|Length|System Init|Maximum history of swoosh sections to retain (must be at least 2)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|COLR|ColorElement|Color|Particle Creation and Update|Modulation color of swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SIDE|IntElement|Side Count|System Init|Count of swoosh cross-section sides (2 for plane, 3+ for extruded prism)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IROT|FloatElement|Instance Rotation|Particle Creation|Rotation bias evaluated for new particle instances (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ROTM|FloatElement|Rotation Master|Particle Update|Rotation bias evaluated per particle instance, per frame (in degrees)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|POFS|VectorElement|Particle Offset|Particle Creation|Local translation bias evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|IVEL|VectorElement|Particle Offset|Particle Creation|Relative velocity evaluated for new particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|NPOS|VectorElement|Particle Offset|Particle Update|Local translation bias updated per particle instance, per frame|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VELM|ModVectorElement|Velocity 1|Particle Update|Continuous position and velocity source of particle instances|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLM2|ModVectorElement|Velocity 2|Particle Update|Second position and velocity source evaluated after VELM|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SPLN|IntElement|Spline Segments|System Init|Count of intra-frame faces to draw per particle connection, using tricubic spline interpolation|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXR|UVElement|Texture|System Render|Texture and UV source for swoosh surfaces|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TSPN|IntElement|Texture Span|System Render|Count of particle instances over which to scale UV coordinate cycle|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|LLRD|BoolElement|Left Radius for Right|System Init|Use LRAD value for RRAD|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CROS|BoolElement|Cross|System Init|Intersect surfaces across cross-section verts, as opposed to a non-intersecting prism|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS1|BoolElement|Local Velocity 1|System Init|Evaluate VELM in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|VLS2|BoolElement|Local Velocity 2|System Init|Evaluate VLM2 in particle-local space|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|SROT|BoolElement|Single Rotation|System Init|Update IROT per particle instance, per frame and ignore ROTM, otherwise once per system update|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|WIRE|BoolElement|Single Rotation|System Init|Render surfaces as triangle wireframe|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|TEXW|BoolElement|{{unknown}}|System Init|Unused|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|AALP|BoolElement|Additive Alpha|System Init|Draw using additive alpha blending|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ZBUF|BoolElement|Z-buffer Update|System Init|Enable Z-buffer updates|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|ORNT|BoolElement|View Orient|System Init|Render surface facing view (2-SIDE only, no SPLN)|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
{{ParticlePropertyRow|CRND|BoolElement|View Orient|System Init|Use current CPU time for random seed, rather than 99|{{check}}|{{nocheck}}|{{nocheck}}|{{nocheck}}|{{nocheck}}}}&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1875</id>
		<title>MAPA (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1875"/>
				<updated>2017-04-25T00:57:47Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''.MAPA file format''' defines the minimap models used in the Metroid Prime series. MAPA or '''MAP A'''rea consists of several sections: The header, Point Of Interest entries, Vertices, Primitive Headers, and the primitives.&lt;br /&gt;
&lt;br /&gt;
{{research|2|A few things are unknown in the header and POI Entries}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Format ==&lt;br /&gt;
=== Header ===&lt;br /&gt;
The header is very straight forward, and has some minor differences depending on version, the unknown values don't seem to do anything, however not much research has been put into them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Magic'''; Always 0xDEADD00D&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Version'''; See below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; unknown function in MP1/3, specifies whether the area appears on the Light (0) or Dark (1) map in MP2&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible (Map Universe Area)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit or Map Station (most MP1 areas)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit only (latter areas of Ruins and Phendrana)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{AABox}}&lt;br /&gt;
|'''Bounding Box'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''POI Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Vertex Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Version ====&lt;br /&gt;
The version value listed above can have the following values:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Game&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 1&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 2: Echoes&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 3: Corruption&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mappable Objects ===&lt;br /&gt;
A Mappable Object in the Metroid Prime series can include: Elevators, Doors, and Save/Missile Stations. Each Mappable Object entry consists of the following struct:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1 &amp;amp; MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; See table below for MP1 types&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Door Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Editor ID'''; Same ID format as SCLY, indicates associated world object&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Vector4f}}&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Padding'''; always -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Transform4f}}&lt;br /&gt;
|'''Tranform Matrix''' The Point of Interest's position in '''world''' space.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32 * 4&lt;br /&gt;
|'''Padding'''; four values of -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MP1 Types ====&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Normal Door&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Shield Door&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Ice Door&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Wave Door&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Plasma Door&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Big Door&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Big Door 2&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|Ice Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|Ice Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|Wave Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Wave Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|Plasma Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|Plasma Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|Ice Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|Wave Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|Plasma Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|27&lt;br /&gt;
|Down Arrow Yellow (Maintenance Tunnel)&lt;br /&gt;
|-&lt;br /&gt;
|28&lt;br /&gt;
|Up Arrow Yellow (Phazon Processing Center)&lt;br /&gt;
|-&lt;br /&gt;
|29&lt;br /&gt;
|Down Arrow Green (Elevator A)&lt;br /&gt;
|-&lt;br /&gt;
|30&lt;br /&gt;
|Up Arrow Green (Elite Control Access)&lt;br /&gt;
|-&lt;br /&gt;
|31&lt;br /&gt;
|Down Arrow Red (Elevator B)&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|Up Arrow Red (Fungal Hall Access)&lt;br /&gt;
|-&lt;br /&gt;
|33&lt;br /&gt;
|Elevator&lt;br /&gt;
|-&lt;br /&gt;
|34&lt;br /&gt;
|Save Station&lt;br /&gt;
|-&lt;br /&gt;
|37&lt;br /&gt;
|Missile Station&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vertices ===&lt;br /&gt;
&lt;br /&gt;
Vertices are a simple array of CVector3f. Geometry in MAPAs is, almost always, centered around the origin (0, 0, 0) and are simplified, full sized, versions of the map they replicate. Each vertex is referenced at least twice: once for the primitive, once for the line border.&lt;br /&gt;
&lt;br /&gt;
=== Primitive Headers ===&lt;br /&gt;
&lt;br /&gt;
The Primitive headers are extremely simple, they merely have a bounding box followed by the primitive table start and end point, relative to the end of the current primitive header. In other words: read in the header, seek to the start of the table from the '''current''' position, then read the primitives tables.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|{{Vector3f}}&lt;br /&gt;
|'''Normal'''&lt;br /&gt;
|-&lt;br /&gt;
|{{Vector3f}}&lt;br /&gt;
|'''Center of Mass'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table Start'''; relative to the end of the header&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Table Start'''; relative to the end of the header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive Table ===&lt;br /&gt;
&lt;br /&gt;
The Primitive is also fairly simple, each one consists of two parts: The GX Primitive list, and the Border list. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count (PC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Primitive * PC&lt;br /&gt;
|'''Primitives'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Count (BC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Border * (BC)&lt;br /&gt;
|'''Borders'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive ===&lt;br /&gt;
&lt;br /&gt;
A primitive in a MAPA is a simple 4 byte aligned list of indices into the vertex list, starting with the GX Primitive type, a count, then an array of indices, each index taking up one byte.&lt;br /&gt;
&lt;br /&gt;
=== Border ===&lt;br /&gt;
&lt;br /&gt;
A border in a MAPA is a simple count followed by a 4 byte aligned list indices into the vertex list, each index taking up one byte. A border is simply drawn using GX_LINESTRIP.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1873</id>
		<title>MAPA (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1873"/>
				<updated>2017-04-22T20:55:39Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Mappable Objects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''.MAPA file format''' defines the minimap models used in the Metroid Prime series. MAPA or '''MAP A'''rea consists of several sections: The header, Point Of Interest entries, Vertices, Primitive Headers, and the primitives.&lt;br /&gt;
&lt;br /&gt;
{{research|2|A few things are unknown in the header and POI Entries}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Format ==&lt;br /&gt;
=== Header ===&lt;br /&gt;
The header is very straight forward, and has some minor differences depending on version, the unknown values don't seem to do anything, however not much research has been put into them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Magic'''; Always 0xDEADD00D&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Version'''; See below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; unknown function in MP1/3, specifies whether the area appears on the Light (0) or Dark (1) map in MP2&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit or Map Station (most MP1 areas)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit only (latter areas of Ruins and Phendrana)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CAABox&lt;br /&gt;
|'''Bounding Box'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''POI Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Vertex Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Version ====&lt;br /&gt;
The version value listed above can have the following values:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Game&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 1&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 2: Echoes&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 3: Corruption&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mappable Objects ===&lt;br /&gt;
A Mappable Object in the Metroid Prime series can include: Elevators, Doors, and Save/Missile Stations. Each Mappable Object entry consists of the following struct:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1 &amp;amp; MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; See table below for MP1 types&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Door Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Editor ID'''; Same ID format as SCLY, indicates associated world object&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|CVector4f&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Padding'''; always -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CTransform4f&lt;br /&gt;
|'''Tranform Matrix''' The Point of Interest's position in '''world''' space.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32 * 4&lt;br /&gt;
|'''Padding'''; four values of -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MP1 Types ====&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Normal Door&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Shield Door&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Ice Door&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Wave Door&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Plasma Door&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Big Door&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Big Door 2&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|Ice Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|Ice Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|Wave Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Wave Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|Plasma Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|Plasma Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|Ice Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|Wave Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|Plasma Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|27&lt;br /&gt;
|Down Arrow Yellow (Maintenance Tunnel)&lt;br /&gt;
|-&lt;br /&gt;
|28&lt;br /&gt;
|Up Arrow Yellow (Phazon Processing Center)&lt;br /&gt;
|-&lt;br /&gt;
|29&lt;br /&gt;
|Down Arrow Green (Elevator A)&lt;br /&gt;
|-&lt;br /&gt;
|30&lt;br /&gt;
|Up Arrow Green (Elite Control Access)&lt;br /&gt;
|-&lt;br /&gt;
|31&lt;br /&gt;
|Down Arrow Red (Elevator B)&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|Up Arrow Red (Fungal Hall Access)&lt;br /&gt;
|-&lt;br /&gt;
|33&lt;br /&gt;
|Elevator&lt;br /&gt;
|-&lt;br /&gt;
|34&lt;br /&gt;
|Save Station&lt;br /&gt;
|-&lt;br /&gt;
|37&lt;br /&gt;
|Missile Station&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vertices ===&lt;br /&gt;
&lt;br /&gt;
Vertices are a simple array of CVector3f. Geometry in MAPAs is, almost always, centered around the origin (0, 0, 0) and are simplified, full sized, versions of the map they replicate. Each vertex is referenced at least twice: once for the primitive, once for the line border.&lt;br /&gt;
&lt;br /&gt;
=== Primitive Headers ===&lt;br /&gt;
&lt;br /&gt;
The Primitive headers are extremely simple, they merely have a bounding box followed by the primitive table start and end point, relative to the end of the current primitive header. In other words: read in the header, seek to the start of the table from the '''current''' position, then read the primitives tables.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Normal'''&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Center of Mass'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table Start'''; relative to the end of the header&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Table Start'''; relative to the end of the header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive Table ===&lt;br /&gt;
&lt;br /&gt;
The Primitive is also fairly simple, each one consists of two parts: The GX Primitive list, and the Border list. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count (PC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Primitive * PC&lt;br /&gt;
|'''Primitives'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Count (BC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Border * (BC)&lt;br /&gt;
|'''Borders'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive ===&lt;br /&gt;
&lt;br /&gt;
A primitive in a MAPA is a simple 4 byte aligned list of indices into the vertex list, starting with the GX Primitive type, a count, then an array of indices, each index taking up one byte.&lt;br /&gt;
&lt;br /&gt;
=== Border ===&lt;br /&gt;
&lt;br /&gt;
A border in a MAPA is a simple count followed by a 4 byte aligned list indices into the vertex list, each index taking up one byte. A border is simply drawn using GX_LINESTRIP.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1872</id>
		<title>MAPA (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1872"/>
				<updated>2017-04-22T20:53:13Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Mappable Objects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''.MAPA file format''' defines the minimap models used in the Metroid Prime series. MAPA or '''MAP A'''rea consists of several sections: The header, Point Of Interest entries, Vertices, Primitive Headers, and the primitives.&lt;br /&gt;
&lt;br /&gt;
{{research|2|A few things are unknown in the header and POI Entries}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Format ==&lt;br /&gt;
=== Header ===&lt;br /&gt;
The header is very straight forward, and has some minor differences depending on version, the unknown values don't seem to do anything, however not much research has been put into them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Magic'''; Always 0xDEADD00D&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Version'''; See below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; unknown function in MP1/3, specifies whether the area appears on the Light (0) or Dark (1) map in MP2&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit or Map Station (most MP1 areas)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit only (latter areas of Ruins and Phendrana)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CAABox&lt;br /&gt;
|'''Bounding Box'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''POI Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Vertex Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Version ====&lt;br /&gt;
The version value listed above can have the following values:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Game&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 1&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 2: Echoes&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 3: Corruption&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mappable Objects ===&lt;br /&gt;
A Mappable Object in the Metroid Prime series can include: Elevators, Doors, and Save/Missile Stations. Each Point of Interest entry consists of the following struct:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1 &amp;amp; MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; See table below for MP1 types&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Door Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Editor ID'''; Same ID format as SCLY, indicates associated world object&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|CVector4f&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Padding'''; always -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CTransform4f&lt;br /&gt;
|'''Tranform Matrix''' The Point of Interest's position in '''world''' space.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32 * 4&lt;br /&gt;
|'''Padding'''; four values of -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MP1 Types ====&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Normal Door&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Shield Door&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Ice Door&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Wave Door&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Plasma Door&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Big Door&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Big Door 2&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|Ice Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|Ice Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|Wave Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Wave Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|Plasma Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|Plasma Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|Ice Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|Wave Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|Plasma Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|27&lt;br /&gt;
|Down Arrow Yellow (Maintenance Tunnel)&lt;br /&gt;
|-&lt;br /&gt;
|28&lt;br /&gt;
|Up Arrow Yellow (Phazon Processing Center)&lt;br /&gt;
|-&lt;br /&gt;
|29&lt;br /&gt;
|Down Arrow Green (Elevator A)&lt;br /&gt;
|-&lt;br /&gt;
|30&lt;br /&gt;
|Up Arrow Green (Elite Control Access)&lt;br /&gt;
|-&lt;br /&gt;
|31&lt;br /&gt;
|Down Arrow Red (Elevator B)&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|Up Arrow Red (Fungal Hall Access)&lt;br /&gt;
|-&lt;br /&gt;
|33&lt;br /&gt;
|Elevator&lt;br /&gt;
|-&lt;br /&gt;
|34&lt;br /&gt;
|Save Station&lt;br /&gt;
|-&lt;br /&gt;
|37&lt;br /&gt;
|Missile Station&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vertices ===&lt;br /&gt;
&lt;br /&gt;
Vertices are a simple array of CVector3f. Geometry in MAPAs is, almost always, centered around the origin (0, 0, 0) and are simplified, full sized, versions of the map they replicate. Each vertex is referenced at least twice: once for the primitive, once for the line border.&lt;br /&gt;
&lt;br /&gt;
=== Primitive Headers ===&lt;br /&gt;
&lt;br /&gt;
The Primitive headers are extremely simple, they merely have a bounding box followed by the primitive table start and end point, relative to the end of the current primitive header. In other words: read in the header, seek to the start of the table from the '''current''' position, then read the primitives tables.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Normal'''&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Center of Mass'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table Start'''; relative to the end of the header&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Table Start'''; relative to the end of the header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive Table ===&lt;br /&gt;
&lt;br /&gt;
The Primitive is also fairly simple, each one consists of two parts: The GX Primitive list, and the Border list. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count (PC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Primitive * PC&lt;br /&gt;
|'''Primitives'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Count (BC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Border * (BC)&lt;br /&gt;
|'''Borders'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive ===&lt;br /&gt;
&lt;br /&gt;
A primitive in a MAPA is a simple 4 byte aligned list of indices into the vertex list, starting with the GX Primitive type, a count, then an array of indices, each index taking up one byte.&lt;br /&gt;
&lt;br /&gt;
=== Border ===&lt;br /&gt;
&lt;br /&gt;
A border in a MAPA is a simple count followed by a 4 byte aligned list indices into the vertex list, each index taking up one byte. A border is simply drawn using GX_LINESTRIP.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1871</id>
		<title>MAPA (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1871"/>
				<updated>2017-04-22T20:51:08Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Point of Interest */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''.MAPA file format''' defines the minimap models used in the Metroid Prime series. MAPA or '''MAP A'''rea consists of several sections: The header, Point Of Interest entries, Vertices, Primitive Headers, and the primitives.&lt;br /&gt;
&lt;br /&gt;
{{research|2|A few things are unknown in the header and POI Entries}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Format ==&lt;br /&gt;
=== Header ===&lt;br /&gt;
The header is very straight forward, and has some minor differences depending on version, the unknown values don't seem to do anything, however not much research has been put into them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Magic'''; Always 0xDEADD00D&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Version'''; See below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; unknown function in MP1/3, specifies whether the area appears on the Light (0) or Dark (1) map in MP2&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit or Map Station (most MP1 areas)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit only (latter areas of Ruins and Phendrana)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CAABox&lt;br /&gt;
|'''Bounding Box'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''POI Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Vertex Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Version ====&lt;br /&gt;
The version value listed above can have the following values:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Game&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 1&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 2: Echoes&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 3: Corruption&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Mappable Objects ===&lt;br /&gt;
A Mappable Object in the Metroid Prime series can include: Elevators, Doors, and Save/Map/Missile Stations. Each Point of Interest entry consists of the following struct:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1 &amp;amp; MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; See table below for MP1 types&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Door Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Editor ID'''; Same ID format as SCLY, indicates associated world object&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|CVector4f&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Padding'''; always -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CTransform4f&lt;br /&gt;
|'''Tranform Matrix''' The Point of Interest's position in '''world''' space.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32 * 4&lt;br /&gt;
|'''Padding'''; four values of -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MP1 Types ====&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Normal Door&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Shield Door&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Ice Door&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Wave Door&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Plasma Door&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Big Door&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Big Door 2&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|Ice Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|Ice Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|Wave Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Wave Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|Plasma Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|Plasma Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|Ice Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|Wave Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|Plasma Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|27&lt;br /&gt;
|Down Arrow Yellow (Maintenance Tunnel)&lt;br /&gt;
|-&lt;br /&gt;
|28&lt;br /&gt;
|Up Arrow Yellow (Phazon Processing Center)&lt;br /&gt;
|-&lt;br /&gt;
|29&lt;br /&gt;
|Down Arrow Green (Elevator A)&lt;br /&gt;
|-&lt;br /&gt;
|30&lt;br /&gt;
|Up Arrow Green (Elite Control Access)&lt;br /&gt;
|-&lt;br /&gt;
|31&lt;br /&gt;
|Down Arrow Red (Elevator B)&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|Up Arrow Red (Fungal Hall Access)&lt;br /&gt;
|-&lt;br /&gt;
|33&lt;br /&gt;
|Elevator&lt;br /&gt;
|-&lt;br /&gt;
|34&lt;br /&gt;
|Save Station&lt;br /&gt;
|-&lt;br /&gt;
|37&lt;br /&gt;
|Missile Station&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vertices ===&lt;br /&gt;
&lt;br /&gt;
Vertices are a simple array of CVector3f. Geometry in MAPAs is, almost always, centered around the origin (0, 0, 0) and are simplified, full sized, versions of the map they replicate. Each vertex is referenced at least twice: once for the primitive, once for the line border.&lt;br /&gt;
&lt;br /&gt;
=== Primitive Headers ===&lt;br /&gt;
&lt;br /&gt;
The Primitive headers are extremely simple, they merely have a bounding box followed by the primitive table start and end point, relative to the end of the current primitive header. In other words: read in the header, seek to the start of the table from the '''current''' position, then read the primitives tables.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Normal'''&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Center of Mass'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table Start'''; relative to the end of the header&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Table Start'''; relative to the end of the header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive Table ===&lt;br /&gt;
&lt;br /&gt;
The Primitive is also fairly simple, each one consists of two parts: The GX Primitive list, and the Border list. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count (PC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Primitive * PC&lt;br /&gt;
|'''Primitives'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Count (BC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Border * (BC)&lt;br /&gt;
|'''Borders'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive ===&lt;br /&gt;
&lt;br /&gt;
A primitive in a MAPA is a simple 4 byte aligned list of indices into the vertex list, starting with the GX Primitive type, a count, then an array of indices, each index taking up one byte.&lt;br /&gt;
&lt;br /&gt;
=== Border ===&lt;br /&gt;
&lt;br /&gt;
A border in a MAPA is a simple count followed by a 4 byte aligned list indices into the vertex list, each index taking up one byte. A border is simply drawn using GX_LINESTRIP.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1870</id>
		<title>MAPA (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1870"/>
				<updated>2017-04-22T20:49:37Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Point of Interest */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''.MAPA file format''' defines the minimap models used in the Metroid Prime series. MAPA or '''MAP A'''rea consists of several sections: The header, Point Of Interest entries, Vertices, Primitive Headers, and the primitives.&lt;br /&gt;
&lt;br /&gt;
{{research|2|A few things are unknown in the header and POI Entries}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Format ==&lt;br /&gt;
=== Header ===&lt;br /&gt;
The header is very straight forward, and has some minor differences depending on version, the unknown values don't seem to do anything, however not much research has been put into them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Magic'''; Always 0xDEADD00D&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Version'''; See below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; unknown function in MP1/3, specifies whether the area appears on the Light (0) or Dark (1) map in MP2&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit or Map Station (most MP1 areas)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit only (latter areas of Ruins and Phendrana)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CAABox&lt;br /&gt;
|'''Bounding Box'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''POI Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Vertex Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Version ====&lt;br /&gt;
The version value listed above can have the following values:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Game&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 1&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 2: Echoes&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 3: Corruption&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Point of Interest ===&lt;br /&gt;
A Point of Interest in the Metroid Prime series can include: Mission Objectives, Elevators, Doors, Map Stations, and Missile Stations. Each Point of Interest entry consists of the following struct:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1 &amp;amp; MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; See table below for MP1 types&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Door Visit&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Map Station or Area Visit&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Editor ID'''; Same ID format as SCLY, indicates associated world object&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|CVector4f&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Padding'''; always -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CTransform4f&lt;br /&gt;
|'''Tranform Matrix''' The Point of Interest's position in '''world''' space.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32 * 4&lt;br /&gt;
|'''Padding'''; four values of -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MP1 Types ====&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Normal Door&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Shield Door&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|Ice Door&lt;br /&gt;
|-&lt;br /&gt;
|3&lt;br /&gt;
|Wave Door&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|Plasma Door&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|Big Door&lt;br /&gt;
|-&lt;br /&gt;
|6&lt;br /&gt;
|Big Door 2&lt;br /&gt;
|-&lt;br /&gt;
|7&lt;br /&gt;
|Ice Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|Ice Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|9&lt;br /&gt;
|Wave Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Wave Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|11&lt;br /&gt;
|Plasma Door Ceiling&lt;br /&gt;
|-&lt;br /&gt;
|12&lt;br /&gt;
|Plasma Door Floor&lt;br /&gt;
|-&lt;br /&gt;
|13&lt;br /&gt;
|Ice Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|14&lt;br /&gt;
|Wave Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|Plasma Door Floor 2&lt;br /&gt;
|-&lt;br /&gt;
|27&lt;br /&gt;
|Down Arrow Yellow (Maintenance Tunnel)&lt;br /&gt;
|-&lt;br /&gt;
|28&lt;br /&gt;
|Up Arrow Yellow (Phazon Processing Center)&lt;br /&gt;
|-&lt;br /&gt;
|29&lt;br /&gt;
|Down Arrow Green (Elevator A)&lt;br /&gt;
|-&lt;br /&gt;
|30&lt;br /&gt;
|Up Arrow Green (Elite Control Access)&lt;br /&gt;
|-&lt;br /&gt;
|31&lt;br /&gt;
|Down Arrow Red (Elevator B)&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|Up Arrow Red (Fungal Hall Access)&lt;br /&gt;
|-&lt;br /&gt;
|33&lt;br /&gt;
|Elevator&lt;br /&gt;
|-&lt;br /&gt;
|34&lt;br /&gt;
|Save Station&lt;br /&gt;
|-&lt;br /&gt;
|37&lt;br /&gt;
|Missile Station&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vertices ===&lt;br /&gt;
&lt;br /&gt;
Vertices are a simple array of CVector3f. Geometry in MAPAs is, almost always, centered around the origin (0, 0, 0) and are simplified, full sized, versions of the map they replicate. Each vertex is referenced at least twice: once for the primitive, once for the line border.&lt;br /&gt;
&lt;br /&gt;
=== Primitive Headers ===&lt;br /&gt;
&lt;br /&gt;
The Primitive headers are extremely simple, they merely have a bounding box followed by the primitive table start and end point, relative to the end of the current primitive header. In other words: read in the header, seek to the start of the table from the '''current''' position, then read the primitives tables.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Normal'''&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Center of Mass'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table Start'''; relative to the end of the header&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Table Start'''; relative to the end of the header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive Table ===&lt;br /&gt;
&lt;br /&gt;
The Primitive is also fairly simple, each one consists of two parts: The GX Primitive list, and the Border list. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count (PC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Primitive * PC&lt;br /&gt;
|'''Primitives'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Count (BC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Border * (BC)&lt;br /&gt;
|'''Borders'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive ===&lt;br /&gt;
&lt;br /&gt;
A primitive in a MAPA is a simple 4 byte aligned list of indices into the vertex list, starting with the GX Primitive type, a count, then an array of indices, each index taking up one byte.&lt;br /&gt;
&lt;br /&gt;
=== Border ===&lt;br /&gt;
&lt;br /&gt;
A border in a MAPA is a simple count followed by a 4 byte aligned list indices into the vertex list, each index taking up one byte. A border is simply drawn using GX_LINESTRIP.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1867</id>
		<title>MAPA (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1867"/>
				<updated>2017-04-20T19:00:42Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Primitive Headers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''.MAPA file format''' defines the minimap models used in the Metroid Prime series. MAPA or '''MAP A'''rea consists of several sections: The header, Point Of Interest entries, Vertices, Primitive Headers, and the primitives.&lt;br /&gt;
&lt;br /&gt;
{{research|2|A few things are unknown in the header and POI Entries}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Format ==&lt;br /&gt;
=== Header ===&lt;br /&gt;
The header is very straight forward, and has some minor differences depending on version, the unknown values don't seem to do anything, however not much research has been put into them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Magic'''; Always 0xDEADD00D&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Version'''; See below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; unknown function in MP1/3, specifies whether the area appears on the Light (0) or Dark (1) map in MP2&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit or Map Station (most MP1 areas)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit only (latter areas of Ruins and Phendrana)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CAABox&lt;br /&gt;
|'''Bounding Box'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''POI Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Vertex Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Version ====&lt;br /&gt;
The version value listed above can have the following values:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Game&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 1&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 2: Echoes&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 3: Corruption&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Point of Interest ===&lt;br /&gt;
A Point of Interest in the Metroid Prime series can include: Mission Objectives, Elevators, Doors, Map Stations, and Missile Stations. Each Point of Interest entry consists of the following struct:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1 &amp;amp; MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; All valid values are not currently known&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u16&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u16&lt;br /&gt;
|'''ID'''; Which door, elevator etc.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|CVector4f&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Padding'''; always -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CTransform4f&lt;br /&gt;
|'''Tranform Matrix''' The Point of Interest's position in '''world''' space.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32 * 4&lt;br /&gt;
|'''Padding'''; four values of -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vertices ===&lt;br /&gt;
&lt;br /&gt;
Vertices are a simple array of CVector3f. Geometry in MAPAs is, almost always, centered around the origin (0, 0, 0) and are simplified, full sized, versions of the map they replicate. Each vertex is referenced at least twice: once for the primitive, once for the line border.&lt;br /&gt;
&lt;br /&gt;
=== Primitive Headers ===&lt;br /&gt;
&lt;br /&gt;
The Primitive headers are extremely simple, they merely have a bounding box followed by the primitive table start and end point, relative to the end of the current primitive header. In other words: read in the header, seek to the start of the table from the '''current''' position, then read the primitives tables.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Normal'''&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Center of Mass'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table Start'''; relative to the end of the header&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Table Start'''; relative to the end of the header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive Table ===&lt;br /&gt;
&lt;br /&gt;
The Primitive is also fairly simple, each one consists of two parts: The GX Primitive list, and the Border list. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count (PC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Primitive * PC&lt;br /&gt;
|'''Primitives'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Count (BC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Border * (BC)&lt;br /&gt;
|'''Borders'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive ===&lt;br /&gt;
&lt;br /&gt;
A primitive in a MAPA is a simple 4 byte aligned list of indices into the vertex list, starting with the GX Primitive type, a count, then an array of indices, each index taking up one byte.&lt;br /&gt;
&lt;br /&gt;
=== Border ===&lt;br /&gt;
&lt;br /&gt;
A border in a MAPA is a simple count followed by a 4 byte aligned list indices into the vertex list, each index taking up one byte. A border is simply drawn using GX_LINESTRIP.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1866</id>
		<title>MAPA (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MAPA_(File_Format)&amp;diff=1866"/>
				<updated>2017-04-20T02:56:43Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Header */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''.MAPA file format''' defines the minimap models used in the Metroid Prime series. MAPA or '''MAP A'''rea consists of several sections: The header, Point Of Interest entries, Vertices, Primitive Headers, and the primitives.&lt;br /&gt;
&lt;br /&gt;
{{research|2|A few things are unknown in the header and POI Entries}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
== Format ==&lt;br /&gt;
=== Header ===&lt;br /&gt;
The header is very straight forward, and has some minor differences depending on version, the unknown values don't seem to do anything, however not much research has been put into them.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Magic'''; Always 0xDEADD00D&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Version'''; See below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; unknown function in MP1/3, specifies whether the area appears on the Light (0) or Dark (1) map in MP2&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Visibility Mode'''; &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;Always Visible&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit or Map Station (most MP1 areas)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Visible on Visit only (latter areas of Ruins and Phendrana)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Never Visible&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CAABox&lt;br /&gt;
|'''Bounding Box'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''POI Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Vertex Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Version ====&lt;br /&gt;
The version value listed above can have the following values:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Game&lt;br /&gt;
!Value&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 1&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 2: Echoes&lt;br /&gt;
|3&lt;br /&gt;
|-&lt;br /&gt;
|Metroid Prime 3: Corruption&lt;br /&gt;
|5&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Point of Interest ===&lt;br /&gt;
A Point of Interest in the Metroid Prime series can include: Mission Objectives, Elevators, Doors, Map Stations, and Missile Stations. Each Point of Interest entry consists of the following struct:&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
!MP1 &amp;amp; MP2&lt;br /&gt;
!MP3&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Type'''; All valid values are not currently known&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u16&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u16&lt;br /&gt;
|'''ID'''; Which door, elevator etc.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|CVector4f&lt;br /&gt;
|{{unknown|Unknown}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Padding'''; always -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|CTransform4f&lt;br /&gt;
|'''Tranform Matrix''' The Point of Interest's position in '''world''' space.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32 * 4&lt;br /&gt;
|'''Padding'''; four values of -1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Vertices ===&lt;br /&gt;
&lt;br /&gt;
Vertices are a simple array of CVector3f. Geometry in MAPAs is, almost always, centered around the origin (0, 0, 0) and are simplified, full sized, versions of the map they replicate. Each vertex is referenced at least twice: once for the primitive, once for the line border.&lt;br /&gt;
&lt;br /&gt;
=== Primitive Headers ===&lt;br /&gt;
&lt;br /&gt;
The Primitive headers are extremely simple, they merely have a bounding box followed by the primitive table start and end point, relative to the end of the current primitive header. In other words: read in the header, seek to the start of the table from the '''current''' position, then read the primitives tables.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Normal'''&lt;br /&gt;
|-&lt;br /&gt;
|CVector3f&lt;br /&gt;
|'''Center of Mass'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table Start'''; relative to the end of the header&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Table End'''; relative to the end of the header&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive Table ===&lt;br /&gt;
&lt;br /&gt;
The Primitive is also fairly simple, each one consists of two parts: The GX Primitive list, and the Border list. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Primitive Count (PC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Primitive * PC&lt;br /&gt;
|'''Primitives'''&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|'''Border Count (BC)'''&lt;br /&gt;
|-&lt;br /&gt;
|Border * (BC)&lt;br /&gt;
|'''Borders'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Primitive ===&lt;br /&gt;
&lt;br /&gt;
A primitive in a MAPA is a simple 4 byte aligned list of indices into the vertex list, starting with the GX Primitive type, a count, then an array of indices, each index taking up one byte.&lt;br /&gt;
&lt;br /&gt;
=== Border ===&lt;br /&gt;
&lt;br /&gt;
A border in a MAPA is a simple count followed by a 4 byte aligned list indices into the vertex list, each index taking up one byte. A border is simply drawn using GX_LINESTRIP.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1865</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1865"/>
				<updated>2017-04-09T19:24:27Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Total number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| 2nd Layer Light Count&lt;br /&gt;
| Lights within total that are in the 2nd BABEDEAD layer.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective. 2nd layer lights are listed first.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree. '''Note:''' the coordinates of the AABB are in local area space (i.e. inverse-transformed with the matrix in the MREA header).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility object count&lt;br /&gt;
| Number of objects per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light object count&lt;br /&gt;
| Number of objects within total that are lights.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA sections. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. The 2nd layer lights are related first. Each light encodes 2-bits apiece,&lt;br /&gt;
with the following enum represented:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Not Visible&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Visible&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Outside Octree Bounds&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1813</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1813"/>
				<updated>2017-02-26T18:11:49Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Unknown 3&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree. '''Note:''' the coordinates of the AABB are in local area space (i.e. inverse-transformed with the matrix in the MREA header).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility object count&lt;br /&gt;
| Number of objects per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light object count&lt;br /&gt;
| Number of objects within total that are lights.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA sections. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. Each light encodes 2-bits apiece,&lt;br /&gt;
with the following enum represented:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Not Visible&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Visible&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Outside Octree Bounds&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1812</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1812"/>
				<updated>2017-02-26T18:11:02Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Unknown 3&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree. '''Note:''' the coordinates of the AABB are in local area space (I.e. inverse-transformed with the matrix in the MREA header).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility object count&lt;br /&gt;
| Number of objects per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light object count&lt;br /&gt;
| Number of objects within total that are lights.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA sections. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. Each light encodes 2-bits apiece,&lt;br /&gt;
with the following enum represented:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Not Visible&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Visible&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Outside Octree Bounds&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1811</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1811"/>
				<updated>2017-02-26T18:02:10Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Unknown 3&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility object count&lt;br /&gt;
| Number of objects per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light object count&lt;br /&gt;
| Number of objects within total that are lights.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA sections. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. Each light encodes 2-bits apiece,&lt;br /&gt;
with the following enum represented:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Not Visible&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Visible&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Outside Octree Bounds&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1810</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1810"/>
				<updated>2017-02-26T06:27:44Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Leaf Nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Unknown 3&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility bit count&lt;br /&gt;
| Number of bits per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light bit count&lt;br /&gt;
| Number of bits after visibility bits that indicate in-bounds/out-of-bounds state of each light.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA sections. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. Each light encodes 2-bits apiece,&lt;br /&gt;
with the following enum represented:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Value&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Not Visible&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Visible&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Outside Octree Bounds&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1809</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1809"/>
				<updated>2017-02-26T06:00:29Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Leaf Nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Unknown 3&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility bit count&lt;br /&gt;
| Number of bits per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light bit count&lt;br /&gt;
| Number of bits after visibility bits that indicate in-bounds/out-of-bounds state of each light.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA sections. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. Following these is another&lt;br /&gt;
set of bits for each light indicating if it's in-bounds of the octree or not.&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1808</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1808"/>
				<updated>2017-02-26T05:59:52Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Octree Nodes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Unknown 3&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility bit count&lt;br /&gt;
| Number of bits per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light bit count&lt;br /&gt;
| Number of bits after visibility bits that indicate in-bounds/out-of-bounds state of each light.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major, depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA section. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. Following these is another&lt;br /&gt;
set of bits for each light indicating if it's in-bounds of the octree or not.&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=MREA_(Metroid_Prime)&amp;diff=1807</id>
		<title>MREA (Metroid Prime)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=MREA_(Metroid_Prime)&amp;diff=1807"/>
				<updated>2017-02-26T05:57:33Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''See [[MREA (File Format)]] for the other revisions of this format.''&lt;br /&gt;
&lt;br /&gt;
The '''MREA format''' defines areas (rooms) in Metroid Prime. It's a massive format that contains tons of different data, including terrain geometry, collision, objects, lights, and more.&lt;br /&gt;
&lt;br /&gt;
{{todo|There's a LOT of sections that are mostly known, but need some documentation written up. SCLY and collision need separate articles (although the unique parts of the collision format, like the octree, could maybe be documented here). The rest should probably stay on this page.}}&lt;br /&gt;
{{research|minor|Discounting unknowns within the actual data sections, the main thing that still isn't known is what the unknown data section is for.}}&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
Like [[CMDL (Metroid Prime)|CMDL]], MREA files are split up into a number of 32-byte aligned sections. Every section both starts and ends on a 32-byte boundary. These are used to separate different parts of the file; different types of sections typically indicate different sets of data. The header declares the section count and the size of each one; using these is the only way to navigate the file.&lt;br /&gt;
&lt;br /&gt;
These are the sections that appear in each MREA file, in the order they appear in the file:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Identifier&lt;br /&gt;
! Name&lt;br /&gt;
|-&lt;br /&gt;
| {{none}}&lt;br /&gt;
| [[#World Geometry|World Geometry]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;AROT&amp;lt;/code&amp;gt;&lt;br /&gt;
| [[#Area Octree|Area Octree]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;SCLY&amp;lt;/code&amp;gt;&lt;br /&gt;
| [[#Script Layers|Script Layers]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;0xDEAFBABE&amp;lt;/code&amp;gt;&lt;br /&gt;
| [[#Collision|Collision]]&lt;br /&gt;
|-&lt;br /&gt;
| {{none}}&lt;br /&gt;
| {{unknown|[[#Unknown Section|Unknown]]}}&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;0xBABEDEAD&amp;lt;/code&amp;gt;&lt;br /&gt;
| [[#Lights|Lights]]&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt;&lt;br /&gt;
| [[#Visibility Tree|Visibility Tree]]&lt;br /&gt;
|-&lt;br /&gt;
| {{none}}&lt;br /&gt;
| [[#Path|Path]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Type&lt;br /&gt;
! Count&lt;br /&gt;
! Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Magic'''&lt;br /&gt;
| Always &amp;lt;code&amp;gt;0xDEADBEEF&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Version'''&lt;br /&gt;
| See [[MREA (File Format)|hub article]] for a list of possible version numbers.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| float&lt;br /&gt;
| 12&lt;br /&gt;
| '''Area Transform'''&lt;br /&gt;
| Matrix that represents the area's transform from the origin. Most area data is pre-transformed, so this matrix is only used occasionally.&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''World Model Count'''&lt;br /&gt;
| Number of world models in this area.&lt;br /&gt;
|-&lt;br /&gt;
| 0x3C&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Data Section Count'''&lt;br /&gt;
| Number of data sections in the file.&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''World Geometry Section'''&lt;br /&gt;
| Section index for [[#World Geometry|world geometry data]]. Always 0; starts on materials.&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Script Layers Section'''&lt;br /&gt;
| Section index for [[#Script Layers|script layer data]].&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Collision Section'''&lt;br /&gt;
| Section index for [[#Collision|collision data]].&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Unknown Section'''&lt;br /&gt;
| Section index for [[#Unknown Section|unknown data]].&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Lights Section'''&lt;br /&gt;
| Section index for [[#Lights|light data]].&lt;br /&gt;
|-&lt;br /&gt;
| 0x54&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Visibility Tree Section'''&lt;br /&gt;
| Section index for [[#Visibility Tree|visibility tree data]].&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Path Section'''&lt;br /&gt;
| Section index for [[#Path|path data]].&lt;br /&gt;
|-&lt;br /&gt;
| 0x5C&lt;br /&gt;
| u32&lt;br /&gt;
| 1&lt;br /&gt;
| '''Area Octree Section'''&lt;br /&gt;
| Section index for [[#Area Octree|area octree data]].&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| u32&lt;br /&gt;
| ''Data Section Count''&lt;br /&gt;
| '''Data Section Sizes'''&lt;br /&gt;
| Array containing the size of each data section in the file. Every size is always a multiple of 32.&lt;br /&gt;
|-&lt;br /&gt;
| colspan=5 {{unknown|End of header; pad to 32 bytes before first data section begins}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== World Geometry ===&lt;br /&gt;
&lt;br /&gt;
''See [[Materials (Metroid Prime)]] and [[Geometry (Metroid Prime)]]''&lt;br /&gt;
&lt;br /&gt;
MREA files have one material section, followed by a number of world models, each of which has its own set of geometry sections. There's couple small differences you'll usually see on world models compared to regular CMDL ones:&lt;br /&gt;
&lt;br /&gt;
* Normals are ''always'' shorts, so vertex format 0 is never used.&lt;br /&gt;
* Most world models use lightmaps, so normally the first UV coordinate on each vertex will read from the short UV array. This isn't always the case, though; you need to make sure you check the material so you know where to read from.&lt;br /&gt;
* Surfaces will usually have a bounding box in the extra data in the surface header. This bounding box is used for depth sorting.&lt;br /&gt;
* Each world model starts with an extra header section which is formatted like this:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Type&lt;br /&gt;
! Count&lt;br /&gt;
! Name&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| [[#Visor Flags|Visor Flags]]&lt;br /&gt;
| 1&lt;br /&gt;
| '''Visor Flags'''&lt;br /&gt;
| 32-bit bitfield that sets parameters controlling how the mesh renders in different visors.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| float&lt;br /&gt;
| 12&lt;br /&gt;
| '''World Model Transform'''&lt;br /&gt;
| World model's transform from the area's local origin. The geometry data is pre-transformed, so this matrix can largely be ignored.&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| float&lt;br /&gt;
| 6&lt;br /&gt;
| '''World Model Bounding Box'''&lt;br /&gt;
| Pre-transformed axis-aligned bounding box for this model.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| colspan=4 {{unknown|End of mesh header section}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Visor Flags ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit&lt;br /&gt;
! Hex&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 0x1&lt;br /&gt;
| {{unknown|Unknown}}&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| 0x2&lt;br /&gt;
| Disable rendering in Combat/Scan Visor&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 0x4&lt;br /&gt;
| Disable rendering in Thermal Visor&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| 0x8&lt;br /&gt;
| Disable rendering in X-Ray Visor&lt;br /&gt;
|-&lt;br /&gt;
| 4-5&lt;br /&gt;
| 0x30&lt;br /&gt;
| Thermal heat level.&lt;br /&gt;
* 0 - Cool&lt;br /&gt;
* 1 - Hot&lt;br /&gt;
* 2 - Warm&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Area Octree ===&lt;br /&gt;
&lt;br /&gt;
{{main|AROT (MREA Section)}}&lt;br /&gt;
&lt;br /&gt;
The AROT section stores the area's octree, accelerating back-to-front rendering of contained meshes. It is also used for spacial queries such as collision.&lt;br /&gt;
&lt;br /&gt;
=== Script Layers ===&lt;br /&gt;
&lt;br /&gt;
{{todo|Format known, needs documentation written up.}}&lt;br /&gt;
&lt;br /&gt;
The SCLY section contains data for objects.&lt;br /&gt;
&lt;br /&gt;
=== Collision ===&lt;br /&gt;
&lt;br /&gt;
''Main article: [[Area Collision (File Format)]]''&lt;br /&gt;
&lt;br /&gt;
=== Unknown Section ===&lt;br /&gt;
&lt;br /&gt;
This one is sandwiched between collision and lights, and usually just contains a single 32-bit &amp;quot;1&amp;quot;. Purpose is unknown. In the Prime 3/DKCR MREA format, this section is labelled &amp;lt;code&amp;gt;LLTE&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Lights ===&lt;br /&gt;
&lt;br /&gt;
This section is for dynamic lights. See the [[Lights_(Metroid_Prime)|Light]] article for details.&lt;br /&gt;
&lt;br /&gt;
=== Visibility Tree ===&lt;br /&gt;
&lt;br /&gt;
{{main|VISI (MREA Section)}}&lt;br /&gt;
&lt;br /&gt;
This section is a PVS octree labeled &amp;quot;VISI&amp;quot;. Some areas don't have visibility octrees; in that case this section will be completely empty and listed with a size of 0.&lt;br /&gt;
&lt;br /&gt;
=== Path ===&lt;br /&gt;
&lt;br /&gt;
This is the final section in the file; its only value is a single [[PATH (File Format)|PATH]] file ID.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Type&lt;br /&gt;
! Name&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| Asset ID&lt;br /&gt;
| '''Area PATH Resource'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of section}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1806</id>
		<title>VISI (MREA Section)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=VISI_(MREA_Section)&amp;diff=1806"/>
				<updated>2017-02-26T05:56:19Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: Created page with &amp;quot;Within MREA resources, the '''VISI section''' stores a PVS  indexed into an octree. This PVS...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Within [[MREA (File Format)|MREA]] resources, the '''VISI section''' stores a [[wikipedia:Potentially_visible_set|PVS]] &lt;br /&gt;
indexed into an [[wikipedia:Octree|octree]]. This PVS is used to determine visibility/occlusion between cubic sections of&lt;br /&gt;
the area and models, scripting entities, and lights in the scene.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Data Type&lt;br /&gt;
! Description&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| FourCC&lt;br /&gt;
| &amp;lt;code&amp;gt;VISI&amp;lt;/code&amp;gt; magic&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| VISI Version&lt;br /&gt;
| 0x2 in ''Metroid Prime''.&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| bool&lt;br /&gt;
| Unknown 2&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Feature count&lt;br /&gt;
| Number of static MREA meshes + script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light count&lt;br /&gt;
| Number of area lights encoded in octree leaves.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Unknown 3&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Entity count&lt;br /&gt;
| Number of script entities encoded in octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Leaf size&lt;br /&gt;
| Size of octree leaf node in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Light visibility node count&lt;br /&gt;
| Count of leaf nodes from light perspectives (matches light count).&lt;br /&gt;
|-&lt;br /&gt;
| u32[entityCount]&lt;br /&gt;
| Entity array&lt;br /&gt;
| Array of entity IDs mapping the octree bits to the lower 16-bits of the SCLY editor IDs.&lt;br /&gt;
|-&lt;br /&gt;
| u8[lightVisibilityNodeCount][leafSize]&lt;br /&gt;
| Light visibility node array&lt;br /&gt;
| Array of [[#Leaf Nodes|leaf node data]] indicating visibility of other objects from light's perspective.&lt;br /&gt;
|-&lt;br /&gt;
| float[2][3]&lt;br /&gt;
| Octree AABB&lt;br /&gt;
| Total bounds subdivided by octree.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total visibility bit count&lt;br /&gt;
| Number of bits per-leaf that indicate visibility from the selected octree region (static + entities + lights).&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Total light bit count&lt;br /&gt;
| Number of bits after visibility bits that indicate in-bounds/out-of-bounds state of each light.&lt;br /&gt;
|-&lt;br /&gt;
| u32&lt;br /&gt;
| Octree length&lt;br /&gt;
| Size of octree in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| u8[octreeLength]&lt;br /&gt;
| Octree data&lt;br /&gt;
| Byte-packed PVS octree data described below.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Octree Nodes ===&lt;br /&gt;
&lt;br /&gt;
The octree data is arranged in a Z-major depth-first hierarchy embedded with variable-length pointers to skip over&lt;br /&gt;
children, permitting rapid child selection. Each node of the octree starts with a 1-byte header&lt;br /&gt;
of classification bits. If at least one subdivide bit is set, the node is a branch and contains 1-7 pointers, addressed&lt;br /&gt;
relative to the position after the pointers. One subdivision will have 1 pointer, two subdivisions will have 3 pointers,&lt;br /&gt;
and three subdivisions will have 7 pointers. The first child pointer is implied to be 0x0. Pointer data type is specified&lt;br /&gt;
in the header (8, 16, or 24 bits).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Bit (from LSB)&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| Branch Subdivide X&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| Branch Subdivide Y&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| Branch Subdivide Z&lt;br /&gt;
|-&lt;br /&gt;
| 3-4&lt;br /&gt;
| Node type &amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Out of bounds (not used)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;End of hierarchy (indicates nothing is visible)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Regular node (followed by branch pointers or leaf bits)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 5-6&lt;br /&gt;
| Branch pointer type &amp;lt;ol start=0&amp;gt;&amp;lt;li&amp;gt;16-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;8-bit pointers&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;24-bit pointers&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Leaf Nodes ===&lt;br /&gt;
&lt;br /&gt;
Instead of child pointers, leaf nodes contain byte-packed bits indicating visibility. &lt;br /&gt;
The bits are arranged from LSB to MSB per-byte. First are the bits relating static MREA geometry &lt;br /&gt;
in-order of the first MREA section. Next are bits relating the scripted entities in the VISI entities table.&lt;br /&gt;
Finally are the bits relating lights in order of the BABEDEAD section of the MREA. Following these is another&lt;br /&gt;
set of bits for each light indicating if it's in-bounds of the octree or not.&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=Metroid_Prime_3:_Corruption&amp;diff=1775</id>
		<title>Metroid Prime 3: Corruption</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=Metroid_Prime_3:_Corruption&amp;diff=1775"/>
				<updated>2016-12-13T18:52:29Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Builds */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Metroid Prime 3: Corruption''' is the third and final game in the Metroid Prime trilogy.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Builds ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Build&lt;br /&gt;
! Date/Time&lt;br /&gt;
! Version&lt;br /&gt;
|-&lt;br /&gt;
| v3.068&lt;br /&gt;
| 3/2/2006 14:55:13&lt;br /&gt;
| E3 2006 Prototype&lt;br /&gt;
|-&lt;br /&gt;
| v3.436&lt;br /&gt;
| 2007/07/27 13:13&lt;br /&gt;
| Wii NTSC (Original Release)&lt;br /&gt;
|-&lt;br /&gt;
| v3.453&lt;br /&gt;
| 2007/08/24 16:52&lt;br /&gt;
| Wii PAL&lt;br /&gt;
|-&lt;br /&gt;
| v3.495&lt;br /&gt;
| 2007/11/12 14:15&lt;br /&gt;
| Wii NTSC-J&lt;br /&gt;
|-&lt;br /&gt;
| v3.593&lt;br /&gt;
| 2008/08/21 17:09&lt;br /&gt;
| Metroid Prime: Trilogy NTSC&lt;br /&gt;
|-&lt;br /&gt;
| v3.629&lt;br /&gt;
| 2009/01/15 14:08&lt;br /&gt;
| Metroid Prime: Trilogy PAL&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Formats ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Format&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| [[ANIM (File Format)|ANIM]]&lt;br /&gt;
| Animation&lt;br /&gt;
|-&lt;br /&gt;
| [[ATBL (File Format)|ATBL]]&lt;br /&gt;
| Audio Lookup Table&lt;br /&gt;
|-&lt;br /&gt;
| [[BFRC (File Format)|BFRC]]&lt;br /&gt;
| Burst Fire Data&lt;br /&gt;
|-&lt;br /&gt;
| [[CAAD (File Format)|CAAD]]&lt;br /&gt;
| {{unknown|Unknown}}&lt;br /&gt;
|-&lt;br /&gt;
| [[CAUD (File Format)|CAUD]]&lt;br /&gt;
| Audio Manager Macro&lt;br /&gt;
|-&lt;br /&gt;
| [[CHAR (File Format)|CHAR]]&lt;br /&gt;
| Character&lt;br /&gt;
|-&lt;br /&gt;
| [[CINF (File Format)|CINF]]&lt;br /&gt;
| Skeleton&lt;br /&gt;
|-&lt;br /&gt;
| [[CMDL (Metroid Prime)|CMDL]]&lt;br /&gt;
| Model&lt;br /&gt;
|-&lt;br /&gt;
| [[CRSC (File Format)|CRSC]]&lt;br /&gt;
| Collision Response Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[CSKR (File Format)|CSKR]]&lt;br /&gt;
| Skin Rules&lt;br /&gt;
|-&lt;br /&gt;
| [[CSMP (File Format)|CSMP]]&lt;br /&gt;
| Audio Sample&lt;br /&gt;
|-&lt;br /&gt;
| [[DCLN (File Format)|DCLN]]&lt;br /&gt;
| Dynamic Collision&lt;br /&gt;
|-&lt;br /&gt;
| [[DGRP (File Format)|DGRP]]&lt;br /&gt;
| Dependency Group&lt;br /&gt;
|-&lt;br /&gt;
| [[DPSC (File Format)|DPSC]]&lt;br /&gt;
| Decal Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[DUMB (File Format)|DUMB]]&lt;br /&gt;
| Binary Data&lt;br /&gt;
|-&lt;br /&gt;
| [[EGMC (File Format)|EGMC]]&lt;br /&gt;
| Editor Object to Static Geometry Map&lt;br /&gt;
|-&lt;br /&gt;
| [[ELSC (File Format)|ELSC]]&lt;br /&gt;
| Electric Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[FONT (File Format)|FONT]]&lt;br /&gt;
| Font&lt;br /&gt;
|-&lt;br /&gt;
| [[FRME (File Format)|FRME]]&lt;br /&gt;
| GUI Frame&lt;br /&gt;
|-&lt;br /&gt;
| [[FSM2 (File Format)|FSM2]]&lt;br /&gt;
| Finite State Machine 2&lt;br /&gt;
|-&lt;br /&gt;
| [[HINT (File Format)|HINT]]&lt;br /&gt;
| Hint System&lt;br /&gt;
|-&lt;br /&gt;
| [[MAPA (File Format)|MAPA]]&lt;br /&gt;
| Area Map&lt;br /&gt;
|-&lt;br /&gt;
| [[MAPW (File Format)|MAPW]]&lt;br /&gt;
| World Map&lt;br /&gt;
|-&lt;br /&gt;
| [[MLVL (File Format)|MLVL]]&lt;br /&gt;
| World&lt;br /&gt;
|-&lt;br /&gt;
| [[MREA (File Format)|MREA]]&lt;br /&gt;
| Area&lt;br /&gt;
|-&lt;br /&gt;
| [[NTWK (File Format)|NTWK]]&lt;br /&gt;
| Tweaks&lt;br /&gt;
|-&lt;br /&gt;
| [[PAK (Metroid Prime)|PAK]]&lt;br /&gt;
| Package&lt;br /&gt;
|-&lt;br /&gt;
| [[PART (File Format)|PART]]&lt;br /&gt;
| Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[PATH (File Format)|PATH]]&lt;br /&gt;
| Pathfinding&lt;br /&gt;
|-&lt;br /&gt;
| [[RSO (File Format)|RSO]]&lt;br /&gt;
| Shared Object&lt;br /&gt;
|-&lt;br /&gt;
| [[RULE (File Format)|RULE]]&lt;br /&gt;
| Rule Set&lt;br /&gt;
|-&lt;br /&gt;
| [[SAND (File Format)|SAND]]&lt;br /&gt;
| Source Animation Data&lt;br /&gt;
|-&lt;br /&gt;
| [[SAVA (File Format)|SAVA]]&lt;br /&gt;
| Area Save Info&lt;br /&gt;
|-&lt;br /&gt;
| [[SAVW (File Format)|SAVW]]&lt;br /&gt;
| World Save Info&lt;br /&gt;
|-&lt;br /&gt;
| [[SCAN (Metroid Prime 2)|SCAN]]&lt;br /&gt;
| Scannable Object Info&lt;br /&gt;
|-&lt;br /&gt;
| [[SPSC (File Format)|SPSC]]&lt;br /&gt;
| Spawn Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[STRG (File Format)|STRG]]&lt;br /&gt;
| String Table&lt;br /&gt;
|-&lt;br /&gt;
| [[STRM (File Format)|STRM]]&lt;br /&gt;
| Streamed Audio&lt;br /&gt;
|-&lt;br /&gt;
| [[SWHC (File Format)|SWHC]]&lt;br /&gt;
| Swoosh Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[THP (File Format)|THP]]&lt;br /&gt;
| Video&lt;br /&gt;
|-&lt;br /&gt;
| [[TXTR (Metroid Prime)|TXTR]]&lt;br /&gt;
| Texture&lt;br /&gt;
|-&lt;br /&gt;
| [[USRC (File Format)|USRC]]&lt;br /&gt;
| User Evaluator Data&lt;br /&gt;
|-&lt;br /&gt;
| [[WPSC (File Format)|WPSC]]&lt;br /&gt;
| Weapon Particle System&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Games]]&lt;br /&gt;
[[Category:Metroid Prime 3: Corruption]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=Metroid_Prime&amp;diff=1774</id>
		<title>Metroid Prime</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=Metroid_Prime&amp;diff=1774"/>
				<updated>2016-12-13T18:45:56Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Builds */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Metroid Prime''' is the first game developed by Retro Studios.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Builds ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Build&lt;br /&gt;
! Date/Time&lt;br /&gt;
! Version&lt;br /&gt;
|-&lt;br /&gt;
| {{none}}&lt;br /&gt;
| Jul 24 2002 14:11:18&lt;br /&gt;
| Multi-Game Demo Disc v7-9&lt;br /&gt;
|-&lt;br /&gt;
| v1.028&lt;br /&gt;
| 10/29/2002 2:21:25&lt;br /&gt;
| GameCube 0-00 NTSC (Original Release)&lt;br /&gt;
|-&lt;br /&gt;
| v1.101&lt;br /&gt;
| 1/14/2003 17:57:24&lt;br /&gt;
| EUR Interactive Multi-Game Demo Disc: February 2003&lt;br /&gt;
|-&lt;br /&gt;
| v1.110&lt;br /&gt;
| 2/4/2003 22:16:07&lt;br /&gt;
| GameCube PAL&lt;br /&gt;
|-&lt;br /&gt;
| v1.111&lt;br /&gt;
| 2/11/2003 10:03:22&lt;br /&gt;
| GameCube 0-00 NTSC-J (Original JP Release)&lt;br /&gt;
|-&lt;br /&gt;
| v1.111&lt;br /&gt;
| 3/10/2003 17:56:21&lt;br /&gt;
| GameCube 0-02 NTSC (Player's Choice)&lt;br /&gt;
|-&lt;br /&gt;
| v3.570&lt;br /&gt;
| 2008/07/22 12:23&lt;br /&gt;
| Wii de Asobu&lt;br /&gt;
|-&lt;br /&gt;
| v3.593&lt;br /&gt;
| 2008/08/21 17:09&lt;br /&gt;
| Metroid Prime: Trilogy NTSC&lt;br /&gt;
|-&lt;br /&gt;
| v3.629&lt;br /&gt;
| 2009/01/15 14:08&lt;br /&gt;
| Metroid Prime: Trilogy PAL&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Formats ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Format&lt;br /&gt;
! Contents&lt;br /&gt;
|-&lt;br /&gt;
| [[AFSM (File Format)|AFSM]]&lt;br /&gt;
| AI Finite State Machine&lt;br /&gt;
|-&lt;br /&gt;
| [[AGSC (File Format)|AGSC]]&lt;br /&gt;
| Audio Group Set&lt;br /&gt;
|-&lt;br /&gt;
| [[ANCS (File Format)|ANCS]]&lt;br /&gt;
| Animation/Character Set&lt;br /&gt;
|-&lt;br /&gt;
| [[ANIM (File Format)|ANIM]]&lt;br /&gt;
| Animation&lt;br /&gt;
|-&lt;br /&gt;
| [[ATBL (File Format)|ATBL]]&lt;br /&gt;
| Audio Lookup Table&lt;br /&gt;
|-&lt;br /&gt;
| [[CINF (File Format)|CINF]]&lt;br /&gt;
| Skeleton&lt;br /&gt;
|-&lt;br /&gt;
| [[CMDL (Metroid Prime)|CMDL]]&lt;br /&gt;
| Model&lt;br /&gt;
|-&lt;br /&gt;
| [[CRSC (File Format)|CRSC]]&lt;br /&gt;
| Collision Response Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[CSKR (File Format)|CSKR]]&lt;br /&gt;
| Skin Rules&lt;br /&gt;
|-&lt;br /&gt;
| [[CSNG (File Format)|CSNG]]&lt;br /&gt;
| MusyX MIDI File&lt;br /&gt;
|-&lt;br /&gt;
| [[CTWK (File Format)|CTWK]]&lt;br /&gt;
| Tweaks&lt;br /&gt;
|-&lt;br /&gt;
| [[DCLN (File Format)|DCLN]]&lt;br /&gt;
| Dynamic Collision&lt;br /&gt;
|-&lt;br /&gt;
| [[DGRP (File Format)|DGRP]]&lt;br /&gt;
| Dependency Group&lt;br /&gt;
|-&lt;br /&gt;
| [[DPSC (File Format)|DPSC]]&lt;br /&gt;
| Decal Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[DSP (File Format)|DSP]]&lt;br /&gt;
| Music&lt;br /&gt;
|-&lt;br /&gt;
| [[DUMB (File Format)|DUMB]]&lt;br /&gt;
| Binary Data&lt;br /&gt;
|-&lt;br /&gt;
| [[ELSC (File Format)|ELSC]]&lt;br /&gt;
| Electric Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[EVNT (File Format)|EVNT]]&lt;br /&gt;
| Animation Event Data&lt;br /&gt;
|-&lt;br /&gt;
| [[FONT (File Format)|FONT]]&lt;br /&gt;
| Font&lt;br /&gt;
|-&lt;br /&gt;
| [[FRME (File Format)|FRME]]&lt;br /&gt;
| GUI Frame&lt;br /&gt;
|-&lt;br /&gt;
| [[HINT (File Format)|HINT]]&lt;br /&gt;
| Hint System&lt;br /&gt;
|-&lt;br /&gt;
| [[MAPA (File Format)|MAPA]]&lt;br /&gt;
| Area Map&lt;br /&gt;
|-&lt;br /&gt;
| [[MAPU (File Format)|MAPU]]&lt;br /&gt;
| Universe Map&lt;br /&gt;
|-&lt;br /&gt;
| [[MAPW (File Format)|MAPW]]&lt;br /&gt;
| World Map&lt;br /&gt;
|-&lt;br /&gt;
| [[MLVL (File Format)|MLVL]]&lt;br /&gt;
| World&lt;br /&gt;
|-&lt;br /&gt;
| [[MREA (Metroid Prime)|MREA]]&lt;br /&gt;
| Area&lt;br /&gt;
|-&lt;br /&gt;
| [[PAK (Metroid Prime)|PAK]]&lt;br /&gt;
| Package&lt;br /&gt;
|-&lt;br /&gt;
| [[PART (File Format)|PART]]&lt;br /&gt;
| Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[PATH (File Format)|PATH]]&lt;br /&gt;
| Pathfinding&lt;br /&gt;
|-&lt;br /&gt;
| [[REL (File Format)|REL]]&lt;br /&gt;
| Relocatable Module&lt;br /&gt;
|-&lt;br /&gt;
| [[SAVW (File Format)|SAVW]]&lt;br /&gt;
| World Save Info&lt;br /&gt;
|-&lt;br /&gt;
| [[SCAN (Metroid Prime)|SCAN]]&lt;br /&gt;
| Scannable Object Info&lt;br /&gt;
|-&lt;br /&gt;
| [[STRG (File Format)|STRG]]&lt;br /&gt;
| String Table&lt;br /&gt;
|-&lt;br /&gt;
| [[SWHC (File Format)|SWHC]]&lt;br /&gt;
| Swoosh Particle System&lt;br /&gt;
|-&lt;br /&gt;
| [[THP (File Format)|THP]]&lt;br /&gt;
| Video&lt;br /&gt;
|-&lt;br /&gt;
| [[TXTR (Metroid Prime)|TXTR]]&lt;br /&gt;
| Texture&lt;br /&gt;
|-&lt;br /&gt;
| [[WPSC (File Format)|WPSC]]&lt;br /&gt;
| Weapon Particle System&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:Games]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1663</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1663"/>
				<updated>2016-08-31T05:52:22Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Curves */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/&amp;quot;. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID''':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Sound object type''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;SoundMacro&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Table&amp;lt;/li&amp;gt;&amp;lt;li value=4&amp;gt;Keymap&amp;lt;/li&amp;gt;&amp;lt;li value=8&amp;gt;Layer&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Unique ID''' (per type namespacing)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of ObjectID}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This is the ID structure produced by MusyX data export tool used for ''Metroid Prime'' &lt;br /&gt;
(which allocates all group ObjectIDs on export). The ObjectID structure is actually an arbitrary 16-bits in MusyX&lt;br /&gt;
(limited to 14-bit uniqueness). Based on findings from other games, this upper-byte type source is not 100% reliable,&lt;br /&gt;
since Factor5 updated the tool during the console's lifetime.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x35&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Attack time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Decay time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values (although typically in MIDI range [0,127])&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Definite Key'''; The default pitch (usually 0x3C00... the second byte may possibly be the MIDI channel)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Parax will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1662</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1662"/>
				<updated>2016-08-31T05:50:34Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* ADSR */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/&amp;quot;. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID''':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Sound object type''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;SoundMacro&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Table&amp;lt;/li&amp;gt;&amp;lt;li value=4&amp;gt;Keymap&amp;lt;/li&amp;gt;&amp;lt;li value=8&amp;gt;Layer&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Unique ID''' (per type namespacing)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of ObjectID}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This is the ID structure produced by MusyX data export tool used for ''Metroid Prime'' &lt;br /&gt;
(which allocates all group ObjectIDs on export). The ObjectID structure is actually an arbitrary 16-bits in MusyX&lt;br /&gt;
(limited to 14-bit uniqueness). Based on findings from other games, this upper-byte type source is not 100% reliable,&lt;br /&gt;
since Factor5 updated the tool during the console's lifetime.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x35&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Attack time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Decay time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release time'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Definite Key'''; The default pitch (usually 0x3C00... the second byte may possibly be the MIDI channel)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Parax will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ANIM_(Metroid_Prime)&amp;diff=1658</id>
		<title>ANIM (Metroid Prime)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ANIM_(Metroid_Prime)&amp;diff=1658"/>
				<updated>2016-08-27T21:16:00Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This article is for the ANIM format used in ''Metroid Prime'' and ''Metroid Prime 2: Echoes''. See [[ANIM (File Format)]] for the other revisions of this format.''&lt;br /&gt;
&lt;br /&gt;
The '''ANIM format''' is used in conjunction with [[CINF (File Format)|CINF]] + [[CSKR (File Format)|CSKR]] rigging to animate [[CMDL (Metroid Prime)|CMDL meshes]]. The format is largely the same between the two games, with the main difference being that starting in ''Metroid Prime 2'', support for animating scale was added.&lt;br /&gt;
&lt;br /&gt;
There are two versions of the ANIM format (indicated by the file's first u32 value), one with compressed animations and one with uncompressed ones:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Version&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0x0&lt;br /&gt;
|[[#Quaternion Array Format (Uncompressed)|Quaternion Array Format (Uncompressed)]]&lt;br /&gt;
|-&lt;br /&gt;
|0x2&lt;br /&gt;
|[[#Rotation Vector Bitstream Format (Compressed)|Rotation Vector Bitstream Format (Compressed)]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Quaternion Array Format (Uncompressed) ==&lt;br /&gt;
&lt;br /&gt;
The '''Quaternion Array Format''' (0x0) is a less common animation format. In ''Metroid Prime'', it only appears in a Ridley intro animation and the rotating pirate data artifact hologram above the Impact Crater, as well as some unused Samus animations, while in ''Metroid Prime 2'', it only seems to show up in some draft/test animations not used in the final game.&lt;br /&gt;
&lt;br /&gt;
This format stores uncompressed animations by mapping animation channels to bones, supplying rotations as an array of [[wikipedia:Quaternion|quaternion]] (WXYZ) keys and translations/scales as an array of XYZ keys. Translations may be specified for a subset of bones as an array of XYZ keys. In ''Metroid Prime'', rotation keys are required on every channel, while translations may be specified for a subset of bones. In ''Metroid Prime 2'', all three transform components are opt-in. &lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!style=&amp;quot;width: 215px;&amp;quot;|Element Count&lt;br /&gt;
!style=&amp;quot;width: 240px;&amp;quot;|Name&lt;br /&gt;
!Notes&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
|-&lt;br /&gt;
|0x4&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Duration'''&lt;br /&gt;
|'''[1/2 in CCharAnimTime]''' Time in seconds that the animation plays for&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x8&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Differential State Enum'''&lt;br /&gt;
|'''[2/2 in CCharAnimTime]''' State of ''Duration'' time point for proper integration control &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Non Zero&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Zero Increasing&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Zero Steady&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Zero Decreasing&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Infinity&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xC&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Key Interval'''&lt;br /&gt;
|'''[1/2 in CCharAnimTime]''' Time in seconds between keys of each bone channel (reciprocal of frame-rate)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x10&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Differential State Enum'''&lt;br /&gt;
|'''[2/2 in CCharAnimTime]''' State of ''Key Interval'' time point for proper integration control&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x14&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Key Count'''&lt;br /&gt;
|Count of keys for each bone channel (keys are set for every frame of the animation)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x18&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Root Bone ID'''&lt;br /&gt;
|ID of the root bone in this ANIM&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1C&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Count'''&lt;br /&gt;
|Count of bone channel indices in the next array. Always 100.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x20&lt;br /&gt;
|u8&lt;br /&gt;
|''Bone Channel Count''&lt;br /&gt;
|'''Bone Channel Index Array'''&lt;br /&gt;
|This table maps each bone to a bone channel, with the index-position corresponding to a ''Bone ID'' in the associated [[CINF (File Format)|CINF]], while the value corresponds to a bone channel index. The value is 0xFF if the bone is not animated by this ANIM.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Rotation Channel Index Count'''&lt;br /&gt;
|Count of rotation channel indices in the next array. Matches the number of valid bone channels.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u8&lt;br /&gt;
|''Rotation Channel Index Count''&lt;br /&gt;
|'''Rotation Channel Index Array'''&lt;br /&gt;
|This table maps each bone channel to a rotation channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a rotation channel. The value is 0xFF if the bone is not rotated by this ANIM. '''Note:''' In ''Metroid Prime'', every bone channel always has rotations, so this array is omitted.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Translation Channel Index Count'''&lt;br /&gt;
|Count of translation channel indices in the next array. Matches the number of valid bone channels.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u8&lt;br /&gt;
|''Translation Channel Index Count''&lt;br /&gt;
|'''Translation Channel Index Array'''&lt;br /&gt;
|This table maps each bonechannel to a translation channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a translation channel. The value is 0xFF if the bone is not translated by this ANIM.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Scale Channel Index Count'''&lt;br /&gt;
|Count of scale channel indices in the next array. Matches the number of valid bone channels.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u8&lt;br /&gt;
|''Scale Channel Index Count''&lt;br /&gt;
|'''Scale Channel Index Array'''&lt;br /&gt;
|This table maps each bone channel to a scale channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a scale channel. The value is 0xFF if the bone is not scaled by this ANIM.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Scale Key Count'''&lt;br /&gt;
|Count of elements in ''Scale Key Array'' below&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|float3&lt;br /&gt;
|''Scale Key Count''&lt;br /&gt;
|'''Scale Key Array'''&lt;br /&gt;
|The scale keys are interleaved as such (bone-major):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
| bone0/key0 | bone0/key1 | ... | bone0/keyN |&lt;br /&gt;
| bone1/key0 | bone1/key1 | ... | bone1/keyN |&lt;br /&gt;
| .......... | .......... | ... | .......... |&lt;br /&gt;
| boneN/key0 | boneN/key1 | ... | boneN/keyN |&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Rotation Key Count'''&lt;br /&gt;
|Count of elements in ''Rotation Key Array'' below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|float4&lt;br /&gt;
|''Rotation Key Count''&lt;br /&gt;
|'''Rotation Key Array'''&lt;br /&gt;
|The rotation keys are interleaved the same way as the scale keys. In ''Metroid Prime 2'', any bone channels that were marked 0xFF in the ''Rotation Channel Index Array'' are skipped.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Translation Key Count'''&lt;br /&gt;
|Count of elements in ''Translation Key Array'' below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|float3&lt;br /&gt;
|''Translation Key Count''&lt;br /&gt;
|'''Translation Key Array'''&lt;br /&gt;
|The translation keys are interleaved the same way as the scale keys. Any bone channels that were marked 0xFF in the ''Translation Channel Index Array'' are skipped.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|[[EVNT (File Format)|EVNT]]&lt;br /&gt;
|1&lt;br /&gt;
|'''EVNT Ref'''&lt;br /&gt;
|ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rotation Vector Bitstream Format (Compressed) ==&lt;br /&gt;
&lt;br /&gt;
The '''Rotation Vector Bitstream Format''' (0x2) is the most widely used animation format.&lt;br /&gt;
The format uses a compressed [[wikipedia:Bitstream|bitstream]] to store keys that have been&lt;br /&gt;
[[wikipedia:Delta encoding|delta encoded]] and [[wikipedia:Quantization (signal processing)|quantized]]&lt;br /&gt;
to make for a very compact, compressed animation. The data is processed sequentially to reconstruct the&lt;br /&gt;
uncompressed bone channel data as quaternions.&lt;br /&gt;
&lt;br /&gt;
In addition to the bitstream quantization, the format includes a bitmap specifying which frames of the animation have&lt;br /&gt;
keys added. Consequently, the runtime generates missing keys via interpolation (reducing animation size further). &lt;br /&gt;
&lt;br /&gt;
=== Key Values ===&lt;br /&gt;
When decoding the animation, each bone's attribute values are initialized to the ''Initial *''&lt;br /&gt;
values in the ''bone channel descriptors''. For every frame of every bone channel, the key value in the bitstream is ''added''&lt;br /&gt;
with the previous key value (to resolve the delta encoding). &lt;br /&gt;
&lt;br /&gt;
Once resolved, rotation components are divided by ''Rotation Divisor'', resulting in an axis-angle&lt;br /&gt;
[[wikipedia:Axis–angle_representation#Rotation_vector|rotation vector]]. This rotation vector is converted&lt;br /&gt;
to quaternion imaginary components with the W component derived via normalized-difference and a ''sign-bit''&lt;br /&gt;
packed into the bitstream:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
q = &amp;amp;pi; / 2.0 / rotation_divisor&lt;br /&gt;
X = sin(rx * q)&lt;br /&gt;
Y = sin(ry * q)&lt;br /&gt;
Z = sin(rz * q)&lt;br /&gt;
W = sqrt(MAX((1.0 - (X*X + Y*Y + Z*Z)), 0.0))&lt;br /&gt;
W = sign_bit ? -W : W&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Translation components are multiplied by ''Translation Multiplier'', and scale components are multiplied by ''Scale Multiplier''.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!style=&amp;quot;width: 220px;&amp;quot;|Element Count&lt;br /&gt;
!style=&amp;quot;width: 240px;&amp;quot;|Name&lt;br /&gt;
!Notes&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Scratch Size'''&lt;br /&gt;
|Amount of memory that the animation system needs to allocate to process animation&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|[[EVNT (File Format)|EVNT]]&lt;br /&gt;
|1&lt;br /&gt;
|'''EVNT Ref'''&lt;br /&gt;
|ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|{{unknown|Unknown 1}}&lt;br /&gt;
|Always 0x1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u16&lt;br /&gt;
|1&lt;br /&gt;
|{{unknown|Unknown 2}}&lt;br /&gt;
| &lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Duration'''&lt;br /&gt;
|Time in seconds that the animation plays for&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Interval'''&lt;br /&gt;
|Time in seconds between frames (reciprocal of frame-rate, typically 30-fps)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Root Bone ID'''&lt;br /&gt;
|ID of the root bone in this ANIM&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Looping Flag'''&lt;br /&gt;
|When non-zero, engine identifies this ANIM as looping&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Rotation Divisor'''&lt;br /&gt;
|Rotation vectors are divided by this value before being applied&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Translation Multiplier'''&lt;br /&gt;
|Translation vectors are multiplied by this value before being applied&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Scale Multiplier'''&lt;br /&gt;
|Scale vectors are multiplied by this value before being applied&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Count'''&lt;br /&gt;
|Count of bone channels present in ANIM&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|{{unknown|Unknown 4}}&lt;br /&gt;
|Always 0x1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Key Bitmap Length'''&lt;br /&gt;
|Number of bits in ''Key Bitmap''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|round_up(''Key Bitmap Length'' / 32)&lt;br /&gt;
|'''Key Bitmap'''&lt;br /&gt;
|Word-packed bitmap. Each word is read from least-significant to most-significant bit. A set bit indicates the frame at the bit's position has keys for each bone channel. If the bit is unset, the keys must be generated via interpolation.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Count'''&lt;br /&gt;
|Count of animated bone channels (matches the previous bone channel count)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Descriptor Count'''&lt;br /&gt;
|Count of bone channel descriptors in ''Bone Channel Descriptor Table''. Matches the ''Bone Channel Counts''.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|[[#Bone Channel Descriptor|Bone Channel Descriptor]]&lt;br /&gt;
|''Bone Channel Descriptor Count''&lt;br /&gt;
|'''Bone Channel Descriptor Table'''&lt;br /&gt;
|Table describing animated bone channels&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|&amp;lt;remainder of file&amp;gt;&lt;br /&gt;
|'''Key Bitstream'''&lt;br /&gt;
|Word-packed bitstream laid out as described by the descriptor table. The bitstream is unpacked just like ''Key Bitmap'' (least-significant to most-significant). &lt;br /&gt;
Key values are tightly-packed, quantized integers whose bit-depth is specified by the ''* Bits'' values in the descriptor table. &lt;br /&gt;
Each bone-channel key-set starts with a single bit providing the ''W sign-bit'' (1 for negative, 0 for positive).&lt;br /&gt;
&lt;br /&gt;
The key integers are signed using [[wikipedia:Two's complement|Two's complement]] representation.&lt;br /&gt;
&lt;br /&gt;
The keys are interleaved as such (key-major):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
| bone0/key0 | bone1/key0 | ... | boneN/key0 |&lt;br /&gt;
| bone0/key1 | bone1/key1 | ... | boneN/key1 |&lt;br /&gt;
| .......... | .......... | ... | .......... |&lt;br /&gt;
| bone0/keyN | bone1/keyN | ... | boneN/keyN |&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Bone Channel Descriptor ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!Name&lt;br /&gt;
!Notes&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
|-&lt;br /&gt;
|0x0&lt;br /&gt;
|u32&lt;br /&gt;
|'''Bone ID'''&lt;br /&gt;
|''Bone ID'' in the associated [[CINF (File Format)|CINF]] for this bone channel&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x4&lt;br /&gt;
|u16&lt;br /&gt;
|'''Rotation Key Count'''&lt;br /&gt;
|Number of rotation keys in the bitstream for this bone channel.&lt;br /&gt;
'''In MP2, if this value is 0, the remaining Rotation fields aren't present'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x6&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Rotation X'''&lt;br /&gt;
|Initial X value of bone's rotation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x8&lt;br /&gt;
|u8&lt;br /&gt;
|'''Rotation Bits X'''&lt;br /&gt;
|Number of bits allocated to bone's rotation delta X in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x9&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Rotation Y'''&lt;br /&gt;
|Initial Y value of bone's rotation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xB&lt;br /&gt;
|u8&lt;br /&gt;
|'''Rotation Bits Y'''&lt;br /&gt;
|Number of bits allocated to bone's rotation delta Y in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xC&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Rotation Z'''&lt;br /&gt;
|Initial Z value of bone's rotation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xE&lt;br /&gt;
|u8&lt;br /&gt;
|'''Rotation Bits Z'''&lt;br /&gt;
|Number of bits allocated to bone's rotation delta Z in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xF&lt;br /&gt;
|u16&lt;br /&gt;
|'''Translation Key Count'''&lt;br /&gt;
|If this bone channel has an animated translation, its value will match ''Rotation Key Count''; otherwise the value will be 0. &lt;br /&gt;
'''If the value is 0, the remaining Translation fields aren't present'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x11&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Translation X'''&lt;br /&gt;
|Initial X value of bone's translation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x13&lt;br /&gt;
|u8&lt;br /&gt;
|'''Translation Bits X'''&lt;br /&gt;
|Number of bits allocated to bone's translation delta X in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x14&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Translation Y'''&lt;br /&gt;
|Initial Y value of bone's translation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x16&lt;br /&gt;
|u8&lt;br /&gt;
|'''Translation Bits Y'''&lt;br /&gt;
|Number of bits allocated to bone's translation delta Y in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x17&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Translation Z'''&lt;br /&gt;
|Initial Z value of bone's translation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x19&lt;br /&gt;
|u8&lt;br /&gt;
|'''Translation Bits Z'''&lt;br /&gt;
|Number of bits allocated to bone's translation delta Z in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1A&lt;br /&gt;
|u16&lt;br /&gt;
|'''Scale Key Count'''&lt;br /&gt;
|If this bone channel has an animated scale, its value will match ''Scale Key Count''; otherwise the value will be 0. &lt;br /&gt;
'''If the value is 0, the remaining Scale fields aren't present'''&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1C&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Scale X'''&lt;br /&gt;
|Initial X value of bone's scale vector&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1E&lt;br /&gt;
|u8&lt;br /&gt;
|'''Scale Bits X'''&lt;br /&gt;
|Number of bits allocated to bone's scale delta X in bitstream&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1F&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Scale Y'''&lt;br /&gt;
|Initial Y value of bone's scale vector&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x21&lt;br /&gt;
|u8&lt;br /&gt;
|'''Scale Bits Y'''&lt;br /&gt;
|Number of bits allocated to bone's scale delta Y in bitstream&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x22&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Scale Z'''&lt;br /&gt;
|Initial Z value of bone's scale vector&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x24&lt;br /&gt;
|u8&lt;br /&gt;
|'''Scale Bits Z'''&lt;br /&gt;
|Number of bits allocated to bone's scale delta Z in bitstream&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x25&lt;br /&gt;
|colspan=5 {{unknown|End of descriptor}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=ANIM_(Metroid_Prime)&amp;diff=1657</id>
		<title>ANIM (Metroid Prime)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=ANIM_(Metroid_Prime)&amp;diff=1657"/>
				<updated>2016-08-27T21:15:29Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Layout */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;''This article is for the ANIM format used in ''Metroid Prime'' and ''Metroid Prime 2: Echoes''. See [[ANIM (File Format)]] for the other revisions of this format.''&lt;br /&gt;
&lt;br /&gt;
The '''ANIM format''' is used in conjunction with [[CINF (File Format)|CINF]] + [[CSKR (File Format)|CSKR]] rigging to animate [[CMDL (Metroid Prime)|CMDL meshes]]. The format is largely the same between the two games, with the main difference being that starting in ''Metroid Prime 2'', support for animating scale was added.&lt;br /&gt;
&lt;br /&gt;
There are two versions of the ANIM format (indicated by the file's first u32 value), one with compressed animations and one with uncompressed ones:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Version&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|0x0&lt;br /&gt;
|[[#Quaternion Array Format (Uncompressed)|Quaternion Array Format (Uncompressed)]]&lt;br /&gt;
|-&lt;br /&gt;
|0x2&lt;br /&gt;
|[[#Rotation Vector Bitstream Format (Compressed)|Rotation Vector Bitstream Format (Compressed)]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Quaternion Array Format (Uncompressed) ==&lt;br /&gt;
&lt;br /&gt;
The '''Quaternion Array Format''' (0x0) is a less common animation format. In ''Metroid Prime'', it only appears in a Ridley intro animation and the rotating pirate data artifact hologram above the Impact Crater, as well as some unused Samus animations, while in ''Metroid Prime 2'', it only seems to show up in some draft/test animations not used in the final game.&lt;br /&gt;
&lt;br /&gt;
This format stores uncompressed animations by mapping animation channels to bones, supplying rotations as an array of [[wikipedia:Quaternion|quaternion]] (WXYZ) keys and translations/scales as an array of XYZ keys. Translations may be specified for a subset of bones as an array of XYZ keys. In ''Metroid Prime'', rotation keys are required on every channel, while translations may be specified for a subset of bones. In ''Metroid Prime 2'', all three transform components are opt-in. &lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!style=&amp;quot;width: 215px;&amp;quot;|Element Count&lt;br /&gt;
!style=&amp;quot;width: 240px;&amp;quot;|Name&lt;br /&gt;
!Notes&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
|-&lt;br /&gt;
|0x4&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Duration'''&lt;br /&gt;
|'''[1/2 in CCharAnimTime]''' Time in seconds that the animation plays for&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x8&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Differential State Enum'''&lt;br /&gt;
|'''[2/2 in CCharAnimTime]''' State of ''Duration'' time point for proper integration control &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;Non Zero&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Zero Increasing&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Zero Steady&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Zero Decreasing&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Infinity&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xC&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Key Interval'''&lt;br /&gt;
|'''[1/2 in CCharAnimTime]''' Time in seconds between keys of each bone channel (reciprocal of frame-rate)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x10&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Differential State Enum'''&lt;br /&gt;
|'''[2/2 in CCharAnimTime]''' State of ''Key Interval'' time point for proper integration control&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x14&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Key Count'''&lt;br /&gt;
|Count of keys for each bone channel (keys are set for every frame of the animation)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x18&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Root Bone ID'''&lt;br /&gt;
|ID of the root bone in this ANIM&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1C&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Count'''&lt;br /&gt;
|Count of bone channel indices in the next array. Always 100.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x20&lt;br /&gt;
|u8&lt;br /&gt;
|''Bone Channel Count''&lt;br /&gt;
|'''Bone Channel Index Array'''&lt;br /&gt;
|This table maps each bone to a bone channel, with the index-position corresponding to a ''Bone ID'' in the associated [[CINF (File Format)|CINF]], while the value corresponds to a bone channel index. The value is 0xFF if the bone is not animated by this ANIM.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Rotation Channel Index Count'''&lt;br /&gt;
|Count of rotation channel indices in the next array. Matches the number of valid bone channels.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u8&lt;br /&gt;
|''Rotation Channel Index Count''&lt;br /&gt;
|'''Rotation Channel Index Array'''&lt;br /&gt;
|This table maps each bone channel to a rotation channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a rotation channel. The value is 0xFF if the bone is not rotated by this ANIM. '''Note:''' In ''Metroid Prime'', every bone channel always has rotations, so this array is omitted.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Translation Channel Index Count'''&lt;br /&gt;
|Count of translation channel indices in the next array. Matches the number of valid bone channels.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u8&lt;br /&gt;
|''Translation Channel Index Count''&lt;br /&gt;
|'''Translation Channel Index Array'''&lt;br /&gt;
|This table maps each bonechannel to a translation channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a translation channel. The value is 0xFF if the bone is not translated by this ANIM.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Scale Channel Index Count'''&lt;br /&gt;
|Count of scale channel indices in the next array. Matches the number of valid bone channels.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u8&lt;br /&gt;
|''Scale Channel Index Count''&lt;br /&gt;
|'''Scale Channel Index Array'''&lt;br /&gt;
|This table maps each bone channel to a scale channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a scale channel. The value is 0xFF if the bone is not scaled by this ANIM.&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Scale Key Count'''&lt;br /&gt;
|Count of elements in ''Scale Key Array'' below&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|float3&lt;br /&gt;
|''Scale Key Count''&lt;br /&gt;
|'''Scale Key Array'''&lt;br /&gt;
|The scale keys are interleaved as such (bone-major):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
| bone0/key0 | bone0/key1 | ... | bone0/keyN |&lt;br /&gt;
| bone1/key0 | bone1/key1 | ... | bone1/keyN |&lt;br /&gt;
| .......... | .......... | ... | .......... |&lt;br /&gt;
| boneN/key0 | boneN/key1 | ... | boneN/keyN |&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Rotation Key Count'''&lt;br /&gt;
|Count of elements in ''Rotation Key Array'' below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|float4&lt;br /&gt;
|''Rotation Key Count''&lt;br /&gt;
|'''Rotation Key Array'''&lt;br /&gt;
|The rotation keys are interleaved the same way as the scale keys. In ''Metroid Prime 2'', any bone channels that were marked 0xFF in the ''Rotation Channel Index Array'' are skipped.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Translation Key Count'''&lt;br /&gt;
|Count of elements in ''Translation Key Array'' below&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|float3&lt;br /&gt;
|''Translation Key Count''&lt;br /&gt;
|'''Translation Key Array'''&lt;br /&gt;
|The translation keys are interleaved the same way as the scale keys. Any bone channels that were marked 0xFF in the ''Translation Channel Index Array'' are skipped.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|{{unknown|}}&lt;br /&gt;
|[[EVNT (File Format)|EVNT]]&lt;br /&gt;
|1&lt;br /&gt;
|'''EVNT Ref'''&lt;br /&gt;
|ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Rotation Vector Bitstream Format (Compressed) ==&lt;br /&gt;
&lt;br /&gt;
The '''Rotation Vector Bitstream Format''' (0x2) is the most widely used animation format.&lt;br /&gt;
The format uses a compressed [[wikipedia:Bitstream|bitstream]] to store keys that have been&lt;br /&gt;
[[wikipedia:Delta encoding|delta encoded]] and [[wikipedia:Quantization (signal processing)|quantized]]&lt;br /&gt;
to make for a very compact, compressed animation. The data is processed sequentially to reconstruct the&lt;br /&gt;
uncompressed bone channel data as quaternions.&lt;br /&gt;
&lt;br /&gt;
In addition to the bitstream quantization, the format includes a bitmap specifying which frames of the animation have&lt;br /&gt;
keys added. Consequently, the runtime generates missing keys via interpolation (reducing animation size further). &lt;br /&gt;
&lt;br /&gt;
=== Key Values ===&lt;br /&gt;
When decoding the animation, each bone's attribute values are initialized to the ''Initial *''&lt;br /&gt;
values in the ''bone channel descriptors''. For every frame of every bone channel, the key value in the bitstream is ''added''&lt;br /&gt;
with the previous key value (to resolve the delta encoding). &lt;br /&gt;
&lt;br /&gt;
Once resolved, rotation components are divided by ''Rotation Divisor'', resulting in an axis-angle&lt;br /&gt;
[[wikipedia:Axis–angle_representation#Rotation_vector|rotation vector]]. This rotation vector is converted&lt;br /&gt;
to quaternion imaginary components with the W component derived via normalized-difference and a ''sign-bit''&lt;br /&gt;
packed into the bitstream:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
q = &amp;amp;pi; / 2.0 / rotation_divisor&lt;br /&gt;
X = sin(rx * q)&lt;br /&gt;
Y = sin(ry * q)&lt;br /&gt;
Z = sin(rz * q)&lt;br /&gt;
W = sqrt(MAX((1.0 - (X*X + Y*Y + Z*Z)), 0.0))&lt;br /&gt;
W = sign_bit ? -W : W&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Translation components are multiplied by ''Translation Multiplier'', and scale components are multiplied by ''Scale Multiplier''.&lt;br /&gt;
&lt;br /&gt;
=== Layout ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Type&lt;br /&gt;
!style=&amp;quot;width: 220px;&amp;quot;|Element Count&lt;br /&gt;
!style=&amp;quot;width: 240px;&amp;quot;|Name&lt;br /&gt;
!Notes&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Scratch Size'''&lt;br /&gt;
|Amount of memory that the animation system needs to allocate to process animation&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|[[EVNT (File Format)|EVNT]]&lt;br /&gt;
|1&lt;br /&gt;
|'''EVNT Ref'''&lt;br /&gt;
|ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|{{unknown|Unknown 1}}&lt;br /&gt;
|Always 0x1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u16&lt;br /&gt;
|1&lt;br /&gt;
|{{unknown|Unknown 2}}&lt;br /&gt;
| &lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Duration'''&lt;br /&gt;
|Time in seconds that the animation plays for&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Interval'''&lt;br /&gt;
|Time in seconds between frames (reciprocal of frame-rate, typically 30-fps)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Root Bone ID'''&lt;br /&gt;
|ID of the root bone in this ANIM&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Looping flag'''&lt;br /&gt;
|When non-zero, engine identifies this ANIM as looping&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Rotation Divisor'''&lt;br /&gt;
|Rotation vectors are divided by this value before being applied&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Translation Multiplier'''&lt;br /&gt;
|Translation vectors are multiplied by this value before being applied&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|float&lt;br /&gt;
|1&lt;br /&gt;
|'''Scale Multiplier'''&lt;br /&gt;
|Scale vectors are multiplied by this value before being applied&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Count'''&lt;br /&gt;
|Count of bone channels present in ANIM&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|{{unknown|Unknown 4}}&lt;br /&gt;
|Always 0x1&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Key Bitmap Length'''&lt;br /&gt;
|Number of bits in ''Key Bitmap''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|round_up(''Key Bitmap Length'' / 32)&lt;br /&gt;
|'''Key Bitmap'''&lt;br /&gt;
|Word-packed bitmap. Each word is read from least-significant to most-significant bit. A set bit indicates the frame at the bit's position has keys for each bone channel. If the bit is unset, the keys must be generated via interpolation.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Count'''&lt;br /&gt;
|Count of animated bone channels (matches the previous bone channel count)&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|1&lt;br /&gt;
|'''Bone Channel Descriptor Count'''&lt;br /&gt;
|Count of bone channel descriptors in ''Bone Channel Descriptor Table''. Matches the ''Bone Channel Counts''.&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|[[#Bone Channel Descriptor|Bone Channel Descriptor]]&lt;br /&gt;
|''Bone Channel Descriptor Count''&lt;br /&gt;
|'''Bone Channel Descriptor Table'''&lt;br /&gt;
|Table describing animated bone channels&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|u32&lt;br /&gt;
|&amp;lt;remainder of file&amp;gt;&lt;br /&gt;
|'''Key Bitstream'''&lt;br /&gt;
|Word-packed bitstream laid out as described by the descriptor table. The bitstream is unpacked just like ''Key Bitmap'' (least-significant to most-significant). &lt;br /&gt;
Key values are tightly-packed, quantized integers whose bit-depth is specified by the ''* Bits'' values in the descriptor table. &lt;br /&gt;
Each bone-channel key-set starts with a single bit providing the ''W sign-bit'' (1 for negative, 0 for positive).&lt;br /&gt;
&lt;br /&gt;
The key integers are signed using [[wikipedia:Two's complement|Two's complement]] representation.&lt;br /&gt;
&lt;br /&gt;
The keys are interleaved as such (key-major):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
| bone0/key0 | bone1/key0 | ... | boneN/key0 |&lt;br /&gt;
| bone0/key1 | bone1/key1 | ... | boneN/key1 |&lt;br /&gt;
| .......... | .......... | ... | .......... |&lt;br /&gt;
| bone0/keyN | bone1/keyN | ... | boneN/keyN |&lt;br /&gt;
|------------|------------|-----|------------|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Bone Channel Descriptor ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Offset&lt;br /&gt;
!Type&lt;br /&gt;
!Name&lt;br /&gt;
!Notes&lt;br /&gt;
!MP1&lt;br /&gt;
!MP2&lt;br /&gt;
|-&lt;br /&gt;
|0x0&lt;br /&gt;
|u32&lt;br /&gt;
|'''Bone ID'''&lt;br /&gt;
|''Bone ID'' in the associated [[CINF (File Format)|CINF]] for this bone channel&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x4&lt;br /&gt;
|u16&lt;br /&gt;
|'''Rotation Key Count'''&lt;br /&gt;
|Number of rotation keys in the bitstream for this bone channel.&lt;br /&gt;
'''In MP2, if this value is 0, the remaining Rotation fields aren't present'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x6&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Rotation X'''&lt;br /&gt;
|Initial X value of bone's rotation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x8&lt;br /&gt;
|u8&lt;br /&gt;
|'''Rotation Bits X'''&lt;br /&gt;
|Number of bits allocated to bone's rotation delta X in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x9&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Rotation Y'''&lt;br /&gt;
|Initial Y value of bone's rotation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xB&lt;br /&gt;
|u8&lt;br /&gt;
|'''Rotation Bits Y'''&lt;br /&gt;
|Number of bits allocated to bone's rotation delta Y in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xC&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Rotation Z'''&lt;br /&gt;
|Initial Z value of bone's rotation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xE&lt;br /&gt;
|u8&lt;br /&gt;
|'''Rotation Bits Z'''&lt;br /&gt;
|Number of bits allocated to bone's rotation delta Z in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0xF&lt;br /&gt;
|u16&lt;br /&gt;
|'''Translation Key Count'''&lt;br /&gt;
|If this bone channel has an animated translation, its value will match ''Rotation Key Count''; otherwise the value will be 0. &lt;br /&gt;
'''If the value is 0, the remaining Translation fields aren't present'''&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x11&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Translation X'''&lt;br /&gt;
|Initial X value of bone's translation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x13&lt;br /&gt;
|u8&lt;br /&gt;
|'''Translation Bits X'''&lt;br /&gt;
|Number of bits allocated to bone's translation delta X in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x14&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Translation Y'''&lt;br /&gt;
|Initial Y value of bone's translation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x16&lt;br /&gt;
|u8&lt;br /&gt;
|'''Translation Bits Y'''&lt;br /&gt;
|Number of bits allocated to bone's translation delta Y in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x17&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Translation Z'''&lt;br /&gt;
|Initial Z value of bone's translation vector&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x19&lt;br /&gt;
|u8&lt;br /&gt;
|'''Translation Bits Z'''&lt;br /&gt;
|Number of bits allocated to bone's translation delta Z in bitstream&lt;br /&gt;
|{{check}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1A&lt;br /&gt;
|u16&lt;br /&gt;
|'''Scale Key Count'''&lt;br /&gt;
|If this bone channel has an animated scale, its value will match ''Scale Key Count''; otherwise the value will be 0. &lt;br /&gt;
'''If the value is 0, the remaining Scale fields aren't present'''&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1C&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Scale X'''&lt;br /&gt;
|Initial X value of bone's scale vector&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1E&lt;br /&gt;
|u8&lt;br /&gt;
|'''Scale Bits X'''&lt;br /&gt;
|Number of bits allocated to bone's scale delta X in bitstream&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x1F&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Scale Y'''&lt;br /&gt;
|Initial Y value of bone's scale vector&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x21&lt;br /&gt;
|u8&lt;br /&gt;
|'''Scale Bits Y'''&lt;br /&gt;
|Number of bits allocated to bone's scale delta Y in bitstream&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x22&lt;br /&gt;
|s16&lt;br /&gt;
|'''Initial Scale Z'''&lt;br /&gt;
|Initial Z value of bone's scale vector&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x24&lt;br /&gt;
|u8&lt;br /&gt;
|'''Scale Bits Z'''&lt;br /&gt;
|Number of bits allocated to bone's scale delta Z in bitstream&lt;br /&gt;
|{{nocheck}}&lt;br /&gt;
|{{check}}&lt;br /&gt;
|-&lt;br /&gt;
|0x25&lt;br /&gt;
|colspan=5 {{unknown|End of descriptor}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1625</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1625"/>
				<updated>2016-06-22T03:57:25Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: /* Region Data */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data via the ''region data index''; value is negative on a dummy ''region info'' to terminate track regions&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 3 types of commands&lt;br /&gt;
in SNG: ''note'', ''control change'', and ''program change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time RLE=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a custom &lt;br /&gt;
[[wikipedia:Run-length encoding|RLE scheme]] to adaptively scale the value's precision&lt;br /&gt;
to reduce the value's size.&lt;br /&gt;
&lt;br /&gt;
The RLE operates on 16-bit words, with the value 0xffff triggering a continuation,&lt;br /&gt;
then a 'dead' 16-bit word skipped over, then the 0xffff is summed with the following RLE value, &lt;br /&gt;
looping the decode algorithm.&lt;br /&gt;
&lt;br /&gt;
In Python, decoding works like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTimeRLE(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        if term == 0xffff:&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            dummy = streamIn.ReadU16()&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bits of both bytes are ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Program Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''program change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/gm-level-1-sound-set standard MIDI program numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always zero&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of program change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of RLE-compressed&lt;br /&gt;
(delta-tick, delta-value) pairs, decoding to signed 16-bit precision. The decoder must track&lt;br /&gt;
the absolute time and value, summing each consecutive update for the current time/values.&lt;br /&gt;
&lt;br /&gt;
The algorithm for this RLE is different than the delta-time one for commands. It may&lt;br /&gt;
scale down to a single byte if able.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeRLE(streamIn):&lt;br /&gt;
    # high-bit shift-trigger RLE, limited to 2 bytes&lt;br /&gt;
    term = streamIn.ReadU8()&lt;br /&gt;
    total = term &amp;amp; 0x7f&lt;br /&gt;
    if term &amp;amp; 0x80:&lt;br /&gt;
        total = total * 256 + streamIn.ReadU8()&lt;br /&gt;
    return total&lt;br /&gt;
&lt;br /&gt;
def DecodeContinuousRLE(streamIn, isValue):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        # 1-2 byte RLE accumulated within continuable RLE&lt;br /&gt;
        term = DecodeRLE(streamIn)&lt;br /&gt;
        if term == 0x8000:&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            dummy = streamIn.ReadU8()&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
&lt;br /&gt;
        # values are signed deltas;&lt;br /&gt;
        # extending into the high-half of 15-bit precision&lt;br /&gt;
        if isValue:&lt;br /&gt;
            if total &amp;gt;= 0x4000:&lt;br /&gt;
                return total - 0xffff&lt;br /&gt;
            else:&lt;br /&gt;
                return total&lt;br /&gt;
&lt;br /&gt;
        # times are always forward-deltas&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1622</id>
		<title>CSNG (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=CSNG_(File_Format)&amp;diff=1622"/>
				<updated>2016-06-20T20:13:18Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: Multi-track SNG clarifications&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''CSNG format''' contains MIDI data. It appears in Metroid Prime 1 and 2.  It is essentially MusyX's GameCube SNG music format, with a custom header. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
All offsets are relative to the start of the main header (after the custom header). &lt;br /&gt;
&lt;br /&gt;
Overall, SNG functions similar to a Type-1 (multi-track) MIDI file, with (up to) 64 tracks&lt;br /&gt;
merging their events into 16 General-MIDI sequencer channels. In addition to the multi-track&lt;br /&gt;
structure, SNG supports storing MIDI regions as indexed ''patterns'', so songs with repetitive&lt;br /&gt;
refrains can save on memory by referencing patterns more than once.&lt;br /&gt;
&lt;br /&gt;
Timings are represented in ''ticks''. Unlike MIDI, the tick-resolution is fixed at 384&lt;br /&gt;
ticks per beat (e.g. 120 beats-per-minute works out to &amp;lt;code&amp;gt;384 * 120 / 60 = 768&amp;lt;/code&amp;gt; ticks-per-second).&lt;br /&gt;
&lt;br /&gt;
=== Custom Header ===&lt;br /&gt;
&lt;br /&gt;
This 0x14-byte header isn't part of the MusyX format; it appears at the start of the file. After parsing this the rest of the file is copied into a buffer and then passed to the MusyX functions.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Magic'''; (always 0x2)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SongGroup ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''[[AGSC (File Format)|AGSC]] ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''SNG File Length'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|MusyX data starts}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Track Index Offset'''; usually 0x18 for GCN games&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Index Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Channel Map Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo Table Offset'''; 0x0 if tempo doesn't change&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Initial Tempo'''; (commonly 0x78 or 120 beats per minute)&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Info===&lt;br /&gt;
&lt;br /&gt;
The ''track index'' has offsets relating the first '''region info''' for each track.&lt;br /&gt;
&lt;br /&gt;
There is a sequence of at least 2 region info structures populating each track, last one acting as terminator:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Start Tick'''; time-point to begin executing region data &lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}; commonly 0xffff0000&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Region Data Index'''; used to select region data via the ''region data index''; value is negative on a dummy ''region info'' to terminate track regions&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region info}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Region Data===&lt;br /&gt;
&lt;br /&gt;
Here begins a free-form blob of indexed region data. It starts with a variable-length &lt;br /&gt;
'''u32 array''' of SNG offsets for each region, then the region data itself.&lt;br /&gt;
&lt;br /&gt;
====Region Data Header====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Region Data Header Size'''; size of the header ''after'' this field (always 0x8)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pitch Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no pitch-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Mod Wheel Data Offset'''; (absolute SNG-offset) 0x0 if no mod-wheel messages in region&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{unknown|End of region data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Region Commands====&lt;br /&gt;
&lt;br /&gt;
After the region data header, the actual playback commands begin. There are only 2 types of commands&lt;br /&gt;
in SNG: ''note'' and ''control change''.&lt;br /&gt;
&lt;br /&gt;
=====Delta Time RLE=====&lt;br /&gt;
&lt;br /&gt;
Just like MIDI, each command starts with a '''delta time''' value telling the sequencer &lt;br /&gt;
how many ticks to wait after the previous command. Unlike MIDI, Factor5 uses a custom &lt;br /&gt;
[[wikipedia:Run-length encoding|RLE scheme]] to adaptively scale the value's precision&lt;br /&gt;
to reduce the value's size.&lt;br /&gt;
&lt;br /&gt;
The RLE operates on 16-bit words, with the value 0xffff triggering a continuation,&lt;br /&gt;
then a 'dead' 16-bit word skipped over, then the 0xffff is summed with the following RLE value, &lt;br /&gt;
looping the decode algorithm.&lt;br /&gt;
&lt;br /&gt;
In Python, decoding works like so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeDeltaTimeRLE(streamIn):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        term = streamIn.ReadU16()&lt;br /&gt;
        if term == 0xffff:&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            dummy = streamIn.ReadU16()&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Note Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''unset'',&lt;br /&gt;
this is a '''note command'''. &lt;br /&gt;
&lt;br /&gt;
Unlike MIDI, which has separate commands for note-on/note-off, SNG attaches a ''note length'' value&lt;br /&gt;
to a note-on command, which is then able to track its own lifetime.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Note'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Velocity'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Note Length'''; count of ticks before note-off issued by sequencer&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| colspan=2 {{unknown|End of note}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====Control Change Command=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time != 0xffff, and the high-bit of the first byte is ''set'',&lt;br /&gt;
this is a '''control change command'''.&lt;br /&gt;
&lt;br /&gt;
See the [https://www.midi.org/specifications/item/table-3-control-change-messages-data-bytes-2 standard MIDI control numbers] for details.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Value'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Control'''; AND with 0x7f for the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of control change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=====End Of Region=====&lt;br /&gt;
&lt;br /&gt;
When the two bytes following the delta-time == 0xffff, this region has no more commands.&lt;br /&gt;
&lt;br /&gt;
====Continuous Pitch / Modulation Data====&lt;br /&gt;
&lt;br /&gt;
If the pitch or mod offsets in a region are non-zero, they point to a buffer of RLE-compressed&lt;br /&gt;
(delta-tick, delta-value) pairs, decoding to signed 16-bit precision. The decoder must track&lt;br /&gt;
the absolute time and value, summing each consecutive update for the current time/values.&lt;br /&gt;
&lt;br /&gt;
The algorithm for this RLE is different than the delta-time one for commands. It may&lt;br /&gt;
scale down to a single byte if able.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
def DecodeRLE(streamIn):&lt;br /&gt;
    # high-bit shift-trigger RLE, limited to 2 bytes&lt;br /&gt;
    term = streamIn.ReadU8()&lt;br /&gt;
    total = term &amp;amp; 0x7f&lt;br /&gt;
    if term &amp;amp; 0x80:&lt;br /&gt;
        total = total * 256 + streamIn.ReadU8()&lt;br /&gt;
    return total&lt;br /&gt;
&lt;br /&gt;
def DecodeContinuousRLE(streamIn, isValue):&lt;br /&gt;
    total = 0&lt;br /&gt;
    while True:&lt;br /&gt;
        # 1-2 byte RLE accumulated within continuable RLE&lt;br /&gt;
        term = DecodeRLE(streamIn)&lt;br /&gt;
        if term == 0x8000:&lt;br /&gt;
            total += 0xffff&lt;br /&gt;
            dummy = streamIn.ReadU8()&lt;br /&gt;
            continue&lt;br /&gt;
        total += term&lt;br /&gt;
&lt;br /&gt;
        # values are signed deltas;&lt;br /&gt;
        # extending into the high-half of 15-bit precision&lt;br /&gt;
        if isValue:&lt;br /&gt;
            if total &amp;gt;= 0x4000:&lt;br /&gt;
                return total - 0xffff&lt;br /&gt;
            else:&lt;br /&gt;
                return total&lt;br /&gt;
&lt;br /&gt;
        # times are always forward-deltas&lt;br /&gt;
        return total&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Channel Map===&lt;br /&gt;
&lt;br /&gt;
This is a simple '''u8 table''' mapping 64 SNG tracks to 16 MIDI channels for instrument selection via the [[AGSC (File Format)#MIDI Setup Entry|SongGroup MIDI-Setup]].&lt;br /&gt;
&lt;br /&gt;
===Tempo Table===&lt;br /&gt;
&lt;br /&gt;
When the SNG has a non-zero tempo table offset, this song features tempo changes. &lt;br /&gt;
The change events are simple absolute-tick / BPM pairs.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tick'''; absolute time-point to perform tempo change&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tempo'''; new tempo in BPM&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of tempo change}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	<entry>
		<id>http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1614</id>
		<title>AGSC (File Format)</title>
		<link rel="alternate" type="text/html" href="http://www.metroid2002.com/retromodding/index.php?title=AGSC_(File_Format)&amp;diff=1614"/>
				<updated>2016-05-31T00:57:12Z</updated>
		
		<summary type="html">&lt;p&gt;Jackoalan: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files. &lt;br /&gt;
&lt;br /&gt;
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.&lt;br /&gt;
&lt;br /&gt;
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}&lt;br /&gt;
{{research|minor|The proj and sdir chunks have a couple unknowns left.}}&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Format ==&lt;br /&gt;
&lt;br /&gt;
The AGSC format is essentially four data chunks combined into one resource, each of which is a standard MusyX file. Of the four data chunks (pool, proj, samp, and sdir), there's one for sound engine scripts, one for sound properties, one for actual ADPCM sound data, and one for sound metadata. The main difference between Prime 1 and 2 is the header, and some slight changes in the way the four chunks are organized. In Metroid Prime, each chunk begins with its own size value; in Metroid Prime 2, every chunk instead has its size listed at the beginning of the file, at the end of the header. In addition, in Metroid Prime, the third chunk is samp, and the fourth is sdir; in Metroid Prime 2, it's the other way around.&lt;br /&gt;
&lt;br /&gt;
=== Header ===&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| '''D'''&lt;br /&gt;
| '''Audio Directory'''. Always &amp;quot;Audio/.&amp;quot; Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D&lt;br /&gt;
| '''N'''&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0 + D + N&lt;br /&gt;
|colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Metroid Prime 2 ====&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''; always 1}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| D&lt;br /&gt;
| '''Audio Group Name'''. Zero-terminated.&lt;br /&gt;
|-&lt;br /&gt;
| 0x4 + D&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''; 0xFFFF if unspecified&lt;br /&gt;
|-&lt;br /&gt;
| 0x6 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Pool size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xA + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Project size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xE + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample directory size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x12 + D&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x16 + D&lt;br /&gt;
| colspan=2 {{unknown|End of header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Pool ===&lt;br /&gt;
&lt;br /&gt;
The Pool chunk contains sub-chunk tables for SoundMacros, ADSR, keymaps, and layers, if applicable. It starts with a 16-byte header before the different data tables begin.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacros Offset''' (always 0x10)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== ObjectID ====&lt;br /&gt;
&lt;br /&gt;
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID''':&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Sound object type''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;SoundMacro&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;Table&amp;lt;/li&amp;gt;&amp;lt;li value=4&amp;gt;Keymap&amp;lt;/li&amp;gt;&amp;lt;li value=8&amp;gt;Layer&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Unique ID''' (per type namespacing)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| colspan=2 {{unknown|End of ObjectID}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This is the ID structure produced by MusyX data export tool used for ''Metroid Prime'' &lt;br /&gt;
(which allocates all group ObjectIDs on export). The ObjectID structure is actually an arbitrary 16-bits in MusyX&lt;br /&gt;
(limited to 14-bit uniqueness). Based on findings from other games, this upper-byte type source is not 100% reliable,&lt;br /&gt;
since Factor5 updated the tool during the console's lifetime.&lt;br /&gt;
&lt;br /&gt;
==== SoundMacros ====&lt;br /&gt;
&lt;br /&gt;
The first Pool table denotes MusyX's '''SoundMacros''', small scripts that apply various effects on the sounds in the game.  Each macro is composed of a header followed by a number of commands; each command specifies its type through a single-byte command ID, then specifies the parameters of that particular command, which vary.&lt;br /&gt;
&lt;br /&gt;
The header of each SoundMacro is eight bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size''' ''(note: includes the size value itself)''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''SoundMacro ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|Commands begin}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
On the commands, each 4 bytes were originally little endian, but have been swapped to big endian in the AGSC files (despite not being longs). To read the data as originally formatted, every four bytes needs to be byte-swapped. Each command is 8 bytes, and is structured as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Command ID''' (varies; there are 79 known commands in the MusyX audio engine.)&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 7&lt;br /&gt;
| '''Command arguments''' (varies between commands)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The SoundMacro will continue with commands until it terminates when the END command is executed.  The command ID for END is 0 and has null command arguments; the next SoundMacro begins after reading it. &lt;br /&gt;
&lt;br /&gt;
These are the possible commands:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! width=&amp;quot;2%&amp;quot; | ID&lt;br /&gt;
! width=&amp;quot;7%&amp;quot; | Name&lt;br /&gt;
! colspan=&amp;quot;91%&amp;quot; | Arguments&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| STOP&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
| width=&amp;quot;13%&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| SPLITKEY&lt;br /&gt;
| Keynumber&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| SPLITVEL&lt;br /&gt;
| Velocity&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| WAIT_TICKS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| Absolute&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| LOOP&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sampleend&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Times&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| GOTO&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| WAIT_MS&lt;br /&gt;
| Keyoff&lt;br /&gt;
| Random&lt;br /&gt;
| Sample end&lt;br /&gt;
| Absolute&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| PLAYMACRO&lt;br /&gt;
| Addnote&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| Priority&lt;br /&gt;
| MaxVoices&lt;br /&gt;
|-&lt;br /&gt;
| 0x9&lt;br /&gt;
| SENDKEYOFF&lt;br /&gt;
| Variable&lt;br /&gt;
| Last started&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| SPLITMOD&lt;br /&gt;
| Mod value&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xB&lt;br /&gt;
| PIANOPAN&lt;br /&gt;
| Scale&lt;br /&gt;
| Centerkey&lt;br /&gt;
| Centerpan&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| SETADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| DLS mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| SCALEVOLUME&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| PANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xF&lt;br /&gt;
| ENVELOPE&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| STARTSAMPLE&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Sample-ID&lt;br /&gt;
| Mode&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Offset&lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| STOPSAMPLE&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| KEYOFF&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| SPLITRND&lt;br /&gt;
| RND&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| FADE-IN&lt;br /&gt;
| Scale&lt;br /&gt;
| Add&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (Curve)&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x15&lt;br /&gt;
| SPANNING&lt;br /&gt;
| Pan position&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Time ms&lt;br /&gt;
| Width&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x16&lt;br /&gt;
| SETADSRCTRL&lt;br /&gt;
| Attack&lt;br /&gt;
| Decay&lt;br /&gt;
| Sustain&lt;br /&gt;
| Relase&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x17&lt;br /&gt;
| RNDNOTE&lt;br /&gt;
| Note Lo&lt;br /&gt;
| Detune&lt;br /&gt;
| Note Hi&lt;br /&gt;
| Fixed/Free&lt;br /&gt;
| Abs/Rel&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| ADDNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| Detune&lt;br /&gt;
| org key&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x19&lt;br /&gt;
| SETNOTE&lt;br /&gt;
| Key&lt;br /&gt;
| Detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1A&lt;br /&gt;
| LASTNOTE&lt;br /&gt;
| Add&lt;br /&gt;
| detune&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1B&lt;br /&gt;
| PORTAMENTO&lt;br /&gt;
| Port. State&lt;br /&gt;
| Port. Type&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| VIBRATO&lt;br /&gt;
| Level note&lt;br /&gt;
| Level fine&lt;br /&gt;
| Modwheel flag&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1D&lt;br /&gt;
| PITCHSWEEP1&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1E&lt;br /&gt;
| PITCHSWEEP2&lt;br /&gt;
| Times&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| ms switch&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Ticks/Millisec.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1F&lt;br /&gt;
| SETPITCH&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; | Frequency (Hz)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Fine&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| SETPITCHADSR&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Table-ID (ADSR)&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| Note range&lt;br /&gt;
| Detune range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x21&lt;br /&gt;
| SCALEVOLUME DLS&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scale&lt;br /&gt;
| Org vol&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x22&lt;br /&gt;
| MOD2VIBRANGE&lt;br /&gt;
| Key range&lt;br /&gt;
| Cent range&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x23&lt;br /&gt;
| SETUP TREMOLO&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Tremolo scale&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Modw. add scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| RETURN&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x25&lt;br /&gt;
| GOSUB&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| TRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro ID&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro step&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x29&lt;br /&gt;
| UNTRAP_EVENT&lt;br /&gt;
| Event&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2A&lt;br /&gt;
| SEND_MESSAGE&lt;br /&gt;
| IsVar&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Macro&lt;br /&gt;
| VID&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2B&lt;br /&gt;
| GET_MESSAGE&lt;br /&gt;
| Variable&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| GET_VID&lt;br /&gt;
| Variable&lt;br /&gt;
| PLAY_MACRO&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| ADDAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x31&lt;br /&gt;
| SETAGECOUNT&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Counter&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x32&lt;br /&gt;
| SENDFLAG&lt;br /&gt;
| Flag-ID&lt;br /&gt;
| Value&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x33&lt;br /&gt;
| PITCHWHEELR&lt;br /&gt;
| Range up&lt;br /&gt;
| Range down&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| SETPRIORITY&lt;br /&gt;
| Prio&lt;br /&gt;
| colspan=&amp;quot;6&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x35&lt;br /&gt;
| ADDPRIORITY&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Add&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x36&lt;br /&gt;
| AGECNTSPEED&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; | Time&lt;br /&gt;
|-&lt;br /&gt;
| 0x37&lt;br /&gt;
| AGECNTVEL&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Base&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | AGE Scale&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| VOL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x41&lt;br /&gt;
| PAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x42&lt;br /&gt;
| PitchW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x43&lt;br /&gt;
| ModW_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| PEDAL_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x45&lt;br /&gt;
| PORTA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x46&lt;br /&gt;
| REVERB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x47&lt;br /&gt;
| SPAN_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x48&lt;br /&gt;
| DOPPLER_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x49&lt;br /&gt;
| TREMOLO_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4A&lt;br /&gt;
| PREA_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4B&lt;br /&gt;
| PREB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4C&lt;br /&gt;
| POSTB_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4D&lt;br /&gt;
| AUXAFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x4E&lt;br /&gt;
| AUXBFX_SELECT&lt;br /&gt;
| MIDI Contr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Scaling percentage&lt;br /&gt;
| Combine&lt;br /&gt;
| is var.&lt;br /&gt;
| Fine scaling&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x50&lt;br /&gt;
| SETUP_LFO&lt;br /&gt;
| LFO Nr.&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Period in ms&lt;br /&gt;
| colspan=&amp;quot;4&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x58&lt;br /&gt;
| MODE_SELECT&lt;br /&gt;
| DLS vol&lt;br /&gt;
| ITD&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x59&lt;br /&gt;
| SET_KEYGROUP&lt;br /&gt;
| group&lt;br /&gt;
| kill&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x5A&lt;br /&gt;
| SRCMODE_SELECT&lt;br /&gt;
| SRC type&lt;br /&gt;
| Type 0 SRC filter&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x60&lt;br /&gt;
| ADD_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x61&lt;br /&gt;
| SUB_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B -&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x62&lt;br /&gt;
| MUL_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B *&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x63&lt;br /&gt;
| DIV_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B /&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| C&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x64&lt;br /&gt;
| ADDI_VARS&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| A =&lt;br /&gt;
| Var/Ctrl&lt;br /&gt;
| B +&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Immediate&lt;br /&gt;
| {{unknown|}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x70&lt;br /&gt;
| IF_EQUAL&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A ==&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x71&lt;br /&gt;
| IF_LESS&lt;br /&gt;
| Ctrl&lt;br /&gt;
| A &amp;lt;&lt;br /&gt;
| Ctrl&lt;br /&gt;
| B&lt;br /&gt;
| Not&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | SoundMacro Step&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| END&lt;br /&gt;
| colspan=&amp;quot;7&amp;quot; {{unknown|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the last soundmacro, the table terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
==== Tables ====&lt;br /&gt;
&lt;br /&gt;
'''Tables''' have two functions: for defining curves for volume scaling, or to be used as ADSR envelopes.&lt;br /&gt;
&lt;br /&gt;
The tables continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Table ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|ADSR/Curve data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== ADSR =====&lt;br /&gt;
&lt;br /&gt;
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Attack time (0-255 milliseconds)'''; no multiplication is done to the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Attack time (0-65280 milliseconds)'''; multiply value by 256&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Decay time (0-255 milliseconds)''';  no multiplication is done to the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Decay time (0-65280 milliseconds)'''; multiply value by 256&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Sustain (percentage)'''; multiply value by 0.0244&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Sustain (percentage)'''; multiply value by 6.25&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Release time (0-255 milliseconds)''';  no multiplication is done to the value&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Release time (0-65280 milliseconds)'''; multiply value by 256&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{unknown|End of ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== DLS ADSR =====&lt;br /&gt;
&lt;br /&gt;
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.&lt;br /&gt;
This representation includes scaling coefficients to respond to played note and velocity &lt;br /&gt;
(so slamming down a key harder plays longer).&lt;br /&gt;
&lt;br /&gt;
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:&lt;br /&gt;
&amp;lt;code&amp;gt;2&amp;lt;sup&amp;gt;timecents / (1200.0 * 65536.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.&lt;br /&gt;
This may be converted to a normalized factor using:&lt;br /&gt;
&amp;lt;code&amp;gt;scale / (1000.0 * 65536.0)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note:''' All fields of the envelope are ''little endian''.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Attack time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Decay time'''; in time-cents&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sustain'''; percentage mapped between [0x0,0x1000]&lt;br /&gt;
|-&lt;br /&gt;
| 0xA&lt;br /&gt;
| 2&lt;br /&gt;
| '''Release'''; in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| colspan=2 {{unknown|End of DLS ADSR}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Curves =====&lt;br /&gt;
&lt;br /&gt;
To express a volume curve, the table data is simply an arbitrarily-sized table of &amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; values&lt;br /&gt;
&lt;br /&gt;
==== Keymaps ====&lt;br /&gt;
&lt;br /&gt;
'''Keymaps''' are swappable, fixed-length tables mapping 128 MIDI keys to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The keymaps continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''; (usually 0x1032)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Keymap ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|128 Keymap entries}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Keymap Entry =====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 8 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Layers ====&lt;br /&gt;
&lt;br /&gt;
'''Layers''' are one-to-many, ranged keyboard mappings to sound-producing objects.&lt;br /&gt;
&lt;br /&gt;
The layers continue until 0xffffffff terminator is reached.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Chunk Size'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Layer ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|-&lt;br /&gt;
| Chunk Size&lt;br /&gt;
| colspan=2 {{Unknown|Layer data}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== Layer Data =====&lt;br /&gt;
&lt;br /&gt;
Within the layer data, there is a '''u32 count''' of layer range structs:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Lo'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Key Hi'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Transpose'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority Offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 1&lt;br /&gt;
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| colspan=2 {{Unknown|Padded to 12 bytes}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The entire Pool chunk is terminated by a value of 0xFFFF.&lt;br /&gt;
&lt;br /&gt;
=== Project ===&lt;br /&gt;
&lt;br /&gt;
The Project properties chunk contains values for the sounds, including priority, polyphony, volume, etc.&lt;br /&gt;
&lt;br /&gt;
Structurally, the Project is the root of the Audio Group tree, defining one or more ''Song Groups'' or ''SFX Groups''&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 4&lt;br /&gt;
| '''Group end offset''' (points to next group in project)&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Group Type'''; 0 for SongGroup (for use with [[CSNG (File Format)|CSNG]]), 1 for SFXGroup.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| '''SoundMacro ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sample ID table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| '''Tables table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Keymaps table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Layers table offset'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Normal page table''' (SongGroup) / '''SFX table offset''' (SFXGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| '''Drum page table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| '''MIDI Setup table offset''' (SongGroup)&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of group header}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
After the header are a number of data tables. &lt;br /&gt;
&lt;br /&gt;
==== SoundMacro ID Table ====&lt;br /&gt;
&lt;br /&gt;
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.&lt;br /&gt;
&lt;br /&gt;
==== Sample ID / Table / Keymap / Layer Tables ====&lt;br /&gt;
&lt;br /&gt;
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.&lt;br /&gt;
&lt;br /&gt;
==== Normal / Drum Page Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map [https://www.midi.org/specifications/item/gm-level-1-sound-set General MIDI program numbers] (instruments)&lt;br /&gt;
to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''GM Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== SFX Entry ====&lt;br /&gt;
&lt;br /&gt;
Used to map auto-generated &amp;lt;code&amp;gt;#define&amp;lt;/code&amp;gt; IDs (used by game code) to sound entities (macros, keymaps, layers)&lt;br /&gt;
&lt;br /&gt;
This table begins with a 16-bit count value, then 16 bits of padding. Each entry in the table is 10 bytes.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''DefineID'''; referenced by game code&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''ObjectID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Priority'''; voices are limited, so priority is used to play more important sounds over others&lt;br /&gt;
|-&lt;br /&gt;
| 0x5&lt;br /&gt;
| 1&lt;br /&gt;
| '''Max number of voices'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 1&lt;br /&gt;
| '''Definite Velocity'''; volume (usually 7F)&lt;br /&gt;
|-&lt;br /&gt;
| 0x7&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2&lt;br /&gt;
| '''Definite Key'''; The default pitch (usually 0x3C00... the second byte may possibly be the MIDI channel)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== MIDI Setup Entry ====&lt;br /&gt;
&lt;br /&gt;
Table of fixed-length tables to map all 16 MIDI channels to program numbers &lt;br /&gt;
(in-turn resolving to sound entities via the page table).&lt;br /&gt;
&lt;br /&gt;
Multiple MIDI Setups may be created to support Song data requiring totally different&lt;br /&gt;
banks of instruments.&lt;br /&gt;
&lt;br /&gt;
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 1&lt;br /&gt;
| '''Program Number'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x1&lt;br /&gt;
| 1&lt;br /&gt;
| '''Volume'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Panning'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Reverb'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 1&lt;br /&gt;
| '''Chorus'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
MIDI setups continue until the ''group end offset'' is reached.&lt;br /&gt;
&lt;br /&gt;
=== Sample ===&lt;br /&gt;
&lt;br /&gt;
The Sample chunk is all the sound data encoded using the standard Gamecube DSP ADPCM codec.  It can be decoded the same way as a [[DSP (File Format)|DSP]] file. Each sound's size is padded to 32 bytes before the next sound's data begins.&lt;br /&gt;
&lt;br /&gt;
=== Sample Directory ===&lt;br /&gt;
&lt;br /&gt;
The Sample Directory chunk (chunk 4 in Metroid Prime, chunk 3 in Metroid Prime 2) is made up of two sets of tables. The structure of both these tables is identical between both games.&lt;br /&gt;
&lt;br /&gt;
==== Table A ====&lt;br /&gt;
&lt;br /&gt;
The first metadata table has one entry per sound, and is terminated with 0xFFFFFFFF; since there's no known sound count anywhere in the file, the only way to read this correctly is to read until you reach the terminator value. Each entry is 0x20 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sound ID'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 2&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 4&lt;br /&gt;
| '''Sound start offset''', relative to the start of the ADPCM chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 4&lt;br /&gt;
| {{unknown|'''Unknown'''}}&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 1&lt;br /&gt;
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: &amp;lt;code&amp;gt;sampleRate * 2&amp;lt;sup&amp;gt;((pitch - baseNote * 100) / 1200.0)&amp;lt;/sup&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 0xD&lt;br /&gt;
| 1&lt;br /&gt;
| '''Padding'''; always 0&lt;br /&gt;
|-&lt;br /&gt;
| 0xE&lt;br /&gt;
| 2&lt;br /&gt;
| '''Sample rate'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 1&lt;br /&gt;
| '''Audio format''' &amp;lt;ol start=&amp;quot;0&amp;quot;&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;DSP-ADPCM (Drum Sample)&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;PCM&amp;lt;/li&amp;gt;&amp;lt;li&amp;gt;N64-VADPCM (Legacy Format)&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt; &lt;br /&gt;
|-&lt;br /&gt;
| 0x11&lt;br /&gt;
| 3&lt;br /&gt;
| '''Number of samples'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop start sample'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| '''Loop length''', in samples. To get the loop end sample, add this to the start sample and subtract 1.&lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| '''Table B entry offset''', relative to the start of the sound metadata chunk&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Table B ====&lt;br /&gt;
&lt;br /&gt;
These are accessed through the offsets in table A's entries; note that it might not match the sound count, because the same entry in this table can be used with multiple sounds. Each entry is 0x28 bytes long.&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Size&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 2&lt;br /&gt;
| {{unknown|'''Unknown'''; always 8}}&lt;br /&gt;
|-&lt;br /&gt;
| 0x2&lt;br /&gt;
| 1&lt;br /&gt;
| '''Initial predictor/scale''' (matches first frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x3&lt;br /&gt;
| 1&lt;br /&gt;
| '''Loop predictor/scale''' (matches loop start frame header)&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 2'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 2&lt;br /&gt;
| '''Loop context sample history 1'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 2 &amp;amp;times; 16&lt;br /&gt;
| '''Decode coefficients'''&lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| colspan=2 {{unknown|End of entry}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Parax will dump all sound effects contained in a given AGSC file.&lt;br /&gt;
&lt;br /&gt;
[[Category:File Formats]]&lt;br /&gt;
[[Category:Audio]]&lt;br /&gt;
[[Category:Metroid Prime]]&lt;br /&gt;
[[Category:Metroid Prime 2: Echoes]]&lt;/div&gt;</summary>
		<author><name>Jackoalan</name></author>	</entry>

	</feed>