Expand Call of Duty XScript definitions
Add new asset type definitions: - GfxWorld and related structures (cells, lights, probes) - Menu system (menudef, itemdef, windowdef, listboxdef) - Sound system (soundalias, soundfile, speakermap, sndcurve) - D3D resources (vertex/index buffers) - Font glyphs and expression entries Update existing definitions with improved field annotations and UI display properties. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
381b28c11f
commit
0fa26e5256
@ -7,44 +7,41 @@ type assetheader
|
||||
asset_type = "UNKNOWN";
|
||||
|
||||
if (game == "COD4" && platform == "PC") {
|
||||
// Corrected mapping based on actual file data
|
||||
if (raw_type == 0) { asset_type = "xmodelpieces"; }
|
||||
if (raw_type == 1) { asset_type = "physpreset"; }
|
||||
if (raw_type == 2) { asset_type = "xanim"; }
|
||||
if (raw_type == 3) { asset_type = "xmodel"; }
|
||||
if (raw_type == 4) { asset_type = "material"; }
|
||||
if (raw_type == 5) { asset_type = "techset"; } // Was pixelshader - CORRECTED
|
||||
if (raw_type == 6) { asset_type = "image"; }
|
||||
if (raw_type == 7) { asset_type = "pixelshader"; }
|
||||
if (raw_type == 8) { asset_type = "vertexshader"; }
|
||||
if (raw_type == 9) { asset_type = "vertexdecl"; }
|
||||
if (raw_type == 10) { asset_type = "sound"; }
|
||||
if (raw_type == 11) { asset_type = "sndcurve"; }
|
||||
if (raw_type == 12) { asset_type = "loaded_sound"; }
|
||||
if (raw_type == 13) { asset_type = "col_map_sp"; }
|
||||
if (raw_type == 14) { asset_type = "col_map_mp"; }
|
||||
if (raw_type == 15) { asset_type = "com_map"; }
|
||||
if (raw_type == 16) { asset_type = "game_map_sp"; }
|
||||
if (raw_type == 17) { asset_type = "game_map_mp"; }
|
||||
if (raw_type == 18) { asset_type = "map_ents"; }
|
||||
if (raw_type == 19) { asset_type = "fx_map"; }
|
||||
if (raw_type == 20) { asset_type = "gfx_map"; }
|
||||
if (raw_type == 21) { asset_type = "lightdef"; }
|
||||
if (raw_type == 22) { asset_type = "ui_map"; }
|
||||
if (raw_type == 23) { asset_type = "font"; }
|
||||
if (raw_type == 24) { asset_type = "menufile"; }
|
||||
if (raw_type == 25) { asset_type = "menu"; }
|
||||
if (raw_type == 26) { asset_type = "localize"; }
|
||||
if (raw_type == 27) { asset_type = "weapon"; }
|
||||
if (raw_type == 28) { asset_type = "snddriverglobals"; }
|
||||
if (raw_type == 29) { asset_type = "fx"; }
|
||||
if (raw_type == 30) { asset_type = "impactfx"; }
|
||||
if (raw_type == 31) { asset_type = "rawfile"; } // Was aitype - CORRECTED
|
||||
if (raw_type == 32) { asset_type = "aitype"; }
|
||||
if (raw_type == 33) { asset_type = "mptype"; }
|
||||
if (raw_type == 34) { asset_type = "character"; }
|
||||
if (raw_type == 35) { asset_type = "xmodelalias"; }
|
||||
if (raw_type == 36) { asset_type = "stringtable"; }
|
||||
// COD4 PC zone file asset type mapping
|
||||
// Note: No pixelshader or vertexshader on PC
|
||||
if (raw_type == 0x00) { asset_type = "xmodelpieces"; }
|
||||
if (raw_type == 0x01) { asset_type = "physpreset"; }
|
||||
if (raw_type == 0x02) { asset_type = "xanim"; }
|
||||
if (raw_type == 0x03) { asset_type = "xmodel"; }
|
||||
if (raw_type == 0x04) { asset_type = "material"; }
|
||||
if (raw_type == 0x05) { asset_type = "techset"; }
|
||||
if (raw_type == 0x06) { asset_type = "image"; }
|
||||
if (raw_type == 0x07) { asset_type = "sound"; }
|
||||
if (raw_type == 0x08) { asset_type = "sndcurve"; }
|
||||
if (raw_type == 0x09) { asset_type = "loaded_sound"; }
|
||||
if (raw_type == 0x0A) { asset_type = "col_map_sp"; }
|
||||
if (raw_type == 0x0B) { asset_type = "col_map_mp"; }
|
||||
if (raw_type == 0x0C) { asset_type = "com_map"; }
|
||||
if (raw_type == 0x0D) { asset_type = "game_map_sp"; }
|
||||
if (raw_type == 0x0E) { asset_type = "game_map_mp"; }
|
||||
if (raw_type == 0x0F) { asset_type = "map_ents"; }
|
||||
if (raw_type == 0x10) { asset_type = "gfx_map"; }
|
||||
if (raw_type == 0x11) { asset_type = "lightdef"; }
|
||||
if (raw_type == 0x12) { asset_type = "ui_map"; }
|
||||
if (raw_type == 0x13) { asset_type = "font"; }
|
||||
if (raw_type == 0x14) { asset_type = "menufile"; }
|
||||
if (raw_type == 0x15) { asset_type = "menu"; }
|
||||
if (raw_type == 0x16) { asset_type = "localize"; }
|
||||
if (raw_type == 0x17) { asset_type = "weapon"; }
|
||||
if (raw_type == 0x18) { asset_type = "snddriverglobals"; }
|
||||
if (raw_type == 0x19) { asset_type = "fx"; }
|
||||
if (raw_type == 0x1A) { asset_type = "impactfx"; }
|
||||
if (raw_type == 0x1B) { asset_type = "aitype"; }
|
||||
if (raw_type == 0x1C) { asset_type = "mptype"; }
|
||||
if (raw_type == 0x1D) { asset_type = "character"; }
|
||||
if (raw_type == 0x1E) { asset_type = "xmodelalias"; }
|
||||
if (raw_type == 0x1F) { asset_type = "rawfile"; }
|
||||
if (raw_type == 0x20) { asset_type = "stringtable"; }
|
||||
}
|
||||
|
||||
asset_type = asset_type [ui, readonly, display="Asset Type"];
|
||||
|
||||
@ -9,9 +9,9 @@ type assetlist [display="Asset List"]
|
||||
// Parse string list inline (don't use parse_here to avoid double-reading count/ptr)
|
||||
stringlist = 0;
|
||||
if (stringlist_ptr != 0) {
|
||||
actual_count = stringlist_count - 1; // C++ code decrements count
|
||||
actual_count = stringlist_count - 1;
|
||||
|
||||
// First pass: read string pointers (skip them - we don't use the values)
|
||||
// First pass: read string pointers (skip them)
|
||||
_str_ptrs_size = actual_count * 4;
|
||||
if (_str_ptrs_size > 0) {
|
||||
_str_ptrs_raw = read(_str_ptrs_size);
|
||||
@ -20,22 +20,21 @@ type assetlist [display="Asset List"]
|
||||
// Second pass: parse strings at current position
|
||||
strings = 0;
|
||||
repeat(actual_count) {
|
||||
_str = parse_here("scriptstring"); // Underscore prefix = internal/temp variable
|
||||
_str = parse_here("scriptstring");
|
||||
strings = push("strings", _str);
|
||||
}
|
||||
|
||||
strings = strings [table="Strings", columns="ptr,value"];
|
||||
_skip_tree_strings = 1; // Marker: don't show 'strings' array in tree
|
||||
stringlist = strings; // For backward compatibility
|
||||
_skip_tree_strings = 1;
|
||||
stringlist = strings;
|
||||
}
|
||||
|
||||
if (assets_ptr != 0) {
|
||||
// First pass: Parse all asset headers (for table display only, not tree)
|
||||
// First pass: Parse all asset headers
|
||||
assets = 0;
|
||||
repeat(asset_count) {
|
||||
_a = parse_here("assetheader"); // Headers are just metadata
|
||||
_a = parse_here("assetheader");
|
||||
|
||||
// Attach stringlist if available
|
||||
if (stringlist != 0) {
|
||||
_a_stringlist = stringlist;
|
||||
}
|
||||
@ -43,11 +42,10 @@ type assetlist [display="Asset List"]
|
||||
assets = push("assets", _a);
|
||||
}
|
||||
|
||||
// Display headers in table widget only (not in tree)
|
||||
assets = assets [table="Assets", columns="asset_ptr,raw_type,asset_type", format_asset_ptr="hex", format_raw_type="hex"];
|
||||
_skip_tree_assets = 1; // Marker: don't show 'assets' array in tree
|
||||
_skip_tree_assets = 1;
|
||||
|
||||
// Second pass: Parse actual asset data based on headers (for tree display)
|
||||
// Second pass: Parse actual asset data based on headers
|
||||
parsed_assets = 0;
|
||||
repeat(asset_count) {
|
||||
_header = get(assets, _i);
|
||||
@ -57,15 +55,67 @@ type assetlist [display="Asset List"]
|
||||
// Parse inline asset data (ptr == -1 which is 4294967295 as u32)
|
||||
if (_ptr == 4294967295) {
|
||||
if (_type == "techset") {
|
||||
_asset = parse_here("materialtechniqueset") [ui];
|
||||
_asset = parse_here("materialtechniqueset");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "material") {
|
||||
_asset = parse_here("material") [ui];
|
||||
_asset = parse_here("material");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "rawfile") {
|
||||
_asset = parse_here("rawfile") [ui];
|
||||
_asset = parse_here("rawfile");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "gfx_map") {
|
||||
_asset = parse_here("gfxworld");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "image") {
|
||||
_asset = parse_here("image");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "pixelshader") {
|
||||
_asset = parse_here("pixelshader");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "font") {
|
||||
_asset = parse_here("font");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "localize") {
|
||||
_asset = parse_here("localize");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "menu") {
|
||||
_asset = parse_here("menu");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "sound") {
|
||||
_asset = parse_here("sound");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "loaded_sound") {
|
||||
_asset = parse_here("loaded_sound");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "sndcurve") {
|
||||
_asset = parse_here("sndcurve");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "xmodel") {
|
||||
_asset = parse_here("xmodel");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "stringtable") {
|
||||
_asset = parse_here("stringtable_asset");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "weapon") {
|
||||
_asset = parse_here("weapon");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
if (_type == "menufile" || _type == "menulist") {
|
||||
_asset = parse_here("menulist");
|
||||
parsed_assets = push("parsed_assets", _asset);
|
||||
}
|
||||
}
|
||||
|
||||
8
definitions/cod/columninfo.xscript
Normal file
8
definitions/cod/columninfo.xscript
Normal file
@ -0,0 +1,8 @@
|
||||
type columninfo [display="Column Info"]
|
||||
{
|
||||
// columnInfo_s - 16 bytes total
|
||||
i32 pos [ui, readonly, display="Pos"];
|
||||
i32 width [ui, readonly, display="Width"];
|
||||
i32 max_chars [ui, readonly, display="Max Chars"];
|
||||
i32 alignment [ui, readonly, display="Alignment"];
|
||||
}
|
||||
8
definitions/cod/d3dindexbuffer.xscript
Normal file
8
definitions/cod/d3dindexbuffer.xscript
Normal file
@ -0,0 +1,8 @@
|
||||
type d3dindexbuffer [display="D3D Index Buffer"]
|
||||
{
|
||||
// D3D Resource base (24 bytes)
|
||||
resource = parse_here("d3dresource");
|
||||
|
||||
u32 address [ui, readonly, display="Address"];
|
||||
u32 size [ui, readonly, display="Size"];
|
||||
}
|
||||
9
definitions/cod/d3dresource.xscript
Normal file
9
definitions/cod/d3dresource.xscript
Normal file
@ -0,0 +1,9 @@
|
||||
type d3dresource [display="D3D Resource"]
|
||||
{
|
||||
u32 common [ui, readonly, display="Common"];
|
||||
u32 reference_count [ui, readonly, display="Reference Count"];
|
||||
u32 fence [ui, readonly, display="Fence"];
|
||||
u32 read_fence [ui, readonly, display="Read Fence"];
|
||||
u32 identifier [ui, readonly, display="Identifier"];
|
||||
u32 base_flush [ui, readonly, display="Base Flush"];
|
||||
}
|
||||
9
definitions/cod/d3dvertexbuffer.xscript
Normal file
9
definitions/cod/d3dvertexbuffer.xscript
Normal file
@ -0,0 +1,9 @@
|
||||
type d3dvertexbuffer [display="D3D Vertex Buffer"]
|
||||
{
|
||||
// D3D Resource base (24 bytes)
|
||||
resource = parse_here("d3dresource");
|
||||
|
||||
// GPU Vertex Fetch Constant / Raw Request (8 bytes - 2 x u32 packed bitfields)
|
||||
u32 fetch_w0 [ui, readonly, display="Fetch W0"];
|
||||
u32 fetch_w1 [ui, readonly, display="Fetch W1"];
|
||||
}
|
||||
12
definitions/cod/editfielddef.xscript
Normal file
12
definitions/cod/editfielddef.xscript
Normal file
@ -0,0 +1,12 @@
|
||||
type editfielddef [display="Edit Field Def"]
|
||||
{
|
||||
// editFieldDef_s - 32 bytes total
|
||||
f32 min_val [ui, readonly, display="Min Val"];
|
||||
f32 max_val [ui, readonly, display="Max Val"];
|
||||
f32 def_val [ui, readonly, display="Def Val"];
|
||||
f32 range [ui, readonly, display="Range"];
|
||||
i32 max_chars [ui, readonly, display="Max Chars"];
|
||||
i32 max_chars_goto_next [ui, readonly, display="Max Chars Goto Next"];
|
||||
i32 max_paint_chars [ui, readonly, display="Max Paint Chars"];
|
||||
i32 paint_offset [ui, readonly, display="Paint Offset"];
|
||||
}
|
||||
28
definitions/cod/expressionentry.xscript
Normal file
28
definitions/cod/expressionentry.xscript
Normal file
@ -0,0 +1,28 @@
|
||||
type expressionentry [display="Expression Entry"]
|
||||
{
|
||||
// expressionEntry struct from IW3_Assets.h
|
||||
// Total: 12 bytes (int type + 8 byte union)
|
||||
|
||||
// int type - EET_OPERATOR(0) or EET_OPERAND(1)
|
||||
i32 entry_type [ui, readonly, display="Type"];
|
||||
|
||||
// entryInternalData union - 8 bytes
|
||||
// If type == 0 (operator): int op (4 bytes) + 4 padding
|
||||
// If type == 1 (operand): Operand struct (dataType + internals = 8 bytes)
|
||||
|
||||
if (entry_type == 0) {
|
||||
// Operator - just an int
|
||||
i32 op_code [ui, readonly, display="Op Code"];
|
||||
i32 _padding [ui, readonly];
|
||||
} else {
|
||||
// Operand - dataType (4) + value union (4)
|
||||
// dataType: 0=INT, 1=FLOAT, 2=STRING
|
||||
i32 data_type [ui, readonly, display="Data Type"];
|
||||
i32 value_raw [ui, readonly, display="Value/Ptr"];
|
||||
|
||||
// If data_type == 2 (STRING) and value is -1, string is inline
|
||||
if (data_type == 2 && value_raw == -1) {
|
||||
string_val = cstring() [ui, readonly, display="String Value"];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,8 +13,6 @@ type fastfile [root, display="Fast File"] byteorder LE
|
||||
version_i = u32at(8);
|
||||
|
||||
// Detect game based on header signature
|
||||
// For now, default to COD4 for IW fast files
|
||||
// TODO: Add more sophisticated detection based on file size, asset types, etc.
|
||||
detected_game = "UNKNOWN";
|
||||
|
||||
if (company_s == "IW" && filetype_s == "ff") {
|
||||
@ -32,23 +30,18 @@ type fastfile [root, display="Fast File"] byteorder LE
|
||||
detected_platform = "UNKNOWN";
|
||||
|
||||
if (version_i == 5) {
|
||||
// Version 5 = PC
|
||||
detected_platform = "PC";
|
||||
}
|
||||
if (version_i == 6) {
|
||||
// Version 6 = XBOX 360
|
||||
detected_platform = "XBOX360";
|
||||
}
|
||||
if (version_i == 12) {
|
||||
// Version 12 = PS3
|
||||
detected_platform = "PS3";
|
||||
}
|
||||
if (version_i == 14) {
|
||||
// Version 14 = WII
|
||||
detected_platform = "WII";
|
||||
}
|
||||
if (version_i > 276 && version_i < 1000) {
|
||||
// Modern COD uses platform_u32 field
|
||||
if (platform_u32 == 0) {
|
||||
detected_platform = "PC";
|
||||
}
|
||||
@ -103,8 +96,10 @@ type fastfile [root, display="Fast File"] byteorder LE
|
||||
// Read and decompress zone file
|
||||
compressed_zone = read(EOF);
|
||||
decompressed_zone = compressed_zone |> zlib;
|
||||
zonefile = decompressed_zone |> parse zonefile;
|
||||
|
||||
// Export decompressed zone file (using _basename to get filename without extension)
|
||||
// Export decompressed zone file FIRST (before parsing)
|
||||
write_file(_basename + ".zone", decompressed_zone);
|
||||
|
||||
// Then parse the zone structure
|
||||
zonefile = decompressed_zone |> parse zonefile;
|
||||
}
|
||||
|
||||
@ -1,10 +1,34 @@
|
||||
type font [display="Font"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
i32 pixel_height [ui, readonly, display="Pixel Height"];
|
||||
i32 glyph_count [ui, readonly, display="Glyph Count"];
|
||||
i32 material_ptr [ui, readonly, display="Material Ptr"];
|
||||
i32 glow_material_ptr [ui, readonly, display="Glow Material Ptr"];
|
||||
i32 glyphs_ptr [ui, readonly, display="Glyphs Ptr"];
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// TODO: Add full font structure (glyph data, metrics, etc.)
|
||||
// Parse inline material
|
||||
if (material_ptr == -1) {
|
||||
material = parse_here("material");
|
||||
}
|
||||
|
||||
// Parse inline glow material
|
||||
if (glow_material_ptr == -1) {
|
||||
glow_material = parse_here("material");
|
||||
}
|
||||
|
||||
// Parse inline glyphs
|
||||
if (glyphs_ptr == -1 && glyph_count > 0) {
|
||||
glyphs = 0;
|
||||
repeat(glyph_count) {
|
||||
_glyph = parse_here("glyph");
|
||||
glyphs = push("glyphs", _glyph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
20
definitions/cod/gfxcell.xscript
Normal file
20
definitions/cod/gfxcell.xscript
Normal file
@ -0,0 +1,20 @@
|
||||
type gfxcell [display="GFX Cell"]
|
||||
{
|
||||
// Bounds (6 floats)
|
||||
mins = read(12) [ui, readonly, display="Mins"];
|
||||
maxs = read(12) [ui, readonly, display="Maxs"];
|
||||
|
||||
i32 aabb_tree_count [ui, readonly, display="AABB Tree Count"];
|
||||
i32 aabb_tree_ptr [ui, readonly, display="AABB Tree Ptr"];
|
||||
|
||||
i32 portal_count [ui, readonly, display="Portal Count"];
|
||||
i32 portals_ptr [ui, readonly, display="Portals Ptr"];
|
||||
|
||||
i32 cull_group_count [ui, readonly, display="Cull Group Count"];
|
||||
i32 cull_groups_ptr [ui, readonly, display="Cull Groups Ptr"];
|
||||
|
||||
u8 reflection_probe_count [ui, readonly, display="Reflection Probe Count"];
|
||||
i32 reflection_probes_ptr [ui, readonly, display="Reflection Probes Ptr"];
|
||||
|
||||
// Note: Array data would be parsed if pointers are valid
|
||||
}
|
||||
20
definitions/cod/gfximageloaddef.xscript
Normal file
20
definitions/cod/gfximageloaddef.xscript
Normal file
@ -0,0 +1,20 @@
|
||||
type gfximageloaddef [display="GFX Image Load Def"]
|
||||
{
|
||||
u8 level_count [ui, readonly, display="Level Count"];
|
||||
u8 flags [ui, readonly, display="Flags"];
|
||||
|
||||
// Dimensions (3 x u16)
|
||||
u16 dimension_0 [ui, readonly, display="Dimension 0"];
|
||||
u16 dimension_1 [ui, readonly, display="Dimension 1"];
|
||||
u16 dimension_2 [ui, readonly, display="Dimension 2"];
|
||||
|
||||
u32 format [ui, readonly, display="Format"];
|
||||
|
||||
// Resource size - when inline, this contains the size of pixel data that follows
|
||||
i32 resource_size [ui, readonly, display="Resource Size"];
|
||||
|
||||
// Read pixel data if present (resource_size > 0 indicates inline data)
|
||||
if (resource_size > 0) {
|
||||
pixel_data = read(resource_size) [ui, readonly, display="Pixel Data"];
|
||||
}
|
||||
}
|
||||
28
definitions/cod/gfxlight.xscript
Normal file
28
definitions/cod/gfxlight.xscript
Normal file
@ -0,0 +1,28 @@
|
||||
type gfxlight [display="GFX Light"]
|
||||
{
|
||||
u8 light_type [ui, readonly, display="Type"];
|
||||
u8 can_use_shadow_map [ui, readonly, display="Can Use Shadow Map"];
|
||||
skip(2); // padding
|
||||
|
||||
// Color (3 floats)
|
||||
color = read(12) [ui, readonly, display="Color RGB"];
|
||||
|
||||
// Direction (3 floats)
|
||||
dir = read(12) [ui, readonly, display="Direction"];
|
||||
|
||||
// Origin (3 floats)
|
||||
origin = read(12) [ui, readonly, display="Origin"];
|
||||
|
||||
// Other params
|
||||
radius = read(4) [ui, readonly, display="Radius"];
|
||||
cos_half_fov_outer = read(4) [ui, readonly, display="Cos Half FOV Outer"];
|
||||
cos_half_fov_inner = read(4) [ui, readonly, display="Cos Half FOV Inner"];
|
||||
i32 exponent [ui, readonly, display="Exponent"];
|
||||
u32 spot_shadow_index [ui, readonly, display="Spot Shadow Index"];
|
||||
|
||||
i32 def_ptr [ui, readonly, display="Def Ptr"];
|
||||
|
||||
if (def_ptr == -1) {
|
||||
def = parse_here("gfxlightdef");
|
||||
}
|
||||
}
|
||||
15
definitions/cod/gfxlightdef.xscript
Normal file
15
definitions/cod/gfxlightdef.xscript
Normal file
@ -0,0 +1,15 @@
|
||||
type gfxlightdef [display="GFX Light Def"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
// Attenuation (GfxLightImage)
|
||||
attenuation = parse_here("gfxlightimage");
|
||||
|
||||
u32 lmap_lookup_start [ui, readonly, display="LMap Lookup Start"];
|
||||
|
||||
// Parse name if inline
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
}
|
||||
25
definitions/cod/gfxlightgrid.xscript
Normal file
25
definitions/cod/gfxlightgrid.xscript
Normal file
@ -0,0 +1,25 @@
|
||||
type gfxlightgrid [display="GFX Light Grid"]
|
||||
{
|
||||
// PC version: 56 bytes (mins/maxs are uint16_t[3], not float[3])
|
||||
u8 has_light_regions [ui, readonly, display="Has Light Regions"];
|
||||
skip(3); // padding
|
||||
|
||||
u32 sun_primary_light_index [ui, readonly, display="Sun Primary Light Index"];
|
||||
|
||||
// Bounds are uint16_t[3] on PC (6 bytes each)
|
||||
mins = read(6) [ui, readonly, display="Mins"];
|
||||
maxs = read(6) [ui, readonly, display="Maxs"];
|
||||
|
||||
u32 row_axis [ui, readonly, display="Row Axis"];
|
||||
u32 col_axis [ui, readonly, display="Col Axis"];
|
||||
|
||||
i32 row_data_start_ptr [ui, readonly, display="Row Data Start Ptr"];
|
||||
u32 raw_row_data_size [ui, readonly, display="Raw Row Data Size"];
|
||||
i32 raw_row_data_ptr [ui, readonly, display="Raw Row Data Ptr"];
|
||||
|
||||
u32 entry_count [ui, readonly, display="Entry Count"];
|
||||
i32 entries_ptr [ui, readonly, display="Entries Ptr"];
|
||||
|
||||
u32 color_count [ui, readonly, display="Color Count"];
|
||||
i32 colors_ptr [ui, readonly, display="Colors Ptr"];
|
||||
}
|
||||
10
definitions/cod/gfxlightimage.xscript
Normal file
10
definitions/cod/gfxlightimage.xscript
Normal file
@ -0,0 +1,10 @@
|
||||
type gfxlightimage [display="GFX Light Image"]
|
||||
{
|
||||
i32 image_ptr [ui, readonly, display="Image Ptr"];
|
||||
u8 sampler_state [ui, readonly, display="Sampler State"];
|
||||
skip(3); // padding
|
||||
|
||||
if (image_ptr == -1) {
|
||||
image = parse_here("image");
|
||||
}
|
||||
}
|
||||
13
definitions/cod/gfxlightmaparray.xscript
Normal file
13
definitions/cod/gfxlightmaparray.xscript
Normal file
@ -0,0 +1,13 @@
|
||||
type gfxlightmaparray [display="GFX Lightmap Array"]
|
||||
{
|
||||
i32 primary_ptr [ui, readonly, display="Primary Ptr"];
|
||||
i32 secondary_ptr [ui, readonly, display="Secondary Ptr"];
|
||||
|
||||
// Images parsed inline if ptr == -1
|
||||
if (primary_ptr == -1) {
|
||||
primary = parse_here("image");
|
||||
}
|
||||
if (secondary_ptr == -1) {
|
||||
secondary = parse_here("image");
|
||||
}
|
||||
}
|
||||
8
definitions/cod/gfxreflectionprobe.xscript
Normal file
8
definitions/cod/gfxreflectionprobe.xscript
Normal file
@ -0,0 +1,8 @@
|
||||
type gfxreflectionprobe [display="GFX Reflection Probe"]
|
||||
{
|
||||
// Origin (3 floats = 12 bytes)
|
||||
origin = read(12) [ui, readonly, display="Origin"];
|
||||
|
||||
// Reflection image
|
||||
reflection_image = parse_here("image");
|
||||
}
|
||||
12
definitions/cod/gfxstreamingaabbtree.xscript
Normal file
12
definitions/cod/gfxstreamingaabbtree.xscript
Normal file
@ -0,0 +1,12 @@
|
||||
type gfxstreamingaabbtree [display="GFX Streaming AABB Tree"]
|
||||
{
|
||||
u16 first_item [ui, readonly, display="First Item"];
|
||||
u16 item_count [ui, readonly, display="Item Count"];
|
||||
u16 first_child [ui, readonly, display="First Child"];
|
||||
u16 child_count [ui, readonly, display="Child Count"];
|
||||
|
||||
// Bounds (6 floats)
|
||||
// Note: Using read() since we don't have float type yet
|
||||
mins = read(12) [ui, readonly, display="Mins"];
|
||||
maxs = read(12) [ui, readonly, display="Maxs"];
|
||||
}
|
||||
10
definitions/cod/gfxtexture.xscript
Normal file
10
definitions/cod/gfxtexture.xscript
Normal file
@ -0,0 +1,10 @@
|
||||
type gfxtexture [display="GFX Texture"]
|
||||
{
|
||||
// GfxTexture is a union of different texture types
|
||||
// For inline data (-1 or -2), parse load def
|
||||
i32 base_map_ptr [ui, readonly, display="Base Map Ptr"];
|
||||
|
||||
if (base_map_ptr == -1 || base_map_ptr == -2) {
|
||||
load_def = parse_here("gfximageloaddef");
|
||||
}
|
||||
}
|
||||
155
definitions/cod/gfxworld.xscript
Normal file
155
definitions/cod/gfxworld.xscript
Normal file
@ -0,0 +1,155 @@
|
||||
type gfxworld [display="GFX World"]
|
||||
{
|
||||
// ========================================
|
||||
// GfxWorld Header - PC VERSION (732 bytes)
|
||||
// ========================================
|
||||
|
||||
// Name pointers (8 bytes)
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
i32 basename_ptr [ui, readonly, display="Base Name Ptr"];
|
||||
|
||||
// Counts and indices (16 bytes)
|
||||
i32 plane_count [ui, readonly, display="Plane Count"];
|
||||
i32 node_count [ui, readonly, display="Node Count"];
|
||||
i32 index_count [ui, readonly, display="Index Count"];
|
||||
i32 indices_ptr [ui, readonly, display="Indices Ptr"];
|
||||
|
||||
// PC has no D3DIndexBuffer - just surfaceCount + unk (8 bytes)
|
||||
i32 surface_count [ui, readonly, display="Surface Count"];
|
||||
i32 unk [ui, readonly, display="Unknown"];
|
||||
|
||||
// Sky data (16 bytes)
|
||||
i32 sky_surf_count [ui, readonly, display="Sky Surf Count"];
|
||||
i32 sky_start_surfs_ptr [ui, readonly, display="Sky Start Surfs Ptr"];
|
||||
i32 sky_image_ptr [ui, readonly, display="Sky Image Ptr"];
|
||||
u8 sky_sampler_state [ui, readonly, display="Sky Sampler State"];
|
||||
skip(3); // padding
|
||||
|
||||
// Vertex data (4 + 8 = 12 bytes)
|
||||
u32 vertex_count [ui, readonly, display="Vertex Count"];
|
||||
vertex_data = parse_here("gfxworldvertexdata");
|
||||
|
||||
// Vertex layer data (4 + 8 = 12 bytes)
|
||||
u32 vertex_layer_data_size [ui, readonly, display="Vertex Layer Data Size"];
|
||||
vertex_layer_data = parse_here("gfxworldvertexlayerdata");
|
||||
|
||||
// Sun light parse params - EMBEDDED (128 bytes on PC - name is char[64])
|
||||
sun_parse = parse_here("sunlightparseparams");
|
||||
|
||||
// Sun light pointer (4 bytes)
|
||||
i32 sun_light_ptr [ui, readonly, display="Sun Light Ptr"];
|
||||
|
||||
// Sun color from BSP (12 bytes)
|
||||
sun_color = read(12) [ui, readonly, display="Sun Color"];
|
||||
|
||||
// Light counts and reflection probes (24 bytes)
|
||||
u32 sun_primary_light_index [ui, readonly, display="Sun Primary Light Index"];
|
||||
u32 primary_light_count [ui, readonly, display="Primary Light Count"];
|
||||
i32 cull_group_count [ui, readonly, display="Cull Group Count"];
|
||||
u32 reflection_probe_count [ui, readonly, display="Reflection Probe Count"];
|
||||
i32 reflection_probes_ptr [ui, readonly, display="Reflection Probes Ptr"];
|
||||
i32 reflection_probe_textures_ptr [ui, readonly, display="Reflection Probe Textures Ptr"];
|
||||
|
||||
// DPVS planes - EMBEDDED (16 bytes)
|
||||
dpvs_planes = parse_here("gfxworlddpvsplanes");
|
||||
|
||||
// Cells and lightmaps (16 bytes)
|
||||
i32 cell_bits_count [ui, readonly, display="Cell Bits Count"];
|
||||
i32 cells_ptr [ui, readonly, display="Cells Ptr"];
|
||||
i32 lightmap_count [ui, readonly, display="Lightmap Count"];
|
||||
i32 lightmaps_ptr [ui, readonly, display="Lightmaps Ptr"];
|
||||
|
||||
// Light grid - EMBEDDED (56 bytes on PC - mins/maxs are uint16)
|
||||
light_grid = parse_here("gfxlightgrid");
|
||||
|
||||
// Texture pointers (16 bytes)
|
||||
i32 lightmaps_primary_ptr [ui, readonly, display="Lightmaps Primary Ptr"];
|
||||
i32 lightmaps_secondary_ptr [ui, readonly, display="Lightmaps Secondary Ptr"];
|
||||
i32 model_count [ui, readonly, display="Model Count"];
|
||||
i32 models_ptr [ui, readonly, display="Models Ptr"];
|
||||
|
||||
// Bounds (24 bytes)
|
||||
mins = read(12) [ui, readonly, display="Mins"];
|
||||
maxs = read(12) [ui, readonly, display="Maxs"];
|
||||
|
||||
// Checksum and material memory (12 bytes)
|
||||
u32 checksum [ui, readonly, display="Checksum"];
|
||||
i32 material_memory_count [ui, readonly, display="Material Memory Count"];
|
||||
i32 material_memory_ptr [ui, readonly, display="Material Memory Ptr"];
|
||||
|
||||
// Sun flare - EMBEDDED (96 bytes)
|
||||
sun_flare = parse_here("sunflare");
|
||||
|
||||
// Outdoor lookup matrix (64 bytes)
|
||||
outdoor_lookup_matrix = read(64) [ui, readonly, display="Outdoor Lookup Matrix"];
|
||||
|
||||
// Final pointers (40 bytes)
|
||||
i32 outdoor_image_ptr [ui, readonly, display="Outdoor Image Ptr"];
|
||||
i32 cell_caster_bits_ptr [ui, readonly, display="Cell Caster Bits Ptr"];
|
||||
i32 scene_dyn_model_ptr [ui, readonly, display="Scene Dyn Model Ptr"];
|
||||
i32 scene_dyn_brush_ptr [ui, readonly, display="Scene Dyn Brush Ptr"];
|
||||
i32 primary_light_ent_shadow_vis_ptr [ui, readonly, display="Primary Light Ent Shadow Vis Ptr"];
|
||||
i32 primary_light_dyn_ent_shadow_vis_ptr_0 [ui, readonly, display="Primary Light Dyn Ent Shadow Vis Ptr 0"];
|
||||
i32 primary_light_dyn_ent_shadow_vis_ptr_1 [ui, readonly, display="Primary Light Dyn Ent Shadow Vis Ptr 1"];
|
||||
i32 primary_light_for_model_dyn_ent_ptr [ui, readonly, display="Primary Light For Model Dyn Ent Ptr"];
|
||||
i32 shadow_geom_ptr [ui, readonly, display="Shadow Geom Ptr"];
|
||||
i32 light_region_ptr [ui, readonly, display="Light Region Ptr"];
|
||||
|
||||
// DPVS static - EMBEDDED (104 bytes on PC - has 3 extra fields)
|
||||
dpvs = parse_here("gfxworlddpvsstatic");
|
||||
|
||||
// DPVS dynamic - EMBEDDED (48 bytes)
|
||||
dpvs_dyn = parse_here("gfxworlddpvsdynamic");
|
||||
|
||||
// ========================================
|
||||
// Inline data (after header, ptr == -1)
|
||||
// ========================================
|
||||
|
||||
// Parse names if inline
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
if (basename_ptr == -1) {
|
||||
basename = cstring() [ui, readonly, display="Base Name"];
|
||||
}
|
||||
|
||||
// Indices array - only if inline (ptr == -1)
|
||||
if (indices_ptr == -1 && index_count > 0) {
|
||||
indices = read(index_count * 2) [ui, readonly, display="Indices"];
|
||||
}
|
||||
|
||||
// Sky start surfs - only if inline
|
||||
if (sky_start_surfs_ptr == -1 && sky_surf_count > 0) {
|
||||
sky_start_surfs = read(sky_surf_count * 4) [ui, readonly, display="Sky Start Surfs"];
|
||||
}
|
||||
|
||||
// Sky image - only if inline
|
||||
if (sky_image_ptr == -1) {
|
||||
sky_image = parse_here("image");
|
||||
}
|
||||
|
||||
// Sun light - only if inline
|
||||
if (sun_light_ptr == -1) {
|
||||
sun_light = parse_here("gfxlight");
|
||||
}
|
||||
|
||||
// Reflection probes - only if inline
|
||||
if (reflection_probes_ptr == -1 && reflection_probe_count > 0) {
|
||||
reflection_probes = 0;
|
||||
repeat(reflection_probe_count) {
|
||||
_probe = parse_here("gfxreflectionprobe");
|
||||
reflection_probes = push("reflection_probes", _probe);
|
||||
}
|
||||
}
|
||||
|
||||
// Reflection probe textures - only if inline
|
||||
if (reflection_probe_textures_ptr == -1 && reflection_probe_count > 0) {
|
||||
reflection_probe_textures = 0;
|
||||
repeat(reflection_probe_count) {
|
||||
_tex = parse_here("gfxtexture");
|
||||
reflection_probe_textures = push("reflection_probe_textures", _tex);
|
||||
}
|
||||
}
|
||||
}
|
||||
20
definitions/cod/gfxworlddpvsdynamic.xscript
Normal file
20
definitions/cod/gfxworlddpvsdynamic.xscript
Normal file
@ -0,0 +1,20 @@
|
||||
type gfxworlddpvsdynamic [display="GFX World DPVS Dynamic"]
|
||||
{
|
||||
// Fixed fields - dynEntClientWordCount[2] and dynEntClientCount[2]
|
||||
u32 dyn_ent_client_word_count_0 [ui, readonly, display="Dyn Ent Client Word Count 0"];
|
||||
u32 dyn_ent_client_word_count_1 [ui, readonly, display="Dyn Ent Client Word Count 1"];
|
||||
u32 dyn_ent_client_count_0 [ui, readonly, display="Dyn Ent Client Count 0"];
|
||||
u32 dyn_ent_client_count_1 [ui, readonly, display="Dyn Ent Client Count 1"];
|
||||
|
||||
// Pointers
|
||||
i32 dyn_ent_cell_bits_ptr_0 [ui, readonly, display="Dyn Ent Cell Bits Ptr 0"];
|
||||
i32 dyn_ent_cell_bits_ptr_1 [ui, readonly, display="Dyn Ent Cell Bits Ptr 1"];
|
||||
i32 dyn_ent_vis_data_ptr_0_0 [ui, readonly, display="Dyn Ent Vis Data Ptr 0-0"];
|
||||
i32 dyn_ent_vis_data_ptr_0_1 [ui, readonly, display="Dyn Ent Vis Data Ptr 0-1"];
|
||||
i32 dyn_ent_vis_data_ptr_0_2 [ui, readonly, display="Dyn Ent Vis Data Ptr 0-2"];
|
||||
i32 dyn_ent_vis_data_ptr_1_0 [ui, readonly, display="Dyn Ent Vis Data Ptr 1-0"];
|
||||
i32 dyn_ent_vis_data_ptr_1_1 [ui, readonly, display="Dyn Ent Vis Data Ptr 1-1"];
|
||||
i32 dyn_ent_vis_data_ptr_1_2 [ui, readonly, display="Dyn Ent Vis Data Ptr 1-2"];
|
||||
|
||||
// Note: Full array parsing not implemented
|
||||
}
|
||||
10
definitions/cod/gfxworlddpvsplanes.xscript
Normal file
10
definitions/cod/gfxworlddpvsplanes.xscript
Normal file
@ -0,0 +1,10 @@
|
||||
type gfxworlddpvsplanes [display="GFX World DPVS Planes"]
|
||||
{
|
||||
// Fixed header fields
|
||||
i32 cell_count [ui, readonly, display="Cell Count"];
|
||||
i32 planes_ptr [ui, readonly, display="Planes Ptr"];
|
||||
i32 nodes_ptr [ui, readonly, display="Nodes Ptr"];
|
||||
i32 scene_ent_cell_bits_ptr [ui, readonly, display="Scene Ent Cell Bits Ptr"];
|
||||
|
||||
// Note: Arrays are parsed separately based on pointers
|
||||
}
|
||||
32
definitions/cod/gfxworlddpvsstatic.xscript
Normal file
32
definitions/cod/gfxworlddpvsstatic.xscript
Normal file
@ -0,0 +1,32 @@
|
||||
type gfxworlddpvsstatic [display="GFX World DPVS Static"]
|
||||
{
|
||||
// PC version: 104 bytes (has 3 extra fields vs 360)
|
||||
u32 smodel_count [ui, readonly, display="SModel Count"];
|
||||
u32 static_surface_count [ui, readonly, display="Static Surface Count"];
|
||||
u32 lit_surfs_begin [ui, readonly, display="Lit Surfs Begin"];
|
||||
u32 lit_surfs_end [ui, readonly, display="Lit Surfs End"];
|
||||
u32 decal_surfs_begin [ui, readonly, display="Decal Surfs Begin"];
|
||||
u32 decal_surfs_end [ui, readonly, display="Decal Surfs End"];
|
||||
u32 emissive_surfs_begin [ui, readonly, display="Emissive Surfs Begin"];
|
||||
u32 emissive_surfs_end [ui, readonly, display="Emissive Surfs End"];
|
||||
u32 unk [ui, readonly, display="Unknown"];
|
||||
u32 lod_data_count [ui, readonly, display="LOD Data Count"];
|
||||
u32 surface_casts_sun_shadow_count [ui, readonly, display="Surface Casts Sun Shadow Count"];
|
||||
|
||||
// Pointers to arrays
|
||||
i32 smodel_vis_data_ptr_0 [ui, readonly, display="SModel Vis Data Ptr 0"];
|
||||
i32 smodel_vis_data_ptr_1 [ui, readonly, display="SModel Vis Data Ptr 1"];
|
||||
i32 smodel_vis_data_ptr_2 [ui, readonly, display="SModel Vis Data Ptr 2"];
|
||||
i32 surface_vis_data_ptr_0 [ui, readonly, display="Surface Vis Data Ptr 0"];
|
||||
i32 surface_vis_data_ptr_1 [ui, readonly, display="Surface Vis Data Ptr 1"];
|
||||
i32 surface_vis_data_ptr_2 [ui, readonly, display="Surface Vis Data Ptr 2"];
|
||||
i32 lod_data_ptr [ui, readonly, display="LOD Data Ptr"];
|
||||
i32 sorted_surf_index_ptr [ui, readonly, display="Sorted Surf Index Ptr"];
|
||||
i32 smodel_insts_ptr [ui, readonly, display="SModel Insts Ptr"];
|
||||
i32 surfaces_ptr [ui, readonly, display="Surfaces Ptr"];
|
||||
i32 cull_groups_ptr [ui, readonly, display="Cull Groups Ptr"];
|
||||
i32 smodel_draw_insts_ptr [ui, readonly, display="SModel Draw Insts Ptr"];
|
||||
i32 surface_materials_ptr [ui, readonly, display="Surface Materials Ptr"];
|
||||
i32 surface_casts_sun_shadow_ptr [ui, readonly, display="Surface Casts Sun Shadow Ptr"];
|
||||
i32 usage_count [ui, readonly, display="Usage Count"];
|
||||
}
|
||||
10
definitions/cod/gfxworldstreaminfo.xscript
Normal file
10
definitions/cod/gfxworldstreaminfo.xscript
Normal file
@ -0,0 +1,10 @@
|
||||
type gfxworldstreaminfo [display="GFX World Stream Info"]
|
||||
{
|
||||
// Fixed 16-byte header (embedded in GfxWorld header)
|
||||
i32 aabb_tree_count [ui, readonly, display="AABB Tree Count"];
|
||||
i32 aabb_trees_ptr [ui, readonly, display="AABB Trees Ptr"];
|
||||
i32 leaf_ref_count [ui, readonly, display="Leaf Ref Count"];
|
||||
i32 leaf_refs_ptr [ui, readonly, display="Leaf Refs Ptr"];
|
||||
|
||||
// Note: Arrays are parsed separately after the main header
|
||||
}
|
||||
6
definitions/cod/gfxworldvertexdata.xscript
Normal file
6
definitions/cod/gfxworldvertexdata.xscript
Normal file
@ -0,0 +1,6 @@
|
||||
type gfxworldvertexdata [display="GFX World Vertex Data"]
|
||||
{
|
||||
// PC version: 8 bytes (2 pointers)
|
||||
i32 vertices_ptr [ui, readonly, display="Vertices Ptr"];
|
||||
i32 world_vb_ptr [ui, readonly, display="World VB Ptr"];
|
||||
}
|
||||
6
definitions/cod/gfxworldvertexlayerdata.xscript
Normal file
6
definitions/cod/gfxworldvertexlayerdata.xscript
Normal file
@ -0,0 +1,6 @@
|
||||
type gfxworldvertexlayerdata [display="GFX World Vertex Layer Data"]
|
||||
{
|
||||
// PC version: 8 bytes (2 pointers)
|
||||
i32 data_ptr [ui, readonly, display="Data Ptr"];
|
||||
i32 layer_vb_ptr [ui, readonly, display="Layer VB Ptr"];
|
||||
}
|
||||
17
definitions/cod/glyph.xscript
Normal file
17
definitions/cod/glyph.xscript
Normal file
@ -0,0 +1,17 @@
|
||||
type glyph [display="Glyph"]
|
||||
{
|
||||
u16 letter [ui, readonly, display="Letter"];
|
||||
i8 x0 [ui, readonly, display="X0"];
|
||||
i8 y0 [ui, readonly, display="Y0"];
|
||||
i8 dx [ui, readonly, display="DX"];
|
||||
i8 pixel_width [ui, readonly, display="Pixel Width"];
|
||||
i8 pixel_height [ui, readonly, display="Pixel Height"];
|
||||
i8 pitch [ui, readonly, display="Pitch"];
|
||||
|
||||
// UV coordinates (4 floats = 16 bytes)
|
||||
// Read as raw bytes since we don't have float type yet
|
||||
uv_coords = read(16) [ui, readonly, display="UV Coords"];
|
||||
|
||||
// Padding to align to 32 bytes total (8 + 16 = 24, need 8 more)
|
||||
skip(8);
|
||||
}
|
||||
@ -1,10 +1,41 @@
|
||||
type image [display="Image"]
|
||||
{
|
||||
// GfxImage struct - 32 bytes total on PC COD4
|
||||
u32 map_type [ui, readonly, display="Map Type"];
|
||||
|
||||
// GfxTexture union - on PC this is just a D3D texture ptr (or -1/-2 for inline loaddef)
|
||||
i32 texture_ptr [ui, readonly, display="Texture Ptr"];
|
||||
|
||||
// Picmip (2 bytes)
|
||||
u8 picmip_0 [ui, readonly, display="Picmip 0"];
|
||||
u8 picmip_1 [ui, readonly, display="Picmip 1"];
|
||||
|
||||
u8 semantic [ui, readonly, display="Semantic"];
|
||||
u8 track [ui, readonly, display="Track"];
|
||||
|
||||
// Card memory (2 x u32 = 8 bytes)
|
||||
u32 card_memory_0 [ui, readonly, display="Card Memory 0"];
|
||||
u32 card_memory_1 [ui, readonly, display="Card Memory 1"];
|
||||
|
||||
u16 width [ui, readonly, display="Width"];
|
||||
u16 height [ui, readonly, display="Height"];
|
||||
u16 depth [ui, readonly, display="Depth"];
|
||||
|
||||
u8 category [ui, readonly, display="Category"];
|
||||
u8 delay_load_pixels [ui, readonly, display="Delay Load Pixels"];
|
||||
|
||||
// Name pointer
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
// Parse inline name if ptr is -1
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// TODO: Add full image structure (texture data, format, dimensions, etc.)
|
||||
// GfxImageLoadDef parsed if texture ptr is -1 or -2 (inline data)
|
||||
// On PC, images with streaming data have loaddef inline
|
||||
if (texture_ptr == -1 || texture_ptr == -2) {
|
||||
load_def = parse_here("gfximageloaddef");
|
||||
}
|
||||
}
|
||||
|
||||
251
definitions/cod/itemdef.xscript
Normal file
251
definitions/cod/itemdef.xscript
Normal file
@ -0,0 +1,251 @@
|
||||
type itemdef [display="Item Def"]
|
||||
{
|
||||
// itemDef_s struct from IW3_Assets.h
|
||||
// Total fixed size: ~368 bytes
|
||||
|
||||
// ============ WindowDef_t embedded (156 bytes) ============
|
||||
window = parse_here("windowdef") [display="Window"];
|
||||
|
||||
// ============ Text Rect (24 bytes) ============
|
||||
text_rect = parse_here("rectdef") [display="Text Rect"];
|
||||
|
||||
// ============ Item Properties ============
|
||||
i32 item_type [ui, readonly, display="Type"];
|
||||
i32 data_type [ui, readonly, display="Data Type"];
|
||||
i32 alignment [ui, readonly, display="Alignment"];
|
||||
i32 font_enum [ui, readonly, display="Font Enum"];
|
||||
i32 text_align_mode [ui, readonly, display="Text Align Mode"];
|
||||
|
||||
f32 text_align_x [ui, readonly, display="Text Align X"];
|
||||
f32 text_align_y [ui, readonly, display="Text Align Y"];
|
||||
f32 text_scale [ui, readonly, display="Text Scale"];
|
||||
|
||||
i32 text_style [ui, readonly, display="Text Style"];
|
||||
i32 game_msg_window_index [ui, readonly, display="Game Msg Window Index"];
|
||||
i32 game_msg_window_mode [ui, readonly, display="Game Msg Window Mode"];
|
||||
|
||||
// Pointers
|
||||
i32 text_ptr [ui, readonly, display="Text Ptr"];
|
||||
i32 item_flags [ui, readonly, display="Item Flags"];
|
||||
i32 parent_ptr [ui, readonly, display="Parent Ptr"];
|
||||
|
||||
i32 mouse_enter_text_ptr [ui, readonly, display="Mouse Enter Text Ptr"];
|
||||
i32 mouse_exit_text_ptr [ui, readonly, display="Mouse Exit Text Ptr"];
|
||||
i32 mouse_enter_ptr [ui, readonly, display="Mouse Enter Ptr"];
|
||||
i32 mouse_exit_ptr [ui, readonly, display="Mouse Exit Ptr"];
|
||||
i32 action_ptr [ui, readonly, display="Action Ptr"];
|
||||
i32 on_accept_ptr [ui, readonly, display="On Accept Ptr"];
|
||||
i32 on_focus_ptr [ui, readonly, display="On Focus Ptr"];
|
||||
i32 leave_focus_ptr [ui, readonly, display="Leave Focus Ptr"];
|
||||
|
||||
i32 dvar_ptr [ui, readonly, display="Dvar Ptr"];
|
||||
i32 dvar_test_ptr [ui, readonly, display="Dvar Test Ptr"];
|
||||
i32 on_key_ptr [ui, readonly, display="On Key Ptr"];
|
||||
i32 enable_dvar_ptr [ui, readonly, display="Enable Dvar Ptr"];
|
||||
i32 dvar_flags [ui, readonly, display="Dvar Flags"];
|
||||
|
||||
i32 focus_sound_ptr [ui, readonly, display="Focus Sound Ptr"];
|
||||
f32 special [ui, readonly, display="Special"];
|
||||
i32 cursor_pos [ui, readonly, display="Cursor Pos"];
|
||||
|
||||
i32 type_data_ptr [ui, readonly, display="Type Data Ptr"];
|
||||
i32 image_track [ui, readonly, display="Image Track"];
|
||||
|
||||
// ============ Expressions (8 x statement_s = 64 bytes) ============
|
||||
visible_exp = parse_here("statement") [display="Visible Exp"];
|
||||
text_exp = parse_here("statement") [display="Text Exp"];
|
||||
material_exp = parse_here("statement") [display="Material Exp"];
|
||||
rect_x_exp = parse_here("statement") [display="Rect X Exp"];
|
||||
rect_y_exp = parse_here("statement") [display="Rect Y Exp"];
|
||||
rect_w_exp = parse_here("statement") [display="Rect W Exp"];
|
||||
rect_h_exp = parse_here("statement") [display="Rect H Exp"];
|
||||
forecolor_a_exp = parse_here("statement") [display="Forecolor A Exp"];
|
||||
|
||||
// ============================================================
|
||||
// INLINE DATA PARSING (zone file streaming order)
|
||||
// ============================================================
|
||||
|
||||
// 1. Window name (if name_ptr == -1)
|
||||
_win_name_ptr = get(window, "name_ptr");
|
||||
if (_win_name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
}
|
||||
|
||||
// 2. Window group (if group_ptr == -1)
|
||||
_win_group_ptr = get(window, "group_ptr");
|
||||
if (_win_group_ptr == -1) {
|
||||
group = cstring() [ui, readonly, display="Group"];
|
||||
}
|
||||
|
||||
// 3. Window background Material (if background_ptr == -1)
|
||||
_win_bg_ptr = get(window, "background_ptr");
|
||||
if (_win_bg_ptr == -1) {
|
||||
background = parse_here("material") [display="Background"];
|
||||
}
|
||||
|
||||
// 4. Text string (if text_ptr == -1)
|
||||
if (text_ptr == -1) {
|
||||
text = cstring() [ui, readonly, display="Text"];
|
||||
}
|
||||
|
||||
// 5. Mouse/action handlers (if ptr == -1)
|
||||
if (mouse_enter_text_ptr == -1) {
|
||||
mouse_enter_text = cstring() [ui, readonly, display="Mouse Enter Text"];
|
||||
}
|
||||
if (mouse_exit_text_ptr == -1) {
|
||||
mouse_exit_text = cstring() [ui, readonly, display="Mouse Exit Text"];
|
||||
}
|
||||
if (mouse_enter_ptr == -1) {
|
||||
mouse_enter = cstring() [ui, readonly, display="Mouse Enter"];
|
||||
}
|
||||
if (mouse_exit_ptr == -1) {
|
||||
mouse_exit = cstring() [ui, readonly, display="Mouse Exit"];
|
||||
}
|
||||
if (action_ptr == -1) {
|
||||
action = cstring() [ui, readonly, display="Action"];
|
||||
}
|
||||
if (on_accept_ptr == -1) {
|
||||
on_accept = cstring() [ui, readonly, display="On Accept"];
|
||||
}
|
||||
if (on_focus_ptr == -1) {
|
||||
on_focus = cstring() [ui, readonly, display="On Focus"];
|
||||
}
|
||||
if (leave_focus_ptr == -1) {
|
||||
leave_focus = cstring() [ui, readonly, display="Leave Focus"];
|
||||
}
|
||||
|
||||
// 6. Dvar strings (if ptr == -1)
|
||||
if (dvar_ptr == -1) {
|
||||
dvar = cstring() [ui, readonly, display="Dvar"];
|
||||
}
|
||||
if (dvar_test_ptr == -1) {
|
||||
dvar_test = cstring() [ui, readonly, display="Dvar Test"];
|
||||
}
|
||||
|
||||
// 7. OnKey handler (if on_key_ptr == -1)
|
||||
if (on_key_ptr == -1) {
|
||||
on_key = parse_here("itemkeyhandler") [display="On Key"];
|
||||
}
|
||||
|
||||
// 8. Enable dvar (if enable_dvar_ptr == -1)
|
||||
if (enable_dvar_ptr == -1) {
|
||||
enable_dvar = cstring() [ui, readonly, display="Enable Dvar"];
|
||||
}
|
||||
|
||||
// 9. Focus sound (if focus_sound_ptr == -1)
|
||||
if (focus_sound_ptr == -1) {
|
||||
focus_sound = parse_here("sound") [display="Focus Sound"];
|
||||
}
|
||||
|
||||
|
||||
// 10. Type-specific data (typeData)
|
||||
// ITEM_TYPE_LISTBOX = 6
|
||||
// ITEM_TYPE_EDITFIELD = 4, NUMERICFIELD = 9, VALIDFILEFIELD = 16, DECIMALFIELD = 17, UPREDITFIELD = 18
|
||||
// ITEM_TYPE_MULTI = 12
|
||||
// ITEM_TYPE_DVARENUM = 13
|
||||
if (type_data_ptr == -1) {
|
||||
if (item_type == 6) {
|
||||
type_data = parse_here("listboxdef") [display="List Box Data"];
|
||||
}
|
||||
if (item_type == 4 || item_type == 9 || item_type == 16 || item_type == 17 || item_type == 18) {
|
||||
type_data = parse_here("editfielddef") [display="Edit Field Data"];
|
||||
}
|
||||
if (item_type == 12) {
|
||||
type_data = parse_here("multidef") [display="Multi Data"];
|
||||
}
|
||||
if (item_type == 13) {
|
||||
type_data = cstring() [ui, readonly, display="Enum Dvar Name"];
|
||||
}
|
||||
}
|
||||
|
||||
// ============ Expression Entries ============
|
||||
// Parse expression entries for all 8 statements
|
||||
|
||||
// 11. Visible expression entries
|
||||
_vis_num = get(visible_exp, "num_entries");
|
||||
_vis_ptr = get(visible_exp, "entries_ptr");
|
||||
if (_vis_ptr == -1 && _vis_num > 0) {
|
||||
_vis_ptr_size = _vis_num * 4;
|
||||
_vis_ptrs = read(_vis_ptr_size) [display="Visible Entry Ptrs"];
|
||||
repeat(_vis_num) {
|
||||
_vis_entry = parse_here("expressionentry") [display="Visible Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 12. Text expression entries
|
||||
_txt_num = get(text_exp, "num_entries");
|
||||
_txt_ptr = get(text_exp, "entries_ptr");
|
||||
if (_txt_ptr == -1 && _txt_num > 0) {
|
||||
_txt_ptr_size = _txt_num * 4;
|
||||
_txt_ptrs = read(_txt_ptr_size) [display="Text Entry Ptrs"];
|
||||
repeat(_txt_num) {
|
||||
_txt_entry = parse_here("expressionentry") [display="Text Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 13. Material expression entries
|
||||
_mat_num = get(material_exp, "num_entries");
|
||||
_mat_ptr = get(material_exp, "entries_ptr");
|
||||
if (_mat_ptr == -1 && _mat_num > 0) {
|
||||
_mat_ptr_size = _mat_num * 4;
|
||||
_mat_ptrs = read(_mat_ptr_size) [display="Material Entry Ptrs"];
|
||||
repeat(_mat_num) {
|
||||
_mat_entry = parse_here("expressionentry") [display="Material Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 14. Rect X expression entries
|
||||
_rx_num = get(rect_x_exp, "num_entries");
|
||||
_rx_ptr = get(rect_x_exp, "entries_ptr");
|
||||
if (_rx_ptr == -1 && _rx_num > 0) {
|
||||
_rx_ptr_size = _rx_num * 4;
|
||||
_rx_ptrs = read(_rx_ptr_size) [display="Rect X Entry Ptrs"];
|
||||
repeat(_rx_num) {
|
||||
_rx_entry = parse_here("expressionentry") [display="Rect X Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 15. Rect Y expression entries
|
||||
_ry_num = get(rect_y_exp, "num_entries");
|
||||
_ry_ptr = get(rect_y_exp, "entries_ptr");
|
||||
if (_ry_ptr == -1 && _ry_num > 0) {
|
||||
_ry_ptr_size = _ry_num * 4;
|
||||
_ry_ptrs = read(_ry_ptr_size) [display="Rect Y Entry Ptrs"];
|
||||
repeat(_ry_num) {
|
||||
_ry_entry = parse_here("expressionentry") [display="Rect Y Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 16. Rect W expression entries
|
||||
_rw_num = get(rect_w_exp, "num_entries");
|
||||
_rw_ptr = get(rect_w_exp, "entries_ptr");
|
||||
if (_rw_ptr == -1 && _rw_num > 0) {
|
||||
_rw_ptr_size = _rw_num * 4;
|
||||
_rw_ptrs = read(_rw_ptr_size) [display="Rect W Entry Ptrs"];
|
||||
repeat(_rw_num) {
|
||||
_rw_entry = parse_here("expressionentry") [display="Rect W Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 17. Rect H expression entries
|
||||
_rh_num = get(rect_h_exp, "num_entries");
|
||||
_rh_ptr = get(rect_h_exp, "entries_ptr");
|
||||
if (_rh_ptr == -1 && _rh_num > 0) {
|
||||
_rh_ptr_size = _rh_num * 4;
|
||||
_rh_ptrs = read(_rh_ptr_size) [display="Rect H Entry Ptrs"];
|
||||
repeat(_rh_num) {
|
||||
_rh_entry = parse_here("expressionentry") [display="Rect H Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 18. Forecolor A expression entries
|
||||
_fc_num = get(forecolor_a_exp, "num_entries");
|
||||
_fc_ptr = get(forecolor_a_exp, "entries_ptr");
|
||||
if (_fc_ptr == -1 && _fc_num > 0) {
|
||||
_fc_ptr_size = _fc_num * 4;
|
||||
_fc_ptrs = read(_fc_ptr_size) [display="Forecolor A Entry Ptrs"];
|
||||
repeat(_fc_num) {
|
||||
_fc_entry = parse_here("expressionentry") [display="Forecolor A Entry"];
|
||||
}
|
||||
}
|
||||
}
|
||||
16
definitions/cod/itemkeyhandler.xscript
Normal file
16
definitions/cod/itemkeyhandler.xscript
Normal file
@ -0,0 +1,16 @@
|
||||
type itemkeyhandler [display="Item Key Handler"]
|
||||
{
|
||||
i32 key [ui, readonly, display="Key"];
|
||||
i32 action_ptr [ui, readonly, display="Action Ptr"];
|
||||
i32 next_ptr [ui, readonly, display="Next Ptr"];
|
||||
|
||||
// Parse inline action
|
||||
if (action_ptr == -1) {
|
||||
action = cstring() [ui, readonly, display="Action"];
|
||||
}
|
||||
|
||||
// Parse inline next handler (linked list)
|
||||
if (next_ptr == -1) {
|
||||
next = parse_here("itemkeyhandler");
|
||||
}
|
||||
}
|
||||
45
definitions/cod/listboxdef.xscript
Normal file
45
definitions/cod/listboxdef.xscript
Normal file
@ -0,0 +1,45 @@
|
||||
type listboxdef [display="List Box Def"]
|
||||
{
|
||||
// listBoxDef_s - fixed part: 340 bytes total
|
||||
i32 mouse_pos [ui, readonly, display="Mouse Pos"];
|
||||
i32 start_pos [ui, readonly, display="Start Pos"];
|
||||
i32 end_pos [ui, readonly, display="End Pos"];
|
||||
i32 draw_padding [ui, readonly, display="Draw Padding"];
|
||||
f32 element_width [ui, readonly, display="Element Width"];
|
||||
f32 element_height [ui, readonly, display="Element Height"];
|
||||
i32 element_style [ui, readonly, display="Element Style"];
|
||||
i32 num_columns [ui, readonly, display="Num Columns"];
|
||||
|
||||
// columnInfo_s columnInfo[16] - 256 bytes
|
||||
repeat(16) {
|
||||
_col = parse_here("columninfo") [display="Column"];
|
||||
}
|
||||
|
||||
i32 double_click_ptr [ui, readonly, display="Double Click Ptr"];
|
||||
i32 not_selectable [ui, readonly, display="Not Selectable"];
|
||||
i32 no_scroll_bars [ui, readonly, display="No Scroll Bars"];
|
||||
i32 use_paging [ui, readonly, display="Use Paging"];
|
||||
|
||||
// selectBorder[4] - 16 bytes
|
||||
f32 select_border_x [ui, readonly, display="Select Border X"];
|
||||
f32 select_border_y [ui, readonly, display="Select Border Y"];
|
||||
f32 select_border_w [ui, readonly, display="Select Border W"];
|
||||
f32 select_border_h [ui, readonly, display="Select Border H"];
|
||||
|
||||
// disableColor[4] - 16 bytes
|
||||
f32 disable_color_r [ui, readonly, display="Disable R"];
|
||||
f32 disable_color_g [ui, readonly, display="Disable G"];
|
||||
f32 disable_color_b [ui, readonly, display="Disable B"];
|
||||
f32 disable_color_a [ui, readonly, display="Disable A"];
|
||||
|
||||
i32 select_icon_ptr [ui, readonly, display="Select Icon Ptr"];
|
||||
|
||||
// Inline data
|
||||
if (double_click_ptr == -1) {
|
||||
double_click = cstring() [ui, readonly, display="Double Click"];
|
||||
}
|
||||
|
||||
if (select_icon_ptr == -1) {
|
||||
select_icon = parse_here("material") [display="Select Icon"];
|
||||
}
|
||||
}
|
||||
@ -2,9 +2,25 @@ type loaded_sound [display="Loaded Sound"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
// snd_info_t structure
|
||||
i32 rate [ui, readonly, display="Sample Rate"];
|
||||
i32 bits [ui, readonly, display="Bits"];
|
||||
i32 channels [ui, readonly, display="Channels"];
|
||||
i32 samples [ui, readonly, display="Samples"];
|
||||
i32 block_size [ui, readonly, display="Block Size"];
|
||||
i32 format [ui, readonly, display="Format"];
|
||||
i32 data_len [ui, readonly, display="Data Length"];
|
||||
|
||||
i32 data_ptr [ui, readonly, display="Data Ptr"];
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// TODO: Add full loaded sound structure (audio data, format, etc.)
|
||||
// Parse inline audio data
|
||||
if (data_ptr == -1 && data_len > 0) {
|
||||
audio_data = read(data_len) [ui, readonly, display="Audio Data"];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
type localize [display="Localize Entry"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
}
|
||||
|
||||
// Value comes first in the structure
|
||||
i32 value_ptr [ui, readonly, display="Value Ptr"];
|
||||
|
||||
// Then name
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
// Parse inline value
|
||||
if (value_ptr == -1) {
|
||||
value = cstring() [ui, readonly, display="Value"];
|
||||
}
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,79 +1,82 @@
|
||||
type material [display="Material"]
|
||||
{
|
||||
// Parse material info inline to get material_name_ptr
|
||||
// Material struct - PC COD4 format (80 bytes header)
|
||||
// Verified against old XPlor C++ code and COD4x_Server source
|
||||
|
||||
// ============ MaterialInfo (24 bytes) ============
|
||||
// Name pointer (4 bytes)
|
||||
i32 material_name_ptr [ui, readonly, display="Material Name Ptr"];
|
||||
|
||||
// Info bytes (4 bytes): game_flags, sort_key, atlas counts
|
||||
u8 game_flags [ui, readonly, display="Game Flags"];
|
||||
u8 sort_key [ui, readonly, display="Sort Key"];
|
||||
u8 texture_atlas_row_count [ui, readonly, display="Texture Atlas Row Count"];
|
||||
u8 texture_atlas_column_count [ui, readonly, display="Texture Atlas Column Count"];
|
||||
|
||||
draw_surf = parse_here("gfxdrawsurf") [ui];
|
||||
// Draw surface - 8 bytes (uint64_t packed bitfield)
|
||||
draw_surf = read(8) [ui, readonly, display="Draw Surf"];
|
||||
|
||||
// Surface type bits (4 bytes)
|
||||
u32 surface_type_bits [ui, readonly, display="Surface Type Bits"];
|
||||
|
||||
// Hash index + padding (4 bytes)
|
||||
u16 hash_index [ui, readonly, display="Hash Index"];
|
||||
skip(2);
|
||||
|
||||
skip(2); // padding
|
||||
|
||||
// State bits entry array (34 bytes)
|
||||
state_bits_entries_raw = read(34);
|
||||
state_bits_entries_raw = state_bits_entries_raw [ui, readonly, display="State Bits Entries"];
|
||||
// ============ Material body (56 bytes) ============
|
||||
// State bits entry array - 34 bytes (TECHNIQUE_COUNT = 34)
|
||||
state_bits_entry = read(34) [ui, readonly, display="State Bits Entry"];
|
||||
|
||||
// Counts (6 bytes: 5 fields + 1 padding)
|
||||
u8 texture_count [ui, readonly, display="Texture Count"];
|
||||
u8 constant_count [ui, readonly, display="Constant Count"];
|
||||
u8 state_bits_count [ui, readonly, display="State Bits Count"];
|
||||
u8 state_flags [ui, readonly, display="State Flags"];
|
||||
u8 camera_region [ui, readonly, display="Camera Region"];
|
||||
skip(1);
|
||||
|
||||
skip(1); // padding
|
||||
|
||||
// Pointers to sub-assets
|
||||
// Pointers (16 bytes)
|
||||
i32 technique_set_ptr [ui, readonly, display="Technique Set Ptr"];
|
||||
i32 texture_table_ptr [ui, readonly, display="Texture Table Ptr"];
|
||||
i32 constant_table_ptr [ui, readonly, display="Constant Table Ptr"];
|
||||
i32 state_bits_table_ptr [ui, readonly, display="State Bits Table Ptr"];
|
||||
|
||||
// ============ Inline data (after header) ============
|
||||
// Material name string (parse if inline)
|
||||
if (material_name_ptr == -1) {
|
||||
material_name = cstring() [ui, readonly, display="Material Name"];
|
||||
_name = material_name; // Set display name
|
||||
_name = material_name;
|
||||
}
|
||||
|
||||
// Parse sub-assets if inline
|
||||
// Parse technique set if inline
|
||||
if (technique_set_ptr == -1) {
|
||||
technique_set = parse_here("materialtechniqueset") [ui];
|
||||
technique_set = parse_here("materialtechniqueset");
|
||||
}
|
||||
|
||||
if (texture_table_ptr == -1) {
|
||||
// Parse texture defs if inline
|
||||
if (texture_table_ptr == -1 && texture_count > 0) {
|
||||
texture_defs = 0;
|
||||
if (texture_count > 0) {
|
||||
repeat(texture_count) {
|
||||
_texture_def = parse_here("materialtexturedef") [ui];
|
||||
_texture_def = parse_here("materialtexturedef");
|
||||
texture_defs = push("texture_defs", _texture_def);
|
||||
}
|
||||
}
|
||||
texture_defs = texture_defs [ui];
|
||||
}
|
||||
|
||||
if (constant_table_ptr == -1) {
|
||||
// Parse constant defs if inline
|
||||
if (constant_table_ptr == -1 && constant_count > 0) {
|
||||
constant_defs = 0;
|
||||
if (constant_count > 0) {
|
||||
repeat(constant_count) {
|
||||
_constant_def = parse_here("materialconstantdef") [ui];
|
||||
_constant_def = parse_here("materialconstantdef");
|
||||
constant_defs = push("constant_defs", _constant_def);
|
||||
}
|
||||
}
|
||||
constant_defs = constant_defs [ui];
|
||||
}
|
||||
|
||||
if (state_bits_table_ptr == -1) {
|
||||
// Parse state bits if inline
|
||||
if (state_bits_table_ptr == -1 && state_bits_count > 0) {
|
||||
state_bits = 0;
|
||||
if (state_bits_count > 0) {
|
||||
repeat(state_bits_count) {
|
||||
_state_bit = parse_here("gfxstatebits") [ui];
|
||||
_state_bit = parse_here("gfxstatebits");
|
||||
state_bits = push("state_bits", _state_bit);
|
||||
}
|
||||
}
|
||||
state_bits = state_bits [ui];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
type materialargumentdef [display="Material Argument Def"]
|
||||
{
|
||||
u16 arg_type [ui, readonly, display="Type"];
|
||||
u16 offset [ui, readonly, display="Offset"];
|
||||
u16 size [ui, readonly, display="Size"];
|
||||
u16 buffer [ui, readonly, display="Buffer"];
|
||||
// MaterialArgumentDef is a 4-byte union on PC:
|
||||
// - float* literalConst (pointer)
|
||||
// - MaterialArgumentCodeConst codeConst (u16 index + u16 firstRow)
|
||||
// - u32 codeSampler
|
||||
// - u32 nameHash
|
||||
// We just read it as raw bytes since interpretation depends on arg type
|
||||
value = read(4) [ui, readonly, display="Value"];
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ type materialinfo [display="Material Info"]
|
||||
u8 texture_atlas_row_count [ui, readonly, display="Texture Atlas Row Count"];
|
||||
u8 texture_atlas_column_count [ui, readonly, display="Texture Atlas Column Count"];
|
||||
|
||||
draw_surf = parse_here("gfxdrawsurf") [ui];
|
||||
draw_surf = parse_here("gfxdrawsurf");
|
||||
|
||||
u32 surface_type_bits [ui, readonly, display="Surface Type Bits"];
|
||||
u16 hash_index [ui, readonly, display="Hash Index"];
|
||||
|
||||
@ -1,23 +1,37 @@
|
||||
type materialpass [display="Material Pass"]
|
||||
{
|
||||
// Vertex declaration
|
||||
vertex_decl = parse_here("materialvertexdeclaration") [ui];
|
||||
// Pointers first (header)
|
||||
i32 vertex_decl_ptr [ui, readonly, display="Vertex Decl Ptr"];
|
||||
i32 vertex_shader_ptr [ui, readonly, display="Vertex Shader Ptr"];
|
||||
i32 pixel_shader_ptr [ui, readonly, display="Pixel Shader Ptr"];
|
||||
|
||||
// Vertex shader
|
||||
vertex_shader = parse_here("materialvertexshader") [ui];
|
||||
// Arg counts (COD4 uses u8)
|
||||
u8 per_prim_arg_count [ui, readonly, display="Per Prim Arg Count"];
|
||||
u8 per_obj_arg_count [ui, readonly, display="Per Obj Arg Count"];
|
||||
u8 stable_arg_count [ui, readonly, display="Stable Arg Count"];
|
||||
u8 custom_sampler_flags [ui, readonly, display="Custom Sampler Flags"];
|
||||
|
||||
// Pixel shader (reusing existing pixelshader type)
|
||||
pixel_shader = parse_here("pixelshader") [ui];
|
||||
i32 args_ptr [ui, readonly, display="Args Ptr"];
|
||||
|
||||
// Shader arguments
|
||||
u8 arg_count [ui, readonly, display="Arg Count"];
|
||||
u8 padding;
|
||||
// Now parse inline data if pointers are -1
|
||||
if (vertex_decl_ptr == -1) {
|
||||
vertex_decl = parse_here("materialvertexdeclaration");
|
||||
}
|
||||
|
||||
// Parse argument array
|
||||
if (vertex_shader_ptr == -1) {
|
||||
vertex_shader = parse_here("materialvertexshader");
|
||||
}
|
||||
|
||||
if (pixel_shader_ptr == -1) {
|
||||
pixel_shader = parse_here("pixelshader");
|
||||
}
|
||||
|
||||
// Parse args if ptr is -1 (inline)
|
||||
_arg_count = stable_arg_count + per_obj_arg_count + per_prim_arg_count;
|
||||
if (args_ptr == -1 && _arg_count > 0) {
|
||||
arguments = 0;
|
||||
if (arg_count > 0) {
|
||||
repeat(arg_count) {
|
||||
_arg = parse_here("materialshaderargument") [ui];
|
||||
repeat(_arg_count) {
|
||||
_arg = parse_here("materialshaderargument");
|
||||
arguments = push("arguments", _arg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,5 +4,5 @@ type materialshaderargument [display="Material Shader Argument"]
|
||||
u16 dest [ui, readonly, display="Dest"];
|
||||
|
||||
// Argument definition
|
||||
arg_def = parse_here("materialargumentdef") [ui];
|
||||
arg_def = parse_here("materialargumentdef");
|
||||
}
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
type materialstreamrouting [display="Material Stream Routing"]
|
||||
{
|
||||
i32 routing_name_ptr [ui, readonly, display="Routing Name Ptr"];
|
||||
|
||||
// Parse routing name if inline
|
||||
if (routing_name_ptr == -1) {
|
||||
routing_name = cstring() [ui, readonly, display="Routing Name"];
|
||||
_name = routing_name;
|
||||
}
|
||||
// Stream routing arrays - 16 bytes each
|
||||
source = read(16) [ui, readonly, display="Source"];
|
||||
dest = read(16) [ui, readonly, display="Dest"];
|
||||
}
|
||||
|
||||
@ -2,21 +2,65 @@ type materialtechnique [display="Material Technique"]
|
||||
{
|
||||
i32 technique_name_ptr [ui, readonly, display="Technique Name Ptr"];
|
||||
|
||||
// Parse technique name if inline
|
||||
u16 flags [ui, readonly, display="Flags"];
|
||||
u16 pass_count [ui, readonly, display="Pass Count"];
|
||||
|
||||
// COD zone streaming order:
|
||||
// 1. All pass HEADERS (20 bytes each)
|
||||
// 2. Technique name (if inline)
|
||||
// 3. Inline data for each pass (vertex_decl, vertex_shader, pixel_shader, args)
|
||||
|
||||
// First pass: Read all pass headers (20 bytes each) and store key values
|
||||
// MaterialPass header = vertex_decl_ptr(4) + vertex_shader_ptr(4) + pixel_shader_ptr(4) +
|
||||
// arg_counts(4) + args_ptr(4) = 20 bytes
|
||||
_pass_headers_start = pos();
|
||||
_pass_header_size = 20;
|
||||
if (pass_count > 0) {
|
||||
_total_header_bytes = pass_count * _pass_header_size;
|
||||
pass_headers_raw = read(_total_header_bytes);
|
||||
}
|
||||
|
||||
// Parse technique name (comes AFTER headers, BEFORE inline data)
|
||||
if (technique_name_ptr == -1) {
|
||||
technique_name = cstring() [ui, readonly, display="Technique Name"];
|
||||
_name = technique_name;
|
||||
}
|
||||
|
||||
u16 flags [ui, readonly, display="Flags"];
|
||||
u16 pass_count [ui, readonly, display="Pass Count"];
|
||||
|
||||
// Parse material passes
|
||||
passes = 0;
|
||||
// Second pass: Parse inline data for each pass based on stored header values
|
||||
// Just parse sequentially - data is laid out in order
|
||||
if (pass_count > 0) {
|
||||
repeat(pass_count) {
|
||||
_pass = parse_here("materialpass") [ui];
|
||||
passes = push("passes", _pass);
|
||||
_base = _pass_headers_start + (_i * _pass_header_size);
|
||||
_vertex_decl_ptr = i32at(_base);
|
||||
_vertex_shader_ptr = i32at(_base + 4);
|
||||
_pixel_shader_ptr = i32at(_base + 8);
|
||||
_per_prim_arg_count = u8at(_base + 12);
|
||||
_per_obj_arg_count = u8at(_base + 13);
|
||||
_stable_arg_count = u8at(_base + 14);
|
||||
_args_ptr = i32at(_base + 16);
|
||||
|
||||
// Parse vertex declaration if inline
|
||||
if (_vertex_decl_ptr == -1) {
|
||||
_vd = parse_here("materialvertexdeclaration");
|
||||
}
|
||||
|
||||
// Parse vertex shader if inline
|
||||
if (_vertex_shader_ptr == -1) {
|
||||
_vs = parse_here("materialvertexshader");
|
||||
}
|
||||
|
||||
// Parse pixel shader if inline
|
||||
if (_pixel_shader_ptr == -1) {
|
||||
_ps = parse_here("pixelshader");
|
||||
}
|
||||
|
||||
// Parse shader arguments if inline
|
||||
_arg_count = _stable_arg_count + _per_obj_arg_count + _per_prim_arg_count;
|
||||
if (_args_ptr == -1 && _arg_count > 0) {
|
||||
repeat(_arg_count) {
|
||||
_arg = parse_here("materialshaderargument");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,8 +5,7 @@ type materialtechniqueset [display="Material Technique Set"]
|
||||
u8 world_vert_format [ui, readonly, display="World Vert Format"];
|
||||
u8 has_been_uploaded [ui, readonly, display="Has Been Uploaded"];
|
||||
|
||||
skip(2); // padding
|
||||
skip(4); // more padding
|
||||
skip(2); // padding to align to 4 bytes (total header = 8 bytes)
|
||||
|
||||
// Technique count depends on game/platform
|
||||
technique_count = 0;
|
||||
@ -35,6 +34,19 @@ type materialtechniqueset [display="Material Technique Set"]
|
||||
|
||||
technique_count = technique_count [ui, readonly, display="Technique Count"];
|
||||
|
||||
// Check if this looks like a valid techset
|
||||
// In stub/minimal techsets (like in _load files), name_ptr is often a small positive value
|
||||
// indicating a reference to another zone. world_vert_format and has_been_uploaded should be 0-1.
|
||||
_is_valid_techset = 1;
|
||||
if (world_vert_format > 1) {
|
||||
_is_valid_techset = 0;
|
||||
}
|
||||
if (has_been_uploaded > 1) {
|
||||
_is_valid_techset = 0;
|
||||
}
|
||||
|
||||
// Only parse technique pointers and inline data for valid techsets
|
||||
if (_is_valid_techset == 1) {
|
||||
// Save position after technique count
|
||||
_ptrs_start_pos = pos();
|
||||
|
||||
@ -47,7 +59,7 @@ type materialtechniqueset [display="Material Technique Set"]
|
||||
// Parse technique set name if inline
|
||||
if (technique_set_name_ptr == -1) {
|
||||
technique_set_name = cstring() [ui, readonly, display="Technique Set Name"];
|
||||
_name = technique_set_name;
|
||||
_name = strip(technique_set_name, ",");
|
||||
}
|
||||
|
||||
// Second pass: Parse each technique if ptr == -1 (inline)
|
||||
@ -57,9 +69,10 @@ type materialtechniqueset [display="Material Technique Set"]
|
||||
_ptr_offset = _ptrs_start_pos + (_i * 4);
|
||||
_ptr = u32at(_ptr_offset);
|
||||
if (_ptr == 4294967295) { // -1 as u32
|
||||
_technique = parse_here("materialtechnique") [ui];
|
||||
_technique = parse_here("materialtechnique");
|
||||
techniques = push("techniques", _technique);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,15 @@
|
||||
type materialtexturedef [display="Material Texture Def"]
|
||||
{
|
||||
// MaterialTextureDef - 12 bytes total
|
||||
// The image pointer is just a reference to a GfxImage asset that's
|
||||
// streamed separately in the zone file - NOT inline within the material
|
||||
u32 name_hash [ui, readonly, display="Name Hash"];
|
||||
u8 name_start [ui, readonly, display="Name Start"];
|
||||
u8 name_end [ui, readonly, display="Name End"];
|
||||
u8 sampler_state [ui, readonly, display="Sampler State"];
|
||||
u8 semantic [ui, readonly, display="Semantic"];
|
||||
|
||||
def_info = parse_here("materialtexturedefinfo") [ui];
|
||||
// GfxImage* image - pointer to image asset (resolved elsewhere in zone)
|
||||
// -1 means "needs fixup", but image data is a separate asset entry
|
||||
i32 image_ptr [ui, readonly, display="Image Ptr"];
|
||||
}
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
type materialtexturedefinfo [display="Material Texture Def Info"]
|
||||
{
|
||||
i32 texture_ptr [ui, readonly, display="Texture Ptr"];
|
||||
|
||||
// Parse inline image if pointer is -1
|
||||
if (texture_ptr == -1) {
|
||||
image = parse_here("image");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,12 @@
|
||||
type materialvertexdeclaration [display="Material Vertex Declaration"]
|
||||
{
|
||||
i32 decl_name_ptr [ui, readonly, display="Decl Name Ptr"];
|
||||
|
||||
// Parse declaration name if inline
|
||||
if (decl_name_ptr == -1) {
|
||||
decl_name = cstring() [ui, readonly, display="Decl Name"];
|
||||
_name = decl_name;
|
||||
}
|
||||
|
||||
// No name pointer in this structure!
|
||||
u8 stream_count [ui, readonly, display="Stream Count"];
|
||||
u8 has_opt_stream [ui, readonly, display="Has Opt Stream"];
|
||||
u8 has_optional_source [ui, readonly, display="Has Optional Source"];
|
||||
u8 is_loaded [ui, readonly, display="Is Loaded"];
|
||||
|
||||
skip(2); // padding
|
||||
skip(1); // padding
|
||||
|
||||
// Vertex stream routing
|
||||
routing = parse_here("materialvertexstreamrouting") [ui];
|
||||
routing = parse_here("materialvertexstreamrouting");
|
||||
}
|
||||
|
||||
@ -2,12 +2,14 @@ type materialvertexshader [display="Material Vertex Shader"]
|
||||
{
|
||||
i32 shader_name_ptr [ui, readonly, display="Shader Name Ptr"];
|
||||
|
||||
// Parse shader name if inline
|
||||
// Vertex shader program (parse header first)
|
||||
program = parse_here("materialvertexshaderprogram");
|
||||
|
||||
// Parse shader name AFTER program (if inline)
|
||||
if (shader_name_ptr == -1) {
|
||||
shader_name = cstring() [ui, readonly, display="Shader Name"];
|
||||
_name = shader_name;
|
||||
}
|
||||
|
||||
// Vertex shader program
|
||||
program = parse_here("materialvertexshaderprogram") [ui];
|
||||
// Note: LoadDef program data parsing happens in materialvertexshaderprogram
|
||||
}
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
type materialvertexshaderprogram [display="Material Vertex Shader Program"]
|
||||
{
|
||||
// On PC COD4, this is just a D3D shader pointer
|
||||
// No load def bytecode on PC - shaders are pre-compiled D3D bytecode
|
||||
i32 vertex_shader_ptr [ui, readonly, display="Vertex Shader Ptr"];
|
||||
|
||||
// If vertex shader ptr is 0, parse load def
|
||||
if (vertex_shader_ptr == 0) {
|
||||
load_def = parse_here("gfxvertexshaderloaddef") [ui];
|
||||
}
|
||||
// NOTE: On console platforms, this would have a GfxVertexShaderLoadDef
|
||||
// but PC uses D3D compiled shaders directly
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
type materialvertexstreamrouting [display="Material Vertex Stream Routing"]
|
||||
{
|
||||
// Parse stream routing data
|
||||
data = parse_here("materialstreamrouting") [ui];
|
||||
// Stream routing data (32 bytes: source[16] + dest[16])
|
||||
data = parse_here("materialstreamrouting");
|
||||
|
||||
// Vertex declaration pointer
|
||||
i32 decl_ptr [ui, readonly, display="Decl Ptr"];
|
||||
}
|
||||
|
||||
@ -1,10 +1,67 @@
|
||||
type menu [display="Menu"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
// windowDef_t embedded structure (156 bytes)
|
||||
window = parse_here("windowdef");
|
||||
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
i32 font_ptr [ui, readonly, display="Font Ptr"];
|
||||
i32 full_screen [ui, readonly, display="Full Screen"];
|
||||
i32 item_count [ui, readonly, display="Item Count"];
|
||||
i32 font_index [ui, readonly, display="Font Index"];
|
||||
i32 cursor_item [ui, readonly, display="Cursor Item"];
|
||||
i32 fade_cycle [ui, readonly, display="Fade Cycle"];
|
||||
|
||||
// Fade values (3 floats = 12 bytes)
|
||||
fade_values = read(12) [ui, readonly, display="Fade Clamp/Amount/InAmount"];
|
||||
|
||||
// Blur radius (float = 4 bytes)
|
||||
blur_radius = read(4) [ui, readonly, display="Blur Radius"];
|
||||
|
||||
// Event handler pointers
|
||||
i32 on_open_ptr [ui, readonly, display="OnOpen Ptr"];
|
||||
i32 on_close_ptr [ui, readonly, display="OnClose Ptr"];
|
||||
i32 on_esc_ptr [ui, readonly, display="OnESC Ptr"];
|
||||
i32 on_key_ptr [ui, readonly, display="OnKey Ptr"];
|
||||
|
||||
i32 sound_name_ptr [ui, readonly, display="Sound Name Ptr"];
|
||||
i32 items_ptr [ui, readonly, display="Items Ptr"];
|
||||
i32 allowed_binding_ptr [ui, readonly, display="Allowed Binding Ptr"];
|
||||
i32 sound_loop_ptr [ui, readonly, display="Sound Loop Ptr"];
|
||||
i32 image_track [ui, readonly, display="Image Track"];
|
||||
|
||||
// Parse inline font
|
||||
if (font_ptr == -1) {
|
||||
font = cstring() [ui, readonly, display="Font"];
|
||||
}
|
||||
|
||||
// TODO: Add full menu structure (items, properties, events, etc.)
|
||||
// Parse inline strings
|
||||
if (on_open_ptr == -1) {
|
||||
on_open = cstring() [ui, readonly, display="OnOpen"];
|
||||
}
|
||||
if (on_close_ptr == -1) {
|
||||
on_close = cstring() [ui, readonly, display="OnClose"];
|
||||
}
|
||||
if (on_esc_ptr == -1) {
|
||||
on_esc = cstring() [ui, readonly, display="OnESC"];
|
||||
}
|
||||
if (on_key_ptr == -1) {
|
||||
on_key = parse_here("itemkeyhandler");
|
||||
}
|
||||
if (sound_name_ptr == -1) {
|
||||
sound_name = cstring() [ui, readonly, display="Sound Name"];
|
||||
}
|
||||
if (allowed_binding_ptr == -1) {
|
||||
allowed_binding = cstring() [ui, readonly, display="Allowed Binding"];
|
||||
}
|
||||
if (sound_loop_ptr == -1) {
|
||||
sound_loop = cstring() [ui, readonly, display="Sound Loop"];
|
||||
}
|
||||
|
||||
// Parse inline items
|
||||
if (items_ptr == -1 && item_count > 0) {
|
||||
items = 0;
|
||||
repeat(item_count) {
|
||||
_item = parse_here("itemdef");
|
||||
items = push("items", _item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
159
definitions/cod/menudef.xscript
Normal file
159
definitions/cod/menudef.xscript
Normal file
@ -0,0 +1,159 @@
|
||||
type menudef [display="Menu Definition"]
|
||||
{
|
||||
// MenuDef_t structure from OpenAssetTools IW3_Assets.h
|
||||
// Fixed part: 272 bytes total
|
||||
|
||||
// ============ WindowDef_t embedded (156 bytes) ============
|
||||
window = parse_here("windowdef") [display="Window"];
|
||||
|
||||
// ============ Menu Properties ============
|
||||
i32 font_ptr [ui, readonly, display="Font Ptr"];
|
||||
i32 full_screen [ui, readonly, display="Full Screen"];
|
||||
i32 item_count [ui, readonly, display="Item Count"];
|
||||
i32 font_index [ui, readonly, display="Font Index"];
|
||||
i32 cursor_item [ui, readonly, display="Cursor Item"];
|
||||
i32 fade_cycle [ui, readonly, display="Fade Cycle"];
|
||||
|
||||
// Fade values (16 bytes)
|
||||
f32 fade_clamp [ui, readonly, display="Fade Clamp"];
|
||||
f32 fade_amount [ui, readonly, display="Fade Amount"];
|
||||
f32 fade_in_amount [ui, readonly, display="Fade In Amount"];
|
||||
f32 blur_radius [ui, readonly, display="Blur Radius"];
|
||||
|
||||
// Event handler pointers
|
||||
i32 on_open_ptr [ui, readonly, display="OnOpen Ptr"];
|
||||
i32 on_close_ptr [ui, readonly, display="OnClose Ptr"];
|
||||
i32 on_esc_ptr [ui, readonly, display="OnESC Ptr"];
|
||||
i32 on_key_ptr [ui, readonly, display="OnKey Ptr"];
|
||||
|
||||
// Visible expression (statement_s = 8 bytes)
|
||||
visible_exp = parse_here("statement") [display="Visible Exp"];
|
||||
|
||||
// More pointers
|
||||
i32 allowed_binding_ptr [ui, readonly, display="Allowed Binding Ptr"];
|
||||
i32 sound_name_ptr [ui, readonly, display="Sound Name Ptr"];
|
||||
i32 image_track [ui, readonly, display="Image Track"];
|
||||
|
||||
// Focus color (16 bytes)
|
||||
f32 focus_color_r [ui, readonly, display="Focus R"];
|
||||
f32 focus_color_g [ui, readonly, display="Focus G"];
|
||||
f32 focus_color_b [ui, readonly, display="Focus B"];
|
||||
f32 focus_color_a [ui, readonly, display="Focus A"];
|
||||
|
||||
// Disable color (16 bytes)
|
||||
f32 disable_color_r [ui, readonly, display="Disable R"];
|
||||
f32 disable_color_g [ui, readonly, display="Disable G"];
|
||||
f32 disable_color_b [ui, readonly, display="Disable B"];
|
||||
f32 disable_color_a [ui, readonly, display="Disable A"];
|
||||
|
||||
// Rect expressions (2 x statement_s = 16 bytes)
|
||||
rect_x_exp = parse_here("statement") [display="Rect X Exp"];
|
||||
rect_y_exp = parse_here("statement") [display="Rect Y Exp"];
|
||||
|
||||
// Items pointer
|
||||
i32 items_ptr [ui, readonly, display="Items Ptr"];
|
||||
|
||||
// ============================================================
|
||||
// INLINE DATA PARSING (exact order from zone file streaming)
|
||||
// ============================================================
|
||||
|
||||
// 1. Window name (if name_ptr == -1)
|
||||
_win_name_ptr = get(window, "name_ptr");
|
||||
if (_win_name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// 2. Window group (if group_ptr == -1)
|
||||
_win_group_ptr = get(window, "group_ptr");
|
||||
if (_win_group_ptr == -1) {
|
||||
group = cstring() [ui, readonly, display="Group"];
|
||||
}
|
||||
|
||||
// 3. Window background Material (if background_ptr == -1)
|
||||
_win_bg_ptr = get(window, "background_ptr");
|
||||
if (_win_bg_ptr == -1) {
|
||||
background = parse_here("material") [display="Background"];
|
||||
}
|
||||
|
||||
// 4. Font (if font_ptr == -1)
|
||||
if (font_ptr == -1) {
|
||||
font = cstring() [ui, readonly, display="Font"];
|
||||
}
|
||||
|
||||
// 5. OnOpen script (if on_open_ptr == -1)
|
||||
if (on_open_ptr == -1) {
|
||||
on_open = cstring() [ui, readonly, display="OnOpen"];
|
||||
}
|
||||
|
||||
// 6. OnClose script (if on_close_ptr == -1)
|
||||
if (on_close_ptr == -1) {
|
||||
on_close = cstring() [ui, readonly, display="OnClose"];
|
||||
}
|
||||
|
||||
// 7. OnESC script (if on_esc_ptr == -1)
|
||||
if (on_esc_ptr == -1) {
|
||||
on_esc = cstring() [ui, readonly, display="OnESC"];
|
||||
}
|
||||
|
||||
// 8. OnKey handler chain (if on_key_ptr == -1)
|
||||
if (on_key_ptr == -1) {
|
||||
on_key = parse_here("itemkeyhandler") [display="OnKey"];
|
||||
}
|
||||
|
||||
// 9. Visible expression entries (if entries_ptr == -1)
|
||||
_vis_num = get(visible_exp, "num_entries");
|
||||
_vis_ptr = get(visible_exp, "entries_ptr");
|
||||
if (_vis_ptr == -1 && _vis_num > 0 ) {
|
||||
// Read pointer array
|
||||
_vis_ptr_size = _vis_num * 4;
|
||||
_vis_ptrs = read(_vis_ptr_size) [display="Visible Entry Ptrs"];
|
||||
// Parse each expression entry
|
||||
repeat(_vis_num) {
|
||||
_vis_entry = parse_here("expressionentry") [display="Visible Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 10. Allowed binding (if allowed_binding_ptr == -1)
|
||||
if (allowed_binding_ptr == -1) {
|
||||
allowed_binding = cstring() [ui, readonly, display="Allowed Binding"];
|
||||
}
|
||||
|
||||
// 11. Sound name (if sound_name_ptr == -1)
|
||||
if (sound_name_ptr == -1) {
|
||||
sound_name = cstring() [ui, readonly, display="Sound Name"];
|
||||
}
|
||||
|
||||
// 12. Rect X expression entries (if entries_ptr == -1)
|
||||
_rx_num = get(rect_x_exp, "num_entries");
|
||||
_rx_ptr = get(rect_x_exp, "entries_ptr");
|
||||
if (_rx_ptr == -1 && _rx_num > 0 ) {
|
||||
_rx_ptr_size = _rx_num * 4;
|
||||
_rx_ptrs = read(_rx_ptr_size) [display="Rect X Entry Ptrs"];
|
||||
repeat(_rx_num) {
|
||||
_rx_entry = parse_here("expressionentry") [display="Rect X Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 13. Rect Y expression entries (if entries_ptr == -1)
|
||||
_ry_num = get(rect_y_exp, "num_entries");
|
||||
_ry_ptr = get(rect_y_exp, "entries_ptr");
|
||||
if (_ry_ptr == -1 && _ry_num > 0 ) {
|
||||
_ry_ptr_size = _ry_num * 4;
|
||||
_ry_ptrs = read(_ry_ptr_size) [display="Rect Y Entry Ptrs"];
|
||||
repeat(_ry_num) {
|
||||
_ry_entry = parse_here("expressionentry") [display="Rect Y Entry"];
|
||||
}
|
||||
}
|
||||
|
||||
// 14. Items array (if items_ptr == -1 and item_count > 0)
|
||||
if (items_ptr == -1 && item_count > 0 ) {
|
||||
// Array of item_count pointers (4 bytes each)
|
||||
_items_ptr_size = item_count * 4;
|
||||
_items_ptrs = read(_items_ptr_size) [display="Item Ptrs"];
|
||||
// Then item_count itemdefs follow (each -1 pointer means inline)
|
||||
repeat(item_count) {
|
||||
_item = parse_here("itemdef") [display="Item"];
|
||||
}
|
||||
}
|
||||
}
|
||||
35
definitions/cod/menulist.xscript
Normal file
35
definitions/cod/menulist.xscript
Normal file
@ -0,0 +1,35 @@
|
||||
type menulist [display="Menu List"]
|
||||
{
|
||||
// MenuList header (12 bytes)
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
u32 menu_count [ui, readonly, display="Menu Count"];
|
||||
i32 menus_ptr [ui, readonly, display="Menus Ptr"];
|
||||
|
||||
// Name string (if inline)
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// Menu definitions (if inline)
|
||||
if (menus_ptr == -1 && menu_count > 0 ) {
|
||||
// First pass: parse all menu pointers
|
||||
menu_ptrs = 0;
|
||||
repeat(menu_count) {
|
||||
_ptr = parse_here("menuptr");
|
||||
menu_ptrs = push("menu_ptrs", _ptr);
|
||||
}
|
||||
|
||||
// Second pass: parse menudefs for inline pointers
|
||||
menus = 0;
|
||||
repeat(menu_count) {
|
||||
_ptr_obj = get(menu_ptrs, _i);
|
||||
_ptr_val = get(_ptr_obj, "ptr");
|
||||
if (_ptr_val == -1) {
|
||||
_menu = parse_here("menudef");
|
||||
menus = push("menus", _menu);
|
||||
}
|
||||
}
|
||||
menus = menus [table="Menus", columns="name"];
|
||||
}
|
||||
}
|
||||
4
definitions/cod/menuptr.xscript
Normal file
4
definitions/cod/menuptr.xscript
Normal file
@ -0,0 +1,4 @@
|
||||
type menuptr [display="Menu Ptr"]
|
||||
{
|
||||
i32 ptr [ui, readonly, display="Ptr"];
|
||||
}
|
||||
51
definitions/cod/multidef.xscript
Normal file
51
definitions/cod/multidef.xscript
Normal file
@ -0,0 +1,51 @@
|
||||
type multidef [display="Multi Def"]
|
||||
{
|
||||
// multiDef_s - fixed part: 392 bytes total
|
||||
// const char* dvarList[32] + const char* dvarStr[32] + float dvarValue[32] + int count + int strDef
|
||||
|
||||
// Read all 32 dvarList pointers
|
||||
i32 dvar_list_ptr_0; i32 dvar_list_ptr_1; i32 dvar_list_ptr_2; i32 dvar_list_ptr_3;
|
||||
i32 dvar_list_ptr_4; i32 dvar_list_ptr_5; i32 dvar_list_ptr_6; i32 dvar_list_ptr_7;
|
||||
i32 dvar_list_ptr_8; i32 dvar_list_ptr_9; i32 dvar_list_ptr_10; i32 dvar_list_ptr_11;
|
||||
i32 dvar_list_ptr_12; i32 dvar_list_ptr_13; i32 dvar_list_ptr_14; i32 dvar_list_ptr_15;
|
||||
i32 dvar_list_ptr_16; i32 dvar_list_ptr_17; i32 dvar_list_ptr_18; i32 dvar_list_ptr_19;
|
||||
i32 dvar_list_ptr_20; i32 dvar_list_ptr_21; i32 dvar_list_ptr_22; i32 dvar_list_ptr_23;
|
||||
i32 dvar_list_ptr_24; i32 dvar_list_ptr_25; i32 dvar_list_ptr_26; i32 dvar_list_ptr_27;
|
||||
i32 dvar_list_ptr_28; i32 dvar_list_ptr_29; i32 dvar_list_ptr_30; i32 dvar_list_ptr_31;
|
||||
|
||||
// Read all 32 dvarStr pointers
|
||||
i32 dvar_str_ptr_0; i32 dvar_str_ptr_1; i32 dvar_str_ptr_2; i32 dvar_str_ptr_3;
|
||||
i32 dvar_str_ptr_4; i32 dvar_str_ptr_5; i32 dvar_str_ptr_6; i32 dvar_str_ptr_7;
|
||||
i32 dvar_str_ptr_8; i32 dvar_str_ptr_9; i32 dvar_str_ptr_10; i32 dvar_str_ptr_11;
|
||||
i32 dvar_str_ptr_12; i32 dvar_str_ptr_13; i32 dvar_str_ptr_14; i32 dvar_str_ptr_15;
|
||||
i32 dvar_str_ptr_16; i32 dvar_str_ptr_17; i32 dvar_str_ptr_18; i32 dvar_str_ptr_19;
|
||||
i32 dvar_str_ptr_20; i32 dvar_str_ptr_21; i32 dvar_str_ptr_22; i32 dvar_str_ptr_23;
|
||||
i32 dvar_str_ptr_24; i32 dvar_str_ptr_25; i32 dvar_str_ptr_26; i32 dvar_str_ptr_27;
|
||||
i32 dvar_str_ptr_28; i32 dvar_str_ptr_29; i32 dvar_str_ptr_30; i32 dvar_str_ptr_31;
|
||||
|
||||
// float dvarValue[32] - 128 bytes
|
||||
dvar_values = read(128) [display="Dvar Values"];
|
||||
|
||||
i32 count [ui, readonly, display="Count"];
|
||||
i32 str_def [ui, readonly, display="Str Def"];
|
||||
|
||||
// Parse inline dvarList strings (only for -1 pointers, up to count)
|
||||
if (dvar_list_ptr_0 == -1 && count > 0) { dvar_list_0 = cstring(); }
|
||||
if (dvar_list_ptr_1 == -1 && count > 1) { dvar_list_1 = cstring(); }
|
||||
if (dvar_list_ptr_2 == -1 && count > 2) { dvar_list_2 = cstring(); }
|
||||
if (dvar_list_ptr_3 == -1 && count > 3) { dvar_list_3 = cstring(); }
|
||||
if (dvar_list_ptr_4 == -1 && count > 4) { dvar_list_4 = cstring(); }
|
||||
if (dvar_list_ptr_5 == -1 && count > 5) { dvar_list_5 = cstring(); }
|
||||
if (dvar_list_ptr_6 == -1 && count > 6) { dvar_list_6 = cstring(); }
|
||||
if (dvar_list_ptr_7 == -1 && count > 7) { dvar_list_7 = cstring(); }
|
||||
|
||||
// Parse inline dvarStr strings (only for -1 pointers, up to count)
|
||||
if (dvar_str_ptr_0 == -1 && count > 0) { dvar_str_0 = cstring(); }
|
||||
if (dvar_str_ptr_1 == -1 && count > 1) { dvar_str_1 = cstring(); }
|
||||
if (dvar_str_ptr_2 == -1 && count > 2) { dvar_str_2 = cstring(); }
|
||||
if (dvar_str_ptr_3 == -1 && count > 3) { dvar_str_3 = cstring(); }
|
||||
if (dvar_str_ptr_4 == -1 && count > 4) { dvar_str_4 = cstring(); }
|
||||
if (dvar_str_ptr_5 == -1 && count > 5) { dvar_str_5 = cstring(); }
|
||||
if (dvar_str_ptr_6 == -1 && count > 6) { dvar_str_6 = cstring(); }
|
||||
if (dvar_str_ptr_7 == -1 && count > 7) { dvar_str_7 = cstring(); }
|
||||
}
|
||||
@ -4,7 +4,7 @@ type pixelshader [display="Pixel Shader"]
|
||||
i32 shader_name_ptr [ui, readonly, display="Shader Name Ptr"];
|
||||
|
||||
// Shader program structure
|
||||
program = parse_here("pixelshaderprogram") [ui];
|
||||
program = parse_here("pixelshaderprogram");
|
||||
|
||||
// Parse shader name if inline
|
||||
if (shader_name_ptr == -1) {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
type pixelshaderprogram [display="Pixel Shader Program"]
|
||||
{
|
||||
// On PC COD4, this is just a D3D shader pointer (or -1 for inline D3D shader)
|
||||
// No load def bytecode on PC - shaders are pre-compiled D3D bytecode
|
||||
i32 pixel_shader_ptr [ui, readonly, display="Pixel Shader Ptr"];
|
||||
|
||||
// If pixel shader ptr is 0 (not -1), parse load def
|
||||
if (pixel_shader_ptr == 0) {
|
||||
load_def = parse_here("gfxpixelshaderloaddef") [ui];
|
||||
}
|
||||
// NOTE: On console platforms, this would have a GfxPixelShaderLoadDef
|
||||
// but PC uses D3D compiled shaders directly
|
||||
}
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
type rawfile [display="Raw File"]
|
||||
{
|
||||
// Header: name_ptr, length, buffer_ptr (12 bytes)
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
i32 len [ui, readonly, display="Length"];
|
||||
i32 buffer_ptr [ui, readonly, display="Buffer Ptr"];
|
||||
|
||||
// Name string (if inline)
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
i32 compression_type [ui, readonly, display="Compression Type"];
|
||||
i32 data_ptr [ui, readonly, display="Data Ptr"];
|
||||
u32 data_len [ui, readonly, display="Data Length"];
|
||||
|
||||
if (data_ptr == -1 && data_len > 0) {
|
||||
raw_data = read(data_len) [ui, readonly, display="Raw Data"];
|
||||
// Data buffer (if inline) - read len + 1 bytes for null terminator
|
||||
if (buffer_ptr == -1 && len > 0) {
|
||||
raw_data = read(len + 1) [ui, readonly, display="Raw Data"];
|
||||
}
|
||||
}
|
||||
|
||||
10
definitions/cod/rectdef.xscript
Normal file
10
definitions/cod/rectdef.xscript
Normal file
@ -0,0 +1,10 @@
|
||||
type rectdef [display="Rect Definition"]
|
||||
{
|
||||
// RectDef - 24 bytes
|
||||
f32 x [ui, readonly, display="X"];
|
||||
f32 y [ui, readonly, display="Y"];
|
||||
f32 w [ui, readonly, display="Width"];
|
||||
f32 h [ui, readonly, display="Height"];
|
||||
i32 horz_align [ui, readonly, display="Horz Align"];
|
||||
i32 vert_align [ui, readonly, display="Vert Align"];
|
||||
}
|
||||
@ -5,5 +5,6 @@ type scriptstring [display="Script String"]
|
||||
if (ptr == -1) {
|
||||
// Read null-terminated string (C-style string)
|
||||
value = cstring() [ui, readonly, display="Value"];
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
19
definitions/cod/sndcurve.xscript
Normal file
19
definitions/cod/sndcurve.xscript
Normal file
@ -0,0 +1,19 @@
|
||||
type sndcurve [display="Sound Curve"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
u16 knot_count [ui, readonly, display="Knot Count"];
|
||||
skip(2); // padding
|
||||
i32 knots_ptr [ui, readonly, display="Knots Ptr"];
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// Parse inline knots (each knot is 2 floats = 8 bytes)
|
||||
if (knots_ptr == -1 && knot_count > 0) {
|
||||
_knots_size = knot_count * 8;
|
||||
knots = read(_knots_size) [ui, readonly, display="Knots"];
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,21 @@
|
||||
type sound [display="Sound"]
|
||||
type sound [display="Sound Alias List"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
i32 head_ptr [ui, readonly, display="Head Ptr"];
|
||||
i32 count [ui, readonly, display="Count"];
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// TODO: Add full sound alias structure
|
||||
// Parse inline sound aliases
|
||||
if (head_ptr == -1 && count > 0) {
|
||||
aliases = 0;
|
||||
repeat(count) {
|
||||
_alias = parse_here("soundalias");
|
||||
aliases = push("aliases", _alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
75
definitions/cod/soundalias.xscript
Normal file
75
definitions/cod/soundalias.xscript
Normal file
@ -0,0 +1,75 @@
|
||||
type soundalias [display="Sound Alias"]
|
||||
{
|
||||
i32 alias_name_ptr [ui, readonly, display="Alias Name Ptr"];
|
||||
i32 subtitle_ptr [ui, readonly, display="Subtitle Ptr"];
|
||||
i32 secondary_alias_name_ptr [ui, readonly, display="Secondary Alias Name Ptr"];
|
||||
i32 chain_alias_name_ptr [ui, readonly, display="Chain Alias Name Ptr"];
|
||||
i32 sound_file_ptr [ui, readonly, display="Sound File Ptr"];
|
||||
|
||||
i32 sequence [ui, readonly, display="Sequence"];
|
||||
|
||||
// Volume (read as raw bytes - 2 floats)
|
||||
vol_min_max = read(8) [ui, readonly, display="Vol Min/Max"];
|
||||
|
||||
// Pitch (read as raw bytes - 2 floats)
|
||||
pitch_min_max = read(8) [ui, readonly, display="Pitch Min/Max"];
|
||||
|
||||
// Distance (read as raw bytes - 2 floats)
|
||||
dist_min_max = read(8) [ui, readonly, display="Dist Min/Max"];
|
||||
|
||||
// Velocity min (float)
|
||||
velocity_min = read(4) [ui, readonly, display="Velocity Min"];
|
||||
|
||||
i32 flags [ui, readonly, display="Flags"];
|
||||
|
||||
// Master priority/percentage (3 floats)
|
||||
master_values = read(12) [ui, readonly, display="Master Priority/Percentage"];
|
||||
|
||||
// Probability (float)
|
||||
probability = read(4) [ui, readonly, display="Probability"];
|
||||
|
||||
// LFE/Center percentage (2 floats)
|
||||
lfe_center = read(8) [ui, readonly, display="LFE/Center Percentage"];
|
||||
|
||||
i32 start_delay [ui, readonly, display="Start Delay"];
|
||||
|
||||
i32 volume_falloff_curve_ptr [ui, readonly, display="Volume Falloff Curve Ptr"];
|
||||
|
||||
// Envelope values (3 floats)
|
||||
envelope_values = read(12) [ui, readonly, display="Envelope Min/Max/Percentage"];
|
||||
|
||||
i32 speaker_map_ptr [ui, readonly, display="Speaker Map Ptr"];
|
||||
|
||||
// Parse inline strings
|
||||
if (alias_name_ptr == -1) {
|
||||
alias_name = cstring() [ui, readonly, display="Alias Name"];
|
||||
_name = alias_name;
|
||||
}
|
||||
|
||||
if (subtitle_ptr == -1) {
|
||||
subtitle = cstring() [ui, readonly, display="Subtitle"];
|
||||
}
|
||||
|
||||
if (secondary_alias_name_ptr == -1) {
|
||||
secondary_alias_name = cstring() [ui, readonly, display="Secondary Alias Name"];
|
||||
}
|
||||
|
||||
if (chain_alias_name_ptr == -1) {
|
||||
chain_alias_name = cstring() [ui, readonly, display="Chain Alias Name"];
|
||||
}
|
||||
|
||||
// Parse inline sound file
|
||||
if (sound_file_ptr == -1) {
|
||||
sound_file = parse_here("soundfile");
|
||||
}
|
||||
|
||||
// Parse inline volume falloff curve
|
||||
if (volume_falloff_curve_ptr == -1) {
|
||||
volume_falloff_curve = parse_here("sndcurve");
|
||||
}
|
||||
|
||||
// Parse inline speaker map
|
||||
if (speaker_map_ptr == -1) {
|
||||
speaker_map = parse_here("speakermap");
|
||||
}
|
||||
}
|
||||
15
definitions/cod/soundfile.xscript
Normal file
15
definitions/cod/soundfile.xscript
Normal file
@ -0,0 +1,15 @@
|
||||
type soundfile [display="Sound File"]
|
||||
{
|
||||
u8 exists [ui, readonly, display="Exists"];
|
||||
u8 sound_type [ui, readonly, display="Type"];
|
||||
skip(2); // padding
|
||||
|
||||
// Sound union - either loaded_sound or streamed
|
||||
// For loaded sound:
|
||||
i32 sound_ptr [ui, readonly, display="Sound Ptr"];
|
||||
|
||||
// Parse inline loaded sound
|
||||
if (sound_ptr == -1) {
|
||||
loaded_sound = parse_here("loaded_sound");
|
||||
}
|
||||
}
|
||||
18
definitions/cod/speakermap.xscript
Normal file
18
definitions/cod/speakermap.xscript
Normal file
@ -0,0 +1,18 @@
|
||||
type speakermap [display="Speaker Map"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
u8 is_default [ui, readonly, display="Is Default"];
|
||||
skip(3); // padding
|
||||
i32 channel_maps_ptr [ui, readonly, display="Channel Maps Ptr"];
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// Channel maps (2 entries of SpeakerChannelMap, each 16 bytes)
|
||||
if (channel_maps_ptr == -1) {
|
||||
channel_maps = read(32) [ui, readonly, display="Channel Maps"];
|
||||
}
|
||||
}
|
||||
17
definitions/cod/statement.xscript
Normal file
17
definitions/cod/statement.xscript
Normal file
@ -0,0 +1,17 @@
|
||||
type statement [display="Statement"]
|
||||
{
|
||||
// statement_s - 8 bytes header ONLY
|
||||
// Expression entries are parsed by the parent type (menudef/itemdef)
|
||||
// at the correct position in the zone streaming order
|
||||
//
|
||||
// When entries_ptr == -1 (inline), the parent must parse:
|
||||
// 1. Array of numEntries pointers (4 bytes each)
|
||||
// 2. For each pointer, an expressionEntry (12 bytes)
|
||||
// 3. For string operands with -1 value, inline string
|
||||
|
||||
i32 num_entries [ui, readonly, display="Num Entries"];
|
||||
i32 entries_ptr [ui, readonly, display="Entries Ptr"];
|
||||
|
||||
// Expression entries are NOT parsed here because they follow
|
||||
// other inline data in the parent struct's streaming order
|
||||
}
|
||||
@ -2,34 +2,29 @@ type stringtable_asset [display="String Table"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
i32 column_count [ui, readonly, display="Column Count"];
|
||||
i32 row_count [ui, readonly, display="Row Count"];
|
||||
i32 values_ptr [ui, readonly, display="Values Ptr"];
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
u32 column_count [ui, readonly, display="Column Count"];
|
||||
u32 row_count [ui, readonly, display="Row Count"];
|
||||
i32 values_ptr [ui, readonly, display="Values Ptr"];
|
||||
|
||||
// Parse string table values if inline
|
||||
if (values_ptr == -1 && row_count > 0 && column_count > 0) {
|
||||
cell_count = row_count * column_count [ui, readonly, display="Cell Count"];
|
||||
cell_count = row_count * column_count;
|
||||
|
||||
// Read all cell pointers and values in one pass
|
||||
// First read all cell pointers (each is 4 bytes)
|
||||
_cell_ptrs_size = cell_count * 4;
|
||||
cell_ptrs = read(_cell_ptrs_size) [ui, readonly, display="Cell Pointers"];
|
||||
|
||||
// Then read all cell string values
|
||||
cells = 0;
|
||||
repeat(cell_count) {
|
||||
i32 cell_ptr;
|
||||
// Store cell pointer for reference
|
||||
current_cell_ptr = cell_ptr;
|
||||
}
|
||||
|
||||
// Read all cell values
|
||||
repeat(cell_count) {
|
||||
// For now, assume all cells have inline string data
|
||||
// TODO: Handle cell_ptr properly to skip non-inline cells
|
||||
cell_value = cstring();
|
||||
cells = push("cells", cell_value);
|
||||
}
|
||||
|
||||
cells = cells [ui, table="Cells", columns="value"];
|
||||
_cell_value = cstring();
|
||||
cells = push("cells", _cell_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
47
definitions/cod/sunflare.xscript
Normal file
47
definitions/cod/sunflare.xscript
Normal file
@ -0,0 +1,47 @@
|
||||
type sunflare [display="Sun Flare"]
|
||||
{
|
||||
u8 has_valid_data [ui, readonly, display="Has Valid Data"];
|
||||
skip(3); // padding
|
||||
|
||||
i32 sprite_material_ptr [ui, readonly, display="Sprite Material Ptr"];
|
||||
i32 flare_material_ptr [ui, readonly, display="Flare Material Ptr"];
|
||||
|
||||
// Sprite/flare params (floats)
|
||||
sprite_size = read(4) [ui, readonly, display="Sprite Size"];
|
||||
flare_min_size = read(4) [ui, readonly, display="Flare Min Size"];
|
||||
flare_min_dot = read(4) [ui, readonly, display="Flare Min Dot"];
|
||||
flare_max_size = read(4) [ui, readonly, display="Flare Max Size"];
|
||||
flare_max_dot = read(4) [ui, readonly, display="Flare Max Dot"];
|
||||
flare_max_alpha = read(4) [ui, readonly, display="Flare Max Alpha"];
|
||||
|
||||
i32 flare_fade_in_time [ui, readonly, display="Flare Fade In Time"];
|
||||
i32 flare_fade_out_time [ui, readonly, display="Flare Fade Out Time"];
|
||||
|
||||
// Blind params
|
||||
blind_min_dot = read(4) [ui, readonly, display="Blind Min Dot"];
|
||||
blind_max_dot = read(4) [ui, readonly, display="Blind Max Dot"];
|
||||
blind_max_darken = read(4) [ui, readonly, display="Blind Max Darken"];
|
||||
|
||||
i32 blind_fade_in_time [ui, readonly, display="Blind Fade In Time"];
|
||||
i32 blind_fade_out_time [ui, readonly, display="Blind Fade Out Time"];
|
||||
|
||||
// Glare params
|
||||
glare_min_dot = read(4) [ui, readonly, display="Glare Min Dot"];
|
||||
glare_max_dot = read(4) [ui, readonly, display="Glare Max Dot"];
|
||||
glare_max_lighten = read(4) [ui, readonly, display="Glare Max Lighten"];
|
||||
|
||||
i32 glare_fade_in_time [ui, readonly, display="Glare Fade In Time"];
|
||||
i32 glare_fade_out_time [ui, readonly, display="Glare Fade Out Time"];
|
||||
|
||||
// Sun FX position (3 floats)
|
||||
sun_fx_position = read(12) [ui, readonly, display="Sun FX Position"];
|
||||
|
||||
// Parse materials if inline
|
||||
if (sprite_material_ptr == -1) {
|
||||
sprite_material = parse_here("material");
|
||||
}
|
||||
|
||||
if (flare_material_ptr == -1) {
|
||||
flare_material = parse_here("material");
|
||||
}
|
||||
}
|
||||
21
definitions/cod/sunlightparseparams.xscript
Normal file
21
definitions/cod/sunlightparseparams.xscript
Normal file
@ -0,0 +1,21 @@
|
||||
type sunlightparseparams [display="Sun Light Parse Params"]
|
||||
{
|
||||
// PC version: Fixed 128-byte struct (embedded in GfxWorld header)
|
||||
// Name is a fixed 64-byte char array, NOT a pointer!
|
||||
name = read(64) [ui, readonly, display="Name"];
|
||||
|
||||
// Ambient settings
|
||||
ambient_scale = read(4) [ui, readonly, display="Ambient Scale"];
|
||||
ambient_color = read(12) [ui, readonly, display="Ambient Color"];
|
||||
|
||||
// Diffuse/Sun settings
|
||||
diffuse_fraction = read(4) [ui, readonly, display="Diffuse Fraction"];
|
||||
sun_light = read(4) [ui, readonly, display="Sun Light"];
|
||||
sun_color = read(12) [ui, readonly, display="Sun Color"];
|
||||
diffuse_color = read(12) [ui, readonly, display="Diffuse Color"];
|
||||
|
||||
// Flags and angles
|
||||
u8 diffuse_color_has_been_set [ui, readonly, display="Diffuse Color Has Been Set"];
|
||||
skip(3); // padding
|
||||
angles = read(12) [ui, readonly, display="Angles"];
|
||||
}
|
||||
@ -1,10 +1,121 @@
|
||||
type weapon [display="Weapon"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
// WeaponDef is extremely large in CoD4 (1000+ bytes)
|
||||
// This is a simplified version focusing on the key fields
|
||||
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
i32 display_name_ptr [ui, readonly, display="Display Name Ptr"];
|
||||
i32 ai_overlay_description_ptr [ui, readonly, display="AI Overlay Desc Ptr"];
|
||||
|
||||
// Gun model pointers
|
||||
i32 gun_model_ptr [ui, readonly, display="Gun Model Ptr"];
|
||||
i32 hand_model_ptr [ui, readonly, display="Hand Model Ptr"];
|
||||
|
||||
// Mode name (for alternate fire modes)
|
||||
i32 mode_name_ptr [ui, readonly, display="Mode Name Ptr"];
|
||||
|
||||
// Player anim type
|
||||
i32 player_anim_type [ui, readonly, display="Player Anim Type"];
|
||||
|
||||
// Weapon type and class
|
||||
i32 weapon_type [ui, readonly, display="Weapon Type"];
|
||||
i32 weapon_class [ui, readonly, display="Weapon Class"];
|
||||
i32 penetrate_type [ui, readonly, display="Penetrate Type"];
|
||||
i32 impact_type [ui, readonly, display="Impact Type"];
|
||||
i32 inventory_type [ui, readonly, display="Inventory Type"];
|
||||
i32 fire_type [ui, readonly, display="Fire Type"];
|
||||
|
||||
// Offhand class
|
||||
i32 offhand_class [ui, readonly, display="Offhand Class"];
|
||||
|
||||
// Stance
|
||||
i32 stance [ui, readonly, display="Stance"];
|
||||
|
||||
// View model pointers
|
||||
i32 view_flash_effect_ptr [ui, readonly, display="View Flash Effect Ptr"];
|
||||
i32 world_flash_effect_ptr [ui, readonly, display="World Flash Effect Ptr"];
|
||||
|
||||
// Sounds
|
||||
i32 pickup_sound_ptr [ui, readonly, display="Pickup Sound Ptr"];
|
||||
i32 pickup_sound_player_ptr [ui, readonly, display="Pickup Sound Player Ptr"];
|
||||
i32 ammo_pickup_sound_ptr [ui, readonly, display="Ammo Pickup Sound Ptr"];
|
||||
i32 ammo_pickup_sound_player_ptr [ui, readonly, display="Ammo Pickup Sound Player Ptr"];
|
||||
i32 projectile_sound_ptr [ui, readonly, display="Projectile Sound Ptr"];
|
||||
i32 pullback_sound_ptr [ui, readonly, display="Pullback Sound Ptr"];
|
||||
i32 pullback_sound_player_ptr [ui, readonly, display="Pullback Sound Player Ptr"];
|
||||
i32 fire_sound_ptr [ui, readonly, display="Fire Sound Ptr"];
|
||||
i32 fire_sound_player_ptr [ui, readonly, display="Fire Sound Player Ptr"];
|
||||
i32 fire_loop_sound_ptr [ui, readonly, display="Fire Loop Sound Ptr"];
|
||||
i32 fire_loop_sound_player_ptr [ui, readonly, display="Fire Loop Sound Player Ptr"];
|
||||
i32 fire_stop_sound_ptr [ui, readonly, display="Fire Stop Sound Ptr"];
|
||||
i32 fire_stop_sound_player_ptr [ui, readonly, display="Fire Stop Sound Player Ptr"];
|
||||
i32 fire_last_sound_ptr [ui, readonly, display="Fire Last Sound Ptr"];
|
||||
i32 fire_last_sound_player_ptr [ui, readonly, display="Fire Last Sound Player Ptr"];
|
||||
i32 empty_fire_sound_ptr [ui, readonly, display="Empty Fire Sound Ptr"];
|
||||
i32 empty_fire_sound_player_ptr [ui, readonly, display="Empty Fire Sound Player Ptr"];
|
||||
i32 melee_swipe_sound_ptr [ui, readonly, display="Melee Swipe Sound Ptr"];
|
||||
i32 melee_swipe_sound_player_ptr [ui, readonly, display="Melee Swipe Sound Player Ptr"];
|
||||
i32 melee_hit_sound_ptr [ui, readonly, display="Melee Hit Sound Ptr"];
|
||||
i32 melee_miss_sound_ptr [ui, readonly, display="Melee Miss Sound Ptr"];
|
||||
i32 rechamber_sound_ptr [ui, readonly, display="Rechamber Sound Ptr"];
|
||||
i32 rechamber_sound_player_ptr [ui, readonly, display="Rechamber Sound Player Ptr"];
|
||||
i32 reload_sound_ptr [ui, readonly, display="Reload Sound Ptr"];
|
||||
i32 reload_sound_player_ptr [ui, readonly, display="Reload Sound Player Ptr"];
|
||||
i32 reload_empty_sound_ptr [ui, readonly, display="Reload Empty Sound Ptr"];
|
||||
i32 reload_empty_sound_player_ptr [ui, readonly, display="Reload Empty Sound Player Ptr"];
|
||||
i32 reload_start_sound_ptr [ui, readonly, display="Reload Start Sound Ptr"];
|
||||
i32 reload_start_sound_player_ptr [ui, readonly, display="Reload Start Sound Player Ptr"];
|
||||
i32 reload_end_sound_ptr [ui, readonly, display="Reload End Sound Ptr"];
|
||||
i32 reload_end_sound_player_ptr [ui, readonly, display="Reload End Sound Player Ptr"];
|
||||
i32 deploy_sound_ptr [ui, readonly, display="Deploy Sound Ptr"];
|
||||
i32 deploy_sound_player_ptr [ui, readonly, display="Deploy Sound Player Ptr"];
|
||||
i32 finish_deploy_sound_ptr [ui, readonly, display="Finish Deploy Sound Ptr"];
|
||||
i32 finish_deploy_sound_player_ptr [ui, readonly, display="Finish Deploy Sound Player Ptr"];
|
||||
i32 breakdown_sound_ptr [ui, readonly, display="Breakdown Sound Ptr"];
|
||||
i32 breakdown_sound_player_ptr [ui, readonly, display="Breakdown Sound Player Ptr"];
|
||||
i32 finish_breakdown_sound_ptr [ui, readonly, display="Finish Breakdown Sound Ptr"];
|
||||
i32 finish_breakdown_sound_player_ptr [ui, readonly, display="Finish Breakdown Sound Player Ptr"];
|
||||
i32 detonate_sound_ptr [ui, readonly, display="Detonate Sound Ptr"];
|
||||
i32 detonate_sound_player_ptr [ui, readonly, display="Detonate Sound Player Ptr"];
|
||||
i32 night_vision_wear_sound_ptr [ui, readonly, display="Night Vision Wear Sound Ptr"];
|
||||
i32 night_vision_wear_sound_player_ptr [ui, readonly, display="Night Vision Wear Sound Player Ptr"];
|
||||
i32 night_vision_remove_sound_ptr [ui, readonly, display="Night Vision Remove Sound Ptr"];
|
||||
i32 night_vision_remove_sound_player_ptr [ui, readonly, display="Night Vision Remove Sound Player Ptr"];
|
||||
i32 alt_switch_sound_ptr [ui, readonly, display="Alt Switch Sound Ptr"];
|
||||
i32 alt_switch_sound_player_ptr [ui, readonly, display="Alt Switch Sound Player Ptr"];
|
||||
i32 raise_sound_ptr [ui, readonly, display="Raise Sound Ptr"];
|
||||
i32 raise_sound_player_ptr [ui, readonly, display="Raise Sound Player Ptr"];
|
||||
i32 first_raise_sound_ptr [ui, readonly, display="First Raise Sound Ptr"];
|
||||
i32 first_raise_sound_player_ptr [ui, readonly, display="First Raise Sound Player Ptr"];
|
||||
i32 put_away_sound_ptr [ui, readonly, display="Put Away Sound Ptr"];
|
||||
i32 put_away_sound_player_ptr [ui, readonly, display="Put Away Sound Player Ptr"];
|
||||
|
||||
// Read remaining weapon data as raw bytes
|
||||
// The full structure has many more fields (damage, range, spread, etc.)
|
||||
// This reads enough to cover the core structure (around 800+ more bytes)
|
||||
weapon_data = read(800) [ui, readonly, display="Weapon Data"];
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// TODO: Add full weapon definition structure (stats, animations, effects, etc.)
|
||||
// Parse inline display name
|
||||
if (display_name_ptr == -1) {
|
||||
display_name = cstring() [ui, readonly, display="Display Name"];
|
||||
}
|
||||
|
||||
// Parse inline AI overlay description
|
||||
if (ai_overlay_description_ptr == -1) {
|
||||
ai_overlay_description = cstring() [ui, readonly, display="AI Overlay Description"];
|
||||
}
|
||||
|
||||
// Parse inline mode name
|
||||
if (mode_name_ptr == -1) {
|
||||
mode_name = cstring() [ui, readonly, display="Mode Name"];
|
||||
}
|
||||
|
||||
// Note: Many more inline assets would follow (models, effects, sounds, etc.)
|
||||
// This is a simplified version
|
||||
}
|
||||
|
||||
58
definitions/cod/windowdef.xscript
Normal file
58
definitions/cod/windowdef.xscript
Normal file
@ -0,0 +1,58 @@
|
||||
type windowdef [display="Window Definition"]
|
||||
{
|
||||
// WindowDef structure - 156 bytes total (fixed part only)
|
||||
// Inline data (name, group, background) parsed by menudef after
|
||||
|
||||
// Name pointer (4 bytes)
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
// Primary rect (24 bytes)
|
||||
rect = parse_here("rectdef") [display="Rect"];
|
||||
|
||||
// Client rect (24 bytes)
|
||||
rect_client = parse_here("rectdef") [display="Rect Client"];
|
||||
|
||||
// Group pointer (4 bytes)
|
||||
i32 group_ptr [ui, readonly, display="Group Ptr"];
|
||||
|
||||
// Style properties (16 bytes)
|
||||
i32 style [ui, readonly, display="Style"];
|
||||
i32 border [ui, readonly, display="Border"];
|
||||
i32 owner_draw [ui, readonly, display="Owner Draw"];
|
||||
i32 owner_draw_flags [ui, readonly, display="Owner Draw Flags"];
|
||||
|
||||
// Border size float (4 bytes)
|
||||
f32 border_size [ui, readonly, display="Border Size"];
|
||||
|
||||
// Flags (12 bytes)
|
||||
i32 static_flags [ui, readonly, display="Static Flags"];
|
||||
i32 dynamic_flags [ui, readonly, display="Dynamic Flags"];
|
||||
i32 next_time [ui, readonly, display="Next Time"];
|
||||
|
||||
// Fore color (16 bytes)
|
||||
f32 fore_color_r [ui, readonly, display="Fore R"];
|
||||
f32 fore_color_g [ui, readonly, display="Fore G"];
|
||||
f32 fore_color_b [ui, readonly, display="Fore B"];
|
||||
f32 fore_color_a [ui, readonly, display="Fore A"];
|
||||
|
||||
// Back color (16 bytes)
|
||||
f32 back_color_r [ui, readonly, display="Back R"];
|
||||
f32 back_color_g [ui, readonly, display="Back G"];
|
||||
f32 back_color_b [ui, readonly, display="Back B"];
|
||||
f32 back_color_a [ui, readonly, display="Back A"];
|
||||
|
||||
// Border color (16 bytes)
|
||||
f32 border_color_r [ui, readonly, display="Border R"];
|
||||
f32 border_color_g [ui, readonly, display="Border G"];
|
||||
f32 border_color_b [ui, readonly, display="Border B"];
|
||||
f32 border_color_a [ui, readonly, display="Border A"];
|
||||
|
||||
// Outline color (16 bytes)
|
||||
f32 outline_color_r [ui, readonly, display="Outline R"];
|
||||
f32 outline_color_g [ui, readonly, display="Outline G"];
|
||||
f32 outline_color_b [ui, readonly, display="Outline B"];
|
||||
f32 outline_color_a [ui, readonly, display="Outline A"];
|
||||
|
||||
// Background material pointer (4 bytes)
|
||||
i32 background_ptr [ui, readonly, display="Background Ptr"];
|
||||
}
|
||||
@ -2,11 +2,49 @@ type xmodel [display="XModel"]
|
||||
{
|
||||
i32 name_ptr [ui, readonly, display="Name Ptr"];
|
||||
|
||||
u8 num_bones [ui, readonly, display="Num Bones"];
|
||||
u8 num_root_bones [ui, readonly, display="Num Root Bones"];
|
||||
u8 num_surfaces [ui, readonly, display="Num Surfaces"];
|
||||
i8 lod_ramp_type [ui, readonly, display="LOD Ramp Type"];
|
||||
|
||||
// Model surfaces pointers (4 LODs)
|
||||
i32 model_surfs_ptr_0 [ui, readonly, display="Model Surfs Ptr LOD0"];
|
||||
i32 model_surfs_ptr_1 [ui, readonly, display="Model Surfs Ptr LOD1"];
|
||||
i32 model_surfs_ptr_2 [ui, readonly, display="Model Surfs Ptr LOD2"];
|
||||
i32 model_surfs_ptr_3 [ui, readonly, display="Model Surfs Ptr LOD3"];
|
||||
|
||||
// LOD info (4 floats = 16 bytes)
|
||||
lod_info = read(16) [ui, readonly, display="LOD Info"];
|
||||
|
||||
i32 coll_surfs_ptr [ui, readonly, display="Coll Surfs Ptr"];
|
||||
i32 num_coll_surfs [ui, readonly, display="Num Coll Surfs"];
|
||||
i32 contents [ui, readonly, display="Contents"];
|
||||
|
||||
i32 bone_info_ptr [ui, readonly, display="Bone Info Ptr"];
|
||||
|
||||
// Bounds (6 floats = 24 bytes for mins + maxs)
|
||||
bounds = read(24) [ui, readonly, display="Bounds"];
|
||||
|
||||
// Radius (float)
|
||||
radius = read(4) [ui, readonly, display="Radius"];
|
||||
|
||||
i32 phys_preset_ptr [ui, readonly, display="Phys Preset Ptr"];
|
||||
i32 phys_collmap_ptr [ui, readonly, display="Phys Collmap Ptr"];
|
||||
|
||||
u16 flags [ui, readonly, display="Flags"];
|
||||
skip(2); // padding
|
||||
|
||||
// Parse inline name
|
||||
if (name_ptr == -1) {
|
||||
name = cstring() [ui, readonly, display="Name"];
|
||||
_name = name;
|
||||
}
|
||||
|
||||
// TODO: Add full XModel structure
|
||||
// For now, just read the name as a placeholder
|
||||
// Full structure includes: LODs, surfaces, bones, collision, etc.
|
||||
// Note: Full XModel inline parsing would require:
|
||||
// - XModelSurfs for each LOD
|
||||
// - XBoneInfo array
|
||||
// - Collision surfaces
|
||||
// - Physics preset
|
||||
// - Physics collision map
|
||||
// These are complex nested structures
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user