.brres

A Binary Revolution Resource (.brres) file is a resource package used in games such as New Super Mario Bros. Wii and Mario Kart Wii that is similar to a Wii U8 Archive. They can contain multiple resources in one single file, hence why it's a resource package. Common resources found in a BRRES file are models, textures, animations, and color palettes for CI4 and CI8 textures.

Opening a BRRES file
Tools such as BrawlBox are able to open and modify BRRES files.

=General Information= Below is a layout of a Mario Kart Wii BRRES file.

Header
The file begins with the header. It is a 0x10 structure as follows:

Root
The root section of the brres file contains all pointers to files and filenames. The header of the root is 0x8 in length.

This header is then followed by a BRRES Index Group. The entries in this group are the folders of this brres file, and point to more BRRES Index Groups within the root section. These then point to the actual sections of the BRRES file.

Others
Other BRRES sections tend to be within specific folders, as set out by the root section. The identifiers of these sections, as well as the normal folder and a description are listed below. BRRES Files contain only a few file formats, they are:

String Table
At the end of the BRRES file is a string table. This is a series of 4-byte length prefixed strings, padded to start at four byte offsets. Various sections point to this table, which is how all text in BRRES files is stored.

=GNU C header example=

typedef struct brres_header_t {   char  magic[4];            // = string "bres" u16  bom;                 // byte order mark // the data is 'bom' dependent big or little endian u16  bom_padding;         // usally 0 u32  size;                // file size u16  root_off;            // offset of root section u16  n_sections;          // number of sections } __attribute__ ((packed)) brres_header_t;

typedef struct brres_entry_t {   u16   id;                  // entry id    u16   unknown;             // always 0? u16  left_idx;            // index to left element in virtual tree u16  right_idx;           // index to right element in virtual tree u32  name_off;            // offset into string table u32  data_off;            // offset to data } __attribute__ ((packed)) brres_entry_t;

typedef struct brres_group_t {   u32            size;       // size of complete group u32           n_entries;  // number of entires brres_entry_t entry[0];   // list of entries, N := 1 + n_entries // entry with index #0 is a special // root node not counting in 'n_entries' } __attribute__ ((packed)) brres_group_t;

typedef struct brres_root_t {   char           magic[4];   // = string "root" u32           size;       // size of complete header brres_group_t group[0];   // first group } __attribute__ ((packed)) brres_root_t;

Overview
The BRRES Index Group is a data structure that occurs very often within BRRES files and sections of BRRES. It can be used to point to more BRRES Index Groups in order to allow folder structure, as in the root section. It has a 0x08 byte header, as follows.

Calculation of the ID
The ID is calculated by comparing a filename (subject) to an other filename (object) using the following algorithm: Initially the subject filename is compared with the the root filename, which is always empty. If an ID with the same value is found while walking through the tree, then a new ID is calculated using the other filename as object.
 * 1) Find the last non equal character of both names and store the INDEX.
 * 2) If the length of the subject filename is greater than the length of the object filename, INDEX is the length of the subject filename minus 1.
 * 3) Otherwise compare each pair of characters until a difference is found.
 * 4) Now compare both characters of position INDEX and find the highest bit that is not equal. If INDEX exceeds the length of object, assume character value 0. Store the bit index (7 for 0x80 .. 0 for 0x01) as BITNUM.
 * 5) Calculate:  

GNU C example
This example is taken from Wiimms SZS Tools, file lib.szs.c: typedef const char * ccp; typedef unsigned int uint; typedef unsigned char u8; typedef u_int16_t    u16;

static u16 get_highest_bit ( u8 val ) {   // 2do: use a lookup table if this is time critical u16 i;   for ( i = 7; i > 0 && !( val & 0x80 ); i--, val <<= 1 ) ;   return i; }

static u16 calc_brres_id (   ccp  object_name,    uint object_len,    ccp  subject_name,    uint subject_len ) {   if ( object_len < subject_len ) return subject_len - 1 << 3 | get_highest_bit(subject_name[subject_len-1]);

while ( subject_len-- > 0 ) {       const u8 ch = object_name[subject_len] ^ subject_name[subject_len]; if (ch) return subject_len << 3 | get_highest_bit(ch); }

return ~(u16)0; }

Calculation of left and right index
The left and right indexes are calculated with an iterative algorithm. Each element is inserted into the tree by traversing the virtual tree. As described above, the ID represents the last different bit of 2 strings. The status of this last bit decides if following the left (bit is cleared) or the right (bit is set) sub tree. For details see the following GNU C example.

GNU C example
This example is taken from Wiimms SZS Tools, file lib.szs.c: typedef struct brres_info_t {   u16  id;          // id    u16  left_idx;    // left index u16 right_idx;   // right index ccp name;        // pointer to name uint nlen;       // lenght of name

} brres_info_t;

static bool get_brres_id_bit (   brres_info_t * info,    u16 id ) {   ASSERT(info); const uint char_idx = id >> 3; return char_idx < info->nlen && info->name[char_idx] >> ( id & 7 ) & 1; }

static void calc_brres_entry (   brres_info_t  * info,    uint          entry_idx ) {   ASSERT(info);

// setup 'entry' : item to insert brres_info_t * entry = info + entry_idx; entry->id = calc_brres_id(0,0,entry->name,entry->nlen); entry->left_idx = entry->right_idx = entry_idx;

// setup 'prev' : the previuos 'current' item brres_info_t * prev = info;

// setup 'current' : the current item whule walking through the tree uint current_idx = prev->left_idx; brres_info_t * current = info + current_idx;

// last direction bool is_right = false;

while ( entry->id <= current->id && current->id < prev->id ) {       if ( entry->id == current->id ) {           // calculate a new entry id            entry->id = calc_brres_id( current->name, current->nlen,                                      entry->name, entry->nlen ); if (get_brres_id_bit(current,entry->id)) {               entry->left_idx  = entry_idx; entry->right_idx = current_idx; }           else {               entry->left_idx  = current_idx; entry->right_idx = entry_idx; }       }

prev = current;

is_right = get_brres_id_bit(entry,current->id); current_idx = is_right ? current->right_idx : current->left_idx; current = info + current_idx; }

if ( current->nlen == entry->nlen && get_brres_id_bit(current,entry->id) ) entry->right_idx = current_idx; else entry->left_idx = current_idx;

if (is_right) prev->right_idx = entry_idx; else prev->left_idx = entry_idx; }

static void calc_brres_entries (   brres_info_t   * info,    uint           n_entries ) {   ASSERT( info ); ASSERT( n_entries > 0 );

// setup root entry info->id = 0xffff; info->left_idx = info->right_idx = 0;

int idx; for ( idx = 0; idx <= n_entries; idx++ ) calc_brres_entry(info,idx); } =Sub files= BRRES files contain many Sub Files. Each of these obeys a similar format.

Preamble
This page contain many statistical information. It is based on a combined DVD created from Mario Kart Wii PAL and NTSC: Summary: If you need more list or want to find files with special content, then download mkw-brres-statistics.zip (1.2MB). It contains different file and sub file lists.
 * All files of Mario Kart Wii/PAL are used.
 * Files only in Mario Kart Wii/NTSC are used too. See &raquo;Filesystem: PAL and NTSC&laquo; for more details.
 * The combined DVD has 1834 SZS files.
 * The combined DVD has 17 BRRES files.
 * If extracting all SZS files, the combined DVD has 4871 BRRES files. This is the test suite for all following statistics.

Common Format
Each file starts with the same header:

The known values for the magic are given below, along with the purpose, and which folder within the BRRES they are in. The Wii ignores the version number, but expects the correct data structure. The section number is one part of the data — if changed, the link to the reference name becomes invalid. This is the reason, that the Wii accepts TEX0 v3 (the standard) and v1: Both share the same data structure with 1 section. Changing the version from v3 to v2 is possible without any impact. But a real TEX0 v2 is not supported, because of the different data structure with 2 sections.
 * Subfiles which SCN0 use
 * Subfiles which SCN0 use
 * Subfiles which SCN0 use

A wrong data structure will freeze the Wii. As of v2.05, Wiimms SZS Tools will warn about wrong section numbers and will print hints about wrong version numbers.

String Pool & Extraction
Nearly all sub files have a directory structure like BRRES files. For this directory structure file names are needed. Most sub files has also some more strings. All these strings of the main BRRES file and of all sub files are stored in common string pool, unique string only once. The string are sorted in ASCII order. The string pool is placed at the end of the BRRES file behind all other data and outside of the sub files.

If extracting only the raw data of a sub file the pointers into the string pool becomes invalid and the names are lost. To avoid this, Chadderz and Wiimm are on the way to define a file format for extracted sub files that includes an local string pool. It is important to understand, that this is not a Nintendo specification!.Wiimms ISO Tools has implemented this since v0.07a.

Strings
For extracting it is also important to find all string positions in the different sub files. The following table is based on a statistical analysis of all BRRES files of the test suite (see &raquo;Preamble&laquo; for details). The table shows the position of pointers into the string table.

The data is divided into 2 tables. The first table is a summary of old sub and not important formats. The second table contains all data needed for geame play.

Old Formats

 * Directory /Race/Course/ files,   ,  ,   and.
 * Directory /Race/Course/Object/ files,  ,  ,  ,  ,  ,   and.