From ebb936ebeed92d444b3e7989bc2a92964686e3b6 Mon Sep 17 00:00:00 2001 From: comex Date: Mon, 2 Feb 2009 21:37:16 -0500 Subject: ........... --- ethyl.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++---------- parse-brlyt.py | 55 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 103 insertions(+), 21 deletions(-) diff --git a/ethyl.py b/ethyl.py index 3c6c755..57b9b3b 100644 --- a/ethyl.py +++ b/ethyl.py @@ -63,6 +63,7 @@ formats = { char name[0x14] // 0 s16 tev_color[4] // 14 s16 unkx // 1c + s16 unky // 1e s16 unk5 // 20 s16 unk6 // 22 s16 unk7 // 24 @@ -105,19 +106,44 @@ for (dname, definition) in formats.items(): else: df.append((typ, name, default)) formats[dname] = df, etc, etcn - -def my_repr(b): - if type(b) in (int, long): + +# Dumb pretty printer +def my_repr(b, start=''): + special = lambda x: type(x) not in (int, str, unicode) + if type(b) == dict: + if len(filter(special, b.values())) == 0: + rep = '{ ' + f = False + for a in sorted(b.keys()): + if f: + rep += ', ' + else: + f = True + rep += '%s: %s' % (str(a), my_repr(b[a])) + rep += ' }' + else: + rep = '{\n' + for a in sorted(b.keys()): + c = b[a] + if type(c) in (dict, list): + rep += '%s:\n%s\n' % (str(a), my_repr(c, ' ')) + else: + rep += '%s: %s\n' % ( str(a), my_repr(c)) + rep += '}' + elif type(b) in (int, long): rep = hex(b) elif type(b) in (list, tuple): - rep = '[' + ', '.join(map(my_repr, b)) + ']' + if len(filter(special, b)) == 0: + rep = '[' + ', '.join(map(my_repr, b)) + ']' + else: + rep = '[\n' + rep += ',\n'.join(my_repr(a, ' ') for a in b) + rep += '\n]' else: rep = repr(b) - return rep -def pr_dict(data, start=''): - for a in sorted(data.keys()): - b = data[a] - print '%s%s: %s' % (start, str(a), my_repr(b)) + return re.sub(re.compile('^', re.M), start, rep) +def pr_dict(*args): + print my_repr(*args) types = { 'u8': 'B', 'u16': 'H', @@ -243,9 +269,30 @@ def iff_to_chunks(z): pos += length chunks.append((cc, data)) return chunks -def bit_extract(num, start, end): +def bit_extract(num, start, end=None): + if end is None: + end = start mask = (2**(31 - start + 1) - 1) - (2**(31 - end) - 1) ret = (num & mask) >> (31 - end) return ret - +def get_array(chunk, startpos, array_size, item_size): + ar = [] + pos = startpos + for n in xrange(array_size): + if item_size == 4: + ar.append(struct.unpack('>I', chunk[pos:pos+4])[0]) + elif item_size % 4 == 0: + ar.append(struct.unpack('>' + 'I'*(item_size/4), chunk[pos:pos+item_size])) + else: + raise Exception('unhandled') + pos += item_size + + return ar, pos +def get_opt(chunk, startpos, enabled, size): + if not enabled: + return None, startpos + elif size == 4: + return struct.unpack('>I', chunk[startpos:startpos+4])[0], startpos + 4 + else: + raise Exception('unhandled') \ No newline at end of file diff --git a/parse-brlyt.py b/parse-brlyt.py index b69eba3..a85c028 100644 --- a/parse-brlyt.py +++ b/parse-brlyt.py @@ -23,12 +23,10 @@ for typ, chunk in ch: os = vars2['~text.name_offs'] - 8 txt = chunk[os:os + vars2['~text.len2']] vars2['~text.text'] = unicode(txt, 'utf_16_be').rstrip('\x00') - vars2['~text.material'] = materials[vars2['~text.mat_off']] vars.update(vars2) #print vars['~text.cnt2'], len(vars2['~text.text']), len(txt), repr(txt) elif typ == 'pic1': vars2, pos = parse_data(chunk, 'pic', prefix='~pic', start=pos) - vars2['~pic.material'] = materials[vars2['~pic.mat_off']] vars2['~pic.texcoords'] = [] for n in xrange(vars2['~pic.num_texcoords']): vars2['~pic.texcoords'].append(struct.unpack('>ffffffff', chunk[pos:pos+0x20])) @@ -63,18 +61,55 @@ for typ, chunk in ch: del vars['offs'] for n in xrange(vars['num']): offset, = struct.unpack('>I', chunk[pos:pos+4]) - mat, mpos = parse_data(chunk[offset - 8:], 'material') + mat, mpos = parse_data(chunk, 'material', start = offset - 8) #vars['materials'].append(mat) flags = mat['flags'] - offs1 = bit_extract(flags, 17, 18) * 0x14 - offs2 = (bit_extract(flags, 28, 31) * 4) + 0x40 - offs3 = offs2 + bit_extract(flags, 24, 27) * 0x14 + bit_extract(flags, 20, 23) * 4 - offs4 = bit_extract(flags, 8, 11) * 4 * 0x14 - print map(hex, [offs1, offs2, offs3, offs4]) + assert mpos == 0x40 + offset - 8 + + + #print hex(struct.unpack('>I', chunk[mpos:mpos+4])[0]) + + # I believe material is: + # 0x40, followed by + # 4 * flags[28-31], followed by + + + mat['ua1'], mpos = get_array(chunk, mpos, bit_extract(flags, 28, 31), 4) + + # 0x14 * flags[24-27], followed by + + mat['ua2'], mpos = get_array(chunk, mpos, bit_extract(flags, 24, 27), 0x14) + + # 4*flags[20-23], followed by + + mat['ua3'], mpos = get_array(chunk, mpos, bit_extract(flags, 20, 23), 4) + + # 4 * flags[6] + + mat['ua4'], mpos = get_opt(chunk, mpos, bit_extract(flags, 6), 4) - pr_dict(mat, ' ') - print + # 4 * flags[4] + + mat['ua5'], mpos = get_opt(chunk, mpos, bit_extract(flags, 4), 4) + + # 4 * flags[19] + + mat['ua6'], mpos = get_opt(chunk, mpos, bit_extract(flags, 19), 4) + + # 0x14 * flags[17-18] + + mat['ua7'], mpos = get_array(chunk, mpos, bit_extract(flags, 17, 18), 0x14) + + # 4 * flags[14-16] + + mat['ua8'], mpos = get_array(chunk, mpos, bit_extract(flags, 14, 16), 4) + + # 4 * flags[8] + + mat['ua9'], mpos = get_opt(chunk, mpos, bit_extract(flags, 8), 4) + + vars['materials'].append(mat) pos += 4 elif typ in ('grs1', 'pas1'): -- cgit v1.3.1