//------------------------------------------------ //--- 010 Editor v12.0.1 Binary Template // // File: dt_texture_compressed.dt // Authors: Lucas Schwiderski // Version: // Purpose: // Category: Darktide // File Mask: // ID Bytes: // History: //------------------------------------------------ // The game does ship with two decompression options, but it I've only seen Oodle in the game files // so far. // I'd guess `0` is uncompressed, which would only happen in the dev releases, and likely be stripped by `#if`s. // The compression method does not affect the rest of the data structure typedef enum { Oodle = 1, Custom = 2, } CompressionType; CompressionType compression_type; uint32 compressed_size; uint32 uncompressed_size; byte compressed_buffer[compressed_size] ; // 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); typedef struct { uint32 offset; uint32 size; } MipInfo; typedef struct { // 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 assigns `flags & 3`, indicating that this bit // does get used somewhere else. // >> 8: TextureFormat.srgb, probably. uint32 flags ; // Does not match with the number of pairs in `mip_infos`. uint32 n_streamable_mips; uint32 width; uint32 height; // Offset and size of mip maps stored in the `.stream` file // Though it seems that they don't align with mipmaps properly. // The first size sometimes doesn't include enough data for a full texture // and it would end up with a black section. MipInfo mip_infos[16] ; uint32 meta_size; } TextureHeader; TextureHeader texture_header; // If there is an associated `.stream` file, its content is compressed with Oodle, // and the numbers in `chunks` below specify the size of each chunk. // I.e. the `comp_buf_size`, while the `raw_buf_size` is always `0x1000`. if (texture_header.meta_size > 0) { uint32 num_chunks; Assert((num_chunks * 4) + 8 == texture_header.meta_size); uint16 unknown_6 ; Assert(unknown_6 == 0); // Always the same as `num_chunks`, but it's weird that this is a u16. // So probably a different meaning that just happens to be the same value in most/all cases. 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`. // See `user_settings.conf` -> `texture_settings` 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