SW: Occasionally missing menu sounds
This possibly became more noticeable after the migration from rand/RAND_MAX to wrand/WRAND_MAX, but it could occur beforehand.
The main reason is the way menu code decides if to play a sound in MNU_OrderCustom
, MNU_UpLevel
or MNU_DoMenu
. Pressing on up/down is a good example of this.
After calling PlaySound
, a voice handle is returned and written to a static local variable. Before calling PlaySound
again at the same spot, it is checked if the sound given by the handle is still active.
Problem is, the voice handle may later get invalidated, or become reused for a totally different sound.
The problem is more noticeable than with DOS version 1.2 due to changes to MV_AllocVoice
. EDuke32's current implementation tries to use MV_MINVOICEHANDLE as the first candidate. In case it's already used, it continues to increment a local voice handle variable in a cyclic manner, until an unused voice handle is found.
The original implementation, however, stores the last assigned voice handle into a global variable named MV_VoiceHandle
. Upon calling MV_AllocVoice
, it begins the scan from the following handle value, rather than MV_MINVOICEHANDLE.
While reverting the behaviors in MV_AllocVoice
should resolve the problem, a proper solution should involve a reset of the handles in SW's menus. This is expected to require moving their definitions out of the function bodies, possibly into a centralized struct.