From 91e9222fcfcd5e10291da5cf770e79a0f5f11484 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 2 Jul 2025 14:40:13 +0300 Subject: [PATCH 01/41] Add Capcom's Devil May Cry 3 HD .mod hexpat Hex Pattern file for Capcom's Devil May Cry 3 HD Collection's .mod (3D Models) files --- patterns/DMC3 HD Mod.hexpat | 160 ++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 patterns/DMC3 HD Mod.hexpat diff --git a/patterns/DMC3 HD Mod.hexpat b/patterns/DMC3 HD Mod.hexpat new file mode 100644 index 00000000..a782d6b3 --- /dev/null +++ b/patterns/DMC3 HD Mod.hexpat @@ -0,0 +1,160 @@ +// author = haru233, many thanks to AxCut +// ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files + +import std.core; + + +struct ModelHeader { + char ID[4]; + float Version; + u8 padding0[8]; + u8 objectCount; + u8 boneCount; + u8 numberTextures; + u8 unknown1; + u32 unknown2; + u64 unknown3; + u64 skeletonOffset; + u8 padding1[24]; +}; + +struct Object { + u8 meshCount; + u8 unknown; + u16 numberVertices; + u8 padding0[4]; + u64 meshOffset; + u32 flags; + u8 padding1[28]; + float X, Y, Z; + float radius; +}; + +struct Positions { + float positions[3]; +}; + + +struct Normals { + float normal[3]; +}; + + +struct UVs { + float uv[2]; +}; + +struct BoneIndices { + u8 boneindex[4]; +}; + +struct Weights { + u16 weight[1]; +}; + +struct MeshSCM { + u16 numberVertices; + u16 textureIndex; + u8 padding0[12]; + u64 VerticesPositionsOffset; + u64 NormalsPositionsOffset; + u64 UVsPositionsOffset; + + u8 padding2[16]; + u64 unknownOffset; + + u64 unknown; + u8 padding3[8]; + + Positions positions[numberVertices] @VerticesPositionsOffset; + Normals normals[numberVertices] @NormalsPositionsOffset; + UVs uvs[numberVertices] @UVsPositionsOffset; + + +}; + +struct Mesh { + u16 numberVertices; + u16 textureIndex; + u8 padding0[12]; + u64 VerticesPositionsOffset; + u64 NormalsPositionsOffset; + u64 UVsPositionsOffset; + + u64 BoneIndicesOffset; + u64 WeightsOffset; + u8 padding1[8]; + + u64 unknown; + u8 padding3[8]; + + Positions positions[numberVertices] @VerticesPositionsOffset; + Normals normals[numberVertices] @NormalsPositionsOffset; + UVs uvs[numberVertices] @UVsPositionsOffset; + + BoneIndices b_index[numberVertices] @BoneIndicesOffset; + Weights weights[numberVertices] @WeightsOffset; + + +}; + + +struct Hierarchy { + u8 hierarchy; +}; + +struct HierarchyOrder { + u8 hierarchyorder; +}; + +struct Unknown { + u8 unknown; +}; + +struct Transform { + float x; + float y; + float z; + float length; // sqrt(x*x + y*y + z*z) +}; + +struct Skeleton{ + u32 hierarchyOffset; + u32 hierarchyOrderOffset; + u32 unknownOffset; + u32 transformsOffset; +}; + + + + + +ModelHeader modelheader @ 0x00; +Object objects[modelheader.objectCount] @ 0x40; + +u32 objectOffset; + +struct IthMesh { + u64 i = std::core::array_index(); + if (modelheader.ID == "SCM ") { + objectOffset = objects[0].meshOffset; + MeshSCM meshscm[objects[i].meshCount] @ objects[i].meshOffset; + + + } else { + objectOffset = objects[0].meshOffset; + Mesh mesh[objects[i].meshCount] @ objects[i].meshOffset; + } +}; + +IthMesh meshes[modelheader.objectCount] @objectOffset; + +Skeleton skeleton @modelheader.skeletonOffset; + +Hierarchy hierarchy[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOffset); + +HierarchyOrder hierarchyorder[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOrderOffset); + +Unknown unknown[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.unknownOffset); + +Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset); From 76b24fc7272d258e37dfed66fedd33ac071528a5 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 2 Jul 2025 17:37:10 +0300 Subject: [PATCH 02/41] Update DMC3 HD Mod.hexpat --- patterns/DMC3 HD Mod.hexpat | 1 + 1 file changed, 1 insertion(+) diff --git a/patterns/DMC3 HD Mod.hexpat b/patterns/DMC3 HD Mod.hexpat index a782d6b3..f5b14b53 100644 --- a/patterns/DMC3 HD Mod.hexpat +++ b/patterns/DMC3 HD Mod.hexpat @@ -1,3 +1,4 @@ +#pragma description Devil May Cry 3 HD .mod 3D model file // author = haru233, many thanks to AxCut // ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files From 7481fe5d7356b1a3175f4b36e116d9b5c752302c Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 2 Jul 2025 17:44:30 +0300 Subject: [PATCH 03/41] Update DMC3 HD Mod.hexpat --- patterns/DMC3 HD Mod.hexpat | 2 ++ 1 file changed, 2 insertions(+) diff --git a/patterns/DMC3 HD Mod.hexpat b/patterns/DMC3 HD Mod.hexpat index f5b14b53..fd103717 100644 --- a/patterns/DMC3 HD Mod.hexpat +++ b/patterns/DMC3 HD Mod.hexpat @@ -1,4 +1,6 @@ #pragma description Devil May Cry 3 HD .mod 3D model file +#pragma MIME 3d-model/capcom.dmc3-hd-mod + // author = haru233, many thanks to AxCut // ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files From 7b08f082d856c4ac51c0c887f44db95c60b00038 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 2 Jul 2025 18:06:35 +0300 Subject: [PATCH 04/41] Update DMC3 HD Mod.hexpat --- patterns/DMC3 HD Mod.hexpat | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/patterns/DMC3 HD Mod.hexpat b/patterns/DMC3 HD Mod.hexpat index fd103717..b08b8dcd 100644 --- a/patterns/DMC3 HD Mod.hexpat +++ b/patterns/DMC3 HD Mod.hexpat @@ -4,6 +4,7 @@ // author = haru233, many thanks to AxCut // ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files + import std.core; @@ -44,7 +45,7 @@ struct Normals { struct UVs { - float uv[2]; + s16 uv[2]; }; struct BoneIndices { @@ -119,6 +120,7 @@ struct Transform { float y; float z; float length; // sqrt(x*x + y*y + z*z) + u8 unknown[16]; }; struct Skeleton{ From e182d178504ad1140bb886152d0b0b8dce70afa2 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 2 Jul 2025 19:47:34 +0300 Subject: [PATCH 05/41] Add files via upload --- .../patterns/test_data/dmc3_hd_mod.hexpat.mod | Bin 0 -> 192784 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/patterns/test_data/dmc3_hd_mod.hexpat.mod diff --git a/tests/patterns/test_data/dmc3_hd_mod.hexpat.mod b/tests/patterns/test_data/dmc3_hd_mod.hexpat.mod new file mode 100644 index 0000000000000000000000000000000000000000..a0a149cd2e98f80c221ff4d4866471cf2ddf82c7 GIT binary patch literal 192784 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%0D4e$$ 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 literal 0 HcmV?d00001 From d2dfe0acc1fbd9437aa2839bf77ff85e08ec0727 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 3 Jul 2025 19:44:26 +0300 Subject: [PATCH 06/41] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 55e004aa..1f352a42 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers | | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | +| MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | ### Scripts From 7e8f6035e198474f0b54a9430f26b785ea52e355 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 3 Jul 2025 19:57:54 +0300 Subject: [PATCH 07/41] Rename DMC3 HD Mod.hexpat to dmc3_hd_mod.hexpat --- patterns/{DMC3 HD Mod.hexpat => dmc3_hd_mod.hexpat} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename patterns/{DMC3 HD Mod.hexpat => dmc3_hd_mod.hexpat} (100%) diff --git a/patterns/DMC3 HD Mod.hexpat b/patterns/dmc3_hd_mod.hexpat similarity index 100% rename from patterns/DMC3 HD Mod.hexpat rename to patterns/dmc3_hd_mod.hexpat From a67765deb455844e0503aaf5328edeeb5a560e3c Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 3 Jul 2025 20:16:32 +0300 Subject: [PATCH 08/41] Delete patterns/dmc3_hd_mod.hexpat --- patterns/dmc3_hd_mod.hexpat | 165 ------------------------------------ 1 file changed, 165 deletions(-) delete mode 100644 patterns/dmc3_hd_mod.hexpat diff --git a/patterns/dmc3_hd_mod.hexpat b/patterns/dmc3_hd_mod.hexpat deleted file mode 100644 index b08b8dcd..00000000 --- a/patterns/dmc3_hd_mod.hexpat +++ /dev/null @@ -1,165 +0,0 @@ -#pragma description Devil May Cry 3 HD .mod 3D model file -#pragma MIME 3d-model/capcom.dmc3-hd-mod - -// author = haru233, many thanks to AxCut -// ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files - - -import std.core; - - -struct ModelHeader { - char ID[4]; - float Version; - u8 padding0[8]; - u8 objectCount; - u8 boneCount; - u8 numberTextures; - u8 unknown1; - u32 unknown2; - u64 unknown3; - u64 skeletonOffset; - u8 padding1[24]; -}; - -struct Object { - u8 meshCount; - u8 unknown; - u16 numberVertices; - u8 padding0[4]; - u64 meshOffset; - u32 flags; - u8 padding1[28]; - float X, Y, Z; - float radius; -}; - -struct Positions { - float positions[3]; -}; - - -struct Normals { - float normal[3]; -}; - - -struct UVs { - s16 uv[2]; -}; - -struct BoneIndices { - u8 boneindex[4]; -}; - -struct Weights { - u16 weight[1]; -}; - -struct MeshSCM { - u16 numberVertices; - u16 textureIndex; - u8 padding0[12]; - u64 VerticesPositionsOffset; - u64 NormalsPositionsOffset; - u64 UVsPositionsOffset; - - u8 padding2[16]; - u64 unknownOffset; - - u64 unknown; - u8 padding3[8]; - - Positions positions[numberVertices] @VerticesPositionsOffset; - Normals normals[numberVertices] @NormalsPositionsOffset; - UVs uvs[numberVertices] @UVsPositionsOffset; - - -}; - -struct Mesh { - u16 numberVertices; - u16 textureIndex; - u8 padding0[12]; - u64 VerticesPositionsOffset; - u64 NormalsPositionsOffset; - u64 UVsPositionsOffset; - - u64 BoneIndicesOffset; - u64 WeightsOffset; - u8 padding1[8]; - - u64 unknown; - u8 padding3[8]; - - Positions positions[numberVertices] @VerticesPositionsOffset; - Normals normals[numberVertices] @NormalsPositionsOffset; - UVs uvs[numberVertices] @UVsPositionsOffset; - - BoneIndices b_index[numberVertices] @BoneIndicesOffset; - Weights weights[numberVertices] @WeightsOffset; - - -}; - - -struct Hierarchy { - u8 hierarchy; -}; - -struct HierarchyOrder { - u8 hierarchyorder; -}; - -struct Unknown { - u8 unknown; -}; - -struct Transform { - float x; - float y; - float z; - float length; // sqrt(x*x + y*y + z*z) - u8 unknown[16]; -}; - -struct Skeleton{ - u32 hierarchyOffset; - u32 hierarchyOrderOffset; - u32 unknownOffset; - u32 transformsOffset; -}; - - - - - -ModelHeader modelheader @ 0x00; -Object objects[modelheader.objectCount] @ 0x40; - -u32 objectOffset; - -struct IthMesh { - u64 i = std::core::array_index(); - if (modelheader.ID == "SCM ") { - objectOffset = objects[0].meshOffset; - MeshSCM meshscm[objects[i].meshCount] @ objects[i].meshOffset; - - - } else { - objectOffset = objects[0].meshOffset; - Mesh mesh[objects[i].meshCount] @ objects[i].meshOffset; - } -}; - -IthMesh meshes[modelheader.objectCount] @objectOffset; - -Skeleton skeleton @modelheader.skeletonOffset; - -Hierarchy hierarchy[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOffset); - -HierarchyOrder hierarchyorder[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOrderOffset); - -Unknown unknown[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.unknownOffset); - -Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset); From 6de6f373ba0dbba6570f8ce8e68052abd060b753 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 3 Jul 2025 20:34:32 +0300 Subject: [PATCH 09/41] Delete tests/patterns/test_data/dmc3_hd_mod.hexpat.mod --- .../patterns/test_data/dmc3_hd_mod.hexpat.mod | Bin 192784 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/patterns/test_data/dmc3_hd_mod.hexpat.mod diff --git a/tests/patterns/test_data/dmc3_hd_mod.hexpat.mod b/tests/patterns/test_data/dmc3_hd_mod.hexpat.mod deleted file mode 100644 index a0a149cd2e98f80c221ff4d4866471cf2ddf82c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 192784 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%0D4e$$ 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 From 646057bf61ff15ea59385320a1f7407fdc6c4e39 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 3 Jul 2025 20:35:06 +0300 Subject: [PATCH 10/41] Add files via upload --- patterns/dmc3_hd_mod.hexpat | 165 ++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 patterns/dmc3_hd_mod.hexpat diff --git a/patterns/dmc3_hd_mod.hexpat b/patterns/dmc3_hd_mod.hexpat new file mode 100644 index 00000000..d691fe9f --- /dev/null +++ b/patterns/dmc3_hd_mod.hexpat @@ -0,0 +1,165 @@ +#pragma description Devil May Cry 3 HD .mod 3D model file +#pragma MIME 3d-model/capcom.dmc3-hd-mod + +// author = haru233, many thanks to AxCut +// ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files + + +import std.core; + + +struct ModelHeader { + char ID[4]; + float Version; + u8 padding0[8]; + u8 objectCount; + u8 boneCount; + u8 numberTextures; + u8 unknown1; + u32 unknown2; + u64 unknown3; + u64 skeletonOffset; + u8 padding1[24]; +}; + +struct Object { + u8 meshCount; + u8 unknown; + u16 numberVertices; + u8 padding0[4]; + u64 meshOffset; + u32 flags; + u8 padding1[28]; + float X, Y, Z; + float radius; +}; + +struct Positions { + float positions[3]; +}; + + +struct Normals { + float normal[3]; +}; + + +struct UVs { + s16 uv[2]; +}; + +struct BoneIndices { + u8 boneindex[4]; +}; + +struct Weights { + u16 weight[1]; +}; + +struct MeshSCM { + u16 numberVertices; + u16 textureIndex; + u8 padding0[12]; + u64 VerticesPositionsOffset; + u64 NormalsPositionsOffset; + u64 UVsPositionsOffset; + + u8 padding2[16]; + u64 unknownOffset; + + u64 unknown; + u8 padding3[8]; + + Positions positions[numberVertices] @VerticesPositionsOffset; + Normals normals[numberVertices] @NormalsPositionsOffset; + UVs uvs[numberVertices] @UVsPositionsOffset; + + +}; + +struct Mesh { + u16 numberVertices; + u16 textureIndex; + u8 padding0[12]; + u64 VerticesPositionsOffset; + u64 NormalsPositionsOffset; + u64 UVsPositionsOffset; + + u64 BoneIndicesOffset; + u64 WeightsOffset; + u8 padding1[8]; + + u64 unknown; + u8 padding3[8]; + + Positions positions[numberVertices] @VerticesPositionsOffset; + Normals normals[numberVertices] @NormalsPositionsOffset; + UVs uvs[numberVertices] @UVsPositionsOffset; + + BoneIndices b_index[numberVertices] @BoneIndicesOffset; + Weights weights[numberVertices] @WeightsOffset; + + +}; + + +struct Hierarchy { + u8 hierarchy; +}; + +struct HierarchyOrder { + u8 hierarchyorder; +}; + +struct Unknown { + u8 unknown; +}; + +struct Transform { + float x; + float y; + float z; + float length; // sqrt(x*x + y*y + z*z) + u8 unknown[16]; +}; + +struct Skeleton{ + u32 hierarchyOffset; + u32 hierarchyOrderOffset; + u32 unknownOffset; + u32 transformsOffset; +}; + + + + + +ModelHeader modelheader @ 0x00; +Object objects[modelheader.objectCount] @ 0x40; + +u32 objectOffset; + +struct IthMesh { + u64 i = std::core::array_index(); + if (modelheader.ID == "SCM ") { + objectOffset = objects[0].meshOffset; + MeshSCM meshscm[objects[i].meshCount] @ objects[i].meshOffset; + + + } else { + objectOffset = objects[0].meshOffset; + Mesh mesh[objects[i].meshCount] @ objects[i].meshOffset; + } +}; + +IthMesh meshes[modelheader.objectCount] @objectOffset; + +Skeleton skeleton @modelheader.skeletonOffset; + +Hierarchy hierarchy[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOffset); + +HierarchyOrder hierarchyorder[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOrderOffset); + +Unknown unknown[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.unknownOffset); + +Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset); \ No newline at end of file From 34341ebc5f4b7b9f8b4692be57165467006faeff Mon Sep 17 00:00:00 2001 From: haruse23 Date: Tue, 8 Jul 2025 08:45:42 +0300 Subject: [PATCH 11/41] Update dmc3_hd_mod.hexpat --- patterns/dmc3_hd_mod.hexpat | 54 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/patterns/dmc3_hd_mod.hexpat b/patterns/dmc3_hd_mod.hexpat index d691fe9f..9872b781 100644 --- a/patterns/dmc3_hd_mod.hexpat +++ b/patterns/dmc3_hd_mod.hexpat @@ -11,25 +11,25 @@ import std.core; struct ModelHeader { char ID[4]; float Version; - u8 padding0[8]; + padding[8]; u8 objectCount; u8 boneCount; u8 numberTextures; - u8 unknown1; - u32 unknown2; - u64 unknown3; + u8; + u32; + u64; u64 skeletonOffset; - u8 padding1[24]; + padding[24]; }; -struct Object { +struct ObjectInfo { u8 meshCount; - u8 unknown; + u8; u16 numberVertices; - u8 padding0[4]; + padding[4]; u64 meshOffset; u32 flags; - u8 padding1[28]; + padding[28]; float X, Y, Z; float radius; }; @@ -59,16 +59,16 @@ struct Weights { struct MeshSCM { u16 numberVertices; u16 textureIndex; - u8 padding0[12]; + padding[12]; u64 VerticesPositionsOffset; u64 NormalsPositionsOffset; u64 UVsPositionsOffset; - u8 padding2[16]; + padding[16]; u64 unknownOffset; - u64 unknown; - u8 padding3[8]; + u64; + padding[8]; Positions positions[numberVertices] @VerticesPositionsOffset; Normals normals[numberVertices] @NormalsPositionsOffset; @@ -80,17 +80,17 @@ struct MeshSCM { struct Mesh { u16 numberVertices; u16 textureIndex; - u8 padding0[12]; + padding[12]; u64 VerticesPositionsOffset; u64 NormalsPositionsOffset; u64 UVsPositionsOffset; u64 BoneIndicesOffset; u64 WeightsOffset; - u8 padding1[8]; + padding[8]; - u64 unknown; - u8 padding3[8]; + u64; + padding[8]; Positions positions[numberVertices] @VerticesPositionsOffset; Normals normals[numberVertices] @NormalsPositionsOffset; @@ -112,7 +112,7 @@ struct HierarchyOrder { }; struct Unknown { - u8 unknown; + u8; }; struct Transform { @@ -120,7 +120,7 @@ struct Transform { float y; float z; float length; // sqrt(x*x + y*y + z*z) - u8 unknown[16]; + padding[16]; }; struct Skeleton{ @@ -135,24 +135,24 @@ struct Skeleton{ ModelHeader modelheader @ 0x00; -Object objects[modelheader.objectCount] @ 0x40; +ObjectInfo objects_info[modelheader.objectCount] @ 0x40; u32 objectOffset; -struct IthMesh { +struct Object { u64 i = std::core::array_index(); if (modelheader.ID == "SCM ") { - objectOffset = objects[0].meshOffset; - MeshSCM meshscm[objects[i].meshCount] @ objects[i].meshOffset; + objectOffset = objects_info[0].meshOffset; + MeshSCM meshscm[objects_info[i].meshCount] @ objects_info[i].meshOffset; } else { - objectOffset = objects[0].meshOffset; - Mesh mesh[objects[i].meshCount] @ objects[i].meshOffset; + objectOffset = objects_info[0].meshOffset; + Mesh mesh[objects_info[i].meshCount] @ objects_info[i].meshOffset; } }; -IthMesh meshes[modelheader.objectCount] @objectOffset; +Object objects[modelheader.objectCount] @objectOffset; Skeleton skeleton @modelheader.skeletonOffset; @@ -162,4 +162,4 @@ HierarchyOrder hierarchyorder[modelheader.boneCount] @(modelheader.skeletonOffse Unknown unknown[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.unknownOffset); -Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset); \ No newline at end of file +Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset); From ff737c3665cdf793e50ffc19fc200f9e4c01c2bf Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:11:29 +0300 Subject: [PATCH 12/41] Add files via upload --- patterns/ACU_DATA_Compressed.hexpat | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 patterns/ACU_DATA_Compressed.hexpat diff --git a/patterns/ACU_DATA_Compressed.hexpat b/patterns/ACU_DATA_Compressed.hexpat new file mode 100644 index 00000000..edc54d93 --- /dev/null +++ b/patterns/ACU_DATA_Compressed.hexpat @@ -0,0 +1,45 @@ +#pragma description Assassin's Creed: Unity's Compressed .data file +#pragma MIME compressed/data + +// author = haru233, many thanks to AxCut +// ImHex Hex Pattern File for Assassin's Creed: Unity's Compressed .data files + + +import std.core; +import std.mem; + +struct CHUNK { + u16 Uncompressed_Size; + u16 Compressed_Size; +}; + +struct CHUNK_Data { + u32 Hash; + + u64 i = std::core::array_index(); + u8 data[parent.chunk[i].Compressed_Size]; +}; + +struct PACK { + u64 ID; + padding[2]; + u8 Compression_Type; + padding[3]; + u8 Version; + u16 CHUNK_Count; + + CHUNK chunk[CHUNK_Count]; + CHUNK_Data data[CHUNK_Count]; + + +}; + +enum CompressionType : u8 { + LZO1X = 0x01, + LZO2A = 0x02, + xmemdecompress = 0x03, + LZO1C = 0x05 +}; + + +PACK pack[while(!std::mem::eof())] @0x00; \ No newline at end of file From baf773f569febc96953c6c36b530479e80f2724b Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:13:26 +0300 Subject: [PATCH 13/41] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1f352a42..cef990fd 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | +| DATA | `compressed/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (contained inside .forge archives) used in Assassin's Creed: Unity | ### Scripts From bee880299678761e5ff0992030824173566e15ef Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:14:09 +0300 Subject: [PATCH 14/41] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cef990fd..e0d78385 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | -| DATA | `compressed/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (contained inside .forge archives) used in Assassin's Creed: Unity | +| DATA | `compressed/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | ### Scripts From 691c10cc62608ae006bf992938ce4fc08621cd41 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:18:40 +0300 Subject: [PATCH 15/41] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e0d78385..c60b3d85 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | -| DATA | `compressed/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | +| DATA | `archives/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | +| FORGE | `archives/forge` | [`patterns/ACU_FORGE.hexpat`](patterns/ACU_FORGE.hexpat) | .forge archive files used in Assassin's Creed: Unity | ### Scripts From a5d43094cb4e8bd6d31a37ea136c2d7262239421 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:21:09 +0300 Subject: [PATCH 16/41] Add files via upload --- patterns/ACU_FORGE.hexpat | 64 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 patterns/ACU_FORGE.hexpat diff --git a/patterns/ACU_FORGE.hexpat b/patterns/ACU_FORGE.hexpat new file mode 100644 index 00000000..e98cc8ea --- /dev/null +++ b/patterns/ACU_FORGE.hexpat @@ -0,0 +1,64 @@ +#pragma description Assassin's Creed: Unity's .forge archive file +#pragma MIME archives/forge + +// author = haru233, many thanks to AxCut +// ImHex Hex Pattern File for Assassin's Creed: Unity's Compressed .data files + +import std.core; + +struct Forge_Header { + char MAGIC[8]; + padding[1]; + u32 Version; + u32 File_Data_Header_Offset; +}; + +struct File_Data_Header { + u32 File_Count; + padding[32]; + u64 File_Data_Header2_Offset; +}; + +struct File_Data_Header2 { + u32 File_Count2; + padding[4]; + u64 File_Table_Offset; + padding[12]; + u32 File_Count3; + u64 File_Name_Table_Offset; + padding[8]; +}; + + +struct File_Table { + u64 Raw_Data_Offset; + u64 File_ID; + u32 Raw_Data_Size; +}; + +struct File_Name_Table { + u32 Raw_Data_Size; + padding[40]; + char Filename[128]; + padding[20]; +}; + + +Forge_Header forge_header @0x00; + +File_Data_Header file_data_header @(forge_header.File_Data_Header_Offset); + +File_Data_Header2 file_data_header2 @(file_data_header.File_Data_Header2_Offset); + +File_Table file_table[file_data_header.File_Count] @(file_data_header2.File_Table_Offset); + +File_Name_Table file_name_table[file_data_header.File_Count] @(file_data_header2.File_Name_Table_Offset); + + +struct Raw_Data_Table { + u64 i = std::core::array_index(); + u8 Raw_Data[file_table[i].Raw_Data_Size] @ file_table[i].Raw_Data_Offset; +}; + + +Raw_Data_Table raw_data_table[file_data_header.File_Count] @0x00; \ No newline at end of file From cba726fdb542474b7c1201e8816997303007a28d Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:22:10 +0300 Subject: [PATCH 17/41] Update ACU_FORGE.hexpat --- patterns/ACU_FORGE.hexpat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patterns/ACU_FORGE.hexpat b/patterns/ACU_FORGE.hexpat index e98cc8ea..519dc9e8 100644 --- a/patterns/ACU_FORGE.hexpat +++ b/patterns/ACU_FORGE.hexpat @@ -2,7 +2,7 @@ #pragma MIME archives/forge // author = haru233, many thanks to AxCut -// ImHex Hex Pattern File for Assassin's Creed: Unity's Compressed .data files +// ImHex Hex Pattern File for Assassin's Creed: Unity's .forge files import std.core; @@ -61,4 +61,4 @@ struct Raw_Data_Table { }; -Raw_Data_Table raw_data_table[file_data_header.File_Count] @0x00; \ No newline at end of file +Raw_Data_Table raw_data_table[file_data_header.File_Count] @0x00; From 4279de2b8f81b6e9f6a0cba729aef1575c899713 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:23:08 +0300 Subject: [PATCH 18/41] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c60b3d85..2bf7b86f 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | -| DATA | `archives/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | +| DATA | `archives/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/ACU_DATA_Compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | | FORGE | `archives/forge` | [`patterns/ACU_FORGE.hexpat`](patterns/ACU_FORGE.hexpat) | .forge archive files used in Assassin's Creed: Unity | ### Scripts From df54d67756a3e0e5ce2fe7ecf9681de2437a9411 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:26:00 +0300 Subject: [PATCH 19/41] Update and rename ACU_DATA_Compressed.hexpat to acu_data_compressed.hexpat --- .../{ACU_DATA_Compressed.hexpat => acu_data_compressed.hexpat} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename patterns/{ACU_DATA_Compressed.hexpat => acu_data_compressed.hexpat} (89%) diff --git a/patterns/ACU_DATA_Compressed.hexpat b/patterns/acu_data_compressed.hexpat similarity index 89% rename from patterns/ACU_DATA_Compressed.hexpat rename to patterns/acu_data_compressed.hexpat index edc54d93..8e27bee2 100644 --- a/patterns/ACU_DATA_Compressed.hexpat +++ b/patterns/acu_data_compressed.hexpat @@ -42,4 +42,5 @@ enum CompressionType : u8 { }; -PACK pack[while(!std::mem::eof())] @0x00; \ No newline at end of file + +PACK pack[while(!std::mem::eof())] @0x00; From dd23dfaf2cd226c4ef8ba27ac1516efd07305b19 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:26:13 +0300 Subject: [PATCH 20/41] Update and rename ACU_FORGE.hexpat to acu_forge.hexpat --- patterns/{ACU_FORGE.hexpat => acu_forge.hexpat} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename patterns/{ACU_FORGE.hexpat => acu_forge.hexpat} (100%) diff --git a/patterns/ACU_FORGE.hexpat b/patterns/acu_forge.hexpat similarity index 100% rename from patterns/ACU_FORGE.hexpat rename to patterns/acu_forge.hexpat From 400a06b94a83d7a8788cd6cf66547da88f883852 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 02:26:59 +0300 Subject: [PATCH 21/41] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2bf7b86f..f5263337 100644 --- a/README.md +++ b/README.md @@ -198,8 +198,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | -| DATA | `archives/data` | [`patterns/ACU_DATA_Compressed.hexpat`](patterns/ACU_DATA_Compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | -| FORGE | `archives/forge` | [`patterns/ACU_FORGE.hexpat`](patterns/ACU_FORGE.hexpat) | .forge archive files used in Assassin's Creed: Unity | +| DATA | `archives/data` | [`patterns/acu_data_compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | +| FORGE | `archives/forge` | [`patterns/acu_forge.hexpat`](patterns/acu_forge.hexpat) | .forge archive files used in Assassin's Creed: Unity | ### Scripts From 7e0ab43e4fdbba37b91f3ad63c3797ae73fe2ac4 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Wed, 17 Sep 2025 03:21:28 +0300 Subject: [PATCH 22/41] Update acu_data_compressed.hexpat --- patterns/acu_data_compressed.hexpat | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/patterns/acu_data_compressed.hexpat b/patterns/acu_data_compressed.hexpat index 8e27bee2..48808833 100644 --- a/patterns/acu_data_compressed.hexpat +++ b/patterns/acu_data_compressed.hexpat @@ -8,6 +8,14 @@ import std.core; import std.mem; +enum CompressionType : u8 { + LZO1X_ = 0x00, // Both 0x00 and 0x01 mean LZO1X + LZO1X = 0x01, + LZO2A = 0x02, + xmemdecompress = 0x03, + LZO1C = 0x05 +}; + struct CHUNK { u16 Uncompressed_Size; u16 Compressed_Size; @@ -23,7 +31,7 @@ struct CHUNK_Data { struct PACK { u64 ID; padding[2]; - u8 Compression_Type; + CompressionType Compression_Type; padding[3]; u8 Version; u16 CHUNK_Count; @@ -34,13 +42,6 @@ struct PACK { }; -enum CompressionType : u8 { - LZO1X = 0x01, - LZO2A = 0x02, - xmemdecompress = 0x03, - LZO1C = 0x05 -}; - PACK pack[while(!std::mem::eof())] @0x00; From caf13272d7983ba813bf1c7f1f632b421d312a8c Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 18 Sep 2025 13:30:40 +0300 Subject: [PATCH 23/41] Update acu_data_compressed.hexpat --- patterns/acu_data_compressed.hexpat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/patterns/acu_data_compressed.hexpat b/patterns/acu_data_compressed.hexpat index 48808833..8d4bb53d 100644 --- a/patterns/acu_data_compressed.hexpat +++ b/patterns/acu_data_compressed.hexpat @@ -1,5 +1,5 @@ #pragma description Assassin's Creed: Unity's Compressed .data file -#pragma MIME compressed/data +#pragma MIME archives/data // author = haru233, many thanks to AxCut // ImHex Hex Pattern File for Assassin's Creed: Unity's Compressed .data files @@ -45,3 +45,4 @@ struct PACK { PACK pack[while(!std::mem::eof())] @0x00; + From 556f81342e27cb6c5582534df0df9d4437f79b26 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 18 Sep 2025 23:55:06 +0300 Subject: [PATCH 24/41] Add files via upload --- patterns/ACU_DATA_Decompressed.hexpat | 93 +++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 patterns/ACU_DATA_Decompressed.hexpat diff --git a/patterns/ACU_DATA_Decompressed.hexpat b/patterns/ACU_DATA_Decompressed.hexpat new file mode 100644 index 00000000..c0ac8704 --- /dev/null +++ b/patterns/ACU_DATA_Decompressed.hexpat @@ -0,0 +1,93 @@ +#pragma description Assassin's Creed: Unity's Decompressed .data file +#pragma MIME archives/acu_data_decompressed + +// Thanks to yretenai on GitHub for helping with the Block Allocator part + +import std.core; +import std.mem; + +struct Block_Allocator_Type0 { + padding[4]; + u32 Class_ID; + u32 Size; +}; + +struct Block_Allocator_Type1 { + padding[4]; + u32 Type_ID; + u32 Size; +}; + +struct Block_Allocator { + u16 Version; + + if (Version == 0) { + u32 Block_Allocator_Number; + Block_Allocator_Type0 block_allocator_type0[Block_Allocator_Number]; + } + + else if (Version == 1) { + u32 Block_Allocator_Number; + Block_Allocator_Type1 block_allocator_type1_[Block_Allocator_Number]; + } + + else if (Version == 2) { + bool Has_Secondary_Block_Allocator; + u32 Main_Block_Allocator_Number; + + Block_Allocator_Type1 block_allocator_type1__[Main_Block_Allocator_Number]; + + if (Has_Secondary_Block_Allocator) { + u32 Secondary_Block_Allocator_Number; + Block_Allocator_Type1 block_allocator_type1___[Secondary_Block_Allocator_Number+1]; + } + } + + +}; + +struct File { + u32 Object_Hash; + u32 File_Size; + u32 Filename_Length; + + if (File_Size > 0) { + if (Filename_Length == 0) { + bool HasBlockAllocator; + + if (HasBlockAllocator) { + Block_Allocator block_allocator; + u8 File_Data[File_Size]; + } + + else + u8 File_Data[File_Size]; + } + + else { + char Filename[Filename_Length]; + + bool HasBlockAllocator; + + if (HasBlockAllocator) { + Block_Allocator block_allocator; + u8 File_Data[File_Size]; + } + + else + u8 File_Data[File_Size]; + + + } + + } + + else + continue; + + + +}; + + +File file[while(!std::mem::eof())] @0x00; \ No newline at end of file From f5aeb83ba0e6284b648ecab148e80a0b42c0e259 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 18 Sep 2025 23:55:28 +0300 Subject: [PATCH 25/41] Update and rename ACU_DATA_Decompressed.hexpat to acu_data_decompressed.hexpat --- ...CU_DATA_Decompressed.hexpat => acu_data_decompressed.hexpat} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename patterns/{ACU_DATA_Decompressed.hexpat => acu_data_decompressed.hexpat} (93%) diff --git a/patterns/ACU_DATA_Decompressed.hexpat b/patterns/acu_data_decompressed.hexpat similarity index 93% rename from patterns/ACU_DATA_Decompressed.hexpat rename to patterns/acu_data_decompressed.hexpat index c0ac8704..db930534 100644 --- a/patterns/ACU_DATA_Decompressed.hexpat +++ b/patterns/acu_data_decompressed.hexpat @@ -90,4 +90,4 @@ struct File { }; -File file[while(!std::mem::eof())] @0x00; \ No newline at end of file +File file[while(!std::mem::eof())] @0x00; From 32b762b70e704f3771df27bdeaa062baff7ddb1d Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 18 Sep 2025 23:57:27 +0300 Subject: [PATCH 26/41] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f5263337..81e1b4bc 100644 --- a/README.md +++ b/README.md @@ -198,8 +198,11 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | -| DATA | `archives/data` | [`patterns/acu_data_compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | | FORGE | `archives/forge` | [`patterns/acu_forge.hexpat`](patterns/acu_forge.hexpat) | .forge archive files used in Assassin's Creed: Unity | +| DATA | `archives/acu_data_compressed` | [`patterns/acu_data_compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | +| DATA | `archives/acu_data_decompressed` | [`patterns/acu_data_decompressed.hexpat`](patterns/acu_data_decompressed.hexpat) | Decompressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | + + ### Scripts From 7cb7460ca0e2b4e7926e6ba91dc8c8078b6e9774 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 18 Sep 2025 23:58:02 +0300 Subject: [PATCH 27/41] Update acu_data_compressed.hexpat --- patterns/acu_data_compressed.hexpat | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/patterns/acu_data_compressed.hexpat b/patterns/acu_data_compressed.hexpat index 8d4bb53d..bd31c28b 100644 --- a/patterns/acu_data_compressed.hexpat +++ b/patterns/acu_data_compressed.hexpat @@ -1,5 +1,5 @@ #pragma description Assassin's Creed: Unity's Compressed .data file -#pragma MIME archives/data +#pragma MIME archives/acu_data_compressed // author = haru233, many thanks to AxCut // ImHex Hex Pattern File for Assassin's Creed: Unity's Compressed .data files @@ -46,3 +46,4 @@ struct PACK { PACK pack[while(!std::mem::eof())] @0x00; + From db46129cf51eed85614136c529fb463bd702cec5 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Thu, 18 Sep 2025 23:58:59 +0300 Subject: [PATCH 28/41] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 81e1b4bc..b4d86526 100644 --- a/README.md +++ b/README.md @@ -199,8 +199,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | | FORGE | `archives/forge` | [`patterns/acu_forge.hexpat`](patterns/acu_forge.hexpat) | .forge archive files used in Assassin's Creed: Unity | -| DATA | `archives/acu_data_compressed` | [`patterns/acu_data_compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | -| DATA | `archives/acu_data_decompressed` | [`patterns/acu_data_decompressed.hexpat`](patterns/acu_data_decompressed.hexpat) | Decompressed .data archive files (found inside .forge archives) used in Assassin's Creed: Unity | +| DATA | `archives/acu_data_compressed` | [`patterns/acu_data_compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files used in Assassin's Creed: Unity | +| DATA | `archives/acu_data_decompressed` | [`patterns/acu_data_decompressed.hexpat`](patterns/acu_data_decompressed.hexpat) | Decompressed .data archive files used in Assassin's Creed: Unity | From 7eabc06f4381d8b18e6e3b86bc6adb9ac90cd0b2 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:25:51 +0300 Subject: [PATCH 29/41] Delete patterns/acu_data_compressed.hexpat --- patterns/acu_data_compressed.hexpat | 49 ----------------------------- 1 file changed, 49 deletions(-) delete mode 100644 patterns/acu_data_compressed.hexpat diff --git a/patterns/acu_data_compressed.hexpat b/patterns/acu_data_compressed.hexpat deleted file mode 100644 index bd31c28b..00000000 --- a/patterns/acu_data_compressed.hexpat +++ /dev/null @@ -1,49 +0,0 @@ -#pragma description Assassin's Creed: Unity's Compressed .data file -#pragma MIME archives/acu_data_compressed - -// author = haru233, many thanks to AxCut -// ImHex Hex Pattern File for Assassin's Creed: Unity's Compressed .data files - - -import std.core; -import std.mem; - -enum CompressionType : u8 { - LZO1X_ = 0x00, // Both 0x00 and 0x01 mean LZO1X - LZO1X = 0x01, - LZO2A = 0x02, - xmemdecompress = 0x03, - LZO1C = 0x05 -}; - -struct CHUNK { - u16 Uncompressed_Size; - u16 Compressed_Size; -}; - -struct CHUNK_Data { - u32 Hash; - - u64 i = std::core::array_index(); - u8 data[parent.chunk[i].Compressed_Size]; -}; - -struct PACK { - u64 ID; - padding[2]; - CompressionType Compression_Type; - padding[3]; - u8 Version; - u16 CHUNK_Count; - - CHUNK chunk[CHUNK_Count]; - CHUNK_Data data[CHUNK_Count]; - - -}; - - - -PACK pack[while(!std::mem::eof())] @0x00; - - From ac54dccf7454e7165270cdf106b68fa6c5c8a9d4 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:26:10 +0300 Subject: [PATCH 30/41] Delete patterns/acu_data_decompressed.hexpat --- patterns/acu_data_decompressed.hexpat | 93 --------------------------- 1 file changed, 93 deletions(-) delete mode 100644 patterns/acu_data_decompressed.hexpat diff --git a/patterns/acu_data_decompressed.hexpat b/patterns/acu_data_decompressed.hexpat deleted file mode 100644 index db930534..00000000 --- a/patterns/acu_data_decompressed.hexpat +++ /dev/null @@ -1,93 +0,0 @@ -#pragma description Assassin's Creed: Unity's Decompressed .data file -#pragma MIME archives/acu_data_decompressed - -// Thanks to yretenai on GitHub for helping with the Block Allocator part - -import std.core; -import std.mem; - -struct Block_Allocator_Type0 { - padding[4]; - u32 Class_ID; - u32 Size; -}; - -struct Block_Allocator_Type1 { - padding[4]; - u32 Type_ID; - u32 Size; -}; - -struct Block_Allocator { - u16 Version; - - if (Version == 0) { - u32 Block_Allocator_Number; - Block_Allocator_Type0 block_allocator_type0[Block_Allocator_Number]; - } - - else if (Version == 1) { - u32 Block_Allocator_Number; - Block_Allocator_Type1 block_allocator_type1_[Block_Allocator_Number]; - } - - else if (Version == 2) { - bool Has_Secondary_Block_Allocator; - u32 Main_Block_Allocator_Number; - - Block_Allocator_Type1 block_allocator_type1__[Main_Block_Allocator_Number]; - - if (Has_Secondary_Block_Allocator) { - u32 Secondary_Block_Allocator_Number; - Block_Allocator_Type1 block_allocator_type1___[Secondary_Block_Allocator_Number+1]; - } - } - - -}; - -struct File { - u32 Object_Hash; - u32 File_Size; - u32 Filename_Length; - - if (File_Size > 0) { - if (Filename_Length == 0) { - bool HasBlockAllocator; - - if (HasBlockAllocator) { - Block_Allocator block_allocator; - u8 File_Data[File_Size]; - } - - else - u8 File_Data[File_Size]; - } - - else { - char Filename[Filename_Length]; - - bool HasBlockAllocator; - - if (HasBlockAllocator) { - Block_Allocator block_allocator; - u8 File_Data[File_Size]; - } - - else - u8 File_Data[File_Size]; - - - } - - } - - else - continue; - - - -}; - - -File file[while(!std::mem::eof())] @0x00; From 2f586be9a7b29953f876723bcecff1223cc6c639 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:26:24 +0300 Subject: [PATCH 31/41] Delete patterns/acu_forge.hexpat --- patterns/acu_forge.hexpat | 64 --------------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 patterns/acu_forge.hexpat diff --git a/patterns/acu_forge.hexpat b/patterns/acu_forge.hexpat deleted file mode 100644 index 519dc9e8..00000000 --- a/patterns/acu_forge.hexpat +++ /dev/null @@ -1,64 +0,0 @@ -#pragma description Assassin's Creed: Unity's .forge archive file -#pragma MIME archives/forge - -// author = haru233, many thanks to AxCut -// ImHex Hex Pattern File for Assassin's Creed: Unity's .forge files - -import std.core; - -struct Forge_Header { - char MAGIC[8]; - padding[1]; - u32 Version; - u32 File_Data_Header_Offset; -}; - -struct File_Data_Header { - u32 File_Count; - padding[32]; - u64 File_Data_Header2_Offset; -}; - -struct File_Data_Header2 { - u32 File_Count2; - padding[4]; - u64 File_Table_Offset; - padding[12]; - u32 File_Count3; - u64 File_Name_Table_Offset; - padding[8]; -}; - - -struct File_Table { - u64 Raw_Data_Offset; - u64 File_ID; - u32 Raw_Data_Size; -}; - -struct File_Name_Table { - u32 Raw_Data_Size; - padding[40]; - char Filename[128]; - padding[20]; -}; - - -Forge_Header forge_header @0x00; - -File_Data_Header file_data_header @(forge_header.File_Data_Header_Offset); - -File_Data_Header2 file_data_header2 @(file_data_header.File_Data_Header2_Offset); - -File_Table file_table[file_data_header.File_Count] @(file_data_header2.File_Table_Offset); - -File_Name_Table file_name_table[file_data_header.File_Count] @(file_data_header2.File_Name_Table_Offset); - - -struct Raw_Data_Table { - u64 i = std::core::array_index(); - u8 Raw_Data[file_table[i].Raw_Data_Size] @ file_table[i].Raw_Data_Offset; -}; - - -Raw_Data_Table raw_data_table[file_data_header.File_Count] @0x00; From f2cbf61772b7aa487e976423cf632a21ab4ffbb9 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:27:10 +0300 Subject: [PATCH 32/41] Create acu_forge.hexpat --- .../Assassin's Creed: Unity/acu_forge.hexpat | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 patterns/Assassin's Creed: Unity/acu_forge.hexpat diff --git a/patterns/Assassin's Creed: Unity/acu_forge.hexpat b/patterns/Assassin's Creed: Unity/acu_forge.hexpat new file mode 100644 index 00000000..e000a492 --- /dev/null +++ b/patterns/Assassin's Creed: Unity/acu_forge.hexpat @@ -0,0 +1,64 @@ +#pragma description Assassin's Creed: Unity's .forge archive file +#pragma author haru233 + +// many thanks to AxCut +// ImHex Hex Pattern File for Assassin's Creed: Unity's .forge files + +import std.core; + +struct Forge_Header { + char MAGIC[8]; + padding[1]; + u32 Version; + u32 File_Data_Header_Offset; +}; + +struct File_Data_Header { + u32 File_Count; + padding[32]; + u64 File_Data_Header2_Offset; +}; + +struct File_Data_Header2 { + u32 File_Count2; + padding[4]; + u64 File_Table_Offset; + padding[12]; + u32 File_Count3; + u64 File_Name_Table_Offset; + padding[8]; +}; + + +struct File_Table { + u64 Raw_Data_Offset; + u64 File_ID; + u32 Raw_Data_Size; +}; + +struct File_Name_Table { + u32 Raw_Data_Size; + padding[40]; + char Filename[128]; + padding[20]; +}; + + +Forge_Header forge_header @0x00; + +File_Data_Header file_data_header @(forge_header.File_Data_Header_Offset); + +File_Data_Header2 file_data_header2 @(file_data_header.File_Data_Header2_Offset); + +File_Table file_table[file_data_header.File_Count] @(file_data_header2.File_Table_Offset); + +File_Name_Table file_name_table[file_data_header.File_Count] @(file_data_header2.File_Name_Table_Offset); + + +struct Raw_Data_Table { + u64 i = std::core::array_index(); + u8 Raw_Data[file_table[i].Raw_Data_Size] @ file_table[i].Raw_Data_Offset; +}; + + +Raw_Data_Table raw_data_table[file_data_header.File_Count] @0x00; From 0ae3f28c62bc79e77583c4053f8db6ced6d26300 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:27:33 +0300 Subject: [PATCH 33/41] Add files via upload --- .../ACU_DATA_Compressed.hexpat | 47 ++++++++++ .../ACU_DATA_Decompressed.hexpat | 93 +++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 patterns/Assassin's Creed: Unity/ACU_DATA_Compressed.hexpat create mode 100644 patterns/Assassin's Creed: Unity/ACU_DATA_Decompressed.hexpat diff --git a/patterns/Assassin's Creed: Unity/ACU_DATA_Compressed.hexpat b/patterns/Assassin's Creed: Unity/ACU_DATA_Compressed.hexpat new file mode 100644 index 00000000..54f4ee4d --- /dev/null +++ b/patterns/Assassin's Creed: Unity/ACU_DATA_Compressed.hexpat @@ -0,0 +1,47 @@ +#pragma description Assassin's Creed: Unity's Compressed .data file +#pragma author haru233 + +// many thanks to AxCut +// ImHex Hex Pattern File for Assassin's Creed: Unity's Compressed .data files + + +import std.core; +import std.mem; + +enum CompressionType : u8 { + LZO1X_ = 0x00, // Both 0x00 and 0x01 mean LZO1X + LZO1X = 0x01, + LZO2A = 0x02, + xmemdecompress = 0x03, + LZO1C = 0x05 +}; + +struct CHUNK { + u16 Uncompressed_Size; + u16 Compressed_Size; +}; + +struct CHUNK_Data { + u32 Hash; + + u64 i = std::core::array_index(); + u8 data[parent.chunk[i].Compressed_Size]; +}; + +struct PACK { + u64 ID; + padding[2]; + CompressionType Compression_Type; + padding[3]; + u8 Version; + u16 CHUNK_Count; + + CHUNK chunk[CHUNK_Count]; + CHUNK_Data data[CHUNK_Count]; + + +}; + + + +PACK pack[while(!std::mem::eof())] @0x00; \ No newline at end of file diff --git a/patterns/Assassin's Creed: Unity/ACU_DATA_Decompressed.hexpat b/patterns/Assassin's Creed: Unity/ACU_DATA_Decompressed.hexpat new file mode 100644 index 00000000..47373733 --- /dev/null +++ b/patterns/Assassin's Creed: Unity/ACU_DATA_Decompressed.hexpat @@ -0,0 +1,93 @@ +#pragma description Assassin's Creed: Unity's Decompressed .data file +#pragma author haru233 + +// Thanks to yretenai on GitHub for helping with the Block Allocator part + +import std.core; +import std.mem; + +struct Block_Allocator_Type0 { + padding[4]; + u32 Class_ID; + u32 Size; +}; + +struct Block_Allocator_Type1 { + padding[4]; + u32 Type_ID; + u32 Size; +}; + +struct Block_Allocator { + u16 Version; + + if (Version == 0) { + u32 Block_Allocator_Number; + Block_Allocator_Type0 block_allocator_type0[Block_Allocator_Number]; + } + + else if (Version == 1) { + u32 Block_Allocator_Number; + Block_Allocator_Type1 block_allocator_type1_[Block_Allocator_Number]; + } + + else if (Version == 2) { + bool Has_Secondary_Block_Allocator; + u32 Main_Block_Allocator_Number; + + Block_Allocator_Type1 block_allocator_type1__[Main_Block_Allocator_Number]; + + if (Has_Secondary_Block_Allocator) { + u32 Secondary_Block_Allocator_Number; + Block_Allocator_Type1 block_allocator_type1___[Secondary_Block_Allocator_Number+1]; + } + } + + +}; + +struct File { + u32 Object_Hash; + u32 File_Size; + u32 Filename_Length; + + if (File_Size > 0) { + if (Filename_Length == 0) { + bool HasBlockAllocator; + + if (HasBlockAllocator) { + Block_Allocator block_allocator; + u8 File_Data[File_Size]; + } + + else + u8 File_Data[File_Size]; + } + + else { + char Filename[Filename_Length]; + + bool HasBlockAllocator; + + if (HasBlockAllocator) { + Block_Allocator block_allocator; + u8 File_Data[File_Size]; + } + + else + u8 File_Data[File_Size]; + + + } + + } + + else + continue; + + + +}; + + +File file[while(!std::mem::eof())] @0x00; \ No newline at end of file From aa842104cefac5c145ec32394c1ec8d27922d89d Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:27:57 +0300 Subject: [PATCH 34/41] Update and rename ACU_DATA_Compressed.hexpat to acu_data_compressed.hexpat --- .../{ACU_DATA_Compressed.hexpat => acu_data_compressed.hexpat} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename patterns/Assassin's Creed: Unity/{ACU_DATA_Compressed.hexpat => acu_data_compressed.hexpat} (90%) diff --git a/patterns/Assassin's Creed: Unity/ACU_DATA_Compressed.hexpat b/patterns/Assassin's Creed: Unity/acu_data_compressed.hexpat similarity index 90% rename from patterns/Assassin's Creed: Unity/ACU_DATA_Compressed.hexpat rename to patterns/Assassin's Creed: Unity/acu_data_compressed.hexpat index 54f4ee4d..cab12712 100644 --- a/patterns/Assassin's Creed: Unity/ACU_DATA_Compressed.hexpat +++ b/patterns/Assassin's Creed: Unity/acu_data_compressed.hexpat @@ -44,4 +44,4 @@ struct PACK { -PACK pack[while(!std::mem::eof())] @0x00; \ No newline at end of file +PACK pack[while(!std::mem::eof())] @0x00; From 12f26f116839a001cc409d14bc5724adcc5c10e9 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:28:16 +0300 Subject: [PATCH 35/41] Update and rename ACU_DATA_Decompressed.hexpat to acu_data_decompressed.hexpat --- ...CU_DATA_Decompressed.hexpat => acu_data_decompressed.hexpat} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename patterns/Assassin's Creed: Unity/{ACU_DATA_Decompressed.hexpat => acu_data_decompressed.hexpat} (93%) diff --git a/patterns/Assassin's Creed: Unity/ACU_DATA_Decompressed.hexpat b/patterns/Assassin's Creed: Unity/acu_data_decompressed.hexpat similarity index 93% rename from patterns/Assassin's Creed: Unity/ACU_DATA_Decompressed.hexpat rename to patterns/Assassin's Creed: Unity/acu_data_decompressed.hexpat index 47373733..84e34e78 100644 --- a/patterns/Assassin's Creed: Unity/ACU_DATA_Decompressed.hexpat +++ b/patterns/Assassin's Creed: Unity/acu_data_decompressed.hexpat @@ -90,4 +90,4 @@ struct File { }; -File file[while(!std::mem::eof())] @0x00; \ No newline at end of file +File file[while(!std::mem::eof())] @0x00; From dcbc6069fd7ecdc4a612c849e1713bfe1565958c Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:30:29 +0300 Subject: [PATCH 36/41] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index b4d86526..06486682 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ARC | | [`patterns/arc.hexpat`](patterns/arc.hexpat) | Minecraft Legacy Console Edition ARC files | | ARIA2 | | [`patterns/aria2.hexpat`](patterns/aria2.hexpat) | ARIA2 Download Manager Control files | | ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout | +| Assassin's Creed: Unity | | [`patterns/Assassin's Creed: Unity`](patterns/Assassin's Creed: Unity) | Assassin's Creed: Unity archive files -- .forge & .data (compressed and decompressed) -- | | Bastion | | [`patterns/bastion/*`](https://gitlab.com/EvelynTSMG/imhex-bastion-pats) | Various [Bastion](https://en.wikipedia.org/wiki/Bastion_(video_game)) files | | BeyondCompare BCSS | | [`patterns/bcss.hexpat`](patterns/bcss.hexpat) | BeyondCompare Snapshot (BCSS) file | | Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files | @@ -198,9 +199,6 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | | MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | -| FORGE | `archives/forge` | [`patterns/acu_forge.hexpat`](patterns/acu_forge.hexpat) | .forge archive files used in Assassin's Creed: Unity | -| DATA | `archives/acu_data_compressed` | [`patterns/acu_data_compressed.hexpat`](patterns/acu_data_compressed.hexpat) | Compressed .data archive files used in Assassin's Creed: Unity | -| DATA | `archives/acu_data_decompressed` | [`patterns/acu_data_decompressed.hexpat`](patterns/acu_data_decompressed.hexpat) | Decompressed .data archive files used in Assassin's Creed: Unity | From 1890bf09be0a3fed4a73f572865ca5dd973567f6 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:34:19 +0300 Subject: [PATCH 37/41] Delete patterns/dmc3_hd_mod.hexpat --- patterns/dmc3_hd_mod.hexpat | 165 ------------------------------------ 1 file changed, 165 deletions(-) delete mode 100644 patterns/dmc3_hd_mod.hexpat diff --git a/patterns/dmc3_hd_mod.hexpat b/patterns/dmc3_hd_mod.hexpat deleted file mode 100644 index 9872b781..00000000 --- a/patterns/dmc3_hd_mod.hexpat +++ /dev/null @@ -1,165 +0,0 @@ -#pragma description Devil May Cry 3 HD .mod 3D model file -#pragma MIME 3d-model/capcom.dmc3-hd-mod - -// author = haru233, many thanks to AxCut -// ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files - - -import std.core; - - -struct ModelHeader { - char ID[4]; - float Version; - padding[8]; - u8 objectCount; - u8 boneCount; - u8 numberTextures; - u8; - u32; - u64; - u64 skeletonOffset; - padding[24]; -}; - -struct ObjectInfo { - u8 meshCount; - u8; - u16 numberVertices; - padding[4]; - u64 meshOffset; - u32 flags; - padding[28]; - float X, Y, Z; - float radius; -}; - -struct Positions { - float positions[3]; -}; - - -struct Normals { - float normal[3]; -}; - - -struct UVs { - s16 uv[2]; -}; - -struct BoneIndices { - u8 boneindex[4]; -}; - -struct Weights { - u16 weight[1]; -}; - -struct MeshSCM { - u16 numberVertices; - u16 textureIndex; - padding[12]; - u64 VerticesPositionsOffset; - u64 NormalsPositionsOffset; - u64 UVsPositionsOffset; - - padding[16]; - u64 unknownOffset; - - u64; - padding[8]; - - Positions positions[numberVertices] @VerticesPositionsOffset; - Normals normals[numberVertices] @NormalsPositionsOffset; - UVs uvs[numberVertices] @UVsPositionsOffset; - - -}; - -struct Mesh { - u16 numberVertices; - u16 textureIndex; - padding[12]; - u64 VerticesPositionsOffset; - u64 NormalsPositionsOffset; - u64 UVsPositionsOffset; - - u64 BoneIndicesOffset; - u64 WeightsOffset; - padding[8]; - - u64; - padding[8]; - - Positions positions[numberVertices] @VerticesPositionsOffset; - Normals normals[numberVertices] @NormalsPositionsOffset; - UVs uvs[numberVertices] @UVsPositionsOffset; - - BoneIndices b_index[numberVertices] @BoneIndicesOffset; - Weights weights[numberVertices] @WeightsOffset; - - -}; - - -struct Hierarchy { - u8 hierarchy; -}; - -struct HierarchyOrder { - u8 hierarchyorder; -}; - -struct Unknown { - u8; -}; - -struct Transform { - float x; - float y; - float z; - float length; // sqrt(x*x + y*y + z*z) - padding[16]; -}; - -struct Skeleton{ - u32 hierarchyOffset; - u32 hierarchyOrderOffset; - u32 unknownOffset; - u32 transformsOffset; -}; - - - - - -ModelHeader modelheader @ 0x00; -ObjectInfo objects_info[modelheader.objectCount] @ 0x40; - -u32 objectOffset; - -struct Object { - u64 i = std::core::array_index(); - if (modelheader.ID == "SCM ") { - objectOffset = objects_info[0].meshOffset; - MeshSCM meshscm[objects_info[i].meshCount] @ objects_info[i].meshOffset; - - - } else { - objectOffset = objects_info[0].meshOffset; - Mesh mesh[objects_info[i].meshCount] @ objects_info[i].meshOffset; - } -}; - -Object objects[modelheader.objectCount] @objectOffset; - -Skeleton skeleton @modelheader.skeletonOffset; - -Hierarchy hierarchy[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOffset); - -HierarchyOrder hierarchyorder[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOrderOffset); - -Unknown unknown[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.unknownOffset); - -Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset); From d5dd93b40e3e7aae0e8f0f285e766928dab09287 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:35:04 +0300 Subject: [PATCH 38/41] Create dmc3_hd_mod.hexpat --- .../dmc3_hd_mod.hexpat | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat diff --git a/patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat b/patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat new file mode 100644 index 00000000..41b21733 --- /dev/null +++ b/patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat @@ -0,0 +1,165 @@ +#pragma description Devil May Cry 3 HD .mod 3D model file +#pragma MIME 3d-model/capcom.dmc3-hd-mod + +// author = haru233, many thanks to AxCut +// ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files + + +import std.core; + + +struct ModelHeader { + char ID[4]; + float Version; + padding[8]; + u8 objectCount; + u8 boneCount; + u8 numberTextures; + u8; + u32; + u64; + u64 skeletonOffset; + padding[24]; +}; + +struct ObjectInfo { + u8 meshCount; + u8; + u16 numberVertices; + padding[4]; + u64 meshOffset; + u32 flags; + padding[28]; + float X, Y, Z; + float radius; +}; + +struct Positions { + float positions[3]; +}; + + +struct Normals { + float normal[3]; +}; + + +struct UVs { + s16 uv[2]; +}; + +struct BoneIndices { + u8 boneindex[4]; +}; + +struct Weights { + u16 weight[1]; +}; + +struct MeshSCM { + u16 numberVertices; + u16 textureIndex; + padding[12]; + u64 VerticesPositionsOffset; + u64 NormalsPositionsOffset; + u64 UVsPositionsOffset; + + padding[16]; + u64 unknownOffset; + + u64; + padding[8]; + + Positions positions[numberVertices] @VerticesPositionsOffset; + Normals normals[numberVertices] @NormalsPositionsOffset; + UVs uvs[numberVertices] @UVsPositionsOffset; + + +}; + +struct Mesh { + u16 numberVertices; + u16 textureIndex; + padding[12]; + u64 VerticesPositionsOffset; + u64 NormalsPositionsOffset; + u64 UVsPositionsOffset; + + u64 BoneIndicesOffset; + u64 WeightsOffset; + padding[8]; + + u64; + padding[8]; + + Positions positions[numberVertices] @VerticesPositionsOffset; + Normals normals[numberVertices] @NormalsPositionsOffset; + UVs uvs[numberVertices] @UVsPositionsOffset; + + BoneIndices b_index[numberVertices] @BoneIndicesOffset; + Weights weights[numberVertices] @WeightsOffset; + + +}; + + +struct Hierarchy { + u8 hierarchy; +}; + +struct HierarchyOrder { + u8 hierarchyorder; +}; + +struct Unknown { + u8; +}; + +struct Transform { + float x; + float y; + float z; + float length; // sqrt(x*x + y*y + z*z) + padding[16]; +}; + +struct Skeleton{ + u32 hierarchyOffset; + u32 hierarchyOrderOffset; + u32 unknownOffset; + u32 transformsOffset; +}; + + + + + +ModelHeader modelheader @ 0x00; +ObjectInfo objects_info[modelheader.objectCount] @ 0x40; + +u32 objectOffset; + +struct Object { + u64 i = std::core::array_index(); + if (modelheader.ID == "SCM ") { + objectOffset = objects_info[0].meshOffset; + MeshSCM meshscm[objects_info[i].meshCount] @ objects_info[i].meshOffset; + + + } else { + objectOffset = objects_info[0].meshOffset; + Mesh mesh[objects_info[i].meshCount] @ objects_info[i].meshOffset; + } +}; + +Object objects[modelheader.objectCount] @objectOffset; + +Skeleton skeleton @modelheader.skeletonOffset; + +Hierarchy hierarchy[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOffset); + +HierarchyOrder hierarchyorder[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.hierarchyOrderOffset); + +Unknown unknown[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.unknownOffset); + +Transform transform[modelheader.boneCount] @(modelheader.skeletonOffset + skeleton.transformsOffset); From e481feeba1d452851a536d063df6eccae9af4281 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:38:13 +0300 Subject: [PATCH 39/41] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 06486682..76dfcfa4 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ARC | | [`patterns/arc.hexpat`](patterns/arc.hexpat) | Minecraft Legacy Console Edition ARC files | | ARIA2 | | [`patterns/aria2.hexpat`](patterns/aria2.hexpat) | ARIA2 Download Manager Control files | | ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout | -| Assassin's Creed: Unity | | [`patterns/Assassin's Creed: Unity`](patterns/Assassin's Creed: Unity) | Assassin's Creed: Unity archive files -- .forge & .data (compressed and decompressed) -- | +| Assassin's Creed: Unity | [`patterns/Assassin's Creed: Unity`](patterns/Assassin's Creed: Unity) | Assassin's Creed: Unity archive files -- .forge & .data (compressed and decompressed) -- | | Bastion | | [`patterns/bastion/*`](https://gitlab.com/EvelynTSMG/imhex-bastion-pats) | Various [Bastion](https://en.wikipedia.org/wiki/Bastion_(video_game)) files | | BeyondCompare BCSS | | [`patterns/bcss.hexpat`](patterns/bcss.hexpat) | BeyondCompare Snapshot (BCSS) file | | Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files | @@ -58,6 +58,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | CREDHIST | | [`patterns/credhist.hexpat`](patterns/credhist.hexpat) | CREDHIST Format | | DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface | | DEX | | [`patterns/dex.hexpat`](patterns/dex.hexpat) | Dalvik EXecutable Format | +| Devil May Cry HD Collection | [`patterns/Devil May Cry HD Collection`](patterns/Devil May Cry HD Collection) | 3D Model files used in Devil May Cry 3 HD Collection | | DICOM | `application/dicom` | [`patterns/dicom.hexpat`](patterns/dicom.hexpat) | DICOM image format | | DMG | | [`patterns/dmg.hexpat`](patterns/dmg.hexpat) | Apple Disk Image Trailer (DMG) | | DMP | | [`patterns/dmp64.hexpat`](patterns/dmp64.hexpat) | Windows Kernel Dump(DMP64) | @@ -198,7 +199,6 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers | | ZLIB | `application/zlib` | [`patterns/zlib.hexpat`](patterns/zlib.hexpat) | ZLIB compressed data format | | ZSTD | `application/zstd` | [`patterns/zstd.hexpat`](patterns/zstd.hexpat) | Zstandard compressed data format | -| MOD | `3d-model/mod` | [`patterns/DMC3HD-Mod.hexpat`](patterns/dmc3_hd_mod.hexpat) | 3D Model files used in Devil May Cry 3 HD Collection | From 6c706f21d48f34c9dff39d9c220d482cdf699dec Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:38:55 +0300 Subject: [PATCH 40/41] Update dmc3_hd_mod.hexpat --- patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat b/patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat index 41b21733..67a4ebac 100644 --- a/patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat +++ b/patterns/Devil May Cry HD Collection/dmc3_hd_mod.hexpat @@ -1,7 +1,7 @@ #pragma description Devil May Cry 3 HD .mod 3D model file -#pragma MIME 3d-model/capcom.dmc3-hd-mod +#pragma author haru233 -// author = haru233, many thanks to AxCut +// many thanks to AxCut // ImHex Hex Pattern File for Capcom's Devil May Cry 3 HD .mod files From d7a6dab2eb0d6466b4243e92c550a0fa313e8778 Mon Sep 17 00:00:00 2001 From: haruse23 Date: Sun, 21 Sep 2025 14:40:03 +0300 Subject: [PATCH 41/41] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 76dfcfa4..44d79040 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | ARC | | [`patterns/arc.hexpat`](patterns/arc.hexpat) | Minecraft Legacy Console Edition ARC files | | ARIA2 | | [`patterns/aria2.hexpat`](patterns/aria2.hexpat) | ARIA2 Download Manager Control files | | ARM VTOR | | [`patterns/arm_cm_vtor.hexpat`](patterns/arm_cm_vtor.hexpat) | ARM Cortex M Vector Table Layout | -| Assassin's Creed: Unity | [`patterns/Assassin's Creed: Unity`](patterns/Assassin's Creed: Unity) | Assassin's Creed: Unity archive files -- .forge & .data (compressed and decompressed) -- | +| Assassin's Creed: Unity | | [`patterns/Assassin's Creed: Unity`](patterns/Assassin's Creed: Unity) | Assassin's Creed: Unity archive files -- .forge & .data (compressed and decompressed) -- | | Bastion | | [`patterns/bastion/*`](https://gitlab.com/EvelynTSMG/imhex-bastion-pats) | Various [Bastion](https://en.wikipedia.org/wiki/Bastion_(video_game)) files | | BeyondCompare BCSS | | [`patterns/bcss.hexpat`](patterns/bcss.hexpat) | BeyondCompare Snapshot (BCSS) file | | Bencode | `application/x-bittorrent` | [`patterns/bencode.hexpat`](patterns/bencode.hexpat) | Bencode encoding, used by Torrent files | @@ -58,7 +58,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | CREDHIST | | [`patterns/credhist.hexpat`](patterns/credhist.hexpat) | CREDHIST Format | | DDS | `image/vnd-ms.dds` | [`patterns/dds.hexpat`](patterns/dds.hexpat) | DirectDraw Surface | | DEX | | [`patterns/dex.hexpat`](patterns/dex.hexpat) | Dalvik EXecutable Format | -| Devil May Cry HD Collection | [`patterns/Devil May Cry HD Collection`](patterns/Devil May Cry HD Collection) | 3D Model files used in Devil May Cry 3 HD Collection | +| Devil May Cry HD Collection | | [`patterns/Devil May Cry HD Collection`](patterns/Devil May Cry HD Collection) | 3D Model files used in Devil May Cry 3 HD Collection | | DICOM | `application/dicom` | [`patterns/dicom.hexpat`](patterns/dicom.hexpat) | DICOM image format | | DMG | | [`patterns/dmg.hexpat`](patterns/dmg.hexpat) | Apple Disk Image Trailer (DMG) | | DMP | | [`patterns/dmp64.hexpat`](patterns/dmp64.hexpat) | Windows Kernel Dump(DMP64) |