From e69507cc28ad5de480f12d9116624b7795738ece Mon Sep 17 00:00:00 2001 From: Colin Snover Date: Fri, 16 Jun 2017 12:57:24 -0500 Subject: SCI32: Implement engine-accurate DPCM overflow behaviour DPCM decompression algorithms in SSCI operate directly on 8- and 16-bit registers, so any sample that ends up being out-of-range during decompression gets wrapped by the CPU, not clipped. This does not fix any known problem with AUD files, but there are some VMDs (e.g. GK2 5280.VMD) which are known to contain OOR samples. Making this code more accurate should prevent trouble with any other similar files. --- engines/sci/sound/decoders/sol.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'engines') diff --git a/engines/sci/sound/decoders/sol.cpp b/engines/sci/sound/decoders/sol.cpp index 121ffe400a..4b366ce9f4 100644 --- a/engines/sci/sound/decoders/sol.cpp +++ b/engines/sci/sound/decoders/sol.cpp @@ -54,13 +54,21 @@ static const byte tableDPCM8[8] = { 0, 1, 2, 3, 6, 10, 15, 21 }; * Decompresses one channel of 16-bit DPCM compressed audio. */ static void deDPCM16Channel(int16 *out, int16 &sample, uint8 delta) { + int32 nextSample = sample; if (delta & 0x80) { - sample -= tableDPCM16[delta & 0x7f]; + nextSample -= tableDPCM16[delta & 0x7f]; } else { - sample += tableDPCM16[delta]; + nextSample += tableDPCM16[delta]; } - sample = CLIP(sample, -32768, 32767); - *out = sample; + + // Emulating x86 16-bit signed register overflow + if (nextSample > 32767) { + nextSample -= 65536; + } else if (nextSample < -32768) { + nextSample += 65536; + } + + *out = sample = nextSample; } /** @@ -101,7 +109,6 @@ static void deDPCM8Nibble(int16 *out, uint8 &sample, uint8 delta) { } else { sample += tableDPCM8[delta & 7]; } - sample = CLIP(sample, 0, 255); *out = ((lastSample + sample) << 7) ^ 0x8000; } -- cgit v1.2.3