def __init__(self, dirfile): self.dirfile = dirfile self.map_offset = dirfile.get_field_start_offset( 'map') + dirfile.map.get_field_start_offset('stream') self.riff_offsets = [self.map_offset] for i, x in enumerate(dirfile.map.stream): if i == 0: continue self.riff_offsets.append( self.riff_offsets[-1] + dirfile.map.get_field_size('stream', index=i - 1)) _, self.imap = self.get_from_offset(self.map_offset) _, self.mmap = self.get_from_offset(self.imap.obj.mmap_offset) _, self.key = self.get_last_from_mmap(b'KEY*') _, self.cas = self.get_last_from_mmap(b'CAS*') _, self.score = self.get_last_from_mmap(b'VWSC') _, self.config = self.get_last_from_mmap(b'VWCF') _, self.cast_order = self.get_last_from_mmap(b'Sord') #self.cast = [self.get_from_mmap_index( self.cas.obj.index[i-1] ) for i in self.cast_order.obj.index] self.cast = [(i, self.get_from_mmap_index(i).obj) if i else (None, None) for i in self.cas.obj.index] self.cast_map = { self.config.obj.cast_array_start + i: self.get_from_mmap_index(x).obj for i, x in enumerate(self.cas.obj.index) if x != 0 } _, self.script_context = self.get_last_from_mmap(b'Lctx') _, self.script_names = self.get_last_from_mmap(b'Lnam') self.script_ids = [] self.scripts = [] self.scripts_text = [] for script_cast in [ c for _, c in self.cast if c and c.cast_type == CastType.SCRIPT ]: script_id = script_cast.detail.script_id - 1 self.script_ids.append(script_id) self.scripts.append( self.get_from_mmap_index( self.script_context.obj.entries[script_id].index)) self.scripts_text.append( script_cast.detail.code.decode('latin').replace('\r', '\n')) self.bitmaps = [] for index, cast in [(i, c) for i, c in self.cast if c and c.cast_type == CastType.BITMAP]: bitmaps = [ self.get_from_mmap_index(x.section_index).obj for x in self.key.obj.entries if riff.TagB(x.chunk_id) == b'BITD' and x.cast_index == index ] if bitmaps: #bitmaps[0].data = BitmapCompressor().import_data( bitmaps[0].data ).payload cast.detail._data = bitmaps[0] self.bitmaps.append((index, cast))
def repr(self): return 'chunk_id: {}, length: 0x{:08x}, offset: 0x{:08x}, flags: {}'.format( riff.TagB(self.chunk_id), self.length, self.offset, self.flags)
def repr(self): return 'chunk_id: {}, section_index: {}, cast_index: {}'.format( riff.TagB(self.chunk_id), self.section_index, self.cast_index)
def dump_scripts(self): for i, script in enumerate(self.scripts): print('SCRIPT {}'.format(self.script_ids[i])) print('NAMES: {}'.format(self.script_names.obj.names)) print('CODE:') print(self.scripts_text[i]) name_lookup = lambda n: self.script_names.obj.names[ n] if n in range(len(self.script_names.obj.names) ) else 'unk_{}'.format(n) assert riff.TagB(script.id) == b'Lscr' for j, f in enumerate(script.obj.functions): if f is None: print('FUNCTION {} - None'.format(j)) continue print('FUNCTION {} - {}({})'.format( j, name_lookup(f.name_index), ', '.join([name_lookup(a) for a in f.args.name_index]))) print('VARS: {}'.format(', '.join( [name_lookup(v) for v in f.vars.name_index]))) for inst in f.code.instructions: if self.script_names: if inst.id in (LingoV4.CALL, ): print('{} # {}()'.format( inst, name_lookup(script.obj.functions[ inst.obj.value].name_index))) elif inst.id in (LingoV4.CALL_EXTERNAL, ): print('{} # {}()'.format( inst, name_lookup(inst.obj.value))) elif inst.id in (LingoV4.PUSH_PROPERTY, LingoV4.POP_PROPERTY, LingoV4.PUSH_PROPERTY_CTX, LingoV4.POP_PROPERTY_CTX, LingoV4.PUSH_PROPERTY_OBJ, LingoV4.POP_PROPERTY_OBJ, LingoV4.PUSH_PROPERTY_RO, LingoV4.PUSH_GLOBAL, LingoV4.POP_GLOBAL, LingoV4.PUSH_OBJECT, LingoV4.PUSH_NAME): print('{} # {}'.format(inst, name_lookup( inst.obj.value))) elif inst.id in (LingoV4.PUSH_CONST, ): print('{} # {}'.format( inst, script.obj.consts[inst.obj.value // 6])) elif inst.id in ( LingoV4.PUSH_PARAM, LingoV4.POP_PARAM, ): print('{} # {}'.format( inst, name_lookup(f.args.name_index[inst.obj.value // 6]) if f.args.name_index else 'unk_{}'.format( inst.obj.value // 6))) elif inst.id in ( LingoV4.PUSH_LOCAL, LingoV4.POP_LOCAL, ): print('{} # {}'.format( inst, name_lookup(f.vars.name_index[inst.obj.value // 6]) if f.vars.name_index else 'unk_{}'.format( inst.obj.value // 6))) else: print(inst) else: print(inst) for j, c in enumerate(script.obj.consts): print('CONST {}'.format(j)) print(c) for j, g in enumerate(script.obj.globals): print('GLOBAL {}'.format(j)) if self.script_names: print(self.script_names.obj.names[g.name_index]) else: print(g.name_index) print()