Everything is little-endian
Header:
struct bar_header_t {
uint8_t file_type; // always 0x11
uint8_t padding; // zero byte for alignment
uint16_t version; // format version
uint16_t oldest_version; // ?, minimum compatible format version?
uint16_t num_map_entries;
uint32_t offset_to_map;
uint32_t map_size;
uint32_t offset_to_offsets;
uint32_t num_offsets;
uint32_t offset_to_rsc_data;
uint32_t rsc_data_size;
} header;
Right after the header (header.offset_to_map
points into there) there's resource list (header.num_map_entries
entries, total size is in header.map_size
, one entry can describe multiple resources of same type with sequential IDs)
struct bar_map_entry_t {
uint16_t resource_type; // resource types. values (RESTYPE_*) can be found in the SDK in AEEShell.h
uint16_t first_id; // ID of the first resource described in the entry
uint16_t add_ids; // amount of additional IDs allocated right after first_id that are described by the same record
uint16_t offset_table_idx; // index of the offset of first resource data (see below), the rest of the offsets are right after the one this entry points to
};
Right after that list, at header.offset_to_offsets
, there's offset table (array of num_offsets
uint32
s). It seems that it should be always sorted in ascending order. Resource size is defined by difference between current and next offset (or offset_to_rsc_data + rsc_data_size - offset
, if it's the last resource)
Right after the offset list, at header.offset_to_rsc_data
, there're resources themselves (total size is header.rsc_data_size).
Information on common resource types can be found in AEEShell.h from SDK, including the internal structure.
enum {
RESTYPE_STRING = 1, // string resource
RESTYPE_IMAGE = 6, // binary file resource (there's tiny header in the beginning, see below)
RESTYPE_DIALOG = 0x2000, // misc resources related to GUI (structure unknown)
RESTYPE_CONTROL= 0x2001,
RESTYPE_LISTITEM=0x2002,
RESTYPE_BINARY = 0x5000 // custom resource (used, for example, in *.mif files (yes, they're BARs too))
};
typedef struct AEEResBlob
{
byte bDataOffset; /* how far into the Blob the real data starts */
byte bZero; /* always zero, is padding in 1.x BREW */
char szMimeType[1]; /* null-terminated string (not just [1]) mimetype,
can be up to 249 characters in length */
} AEEResBlob;
one or two bytes specify the charset:
FF FE - UTF-16LE
03 - Latin-1
02 - UTF-8
FD FE - Shift_Jis
FE FE - EUC-KR
FC - EUC-CN
FA - ASCII?
04 - ISO-8859-8
05 - GSM 03.38
06 - ???