示例#1
0
    def read_tex1(self):
        self.textures = []
        self.num_textures = read_u16(self.data, 8)
        self.texture_header_list_offset = read_u32(self.data, 0x0C)
        for texture_index in range(self.num_textures):
            bti_header_offset = self.texture_header_list_offset + texture_index * 0x20
            texture = BTI(self.data, bti_header_offset)
            self.textures.append(texture)

        self.string_section_offset = read_u32(self.data, 0x10)
        self.num_strings = read_u16(self.data, self.string_section_offset)
        self.string_unknown_1 = read_u16(self.data,
                                         self.string_section_offset + 2)
        self.string_unknown_2 = read_u16(self.data,
                                         self.string_section_offset + 4)
        self.string_data_offset = read_u16(self.data,
                                           self.string_section_offset + 6)
        self.string_unknown_3 = read_bytes(self.data,
                                           self.string_section_offset + 8,
                                           self.string_data_offset - 8)

        self.texture_names = []
        self.textures_by_name = OrderedDict()
        offset_in_string_list = self.string_data_offset
        for texture in self.textures:
            filename = read_str_until_null_character(
                self.data, self.string_section_offset + offset_in_string_list)
            self.texture_names.append(filename)
            if filename not in self.textures_by_name:
                self.textures_by_name[filename] = []
            self.textures_by_name[filename].append(texture)

            offset_in_string_list += len(filename) + 1
示例#2
0
    def read_chunk_specific_data(self):
        self.textures = []
        self.num_textures = read_u16(self.data, 8)
        self.texture_header_list_offset = read_u32(self.data, 0x0C)
        for texture_index in range(self.num_textures):
            bti_header_offset = self.texture_header_list_offset + texture_index * 0x20
            texture = BTI(self.data, bti_header_offset)
            self.textures.append(texture)

        self.string_table_offset = read_u32(self.data, 0x10)
        self.texture_names = self.read_string_table(self.string_table_offset)
        self.textures_by_name = OrderedDict()
        for i, texture in enumerate(self.textures):
            texture_name = self.texture_names[i]
            if texture_name not in self.textures_by_name:
                self.textures_by_name[texture_name] = []
            self.textures_by_name[texture_name].append(texture)
示例#3
0
文件: jpc.py 项目: firesly1/betterww
    def __init__(self, jpc_data, section_offset):
        self.magic = read_str(jpc_data, section_offset, 4)
        self.size = read_u32(jpc_data, section_offset + 4)

        jpc_data.seek(section_offset)
        self.data = BytesIO(jpc_data.read(self.size))

        if self.magic == "TEX1":
            # This string is 0x14 bytes long, but sometimes there are random garbage bytes after the null byte.
            self.filename = read_str_until_null_character(self.data, 0xC)

            bti_data = BytesIO(read_bytes(self.data, 0x20, self.size - 0x20))
            self.bti = BTI(bti_data)
        elif self.magic == "TDB1":
            # Texture ID database (list of texture IDs in this JPC file used by this particle)

            num_texture_ids = ((self.size - 0xC) // 2)
            self.texture_ids = []
            for texture_id_index in range(0, num_texture_ids):
                texture_id = read_u16(self.data, 0xC + texture_id_index * 2)
                self.texture_ids.append(texture_id)

            self.texture_filenames = [
            ]  # Leave this list empty for now, it will be populated after the texture list is read.
示例#4
0
    def read_chunk_specific_data(self):
        # This string is 0x14 bytes long, but sometimes there are random garbage bytes after the null byte.
        self.filename = read_str_until_null_character(self.data, 0xC)

        bti_data = BytesIO(read_bytes(self.data, 0x20, self.size - 0x20))
        self.bti = BTI(bti_data)
示例#5
0
    def read(self):
        if self.magic == "TEX1":
            # This string is 0x14 bytes long, but sometimes there are random garbage bytes after the null byte.
            self.filename = read_str_until_null_character(self.data, 0xC)

            bti_data = BytesIO(read_bytes(self.data, 0x20, self.size - 0x20))
            self.bti = BTI(bti_data)
        elif self.magic == "TDB1":
            # Texture ID database (list of texture IDs in this JPC file used by this particle)

            num_texture_ids = ((self.size - 0xC) // 2)
            self.texture_ids = []
            for texture_id_index in range(num_texture_ids):
                texture_id = read_u16(self.data, 0xC + texture_id_index * 2)
                self.texture_ids.append(texture_id)

            # There's an issue with reading texture IDs where it can include false positives because the texture ID list pads the end with null bytes, which can be interpreted as the texture with ID 0.
            # So we use a heuristic to guess when the list really ends and the padding starts.
            # Simply, we count all texture IDs up until the last nonzero ID, then stop counting zero IDs after that.
            # However, we always include the texture ID at index 0, even if it's zero.
            # TODO: This is a bit hacky. A proper way would involve completely implementing all JPC sections and reading all the texture ID indexes from them, and then reading only the texture IDs at those indexes. But that would be much more work, and this appears to work fine.
            last_nonzero_texture_id_index = None
            for texture_id_index in reversed(range(num_texture_ids)):
                if self.texture_ids[texture_id_index] != 0:
                    last_nonzero_texture_id_index = texture_id_index
                    break
            if last_nonzero_texture_id_index is None:
                last_nonzero_texture_id_index = 0
            self.texture_ids = self.texture_ids[:
                                                last_nonzero_texture_id_index +
                                                1]

            self.texture_filenames = [
            ]  # Leave this list empty for now, it will be populated after the texture list is read.
        elif self.magic == "BSP1":
            self.color_flags = read_u8(self.data, 0xC + 0x1B)

            r = read_u8(self.data, 0xC + 0x20)
            g = read_u8(self.data, 0xC + 0x21)
            b = read_u8(self.data, 0xC + 0x22)
            a = read_u8(self.data, 0xC + 0x23)
            self.color_prm = (r, g, b, a)
            r = read_u8(self.data, 0xC + 0x24)
            g = read_u8(self.data, 0xC + 0x25)
            b = read_u8(self.data, 0xC + 0x26)
            a = read_u8(self.data, 0xC + 0x27)
            self.color_env = (r, g, b, a)

            self.color_prm_anm_data_count = 0
            self.color_prm_anm_table = []
            if self.color_flags & 0x02 != 0:
                self.color_prm_anm_data_offset = read_u16(self.data, 0xC + 0x4)
                self.color_prm_anm_data_count = read_u8(self.data, 0xC + 0x1C)
                self.color_prm_anm_table = self.read_color_table(
                    self.color_prm_anm_data_offset,
                    self.color_prm_anm_data_count)

            self.color_env_anm_data_count = 0
            self.color_env_anm_table = []
            if self.color_flags & 0x08 != 0:
                self.color_env_anm_data_offset = read_u16(self.data, 0xC + 0x6)
                self.color_env_anm_data_count = read_u8(self.data, 0xC + 0x1D)
                self.color_env_anm_table = self.read_color_table(
                    self.color_env_anm_data_offset,
                    self.color_env_anm_data_count)
        elif self.magic == "SSP1":
            r = read_u8(self.data, 0xC + 0x3C)
            g = read_u8(self.data, 0xC + 0x3D)
            b = read_u8(self.data, 0xC + 0x3E)
            a = read_u8(self.data, 0xC + 0x3F)
            self.color_prm = (r, g, b, a)
            r = read_u8(self.data, 0xC + 0x40)
            g = read_u8(self.data, 0xC + 0x41)
            b = read_u8(self.data, 0xC + 0x42)
            a = read_u8(self.data, 0xC + 0x43)
            self.color_env = (r, g, b, a)