diff --git a/context/project-overview.md b/context/project-overview.md index 0c87aa1..bffac6d 100644 --- a/context/project-overview.md +++ b/context/project-overview.md @@ -42,7 +42,9 @@ fire → damage → destroy → respawn** single-player loop (task #52). **2-nod end-to-end** — replication, cross-pod targeting/damage/kill, beam visuals, replicant gait (tasks #46-#51, [[multiplayer]]). All 8 cockpit canopies are authentic + the horizontal-FOV fix (task #55, [[cockpit-view]]); the Gyroscope is live byte-exact with hit-bounce (task #56); the **gauge system -is complete** ([[gauges-hud]]). The engine/renderer/HAL/audio are done (WinTesla); the active work +is complete** ([[gauges-hud]]). The engine/renderer/HAL are done (WinTesla); AUDIO is the exception — +the OpenAL engine is ported + now on by default (2026-07-15) but the soundbank + game triggering are +unbuilt, so it's still SILENT (see [[wintesla-port]] Audio). The active work is reconstructing each BT subsystem's authentic behavior from the binary. Remaining: pod-LAN config, Mech-level update records, per-subsystem waves. [T2] diff --git a/context/wintesla-port.md b/context/wintesla-port.md index 84378bc..2f89e6c 100644 --- a/context/wintesla-port.md +++ b/context/wintesla-port.md @@ -16,7 +16,19 @@ on top of it. Full detail: `docs/PROGRESS_LOG.md §5b, §8`. ## What WinTesla already did (do NOT rebuild) - **Renderer bypass: DONE** — `MUNGA_L4/L4D3D.cpp` + `DXUtils` replace libDPL / the IG board with Direct3D9. No `libdpl.lib` in the tree. (The early from-scratch D3D9 viewer was retired and removed.) [T1] -- **Audio: DONE** — OpenAL + libsndfile replacing the HMI "SOS" engine. [T1] +- **Audio: ENGINE ported but NOT wired end-to-end** [T2, corrected 2026-07-15 — the old "DONE" + was wrong]. OpenAL + libsndfile replace the HMI "SOS" engine, and the renderer→device→buffer→ + source→play chain IS all implemented (`L4AUDRND`/`L4AUDRES`/`L4AUDLVL`; `PatchLevelOfDetail::PlayNote` + really calls `alSourcePlay`). But there were THREE gaps, so the game is SILENT: (1) it was gated + OFF — `BTL4Application::MakeAudioRenderer` returned NULL unless the pod's `AWE_FRONT`/`AWE_REAR` + sound-card env vars were set (dead on modern HW; the real "no sound" root cause). **RELAXED + 2026-07-15 to default-on** (`BT_NO_AUDIO=1` disables); the OpenAL device now opens. (2) The + soundbank preset table `allPresets[2][100]` (btstubs.cpp) is a zero-init **STUB** — no + sound-event→sample mapping, so 0 buffers load. The sample DATA exists in `AUDIO1/2.RES` + (`EnginePower01`, `LaserAFire01-03`, `LaserASustain`, …) but the map is gone (not in the decomp). + (3) The reconstructed game **never creates AudioEntities** — no triggering on weapon fire / steps / + engine. So enabling real audio = reconstruct the soundbank + wire the game triggers (a proper audio + wave). Diagnostic harness: `BT_AUDIO_LOG` traces the chain (Initialize → device → buffers → play). - **L4 HAL on Windows + the VS build system: DONE.** [T1] - **Red Planet game logic: COMPLETE & buildable** — `VTV/VTVMPPR/WEAPSYS/...`. RP is at/near playable. [T1] - **Multiplayer: the DOS `NETNUB` driver is already replaced by a ~3.5k-line WinSock2 TCP diff --git a/engine/MUNGA_L4/L4AUDLVL.cpp b/engine/MUNGA_L4/L4AUDLVL.cpp index 35baa6b..2c3aaee 100644 --- a/engine/MUNGA_L4/L4AUDLVL.cpp +++ b/engine/MUNGA_L4/L4AUDLVL.cpp @@ -1,3 +1,4 @@ +#include #include "mungal4.h" #pragma hdrstop @@ -140,6 +141,7 @@ void if (sourceState == AL_INITIAL) { alSourcei(sourceSet.sources[i],AL_BUFFER,AL_getBuffer(info.bufferIndex)); + { static int s_a=0; if (getenv("BT_AUDIO_LOG") && s_a++<8) DEBUG_STREAM << "[audio] SetupPatch attach bank=" << (int)bankID << " patch=" << (int)patchID << " buf=" << info.bufferIndex << "\n" << std::flush; } alSourcei(sourceSet.sources[i],AL_SOURCE_RELATIVE,AL_TRUE); AudioRenderer *render = application->GetAudioRenderer(); @@ -188,6 +190,7 @@ void PatchLevelOfDetail::PlayNote(SourceSet sourceSet) if (state != AL_PLAYING) { alSourcePlay(sourceSet.sources[i]); + { static int s_p=0; if (getenv("BT_AUDIO_LOG") && s_p++<8) DEBUG_STREAM << "[audio] PlayNote alSourcePlay src=" << sourceSet.sources[i] << "\n" << std::flush; } } ALenum error = alGetError(); diff --git a/engine/MUNGA_L4/L4AUDRES.cpp b/engine/MUNGA_L4/L4AUDRES.cpp index 4244eb6..8152a4e 100644 --- a/engine/MUNGA_L4/L4AUDRES.cpp +++ b/engine/MUNGA_L4/L4AUDRES.cpp @@ -1,3 +1,4 @@ +#include #include "mungal4.h" #pragma hdrstop @@ -558,6 +559,7 @@ void alGetError(); g_buffers = new ALuint[g_numBuffers]; alGenBuffers(g_numBuffers,g_buffers); + if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] alGenBuffers count=" << g_numBuffers << "\n" << std::flush; ALenum error; if ((error = alGetError()) != AL_NO_ERROR) { diff --git a/engine/MUNGA_L4/L4AUDRND.cpp b/engine/MUNGA_L4/L4AUDRND.cpp index 9521f87..dfa8196 100644 --- a/engine/MUNGA_L4/L4AUDRND.cpp +++ b/engine/MUNGA_L4/L4AUDRND.cpp @@ -1,3 +1,4 @@ +#include #include "mungal4.h" #pragma hdrstop @@ -98,6 +99,7 @@ void L4AudioRenderer::Initialize() { Check(this); + if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] L4AudioRenderer::Initialize ENTERED\n" << std::flush; // //---------------------------------------------------------------------- @@ -133,6 +135,7 @@ void NotationFile notation_file(audio_file_name); Check(¬ation_file); + if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] notation file opened; about to read scalars\n" << std::flush; // //---------------------------------------------------------------------- @@ -379,6 +382,11 @@ void { ALCcontext *context = alcCreateContext(device,NULL); alcMakeContextCurrent(context); + if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] OpenAL device OPENED + context current\n" << std::flush; + } + else + { + if (getenv("BT_AUDIO_LOG")) DEBUG_STREAM << "[audio] OpenAL device FAILED to open (alcOpenDevice NULL)\n" << std::flush; } // diff --git a/game/reconstructed/btl4app.cpp b/game/reconstructed/btl4app.cpp index 88efd1a..1b6a2c9 100644 --- a/game/reconstructed/btl4app.cpp +++ b/game/reconstructed/btl4app.cpp @@ -266,7 +266,15 @@ BTL4Application::SharedData char *front_card = getenv(AWE_FRONT_ENV_VAR); // FUN_004dee74 char *rear_card = getenv(AWE_REAR_ENV_VAR); - if (front_card == NULL || rear_card == NULL) + // AUTHENTIC 1995 gate: the pod carried TWO AWE32 cards (front/rear) and + // audio was OFF unless both AWE_FRONT/AWE_REAR were set. Those cards don't + // exist on modern hardware, so this check silenced audio on every machine + // (root cause of "no sound" -- the renderer was never created). + // MODERNIZED (task #50, 2026-07-15): default audio ON through the WinTesla + // OpenAL renderer (the OS default output device). BT_NO_AUDIO=1 restores + // the silent/no-renderer behavior; the AWE vars still force it on too. + (void)front_card; (void)rear_card; + if (getenv("BT_NO_AUDIO")) { return NULL; }