Add existing templates
This commit is contained in:
parent
e7385aa3b0
commit
6175784bfa
24 changed files with 1845 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Repository/
|
54
dt_bundle.bt
Normal file
54
dt_bundle.bt
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File:
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category:
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 extension <format=hex>;
|
||||||
|
uint64 name <format=hex>;
|
||||||
|
uint32 flags <format=binary>;
|
||||||
|
} FileMeta;
|
||||||
|
|
||||||
|
uint32 format <format=hex>;
|
||||||
|
uint32 unknown_1 <format=hex>;
|
||||||
|
Assert(unknown_1 == 3);
|
||||||
|
|
||||||
|
uint32 num_entries;
|
||||||
|
uint64 properties[32] <format=hex>;
|
||||||
|
|
||||||
|
FileMeta file_meta[num_entries];
|
||||||
|
|
||||||
|
uint32 num_chunks;
|
||||||
|
uint32 chunk_sizes[num_chunks];
|
||||||
|
|
||||||
|
local int padding_size = 16 - (FTell() % 16);
|
||||||
|
if (padding_size < 16) {
|
||||||
|
byte padding[padding_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 unpacked_size;
|
||||||
|
uint32 unknown_3;
|
||||||
|
|
||||||
|
local int chunk_index;
|
||||||
|
for (chunk_index = 0; chunk_index < num_chunks; chunk_index++) {
|
||||||
|
struct Chunk {
|
||||||
|
uint32 size <bgcolor=0x0015FF>;
|
||||||
|
|
||||||
|
local int padding_size = 16 - (FTell() % 16);
|
||||||
|
|
||||||
|
if (padding_size < 16) {
|
||||||
|
byte padding[padding_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
byte data[chunk_sizes[chunk_index]] <bgcolor=0xFF1500>;
|
||||||
|
};
|
||||||
|
Chunk chunks;
|
||||||
|
}
|
84
dt_bundle_database.bt
Normal file
84
dt_bundle_database.bt
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: dt_bundle_database.dt
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Darktide
|
||||||
|
// File Mask: bundle_database.data
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
uint32 format <format=hex>;
|
||||||
|
uint32 num_entries;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 version;
|
||||||
|
Assert(version == 0x4);
|
||||||
|
|
||||||
|
uint32 len_name;
|
||||||
|
char name[len_name];
|
||||||
|
|
||||||
|
uint32 len_stream;
|
||||||
|
char stream[len_stream];
|
||||||
|
|
||||||
|
byte platform_specific; // boolean
|
||||||
|
|
||||||
|
// byte buffer[20] <bgcolor=0x3399ff>;
|
||||||
|
byte buffer[20];
|
||||||
|
|
||||||
|
local int is_0 = true;
|
||||||
|
local int i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 15; i++) {
|
||||||
|
if (buffer[i] != 0) {
|
||||||
|
is_0 = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_0) {
|
||||||
|
Warning("Unknown 20-byte buffer is not 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 file_time; // win32 FILETIME
|
||||||
|
} File;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 hash <format=hex>;
|
||||||
|
uint32 num_files;
|
||||||
|
|
||||||
|
File files[num_files] <optimize=false>;
|
||||||
|
} Entry;
|
||||||
|
|
||||||
|
Entry entries[num_entries] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 num_hashes;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 bundle <format=hex>;
|
||||||
|
uint64 resource_hash <format=hex>;
|
||||||
|
} ResourceHash;
|
||||||
|
|
||||||
|
ResourceHash hashes[num_hashes];
|
||||||
|
|
||||||
|
if (format <= 5) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 num_contents;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 extension <format=hex>;
|
||||||
|
uint64 name <format=hex>;
|
||||||
|
} Filename;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 hash <format=hex>;
|
||||||
|
uint32 num_files;
|
||||||
|
|
||||||
|
Filename files[num_files];
|
||||||
|
} BundleContents;
|
||||||
|
|
||||||
|
BundleContents contents[num_contents] <optimize=false>;
|
85
dt_bundle_decompressed.bt
Normal file
85
dt_bundle_decompressed.bt
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: dt_bundle_decompressed.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Darktide
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 extension <format=hex>;
|
||||||
|
uint64 name <format=hex>;
|
||||||
|
uint32 flags <format=binary>;
|
||||||
|
} FileMeta;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 lang <format=binary>;
|
||||||
|
byte is_data_file <comment="If 1, data chunk will be a file name in data/">;
|
||||||
|
uint32 size;
|
||||||
|
byte unknown_2;
|
||||||
|
// If > 0, data chunk will be followed by a string of that length, which is an auxiliary/extension file
|
||||||
|
// to the data in the data chunk.
|
||||||
|
// Example: `.wwise_stream` only contains 12 bytes of data in the bundle, which includes an offset and a length.
|
||||||
|
// The extra file then contains the actual data.
|
||||||
|
uint32 len_data_file_name;
|
||||||
|
|
||||||
|
if (is_data_file == 1) {
|
||||||
|
if (size > 40) {
|
||||||
|
Warning("is_data_file == true, but size is too big for a simple file name: size = %d", size);
|
||||||
|
}
|
||||||
|
if (len_data_file_name > 0) {
|
||||||
|
Warning("is_data_file == true, but we also got len_data_file_name > 0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unknown_2 != 1) {
|
||||||
|
Assert("Expected '1' for 'unknown_2', got '%x'", unknown_2);
|
||||||
|
}
|
||||||
|
} FileHeader;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 extension <format=hex>;
|
||||||
|
uint64 name <format=hex>;
|
||||||
|
|
||||||
|
uint32 header_count;
|
||||||
|
uint32 unknown_1;
|
||||||
|
|
||||||
|
FileHeader headers[header_count];
|
||||||
|
|
||||||
|
local int i = 0;
|
||||||
|
for (i = 0; i < header_count; i++) {
|
||||||
|
if (headers[i].is_data_file) {
|
||||||
|
char data_file[headers[i].size];
|
||||||
|
} else {
|
||||||
|
byte data[headers[i].size];
|
||||||
|
char data_file[headers[i].len_data_file_name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} File;
|
||||||
|
|
||||||
|
uint32 version <format=hex>;
|
||||||
|
uint32 unknown_1;
|
||||||
|
Assert(unknown_1 == 3);
|
||||||
|
|
||||||
|
uint32 num_entries;
|
||||||
|
uint64 properties[32] <format=hex>;
|
||||||
|
|
||||||
|
FileMeta file_meta[num_entries];
|
||||||
|
|
||||||
|
uint32 num_chunks;
|
||||||
|
uint32 chunk_sizes[num_chunks];
|
||||||
|
|
||||||
|
local int padding_size = 16 - (FTell() % 16);
|
||||||
|
if (padding_size < 16) {
|
||||||
|
byte padding[padding_size];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 unpacked_size <bgcolor=0x0015FF>;
|
||||||
|
uint32 unknown_3;
|
||||||
|
|
||||||
|
File files[num_entries] <optimize=false>;
|
21
dt_chunk.bt
Normal file
21
dt_chunk.bt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: dt_chunk.dt
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category:
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
uint64 extension_hash <format=hex>;
|
||||||
|
uint64 name_hash <format=hex>;
|
||||||
|
|
||||||
|
// Probably a count, could be the number of file
|
||||||
|
uint32 unknown_3;
|
||||||
|
|
||||||
|
// Until eof?
|
||||||
|
// Probably not, because many bundles, even when uncompressed, end with the same/similar trailer
|
||||||
|
byte data;
|
68
dt_dds_image.bt
Executable file
68
dt_dds_image.bt
Executable file
|
@ -0,0 +1,68 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File:
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category:
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
// ========
|
||||||
|
// Typedefs
|
||||||
|
// ========
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int dxgiFormat;
|
||||||
|
unsigned int resourceDimension;
|
||||||
|
unsigned int miscFlag;
|
||||||
|
unsigned int arraySize;
|
||||||
|
unsigned int miscFlags2;
|
||||||
|
} stingray::image::DDSImage::DDS_DX10_HEADER;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned int dwSize;
|
||||||
|
unsigned int dwFlags;
|
||||||
|
unsigned int dwFourCC;
|
||||||
|
unsigned int dwRGBBitCount;
|
||||||
|
unsigned int dwRBitMask;
|
||||||
|
unsigned int dwGBitMask;
|
||||||
|
unsigned int dwBBitMask;
|
||||||
|
unsigned int dwABitMask;
|
||||||
|
} stingray::image::DDSImage::DDS_PIXELFORMAT;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int dwSize;
|
||||||
|
unsigned int dwHeaderFlags;
|
||||||
|
unsigned int dwHeight;
|
||||||
|
unsigned int dwWidth;
|
||||||
|
unsigned int dwPitchOrLinearSize;
|
||||||
|
unsigned int dwDepth;
|
||||||
|
unsigned int dwMipMapCount;
|
||||||
|
unsigned int dwReserved1[11];
|
||||||
|
stingray::image::DDSImage::DDS_PIXELFORMAT ddspf;
|
||||||
|
unsigned int dwCaps;
|
||||||
|
unsigned int dwCaps2;
|
||||||
|
unsigned int dwReserved2[3];
|
||||||
|
} stingray::image::DDSImage::DDS_HEADER;
|
||||||
|
|
||||||
|
// =========
|
||||||
|
// Structure
|
||||||
|
// =========
|
||||||
|
|
||||||
|
uint32 skip_1;
|
||||||
|
stingray::image::DDSImage::DDS_HEADER header;
|
||||||
|
|
||||||
|
if (header.ddspf.dwFourCC == 0x30315844) {
|
||||||
|
stingray::image::DDSImage::DDS_DX10_HEADER dx10_header;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Lots of calculations and value checking is done in the code
|
||||||
|
// before it's determined how to read the next section.
|
||||||
|
// Though it does look like there are only two ways that it does end up proceeding.
|
||||||
|
// In the first case, `header.dwDepth` plays a role
|
22
dt_package.bt
Normal file
22
dt_package.bt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File:
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category:
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
uint32 version;
|
||||||
|
uint32 num_entries;
|
||||||
|
|
||||||
|
typedef struct Entry {
|
||||||
|
uint64 type <format=hex>;
|
||||||
|
uint64 name <format=hex>;
|
||||||
|
};
|
||||||
|
|
||||||
|
Entry entries[num_entries];
|
22
dt_strings.bt
Normal file
22
dt_strings.bt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: dt_strings.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version: 1.0
|
||||||
|
// Purpose: Darktide Strings
|
||||||
|
// Category: Darktide
|
||||||
|
// File Mask: *.strings
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
uint32 header <hidden=true>;
|
||||||
|
uint32 count;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 name_hash <format=hex>;
|
||||||
|
uint32 address <format=hex>;
|
||||||
|
} Entry;
|
||||||
|
|
||||||
|
Entry entries[count];
|
19
dt_texture.bt
Normal file
19
dt_texture.bt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File:
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category:
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
uint32 type;
|
||||||
|
|
||||||
|
uint32 compressed_size;
|
||||||
|
uint32 decompressed_size;
|
||||||
|
|
||||||
|
byte data[compressed_size];
|
95
dt_texture_compressed.bt
Normal file
95
dt_texture_compressed.bt
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 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] <format=hex, bgcolor=0x888545>;
|
||||||
|
|
||||||
|
// 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 <comment="Always 67 (0x43), so maybe a format/type specifier.">;
|
||||||
|
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 <format=binary, comment="Some bitflags.">;
|
||||||
|
|
||||||
|
// 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] <bgcolor=0x9b86d3, fgcolor=0xb2dbeb>;
|
||||||
|
|
||||||
|
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 <hidden=true>;
|
||||||
|
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 <hidden=true>;
|
||||||
|
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 <format=hex, comment="An IdString32">;
|
||||||
|
|
||||||
|
// 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
|
33
dt_wwise_bank.bt
Normal file
33
dt_wwise_bank.bt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: dt_wwise_bank.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Darktide
|
||||||
|
// File Mask: *.wwise_bank
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
uint32 version <format=hex>;
|
||||||
|
Assert(version == 0x1b);
|
||||||
|
uint32 length;
|
||||||
|
|
||||||
|
// A section of values that don't belong the actual Wwise bank
|
||||||
|
struct {
|
||||||
|
uint32 unknown1;
|
||||||
|
Assert(unknown1 == 0x0);
|
||||||
|
// Matches the file itself
|
||||||
|
uint64 this_file <format=hex>;
|
||||||
|
uint32 unknown2;
|
||||||
|
Assert(unknown2 == 0x20);
|
||||||
|
uint32 unknown3;
|
||||||
|
Assert(unknown3 == 0x0);
|
||||||
|
} header;
|
||||||
|
|
||||||
|
struct bnk
|
||||||
|
{
|
||||||
|
#include "bnk.bt";
|
||||||
|
} wwise_bank <open=true>;
|
68
dt_wwise_event.bt
Normal file
68
dt_wwise_event.bt
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: dt_wwise_event.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Darktide
|
||||||
|
// File Mask: *.wwise_event
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
File Definition:
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
uint32 version <format=hex>;
|
||||||
|
Assert(version == 0x1b);
|
||||||
|
uint32 length;
|
||||||
|
|
||||||
|
// A section of values that don't belong the actual Wwise bank
|
||||||
|
struct {
|
||||||
|
uint32 unknown1;
|
||||||
|
Assert(unknown1 == 0x0);
|
||||||
|
// Matches the file itself
|
||||||
|
uint64 this_file <format=hex>;
|
||||||
|
uint32 unknown2;
|
||||||
|
Assert(unknown2 == 0x40);
|
||||||
|
uint32 unknown3;
|
||||||
|
Assert(unknown3 == 0x0);
|
||||||
|
|
||||||
|
// The following hash-like values will probably define some of these values:
|
||||||
|
// - name of the event
|
||||||
|
// - Wwise bus the event runs on
|
||||||
|
|
||||||
|
// Corresponds to the `id` value of a HIRC object of type "event" later on in the file
|
||||||
|
uint32 hirc_event_id <format=hex>;
|
||||||
|
|
||||||
|
// No particularly clear value.
|
||||||
|
// Sometimes when interpreted as `float`, it produces whole numbers.
|
||||||
|
// Sometimes, it's very close to `0xFFFFFFFF`.
|
||||||
|
uint32 unknown4;
|
||||||
|
|
||||||
|
// Following two usually look like hashes.
|
||||||
|
// Also often reasonably looking floats close to `1`. Could be something like volume.
|
||||||
|
// Would still fit with it sometimes showing up elsewhere in a `.wwise_bank`: It's not unreasonable
|
||||||
|
// for the bnk to have volume values as well.
|
||||||
|
|
||||||
|
// In at least one instance, shows up in `MotionBus`/`MotionFX` sections in a `.wwise_bank`.
|
||||||
|
uint32 unknown5 <format=hex, comment="Looks like a short hash">;
|
||||||
|
// At least in one instance, this was identical with `unknown6`
|
||||||
|
uint32 unknown6 <format=hex, comment="Looks like a short hash">;
|
||||||
|
|
||||||
|
uint32 unknown7;
|
||||||
|
Assert(unknown7 == 0x0 || unknown7 == 0x1);
|
||||||
|
uint32 unknown8;
|
||||||
|
Assert(unknown8 == 0x0 || unknown8 == 0x1);
|
||||||
|
uint32 unknown9;
|
||||||
|
Assert(unknown9 == 0x0);
|
||||||
|
uint32 unknown10;
|
||||||
|
Assert(unknown10 == 0x0);
|
||||||
|
} header;
|
||||||
|
|
||||||
|
struct bnk
|
||||||
|
{
|
||||||
|
#include "bnk.bt";
|
||||||
|
} wwise_bank <open=true>;
|
22
dt_wwise_stream.bt
Executable file
22
dt_wwise_stream.bt
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: dt_wwise_stream.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Darktide
|
||||||
|
// File Mask: *.wwise_stream
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
// Could be the version, but 27 different versions of a file that only contains an offset seems unlikely
|
||||||
|
uint32 unknown1;
|
||||||
|
Assert(unknown1 == 0x1b);
|
||||||
|
|
||||||
|
// Offset and length of the section within the `.stream` file.
|
||||||
|
// Since all `.wwise_stream` files seem to get their own `.stream` file, `offset` always ends up being `0`,
|
||||||
|
// and `length` always ends up matching the `.stream` file's size.
|
||||||
|
uint32 offset;
|
||||||
|
uint32 length;
|
47
vt2_bundle.bt
Normal file
47
vt2_bundle.bt
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v10.0 Binary Template
|
||||||
|
//
|
||||||
|
// File:
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose: Vermintide 2 Decompressed Bundle
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
typedef struct {
|
||||||
|
uint64 type <format=hex,bgcolor=0x0015FF>;
|
||||||
|
uint64 name <format=hex,bgcolor=0x0010BF>;
|
||||||
|
uint32 padding;
|
||||||
|
// Data size for all versions combined
|
||||||
|
uint32 data_size;
|
||||||
|
} Metadata;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 lang;
|
||||||
|
uint32 size;
|
||||||
|
uint32 stream_size;
|
||||||
|
} FileVersion;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint64 type <format=hex,bgcolor=0x0015FF>;
|
||||||
|
uint64 name <format=hex,bgcolor=0x0010BF>;
|
||||||
|
uint32 version_count;
|
||||||
|
uint32 stream_offset;
|
||||||
|
FileVersion versions[version_count];
|
||||||
|
|
||||||
|
local int i = 0;
|
||||||
|
for (i = 0; i < version_count; i++) {
|
||||||
|
struct FileData {
|
||||||
|
uchar data[versions[i].size];
|
||||||
|
} file_data;
|
||||||
|
}
|
||||||
|
} File;
|
||||||
|
|
||||||
|
|
||||||
|
uint32 item_count;
|
||||||
|
uint64 properties[32] <format=hex>;
|
||||||
|
|
||||||
|
Metadata items[item_count];
|
||||||
|
File files[item_count] <optimize=false>;
|
38
vt2_compressed_bundle.bt
Normal file
38
vt2_compressed_bundle.bt
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v10.0 Binary Template
|
||||||
|
//
|
||||||
|
// File:
|
||||||
|
// Authors:
|
||||||
|
// Version:
|
||||||
|
// Purpose: Vermintide 2 Compressed Bundle
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask:
|
||||||
|
// ID Bytes:
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
uint32 format <format=hex>;
|
||||||
|
uint32 inflate_size;
|
||||||
|
|
||||||
|
uint32 padding <hidden=true>;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 block_size;
|
||||||
|
uchar data[block_size];
|
||||||
|
} Block <read=ReadBlock>;
|
||||||
|
|
||||||
|
string ReadBlock(Block &block)
|
||||||
|
{
|
||||||
|
if(exists(block.block_size)) {
|
||||||
|
string s;
|
||||||
|
SPrintf(s, "%lg", block.block_size);
|
||||||
|
return s;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// No clue how to do "until there is nothing left" with this, so I'll just make up a number
|
||||||
|
// This is good enough to show the concept anyways
|
||||||
|
local uint block_count = 100;
|
||||||
|
Block blocks[block_count] <optimize=false>;
|
126
vt2_level.bt
Normal file
126
vt2_level.bt
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v12.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_level.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.level
|
||||||
|
// ID Bytes: B5 00 00 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
// See <https://gitlab.com/IstotI/vtextract/-/blob/master/Assets%20Types/Converters/LevelConversion.cs>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} Vector3;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
} Quaternion;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 unknown_1 <format=hex>;
|
||||||
|
uint32 unknown_2 <format=hex>;
|
||||||
|
// unknown before this
|
||||||
|
// maps directly to the keys of the same name, as murmur64 hashes
|
||||||
|
uint64 id_hash <format=hex>; // has to be there
|
||||||
|
uint64 name_hash <format=hex>; // Will be `0x0` when no name was given
|
||||||
|
uint64 type_hash <format=hex>; // has to be there
|
||||||
|
uint64 material_hash <format=hex>; // will be `0x0` when not given
|
||||||
|
|
||||||
|
// defaults to 0, 0, 0
|
||||||
|
Vector3 pos;
|
||||||
|
// defaults to 0, 0, 0, 0
|
||||||
|
Quaternion rot;
|
||||||
|
// Not sure why they felt the need to abbreviate "scale". Defaults to 1, 1, 1
|
||||||
|
Vector3 scl;
|
||||||
|
// unknown after this
|
||||||
|
} Unit;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 name <format=hex>; // murmur64-half
|
||||||
|
uint64 resource <format=hex>; // murmur64
|
||||||
|
} Material;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 unit_id;
|
||||||
|
uint32 num_materials;
|
||||||
|
|
||||||
|
Material materials[num_materials];
|
||||||
|
} UnitMaterials;
|
||||||
|
|
||||||
|
// File Parsing
|
||||||
|
|
||||||
|
uint32 version <format=hex>; // correct
|
||||||
|
uint32 num_units; // correct
|
||||||
|
uint32 num_background_units; // correct
|
||||||
|
|
||||||
|
uint32 section_address_unit_data <format=hex>; //Unit Data & Level Settings
|
||||||
|
uint32 section_address_unknown1 <format=hex>;
|
||||||
|
uint32 section_address_prototypes <format=hex>;
|
||||||
|
uint32 section_address_prototypes_data_size <format=hex>; //Or adress to prototypes collision
|
||||||
|
uint32 section_address_unknown2 <format=hex>;
|
||||||
|
uint32 section_address_unknown3 <format=hex>;
|
||||||
|
uint32 section_address_unknown4 <format=hex>;
|
||||||
|
uint32 section_address_unknown5 <format=hex>;
|
||||||
|
uint32 section_address_unknown6 <format=hex>;
|
||||||
|
uint32 section_address_unknown7 <format=hex>;
|
||||||
|
uint32 section_address_unknown8 <format=hex>;
|
||||||
|
uint32 section_address_level_settings <format=hex>;
|
||||||
|
uint32 particles_count;
|
||||||
|
uint32 section_address_particles <format=hex>;
|
||||||
|
uint32 section_address_unknown12 <format=hex>;
|
||||||
|
uint32 section_address_unknown13 <format=hex>;
|
||||||
|
uint32 section_address_unknown14 <format=hex>;
|
||||||
|
uint32 section_address_unknown15 <format=hex>;
|
||||||
|
uint32 section_address_unknown16 <format=hex>;
|
||||||
|
uint32 section_address_unknown17 <format=hex>;
|
||||||
|
uint32 section_address_unknown18 <format=hex>;
|
||||||
|
uint32 section_address_unknown19 <format=hex>;
|
||||||
|
uint32 section_address_unknown20 <format=hex>;
|
||||||
|
uint32 section_address_unknown21 <format=hex>;
|
||||||
|
uint32 section_address_unknown22 <format=hex>;
|
||||||
|
uint32 section_address_stories <format=hex>;
|
||||||
|
uint32 section_address_unknown24 <format=hex>;
|
||||||
|
uint32 section_address_unknown25 <format=hex>;
|
||||||
|
uint32 section_address_unknown26 <format=hex>;
|
||||||
|
uint32 section_address_unknown27 <format=hex>;
|
||||||
|
uint32 section_address_unknown28 <format=hex>;
|
||||||
|
uint32 section_address_unknown29 <format=hex>;
|
||||||
|
uint32 section_address_unit_materials <format=hex>;
|
||||||
|
uint32 section_address_unknown31 <format=hex>;
|
||||||
|
uint32 section_address_unknown32 <format=hex>;
|
||||||
|
uint32 section_address_unknown33 <format=hex>;
|
||||||
|
|
||||||
|
uint32 num_settings_entries;
|
||||||
|
|
||||||
|
// section start: unit, position unknown:
|
||||||
|
Unit units[num_units];
|
||||||
|
|
||||||
|
FSeek(section_address_unit_materials);
|
||||||
|
uint32 num_unit_materials;
|
||||||
|
UnitMaterials unit_materials[num_unit_materials];
|
||||||
|
|
||||||
|
// section end
|
||||||
|
|
||||||
|
uint32 len_sound_environment; // position unknown
|
||||||
|
byte sound_environment[len_sound_environment];
|
||||||
|
|
||||||
|
if (len_sound_environment < 4) {
|
||||||
|
byte padding_1[4 - (len_sound_environment % 4)]; // guess
|
||||||
|
}
|
||||||
|
byte unknown_3[3 * 4];
|
||||||
|
|
||||||
|
uint32 len_timpani_sound_environment; // position unknown
|
||||||
|
byte timpani_sound_environment[len_timpani_sound_environment];
|
||||||
|
|
||||||
|
if (len_timpani_sound_environment < 4) {
|
||||||
|
byte padding_2[4 - (len_timpani_sound_environment % 4)]; // guess
|
||||||
|
}
|
101
vt2_nav_data.bt
Normal file
101
vt2_nav_data.bt
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v11.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_nav_data.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.(NavData|nav_data)
|
||||||
|
// ID Bytes: 42 6C 6F 62 41 67 67 46 69 6C 65 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
string file_type;
|
||||||
|
uint32 unknown_1;
|
||||||
|
if (unknown_1 != 0)
|
||||||
|
return "Unexpected value";
|
||||||
|
|
||||||
|
|
||||||
|
// Equals `02` for empty.level, `03` for all others so far
|
||||||
|
// The empty level was missing a section, so that's likely the count for it
|
||||||
|
uint32 count_sections;
|
||||||
|
|
||||||
|
// TODO: Create an enum for section types and make this section stuff proper
|
||||||
|
struct {
|
||||||
|
uint32 section_1_type;
|
||||||
|
if (section_1_type != 0x0500)
|
||||||
|
return "Unexpected value";
|
||||||
|
|
||||||
|
uint32 unknown_4;
|
||||||
|
if (unknown_4 != 0)
|
||||||
|
return "Unexpected value";
|
||||||
|
|
||||||
|
|
||||||
|
// Both always `0x28`
|
||||||
|
uint32 unknown_5;
|
||||||
|
uint32 unknown_6;
|
||||||
|
|
||||||
|
uint32 build_string_length;
|
||||||
|
|
||||||
|
// Always `0x04`
|
||||||
|
uint32 unknown_8;
|
||||||
|
|
||||||
|
char build_string[build_string_length];
|
||||||
|
|
||||||
|
// Padding to get `build_string_length` to divide by 4 (technically `sizeof(uint32)`)
|
||||||
|
if (build_string_length % 4 != 0) {
|
||||||
|
byte build_string_padding[4 - (build_string_length % 4)];
|
||||||
|
}
|
||||||
|
} Header;
|
||||||
|
|
||||||
|
uint32 section_2_type;
|
||||||
|
if (section_2_type == 0x01) {
|
||||||
|
|
||||||
|
uint32 count_nav_meshes;
|
||||||
|
|
||||||
|
struct NavMesh {
|
||||||
|
uint32 data_length;
|
||||||
|
// Could be length of the following section
|
||||||
|
uint32 section_length;
|
||||||
|
|
||||||
|
byte data[data_length];
|
||||||
|
} nav_meshes[count_nav_meshes] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 section_3_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 unknown_12;
|
||||||
|
// For any non-empty navdata, this seems to increas by 4
|
||||||
|
uint32 unknown_13;
|
||||||
|
// Seems to be always the same as `unknown_13`
|
||||||
|
uint32 unknown_14;
|
||||||
|
uint32 unknown_15;
|
||||||
|
uint32 unknown_16;
|
||||||
|
uint32 unknown_17;
|
||||||
|
uint32 unknown_18;
|
||||||
|
uint32 unknown_19;
|
||||||
|
uint32 unknown_20;
|
||||||
|
uint32 unknown_21;
|
||||||
|
uint32 unknown_22;
|
||||||
|
|
||||||
|
// Not actually null-terminated
|
||||||
|
char header_sector_descriptor[16];
|
||||||
|
|
||||||
|
struct SectorDescriptor{
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 sector_name_header_length;
|
||||||
|
uint32 unknown_3;
|
||||||
|
uint32 sector_name_value_length;
|
||||||
|
uint32 generator_type_name_length;
|
||||||
|
uint32 unknown_6;
|
||||||
|
uint32 unknown_7;
|
||||||
|
uint32 unknown_8;
|
||||||
|
uint32 unknown_9;
|
||||||
|
} sector_descriptor;
|
||||||
|
|
||||||
|
// Terminated by two! nulls
|
||||||
|
char header_sector_name[sector_descriptor.sector_name_header_length];
|
||||||
|
// Padding to get string length to divide by 4 (technically `sizeof(uint32)`)
|
||||||
|
byte header_sector_name_padding[4 - (sector_descriptor.sector_name_header_length % 4)];
|
||||||
|
string sector_name;
|
40
vt2_network_config.bt
Normal file
40
vt2_network_config.bt
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v11.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_network_config.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.network_config
|
||||||
|
// ID Bytes: 20 00 00 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
typedef enum<UINT32> {
|
||||||
|
PeerToPeer,
|
||||||
|
ClientServer
|
||||||
|
} NetworkType;
|
||||||
|
|
||||||
|
typedef enum<BYTE> {
|
||||||
|
Int = 0x01,
|
||||||
|
Int64 = 0x07,
|
||||||
|
GamerObjectId = 0x34
|
||||||
|
} Primitive;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Primitive primitive;
|
||||||
|
uint16 bits;
|
||||||
|
uint32 padding;
|
||||||
|
uint32 name_hash;
|
||||||
|
uint32 tolerance;
|
||||||
|
uint32 min; // Possibly 'min' for number values
|
||||||
|
uint32 max;
|
||||||
|
} Type;
|
||||||
|
|
||||||
|
uint32 version;
|
||||||
|
NetworkType network_type;
|
||||||
|
uint32 reliable_send_buffer_size;
|
||||||
|
uint32 reliable_receive_buffer_size;
|
||||||
|
|
||||||
|
uint32 num_types <hidden=true>;
|
||||||
|
Type types[num_types];
|
92
vt2_network_config_new.bt
Normal file
92
vt2_network_config_new.bt
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v11.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_network_config_new.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.network_config
|
||||||
|
// ID Bytes: 23 00 00 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
typedef enum<BYTE> {
|
||||||
|
Bool,
|
||||||
|
Int,
|
||||||
|
Float,
|
||||||
|
Vector3,
|
||||||
|
Quaternion,
|
||||||
|
String,
|
||||||
|
Int64 = 0x07,
|
||||||
|
Array,
|
||||||
|
GamerObjectId = 0x34
|
||||||
|
} Primitive;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 name_hash;
|
||||||
|
uint32 padding;
|
||||||
|
uint32 data_1;
|
||||||
|
Primitive primitive;
|
||||||
|
uint16 bits;
|
||||||
|
byte unknown_1;
|
||||||
|
uint32 min; // Possibly 'min' for number values
|
||||||
|
uint32 max;
|
||||||
|
} Type;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 index;
|
||||||
|
} ObjectField;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 index;
|
||||||
|
} ObjectFieldType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
} ObjectFieldName;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 name_hash;
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 unknown_2;
|
||||||
|
float priority;
|
||||||
|
float update_rate;
|
||||||
|
uint32 num_field_types <hidden=true>;
|
||||||
|
ObjectFieldType object_field_types[num_field_types];
|
||||||
|
uint32 num_field_names <hidden=true>;
|
||||||
|
if (num_field_names != num_field_types)
|
||||||
|
return "Number of objects types and names doesn't match";
|
||||||
|
ObjectFieldName object_field_names[num_field_names];
|
||||||
|
} Object;
|
||||||
|
|
||||||
|
// Templates don't support defining an array of null-terminated strings,
|
||||||
|
// so we need to wrap it into a struct
|
||||||
|
typedef struct {
|
||||||
|
string name;
|
||||||
|
} ObjectName;
|
||||||
|
|
||||||
|
uint32 version;
|
||||||
|
uint32 reliable_send_buffer_size;
|
||||||
|
uint32 reliable_receive_buffer_size;
|
||||||
|
|
||||||
|
uint32 num_types <hidden=true>;
|
||||||
|
Type types[num_types];
|
||||||
|
|
||||||
|
uint32 num_object_names <hidden=true>;
|
||||||
|
uint16 object_start_positions[num_object_names] <hidden=true>;
|
||||||
|
uint32 total_names_length <hidden=true>;
|
||||||
|
|
||||||
|
// By default the array would be optimized to truncate every entry
|
||||||
|
// to the length of the first one.
|
||||||
|
ObjectName object_names[num_object_names] <optimize=false, open=false, hidden=true>;
|
||||||
|
|
||||||
|
uint32 padding_length <hidden=true>;
|
||||||
|
FSkip(padding_length);
|
||||||
|
|
||||||
|
uint32 num_objects <hidden=false>;
|
||||||
|
|
||||||
|
if (num_object_names != num_objects)
|
||||||
|
return "Number of objects and names doesn't match";
|
||||||
|
|
||||||
|
Object objects[num_objects] <optimize=false, open=false>;
|
22
vt2_strings.bt
Normal file
22
vt2_strings.bt
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v10.0 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_strings.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version: 1.0
|
||||||
|
// Purpose: Vermintide 2 Strings
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.strings
|
||||||
|
// ID Bytes: AE F3 85 3E
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
uint32 header <hidden=true>;
|
||||||
|
uint32 count;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 name_hash <format=hex>;
|
||||||
|
uint32 address <format=hex>;
|
||||||
|
} A;
|
||||||
|
|
||||||
|
A a[count];
|
466
vt2_unit.bt
Normal file
466
vt2_unit.bt
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v11.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_unit.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.unit
|
||||||
|
// ID Bytes: BA 00 00 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
// See <https://gitlab.com/IstotI/vtextract/-/blob/master/Assets%20Types/Converters/UnitConversion.cs>
|
||||||
|
|
||||||
|
// Type Definitions
|
||||||
|
|
||||||
|
// 16 byte
|
||||||
|
typedef struct {
|
||||||
|
float row_1[4];
|
||||||
|
float row_2[4];
|
||||||
|
float row_3[4];
|
||||||
|
float row_4[4];
|
||||||
|
} Matrix4x4;
|
||||||
|
|
||||||
|
// 3 byte
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} Vector3;
|
||||||
|
|
||||||
|
// 7 byte
|
||||||
|
typedef struct {
|
||||||
|
float lx;
|
||||||
|
float ly;
|
||||||
|
float lz;
|
||||||
|
|
||||||
|
float ux;
|
||||||
|
float uy;
|
||||||
|
float uz;
|
||||||
|
|
||||||
|
byte unknown[4];
|
||||||
|
} Bounds;
|
||||||
|
|
||||||
|
// 21 byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 data_size;
|
||||||
|
byte data[data_size];
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 unknown_2;
|
||||||
|
uint32 num_elements;
|
||||||
|
uint32 element_size;
|
||||||
|
} MeshSection;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
uint32 type;
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 index;
|
||||||
|
byte unknown_2;
|
||||||
|
} MeshChannelDefinition;
|
||||||
|
|
||||||
|
// 4 + (x * 21) byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 num_streams;
|
||||||
|
struct Stream {
|
||||||
|
uint32 data_size;
|
||||||
|
hfloat data[data_size / 2];
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 unknown_2;
|
||||||
|
uint32 num_elements;
|
||||||
|
uint32 element_size;
|
||||||
|
} streams[num_streams] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 num_streams_2 <hidden=true>;
|
||||||
|
struct StreamMeta {
|
||||||
|
uint32 name;
|
||||||
|
uint32 type;
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 index;
|
||||||
|
byte unknown_2;
|
||||||
|
} stream_meta[num_streams] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 unknown_2;
|
||||||
|
// Apparently the number of vertices with position values
|
||||||
|
// that don't fit in a single short/uint16
|
||||||
|
// When > 0, indicates that following data should be read as uint32
|
||||||
|
// instead
|
||||||
|
uint32 unknown_3;
|
||||||
|
|
||||||
|
uint32 num_index_stream_data;
|
||||||
|
uint32 size_index_stream_data;
|
||||||
|
// this means each entrie's size is `size_stream_data / num_stream_data`
|
||||||
|
if (size_index_stream_data / num_index_stream_data == 2) {
|
||||||
|
uint16 index_stream_data[num_index_stream_data];
|
||||||
|
} else {
|
||||||
|
byte index_stream_data[size_index_stream_data];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 num_materials;
|
||||||
|
struct Material {
|
||||||
|
uint32 id;
|
||||||
|
uint32 tri_array_start;
|
||||||
|
uint32 tri_count;
|
||||||
|
uint32 unknown;
|
||||||
|
} materials[num_materials];
|
||||||
|
|
||||||
|
Bounds bounds;
|
||||||
|
|
||||||
|
uint32 num_materials_2 <hidden=true>;
|
||||||
|
uint32 material_names[num_materials_2];
|
||||||
|
} Geometry;
|
||||||
|
|
||||||
|
// 4 + (x * 16) + (x * 4) byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 num_bones;
|
||||||
|
Matrix4x4 matrix[num_bones];
|
||||||
|
uint32 bone_ids[num_bones];
|
||||||
|
} Skin;
|
||||||
|
|
||||||
|
// 15 byte
|
||||||
|
typedef struct {
|
||||||
|
Vector3 localXAxis;
|
||||||
|
Vector3 localYAxis;
|
||||||
|
Vector3 localZAxis;
|
||||||
|
Vector3 localPosition;
|
||||||
|
Vector3 localScale;
|
||||||
|
} NodeLocal;
|
||||||
|
|
||||||
|
// 4 byte
|
||||||
|
typedef struct {
|
||||||
|
uint16 unknown;
|
||||||
|
// Index into `num_nodes`
|
||||||
|
uint16 parent_id;
|
||||||
|
} NodeExtra;
|
||||||
|
|
||||||
|
enum <uint32> NodeFlags {
|
||||||
|
// Rarely set, since renderables with this value aren't included
|
||||||
|
// for compilation by default
|
||||||
|
VIEWPORT_VISIBLE=1,
|
||||||
|
SHADOW_CASTER=2,
|
||||||
|
CULLING_DISABLED=4,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 27 byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 parent;
|
||||||
|
uint32 name;
|
||||||
|
uint32 num_geometries;
|
||||||
|
uint32 geometry_name[num_geometries];
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 unknown_2;
|
||||||
|
uint32 unknown_3;
|
||||||
|
// Flags set in the .unit file
|
||||||
|
// Usually set to `1`, since hidden renderables are skipped
|
||||||
|
// during compilation by default
|
||||||
|
uint32 viewport_visible : 1;
|
||||||
|
uint32 shadow_caster : 1;
|
||||||
|
// Need to check if this is really defined as a negative, as implied by the name
|
||||||
|
// Usually, you should name booleans after the positive value to minimize confusion.
|
||||||
|
uint32 culling_disabled : 1;
|
||||||
|
uint32 occluder : 1;
|
||||||
|
uint32 surface_queries : 1;
|
||||||
|
uint32 always_keep : 1;
|
||||||
|
Bounds bounds;
|
||||||
|
} Node;
|
||||||
|
|
||||||
|
// 12 byte
|
||||||
|
//typedef struct {
|
||||||
|
// uint32 name;
|
||||||
|
// uint64 resource;
|
||||||
|
//} Material;
|
||||||
|
|
||||||
|
enum <uint32> ActorShapeType {
|
||||||
|
Sphere,
|
||||||
|
Box,
|
||||||
|
Capsule,
|
||||||
|
MESH,
|
||||||
|
Convex,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 32 + x + (1, 2, 3, ?) byte
|
||||||
|
typedef struct {
|
||||||
|
ActorShapeType type;
|
||||||
|
uint32 material;
|
||||||
|
uint32 template;
|
||||||
|
Matrix4x4 pose;
|
||||||
|
uint32 physx_data_size;
|
||||||
|
byte physx_data[physx_data_size];
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 0:
|
||||||
|
byte shape_shpere_radius;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
byte shape_box_half_size_x;
|
||||||
|
byte shape_box_half_size_y;
|
||||||
|
byte shape_box_half_size_z;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
byte shape_capsule_radius;
|
||||||
|
byte shape_capsule_length;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return "ActorShapeType.MESH not implemented";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
return "ActorShapeType.Convex not implemented";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} Shape;
|
||||||
|
|
||||||
|
// 17 + (x * (32 + y + (1, 2, 3, ?))) byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
uint32 template;
|
||||||
|
uint32 node;
|
||||||
|
byte mass;
|
||||||
|
uint32 num_shapes;
|
||||||
|
Shape shapes[num_shapes] <optimize=false>;
|
||||||
|
} Actor;
|
||||||
|
|
||||||
|
// 15 byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
uint32 unknown_1;
|
||||||
|
byte near_range;
|
||||||
|
byte far_range;
|
||||||
|
byte vertical_fov;
|
||||||
|
uint32 unknown_2;
|
||||||
|
} Camera;
|
||||||
|
|
||||||
|
enum <uint32> LightType {
|
||||||
|
Omni,
|
||||||
|
Spot,
|
||||||
|
BOX,
|
||||||
|
Directional,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef byte boolean;
|
||||||
|
|
||||||
|
// 35 + (6, 8) byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
uint32 node_id;
|
||||||
|
byte color_r;
|
||||||
|
byte color_g;
|
||||||
|
byte color_b;
|
||||||
|
|
||||||
|
// Should both be 1
|
||||||
|
byte check_1;
|
||||||
|
byte check_2;
|
||||||
|
|
||||||
|
LightType type;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 0: // Fallthrough
|
||||||
|
case 1:
|
||||||
|
byte falloff_start;
|
||||||
|
byte falloff_end;
|
||||||
|
byte unknown_1;
|
||||||
|
byte spot_angle_start;
|
||||||
|
byte spot_angle_end;
|
||||||
|
byte unknown_2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
byte box_min_x;
|
||||||
|
byte box_min_y;
|
||||||
|
byte box_min_z;
|
||||||
|
byte box_max_x;
|
||||||
|
byte box_max_y;
|
||||||
|
byte box_max_z;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
uint unknown_1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean cast_shadows;
|
||||||
|
byte bs[17];
|
||||||
|
} Light;
|
||||||
|
|
||||||
|
// 21 byte
|
||||||
|
typedef struct {
|
||||||
|
byte step_end;
|
||||||
|
byte step_start;
|
||||||
|
uint32 num_renderables;
|
||||||
|
uint32 renderable_id[num_renderables];
|
||||||
|
Bounds bounding_volume;
|
||||||
|
uint32 unknown_flags;
|
||||||
|
} LODSteps;
|
||||||
|
|
||||||
|
// 12 + (x * 21) byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
uint32 orientation;
|
||||||
|
uint32 num_steps;
|
||||||
|
LODSteps steps[num_steps];
|
||||||
|
} LOD;
|
||||||
|
|
||||||
|
// 19 byte
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
byte height;
|
||||||
|
byte radius;
|
||||||
|
uint32 collision_filter;
|
||||||
|
byte slope_limit;
|
||||||
|
byte ffx8[8];
|
||||||
|
} Mover;
|
||||||
|
|
||||||
|
// 8 + (x * 4)
|
||||||
|
typedef struct {
|
||||||
|
uint32 name;
|
||||||
|
uint32 num_members;
|
||||||
|
uint32 renderable_ids[num_members];
|
||||||
|
} VisibilityGroup;
|
||||||
|
|
||||||
|
// File Parsing
|
||||||
|
|
||||||
|
uint32 version;
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Meshes
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_geometries;
|
||||||
|
Geometry geometries[num_geometries] <optimize=false>;
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Skins
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_skins;
|
||||||
|
Skin skins[num_skins] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 size_unknown_1;
|
||||||
|
byte unknown_1[size_unknown_1];
|
||||||
|
uint32 num_unknown_2;
|
||||||
|
uint32 unknown_2[num_unknown_2];
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Nodes
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_nodes;
|
||||||
|
NodeLocal node_locals[num_nodes];
|
||||||
|
Matrix4x4 node_world_poses[num_nodes];
|
||||||
|
|
||||||
|
// Should be 0
|
||||||
|
uint32 unknown_3;
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Renderables
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_nodes;
|
||||||
|
Node nodes[num_nodes] <optimize=false>;
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Physics
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_actors;
|
||||||
|
Actor actors[num_actors] <optimize=false>;
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Cameras
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_cameras;
|
||||||
|
Camera cameras[num_cameras];
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Lights
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_lights;
|
||||||
|
Light lights[num_lights];
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// LOD
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_lods;
|
||||||
|
LOD lods[num_lods];
|
||||||
|
|
||||||
|
// Should both be 0. Sections I don't know yet?
|
||||||
|
uint32 unknown_4;
|
||||||
|
uint32 unknown_5;
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Movers
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_movers;
|
||||||
|
Mover movers[num_movers];
|
||||||
|
|
||||||
|
// Should be 0. Section I don't know yet?
|
||||||
|
uint32 unknown_6;
|
||||||
|
|
||||||
|
boolean unknown_has_animation_blender_bones;
|
||||||
|
|
||||||
|
uint32 str_length;
|
||||||
|
char str[str_length];
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Script Data
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 script_data_size;
|
||||||
|
byte script_data[script_data_size];
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Visibility Group
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
uint32 num_visibility_groups;
|
||||||
|
VisibilityGroup visibility_groups[num_visibility_groups];
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Unknown
|
||||||
|
// ===================
|
||||||
|
|
||||||
|
// Probably related to scripting/Flow
|
||||||
|
// When there is data, it contains strings that look like function calls
|
||||||
|
uint32 size_flow_data_1;
|
||||||
|
byte flow_data_1[size_flow_data_1];
|
||||||
|
uint32 size_flow_data_2;
|
||||||
|
byte flow_data_2[size_flow_data_2];
|
||||||
|
|
||||||
|
// ===================
|
||||||
|
// Materials
|
||||||
|
// ===================
|
||||||
|
uint32 size_material_definition;
|
||||||
|
uint32 num_materials;
|
||||||
|
struct MaterialDefinition {
|
||||||
|
// Probably the index into the other material section
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 num_primitives;
|
||||||
|
uint32 unknown_2;
|
||||||
|
uint32 num_primitives_2;
|
||||||
|
uint32 unknown_3;
|
||||||
|
// Fits for the 6 vectors, but not for the last `unknown`.
|
||||||
|
Bounds bounds;
|
||||||
|
uint32 num_primitives_3;
|
||||||
|
uint32 primitives[num_primitives_3];
|
||||||
|
} material_definitions[num_materials] <optimize=false>;
|
||||||
|
|
||||||
|
// Should be 0. Sections I don't know yet?
|
||||||
|
uint32 unknown_7;
|
||||||
|
uint32 unknown_8;
|
||||||
|
uint32 unknown_9;
|
||||||
|
uint32 unknown_10;
|
||||||
|
|
||||||
|
// Apparently doesn't have to match the previous `num_materials`
|
||||||
|
uint32 num_materials_2;
|
||||||
|
struct MaterialResources {
|
||||||
|
uint32 name;
|
||||||
|
uint64 resource;
|
||||||
|
} material_resources[num_materials_2];
|
||||||
|
|
||||||
|
// Should be 0. Sections I don't know yet?
|
||||||
|
uint32 unknown_11;
|
||||||
|
uint32 unknown_12;
|
||||||
|
uint32 unknown_13;
|
||||||
|
uint32 unknown_14;
|
51
vt2_unit_186
Normal file
51
vt2_unit_186
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v11.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_unit_186.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.unit
|
||||||
|
// ID Bytes: BA 00 00 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// =============
|
||||||
|
// Mesh Geometry
|
||||||
|
// =============
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32 data_length;
|
||||||
|
char data[data_length];
|
||||||
|
uint32 validity;
|
||||||
|
uint32 stream_type;
|
||||||
|
uint32 count;
|
||||||
|
uint32 stride;
|
||||||
|
} VertexBuffer;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32 buffer_count;
|
||||||
|
VertexBuffer vertex_buffers[buffer_count];
|
||||||
|
} MeshGeometry;
|
||||||
|
|
||||||
|
// TODO: vertex buffers
|
||||||
|
|
||||||
|
// TODO: index buffers
|
||||||
|
// TODO: batch range
|
||||||
|
// TODO: bounding volume
|
||||||
|
// TODO: materials
|
||||||
|
|
||||||
|
// TODO: skin data
|
||||||
|
// TODO: simple animation
|
||||||
|
// TODO: simple animation groups
|
||||||
|
// TODO: scene graph
|
||||||
|
// TODO: mesh objects
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// File
|
||||||
|
// ====
|
||||||
|
|
||||||
|
uint version;
|
||||||
|
MeshGeometry mesh_geometry;
|
205
vt2_unit_186.bt
Normal file
205
vt2_unit_186.bt
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v11.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_unit_186.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.unit
|
||||||
|
// ID Bytes: BA 00 00 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
typedef uint32 Murmur32 <format=hex>;
|
||||||
|
typedef uint64 Murmur64 <format=hex>;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} Vector3;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
float w;
|
||||||
|
} Quaternion;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float m11;
|
||||||
|
float m12;
|
||||||
|
float m13;
|
||||||
|
float m14;
|
||||||
|
float m21;
|
||||||
|
float m22;
|
||||||
|
float m23;
|
||||||
|
float m24;
|
||||||
|
float m31;
|
||||||
|
float m32;
|
||||||
|
float m33;
|
||||||
|
float m34;
|
||||||
|
} Matrix3x3;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float m11;
|
||||||
|
float m12;
|
||||||
|
float m13;
|
||||||
|
float m14;
|
||||||
|
float m21;
|
||||||
|
float m22;
|
||||||
|
float m23;
|
||||||
|
float m24;
|
||||||
|
float m31;
|
||||||
|
float m32;
|
||||||
|
float m33;
|
||||||
|
float m34;
|
||||||
|
float m41;
|
||||||
|
float m42;
|
||||||
|
float m43;
|
||||||
|
float m44;
|
||||||
|
} Matrix4x4;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 len_data <hidden=true>;
|
||||||
|
hfloat data[len_data / 2];
|
||||||
|
uint32 validity;
|
||||||
|
uint32 stream_type;
|
||||||
|
uint32 count;
|
||||||
|
uint32 stride;
|
||||||
|
} VertexBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 vertex_component;
|
||||||
|
uint32 type;
|
||||||
|
uint32 set;
|
||||||
|
uint32 stream;
|
||||||
|
byte is_instance;
|
||||||
|
} Channel;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 validity;
|
||||||
|
uint32 stream_type;
|
||||||
|
uint32 index_format;
|
||||||
|
uint32 index_count;
|
||||||
|
uint32 len_indices <hidden=true>;
|
||||||
|
char indices[len_indices];
|
||||||
|
} IndexBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 material_index;
|
||||||
|
uint32 start;
|
||||||
|
uint32 end;
|
||||||
|
uint32 bone_set;
|
||||||
|
} BatchRange;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Vector3 lower_bounds;
|
||||||
|
Vector3 upper_bounds;
|
||||||
|
float radius;
|
||||||
|
} BoundingVolume;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 num_buffers <hidden=true>;
|
||||||
|
VertexBuffer vertex_buffers[num_buffers] <optimize=false>;
|
||||||
|
uint32 num_channels <hidden=true>;
|
||||||
|
if (num_buffers != num_channels)
|
||||||
|
return "Buffer count and Channel count don't match";
|
||||||
|
Channel channels[num_channels];
|
||||||
|
IndexBuffer index_buffer;
|
||||||
|
uint32 num_batch_ranges <hidden=true>;
|
||||||
|
BatchRange batch_ranges[num_batch_ranges] <optimize=false>;
|
||||||
|
BoundingVolume bounding_volume;
|
||||||
|
uint32 num_materials <hidden=true>;
|
||||||
|
Murmur32 materials[num_materials];
|
||||||
|
} MeshGeometry;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 num_index_sets <hidden=true>;
|
||||||
|
uint32 index_sets[num_index_sets];
|
||||||
|
} MatrixIndexSet;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 num_inverse_bind_matrices <hidden=true>;
|
||||||
|
Matrix4x4 inverse_bind_matrices[num_inverse_bind_matrices];
|
||||||
|
uint32 num_node_indices <hidden=true>;
|
||||||
|
uint32 node_indices[num_node_indices];
|
||||||
|
uint32 num_matrix_index_sets <hidden=true>;
|
||||||
|
MatrixIndexSet matrix_index_sets[num_matrix_index_sets];
|
||||||
|
} SkinData;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// TODO: Murmur32?
|
||||||
|
uint32 id;
|
||||||
|
uint32 num_data <hidden=true>;
|
||||||
|
int32 data[num_data];
|
||||||
|
} SimpleAnimationGroup;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 num_nodes <hidden=true>;
|
||||||
|
struct LocalTransform {
|
||||||
|
Vector3 x;
|
||||||
|
Vector3 y;
|
||||||
|
Vector3 z;
|
||||||
|
Vector3 position;
|
||||||
|
Vector3 scale;
|
||||||
|
} local_transform[num_nodes];
|
||||||
|
|
||||||
|
Matrix4x4 world_transform[num_nodes];
|
||||||
|
|
||||||
|
struct ParentNode {
|
||||||
|
uint16 parent_type;
|
||||||
|
uint16 parent_index;
|
||||||
|
} parent_node[num_nodes];
|
||||||
|
|
||||||
|
Murmur32 name[num_nodes];
|
||||||
|
} SceneGraph;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Murmur32 name;
|
||||||
|
uint32 node_index;
|
||||||
|
uint32 geometry_index;
|
||||||
|
uint32 skin_index;
|
||||||
|
uint32 flags;
|
||||||
|
BoundingVolume bounding_volume;
|
||||||
|
} MeshObject;
|
||||||
|
|
||||||
|
|
||||||
|
// ====
|
||||||
|
// File
|
||||||
|
// ====
|
||||||
|
|
||||||
|
uint32 version;
|
||||||
|
|
||||||
|
uint32 num_mesh_geometries <hidden=true>;
|
||||||
|
MeshGeometry mesh_geometry[num_mesh_geometries] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 num_skins <hidden=true>;
|
||||||
|
SkinData skins[num_skins];
|
||||||
|
|
||||||
|
uint32 len_simple_animation <hidden=true>;
|
||||||
|
char simple_animation[len_simple_animation] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 num_simple_animation_groups <hidden=true>;
|
||||||
|
SimpleAnimationGroup simple_animation_groups[num_simple_animation_groups] <optimize=false>;
|
||||||
|
|
||||||
|
SceneGraph scene_graph;
|
||||||
|
|
||||||
|
uint32 num_mesh_objects <hidden=true>;
|
||||||
|
MeshObject mesh_objects[num_mesh_objects];
|
63
vt2_unit_new.bt
Normal file
63
vt2_unit_new.bt
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
//------------------------------------------------
|
||||||
|
//--- 010 Editor v11.0.1 Binary Template
|
||||||
|
//
|
||||||
|
// File: vt2_unit_new.bt
|
||||||
|
// Authors: Lucas Schwiderski
|
||||||
|
// Version:
|
||||||
|
// Purpose:
|
||||||
|
// Category: Vermintide 2
|
||||||
|
// File Mask: *.unit
|
||||||
|
// ID Bytes: BA 00 00 00
|
||||||
|
// History:
|
||||||
|
//------------------------------------------------
|
||||||
|
|
||||||
|
uint32 version;
|
||||||
|
|
||||||
|
// Assuming "MeshGeometry" based on stot's "vkextract"
|
||||||
|
uint32 num_geometries;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 num_index_streams;
|
||||||
|
// One potential content for such a stream is vertex data: 4 half floats.
|
||||||
|
struct IndexStream {
|
||||||
|
uint32 data_size;
|
||||||
|
hfloat data[data_size / 2];
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 unknown_2;
|
||||||
|
uint32 size;
|
||||||
|
uint32 stride;
|
||||||
|
} index_streams[num_index_streams] <optimize=false>;
|
||||||
|
|
||||||
|
uint32 num_streams;
|
||||||
|
|
||||||
|
struct Stream {
|
||||||
|
// One of the unknown uint32 is probably the `index` from .bsi
|
||||||
|
uint32 unknown_1;
|
||||||
|
// `0x11` -> "CT_FLOAT3", `0x0F` -> "CT_FLOAT2"
|
||||||
|
uint32 channel_type;
|
||||||
|
uint32 unknown_2;
|
||||||
|
// Probably the index into `index_streams`
|
||||||
|
uint32 index;
|
||||||
|
byte unknown_3;
|
||||||
|
} streams[num_streams];
|
||||||
|
|
||||||
|
struct StreamData {
|
||||||
|
uint32 unknown_1;
|
||||||
|
uint32 unknown_2;
|
||||||
|
// Apparently the number of vertices with position values
|
||||||
|
// that don't fit in a single short/uint16
|
||||||
|
// When > 0, indicates that following data should be read as uint32
|
||||||
|
// instead
|
||||||
|
uint32 unknown_3;
|
||||||
|
|
||||||
|
uint32 num_stream_data;
|
||||||
|
uint32 size_stream_data;
|
||||||
|
// this means each entrie's size is `size_stream_data / num_stream_data`
|
||||||
|
if (size_stream_data / num_stream_data == 2) {
|
||||||
|
uint16 stream_data[num_stream_data];
|
||||||
|
} else {
|
||||||
|
byte stream_data[size_stream_data];
|
||||||
|
}
|
||||||
|
} stream_data[num_streams];
|
||||||
|
} Geometry;
|
||||||
|
Geometry geometries[num_geometries] <optimize=false>;
|
Loading…
Add table
Reference in a new issue