Cockpit: the authentic punch STENCIL-CUT -- all 8 cockpits real (task #55)

The user caught the inversion (blocked viewports, see-through frames); the
answer came from the rasterizer board itself: an i860 disassembly of the
VREND.MNG firmware decoded the damageize handler (@0xf040f6f8) -- cmd 0x20
(vr_damage_action) writes the dpl_Punchize token triple onto the punch
geogroup's first three geometry chunks IN FILE ORDER:

  chunk1 = the detailed window-aperture shapes -> an invisible per-pixel MASK
  chunk2 = the coarse hull -> the ONLY colour-drawn geometry (where not masked)
  chunk3 = byte-identical hull twin -> the damage-reset record, never visible

Visible canopy = hull-minus-apertures.  Both earlier readings were wrong ways
around the same three chunks: dropping all punch left floating fragments (no
hull); hiding the duplicate pair hid the HULL and drew the MASK -- the exact
inversion observed.

Port: bgfload tags per punch patch {non-paired pmesh = mask (role 1),
first twin = hull (role 2), second twin = skip}; L4D3D DrawMesh runs
mask->stencil-1 (no colour/z-write, z-tested), hull->stencil-NOTEQUAL,
mask->stencil-0; device D24X8 -> D24S8 + stencil clear.  The cut never
touches z, so later-drawn entities show through the apertures.
BT_COP_PLATES=1 disables (diag).

In-game, all 8 mechs on pure defaults: connected dark frames with clear
viewports -- thor (the footage mech) shows the central viewport + surrounding
frame exactly as filmed.  Combat regression clean (kill + no NaN).

Arena textured punch uses the same firmware kit; the black-texel alpha path
there is a working approximation, flagged in the KB.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-11 08:53:22 -05:00
co-authored by Claude Fable 5
parent 8431e69b1a
commit 96b8892e7c
8 changed files with 136 additions and 41 deletions
+33 -17
View File
@@ -504,7 +504,8 @@ struct Builder {
bool currentTSphere = false; // material is tsphere_mtl (translocation warp): ramp it despite normals
bool meshIsTSphere = false; // this OBJECT is the translocation warp -> smooth-tessellate the cone
bool meshIsCop = false; // this OBJECT is a *_cop cockpit canopy shell (task #55)
std::set<const void*> copPlateSkip; // duplicate damage-plate PMESHes to hide (see TAG_PATCH)
std::map<const void*, int> copRoleMap; // punch-kit roles per PMESH chunk: 1=mask 2=hull 3=skip (see TAG_PATCH)
int currentCopRole = 0; // role of the pmesh being built (consumed by buildPmesh)
bool currentHasEmissive = false;
float currentEmissive[3] = {0,0,0};
@@ -734,6 +735,7 @@ struct Builder {
batch.lodNear = currentLodNear;
batch.lodFar = currentLodFar;
batch.punch = currentPunch;
batch.copRole = currentCopRole; // punch stencil-kit role (task #55)
batch.shadowMat = currentShadowMat;
batch.hasEmissive = currentHasEmissive;
for (int i = 0; i < 3; ++i) batch.emissive[i] = currentEmissive[i];
@@ -964,24 +966,24 @@ struct Builder {
if (memcmp(s + i, "PUNCH", 5) == 0) currentPunch = true;
if (currentPunch) break;
}
// COCKPIT DAMAGE-STATE PLATES (task #55, resolved 2026-07-11): every
// *_cop PUNCH patch contains exactly one pair of BYTE-IDENTICAL
// duplicate PMESHes -- solid cover plates for the tricoder per-triangle
// damage machinery (dpl_Punchize tokens = {dmg_set, undmg2enbl|texture,
// dmg_clear}; TRICODER.H), NOT visible undamaged structure. Rendering
// them was the "solid black canopy"; hiding only whole punch patches
// instead left disconnected floating frame bits. Hide the duplicate
// pairs (both copies), render the rest of the punch lattice opaque --
// verified from every mech's authored eye (SKL [jointeye]): all 8
// cockpits read as CONNECTED frames with window apertures. Duplicates
// are counted WITHIN the patch (BLX repeats its whole main lattice
// ACROSS its three dz-material patches -- those must stay).
// BT_COP_PLATES=1 renders the plates (diagnostic).
// PUNCH STENCIL-CUT KIT (task #55, FINAL -- decoded from the i860
// VREND.MNG firmware 'damageize' handler @0xf040f6f8 + the dpl_Punchize
// token triple {dmg_set, undmg2enbl|texture, dmg_clear}): a PUNCH
// patch's pmeshes are, in FILE ORDER, {aperture MASK, visible HULL,
// byte-identical hull TWIN}. The board rasterizes the MASK as an
// invisible per-pixel cutout, colour-draws ONLY the HULL where not
// masked (= the canopy frame with the window apertures cut through),
// and keeps the TWIN as the damage-reset record (never visible).
// Identify the twin pair WITHIN the patch by content hash: pair FIRST
// = the hull (role 2), pair SECOND = skipped; every non-paired pmesh
// = the aperture mask (role 1; drawn stencil-only by L4D3D).
// BT_COP_PLATES=1 disables the kit (all pmeshes draw plain, diag).
if (meshIsCop && currentPunch) {
static int s_plates = -1;
if (s_plates < 0) { const char* e = getenv("BT_COP_PLATES"); s_plates = (e && e[0] != '0') ? 1 : 0; }
if (!s_plates) {
std::map<std::pair<size_t, uint64_t>, const Chunk*> seen;
bool pairFound = false;
for (const Chunk& ch : c.children) {
if (ch.id != TAG_PMESH) continue;
uint64_t h = 1469598103934665603ull; // FNV-1a
@@ -990,12 +992,19 @@ struct Builder {
auto it = seen.find(key);
if (it == seen.end()) seen[key] = &ch;
else {
copPlateSkip.insert(&ch); copPlateSkip.insert(it->second);
copRoleMap[it->second] = 2; // hull (first twin)
copRoleMap[&ch] = 3; // reset record: never drawn
pairFound = true;
if (getenv("BT_COP_DUMP"))
fprintf(stderr, "[cop] hid duplicate plate pair (pmesh len=%u)\n",
fprintf(stderr, "[cop] punch kit: hull+twin pair (pmesh len=%u)\n",
(unsigned)ch.len);
}
}
if (pairFound)
for (const Chunk& ch : c.children)
if (ch.id == TAG_PMESH && !copRoleMap.count(&ch))
copRoleMap[&ch] = 1; // aperture mask
// no pair -> every pmesh stays role 0 (draw plain; unexpected shape)
}
}
for (const Chunk& ch : c.children)
@@ -1067,7 +1076,14 @@ struct Builder {
for (int i = 0; i < 3; ++i) { currentRampLo[i] = savedRampLo[i]; currentRampHi[i] = savedRampHi[i]; }
break;
}
case TAG_PMESH: if (copPlateSkip.count(&c)) break; buildPmesh(c); break;
case TAG_PMESH: {
auto rit = copRoleMap.find(&c);
currentCopRole = (rit != copRoleMap.end()) ? rit->second : 0;
if (currentCopRole == 3) { currentCopRole = 0; break; } // hull twin: never drawn
buildPmesh(c);
currentCopRole = 0;
break;
}
default: for (const Chunk& ch : c.children) collect(ch); break;
}
}