Talk:BRRES Index Group (File Format)
Meaning of entry values
Does anyone know more about ID, left and right index? My tools can now list and extract BRRES files, but for creating I must know how to calculate them. Here is an example for discussion:
- File Race/Course/ridgehighway_course.szs -> course_model.brres
idx ID ? left right name data magic name ------------------------------------------------------------------------------- 0: ffff 0 f 0 0 0 - 1: 66 0 9 5 3be0f4 866b8 TEX0 ef_arrowBumpS 2: 5c 0 2 1 3be108 876f8 TEX0 ef_arrowGradS 3: 56 0 14 a 3be130 87f38 TEX0 ef_prj_glow 4: 6d 0 1 4 3be140 88f78 TEX0 ef_rainbowRed2 5: 65 0 2 5 3be160 891b8 TEX0 ef_wave1P_Mip 6: 6e 0 4 7 3be174 8a6f8 TEX0 ef_wave_indMip 7: 6a 0 1c 7 3bdc3c 8d138 TEX0 ETC_DenkouTubu 8: 95 0 10 8 3bdc50 8fc58 TEX0 ETC_Kanban_00_mod01 9: 5e 0 3 12 3bdec0 a5098 TEX0 Mi_LightMask a: 54 0 11 3 3bde3c a90d8 TEX0 M_bill_merg b: 7e 0 d 1e 3bde4c b9118 TEX0 M_bill_merg_mask c: 52 0 c 1d 3bdd38 c1158 TEX0 M_EnkeiYama d: 76 0 6 13 3bdd48 d1198 TEX0 M_IwaKabe00_mip e: 3e 0 20 e 3bde64 e65d8 TEX0 M_jyukai f: 96 0 8 f 3bdd5c 1110d8 TEX0 M_Kanban2_mod01_mip 10: 8e 0 b 10 3bdd74 166118 TEX0 M_Kanban_mod01_mip 11: 53 0 c 11 3bdd8c 2ba158 TEX0 M_KasanDash 12: 5d 0 12 16 3bddac 2be198 TEX0 M_Kirakira_A 13: 74 0 13 d 3bddc0 2ce1d8 TEX0 M_Kirakira_mask 14: 4e 0 18 14 3bdd9c 2ce618 TEX0 M_Ki_enkei 15: 2e 0 0 17 3bde74 2d0658 TEX0 M_kusa 16: 5b 0 16 9 3bddd4 2db158 TEX0 M_NoboriKabe 17: 2b 0 1f 17 3bdde8 2f0598 TEX0 M_Nuki 18: 45 0 e 1a 3bde80 3059d8 TEX0 M_road_00 19: 40 0 18 21 3bde90 31aff8 TEX0 M_road_01 1a: 41 0 19 1b 3bdea0 330618 TEX0 M_road_02 1b: 40 0 22 1b 3bdeb0 345c38 TEX0 M_road_03 1c: 5d 0 6 1c 3bddf4 347218 TEX0 M_TubeRoof_mip 1d: 51 0 1d a 3bde08 371a58 TEX0 M_TuchiRoad 1e: 7c 0 b 1e 3bde18 379a98 TEX0 M_WallMerg00_mip 1f: 24 0 1f 15 3bde30 38ead8 TEX0 M_Yama 20: 3d 0 15 20 3be3f0 3995d8 TEX0 wl_tire2 21: 35 0 19 21 3be02c 3b9618 TEX0 WT_taki01 22: 35 0 1a 22 3be03c 3bb658 TEX0 WT_taki02
Wiimm 15:53, 8 April 2011 (CEST)
- I haven't yet finished working them out. Brawl box has a working implementation.
- Chadderz 20:51, 8 April 2011 (CEST)
Coding Example of BrawlTools
public static void Build(ResourceGroup* group, int index, VoidPtr dataAddress, BRESString* pString) { ResourceEntry* list = &group->_first; ResourceEntry* entry = &list[index]; ResourceEntry* prev = &list[0], current = &list[prev->_leftIndex]; ushort currentIndex = prev->_leftIndex; bool isRight = false; int strLen = pString->_length; byte* pChar = (byte*)pString + 4, sChar; int eIndex = strLen - 1, eBits = pChar[eIndex].CompareBits(0), val; *entry = new ResourceEntry((eIndex << 3) | eBits, index, index, (int)dataAddress - (int)group, (int)pChar - (int)group); //Continue while the previous id is greater than the current. // Loop backs will stop the processing. //Continue while the entry id is less than or equal the current id. // Being higher than the current id means we've found a place to insert. while ((entry->_id <= current->_id) && (prev->_id > current->_id)) { if (entry->_id == current->_id) { sChar = (byte*)group + current->_stringOffset; //Rebuild new id relative to current entry for (eIndex = strLen; (eIndex-- > 0) && (pChar[eIndex] == sChar[eIndex]); ) ; eBits = pChar[eIndex].CompareBits(sChar[eIndex]); entry->_id = (ushort)((eIndex << 3) | eBits); if (((sChar[eIndex] >> eBits) & 1) != 0) { entry->_leftIndex = (ushort)index; entry->_rightIndex = currentIndex; } else { entry->_leftIndex = currentIndex; entry->_rightIndex = (ushort)index; } } //Is entry to the right or left of current? isRight = ((val = current->_id >> 3) < strLen) && (((pChar[val] >> (current->_id & 7)) & 1) != 0); prev = current; current = &list[currentIndex = (isRight) ? current->_rightIndex : current->_leftIndex]; } sChar = (current->_stringOffset == 0) ? null : (byte*)group + current->_stringOffset; val = sChar == null ? 0 : (int)(*(bint*)(sChar - 4)); if ((val == strLen) && (((sChar[eIndex] >> eBits) & 1) != 0)) entry->_rightIndex = currentIndex; else entry->_leftIndex = currentIndex; if (isRight) prev->_rightIndex = (ushort)index; else prev->_leftIndex = (ushort)index; }
This is the CompareBits() function: it find out the highest different bit and returns the bit number (0..7):
public static int CompareBits(this Byte b1, byte b2) { for (int i = 8, b = 0x80; i-- != 0; b >>= 1) if ((b1 & b) != (b2 & b)) return i; return 0; }
(In my eyes) it could be written a little bit clearer (not knowing if this language supports the ^ operator:
public static int CompareBits(this Byte b1, byte b2) { b1 ^= b2; // and now find the highest set bit for ( int i = 7; i > 0 && !(b1&0x80); i--, b1 <<= 1 ) ; return i; }
Wiimms code snippets
Here is my first code snippet to calculate the ID. I have done some empirical tests and it seems to work:
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; } typedef const char * ccp; static u16 calc_brres_id ( ccp prev_name, uint prev_len, ccp cur_name, uint cur_len ) { if ( prev_len < cur_len ) return cur_len - 1 << 3 | get_highest_bit(cur_name[cur_len-1]); while ( cur_len-- > 0 ) { const u8 ch = prev_name[cur_len] ^ cur_name[cur_len]; if (ch) return cur_len << 3 | get_highest_bit(ch); } return ~(u16)0; }
Names
I'm starting to get more information about brres files but I'm stuck at generating the id, as in I don't actually get where the filename (subject) and another filename (object) are stored in a brres. The code examples don't seem to give an answer to me.
kHacker35000vr 20:16, 5 April 2012 (CEST)
- It's hard stuff and coding experience may help to understand´d it. Here is my code version:http://opensvn.wiimm.de/viewvc/wii/trunk/wiimms-szs-tools/src/lib-brres.c?view=annotate#l305
- It's only a little bit different, but maybe a little bit alternative implementation may help.
- Wiimm 21:38, 5 April 2012 (CEST)