From d2640462cb9e816e72816b3b8ad8635484f873da Mon Sep 17 00:00:00 2001 From: Kp Date: Sat, 26 Oct 2019 23:13:14 +0000 Subject: [PATCH] Backport D2's Dont_start_sound_objects to D1 Descent 2 has a hack, present as far back as I can trace, that suppresses starting sounds during level load. The original reason was not recorded, but this hack has the useful side effect that it avoids using uninitialized data when set_sound_sources tries to use a Viewer that has not been reset for the objects of the new level. Descent 1 lacks this hack, so an invalid Viewer is used, which may trigger a valptridx trap if the undefined data has an invalid segment number, and could cause memory corruption in builds which do not validate the segment index. The valptridx trap: ``` terminate called after throwing an instance of 'valptridx::index_range_exception' what(): similar/main/digiobj.cpp:389: invalid index used in array subscript: base=(nil) size=9000 index=65021 ``` The backtrace leading to the trap: ``` d1x::digi_link_sound_common (viewer=..., so=..., pos=..., forever=, max_volume=, max_distance=..., soundnum=42, segnum=...) at similar/main/digiobj.cpp:389 0x00005555555a4e2d in d1x::digi_link_sound_to_pos2 (vcobjptr=..., max_distance=..., max_volume=32768, forever=1, pos=..., sidenum=4, segnum=..., org_soundnum=121) at similar/main/digiobj.cpp:483 d1x::digi_link_sound_to_pos (soundnum=soundnum@entry=121, segnum=..., sidenum=sidenum@entry=4, pos=..., forever=forever@entry=1, max_volume=32768) at similar/main/digiobj.cpp:490 0x00005555555c140d in d1x::set_sound_sources (vcsegptridx=..., vcvertptr=...) at similar/main/gameseq.cpp:817 d1x::LoadLevel (level_num=, page_in_textures=1) at similar/main/gameseq.cpp:1022 0x00005555555c2654 in d1x::StartNewLevelSub (level_num=-1, page_in_textures=) at similar/main/gameseq.cpp:1865 ``` Backport this hack into Descent 1. Ultimately, the hack should go away and data should be loaded in an order that does not access undefined memory. Reported-by: Spacecpp --- common/main/digi.h | 3 +-- similar/main/digiobj.cpp | 6 ------ similar/main/gameseq.cpp | 5 +---- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/common/main/digi.h b/common/main/digi.h index 0979e1854..85df179ba 100644 --- a/common/main/digi.h +++ b/common/main/digi.h @@ -138,9 +138,8 @@ extern void digi_start_sound_queued( short soundnum, fix volume ); extern int digi_volume; #if defined(DXX_BUILD_DESCENT_I) extern int digi_sample_rate; -#elif defined(DXX_BUILD_DESCENT_II) -extern int Dont_start_sound_objects; #endif +extern int Dont_start_sound_objects; extern int SoundQ_channel; void digi_select_system(); diff --git a/similar/main/digiobj.cpp b/similar/main/digiobj.cpp index 9c72f4a32..af163c431 100644 --- a/similar/main/digiobj.cpp +++ b/similar/main/digiobj.cpp @@ -333,10 +333,8 @@ static void digi_unpause_looping_sound() digi_play_sample_looping_sub(); } -#if defined(DXX_BUILD_DESCENT_II) //hack to not start object when loading level int Dont_start_sound_objects = 0; -#endif static void digi_start_sound_object(sound_object &s) { @@ -346,10 +344,8 @@ static void digi_start_sound_object(sound_object &s) if ( s.volume <= 0 ) return; -#if defined(DXX_BUILD_DESCENT_II) if ( Dont_start_sound_objects ) return; -#endif // only use up to half the sound channels for "permanent" sounts if ((s.flags & SOF_PERMANENT) && (N_active_sound_objects >= max(1, digi_max_channels / 4))) @@ -378,13 +374,11 @@ static void digi_link_sound_common(const object_base &viewer, sound_object &so, so.max_distance = max_distance; so.volume = 0; so.pan = 0; -#if defined(DXX_BUILD_DESCENT_II) if (Dont_start_sound_objects) { //started at level start so.flags |= SOF_PERMANENT; so.channel = -1; } else -#endif { digi_get_sound_loc(viewer.orient, viewer.pos, segnum.absolute_sibling(viewer.segnum), pos, segnum, so.max_volume, diff --git a/similar/main/gameseq.cpp b/similar/main/gameseq.cpp index 2c2050c48..922b8b91f 100644 --- a/similar/main/gameseq.cpp +++ b/similar/main/gameseq.cpp @@ -760,8 +760,8 @@ static void set_sound_sources(fvcsegptridx &vcsegptridx, fvcvertptr &vcvertptr) #if defined(DXX_BUILD_DESCENT_II) auto &Walls = LevelUniqueWallSubsystemState.Walls; auto &vcwallptr = Walls.vcptr; - Dont_start_sound_objects = 1; #endif + Dont_start_sound_objects = 1; const auto get_eclip_for_tmap = [](const d_level_unique_tmap_info_state::TmapInfo_array &TmapInfo, const unique_side &side) { if (const auto tm2 = side.tmap_num2) @@ -819,10 +819,7 @@ static void set_sound_sources(fvcsegptridx &vcsegptridx, fvcvertptr &vcvertptr) } } } - -#if defined(DXX_BUILD_DESCENT_II) Dont_start_sound_objects = 0; -#endif } constexpr fix flash_dist=fl2f(.9);