diff --git a/File-Type---Texture.md b/File-Type---Texture.md index 3a93ca0..df366f4 100644 --- a/File-Type---Texture.md +++ b/File-Type---Texture.md @@ -27,47 +27,80 @@ header { --- ```010editor -uint32 type; -// Presumably, there are other values as well, but `1` is the only case partially figured out, so far. -Assert(type == 1); -uint32 compressed_size; -uint32 uncompressed_size; +uint32 compression_type; +Assert(compression_type == 1 || compression_type == 0); -byte compressed_data[compressed_size]; +if (compression_type == 1) { + uint32 compressed_size; + uint32 uncompressed_size; + + byte data[compressed_size] ; + + // Seems to be skipped by the decompiled binary's code. + // Doesn't fit to be a length of a later data section. It doesn't match anything, and it's an uneven number. + uint32 unknown_1 ; + //Assert(unknown_1 == 0x43); + + // At this point, the code reads an array of 37 uint32 fields. + // This will be slowly split into individual named fields as I figure them out. + + typedef struct TextureHeader { + // Checked bits: + // >> 1: Some extra calculations are done with the next three fields around mipmaps + // Also determines if `unknown_2` is saved into `TextureImage` + // => Presumable means "has mipmaps" or VT2's "is streamable" + // >> 2: So far, I haven't found a line of code that actually uses this bit. But there is a line that does `flags & 3`, + // indicating that this bit does get used somewhere else. + // >> 8: TextureFormat.srgb + uint32 flags ; + + uint32 n_streamable_mips; + uint32 width; + uint32 height; + + // At some point, the code will move 68 bytes from an offset to the start of this array. + uint32 unknown_2[(68 + 60) / 4] ; + + }; + + TextureHeader texture_header; + + uint32 meta_size; + + // According to limn, this is something that happens inside `meta_data`. + // But so far, I haven't found the part in the decompiled binary that handles this data. + if (meta_size > 0) { + uint32 num_chunks ; + Assert((num_chunks * 4) + 8 == meta_size); + + uint16 unknown_6 ; + Assert(unknown_6 == 0); + + uint16 num_chunks_2 ; + Assert(num_chunks == num_chunks_2); + + uint32 chunks[num_chunks]; + } + + // A key to look up a value in the engine's internal render quality settings. + // Specifically, a value that VT2 calls `mip_drop`. + // TODO: Check how many unique values there are in the game files. + // Ideally, there would only be a handful that we can simply hard code. + uint32 category ; + + // Shortcuts to get to compile this: + // - `flags = 0` -> skips most of the mipmap stuff in the bundle file + // - `width = 0`, `height = 0` -> also skips some of the mipmap stuff + // - `n_streamable_mipmaps = 0` -> seems to be an intended value to only rely on DDS mipmaps + // It does force `srgb` on through setting a special value for `flags`, though. So if that produces issues, I might + // need to fake it s +} else if (compression_type == 0) { + uint32 unknown_1; + uint32 unknown_2; -uint32 unknown_1; -Assert(unknown_1 == 0x43); - -uint32 unknown_2; - -uint32 num_mipmaps; -uint32 largest_width; -uint32 largest_height; - -byte unknown_3[60]; - -uint32 image_size; - -byte unknown_4[64]; - -uint32 meta_size; - -if (meta_size == 0) { - uint32 unknown_5; -} else { - uint32 num_chunks; - Assert((num_chunks * 4) + 8 == meta_size); - - uint16 unknown_6; - Assert(unknown_6 == 0); - - uint16 num_chunks_2; - Assert(num_chunks == num_chunks_2); - - uint32 chunks[num_chunks]; - - uint32 unknown_7; + Assert(unknown_1 == 0); + Assert(unknown_2 == 0); } ```