Mech milestone: reconstruct AlarmIndicator (helper 1/3), compile-verified

First of the 3 missing Mech embedded-helper classes. AlarmIndicator is the
multi-level status indicator the Mech carries four of (master/heat/stability/
status). Reconstructed as a StateIndicator subclass: the shipped ctor
(@0041b9ec) is byte-for-byte the surviving StateIndicator(unsigned) ctor
(stateCount=oldState=currentState=count; 3 watcher sockets NULL) with a distinct
vtable, so a derived class reproduces it exactly and adds the level API
(SetLevel/GetLevel/GetLevelCount -> SetState/GetState/stateCount). Header-only
(StateIndicator's methods are in SIMULATE.CPP, already in munga.lib).

Compile-verified standalone under BC4.52 with the authentic build flags.
Evidence + placement in ALARM.NOTES.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-19 20:49:26 -05:00
co-authored by Claude Fable 5
parent 26e08a39f7
commit 9a4f1c293b
2 changed files with 81 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
#if !defined(ALARM_HPP)
# define ALARM_HPP
# if !defined(STATE_HPP)
# include <state.hpp>
# endif
//##########################################################################
//######################## AlarmIndicator ############################
//##########################################################################
//
// A multi-level status indicator. The Mech carries four (master, heat,
// stability, status); each maps a discrete alarm LEVEL onto a StateIndicator
// state, so a level change fires the same audio / video / gauge watchers as
// StateIndicator::SetState.
//
// Reconstructed: the shipped ctor (@0041b9ec) is byte-for-byte the
// StateIndicator(unsigned) ctor (stateCount = oldState = currentState =
// level_count; the three watcher sockets initialised NULL) with a distinct
// vtable, i.e. a StateIndicator subclass. See ALARM.NOTES.md.
//
class AlarmIndicator:
public StateIndicator
{
public:
AlarmIndicator(unsigned level_count = 0):
StateIndicator(level_count)
{
}
void
SetLevel(unsigned level)
{Check(this); SetState(level);}
unsigned
GetLevel()
{Check(this); return GetState();}
unsigned
GetLevelCount()
{Check(this); return stateCount;}
};
#endif
@@ -0,0 +1,39 @@
# ALARM.HPP — reconstruction notes
**Status: RECONSTRUCTED, compile-verified under BC4.52. First of the 3 missing
Mech embedded-helper classes ([[MECH-LAYOUT]] step 1).**
`AlarmIndicator` — the multi-level status indicator the Mech carries four of
(masterAlarm 33 levels, heatAlarm 3, stabilityAlarm 2, statusAlarm 33). Absent
from the 4.10 archive (no ALARM/STATE variant survives it); reconstructed from
the shipped binary + the surviving StateIndicator source.
## Evidence
- Ctor decomp `FUN_0041b9ec(this, count)` (BT411 reference/decomp part_002.c):
base ctor, own vtable `&PTR_FUN_004e3440`, three watcher sockets initialised at
+6/+0xb/+0x10 via `FUN_0041c42c(_, 0)`, then `this[3]=this[4]=this[5]=count`.
- The surviving `StateIndicator::StateIndicator(unsigned max_states)` (CODE/RP/
MUNGA/SIMULATE.CPP:62) is **byte-for-byte identical**: `audioWatcherSocket(NULL),
videoWatcherSocket(NULL), gaugeWatcherSocket(NULL)` then `stateCount = oldState
= currentState = max_states`.
The only difference is the vtable ⇒ AlarmIndicator is a StateIndicator **subclass**
(same Node + 3 state words + 3 SChainOf watcher-socket layout, adds no data). A
derived class naturally gets its own vtable, reproducing `PTR_FUN_004e3440`.
## API
The Mech drives the alarms with `SetLevel(unsigned)` / `GetLevel()` (and reads
`GetLevelCount()`). These map to StateIndicator's `SetState` / `GetState` /
`stateCount` — a level IS a state, so a level change notifies the audio/video/
gauge watchers exactly as SetState does. (BT411's `ReconAlarm` proxy exposed a
raw `level` member; that was a proxy artifact — the real class stores it as
`currentState`.)
## Placement
The 1995 source filename for AlarmIndicator is unknown (BT411 handled it via the
mechrecon.hpp proxy; nothing survives in CODE). Filed as MUNGA/ALARM.HPP; the
Mech includes it. StateIndicator's out-of-line methods live in SIMULATE.CPP
(already in munga.lib), so no new .CPP is needed — AlarmIndicator is header-only.