From Nathan's crash dump: an access violation reading 8093e920, fourteen
minutes into a session, on 4.12.115.
rpl4opt!PatchLevelOfDetail::SetupPatch+0xbb
rpl4opt!Static3DPatchSource::StartImplementation+0x50
rpl4opt!AudioRenderer::ExecuteBackground+0x9e
The faulting instruction is g_buffers[index] with index = 0x20000000 -
536 million - and the array base in eax at 0093e920, which is exactly the
address it died on. So the index was garbage, and the dump says where the
garbage came from: the stack slot holding info.bufferIndex.
PRESET_getSampleInfo builds a SAMPLEINFO to return when it is asked for a
zone the preset does not have. It sets chan, file, implemented and loop -
and not bufferIndex. Every caller tests bufferIndex >= 0 before using it,
so "no such zone" was meant to be rejected there; instead the test read
whatever was on the stack, and passed whenever that happened to be
positive. AL_getBuffer then indexed the array with it, unchecked.
Why it asked for a zone that is not there: the loop runs to
sourceSet.count, which was fixed when the audio source was built, from
whichever level of detail was selected at the time. SetDistance re-picks
the level of detail by distance on the line immediately before SetupPatch
runs, and the zone counts across the recovered banks are nothing like
uniform - of 200 presets, 46 have no zones at all, and the rest run 1 to
4. So a sound that moved far enough to drop to a quieter patch could ask
that patch for a zone it never had. In the dump: count 3, died asking for
zone 2.
Fixed at all three levels, because any one of them alone would have held:
the default carries bufferIndex = -1 so the existing guard works,
AL_getBuffer returns AL_NONE rather than reading past its array, and
SetupPatch asks for no more zones than the patch it is actually using
has.
Verified: the dump's own numbers reproduce arithmetically, and two full
races run clean. The distance-dependent trigger itself was reasoned from
the dump rather than reproduced here - it needs a sound to cross a level
of detail boundary into a shorter patch - so the belt-and-braces.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Imports the current Win32 source for the pod-racing game 'Red Planet',
built on the MUNGA engine and its L4 (Win32/DirectX) platform layer:
- MUNGA / MUNGA_L4: cross-platform engine core and Win32 backend
- RP / RP_L4: Red Planet game logic and Win32 application
- DivLoader, Setup1: asset loader and installer project
- lib, MUNGA_L4/openal, MUNGA_L4/sos: third-party audio dependencies
Removed stale Subversion metadata and added .gitignore/.gitattributes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>