WAN File Format
The WAN file format is used in Pokémon Mystery Dungeon: Explorers of Time/Darkness/Sky to store animated character sprites along with map props, and even some UI elements.
This format is always wrapped by a SIR0 container, and it doesn't possess its own magic number. However, it does have its own header and structure. Its one of the most complex formats used in the game.
General Information
The file is read from bottom to the top. This is likely because of the way the content of the file is organized, and how the files are meant to be loaded into memory and used as data structures right away.
The content of the file is split in 5 categories.
Meta-Frames
The meta-frames are basically the virtual image that the animations are referring to. They're essentially an abstraction layer above the actual images, and contain data about these ranging from which image in the image pointer table a meta-frame refers to, the actual image's resolution, whether the image should be flipped vertically or horizontally, and even more.
Meta-frames can be "grouped" together in a sequence, with the last meta-frame in a group being indicated by as special bit flag. This allows the game to combine several small images together, to assemble a bigger one. The Offsets stored in the meta-frame allow positioning the images to properly assemble them. The animations refer to each meta frame, even single ones, as a meta-frame group, via index. The location of the first meta-frame of a group is stored in the Meta-Frame Groups Reference Table.
Image Data
The actual images are stored as pixel strips, followed with an assembly table. The table contains a list of entries indicating how to rebuild the image. The main reason the images are stored that way seems to be to remove needless zeroes that normally make the bulk of most images. The table indicates in what order to insert either a pixel strip of a certain length, or to insert the specified amount of zeroes. All the lengths of the strips of pixels, or the amount of zero to insert is always divisible by 16.
The format of the image data can be either 4 bpp or 8bpp, as indicated in the WAN Header.
Animations
Each animation is made up of 3 things, a group, some sequences, and some frames.
The groups itself is the "handle" of the animation. You can label them with an action, like "Run" for example. For character sprites(non-character sprites or special sprites follow different rules), each groups has 8 slots, each slot refers to a sequence. One for each of the 8 directions of movement. Groups may refer to the same sequence in all their slots.
In character sprites, specific groups across all sprites/characters of the same type, have all the same use. For example, all character sprites' first group in the list is always the running animation!
Each sequence is a list of animation frames one after the other, terminated with a null frame. Each frames contains a display duration, the index of the meta-frame group to be displayed, an offset to move slightly the image relative to the logical center of the sprite, and an offset for the shadow blob displayed under the character.
Particle Offsets
Not much is known about those. They're a very long list of 16 bits signed integers, meant to be read 2 by 2. They indicate the offset to display particles, like sweat drops, along with exclamation marks and etc..
For now, its unknown how the game knows which is the correct one to pick for what.
Color Data
This contains the palette used by all the images in the sprite. It also contains details as to where to store the palette in video memory.
Still not much is known about how exactly it all works, besides the actual color palette.
Overview
Here's an overview of how a WAN file is laid out.
Offset | Length | Name | Description |
---|---|---|---|
0x00 | 16 | SIR0 Header | The SIR0 container's header. The first pointer points to the WAN Header. The second to the SIR0 Encoded Pointer Offsets List. |
0x10 | Varies | Meta-Frame Groups Block | This contains all the meta-frames groups. |
After Meta-Frame Groups Block | Varies | Animation Sequences Block | Contains all the animation sequences, and the frames that makes them up. |
After Animation Sequences Block | Varies | 0xAA Padding Bytes (If needed) | Some padding to align the next block on an offset divisible by 4. |
After Padding Bytes | Varies | Image Data Block | Contains all the image data. |
After Image Data Block | Varies | Color Data Block | Contains the palette, along with some other color information. |
After Color Data Block | Varies | Meta-Frames Reference Table | A list of 4 bytes pointers, containing the offset of the first meta-frame of every meta-frame groups located inside the Meta-Frame Groups Block. |
After Meta-Frames Reference Table | Varies | Particle Offset Table | A list of made of pairs of 16 bits signed integers indicating offsets to display particle effects at. |
After Particle Offset Table | Varies | Animation Groups' Sequences Reference Table | Several lists of 4 bytes pointers to animation sequences inside the Animation Sequences Block. Each list is pointed to by an entry in the Animation Groups Table. |
After Animation Groups' Sequences Reference Table | Varies | Animation Groups Table | A list made up of a pair of 32 bits integers, one a pointer to a list of sequence in Animation Groups' Sequences Reference Table, the other a number indicating the length of that list. |
After Animation Groups Table | Varies | Image Data Pointer Table | A list of 4 bytes pointers to the assembly table of every images in the Image Data Block. |
After Image Data Pointer Table | Varies | Animation Info Structure | Contains info on, and pointers to the animation data. |
After Animation Info Structure | Varies | Image Info Structure | Contains info on, and pointers to the Image Data Pointer Table, and Color Data Block. |
After Image Info Structure | Varies | WAN Header | Contains 2 pointers to the the 2 structures above, along with a boolean indicating whether this is a prop, or an 8 way animated sprite. |
After WAN Header | Varies | 0xAA Padding Bytes (If needed) | Some padding bytes to make sure the next block starts on an offset divisible by 16. |
After Padding Bytes | Varies | SIR0 Encoded Pointer Offsets List | A compressed list of every pointer pointer offsets in the file. Used to translate file-relative pointers to NDS memory relative pointers. |
After SIR0 Encoded Pointer Offsets List | Varies | 0xAA End Of File Padding Bytes (If needed) | Some padding bytes to make sure the file ends on an offset divisible by 16. |