Gitea #6: secondary MFD Damage/Critical/Heat cycling -- reconstruct the
NotifyOfDisplayModeChange override (vtbl+0x4C @4d1ae4) + wire desktop 'N'
The secondary screen's schematic selector was mislabeled: @004d1ae4 (the
bits-18..20 ModeSecondary* mask swap) was reconstructed as a non-virtual
"SetControlMode" that nothing called, so the desktop stayed pinned on the
Damage view. The binary's L4 vtable @0051e440 pins the truth:
+0x48 = @004d1acc <- CycleControlModeMessageHandler (FUN_004afbe0):
forwards to the base RET no-op @004b048c. A BAS/MID/ADV
control-mode change never touches the secondary view
(empirically confirmed: BT_MODECYCLE_TEST cycles the CONTROL
MODE lamp, mask bits 18-20 unchanged, schematic stays ARMOR).
+0x4C = @004d1ae4 <- CycleDisplayModeMessageHandler (FUN_004afcac):
THE Damage/Critical/Heat selector, indexed by displayMode
(table @0051dbe4 = ModeSecondaryDamage/Critical/Heat).
Authentic pod inputs (streamed type-6 .CTL EventMappings, dumped via the
new BT_CTRLMAP_LOG EVENT records): secondary-panel button 0x15 -> msg
0x15 CycleDisplayMode (manual p13, the "'Mech status Info center" bottom
left of the secondary screen), button 0x18 -> msg 0x14 CycleControlMode
(manual p6, top right), 0x10/0x11 -> ZoomIn/Out. The DOS keyboard
fallbacks (Keypress 0x13d/0x13e = extended F3/F4) are dead under the
WinTesla VK map, hence the desktop pin.
Port wiring (the M/ModeCycle pattern): key N / pad RightThumb -> action
DisplayCycle -> gBTDisplayCycle -> CycleDisplayModeNow() -- the same body
the pod console button message drives. Both .MAP profiles + the
compiled-in default updated.
Verified live (docked gauges + BT_SHOT, BT_VIEWCYCLE_TEST): the sec
panel cycles ARMOR DAMAGE silhouette -> CRITICAL DAMAGE subsystem list
-> HEAT DAMAGE colored list, mask 0x450421 -> 0x490421 -> 0x510421; M
control-mode cycling un-regressed (BAS/MID/ADV lamp cycles, view pinned).
Diags: BT_MODE_LOG, BT_VIEWCYCLE_TEST=<frame>, BT_MODECYCLE_TEST=<frame>,
BT_CTRLMAP_LOG now dumps EVENT records. KB: gauges-hud secondary-view
section rewritten, CLASSMAP +0x48/+0x4C slots, decomp-reference env
gates, GAUGE_COMPOSITE phase-4 entry resolved.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
2ae9bd43ae
commit
1d6339b226
@@ -30,10 +30,12 @@
|
||||
// @004d17ac ctor @004d1814 dtor
|
||||
// @004d196c InterpretControls (target-range ramp + review-mode watch)
|
||||
// @004d1b64 ZoomTargetRangeIn @004d1b9c ZoomTargetRangeOut
|
||||
// @004d1ae4 SetControlMode (mode-mask switch; calls base NotifyOfDisplayMode)
|
||||
// @004d1acc NotifyOfControlModeChange (+0x48; forwards to base no-op @004b048c)
|
||||
// @004d1ae4 NotifyOfDisplayModeChange (+0x4C; the secondary-view mask swap
|
||||
// -- Gitea #6 relabel; ex-"SetControlMode")
|
||||
// @004d1b24 SetPresetMode (group/item -> preset mode-mask)
|
||||
// @004d1840 CreateTemporaryEventMappings @004d18dc RemoveTemporaryEventMappings
|
||||
// @004d195c NotifyOfControlModeChange (no-op) @004d1964 NotifyOfConfigurationModeChange (no-op)
|
||||
// @004d1840 EnterConfiguration @004d18dc ExitConfiguration
|
||||
// @004d195c/@004d1964 AddOrErase evt/dir (+0x40/+0x44, RET no-ops)
|
||||
// @004d1bf0 KeypressMessageHandler (the shared L4 keyboard dispatcher)
|
||||
// MechThrustmasterMapper --------------------------- vtable @0051e3f0
|
||||
// @004d21d0 ctor @004d22b4 dtor @004d22e0 TestInstance
|
||||
@@ -81,7 +83,8 @@
|
||||
// _DAT_004d1ac8 = 0x437a0000 = 250.0f (target-range scale: range = 250*2^x)
|
||||
// _DAT_004d1b94 = 1.0f zoom-in step _DAT_004d1b98 = 0.0f min exponent
|
||||
// _DAT_004d1bcc = 1.0f zoom-out step _DAT_004d1bd0 = 5.0f max exponent
|
||||
// DAT_0051dbe4[3] = {0x40000,0x80000,0x100000} control-mode mode-masks
|
||||
// DAT_0051dbe4[3] = {0x40000,0x80000,0x100000} secondary-VIEW mode-masks
|
||||
// (ModeSecondaryDamage/Critical/Heat, indexed by displayMode)
|
||||
// DAT_0051dbf0[15] = {clear,set} mode-mask pairs (group*5+item), preset select
|
||||
// DAT_0051dcd0[8] = {0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30} hotbox buttons
|
||||
//
|
||||
@@ -482,25 +485,61 @@ L4MechControlsMapper::MessageHandlerSet&
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// SetControlMode @004d1ae4
|
||||
// NotifyOfControlModeChange @004d1acc (vtbl+0x48)
|
||||
// NotifyOfDisplayModeChange @004d1ae4 (vtbl+0x4C)
|
||||
//#############################################################################
|
||||
//
|
||||
// Swap the application mode-manager's control-mode bits (18..20) for the bit
|
||||
// selected by new_mode, then notify the base of the implied display change.
|
||||
// Gitea #6 RELABEL (2026-07-19). The old reconstruction carried @004d1ae4 as
|
||||
// a non-virtual "SetControlMode" that nothing ever called, so the desktop's
|
||||
// secondary MFD stayed pinned on the Damage view. The vtable @0051e440
|
||||
// (section_dump.txt:73033) pins the truth:
|
||||
//
|
||||
// +0x48 = @004d1acc -- dispatched by CycleControlModeMessageHandler
|
||||
// (FUN_004afbe0) with the new controlMode. Capstone disasm: pushes
|
||||
// its two args and forwards to the BASE no-op @004b048c. A
|
||||
// control-mode (BAS/MID/ADV) change never touches the secondary
|
||||
// view -- in the shipped binary OR here.
|
||||
// +0x4C = @004d1ae4 -- dispatched by CycleDisplayModeMessageHandler
|
||||
// (FUN_004afcac) with the new displayMode. THE secondary-view
|
||||
// selector: clears mode bits 18..20 (& 0xffe3ffff =
|
||||
// ~ModeSecondaryAll), sets the mask picked from the table @0051dbe4
|
||||
// = {ModeSecondaryDamage 0x40000, ModeSecondaryCritical 0x80000,
|
||||
// ModeSecondaryHeat 0x100000}, then chains the base no-op
|
||||
// @004b0494. displayMode 0/1/2 = Damage/Critical/Heat -- the
|
||||
// manual-p13 "'Mech status Info center" schematic cycle (bottom
|
||||
// left of the secondary screen).
|
||||
//
|
||||
void
|
||||
L4MechControlsMapper::SetControlMode(int new_mode)
|
||||
L4MechControlsMapper::NotifyOfControlModeChange(int new_mode)
|
||||
{
|
||||
static const ModeMask control_mode_mask[] = // @0051dbe4
|
||||
{ 0x40000, 0x80000, 0x100000 };
|
||||
MechControlsMapper::NotifyOfControlModeChange(new_mode); // @004b048c (no-op)
|
||||
}
|
||||
|
||||
void
|
||||
L4MechControlsMapper::NotifyOfDisplayModeChange(int new_mode)
|
||||
{
|
||||
static const ModeMask display_mode_mask[] = // @0051dbe4
|
||||
{
|
||||
BTL4ModeManager::ModeSecondaryDamage, // 0 -> 0x040000
|
||||
BTL4ModeManager::ModeSecondaryCritical, // 1 -> 0x080000
|
||||
BTL4ModeManager::ModeSecondaryHeat // 2 -> 0x100000
|
||||
};
|
||||
|
||||
BTL4ModeManager *mode_manager =
|
||||
(BTL4ModeManager*)application->GetModeManager(); // DAT_004efc94+0x50
|
||||
|
||||
mode_manager->RemoveModeMask(0x001c0000); // clear bits 18..20 (~0xffe3ffff)
|
||||
mode_manager->AddModeMask(control_mode_mask[new_mode]);
|
||||
mode_manager->RemoveModeMask( // clear bits 18..20
|
||||
BTL4ModeManager::ModeSecondaryAll); // (& 0xffe3ffff)
|
||||
mode_manager->AddModeMask(display_mode_mask[new_mode]);
|
||||
|
||||
NotifyOfDisplayModeChange(displayMode); // FUN_004b0494
|
||||
// DIAG (BT_MODE_LOG): the resulting manager mask -- proves the
|
||||
// secondary-view bit actually flipped for the gauge layer gating.
|
||||
if (getenv("BT_MODE_LOG"))
|
||||
DEBUG_STREAM << "[mode] display notify " << new_mode
|
||||
<< " -> manager mask 0x" << std::hex
|
||||
<< mode_manager->GetModeMask() << std::dec << "\n" << std::flush;
|
||||
|
||||
MechControlsMapper::NotifyOfDisplayModeChange(new_mode); // @004b0494 (no-op)
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user