diff --git a/MUNGA_L4/L4AUDLVL.cpp b/MUNGA_L4/L4AUDLVL.cpp index d5ef095..5f3fb4d 100644 --- a/MUNGA_L4/L4AUDLVL.cpp +++ b/MUNGA_L4/L4AUDLVL.cpp @@ -128,8 +128,25 @@ void // #endif SAMPLEINFO info; + // + // Ask this patch for no more zones than it has. + // + // sourceSet.count 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 immediately before this + // runs (see Static3DPatchSource::StartImplementation), and a + // further-away patch can have fewer zones than the one the source was + // sized for - so the count outruns this patch's zone list, and the + // zones past the end come back as "no such zone". + // + int zone_count = PRESET_getNumSamples(bankID,patchID); + if (zone_count > sourceSet.count) + { + zone_count = sourceSet.count; + } + //Attach buffers - for (int i=0; i < sourceSet.count; i++) + for (int i=0; i < zone_count; i++) { info = PRESET_getSampleInfo(bankID,patchID,i); if (info.bufferIndex >= 0) diff --git a/MUNGA_L4/L4AUDRES.cpp b/MUNGA_L4/L4AUDRES.cpp index eb79704..b6bbdf1 100644 --- a/MUNGA_L4/L4AUDRES.cpp +++ b/MUNGA_L4/L4AUDRES.cpp @@ -871,6 +871,16 @@ void ALuint AL_getBuffer(int index) { + // + // 0 is AL_NONE - "no buffer" - which alSourcei accepts and which detaches + // the source rather than crashing. An index that is out of range means a + // zone that does not exist, and the only thing an unchecked lookup here + // can do about it is read whatever lies past the array. + // + if (g_buffers == NULL || index < 0 || index >= g_numBuffers) + { + return 0; + } return g_buffers[index]; } diff --git a/MUNGA_L4/WTPresets.cpp b/MUNGA_L4/WTPresets.cpp index 047f309..a3fe3ff 100644 --- a/MUNGA_L4/WTPresets.cpp +++ b/MUNGA_L4/WTPresets.cpp @@ -32,6 +32,13 @@ SAMPLEINFO PRESET_getSampleInfo(int bank, int preset, int sampleInd) default.file = ""; default.implemented = false; default.loop = SampleLoop::LoopAtWill; + // + // -1 = no buffer. Every caller tests bufferIndex >= 0 before using it as + // an index, and this one field was being left as whatever was on the + // stack - so "this zone does not exist" read as a real buffer whenever + // the garbage happened to be positive, and indexed g_buffers with it. + // + default.bufferIndex = -1; if (sampleInd < 0 || sampleInd >= allPresets[bank-1][preset].sampleNum) {