Exemple #1
0
    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))
Exemple #2
0
 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)
Exemple #3
0
 def repr(self):
     return 'chunk_id: {}, section_index: {}, cast_index: {}'.format(
         riff.TagB(self.chunk_id), self.section_index, self.cast_index)
Exemple #4
0
    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()