Skip to content

Commit

Permalink
SCI32: Implement engine-accurate DPCM overflow behaviour
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
csnover committed Jun 17, 2017
1 parent 7334f33 commit e69507c
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions engines/sci/sound/decoders/sol.cpp
Expand Up @@ -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<int16>(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;
}

/**
Expand Down Expand Up @@ -101,7 +109,6 @@ static void deDPCM8Nibble(int16 *out, uint8 &sample, uint8 delta) {
} else {
sample += tableDPCM8[delta & 7];
}
sample = CLIP<byte>(sample, 0, 255);
*out = ((lastSample + sample) << 7) ^ 0x8000;
}

Expand Down

0 comments on commit e69507c

Please sign in to comment.