Clean, self-contained extraction of the BattleTech-specific work from the
reverse-engineering workspace -- engine + game + content + build, with nothing
from Red Planet or the raw archive dumps. Builds green (Win32) and runs the
single-player drive->animate->target->fire->damage->destroy loop out of the box.
Layout:
engine/ MUNGA + MUNGA_L4 shared 2007 engine, carrying our BT render/loader
work (bgfload/L4D3D/L4VIDEO: BSL bit-slice decode, LOD/ground/shadow
models) + image codec; the minimal rp/ headers the audio HAL needs
game/ reconstructed BT logic + surviving-original BT source + fwd shims
+ WinMain launcher
content/ full runtime tree (BTL4.RES, VIDEO/, GAUGE/, AUDIO/, eggs, BTDPL.INI)
docs/ format specs + reconstruction ledgers
reference/ raw Ghidra pseudocode (recon source-of-truth) + decomp exporter
tools/ MP console emulator + map/resource scanners
One top-level CMake builds munga_engine lib + bt410_l4 game lib + btl4.exe.
All paths relativized (186 fwd shims + ~437 CMake abs paths -> repo-relative);
DXSDK is the one external, overridable via -DDXSDK. Verified: builds to a
byte-identical 2.27MB exe and runs combat (TARGET DESTROYED, 0 crashes) against
the bundled content.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.8 KiB
Asset Pipeline — Textures, Materials & Gauges
Companion to BGF_FORMAT.md. Covers how a model's surface resolves to pixels, and the cockpit
gauge/HUD formats. Verified by hexdump against real content; header cites are file:line under
…/CODE/RP/MUNGA_L4/libDPL/.
Format inventory (CONTENT/BT)
| Ext | Count | Kind | Role |
|---|---|---|---|
.bgf |
1275 | DIV-BIZ2 FILETYPE=0 |
3D geometry (see BGF_FORMAT.md) |
.bmf |
2222 | DIV-BIZ2 FILETYPE=1 |
material + texture libraries (no pixels) |
.vtx |
5 | DIV-VTX2 |
raw RGB texel image |
.tga |
8 | Truevision TGA2 type-2 | 24-bit truecolor texel image |
.sgi |
0 | (loader exists) | RGBA texel image (none shipped) |
.bsl |
3 | DIV-BSL2 |
bit-slice / multi-image + mip container |
.pcc |
434 | ZSoft PCX, 8-bit RLE | cockpit HUD/gauge raster bitmaps |
.gim |
311 | ASCII INI | MFD/radar vector line-gauges (NOT raster) |
.gat |
3 | ASCII INI | gauge color/attribute table |
Layout: VIDEO/GEO/*.bgf, VIDEO/MAT/*.bmf, VIDEO/TEX/*.vtx,*.bsl (+ TEX/BUILD/*.tga),
VIDEO/BUILD/* staging, GAUGE/*.gim,*.gat,*.pcc, MODELS/*.mod (INI tying bgf+gim+sld).
Name-resolution chain (verified)
BGF geogroup SV_F_MATERIAL "library:material"
→ open library.bmf
→ MATERIAL chunk whose NAME == "material"
→ its MATERIAL_TEXTURE (0x0021): [u8 type=2 NAMED][texture-name string]
→ TEXTURE chunk whose NAME == that texture-name
→ its TEXTURE_MAP (0x0011): image basename (no ext)
→ loader appends ext, searches texmap path → .vtx/.tga/.sgi/.bsl
dpfCreateMaterialName(extPath,library,mname) PFILE.H:821.
.BMF chunk layout (same TLV grammar as BGF; tags in PFBIZTAG.H:43-62)
TEXTURE 0x0010 (dpfTEXTURE, __PFILE.H:120-137): NAME 0x2008 (string); TEXTURE_MAP 0x0011
(basename string); MINIFY 0x0012/MAGNIFY 0x0013 (mip/filter enums, PFILE.H:155-162); ALPHA 0x0014
{blend/cut/blendcut}; WRAP_U/V 0x0015/16 {repeat/clamp/select}; DETAIL 0x0017; BITSLICE 0x0018 (u8 → .bsl slice).
MATERIAL 0x0020 (dpfMATERIAL, __PFILE.H:152-169): NAME 0x2008; MATERIAL_TEXTURE 0x0021
[u8 type(2=named)+name]; AMBIENT 0x0023/DIFFUSE 0x0024 = 3×f32 RGB (verified); SPECULAR 0x0025/
EMISSIVE 0x0026/OPACITY 0x0027 (optional, inferred 3-4 f32); RAMP 0x0028 (ramp-name string).
RAMP 0x0030: NAME + RAMP_DATA 0x0031 (float color data).
Pixel formats (normalize all to 32-bit RGBA at load)
- .VTX (
DIV-VTX2): TLV; size tag0x2062= two int32 (w,h, e.g. 128×128); body = uncompressed RGB 3 B/px, top-to-bottom. Type enumdpiBSLTYPE(PIMAGE.H:104-116): MONO0-5/BILINEAR/RGB/RGBA. - .TGA: standard type-2, 24-bit BGR, TGA2 footer.
dpl_tgaRead. - .SGI: RGBA (
dpl_sgiRead; none shipped). - .BSL (
DIV-BSL2): DECODED — a BIT-SLICED multi-image container (corpus-verified on all 66 archive BSLs; reference = the shipping WinTesla loaderDivLoader/VGCDivLoader.cpp:323-410LoadBSLFile/getBSLData+ Divisiondsys/PIMAGE.HdpiBSLTYPE+ the content build scriptsimg2vtx.exe -b -mN <tga>). Header (int32 LE): w@0x08, h@0x0C, depth@0x10(bits per slice, always 4), tableBytes@0x14(directory length counted from the nEntries field; imageDataOffset =0x18 + tableBytes), nEntries@0x18; directory entries{int32 recLen; int32 sliceType; char name[recLen-4]}— entry names are authoring records only, read-and-discarded at runtime; thenw*hlittle-endian 32-bit texel WORDS. Byte 0 of each word = pad (structurally unused, 0 in all 66 files); the other 3 bytes = SIX independent 4-bit GRAYSCALE slices, nibble PAIR-SWAPPED (even slice = HIGH nibble): slice0=bits12-15, 1=8-11, 2=20-23, 3=16-19, 4=28-31, 5=24-27 (shift=(c+((c+1)%2)*2)*4, value returned<<4= 0x00..0xF0). sliceType 7 = RGB444 (r=s5,g=s4,b=s3), 8 = RGBA4444 (+a=s2); both coexist with mono slices in one file (BDAM/BEXP/BDET). Slice SELECTION = the BMF TEXTURE record'sBITSLICEtag0x18(u8; absent = slice 0) — e.g. BLHSKIN.BMF blkhwk1_tex=absent(0), blkhwk2/3/4_tex=01/02/03, all mapping image basenameblkhwk→ BLKHWK.BSL. Mono slices are colorized downstream by material RAMP (+ diffuse tint on neutral ramps) — all mech skins, vehicle atlases (BASEV = 6 gray sheets, NOT truecolor), logos, effects grit. ⚠ The previous "base image = trailing whbpp, pixel order [pad,R,G,B]" claim was WRONG — it overlaid 2-3 different gray slices as RGB channels (the rainbow "graffiti" mech-skin bug); it survives as theBT_BSL=0diagnostic fallback inport/src/image.cpp decodeBSL.
Cockpit gauges
- .GIM = ASCII INI, vector top-down line drawing for MFD/radar:
[lods] level0=3000…,[vertices] v0=x,y,z,[level0] linelist=<group> v0 v1 v2…. First token = color/attr group resolved via.gat. Feeds thedpl2d_*2D line path. VerifiedAB01_GA.GIM. - .GAT = ASCII INI:
[colors],[groups] a_bld=amber1…→ group→palette-index. VerifiedGAUGE.GAT. - .PCC = ZSoft PCX, 8-bit RLE, 256-color palette (palette after
0x0CEOF marker); 640×480-class. The actual HUD raster bitmaps → need 8-bit-palette → RGBA expansion. VerifiedADPAL.PCC.
⚠ Dependencies / open items
- The retail texel raster set is NOT in this archive — only the BUILD/logo subset of
.vtx/.tga/.bslships. The 2222.bmfreference maps that aren't here. Need the full texture content from Nick, or the renderer must tolerate missing maps and fall back to material DIFFUSE color. - No source for the
.gim/.gat/.pccloaders — inside the closedLIBDPL.LIB..pcc(PCX) and.gim/.gat(INI) are standard/simple..bsland.vtxare now FULLY decoded (see Pixel formats above; the shippingDivLoader/VGCDivLoader.cppturned out to carry the reference reader for both).