I’m looking for some feedback.
EDIT: Sorry - For clarity this is an interpreter written as a binary library. I am not writing an Inform library.
I went back and looked at how I handled sound for The Lurking Horror (TLH) in my z-machine interpreter library and am now questioning whether I took the best approach.
The TLH problem:
At two different points near the end of the game TLH plays two sounds in quick succession, i.e. without an intervening read instruction. In the first case the second play instruction is quickly followed by a stop instruction for the second sound. In the other case by a stop 0 instruction (which Standard 1.1 has defined to mean ‘stop all’ instead of Infocom’s interpretation of ‘stop most recent sound’).
On a slow enough interpreter, i.e. from the 1980’s, you can hear both sounds, but otherwise the instructions happen too quickly unless care has been taken by the interpreter’s author to deal with it. Assuming I don’t want to code anything specific to TLH, and instead handle arbitrary z-code that does crazy things: I see two viable approaches, each with some minor variations possible.
Approach 1 Synchronous:
Within a turn, when a second sound is played before the first has finished, pause the z-machine until one iteration of the first sound completes, then play the second sound and resume execution. A stop instruction issued for a sound started this turn also results in this wait state until the sound to be stopped has completed at least one iteration.
Approach 2 Asynchronous:
Within a turn, when a second sound is played before the first has finished, set the first sound to stop after one iteration and queue the second to play when the first has finished. Proceed running normally. Any stop instruction issued for a sound started this turn reduces the iterations to play to a single iteration but does not stop the sound.
Pros of Approach 1:
Plays at least one iteration of any sound regardless of machine speed (On a slow machine more iterations may happen). Play and Stop instruction behavior is straightforward and can handle more than two sounds played in quick succession (not needed for TLH).
Cons of Approach 1:
Will almost certainly cause a noticeable delay in appearance and responsiveness of the input prompt when this happens as the machine waits for the sound to complete.
Pros of Approach 2:
Plays at least one iteration of any sound regardless of machine speed (On a slow machine more iterations may happen). The Z-machine does not pause and input appears as quickly and responsively as normal.
Cons of Approach 2:
Without a larger or dynamic queue size, handling more than two sounds played in quick succession (not needed for TLH) would likely need to be considered an error, leading to a discrepancy in behavior between fast and slow machines. Play and Stop instruction logic is slightly more complex, including needing special handling for Stop instructions that happen after the next input but refer to the first or second sound from the previous turn, e.g. A stop command for the queued sound comes in after the next turn starts, but the sound hasn’t actually begun playing yet.
This may all seem silly since there are no z-code files that do anything beyond what TLH does, but I’d like to know my code can deal with it anyway.