In the z-machine standard is the following remark:
…probably due to a bug in its own code, ‘TLH’ can also generate sound_effect 4 8 sound_effect 4095 2 15
I have a full game script which I use for testing my interpreter. It triggers every valid sound in the game, but these two cases never occur. Does anyone know how to trigger them?
The first one has to do with the rats both by the number and placement in the code, but I still can’t see how it is triggered.
I think the second one must have something to do with saving, restoring, or turning the sound off and on as those are the only locations in the code that don’t use a constant value for the sound number.
Looks like “$so” (action routine $a988) can be used to play an arbirtary sound effect. I think if it’s called with a value of -1, it will try to play 4095, 2, 15 (It divides the number it gets by 16. If it gets -1, ( = $ffff) I think this would result in 4095, with 15 as the remainder, which would result in this call.)
Maybe something like “$so me” or “$so foo” will do this?
Partway there I think. The action routine for $so isn’t called with arguments. The locals are populated from a table. The first word contains the current playing sound or zero. The second word contains a saved sound (in the event sound has been turned off) or zero.
The sound numbers are multiplied by 16 and added to the volume before being stored in the table. To restart a looping sound when sound is turned on or a restore is performed, the sound number is retrieved by dividing the value by 16 and the volume is the value modulus 16.
The question would now be how does -1 end up in table?
You are correct. With signed operations we should end up with sound_effect 0 2 255. Not sure what’s really at work here, but it may be a combination of bug in the code and bug in the interpreter that produced the value sound_effect 4095 2 15. Still no clue how to trigger it.
There does appear to be a -1 in table to start with (edit: confirmed, there is a -1 here at game start), but it looks like it should be overwritten before being read. Even so, if the division and modulus were signed we should never see the 4095/15 values. Hmm…