diff --git a/engine/MUNGA/AUDCMP.cpp b/engine/MUNGA/AUDCMP.cpp index 50224e0..1e20e18 100644 --- a/engine/MUNGA/AUDCMP.cpp +++ b/engine/MUNGA/AUDCMP.cpp @@ -1,3 +1,4 @@ +#include #include "munga.h" #pragma hdrstop @@ -793,6 +794,9 @@ void } Check(audioComponentSocket.GetCurrent()); + if (getenv("BT_AUDIO_SPATIAL") && mult_value <= 0.0f) { static int s_mx=0; if (s_mx++<300) + DEBUG_STREAM << "[mult0] mult=" << (void*)this << " -> tgt=" << (void*)audioComponentSocket.GetCurrent() + << " in[" << index << "]=" << control_value << " product=" << mult_value << "\n" << std::flush; } audioComponentSocket.GetCurrent()->ReceiveControl( outputControlID, mult_value diff --git a/engine/MUNGA/AUDSRC.cpp b/engine/MUNGA/AUDSRC.cpp index 6991519..765a4f2 100644 --- a/engine/MUNGA/AUDSRC.cpp +++ b/engine/MUNGA/AUDSRC.cpp @@ -663,6 +663,8 @@ void Check(this); Clamp(control_value, MinAudioVolume, MaxAudioVolume); volumeScale = control_value / (MaxAudioVolume - MinAudioVolume); + if (getenv("BT_AUDIO_SPATIAL")) { static int s_vh=0; if (s_vh++<300) + DEBUG_STREAM << "[volset] src=" << (void*)this << " vol=" << volumeScale << "\n" << std::flush; } } // diff --git a/engine/MUNGA/AUDWTHR.h b/engine/MUNGA/AUDWTHR.h index 6e5974c..c36f706 100644 --- a/engine/MUNGA/AUDWTHR.h +++ b/engine/MUNGA/AUDWTHR.h @@ -305,6 +305,14 @@ template MemoryStream_Read(stream, &controlValueOff); triggerOn = False; + + if (getenv("BT_ATTRBIND_LOG")) { static int s_tc=0; if (s_tc++<80) + DEBUG_STREAM << "[trigcfg] attrPtr=" << (void*)attributePointer + << " thresh=" << attributeValueThreshold + << " inverse=" << (int)inverseTrigger + << " onID=" << (int)controlIDOn << "/" << controlValueOn + << " offID=" << (int)controlIDOff << "/" << controlValueOff + << "\n" << std::flush; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -631,10 +639,8 @@ template void Check(&audioComponentSocket); Check(audioComponentSocket.GetCurrent()); if (getenv("BT_AUDIO_SPATIAL") && control_value <= 0.0f) { - static int s_sc=0; if (s_sc++<40) - DEBUG_STREAM << "[spatial] scale->0 attrPtr=" << (void*)attributePointer - << " raw=" << current_value << " ctlID=" << (int)controlID - << " ctl=" << control_value << "\n" << std::flush; } + static int s_sc=0; if (s_sc++<400) + DEBUG_STREAM << "[spatial] scale->0 attrPtr=" << (void*)attributePointer << " comp=" << (void*)audioComponentSocket.GetCurrent() << " raw=" << current_value << " ctlID=" << (int)controlID << " ctl=" << control_value << " aB=[" << attributeValueBoundary1 << "," << attributeValueBoundary2 << "]" << " cB=[" << controlValueBoundary1 << "," << controlValueBoundary2 << "]\n" << std::flush; } audioComponentSocket.GetCurrent()->ReceiveControl( controlID, control_value @@ -731,6 +737,12 @@ template MemoryStream_Read(stream, &attributeMatchValue); MemoryStream_Read(stream, &controlID); MemoryStream_Read(stream, &controlValue); + + if (getenv("BT_ATTRBIND_LOG")) { static int s_mc=0; if (s_mc++<80) + DEBUG_STREAM << "[matchcfg] attrPtr=" << (void*)attributePointer + << " match=" << attributeMatchValue + << " ctlID=" << (int)controlID << " ctlVal=" << controlValue + << "\n" << std::flush; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -777,6 +789,10 @@ template void if (current_value == attributeMatchValue) { + if (getenv("BT_AUDIO_SPATIAL")) { static int s_mf=0; if (s_mf++<40) + DEBUG_STREAM << "[matchfire] attrPtr=" << (void*)attributePointer << " comp=" << (void*)audioComponentSocket.GetCurrent() << " compClass=" << (int)audioComponentSocket.GetCurrent()->GetClassID() + << " val=" << current_value << " -> ctl " << (int)controlID + << "/" << controlValue << "\n" << std::flush; } Check(&audioComponentSocket); Check(audioComponentSocket.GetCurrent()); #if 1 diff --git a/engine/MUNGA/WATCHER.h b/engine/MUNGA/WATCHER.h index 374739d..256894a 100644 --- a/engine/MUNGA/WATCHER.h +++ b/engine/MUNGA/WATCHER.h @@ -266,6 +266,13 @@ template void if (getenv("BT_AUDIO_SPATIAL")) { // poll-rate probe: total watcher polls + change events static long s_polls=0; if ((++s_polls % 2000)==0) DEBUG_STREAM << "[watchpoll] total polls=" << s_polls << "\n" << std::flush; + extern void *g_btFootStepAddr; // DIAG: uncapped tracer on THE footstep watcher + if ((void*)attributePointer == g_btFootStepAddr) { + static long s_fsp=0; + if ((++s_fsp % 120)==0 || !(currentValue == *(T*)attributePointer)) + DEBUG_STREAM << "[fswatch] poll#" << s_fsp << " cur=" << (int)*(int*)¤tValue + << " mem=" << *(int*)attributePointer << "\n" << std::flush; + } } if (!(currentValue == *(T*)attributePointer)) { diff --git a/engine/MUNGA_L4/L4AUDLVL.cpp b/engine/MUNGA_L4/L4AUDLVL.cpp index ee4116e..efcaac4 100644 --- a/engine/MUNGA_L4/L4AUDLVL.cpp +++ b/engine/MUNGA_L4/L4AUDLVL.cpp @@ -138,6 +138,11 @@ void ALenum sourceState; alGetSourcei(sourceSet.sources[i], AL_SOURCE_STATE, &sourceState); + if (getenv("BT_AUDIO_SPATIAL")) { static int s_se=0; if (s_se++<200) + DEBUG_STREAM << "[audio] SetupPatch ENTRY bank=" << (int)bankID << " patch=" << (int)patchID << " src=" << sourceSet.sources[i] + << " file=" << (info.file?info.file:"?") + << " state=" << sourceState << " (INITIAL=" << AL_INITIAL << ")" << "\n" << std::flush; } + if (sourceState == AL_INITIAL) { alSourcei(sourceSet.sources[i],AL_BUFFER,AL_getBuffer(info.bufferIndex)); diff --git a/game/reconstructed/btstubs.cpp b/game/reconstructed/btstubs.cpp index 5d358ff..946a7b2 100644 --- a/game/reconstructed/btstubs.cpp +++ b/game/reconstructed/btstubs.cpp @@ -398,3 +398,7 @@ void VideoComponent::ReceiveControl(VideoControlID /*control_ID*/, Scalar /*cont void VideoComponent::Execute() { } + +// DIAG (audio footstep chain): the live &mech->footStep, exported so the +// engine watcher poll can trace THE footstep watcher without per-run pointers. +void *g_btFootStepAddr = 0; diff --git a/game/reconstructed/mech.cpp b/game/reconstructed/mech.cpp index b4cf913..2def1f2 100644 --- a/game/reconstructed/mech.cpp +++ b/game/reconstructed/mech.cpp @@ -925,6 +925,7 @@ Mech::Mech( collisionTemporaryState = 0; footStep = 0; // FootStep pulse (audio trigger) footStepDecay = 0; + { extern void *g_btFootStepAddr; g_btFootStepAddr = &footStep; } // DIAG: watcher-poll tracer target radarRange = 1000.0f; // radar display scale (SetTargetRange is stubbed; // 1km default zoom so contacts within ~500m show on // the radar, vs the config maximum_range=4000 edge) diff --git a/game/reconstructed/mech.hpp b/game/reconstructed/mech.hpp index 265e73a..94f46c6 100644 --- a/game/reconstructed/mech.hpp +++ b/game/reconstructed/mech.hpp @@ -847,8 +847,12 @@ protected: // stride clip (each walk/run/reverse alternation == one foot plant) and the // per-frame motion tick decays it back to 0 a few frames later, giving one // clean rising edge per step. [T2] - int footStep; // the Logical the trigger polls (1 = contact) - int footStepDecay; // frames until the pulse clears + int footStep; // the Logical the matcher polls (1 = contact) + int footStepDecay; // MILLISECONDS until the pulse clears (time-based: + // the watcher polls ~10Hz and strides re-pulse ~2Hz, + // so the pulse must be one poll-period wide but end + // well before the next stride -- match=1 fires on the + // CHANGE to 1, so footStep must return to 0 in between) // Radar/map gauge attributes (binary @0x404/0x408/0x40c/0x3f8). The map // widget reads position/angle as POINTERS into the mech's live origin, so // radarLinearPosition/radarAngularPosition point at localOrigin.{linear, diff --git a/game/reconstructed/mech2.cpp b/game/reconstructed/mech2.cpp index 388bb0f..82efecd 100644 --- a/game/reconstructed/mech2.cpp +++ b/game/reconstructed/mech2.cpp @@ -261,9 +261,9 @@ void if (state >= 1 && state <= 0x17) { footStep = 1; - footStepDecay = 20; // ~1/3s: outlives the watcher poll cadence (still < stride period) + footStepDecay = 150; // ms: ~1.5 poll periods ON, OFF well before the next stride if (getenv("BT_AUDIO_LOG")) { static int s_fs=0; if (s_fs++<40) - DEBUG_STREAM << "[audio] footstep pulse (clip " << state << ") addr=" << (void*)&footStep << "\n" << std::flush; } + DEBUG_STREAM << "[audio] footstep pulse (clip " << state << ") leftover=" << footStepDecay << "\n" << std::flush; } } } diff --git a/game/reconstructed/mech4.cpp b/game/reconstructed/mech4.cpp index 925fc93..685975c 100644 --- a/game/reconstructed/mech4.cpp +++ b/game/reconstructed/mech4.cpp @@ -292,10 +292,8 @@ Logical // Choose this frame's forward-cycle slew rate. forwardCycleRate = airborneSelect ? airborneCycleRate : groundCycleRate; // 0x344<-0x5bc/0x5b8 - // FootStep pulse decay (see SetBodyAnimation): clear the contact flag a few - // frames after the plant so the AudioLogicalTrigger re-arms for the next step. - if (footStepDecay > 0 && --footStepDecay == 0) - footStep = 0; + // (FootStep pulse decay moved to PerformAndWatch -- this integrator does not + // run on the current gait path, so a decay here never fired.) if (IsDisabled()) // FUN_0049fb54 { @@ -5205,6 +5203,21 @@ void // (AudioLogicalTrigger FootStep, AudioMotionScale/Trigger LocalVelocity, ...) // never executed -- only the PUSHED StateIndicator watchers fired. That's // why footsteps/motion-scaled sounds were silent while state sounds worked. [T0] + // FootStep pulse decay (see SetBodyAnimation): clear the contact flag ~150ms + // after the plant so the FootStep matcher (fires on the CHANGE to 1) sees a 0 + // before the next stride re-pulses. Lives HERE (not IntegrateMotion, which the + // current gait path never calls) so it provably ticks every mech frame, right + // before the watcher poll below reads it. Time-based -- tick-rate immune. + if (footStepDecay > 0) + { + footStepDecay -= (int)(dt * 1000.0f); + if (footStepDecay <= 0) + { + footStepDecay = 0; + footStep = 0; + } + } + if (getenv("BT_AUDIO_LOG")) { static int s_wd=0; if ((s_wd++ % 300)==0) DEBUG_STREAM << "[audio] mech watcher poll: delayed=" << (int)AreWatchersDelayed() << " audioWatchers=" << DebugAudioWatcherCount() << " simFlags=0x" << std::hex << (unsigned)simulationFlags << std::dec