BT410 5.3.124: one ladder to rule the valves -- MoveValve unifies onto the coolant priorities, and valveState retires
The condenser valve button and the mech's BalanceCoolant now drive ONE mechanism, as the binary does: MoveValve (@004ae464) steps the heatable-base coolantPriority through the authentic 0 -> 1 -> 5 -> 50 -> 0 ladder and calls the mech's RedistributeCoolantShares (@0049f788); valveState and the condenser-local renormalization are gone. RecomputeValves survives only as the [T3] conduction-flow bridge: the fight-verified pump (5.3.12-15 byte curves) consumes a CONDENSER-relative fraction, refreshed from the redistribute tail -- numerically identical to the old math, since non-condenser priorities cancel in the ratio. Registration caveat recorded: the @0x50e534 name table sits in the HEAT TU statics but its owning class is not proven, so the handler stays on Condenser id 4 (the live-verified streamed binding). Soak (pod_render_valve.conf, BT_PRESS_VALVE + BT_PRESS_BALANCE): spawn equal split (total 20, flows 6 x 0.166667) -> valve press (Condenser1 priority 5, total 24, flows 0.5 / 5 x 0.1 -- the exact predicted ratios) -> balance press restores the equal split, crash-sig 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
# pod_render_norio.conf -- pod_render_rec with the RIO serial port OFF.
|
||||
#
|
||||
# The emulator log shows a steady stream of serial1 RX OVERRUN errors on
|
||||
# the RIO pipe, and controls post their events at HighEventPriority
|
||||
# UNCONDITIONALLY (CONTROLS.HPP:250) -- so a chattering RIO port would
|
||||
# flood a priority the background pump always serves first, starving the
|
||||
# priority-0 renderer events the load gate waits on. This conf tests that
|
||||
# by removing the port entirely. Everything else is identical to the rec
|
||||
# conf, so a launch here and a hang there isolates the RIO.
|
||||
#
|
||||
[sdl]
|
||||
output=opengl
|
||||
# higher,higher not highest: HIGH_PRIORITY_CLASS starved the host desktop;
|
||||
# with the retry patches a rare dropout self-recovers (see gauge_rio.conf).
|
||||
priority=higher,higher
|
||||
[dosbox]
|
||||
memsize=32
|
||||
machine=svga_s3
|
||||
[cpu]
|
||||
core=dynamic
|
||||
cputype=pentium
|
||||
cycles=max
|
||||
[sblaster]
|
||||
sbtype=sb16
|
||||
sbbase=220
|
||||
irq=5
|
||||
dma=1
|
||||
hdma=5
|
||||
[mixer]
|
||||
# match the EMU8000s' native rate (no resample) and buffer ~60ms so brief
|
||||
# emulation-thread stalls (RIO retry recovery) don't audibly chop
|
||||
rate=44100
|
||||
blocksize=1024
|
||||
prebuffer=60
|
||||
[serial]
|
||||
# RIO on COM1 with the low-latency options (rxpollus/rxburst) so the board's
|
||||
# few-ms ACK deadline is met; plasma display on COM2 (real pod has both).
|
||||
# VWE fork namedpipe backend (com0com/realport retired -- COM1/COM2 gone):
|
||||
# DOSBox = pipe client (retry), vRIO/vPLASMA apps = servers; an unconnected
|
||||
# pipe behaves as an unplugged cable so the mission still runs. serialnamedpipe.h
|
||||
serial1=disabled
|
||||
serial2=namedpipe pipe:vplasma
|
||||
# live UNBUFFERED game output: DOS char devices are not buffered, so
|
||||
# redirecting stdout to COM3 lands every line immediately. A normal
|
||||
# '> file' redirect stays 0 bytes until the process exits, which hides
|
||||
# all progress on a run that does NOT crash.
|
||||
serial3=file file:C:\VWE\TeslaRel410\emulator\render-bridge\podlog.txt
|
||||
[autoexec]
|
||||
mount c "C:\VWE\TeslaRel410\ALPHA_1"
|
||||
c:
|
||||
cd \REL410\BT
|
||||
set VIDEOFORMAT=svga
|
||||
rem production pod card init (PARAMETR.BAT:181-186): DIAGNOSE + AWEUTIL per
|
||||
rem card -- AWEUTIL /S does the EMU8000 bring-up and DRAM detect the HMI SOS
|
||||
rem driver relies on; skipping it left the cards uninitialized (silent).
|
||||
rem aweutil /s SKIPPED for now: it verifies the AWE32 GM ROM, which the
|
||||
rem emulated cards lack (hangs in a retry loop) -- restore once the ROM is
|
||||
rem dumped from a real card. diagnose /s kept (passes, sets mixer config).
|
||||
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||
c:\sb16\diagnose /s
|
||||
set BLASTER=A240 I7 D3 H6 P300 T6
|
||||
c:\sb16\diagnose /s
|
||||
set BLASTER=A220 I5 D1 H5 P330 T6
|
||||
set TEMP=c:\
|
||||
rem arena1 city mission (TESTARN.EGG: map=arena1, time=day) with the RIO
|
||||
rem attached; stdout redirected so mission-load progress survives kills.
|
||||
set BT_JOINTS=1
|
||||
set L4VIEWEXT=1
|
||||
set BT_STACK_LOG=1
|
||||
set BT_MECH_LOG=1
|
||||
set BT_PRESS_BALANCE=1
|
||||
set BT_PRESS_VALVE=1
|
||||
set BT_GAUGE_LOG=1
|
||||
set BT_FORCE_THROTTLE=0
|
||||
set BT_FORCE_TURN=0
|
||||
set HEAPSIZE=15000000
|
||||
set L4GAUGE=640x480x16
|
||||
call setenv.bat r s n p
|
||||
32rtm.exe -x
|
||||
BTL4REC.EXE -egg testarn.egg > COM3
|
||||
|
||||
echo GAME-RC=%errorlevel% >> RC.TXT
|
||||
32rtm.exe -u
|
||||
echo ALPHA1-RUN-DONE
|
||||
pause
|
||||
|
||||
@@ -1053,8 +1053,9 @@ Condenser::Condenser(
|
||||
// (RecomputeValves: MoveValve presses, and once at mech spawn) assigns
|
||||
// each condenser its share of the total valve opening.
|
||||
//
|
||||
valveState = 1;
|
||||
coolantFlowScale = 0.0f;
|
||||
coolantFlowScale = 0.0f; // the mech ctor's redistribute seeds the
|
||||
// bank's flow shares (priority born 1 on
|
||||
// the heatable base)
|
||||
refrigerationFactor = subsystem_resource->refrigerationFactor;
|
||||
massScale = refrigerationFactor;
|
||||
|
||||
@@ -1152,24 +1153,32 @@ void
|
||||
return;
|
||||
}
|
||||
|
||||
switch (valveState)
|
||||
//
|
||||
// Binary @004ae464: the ladder steps the HEATABLE-base coolant
|
||||
// priority (+0x1d0 -- the same cell the mech's BalanceCoolant resets
|
||||
// to 1 across the board) and the renormalization is the MECH's
|
||||
// RedistributeCoolantShares (@0049f788), which also refreshes the
|
||||
// conduction flow bridge.
|
||||
//
|
||||
switch (coolantPriority)
|
||||
{
|
||||
case 0: valveState = 1; break;
|
||||
case 1: valveState = 5; break;
|
||||
case 5: valveState = 50; break;
|
||||
case 50: valveState = 0; break;
|
||||
case 0: coolantPriority = 1; break;
|
||||
case 1: coolantPriority = 5; break;
|
||||
case 5: coolantPriority = 50; break;
|
||||
case 50: coolantPriority = 0; break;
|
||||
default: return; // unknown -> no change, no recompute
|
||||
}
|
||||
|
||||
RecomputeValves((Entity *)owner);
|
||||
owner->RedistributeCoolantShares();
|
||||
}
|
||||
|
||||
//
|
||||
//#############################################################################
|
||||
// RecomputeValves -- assign every condenser its coolant flow share
|
||||
// (valve / sum-of-valves) after a valve move (binary @0049f788). All valves
|
||||
// at the spawn default (1) yield equal shares. (The condenser-alarm change
|
||||
// pulse joins with the gauge wave.)
|
||||
// RecomputeValves -- the [T3] conduction-flow bridge (see HEAT.HPP): every
|
||||
// condenser's coolantFlowScale = its priority / the CONDENSER priority
|
||||
// total, numerically identical to the retired valveState math for any
|
||||
// priority pattern. Called from the tail of the mech's
|
||||
// RedistributeCoolantShares.
|
||||
//#############################################################################
|
||||
//
|
||||
void
|
||||
@@ -1186,7 +1195,7 @@ void
|
||||
Subsystem *s = owner_mech->GetSubsystem(i);
|
||||
if (s != NULL && s->IsDerivedFrom(Condenser::ClassDerivations))
|
||||
{
|
||||
total += ((Condenser *)s)->valveState;
|
||||
total += ((Condenser *)s)->coolantPriority;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1197,12 +1206,12 @@ void
|
||||
{
|
||||
Condenser *condenser = (Condenser *)s;
|
||||
condenser->coolantFlowScale = (total > 0)
|
||||
? ((Scalar)condenser->valveState / (Scalar)total)
|
||||
? ((Scalar)condenser->coolantPriority / (Scalar)total)
|
||||
: 0.0f;
|
||||
if (getenv("BT_MECH_LOG"))
|
||||
{
|
||||
DEBUG_STREAM << "[valve] '" << condenser->GetName()
|
||||
<< "' valve=" << condenser->valveState
|
||||
<< "' priority=" << condenser->coolantPriority
|
||||
<< " flow=" << condenser->coolantFlowScale << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,9 +511,15 @@
|
||||
MoveValveMessageHandler(ReceiverDataMessageOf<int> *message);
|
||||
|
||||
//
|
||||
// Recompute every condenser's coolantFlowScale as its share of the
|
||||
// total valve opening (called by MoveValve, and once at mech spawn so
|
||||
// the initial all-1 valves yield equal shares).
|
||||
// [T3 bridge] Recompute every condenser's coolantFlowScale as its
|
||||
// CONDENSER-relative share of the coolant priorities -- the term the
|
||||
// fight-verified conduction model (5.3.12-15 byte curves) consumes.
|
||||
// Since 5.3.124 the ladder cell is the heatable-base coolantPriority
|
||||
// (binary +0x1d0) and the caller is the tail of the mech's
|
||||
// RedistributeCoolantShares, so valve presses, BalanceCoolant and
|
||||
// spawn/Reset all refresh it through ONE path. Retire onto the
|
||||
// real binary conduction cell once the @004ad6f8/pump reads are
|
||||
// decoded.
|
||||
//
|
||||
static void
|
||||
RecomputeValves(Entity *owner_mech);
|
||||
@@ -556,7 +562,6 @@
|
||||
GetCondenserNumber() const { Check(this); return condenserNumber; }
|
||||
|
||||
protected:
|
||||
int valveState;
|
||||
int condenserNumber;
|
||||
Scalar refrigerationFactor;
|
||||
//
|
||||
|
||||
@@ -821,13 +821,6 @@ Mech::Mech(
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Seed the condenser flow shares: every valve spawns at 1, so the initial
|
||||
// recompute yields equal shares across the bank (a MoveValve press
|
||||
// re-shares them).
|
||||
//
|
||||
Condenser::RecomputeValves(this);
|
||||
|
||||
//
|
||||
// Install the per-frame body Performance. Until now the mech ran the base
|
||||
// DoNothingOnce; from here the engine dispatches Mech::Simulate every frame
|
||||
@@ -1030,6 +1023,13 @@ void
|
||||
<< " heatables, total priority " << total
|
||||
<< ", first share " << first_share << endl << flush;
|
||||
}
|
||||
|
||||
//
|
||||
// The conduction-flow bridge (see HEAT.HPP RecomputeValves): the
|
||||
// fight-verified condenser pump consumes a CONDENSER-relative
|
||||
// fraction; refresh it whenever the shares move.
|
||||
//
|
||||
Condenser::RecomputeValves(this);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -694,6 +694,16 @@
|
||||
Scalar
|
||||
CurrentTorsoTwist();
|
||||
|
||||
//
|
||||
// The coolant-share renormalizer (binary @0049f788): share =
|
||||
// priority / total across the heatable chain, blipping each
|
||||
// heatable's balance alarm with the change direction. PUBLIC:
|
||||
// Condenser::MoveValve calls it (binary callers: the 0x16 handler,
|
||||
// the ctor tail, Reset, and the valve stepper @004ae464).
|
||||
//
|
||||
void
|
||||
RedistributeCoolantShares();
|
||||
|
||||
DamageLookupTable*
|
||||
GetDamageLookupTable() const { Check(this); return damageLookupTable; }
|
||||
|
||||
@@ -983,15 +993,6 @@
|
||||
void
|
||||
BalanceCoolantMessageHandler(Receiver::Message *message);
|
||||
|
||||
//
|
||||
// The coolant-share renormalizer (binary @0049f788): share =
|
||||
// priority / total across the heatable chain, blipping each
|
||||
// heatable's balance alarm with the change direction. Callers in
|
||||
// the binary: the 0x16 handler, the ctor tail, Reset, and the
|
||||
// per-subsystem priority stepper (@004ae464, not yet landed).
|
||||
//
|
||||
void
|
||||
RedistributeCoolantShares();
|
||||
void
|
||||
SetStandingCollisionVolume(); // binary @004ac04c... see .CPP
|
||||
void
|
||||
|
||||
@@ -303,16 +303,19 @@ Still to land from the roster:
|
||||
RedistributeCoolantShares @0049f788 + the heatable ctor sweep that
|
||||
populates the heatableSubsystems chain + ctor/Reset redistribute calls;
|
||||
soak: 20 heatables, first share 0.05, ctor + BT_PRESS_BALANCE both
|
||||
renormalize, crash-sig 0). UNIFICATION OWED (5.3.124): the binary's
|
||||
MoveValve handler is @004ae464 registered on the HEATABLE base (the
|
||||
0x50e534 name table in the heatable statics region), novice-locked via
|
||||
mapper+0x274 == 0 (FUN_004ac9c8 -- our NoviceLockout is correct),
|
||||
stepping heatable+0x1d0 through 0 -> 1 -> 5 -> 50 -> 0 then calling the
|
||||
MECH redistribute -- i.e. our Condenser::MoveValve / RecomputeValves /
|
||||
valveState triple is the SAME mechanism scoped to condensers only;
|
||||
retire it onto coolantPriority/RedistributeCoolantShares and re-home
|
||||
the handler on HeatableSubsystem (ValveSetting attribute retargets to
|
||||
the share/priority cells).
|
||||
renormalize, crash-sig 0). UNIFIED 5.3.124: MoveValve
|
||||
steps the heatable-base coolantPriority and calls the mech's
|
||||
RedistributeCoolantShares; valveState and the condenser-local
|
||||
renormalization are retired (RecomputeValves survives only as the [T3]
|
||||
conduction-flow bridge -- the fight-verified pump consumes a
|
||||
CONDENSER-relative fraction, refreshed from the redistribute tail; the
|
||||
ratios are numerically identical to the old math since non-condenser
|
||||
priorities cancel). REGISTRATION CAVEAT: the @0x50e534 name table sits
|
||||
in the HEAT TU statics but its owning class (heatable base vs
|
||||
Condenser) is NOT proven -- our registration stays Condenser id 4 (the
|
||||
live-verified streamed binding); revisit if a non-condenser valve
|
||||
binding ever surfaces. ValveSetting attribute still publishes
|
||||
coolantFlowScale (the displayed fractions are unchanged).
|
||||
* **EjectPilot @0049f854** (head read): gated on payload > 0 AND
|
||||
**mech+0x414** -- THE EFFECTIVENESS-CENSUS CONSUMER FOUND: you can only
|
||||
eject a CRIPPLED mech (@0049fa1c's weapons/coolant/generator/limp
|
||||
|
||||
Reference in New Issue
Block a user