gauges: colorMapperMultiArmor (worst-of-8-zones) + fix the interpreterTable overflow [widget recon 4]
Reconstructs colorMapperMultiArmor -- tints one schematic colour (a whole torso section) by the WORST of up to 8 damage zones: - MultiArmorConnection (@004c346c/@004c34f4): scans 8 zones via entity->damageZones[idx], keeps the max damageLevel, count==0 ? 100 : Round(worst*100). - ColorMapperMultiArmor::Make/ctor (@004c3c48/@004c3d60): resolves 8 named zones to indices via Entity::GetDamageZoneIndex (13-param methodDescription). ALSO fixes a latent HEAP CORRUPTION that registering this widget exposed (and that would have blocked every further widget): GaugeInterpreter's bytecode buffer is a fixed interpreterTableSize=46864 (GAUGREND.h) tuned for RP's config, and its Insert() bounds guard is a Verify() that compiles out at DEBUG_LEVEL 0. As each BT gauge widget is registered, more of BT's larger L4GAUGE.CFG resolves into bytecode (vs being parse-skipped); colorMapperMultiArmor's 13 params x hundreds of calls pushed the total past 46864 -> silent overflow past the char[] -> heap smash detected later in mission bitmap loading (not the gauge code). Fix: interpreterTableSize -> 262144 (sized for BT's full config). Verified: parses, builds, all zones resolve, no /FORCE unresolved, combat un-regressed (TARGET DESTROYED, 0 crashes), stable. Details: docs/GAUGE_COMPOSITE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1d2ddd8399
commit
fb8c1d6ace
+23
-1
@@ -307,7 +307,29 @@ Ghidra dropped (`scratchpad/disas_hp.py`):
|
||||
(ColorMapperCritical, CriticalConnection @004c3598) are the same shape — easy follow-ups now the pattern
|
||||
+ the ColorMapper base facts are pinned.
|
||||
|
||||
**Next increments (priority order from the map):** `colorMapperMultiArmor`/`cmCrit` (same ColorMapper pattern), then the
|
||||
**✅ Increment 4 — `colorMapperMultiArmor` DONE — worst-of-N-zones tint.** Tints one schematic colour (a whole
|
||||
torso SECTION) by the worst of up to 8 damage zones. Reconstructed `MultiArmorConnection` (@004c346c ctor /
|
||||
@004c34f4 Transfer: scan 8 zones via `entity->damageZones[idx]`, keep max `damageLevel`, `count==0 ? 100 :
|
||||
Round(worst*100)`) + `ColorMapperMultiArmor::Make`/ctor (@004c3c48/@004c3d60 — resolves 8 zone names to
|
||||
indices via `GetDamageZoneIndex`, 13-param methodDescription). Verified: parses, builds, all zones resolve,
|
||||
combat un-regressed (TARGET DESTROYED, 0 crashes).
|
||||
|
||||
**⭐⭐ THE `interpreterTable` OVERFLOW — a latent heap-corruption fixed (every future widget needed this).**
|
||||
Registering colorMapperMultiArmor CRASHED — but not in the gauge code: a heap corruption surfaced later in
|
||||
mission bitmap loading (`ObjectNameList::AddEntry` → malloc AV). ROOT CAUSE: `GaugeInterpreter`'s bytecode
|
||||
buffer is a FIXED `interpreterTableSize = 46864` (GAUGREND.h) tuned for RP's config, and its `Insert()` bounds
|
||||
guard is a `Verify()` that COMPILES OUT at DEBUG_LEVEL 0 (the same dead-`Verify` class as the BNDGBOX/heat
|
||||
bugs). As each BT gauge widget is registered, more of BT's (larger) L4GAUGE.CFG resolves into bytecode instead
|
||||
of being parse-skipped; cmHeat+headingPointer+cmArmor got close, colorMapperMultiArmor (13 params × ~hundreds
|
||||
of calls) tipped it past 46864 → silent overflow past the `char[]` → heap smash detected at the next big alloc.
|
||||
FIX: `interpreterTableSize` → 262144 (sized for BT's full config). ⚠ This was going to block EVERY further
|
||||
widget — the table is cumulative across all registered gauges. **LESSON (add to the checklist): a heap
|
||||
corruption that surfaces in an INNOCENT later alloc, right after registering a gauge, is the interpreterTable
|
||||
overflow — the Insert bounds-`Verify` is dead at DEBUG_LEVEL 0.**
|
||||
|
||||
**Next increments (priority order from the map):** `cmCrit` (ColorMapperCritical -- needs the subsystem
|
||||
`damageZone@0xE0` shadow resolved; CriticalConnection = state==1?100:Round(subsys->damageZone->damageLevel*100)),
|
||||
then the
|
||||
`ArmorZoneConnection`/`MultiArmorConnection` classes reconstructed); then the attribute-table wave (`vertBar`/
|
||||
`segmentArcRatio` speed/`GeneratorCluster` — need `AttributePointers[]` on Mech/HeatableSubsystem, a separate
|
||||
pass); the XL items (`map`/`vehicleSubSystems`/`PlayerStatus`) last. The POD path needs the FULL 23-entry
|
||||
|
||||
Reference in New Issue
Block a user