Nintendo DS File Formats

Note: All the contents of this article are entirely copied from http://llref.emutalk.net/nds_formats.htm for archival purpose. *1

Sections
  • Generic Header Format
  • Graphic File Formats
  • Archive File Formats
  • Sound File Formats
  • Custom File Formats
  • Compression Formats

Generic Header Format

Offset Length Name Description
0x0 0x4 Magic ID Identifies the file format.
0x4 0x4 Constant Always (0xFFFE0001)
0x8 0x4 Section Size Size of this section, including the header.
0xC 0x2 Header Size Size of this header. (Should always equal 0x10)
0xE 0x2 Number of Sections The number of sub-sections in this section.

Graphic File Formats

Nintendo Tile Format Palette (NTFP)
Offset Length Name Description
DATA 0x2 Palette Color Format is BGR555 (XBBBBBGGGGGRRRRR).
Nintendo Tile Format Tile (NTFT)
Offset Length Name Description
DATA 8Bits or 4Bits Tile Data Indexes to colors in a palette.
Nintendo Tile Format Screen (NTFS)
Offset Length Name Description
DATA 0x2 Screen Data Indexes to a tile.
Format is (YYYYXXNNNNNNNNNN)
Y4 Palette Number
X2 Transformation (YFlip/XFlip)
N10 Tile Number
Nintendo Color Resource (NCLR/RLCN)
  • uses Generic Header
  • magic ID is #RLCN (0x524C434E)
  • contains 2 sub-sections
#1 Section - Palette Data (TTLP)
Offset Length Name Description
0x0 0x4 Magic ID #TTLP (0x54544C50)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Palette Bit Depth 3 = 4 Bits
4 = 8 Bits
0xC 0x4 Padding? Always ( 0x000000)
0x10 0x4 Palette Data Size Size of Palette Data in bytes.
if (0x200-size > 0) then size = 0x200-size
also if the bit depth is 8 palette is 0x200
0x14 0x4 Colors Per Palette Probably always (16 colors).
DATA Palette Data stored as NTFP
#2 Section - Palette Count Map? (PMCP)
Offset Length Name Description
0x0 0x4 Magic ID #PMCP (0x504D4350)
0x4 0x4 Section Size Should always be (0x12).
0x8 0x2 Palette Count Number of palettes in file.
0xA 0x6 Unknown Always (0xEFBE080000)
DATA 0x2 Palette ID Simple ID number for each palette (starting from 0x0).
Nintendo Character Graphic Resource (NCGR/RGCN)
  • uses Generic Header
  • magic ID is #RGCN (0x5247434E)
  • contains 2 sub-sections
#1 Section - Character Data (RAHC)
Offset Length Name Description
0x0 0x4 Magic ID #RAHC (0x52414843)
0x4 0x1 Header Size Should always be (0x20)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x2 Tile Count Multiplied by 1024 gets the total number of pixels in the file.
0xA 0x2 Tile Size Always (0x20)
0xC 0x4 Tile Bit Depth 3 = 4 Bits
4 = 8 Bits
0x10 0x8 Padding? Always (0x0)
0x18 0x4 Tile Data Size Divided by 1024 should equal Tile Count.
0x1C 0x4 Unknown Always (0x24)
DATA Tile Data stored as NTFT
#2 Section - (SOPC)
Offset Length Name Description
0x0 0x4 Magic ID #SOPC (0x534F5043)
0x4 0x4 Section Size Should always be (0x10)
0x8 0x4 Padding Always (0x0)
0xC 0x2 Tile Size? Always (0x20)
0xE 0x2 Tile Count Is always identical to Tile Count in #1 Section.
Nintendo Screen Resource (NSCR/RCSN)
  • uses Generic Header
  • magic ID is #RCSN (0x5243534E)
  • contains only 1 sub-section
#1 Section - Screen Data (NRCS)
Offset Length Name Description
0x0 0x4 Magic ID #NRCS (0x4E524353)
0x4 0x1 Header Size Should always be (0x14)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x2 Screen Width Value is in pixels.
0xA 0x2 Screen Height Value is in pixels.
0xC 0x4 Padding Always (0x0)
0x10 0x4 Screen Data Size
DATA Screen Data stored as NTFS
Nintendo Animation Resource (NANR/RNAN)
  • uses Generic Header
  • magic ID is #RNAN (0x?)
  • contains 3 sub-sections
#1 Section - Animation Bank (KNBA)
Offset Length Name Description
0x0 0x4 Magic ID #KNBA (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x2 Number of Animations Each animation is 16 bytes.
0xA 0x2 Frame Count Each frame is 8 bytes.
0xC 0x4 Unknown Constant
0x10 0x4 Unknown
0x14 0x4 Unknown Size
0x18 0x8 Padding (Always 0x0)
DATA Animation Blocks
0x0 0x4 Number of Frames
0x4 0x2 Unknown
0x6 0x2 Unknown Always (0x1)
0x8 0x4 Unknown
0xC 0x4 First Frame Offset RELATIVE to the end of this section.
DATA Frame Blocks
0x4 Unknown Offset
0x2 Frame Width
0x2 Unknown Always (0xBEEF)
DATA Frame Data
Nintendo CEII Resource (NCER/RECN)
  • uses Generic Header
  • magic ID is #RECN (0x5245434E)
  • contains 3 sub-sections
#1 Section - CEII Bank (KBEC)
Offset Length Name Description
0x0 0x4 Magic ID #KBEC (0x4B424543)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Number of Images
0xC 0x4 Unknown Always (0x12)
0x10 0x4 Boundary Size Specifies the the area in which the image can be drawn multiplied by 64.
ie a boundary size of 2 means that the area is 128x128 pixels.
0x14 0x12 Padding Always (0x0)
DATA Cell Table (8 bytes each)
0x0 0x2 Number of Cells The number of cells that make up an image.
0x2 0x2 Unknown
0x4 0x4 Cell Data Offset This offset is RELATIVE to the end of the Cell Table.
DATA Cell Data (Starts at Number of Cells * 8 | each cell is made up of 6 bytes)
0x0 0x1 Row Data Format is (RRY1Y2??)
RR = Row (Note that the row order is 2, 3, 0, 1)
Y1 = Y Offset from the top of the row. (Multiplied by 16)
Y2 = Y Offset from the top of the row. (Multiplied by 4)
0x1 0x1 Cell Width Format is (WW????FF)
WW = Width of the cell.
FF = Vertical Flag (Not sure if this is used or not).
0x2 0x1 Column Data Format is (CCX1X2??)
CC = Column (Note that the column order is 2, 3, 0, 1)
X1 = X Offset from the top of the row. (Multiplied by 16)
X2 = X Offset from the top of the row. (Multiplied by 4)
0x3 0x1 Cell Height Format is (HH????FF)
HH = Height of the cell.
FF = Horizontal flag.

Rows/Columns:

Row/Column are numbered like that because for regular images, they shouldn't exceed the size of 0 & 1 (128x128 pixels), the frist two rows/columns are meant for larger images up to 256x256 pixels).

The height and width of the cell is determined by referencing to 2D array. I am yet to find any cells that use nodes with ??.

  Height
Width   00 01 10 11
00 8x8 16x16 32x32 64x64
01 16x8 32x8 32x16 64x32
10 8x16 8x32 16x32 32x64
11 ?? ?? ?? ??

So if a cell has a WW of 0 and a HH of 3 it's size is 64x64.

X & Y Offsets:
I am not sure if the Y Offset is affected in the same way, but if the position of a cell is within the far right column and the FF (Flag) value is equal to 1. The offset is subtracted by 256.

0x4 0x2 Tile Offset The offset into the tile data where this cell starts.

The last two sections of both files use the same format.

#2 Section - Animation Label (LABL)
Offset Length Name Description
0x0 0x4 Magic ID #LBAL (0x4C42414C)
0x4 0x4 Section Size Size of this section, including the header.
DATA
0x8 0x4 Label Offset
DATA
Label Name Terminated by (0x0)
#3 Section - (TXEU)
Offset Length Name Description
0x0 0x4 Magic ID #TXEU (0x54584555)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Unknown 0 or 1

Archive File Formats

Nintendo Archive (ARC/NARC)
  • uses Generic Header
  • magic ID is #NARC (0x4E415243)
  • contains 3 sub-sections
#1 Section - File Allocation Table (BTAF)
Offset Length Name Description
0x0 0x4 Magic ID #BTAF (0x42544146)
0x4 0x1 Header Size
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Number of Files The number of files in the archive.
DATA See below.
0xC 0x4 Start Offset Is RELATIVE to the GMIF section start offset.
0x10 0x4 End Offset Is RELATIVE to the GMIF section start offset.
#2 Section - File Name Table (BTNF)
Offset Length Name Description
0x0 0x4 Magic ID #BTNF (0x42544E46)
0x4 0x4 Section Size Size of this section, including the header.
DATA Directory Table
0x4 Directory Start Offset All other offsets are RELATIVE to the first directory start offset which is the root folder.
0x2 First File Position
0x2 Directory Count / Parent Directory For the root folder it has the total number of directories in the archive, and the latter for everything else.
DATA Name Table
0x1 Size of Name The first bit specifies whether it is a file or a folder.
0xLENGTH Name String
EXTRA 0x2 Directory ID The number reference of that directory.
#3 Section - File Image (GMIF)
Offset Length Name Description
0x0 0x4 Magic ID #GMIF (0x474D4946)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Compression ID #LZ77 (0x4C5A3737)
Indicates that the file data is compressed.

Sound File Formats

Sound Data File (SDAT)
  • uses Generic Header
  • magic ID is #SDAT (0x53444154)
  • contains 4 sub-sections
Section Offsets
Offset Length Name Description
0x0 0x4 SYMB Offset Offset to SYMB Section
0x4 0x4 SYMB Size Size of SYMB Section
0x8 0x4 INFO Offset Offset to INFO Section
0xC 0x4 INFO Size Size of INFO Section
0x10 0x4 FAT Offset Offset to FAT Section
0x14 0x4 FAT Size Size of FAT Section
0x18 0x4 FILE Offset Offset to FILE Section
0x1C 0x4 FILE Size Size of FILE Section
0x20 0x16 Padding
#1 Section - (SYMB)
Offset Length Name Description
0x0 0x4 Magic ID #SYMB (0x53594D42)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Sequences Offset
0xC 0x4 Sound Effects Offset
0x10 0x4 Banks Offset
0x14 0x4 Waves Offset
0x18 0x4 Players Offset
0x1C 0x4 Groups Offset
0x20 0x4 Streams Offset
0x24 0x4 Unknown Offset
0x28 0x24 Padding
DATA
0x40 0x4 Number of Files The number of files in this section
0x44 0x4 Filename Offset Offset is RELATIVE to each section offset
#2 Section - Information (INFO)
Offset Length Name Description
0x0 0x4 Magic ID #INFO (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Sequences Offset
0xC 0x4 Sound Effects Offset
0x10 0x4 Banks Offset
0x14 0x4 Waves Offset
0x18 0x4 Players Offset
0x1C 0x4 Groups Offset
0x20 0x4 Streams Offset
0x24 0x4 Unknown Offset
0x28 0x24 Padding
DATA
0x4 Number of Elements
0x4 Offset to First Element
0x4 ID of Current Element
0x8 Sequences Variables
0x8 Banks Variables
0x8 Players Variables
0x8 Groups Variables
#3 Section - FIle Allocation Table (FAT)
Offset Length Name Description
0x0 0x4 Magic ID #FAT (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Number of Files
DATA FAT Table (Repeats)
0x4 File Offset
0x4 File Size
0x8 Unknown
#4 Section - File Data (FILE)
Offset Length Name Description
0x0 0x4 Magic ID #FILE (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Number of Files
0xC 0x4 Unknown
Sound Sequence (SSEQ)
  • uses Generic Header
  • magic ID is #SSEQ (0x?)
  • contains only one section?
#1 Section - Sequence Data (DATA)
Offset Length Name Description
0x0 0x4 Magic ID #DATA (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Start Offset The offset to where the notation data begins.
0xC 0x3 Track Description (Command)
DATA (Track Reference which repeats for the number of tracks)
0x4 Open Track (Command) Fist bytes is the command code, second byte is the track number, and the last 2 bytes are the track offet.
DATA
0x3 Set Mono/Poly (Command)
0x3 Set Tempo (Command)
Sequence Commands
Code Value Length Name Description
0x00 - 0x7F 0x2 Music Note Format is (0xVVDD)
V2 = Velocity
D2 = Duration
0x80 0x1 Rest Note Duration of rest note.
0x81 0x1 Change Instrument Instrument number to change to.
0x93 0x4 Open Track Format is (0xAABBBBBB)
A2 = Track number
B6 = Track offset (RELATIVE to the start offset)
0x94 0x3 Jump Move to postion in the track and loop.
0x95 0x3 Call Move to the start of another track.
0xC0 0x1 Channel Panning Set panning value (-128 to 127)
0xC1 0x1 Channel Volume Set volume
0xC2 0x1 Global Volume Set the sequence volume
0xC3 0x1 Transpose
0xC4 0x1 Portamento
0xC5 0x1 Portamento Range
0xC6 0x1 Priority Set the priority of the track.
0xC7 0x1 Mono / Poly Set the phonie
0 = Polyphonie
1 = Monophonie
0xCA 0x1 Vibrato Depth
0xCB 0x1 Vibrato Speed
0xE1 0x1 Tempo Set the tempo.
0xFD 0x0 Return Return from the previous "Call" command.
0xFE 0x2 Track Description Number of tracks and their position.
0xFF 0x0 End End of the track.
Sound Sequence Archive (SSAR)
  • uses Generic Header
  • magic ID is #SSAR (0x?)
  • contains only 1 section
#1 Section - Data (DATA)
Offset Length Name Description
0x0 0x4 Magic ID #DATA (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x4 Unknown Offset
0xC 0x4 Number of elements
0x10 0x4 Padding Always (0x0)
DATA
0x8 Unknown
0x4 Data Offset RELATIVE to Unknown Offset
DATA Actual Data
Sound Wave Archive (SWAR)
  • uses Generic Header
  • magic ID is #SWAR (0x?)
  • contains only 1 section
#1 Section - Data (DATA)
Offset Length Name Description
0x0 0x4 Magic ID #DATA (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x32 Unknown
0x28 0x4 Number of Files
DATA Repeats by Number of Files.
0x2C 0x4 Wave Offset RELATIVE to the start of the file.
DATA Data at Wave Offset.
0x0 0x1 Wave Type 0 = PCM 8Bit
1 = PCM 16Bit
2 = ADPCM
0x1 0x1 Loop Support 0 = False
1 = True
0x2 0x2 Sample Rate
0x4 0x2 Duration
0x6 0x2 Loop Start Multiply by 4.
0x8 0x4 Loop Length Multiply by 4.
DATA Wave Data
Sound Bank (SBNK)
  • uses Generic Header
  • magic ID is #SBNK (0x?)
  • contains only 1 section
#1 Section - Data (DATA)
Offset Length Name Description
0x0 0x4 Magic ID #DATA (0x?)
0x4 0x4 Section Size Size of this section, including the header.
0x8 0x32 Unknown
0x28 0x4 Number of Samples
0x2C 0x1 Unknown Type
DATA
0x2D 0x3 Data Offset RELATIVE to the start of the file.
DATA Sample Data
0x0 0x2 Sample Number
0x2 0x? Unknown Flag

Custom File Formats

Package File (PAK)
  • found in Digimon Games
  • groups files (ie Palette/Graphic/Animation) either in separate PAK files for each type, or in a single file with each file in an ordered manner
  • no filenames so referencing should be done by the index in the offset table (see below)
  • each file is compressed
Section Offsets
Offset Length Name Description
0x0 0x4 Number of Files
DATA
0x4 File Start Offset
0x4 File Size

PAK5 Files

  • known file formats with a custom 5 byte header added before the start of the normal file format
  • found in PAK files and files in the normal file system of Digimon Games (named using a combination of a hex number and letter representing what format the file contains)

Compression Formats

Files may be stored using a variety of different compression formats including LZ77, Huffman and RLUncomp. Because there's a real lack of good easy to understand documentation on it (and trust me I know in order to be able to write this), I'm going to write my interpretations here.

Generally the filenames of files will indicate whether or not they are compressed, but otherwise you have to guess it on your own. For starters if while looking at a file in a Hex Editor, the first 5 Bytes are then followed by a Magic ID, then it is almost guaranteed to be a compressed known file format, and this is where documentation helps!

So first off we have a look at the first 4 Bytes or rather first 32 Bits, keeping in mind that the Nintendo DS works from right to left (Least Significant to Most Significant), which is Little Endian if you aren't very familiar with stuff like that.

Compression Header (Same for all types)
Offset (Bits) Length (Bits) Name Description
0x0 0x4 Reserved / Compression Size Should always be (0x0) unless Compression Type is Huffman, in which case this specifies the Compression Size.
0x4 0x4 Compression Type Specifies what type of compression is used.
1 = LZ77
2 = Huffman
3 = RLUncomp
0x8 0x24 Decompressed File Size The size the file will be after being decompressed.

After the header comes the compressed data, and depending on what Compression Type it is will affect how it is stored.

#1 Type - LZ77 Compression
Offset (Bits) Length (Bits) Name Description
0x0 0x8 Flag Each Bit tells if the corresponding Block of Data is compressed or uncompressed.
0 = Uncompressed
1 = Compressed
0x8 Uncompressed Data No decompression needed, single byte can be copied to the end of the place where the decompressed file is being stored.
0x16 Compressed Reference Format is (MMMMNNNNLLLLLLLL)
M4 = Most significant Bits
N4 = Number of Bytes to be copied
L8 = Least significant Bits

Copy Offset = (L8 | M4 << 8) +1

So when the decompressor finds a compressed block, it copies N+3 Bytes from the current position in the decompressed file minus the Copy Offset.
example:

data = getBytes ( Data:decompressedData , Offset:currentOffset-copyOffset , Length:copyCount );

An important thing to note is that if the Copy Count greater than the distance between the Copy Offset and the Current Offset in the decompressed file, the data is repeatedly copied until it matches the Copy Count. This will often occur when the compressed data has the same value.

#2 Type - Huffman Compression

(No notes were written)

#3 Type - RL Compression
Offset (Bits) Length (Bits) Name Description
0x0 0x7 Expanded Length / Copy Count If the Flag is 0 this specifies how many bytes after the flag are copied to where the decompressed file is being stored.
Otherwise it specifies how many times the next byte is copied to where the decompressed file is being stored.
0x7 0x1 Flag 0 = Uncompressed (Add 1 to the Copy Count)
1 = Compressed (Add 3 to the Expanded Length)

This is much simpler than the other two formats as you are only copying bytes from the source file to the decompressed file.

*1:The server was dead when I found the site... oh well