diff --git a/Descent3/terrain.h b/Descent3/terrain.h index 53c87f65a..1037732ef 100644 --- a/Descent3/terrain.h +++ b/Descent3/terrain.h @@ -213,7 +213,18 @@ extern terrain_tex_segment Terrain_tex_seg[TERRAIN_TEX_WIDTH * TERRAIN_TEX_DEPTH // first object to render after cell has been rendered (only used for SW renderer) extern short Terrain_seg_render_objs[]; +#ifdef RELEASE #define TERRAIN_REGION(x) ((Terrain_seg[0x7FFFFFFF & x].flags & TFM_REGION_MASK) >> 5) +#else // debug(-ish) builds - check if x is valid +inline int TERRAIN_REGION(int x) { + ASSERT(x != -1 && "invalid/unset room number (-1)!"); + // Note: due to the 0x7FFFFFFF mask, terrSegIdx will be >= 0 + int terrSegIdx = 0x7FFFFFFF & x; + // catch other invalid cell/segment numbers than -1 as well + ASSERT((terrSegIdx < TERRAIN_WIDTH * TERRAIN_DEPTH) && "invalid cellnum!"); + return (Terrain_seg[terrSegIdx].flags & TFM_REGION_MASK) >> 5; +} +#endif extern terrain_sky Terrain_sky; diff --git a/sndlib/hlsoundlib.cpp b/sndlib/hlsoundlib.cpp index cdbd9b4a5..2075d87e0 100644 --- a/sndlib/hlsoundlib.cpp +++ b/sndlib/hlsoundlib.cpp @@ -922,6 +922,17 @@ bool hlsSystem::ComputePlayInfo(int sound_obj_index, vector *virtual_pos, vector sound_seg = m_sound_objects[sound_obj_index].m_link_info.pos_info.segnum; } + // sound_seg == -1 (which just means that the roomnum/segnum hasn't been + // initialized to a proper value yet )causes crashes when BOA_INDEX() + // calls TERRAIN_REGION() with that value. (By pure luck on 32bit platforms + // the overflow and truncation will likely use an address that doesn't crash, + // but it's still invalid). At least one case that could cause this was fixed, + // if there are others, the ASSERT should tell us about it + // (and if assertions are disabled, return false to handle this gracefully) + ASSERT(sound_seg != -1 && "invalid (unset) roomnum/segnum!"); + if (sound_seg == -1) + return false; + sound_seg = BOA_INDEX(sound_seg); ear_seg = BOA_INDEX(Viewer_object->roomnum); if (!BOA_IsSoundAudible(sound_seg, ear_seg)) @@ -1079,6 +1090,13 @@ int hlsSystem::Play3dSound(int sound_index, pos_state *cur_pos, object *cur_obj, return -1; if (sound_index >= MAX_SOUNDS || Sounds[sound_index].used == 0) return -1; + // if the position doesn't belong to any valid room or cell, + // all this would fail anyway (in Emulate3dSound() -> ComputePlayInfo()), + // so might as well give up now; furthermore, this prevents m_sound_objects[i] + // from remaining in an half-initialized state below (esp. for looping sounds + // where StopSound() wouldn't be called after Emulate3dSound() returns false) + if (cur_pos->roomnum == -1) + return -1; // initialize sound. Sound_system.CheckAndForceSoundDataAlloc(sound_index); int sample_offset = offset * 22050.0f;