aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Haisch2009-01-25 01:58:16 +0000
committerBenjamin Haisch2009-01-25 01:58:16 +0000
commit6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4 (patch)
treeb7db06751dff7c16b5dc238ca68b26dae716bf26
parentb93db9f30f9dca7398f56c3be1a5f04cbdbd3e8d (diff)
downloadscummvm-rg350-6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4.tar.gz
scummvm-rg350-6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4.tar.bz2
scummvm-rg350-6297561f7caefe5a7f5bf65ec8ca5e3eaa87f2c4.zip
- Implemented sound decompression for Manhole EGA
svn-id: r36048
-rw-r--r--engines/made/made.cpp19
-rw-r--r--engines/made/resource.cpp12
-rw-r--r--engines/made/sound.cpp107
-rw-r--r--engines/made/sound.h19
4 files changed, 147 insertions, 10 deletions
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index a7be211ada..e225f41c17 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -112,7 +112,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_soundRate = 11025;
break;
case GID_MANHOLE:
- _soundRate = getVersion() == 2 ? 11025 : 4000;
+ _soundRate = 11025;
break;
case GID_LGOP2:
_soundRate = 8000;
@@ -249,6 +249,23 @@ void MadeEngine::handleEvents() {
Common::Error MadeEngine::go() {
+/*
+ byte source[200000], dest[500000];
+
+ int size;
+ FILE *f = fopen("Q:\\OldGames\\scummvm\\00000003.snd", "rb");
+ size = fread(source, 1, 200000, f);
+ fclose(f);
+
+ ManholeEgaSoundDecompressor dec;
+ dec.decompress(source, dest, size);
+
+ FILE *x = fopen("Q:\\OldGames\\scummvm\\test.0", "wb");
+ fwrite(dest, size * 4, 1, x);
+ fclose(x);
+
+ return Common::kNoError;
+*/
resetAllTimers();
if (getGameID() == GID_RTZ) {
diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp
index c3c9195204..b44c2d100c 100644
--- a/engines/made/resource.cpp
+++ b/engines/made/resource.cpp
@@ -265,16 +265,10 @@ Audio::AudioStream *SoundResource::getAudioStream(int soundRate, bool loop) {
}
void SoundResourceV1::load(byte *source, int size) {
- // TODO: This is all wrong. Seems like the sound is compressed
- // but where is the compression info? (chunks, chunk size)
-
- _soundSize = size;
+ _soundSize = size * 4;
_soundData = new byte[_soundSize];
-
- // TODO: We set the audio to silent for now
- //memcpy(_soundData, source, _soundSize);
- memset(_soundData, 0x80, _soundSize);
-
+ ManholeEgaSoundDecompressor dec;
+ dec.decompress(source, _soundData, size);
}
/* MenuResource */
diff --git a/engines/made/sound.cpp b/engines/made/sound.cpp
index 9c59232dd2..5af514d3bc 100644
--- a/engines/made/sound.cpp
+++ b/engines/made/sound.cpp
@@ -31,6 +31,113 @@
namespace Made {
+void ManholeEgaSoundDecompressor::decompress(byte *source, byte *dest, uint32 size) {
+ /* Some kind of ADPCM compression. I hope this works on BE machines. */
+ int newmode;
+ _source = source;
+ _dest = dest;
+ _size = size;
+ _bitBuffer = 0;
+ _bitsLeft = 0;
+ _writeFlag = false;
+ _eof = false;
+ _sample1 = 0x80000;
+ _sample2 = 0x800000;
+ _sample3 = 0x800000;
+ _sample4 = 0x800000;
+ _mode = getBit();
+ while (!_eof) {
+ update1();
+ update3();
+ update0();
+ newmode = getBit();
+ if (_eof)
+ break;
+ if (newmode == _mode) {
+ update1();
+ update3();
+ do {
+ update0();
+ newmode = getBit();
+ if (_eof || newmode != _mode)
+ break;
+ update2();
+ update3();
+ } while (1);
+ }
+ _mode = newmode;
+ }
+}
+
+int ManholeEgaSoundDecompressor::getBit() {
+ if (_bitsLeft == 0) {
+ if (_size == 0) {
+ _eof = true;
+ return 0;
+ }
+ _bitBuffer = READ_BE_UINT16(_source);
+ _source += 2;
+ _bitsLeft = 16;
+ _size -= 2;
+ }
+ int temp = _bitBuffer & 0x8000;
+ _bitBuffer <<= 1;
+ _bitsLeft--;
+ return temp;
+}
+
+void ManholeEgaSoundDecompressor::update0() {
+ SWAP(_sample1, _sample3);
+ if (_sample2 & 0x80000000) {
+ _sample2 -= (_sample2 >> 8) | 0xFF000000;
+ } else {
+ _sample2 -= _sample2 >> 8;
+ }
+ _sample2 += 0x8000;
+ if (_sample2 & 0x80000000) {
+ _sample2 = 0;
+ } else if ((_sample2 & 0xFFFF0000) > 0x00FF0000) {
+ _sample2 = 0xFF0000;
+ }
+ _sample1 += _sample2;
+ _sample1 >>= 1;
+ _sample1 -= _sample4;
+ _sample1 >>= 2;
+ _sample4 += _sample1;
+ if (_writeFlag) {
+ *_dest++ = (_sample4 & 0xFF0000) >> 16;
+ }
+ _writeFlag = !_writeFlag;
+ _sample1 = _sample2;
+ SWAP(_sample1, _sample3);
+}
+
+void ManholeEgaSoundDecompressor::update1() {
+ if (_sample1 & 0x80000000) {
+ _sample1 -= (_sample1 >> 8) | 0xFF000000;
+ } else {
+ _sample1 -= _sample1 >> 8;
+ }
+ _sample1 += 500;
+}
+
+void ManholeEgaSoundDecompressor::update2() {
+ uint32 temp = (_sample1 >> 6) | ((_sample1 & 0xFF) << 27) | ((_sample1 & 0xC0) >> 5);
+ if (_sample1 & 0x80000000) {
+ _sample1 += temp | 0xFC000000;
+ } else {
+ _sample1 += temp & 0x03FFFFFF;
+ }
+ _sample1 += 500;
+}
+
+void ManholeEgaSoundDecompressor::update3() {
+ if (_mode)
+ _sample2 -= _sample1;
+ else
+ _sample2 += _sample1;
+}
+
void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray) {
int16 prevSample = 0, workSample = 0;
diff --git a/engines/made/sound.h b/engines/made/sound.h
index 02e046ed2e..eb2157bd42 100644
--- a/engines/made/sound.h
+++ b/engines/made/sound.h
@@ -33,6 +33,25 @@
namespace Made {
+class ManholeEgaSoundDecompressor {
+public:
+ void decompress(byte *source, byte *dest, uint32 size);
+protected:
+ byte *_source, *_dest;
+ uint32 _size;
+ uint16 _bitBuffer;
+ int _bitsLeft;
+ int32 _sample1, _sample2, _sample3, _sample4;
+ bool _writeFlag;
+ bool _eof;
+ int _mode;
+ int getBit();
+ void update0();
+ void update1();
+ void update2();
+ void update3();
+};
+
struct SoundEnergyItem {
uint32 position;
byte energy;