Skip to content

Instantly share code, notes, and snippets.

@eliasdaler
Created September 16, 2025 16:43
Show Gist options
  • Select an option

  • Save eliasdaler/939537a03d518ebfc15f080c5c9fe4dc to your computer and use it in GitHub Desktop.

Select an option

Save eliasdaler/939537a03d518ebfc15f080c5c9fe4dc to your computer and use it in GitHub Desktop.
TMD ImHex parser (unfinished)
import std.io;
import std.core;
import std.sys;
#include <math.hexpat>
struct Vec3Pad {
FixedPoint<s16> x, y, z;
u16 pad [[hidden]];
} [[sealed, format("format_vec3")]];
// Only flat shaded triangles are properly parsed
struct Primitive {
u8 olen;
u8 ilen;
u8 flag;
u8 mode;
if (mode == 32) {
u8 r;
u8 g;
u8 b;
u8 md;
u16 normal;
u16 v0;
u16 v1;
u16 v2;
} else {
$ += ilen * 4;
}
};
u32 objOffset;
struct Object {
objOffset = $;
u32 vertTopAddr;
u32 numVert;
u32 normalTopAddr;
u32 numNormal;
u32 primitiveTopAddr;
u32 numPrimitives;
u32 scale;
$ = vertTopAddr + objOffset;
Vec3Pad vertices[numVert];
$ = primitiveTopAddr + objOffset;
Primitive prims[numPrimitives];
$ = normalTopAddr + objOffset;
Vec3Pad normals[numNormal];
};
struct TMDFile {
u32 id;
std::assert(id == 0x41, "Invalid TMD id");
u32 flags;
u32 numObj;
Object objects[numObj];
};
TMDFile file @ 0x0;
struct VertexFloat {
float x, y, z;
};
u16 objToInspect in;
u16 numObjects out;
const u16 numVerts = file.objects[objToInspect].numVert;
const u16 numIndices = file.objects[objToInspect].numPrimitives * 3;
struct Model {
VertexFloat vertices[numVerts];
float colors[numVerts * 4];
u32 indices[numIndices];
} [[hex::visualize("3d", vertices, indices, null, colors)]];
std::mem::Section section = std::mem::create_section("Section");
std::mem::set_section_size(section, sizeof(Model));
Model model @ 0x00 in section;
fn main() {
numObjects = file.numObj;
Object obj @ addressof(file.objects[objToInspect]);
for (u32 i = 0, i < numVerts, i= i + 1) {
model.vertices[i].x = fixedX12_to_float(obj.vertices[i].x);
// flip Y and Z for visualization
model.vertices[i].y = -fixedX12_to_float(obj.vertices[i].y);
model.vertices[i].z = -fixedX12_to_float(obj.vertices[i].z);
}
for (u32 i = 0, i < numIndices / 3, i = i + 1) {
Primitive prim @ addressof(obj.prims[i]);
model.indices[i * 3 + 0] = prim.v0;
model.indices[i * 3 + 1] = prim.v1;
model.indices[i * 3 + 2] = prim.v2;
model.colors[4 * prim.v0 + 0] = float(prim.r) / 255.0;
model.colors[4 * prim.v0 + 1] = float(prim.g) / 255.0;
model.colors[4 * prim.v0 + 2] = float(prim.b) / 255.0;
model.colors[4 * prim.v0 + 3] = 1.0;
model.colors[4 * prim.v1 + 0] = float(prim.r) / 255.0;
model.colors[4 * prim.v1 + 1] = float(prim.g) / 255.0;
model.colors[4 * prim.v1 + 2] = float(prim.b) / 255.0;
model.colors[4 * prim.v1 + 3] = 1.0;
model.colors[4 * prim.v2 + 0] = float(prim.r) / 255.0;
model.colors[4 * prim.v2 + 1] = float(prim.g) / 255.0;
model.colors[4 * prim.v2 + 2] = float(prim.b) / 255.0;
model.colors[4 * prim.v2 + 3] = 1.0;
}
};model.colors[4 * prim.v2 + 3] = 1.0;
}
}; v1i + 3] = 1.0;
model.colors[4 * v2i + 0] = float(file.objects[0].prims[x].r)/ 255.0;
model.colors[4 * v2i + 1]= float(file.objects[0].prims[x].g)/ 255.0;
model.colors[4 * v2i + 2] = float(file.objects[0].prims[x].b)/ 255.0;
model.colors[4 * v2i + 3] = 1.0;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment