Files
BT412/docs/ASSET_PIPELINE.md
T
arcattackandClaude Opus 4.8 7b7d465e5e Initial commit: bt411 -- standalone Windows BattleTech (Tesla 4.10 port)
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>
2026-07-05 21:03:40 -05:00

5.8 KiB
Raw Blame History

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 tag 0x2062 = two int32 (w,h, e.g. 128×128); body = uncompressed RGB 3 B/px, top-to-bottom. Type enum dpiBSLTYPE (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 loader DivLoader/VGCDivLoader.cpp:323-410 LoadBSLFile/getBSLData + Division dsys/PIMAGE.H dpiBSLTYPE + the content build scripts img2vtx.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; then w*h little-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's BITSLICE tag 0x18 (u8; absent = slice 0) — e.g. BLHSKIN.BMF blkhwk1_tex=absent(0), blkhwk2/3/4_tex=01/02/03, all mapping image basename blkhwk → 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 the BT_BSL=0 diagnostic fallback in port/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 the dpl2d_* 2D line path. Verified AB01_GA.GIM.
  • .GAT = ASCII INI: [colors],[groups] a_bld=amber1… → group→palette-index. Verified GAUGE.GAT.
  • .PCC = ZSoft PCX, 8-bit RLE, 256-color palette (palette after 0x0C EOF marker); 640×480-class. The actual HUD raster bitmaps → need 8-bit-palette → RGBA expansion. Verified ADPAL.PCC.

⚠ Dependencies / open items

  1. The retail texel raster set is NOT in this archive — only the BUILD/logo subset of .vtx/.tga/.bsl ships. The 2222 .bmf reference 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.
  2. No source for the .gim/.gat/.pcc loaders — inside the closed LIBDPL.LIB. .pcc(PCX) and .gim/.gat(INI) are standard/simple. .bsl and .vtx are now FULLY decoded (see Pixel formats above; the shipping DivLoader/VGCDivLoader.cpp turned out to carry the reference reader for both).