1,158
edits
imported>BravelyPeculiar (→Usage in Breath of the Wild: Added content) |
(→Structure: fix struct definitions (offsets and counts are packed as a single u32; they are not separate fields)) |
||
(33 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
'''AAMP''' | <onlyinclude> | ||
'''AAMP'''s are parameter files (officially: binary resource parameter archives). | |||
</onlyinclude> | |||
Only version 2 is documented in this article since this is what ''Breath of the Wild'' and recent Nintendo games use. | |||
== Structure == | == Structure == | ||
AAMP is a (typically) little endian format. | |||
Unlike some other file formats, AAMP files in ''Breath of the Wild'' have the exact same structure and endianness on Wii U and Switch, so these files are interchangeable between the consoles. | |||
=== Introduction === | |||
* Parameters are a key-value pair. In the binary form, the key is a CRC32 hash. | |||
* Parameter Objects are dicts that contain Parameters. | |||
* Parameter Lists are structures that contain Parameter Objects and Parameter Lists. | |||
* The root parameter list is called the Parameter IO. It is associated with a version and type string in the header which is checked by the AAMP library. | |||
=== Section order === | |||
* Header | |||
* Parameter lists | |||
* Parameter objects | |||
* Parameters | |||
* Data section (to store parameter data) | |||
* String section (to store strings) | |||
* Unknown uint32 section (unused?) | |||
For more information on the ordering, refer to the [https://github.com/zeldamods/oead/blob/v0.9.0-2/src/aamp.cpp#L262 oead source code]. | |||
=== Header === | |||
{| class="wikitable" | |||
! Offset !! Type !! Description | |||
|- | |||
| 0x0 || char[4] || Magic ("AAMP") | |||
|- | |||
| 0x4 || u32 || Version (2) | |||
|- | |||
| 0x8 || u32 || Flags (LittleEndian: 1 << 0, UTF8: 1 << 1) | |||
|- | |||
| 0xc || u32 || File size | |||
|- | |||
| 0x10 || u32 || Parameter IO version | |||
|- | |||
| 0x14 || u32 || Offset to parameter IO relative to 0x30 | |||
|- | |||
| 0x18 || u32 || Number of lists (including parameter IO) | |||
|- | |||
| 0x1c || u32 || Number of objects | |||
|- | |||
| 0x20 || u32 || Number of parameters | |||
|- | |||
| 0x24 || u32 || Data section size | |||
|- | |||
| 0x28 || u32 || String section size | |||
|- | |||
| 0x2c || u32 || Unknown: number of uint32s after the string section | |||
|- | |||
| 0x30 || char[] || Parameter IO type (typically <code>xml</code>) | |||
|} | |||
=== Parameter list === | |||
{| class="wikitable" | |||
! Offset !! Type !! Description | |||
|- | |||
| 0x0 || u32 || Name CRC32 | |||
|- | |||
| 0x4 || u32 || | |||
* Bits 0-15: Offset to child lists, divided by 4 and relative to parameter list start | |||
* Bits 16-31: Number of child lists | |||
|- | |||
| 0x8 || u32 || | |||
* Bits 0-15: Offset to child objects, divided by 4 and relative to parameter list start | |||
* Bits 16-31: Number of child objects | |||
|} | |||
=== Parameter object === | |||
{| class="wikitable" | |||
! Offset !! Type !! Description | |||
|- | |||
| 0x0 || u32 || Name CRC32 | |||
|- | |||
| 0x4 || u32 || | |||
* Bits 0-15: Offset to child parameters, divided by 4 and relative to parameter object start | |||
* Bits 16-31: Number of child parameters | |||
|} | |||
=== Parameter === | |||
{| class="wikitable" | |||
! Offset !! Type !! Description | |||
|- | |||
| 0x0 || u32 || Name CRC32 | |||
|- | |||
| 0x4 || u32 || | |||
* Bits 0-23: Offset to data, divided by 4 and relative to parameter start.<br>For strings, this points to a string in the string section. For other parameter types, this points to the data section. | |||
* Bits 24-31: Parameter type | |||
|} | |||
=== ParameterType === | |||
The following parameter type and class names are ''official'' and come from Nintendo's AAMP library. | |||
{| class="wikitable" | |||
! ID | |||
! Type | |||
! Parameter type | |||
|- | |||
| 0 | |||
| bool | |||
| <code>agl::utl::Parameter<bool></code> | |||
|- | |||
| 1 | |||
| f32 | |||
| <code>agl::utl::Parameter<float></code> | |||
|- | |||
| 2 | |||
| int | |||
| <code>agl::utl::Parameter<int></code> | |||
|- | |||
| 3 | |||
| vec2 | |||
| <code>agl::utl::Parameter<sead::Vector2<float>></code> | |||
|- | |||
| 4 | |||
| vec3 | |||
| <code>agl::utl::Parameter<sead::Vector3<float>></code> | |||
|- | |||
| 5 | |||
| vec4 | |||
| <code>agl::utl::Parameter<sead::Vector4<float>></code> | |||
|- | |||
| 6 | |||
| color | |||
| <code>agl::utl::Parameter<sead::Color4f></code> | |||
|- | |||
| 7 | |||
| string32 | |||
| <code>agl::utl::Parameter<sead::FixedSafeString<32>></code> | |||
|- | |||
| 8 | |||
| string64 | |||
| <code>agl::utl::Parameter<sead::FixedSafeString<64>></code> | |||
|- | |||
| 9 | |||
| curve1 | |||
| <code>agl::utl::ParameterCurve<1u></code> | |||
|- | |||
| 10 | |||
| curve2 | |||
| <code>agl::utl::ParameterCurve<2u></code> | |||
|- | |||
| 11 | |||
| curve3 | |||
| <code>agl::utl::ParameterCurve<3u></code> (unused in BotW?) | |||
|- | |||
| 12 | |||
| curve4 | |||
| <code>agl::utl::ParameterCurve<4u></code> | |||
|- | |||
| 13 | |||
| buffer_int | |||
| <code>agl::utl::ParameterBuffer<int></code> | |||
|- | |||
| 14 | |||
| buffer_f32 | |||
| <code>agl::utl::ParameterBuffer<float></code> | |||
|- | |||
| 15 | |||
| string256 | |||
| <code>agl::utl::Parameter<sead::FixedSafeString<256>></code> | |||
|- | |||
| 16 | |||
| quat | |||
| <code>agl::utl::Parameter<sead::Quat<float>></code> | |||
|- | |||
| 17 | |||
| u32 | |||
| <code>agl::utl::Parameter<uint></code> | |||
|- | |||
| 18 | |||
| buffer_u32 | |||
| <code>agl::utl::ParameterBuffer<unsigned int></code> | |||
|- | |||
| 19 | |||
| buffer_binary | |||
| <code>agl::utl::ParameterBuffer<unsigned char></code> | |||
|- | |||
| 20 | |||
| stringRef | |||
| <code>agl::utl::Parameter<sead::SafeStringBase<char>></code> | |||
|- | |||
| 21 | |||
| (none, special) | |||
| <code>agl::utl::Parameter<int *></code>, <code>agl::utl::Parameter<float *></code>, <code>agl::utl::Parameter<unsigned int *></code>, <code>agl::utl::Parameter<unsigned char *></code> | |||
|} | |||
== Usage in ''Breath of the Wild'' == | == Usage in ''Breath of the Wild'' == | ||
AAMP files are used in ''Breath of the Wild'' to store parameters that define the game's behaviour. They are very frequently used inside | AAMP files are used in ''Breath of the Wild'' to store parameters that define the game's behaviour. They are very frequently used inside [[actor pack]] archives, where they define most of an Actor's characteristics. | ||
=== Naming conventions for arrays === | |||
Nintendo works around the lack of lists/arrays in the AAMP format by using parameter lists/objects and numbered names for children. | |||
By convention, if the parent name is <code>{parent name}</code>, children will typically have one of the following names: | |||
* <code>{singular parent name}_%d</code> | |||
* <code>{singular parent name}_%02d</code> | |||
* <code>{singular parent name}_%03d</code> | |||
* <code>{singular parent name}%d</code> | |||
* <code>{singular parent name}%02d</code> | |||
* <code>{singular parent name}%03d</code> | |||
This is of course not the case for all documents and there are in fact many exceptions. | |||
=== Extensions === | === Extensions === | ||
AAMP files have a wide range of extensions. The file format is the same regardless of the extension, but the parameters defines inside it differ depending on the extension. | AAMP files have a wide range of extensions. The file format is the same regardless of the extension, but the parameters defines inside it differ depending on the extension. | ||
The | {{#dpl: | ||
* | |category = File extensions (AAMP) | ||
* | |columns=5 | ||
* | |rowcolformat=width=100% | ||
}} | |||
=== Internal usage === | |||
Parameter classes (e.g. Bdmgparam) inherit from agl::utl::IParameterIO -> agl::utl::IParameterList. | |||
In their constructors or in an init function, agl::utl::Parameter objects are created and initialised by passing the key name, the description and help strings (see <code>agl::utl::ParameterBase::initializeListNode</code>). The CRC32 for the keys are stored and then the Parameter object is added to a agl::utl::IParameterObj list. | |||
Finally, to actually load the AAMP binary data into all the parameter objects, the game constructs a agl::utl::ResParameterArchive::ResParameterArchive and then passes it to <code>applyResParameterArchive()</code>. | |||
==== Structures ==== | |||
agl::utl::ResParameterArchive holds a pointer to agl::utl::ResParameterArchiveData (which is the AAMP header structure). | |||
Elements like param_root are parameter lists (agl::utl::IParameterList, tag: <code>param_list</code>). The binary structure for lists is agl::utl::ResParameterList. | |||
A param list holds parameter objects (agl::utl::IParameterObj, tag: <code>param_array</code>) or other parameter lists. The binary structure for objects is agl::utl::ResParameterObj. | |||
Param objects store parameters (agl::utl::ParameterBase, tag: <code>param</code>). The binary structure for parameters is agl::utl::ResParameter. | |||
=== Parameter list name === | |||
agl::utl::IParameterIO (in Nintendo's AAMP library) automatically sets the 'parameter list name' / tag name to <code>param_root</code>. | |||
== al::Parameter == | |||
''Super Mario Odyssey'''s al::Parameter classes are extremely similar to the agl::utl::Parameter utils and appear to be an improved version. They share most of the public interface, presumably because Nintendo wanted to make switching to al:: easier. | |||
The human readable format is YAML instead of XML and the binary format uses BYML. Key names are stored in plain text unlike agl::utl::Parameter which stores only the hashes of the key strings. | |||
* Parameters have the same purpose as in the agl:: implementation. | |||
* ParameterLists are dicts (key-value mapping, with keys being strings) that contain Parameters, ParameterObjects, ParameterArrays and ParameterLists. | |||
* ParameterObjects are dicts that contain Parameters and ParameterArrays. | |||
* ParameterArrays are arrays of ParameterObjects. This is a new structure. | |||
== Tools == | == Tools == | ||
The following tools can be used to convert AAMP files to an editable format, and back again: | The following tools can be used to convert AAMP files to an editable format, and back again: | ||
{{Tool table|category=Tools (AAMP)}} | |||
[[Category:File formats]] | |||