# 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
  w*h*bpp, 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).
