예제 #1
0
    def load_resources(path: str) -> List[Resource]:
        reader = BinaryReader.from_path(path)
        resources = []

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)
        reader.seek(16)
        resource_count = reader.read_uint32()
        reader.seek(24)
        key_list_offset = reader.read_uint32()
        resource_list_offset = reader.read_uint32()

        for i in range(resource_count):
            reader.seek(key_list_offset + 24 * i)
            res_ref = reader.read_string(16)
            reader.skip(4)
            res_type = ResourceType.get(reader.read_uint16())
            reader.skip(2)

            reader.seek(resource_list_offset + 8 * i)
            res_offset = reader.read_uint32()
            res_size = reader.read_uint32()

            resources.append(Resource(res_ref, res_type, res_size, res_offset))

        return resources
예제 #2
0
파일: tpc.py 프로젝트: NickHugi/PyKotor
    def _rgba_bytes_from_dxt1(self, mipmap: int = 0) -> bytearray:
        dxt_reader = BinaryReader.from_data(self._mipmaps[mipmap])
        width, height = self.get_mipmap_size(mipmap)
        pixels = [0] * width * height

        for ty in range(height, 0, -4):
            for tx in range(0, width, 4):
                color0 = self._rgba565_to_rgb888(dxt_reader.read_int16())
                color1 = self._rgba565_to_rgb888(dxt_reader.read_int16())
                dxt_pixels = dxt_reader.read_uint32(True)

                color_code = []
                color_code.extend([color0, color1])
                if color0 > color1:
                    color_code.append(self._interpolate(0.3333333, color0, color1))
                    color_code.append(self._interpolate(0.6666666, color0, color1))
                else:
                    color_code.append(self._interpolate(0.5555555, color0, color1))
                    color_code.append(0xFF000000)

                for y in range(4):
                    for x in range(4):
                        pixel_code = dxt_pixels & 3
                        dxt_pixels >>= 2
                        pixels[(ty - 4 + y) * self._width + (tx + x)] = color_code[pixel_code] + 0xFF000000

        data = bytearray()
        for pixel in pixels:

            data.append((pixel & 0x00FF0000) >> 16)
            data.append((pixel & 0x0000FF00) >> 8)
            data.append((pixel & 0x000000FF))
            data.append(255)

        return data
예제 #3
0
    def load(data: bytes) -> TLK:
        reader = BinaryReader.from_data(data)
        tlk = TLK()

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)
        tlk.language_id = reader.read_uint32()
        string_count = reader.read_uint32()
        string_entries_offset = reader.read_uint32()

        for i in range(string_count):
            reader.seek(20 + i * 40)
            flags = reader.read_uint32()
            res_ref = reader.read_string(16)
            reader.skip(4)
            reader.skip(4)
            offset_to_string = reader.read_uint32() + string_entries_offset
            string_size = reader.read_uint32()
            reader.skip(4)

            reader.seek(offset_to_string)
            text = reader.read_string(string_size)

            tlk.add(Entry.new(res_ref, text))

        return tlk
예제 #4
0
    def load(data: bytes) -> ERF:
        reader = BinaryReader.from_data(data)
        erf = ERF()

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)
        reader.seek(16)
        resource_count = reader.read_uint32()
        reader.seek(24)
        key_list_offset = reader.read_uint32()
        resource_list_offset = reader.read_uint32()

        for i in range(resource_count):
            reader.seek(key_list_offset + 24 * i)
            res_ref = reader.read_string(16)
            reader.skip(4)
            res_type = ResourceType.get(reader.read_uint16())
            reader.skip(2)

            reader.seek(resource_list_offset + 8 * i)
            res_offset = reader.read_uint32()
            res_size = reader.read_uint32()

            reader.seek(res_offset)
            res_data = reader.read_bytes(res_size)
            erf.add(Resource.new(res_ref, res_type, res_data))

        return erf
예제 #5
0
파일: wok.py 프로젝트: NickHugi/PyKotor
    def load(data: bytes) -> WOK:
        reader = BinaryReader.from_data(data)
        wok = WOK()

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)
        wok.walkmesh_type = WalkmeshType(reader.read_int32())
        reader.skip(48)

        vertex_count = reader.read_vertex()
        vertex_count = reader.read_uint32()
        vertices_offset = reader.read_uint32()
        face_count = reader.read_uint32()
        face_indices_offset = reader.read_uint32()
        face_materials_offset = reader.read_uint32()
        face_normals_offset = reader.read_uint32()
        face_distances_offset = reader.read_uint32()
        aabb_count = reader.read_uint32()
        aabbs_offset = reader.read_uint32()
        reader.skip(4)
        adjacency_count = reader.read_int32()
        adjacencies_offset = reader.read_int32()
        edge_count = reader.read_int32()
        edges_offset = reader.read_int32()
        perimeter_count = reader.read_int32()
        perimeters_offset = reader.read_int32()

        wok.faces = [Face() for _ in range(face_count)]

        vertices = []
        reader.seek(vertices_offset)
        for i in range(vertex_count):
            vertices.append(reader.read_vertex())

        reader.seek(face_indices_offset)
        for i in range(face_count):
            v1 = reader.read_uint32()
            v2 = reader.read_uint32()
            v3 = reader.read_uint32()
            wok.faces[i].vertices[0] = vertices[v1]
            wok.faces[i].vertices[1] = vertices[v2]
            wok.faces[i].vertices[2] = vertices[v3]

        reader.seek(face_materials_offset)
        for i in range(face_count):
            wok.faces[i].material = Material(reader.read_int32())

        reader.seek(edges_offset)
        for i in range(edge_count):
            edge_index = reader.read_int32()
            transition = reader.read_int32()
            face_index = edge_index // 3
            adjaceny_index = edge_index % 3
            if transition != -1:
                wok.faces[face_index].transitions[adjaceny_index] = transition

        return wok
예제 #6
0
파일: tpc.py 프로젝트: NickHugi/PyKotor
    def _rgba_bytes_from_dxt5(self, mipmap: int = 0) -> bytearray:
        dxt_reader = BinaryReader.from_data(self._mipmaps[mipmap])
        width, height = self.get_mipmap_size(mipmap)
        pixels = [0] * width * height

        for ty in range(height, 0, -4):
            for tx in range(0, width, 4):
                alpha0 = dxt_reader.read_uint8()
                alpha1 = dxt_reader.read_uint8()
                dxt_alpha = self._integer48(dxt_reader.read_bytes(6))
                color0 = self._rgba565_to_rgb888(dxt_reader.read_int16())
                color1 = self._rgba565_to_rgb888(dxt_reader.read_int16())
                dxt_pixels = dxt_reader.read_uint32(True)

                color_code = []
                color_code.extend([color0, color1])
                if color0 > color1:
                    color_code.append(self._interpolate(0.3333333, color0, color1))
                    color_code.append(self._interpolate(0.6666666, color0, color1))
                else:
                    color_code.append(self._interpolate(0.5555555, color0, color1))
                    color_code.append(0xFF000000)

                alpha_code = [alpha0, alpha1]
                if alpha0 > alpha1:
                    alpha_code.append(int((6.0 * alpha0 + 1.0 * alpha1 + 3) / 7))
                    alpha_code.append(int((5.0 * alpha0 + 2.0 * alpha1 + 3) / 7))
                    alpha_code.append(int((4.0 * alpha0 + 3.0 * alpha1 + 3) / 7))
                    alpha_code.append(int((3.0 * alpha0 + 4.0 * alpha1 + 3) / 7))
                    alpha_code.append(int((2.0 * alpha0 + 5.0 * alpha1 + 3) / 7))
                    alpha_code.append(int((1.0 * alpha0 + 6.0 * alpha1 + 3) / 7))
                else:
                    alpha_code.append(int((4.0 * alpha0 + 1.0 * alpha1 + 1) / 5))
                    alpha_code.append(int((3.0 * alpha0 + 2.0 * alpha1 + 2) / 5))
                    alpha_code.append(int((2.0 * alpha0 + 3.0 * alpha1 + 2) / 5))
                    alpha_code.append(int((1.0 * alpha0 + 4.0 * alpha1 + 2) / 5))
                    alpha_code.append(0)
                    alpha_code.append(255)

                for y in range(4):
                    for x in range(4):
                        pixelc_code = dxt_pixels & 3
                        dxt_pixels >>= 2
                        a = alpha_code[(dxt_alpha >> (3 * (4 * (3 - y) + x))) & 7]
                        pixel = color_code[pixelc_code] | (a << 24)
                        pixels[(ty - 4 + y) * self.width + (tx + x)] = pixel

        data = bytearray()
        for pixel in pixels:

            data.append((pixel & 0x00FF0000) >> 16)
            data.append((pixel & 0x0000FF00) >> 8)
            data.append((pixel & 0x000000FF))
            data.append((pixel & 0xFF000000) >> 24)

        return data
예제 #7
0
파일: ssf.py 프로젝트: NickHugi/PyKotor
    def load(data: bytes) -> SSF:
        ssf = SSF()
        reader = BinaryReader.from_data(data)

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)

        table_offset = reader.read_uint32()

        reader.seek(table_offset)
        for i in range(40):
            ssf.entries[i] = reader.read_int32()

        return ssf
예제 #8
0
    def load_resources(path: str, resources: Dict[int, Resource]) -> None:
        reader = BinaryReader.from_path(path)

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)

        resource_count = reader.read_uint32()
        reader.skip(4)
        resources_offset = reader.read_uint32()

        reader.seek(resources_offset)
        for i in range(resource_count):
            res_id = reader.read_uint32()
            resources[res_id].res_offset = reader.read_uint32()
            resources[res_id].res_size = reader.read_uint32()
            resources[res_id].path = path
            res_type_id = reader.read_uint32()
예제 #9
0
파일: lip.py 프로젝트: NickHugi/PyKotor
    def load(data: bytes) -> LIP:
        lip = LIP()
        reader = BinaryReader.from_data(data)

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)
        lip.length = reader.read_float32()
        entry_count = reader.read_int32()
        ''' KotOR.JS ignores 5 bytes after the header and subtracts the entry count by 1? Not sure why... '''

        for i in range(entry_count):
            time = reader.read_float32()
            shape = Shape(reader.read_int8())
            keyframe = KeyFrame.new(time, shape)
            lip.frames.append(keyframe)

        return lip
예제 #10
0
    def load_resources(directory: str) -> Dict[int, Resource]:
        reader = BinaryReader.from_path(directory + "/chitin.key")
        resources: Dict[int, Resource] = dict()

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)

        bif_count = reader.read_uint32()
        key_count = reader.read_uint32()

        bif_names_offset = reader.read_uint32()
        keys_offset = reader.read_uint32()

        bif_paths = []
        for i in range(bif_count):
            reader.seek(bif_names_offset + i * 12)
            bif_size = reader.read_uint32()
            filename_offset = reader.read_uint32()
            filename_size = reader.read_uint16()
            drive = reader.read_uint16()

            reader.seek(filename_offset)
            bif_path = (directory + '/' +
                        reader.read_string(filename_size)).replace('\\', '/')
            bif_paths.append(bif_path)

        reader.seek(keys_offset)
        for i in range(key_count):
            res_ref = reader.read_string(16)
            res_type = ResourceType.get(reader.read_uint16())
            res_id = reader.read_uint32()
            resources[res_id] = Resource(res_ref, res_type)

        for bif in bif_paths:
            try:
                _BIFReader.load_resources(bif, resources)
            finally:
                pass

        return resources
예제 #11
0
파일: tpc.py 프로젝트: NickHugi/PyKotor
    def load(data: bytes) -> TPC:
        tpc = TPC()
        reader = BinaryReader.from_data(data)

        size = reader.read_int32()
        unknown = reader.read_float32()
        width = reader.read_int16()
        height = reader.read_int16()
        encoding = reader.read_uint8()
        mipmap_count = reader.read_uint8()
        reader.skip(114)

        texture_type = TextureType.Invalid
        if encoding == 1 and size == 0:
            texture_type = TextureType.Greyscale
        if encoding == 2 and size == 0:
            texture_type = TextureType.RGB
        if encoding == 4 and size == 0:
            texture_type = TextureType.RGBA
        if encoding == 2 and size > 0:
            texture_type = TextureType.DXT1
        if encoding == 4 and size > 0:
            texture_type = TextureType.DXT5

        mipmap_width = width
        mipmap_height = height
        mipmaps = []
        for i in range(mipmap_count):
            mipmap_data = reader.read_bytes(_TPCReader._get_data_size(texture_type, mipmap_width, mipmap_height))
            mipmap_width >>= 1
            mipmap_height >>= 1
            mipmaps.append(mipmap_data)

        tpc.set_mipmaps(width, height, mipmaps, texture_type)

        reader.seek(_TPCReader._get_txi_offset(texture_type, width, height, len(mipmaps), size))
        tpc.txi = reader.read_string(reader.size() - reader.position())

        return tpc
예제 #12
0
    def load(data: bytes) -> RIM:
        reader = BinaryReader.from_data(data)
        rim = RIM()

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)
        reader.skip(4)
        resource_count = reader.read_uint32()
        table_offset = reader.read_uint32()
        reader.skip(100)

        for i in range(resource_count):
            reader.seek(table_offset + 32 * i)
            res_ref = reader.read_string(16)
            res_type = ResourceType.get(reader.read_uint32())
            reader.skip(4)
            res_offset = reader.read_uint32()
            res_size = reader.read_uint32()
            reader.seek(res_offset)
            res_data = reader.read_bytes(res_size)
            rim.add(Resource.new(res_ref, res_type, res_data))

        return rim
예제 #13
0
    def load(data: bytes) -> TwoDA:
        reader = BinaryReader.from_data(data)
        twoda = TwoDA()

        file_type = reader.read_string(4)
        file_version = reader.read_string(4)
        reader.skip(1)

        columns = []
        while reader.peek() != 0:
            columns.append(reader.read_terminated_string('\t'))
            twoda.add_column(columns[-1])
        column_count = len(columns)

        reader.skip(1)
        row_count = reader.read_int32()
        for i in range(row_count):
            row_name = reader.read_terminated_string('\t')

        cell_count = row_count * len(columns)
        cell_offsets = []
        for i in range(cell_count):
            cell_offsets.append(reader.read_uint16())

        reader.skip(2)
        data_offset = reader.position()

        for i in range(row_count):
            twoda.add_row()
            for j in range(column_count):
                cell_index = j + i * column_count
                reader.seek(data_offset + cell_offsets[cell_index])
                data = reader.read_terminated_string('\0')
                twoda.set_data(columns[j], i, data)

        return twoda