Exemple #1
0
    def pack(self) -> bytes:
        """Pack TPF file to bytes."""
        writer = BinaryWriter(
            big_endian=self.platform in {TPFPlatform.Xbox360, TPFPlatform.PS3})
        writer.append(b"TPF\0")
        writer.reserve("data_size", "i")
        writer.pack("i", len(self.textures))
        writer.pack("b", self.platform)
        writer.pack("b", self.tpf_flags)
        writer.pack("b", self.encoding)
        writer.pad(1)

        for i, texture in enumerate(self.textures):
            texture.pack_header(writer, i, self.platform, self.tpf_flags)
        for i, texture in enumerate(self.textures):
            texture.pack_name(writer, i, self.encoding)

        data_start = writer.position
        for i, texture in enumerate(self.textures):
            # TKGP notes: padding varies wildly across games, so don't worry about it too much.
            if len(texture.data) > 0:
                writer.pad_align(4)
            texture.pack_data(writer, i)
        writer.fill("data_size", writer.position - data_start)
        return writer.finish()
Exemple #2
0
 def pack_header(self, writer: BinaryWriter):
     writer.append(b"BND3")
     writer.pack("8s", self.signature.encode("ascii"))
     self.flags.pack(writer, self.bit_big_endian)
     writer.pack("?", self.big_endian)
     writer.pack("?", self.bit_big_endian)
     writer.pad(1)
     writer.pack("i", len(self._entries))
     writer.reserve("file_size", "i")
     writer.pad(8)
Exemple #3
0
 def pack_bnd3(self, writer: BinaryWriter, binder_flags: BinderFlags, bit_big_endian: bool):
     self.flags.pack(writer, bit_big_endian)
     writer.pad(3)
     writer.pack("i", self.compressed_size)
     writer.reserve("data_offset", "q" if binder_flags.has_long_offsets else "I", obj=self)
     if binder_flags.has_ids:
         writer.pack("i", self.id)
     if binder_flags.has_names:
         writer.reserve("path_offset", "i", obj=self)
     if binder_flags.has_compression:
         writer.pack("i", self.uncompressed_size)
Exemple #4
0
    def pack_header(self, writer: BinaryWriter, index: int,
                    platform: TPFPlatform, tpf_flags: int):
        if platform == TPFPlatform.PC:
            dds = self.get_dds()
            if dds.header.caps_2 & DDSCAPS2.CUBEMAP:
                tex_type = TextureType.Cubemap
            elif dds.header.caps_2 & DDSCAPS2.VOLUME:
                tex_type = TextureType.Volume
            else:
                tex_type = TextureType.Texture
            mipmap_count = dds.header.mipmap_count
        else:
            tex_type = self.texture_type
            mipmap_count = self.mipmaps

        writer.reserve(f"file_data_{index}", "I")
        writer.reserve(f"file_size_{index}", "i")
        writer.pack("b", self.format)
        writer.pack("b", tex_type)
        writer.pack("b", mipmap_count)
        writer.pack("b", self.texture_flags)

        if platform != TPFPlatform.PC:
            writer.pack("h", self.header.width)
            writer.pack("h", self.header.height)
            if platform == TPFPlatform.Xbox360:
                writer.pad(4)
            elif platform == TPFPlatform.PS3:
                writer.pack("i", self.header.unk1)
                if tpf_flags != 0:
                    writer.pack("i", self.header.unk2)
            elif platform in {TPFPlatform.PS4, TPFPlatform.XboxOne}:
                writer.pack("i", self.header.texture_count)
                writer.pack("i", self.header.unk2)

        writer.reserve(f"file_name_{index}", "I")
        writer.pack("i", 0 if self.float_struct is None else 1)

        if platform in {TPFPlatform.PS4, TPFPlatform.XboxOne}:
            writer.pack("i", self.header.dxgi_format)

        if self.float_struct:
            self.float_struct.pack(writer)
Exemple #5
0
    def pack_header(self, writer: BinaryWriter):
        writer.append(b"BHF4")
        writer.pack("?", self.unknown1)
        writer.pack("?", self.unknown2)
        writer.pad(3)
        writer.pack("?", self.big_endian)
        writer.pack("?", not self.bit_big_endian)  # note reversal
        writer.pad(1)

        writer.pack("i", len(self._entries))
        writer.pack("q", 0x40)  # header size
        writer.pack("8s", self.signature.encode("ascii"))
        writer.pack("q", self.flags.get_bnd_entry_header_size())
        writer.reserve("data_offset", "q")
        writer.pack("?", self.unicode)
        self.flags.pack(writer, self.bit_big_endian)
        writer.pack("B", self.hash_table_type)
        writer.pad(5)
        if self.hash_table_type == 4:
            writer.reserve("hash_table_offset", "q")
        else:
            writer.pad(8)