Hacking - DS Generation: NARC File Format

The NARC File Format is the basic archive format for NDS files. Kudos to natrium42 for making the original source of narctool, on which this documentation is based.

The NARC file format is built on top of the Nitro File Format, so that should be understood before continuing. NARC's file magic is "NARC" with a bom of 0xFFFE (so its representation in the file is "NARC", not "CRAN"). NARC files have three frames: FATB, FNTB, and FIMG.

Frames

FATB Frame

The first frame in a NARC file is the FATB frame, which contains the offsets of the beginning and end of all contained files. The FATB frame has a simple sub-header following the standard frame header:

struct fatb_header {
    long num_entries; // Contains the number of files in this NARC file.
};

This header is followed by num_entries structs of the following form representing the beginning and ending offsets of each of the num_entries files.

struct fatb_entry {
    long start; // Contains the start offset of this file
    long end;   // Contains the end offset of this file
};

Implementors seeking to repack NARC files should be aware that start offsets should be on 4-byte boundaries, and space between the beginning and end of files in the FIMG frame should be filled with the byte 0xFF.

FNTB Frame

The second frame in a NARC file is the FNTB frame, which may contain the filenames of all contained files. The FNTB frame has a simple sub-header following the standard frame header:

struct fntb_header {
    long unknown1; // May be 0x00000008 when filenames are present.
                   // Pokémon D/P have this set to 0x00000004 and lack names.
    long unknown2; // Appears to always be 0x00010000.
};

This header is optionally followed by fatb_header.num_entries structs of the following form representing the names of each of the num_entries files (only if (unknown1 == 0x00000008)? If (unknown1 == 0x00000004) there are NOT any filenames).

struct fntb_entry {
    char length; // Contains the length of this filename
    char name[256];   // Not actually 256 characters, but only 'length'.
};

Do NOT read into struct fntb_entry as the actual contents are a single byte length followed by length bytes of the filename.

FIMG Frame

The third and final frame in a NARC file is the FIMG frame, which simply contains all of the files uncompressed and concatenated into one frame. As noted in the notes for the FATB frame, file starts should be aligned to 4-byte boundaries and should be padded between files (if necessary) with 0xFF. Note also that order is most likely important, especially with NARC archives that lack filenames.