U8 Archive: Difference between revisions
mNo edit summary |
mNo edit summary |
||
| (14 intermediate revisions by 3 users not shown) | |||
| Line 1: | Line 1: | ||
'''''U8 Archive''''' is a hierarchical archive format developed by Nintendo during the GameCube era and was predominantly used on the Wii. | |||
== Titles using U8 Archive == | |||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ | ||
! | !Game | ||
! | !Platforms | ||
! | !Usage | ||
|- | |- | ||
| | |Sonic Heroes | ||
| | |PlayStation 2 | ||
|Used | | rowspan="2" |Used as the packed file system. | ||
|- | |- | ||
| | |[[Sonic the Hedgehog (2006)]] | ||
|Xbox 360, PlayStation 3 | |||
| | |||
|- | |- | ||
| | |Sonic and the Secret Rings | ||
| | | rowspan="3" |Wii | ||
| | | rowspan="2" |Used for operating system only. | ||
|- | |- | ||
| | |Sonic and the Black Knight | ||
| | |- | ||
|Used | |[[Sonic Colors]] | ||
|Used as the packed file system. | |||
|- | |||
|Sonic Colors: Ultimate | |||
|Windows, Xbox One, PlayStation 4, Switch | |||
|Used as the packed file system for data not covered by Godot. | |||
|} | |} | ||
== Specification == | == Specification == | ||
=== Header === | === Header === | ||
The header consists of the following data structure: | The header consists of the following data structure: | ||
| Line 44: | Line 42: | ||
|UInt32 | |UInt32 | ||
|Signature | |Signature | ||
|Always 0x55AA382D (big-endian). | |Always 0x55AA382D (big-endian) or 0x2D38AA55 (little-endian). | ||
|- | |- | ||
|0x04 | |0x04 | ||
| Line 64: | Line 62: | ||
|UInt32[4] | |UInt32[4] | ||
|Reserved | |Reserved | ||
|These fields appear to be populated in archives for | |These fields appear to be populated in archives for '''Sonic the Hedgehog (2006)''', but this is bogus data from uninitialised memory and should be ignored. | ||
For the sake of tooling heuristics, writing <code>0xE4F91300</code> (big-endian) to index 0 and <code>0x78013800</code> (big-endian) to index 3 would be ideal for detecting whether | For the sake of tooling heuristics, writing <code>0xE4F91300</code> (big-endian) to index 0 and <code>0x78013800</code> (big-endian) to index 3 would be ideal for detecting whether an archive is from that game specifically. | ||
|} | |} | ||
| Line 71: | Line 69: | ||
The file system consists of an array of the following data structure: | The file system consists of an array of the following data structure: | ||
{| class="wikitable" | {| class="wikitable" | ||
|+Length: 0x10 | |+Length: 0x0C (or 0x10 for Sonic the Hedgehog (2006)) | ||
!Offset | !Offset | ||
!Type | !Type | ||
| Line 119: | Line 117: | ||
|UInt32 | |UInt32 | ||
|UncompressedLength | |UncompressedLength | ||
| | |This field is unique to archives for '''Sonic the Hedgehog (2006)'''. | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ | ||
| Line 136: | Line 134: | ||
=== String Pool === | === String Pool === | ||
The string pool offset can be calculated after reading the root node and using the following expression:<syntaxhighlight> | The string pool offset can be calculated after reading the root node and using the following expression:<syntaxhighlight lang="text"> | ||
FSTableOffset + (Root.NodeCount * | FSTableOffset + (Root.NodeCount * FSNodeSize) // FSNodeSize = 0x0C (or 0x10 for Sonic the Hedgehog (2006)) | ||
</syntaxhighlight>Each string in the pool is ASCII encoded and null-terminated, the offsets to which are relative to the start of the pool. | </syntaxhighlight>Each string in the pool is ASCII-encoded and null-terminated, the offsets to which are relative to the start of the pool. | ||
The string pool '''must''' have a single null terminator at the beginning for the root node, as it does not have a name. | The string pool '''must''' have a single null terminator at the beginning for the root node, as it does not have a name. | ||
=== File Data === | === File Data === | ||
Files | Files are aligned by 32 bytes per file after the string pool. | ||
In '''Sonic the Hedgehog (2006)''', files may be compressed using [[wikipedia:Zlib|zlib]]. This compression is optional, and files can be stored uncompressed so long as <code>UncompressedLength</code> is set to zero. | |||
[[Category:File Formats]] | |||
| | |||
Latest revision as of 20:37, 2 December 2025
U8 Archive is a hierarchical archive format developed by Nintendo during the GameCube era and was predominantly used on the Wii.
Titles using U8 Archive
| Game | Platforms | Usage |
|---|---|---|
| Sonic Heroes | PlayStation 2 | Used as the packed file system. |
| Sonic the Hedgehog (2006) | Xbox 360, PlayStation 3 | |
| Sonic and the Secret Rings | Wii | Used for operating system only. |
| Sonic and the Black Knight | ||
| Sonic Colors | Used as the packed file system. | |
| Sonic Colors: Ultimate | Windows, Xbox One, PlayStation 4, Switch | Used as the packed file system for data not covered by Godot. |
Specification
Header
The header consists of the following data structure:
| Offset | Type | Name | Description |
|---|---|---|---|
| 0x00 | UInt32 | Signature | Always 0x55AA382D (big-endian) or 0x2D38AA55 (little-endian). |
| 0x04 | UInt32 | FSTableOffset | The offset of the file system table. |
| 0x08 | UInt32 | FSTableLength | The length of the file system table (including the string pool). |
| 0x0C | UInt32 | DataOffset | The offset of the file data. |
| 0x10 | UInt32[4] | Reserved | These fields appear to be populated in archives for Sonic the Hedgehog (2006), but this is bogus data from uninitialised memory and should be ignored.
For the sake of tooling heuristics, writing |
File System
The file system consists of an array of the following data structure:
| Offset | Type | Name | Description | ||||
|---|---|---|---|---|---|---|---|
| 0x00 | Boolean (UInt8) | IsDirectory | Determines whether this node is a directory. | ||||
| 0x01 | UInt24 | NameOffset | The offset of this node's name in the string pool.
If root, always zero. | ||||
| 0x04 | Union (UInt32, UInt32) | DataOffset, ParentIndex |
| ||||
| 0x08 | Union (UInt32, UInt32) | Length, NodeCount |
| ||||
| 0x0C | UInt32 | UncompressedLength | This field is unique to archives for Sonic the Hedgehog (2006).
|
The total number of nodes to read is determined by the root node's NodeCount field. As this is a hierarchical file system, nodes should be read recursively to build the file system correctly.
The first node must be a root node defined as a directory, with the NodeCount field set to the total number of nodes in the archive. This is necessary for determining the length of the file system table.
String Pool
The string pool offset can be calculated after reading the root node and using the following expression:
FSTableOffset + (Root.NodeCount * FSNodeSize) // FSNodeSize = 0x0C (or 0x10 for Sonic the Hedgehog (2006))
Each string in the pool is ASCII-encoded and null-terminated, the offsets to which are relative to the start of the pool.
The string pool must have a single null terminator at the beginning for the root node, as it does not have a name.
File Data
Files are aligned by 32 bytes per file after the string pool.
In Sonic the Hedgehog (2006), files may be compressed using zlib. This compression is optional, and files can be stored uncompressed so long as UncompressedLength is set to zero.