aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTravis Howell2006-04-14 04:22:49 +0000
committerTravis Howell2006-04-14 04:22:49 +0000
commitde0dd94c9cbf44f5dae72c69467fb7d24872eca5 (patch)
treec184aeda3426ddc360c4032c8d34fe22ae018048 /engines
parent53f81b33663d35cdc5b1fed0748501f00579f472 (diff)
downloadscummvm-rg350-de0dd94c9cbf44f5dae72c69467fb7d24872eca5.tar.gz
scummvm-rg350-de0dd94c9cbf44f5dae72c69467fb7d24872eca5.tar.bz2
scummvm-rg350-de0dd94c9cbf44f5dae72c69467fb7d24872eca5.zip
Add support for sound effects in Amiga version of FF and cleanup
svn-id: r21870
Diffstat (limited to 'engines')
-rw-r--r--engines/simon/res.cpp297
-rw-r--r--engines/simon/simon.cpp268
-rw-r--r--engines/simon/simon.h2
-rw-r--r--engines/simon/sound.cpp1
-rw-r--r--engines/simon/vga.cpp4
5 files changed, 300 insertions, 272 deletions
diff --git a/engines/simon/res.cpp b/engines/simon/res.cpp
index 7f307bee86..c9ddd6a27b 100644
--- a/engines/simon/res.cpp
+++ b/engines/simon/res.cpp
@@ -22,9 +22,19 @@
// Resource file routines for Simon1/Simon2
#include "common/stdafx.h"
+
#include "common/file.h"
+
#include "simon/simon.h"
#include "simon/intern.h"
+#include "simon/sound.h"
+
+
+#ifdef USE_ZLIB
+#include <zlib.h>
+#endif
+
+using Common::File;
namespace Simon {
@@ -135,6 +145,35 @@ uint32 SimonEngine::readUint32Wrapper(const void *src) {
return READ_BE_UINT32(src);
}
+void SimonEngine::decompressData(const char *srcName, byte *dst, uint32 offset, uint32 srcSize, uint32 dstSize) {
+#ifdef USE_ZLIB
+ File in;
+ in.open(srcName);
+ if (in.isOpen() == false)
+ error("decompressData: can't open %s", srcName);
+
+ in.seek(offset, SEEK_SET);
+ if (srcSize != dstSize) {
+ byte *srcBuffer = (byte *)malloc(srcSize);
+
+ if (in.read(srcBuffer, srcSize) != srcSize)
+ error("decompressData: read failed");
+
+ unsigned long decompressedSize = dstSize;
+ int result = uncompress(dst, &decompressedSize, srcBuffer, srcSize);
+ if (result != Z_OK)
+ error("decompressData() Zlib uncompress error");
+ free(srcBuffer);
+ } else {
+ if (in.read(dst, dstSize) != dstSize)
+ error("decompressData: read failed");
+ }
+ in.close();
+#else
+ error("Zlib support is required for Amiga and Macintosh versions");
+#endif
+}
+
void SimonEngine::loadOffsets(const char *filename, int number, uint32 &file, uint32 &offset, uint32 &srcSize, uint32 &dstSize) {
Common::File in;
@@ -409,4 +448,262 @@ byte *SimonEngine::readSingleOpcode(Common::File *in, byte *ptr) {
}
}
+// Thanks to Stuart Caie for providing the original
+// C conversion upon which this decruncher is based.
+
+#define SD_GETBIT(var) do { \
+ if (!bits--) { \
+ s -= 4; \
+ if (s < src) \
+ return false; \
+ bb = READ_BE_UINT32(s); \
+ bits = 31; \
+ } \
+ (var) = bb & 1; \
+ bb >>= 1; \
+}while (0)
+
+#define SD_GETBITS(var, nbits) do { \
+ bc = (nbits); \
+ (var) = 0; \
+ while (bc--) { \
+ (var) <<= 1; \
+ SD_GETBIT(bit); \
+ (var) |= bit; \
+ } \
+}while (0)
+
+#define SD_TYPE_LITERAL (0)
+#define SD_TYPE_MATCH (1)
+
+static bool decrunchFile(byte *src, byte *dst, uint32 size) {
+ byte *s = src + size - 4;
+ uint32 destlen = READ_BE_UINT32 (s);
+ uint32 bb, x, y;
+ byte *d = dst + destlen;
+ byte bc, bit, bits, type;
+
+ // Initialize bit buffer.
+ s -= 4;
+ bb = x = READ_BE_UINT32 (s);
+ bits = 0;
+ do {
+ x >>= 1;
+ bits++;
+ } while (x);
+ bits--;
+
+ while (d > dst) {
+ SD_GETBIT(x);
+ if (x) {
+ SD_GETBITS(x, 2);
+ switch (x) {
+ case 0:
+ type = SD_TYPE_MATCH;
+ x = 9;
+ y = 2;
+ break;
+
+ case 1:
+ type = SD_TYPE_MATCH;
+ x = 10;
+ y = 3;
+ break;
+
+ case 2:
+ type = SD_TYPE_MATCH;
+ x = 12;
+ SD_GETBITS(y, 8);
+ break;
+
+ default:
+ type = SD_TYPE_LITERAL;
+ x = 8;
+ y = 8;
+ }
+ } else {
+ SD_GETBIT(x);
+ if (x) {
+ type = SD_TYPE_MATCH;
+ x = 8;
+ y = 1;
+ } else {
+ type = SD_TYPE_LITERAL;
+ x = 3;
+ y = 0;
+ }
+ }
+
+ if (type == SD_TYPE_LITERAL) {
+ SD_GETBITS(x, x);
+ y += x;
+ if ((int)(y + 1) > (d - dst))
+ return false; // Overflow?
+ do {
+ SD_GETBITS(x, 8);
+ *--d = x;
+ } while (y-- > 0);
+ } else {
+ if ((int)(y + 1) > (d - dst))
+ return false; // Overflow?
+ SD_GETBITS(x, x);
+ if ((d + x) > (dst + destlen))
+ return false; // Offset overflow?
+ do {
+ d--;
+ *d = d[x];
+ } while (y-- > 0);
+ }
+ }
+
+ // Successful decrunch.
+ return true;
+}
+
+#undef SD_GETBIT
+#undef SD_GETBITS
+#undef SD_TYPE_LITERAL
+#undef SD_TYPE_MATCH
+
+void SimonEngine::read_vga_from_datfile_1(uint vga_id) {
+ if (getFeatures() & GF_OLD_BUNDLE) {
+ File in;
+ char filename[15];
+ uint32 size;
+ if (vga_id == 23)
+ vga_id = 112;
+ if (vga_id == 328)
+ vga_id = 119;
+
+ if (getPlatform() == Common::kPlatformAmiga) {
+ if (getFeatures() & GF_TALKIE)
+ sprintf(filename, "0%d.out", vga_id);
+ else
+ sprintf(filename, "0%d.pkd", vga_id);
+ } else {
+ sprintf(filename, "0%d.VGA", vga_id);
+ }
+
+ in.open(filename);
+ if (in.isOpen() == false)
+ error("read_vga_from_datfile_1: can't open %s", filename);
+ size = in.size();
+
+ if (getFeatures() & GF_CRUNCHED) {
+ byte *buffer = new byte[size];
+ if (in.read(buffer, size) != size)
+ error("read_vga_from_datfile_1: read failed");
+ decrunchFile(buffer, _vgaBufferPointers[11].vgaFile2, size);
+ delete [] buffer;
+ } else {
+ if (in.read(_vgaBufferPointers[11].vgaFile2, size) != size)
+ error("read_vga_from_datfile_1: read failed");
+ }
+ in.close();
+ } else {
+ uint32 offs_a = _gameOffsetsPtr[vga_id];
+ uint32 size = _gameOffsetsPtr[vga_id + 1] - offs_a;
+
+ resfile_read(_vgaBufferPointers[11].vgaFile2, offs_a, size);
+ }
+}
+
+byte *SimonEngine::read_vga_from_datfile_2(uint id, uint type) {
+ File in;
+ char filename[15];
+ byte *dst = NULL;
+
+ // !!! HACK !!!
+ // allocate more space for text to cope with foreign languages that use
+ // up more space than english. I hope 6400 bytes are enough. This number
+ // is base on: 2 (lines) * 320 (screen width) * 10 (textheight) -- olki
+ int extraBuffer = (id == 5 ? 6400 : 0);
+
+ if (getFeatures() & GF_ZLIBCOMP) {
+ uint32 file, offset, srcSize, dstSize;
+ if (getPlatform() == Common::kPlatformAmiga) {
+ loadOffsets((const char*)"gfxindex.dat", id / 2 * 3 + type, file, offset, srcSize, dstSize);
+ } else {
+ loadOffsets((const char*)"graphics.vga", id / 2 * 3 + type, file, offset, srcSize, dstSize);
+ }
+
+ if (getPlatform() == Common::kPlatformAmiga)
+ sprintf(filename, "GFX%d.VGA", file);
+ else
+ sprintf(filename, "graphics.vga");
+
+ dst = allocBlock(dstSize);
+ decompressData(filename, dst, offset, srcSize, dstSize);
+ return dst;
+ } else if (getFeatures() & GF_OLD_BUNDLE) {
+ uint32 size;
+ if (getPlatform() == Common::kPlatformAmiga) {
+ if (getFeatures() & GF_TALKIE)
+ sprintf(filename, "%.3d%d.out", id / 2, type);
+ else
+ sprintf(filename, "%.3d%d.pkd", id / 2, type);
+ } else {
+ sprintf(filename, "%.3d%d.VGA", id / 2, type);
+ }
+
+ in.open(filename);
+ if (in.isOpen() == false) {
+ if (type == 3)
+ return NULL;
+ else
+ error("read_vga_from_datfile_2: can't open %s", filename);
+ }
+ size = in.size();
+
+ if (getFeatures() & GF_CRUNCHED) {
+ byte *buffer = new byte[size];
+ if (in.read(buffer, size) != size)
+ error("read_vga_from_datfile_2: read failed");
+ dst = allocBlock (READ_BE_UINT32(buffer + size - 4) + extraBuffer);
+ decrunchFile(buffer, dst, size);
+ delete[] buffer;
+ } else {
+ dst = allocBlock(size + extraBuffer);
+ if (in.read(dst, size) != size)
+ error("read_vga_from_datfile_2: read failed");
+ }
+ in.close();
+
+ return dst;
+ } else {
+ uint32 offs_a = _gameOffsetsPtr[id];
+ uint32 size = _gameOffsetsPtr[id + 1] - offs_a;
+
+ dst = allocBlock(size + extraBuffer);
+ resfile_read(dst, offs_a, size);
+
+ return dst;
+ }
+}
+
+void SimonEngine::loadSound(uint sound, uint pan, uint vol, bool ambient) {
+ if (getFeatures() & GF_ZLIBCOMP) {
+ char filename[15];
+
+ uint32 file, offset, srcSize, dstSize;
+ if (getPlatform() == Common::kPlatformAmiga) {
+ loadOffsets((const char*)"sfxindex.dat", _zoneNumber * 22 + sound, file, offset, srcSize, dstSize);
+ } else {
+ loadOffsets((const char*)"effects.wav", _zoneNumber * 22 + sound, file, offset, srcSize, dstSize);
+ }
+
+ if (getPlatform() == Common::kPlatformAmiga)
+ sprintf(filename, "sfx%d.wav", file);
+ else
+ sprintf(filename, "effects.wav");
+
+ byte *dst = (byte *)malloc(dstSize);
+ decompressData(filename, dst, offset, srcSize, dstSize);
+ _sound->playSoundData(dst, sound, pan, vol, ambient);
+ } else {
+ int offs = READ_LE_UINT32(_curSfxFile + sound * 4);
+ _sound->playSoundData(_curSfxFile + offs, sound, pan, vol, ambient);
+ }
+}
+
} // End of namespace Simon
diff --git a/engines/simon/simon.cpp b/engines/simon/simon.cpp
index 25a93935bd..d2fbfa94dd 100644
--- a/engines/simon/simon.cpp
+++ b/engines/simon/simon.cpp
@@ -48,10 +48,6 @@ extern bool isSmartphone(void);
#include "globals.h"
#endif
-#ifdef USE_ZLIB
-#include <zlib.h>
-#endif
-
using Common::File;
namespace Simon {
@@ -3275,270 +3271,6 @@ void SimonEngine::playSpeech(uint speech_id, uint vgaSpriteId) {
}
}
-// Thanks to Stuart Caie for providing the original
-// C conversion upon which this decruncher is based.
-
-#define SD_GETBIT(var) do { \
- if (!bits--) { \
- s -= 4; \
- if (s < src) \
- return false; \
- bb = READ_BE_UINT32(s); \
- bits = 31; \
- } \
- (var) = bb & 1; \
- bb >>= 1; \
-}while (0)
-
-#define SD_GETBITS(var, nbits) do { \
- bc = (nbits); \
- (var) = 0; \
- while (bc--) { \
- (var) <<= 1; \
- SD_GETBIT(bit); \
- (var) |= bit; \
- } \
-}while (0)
-
-#define SD_TYPE_LITERAL (0)
-#define SD_TYPE_MATCH (1)
-
-static bool decrunchFile(byte *src, byte *dst, uint32 size) {
- byte *s = src + size - 4;
- uint32 destlen = READ_BE_UINT32 (s);
- uint32 bb, x, y;
- byte *d = dst + destlen;
- byte bc, bit, bits, type;
-
- // Initialize bit buffer.
- s -= 4;
- bb = x = READ_BE_UINT32 (s);
- bits = 0;
- do {
- x >>= 1;
- bits++;
- } while (x);
- bits--;
-
- while (d > dst) {
- SD_GETBIT(x);
- if (x) {
- SD_GETBITS(x, 2);
- switch (x) {
- case 0:
- type = SD_TYPE_MATCH;
- x = 9;
- y = 2;
- break;
-
- case 1:
- type = SD_TYPE_MATCH;
- x = 10;
- y = 3;
- break;
-
- case 2:
- type = SD_TYPE_MATCH;
- x = 12;
- SD_GETBITS(y, 8);
- break;
-
- default:
- type = SD_TYPE_LITERAL;
- x = 8;
- y = 8;
- }
- } else {
- SD_GETBIT(x);
- if (x) {
- type = SD_TYPE_MATCH;
- x = 8;
- y = 1;
- } else {
- type = SD_TYPE_LITERAL;
- x = 3;
- y = 0;
- }
- }
-
- if (type == SD_TYPE_LITERAL) {
- SD_GETBITS(x, x);
- y += x;
- if ((int)(y + 1) > (d - dst))
- return false; // Overflow?
- do {
- SD_GETBITS(x, 8);
- *--d = x;
- } while (y-- > 0);
- } else {
- if ((int)(y + 1) > (d - dst))
- return false; // Overflow?
- SD_GETBITS(x, x);
- if ((d + x) > (dst + destlen))
- return false; // Offset overflow?
- do {
- d--;
- *d = d[x];
- } while (y-- > 0);
- }
- }
-
- // Successful decrunch.
- return true;
-}
-
-#undef SD_GETBIT
-#undef SD_GETBITS
-#undef SD_TYPE_LITERAL
-#undef SD_TYPE_MATCH
-
-void SimonEngine::read_vga_from_datfile_1(uint vga_id) {
- if (getFeatures() & GF_OLD_BUNDLE) {
- File in;
- char buf[15];
- uint32 size;
- if (vga_id == 23)
- vga_id = 112;
- if (vga_id == 328)
- vga_id = 119;
-
- if (getPlatform() == Common::kPlatformAmiga) {
- if (getFeatures() & GF_TALKIE)
- sprintf(buf, "0%d.out", vga_id);
- else
- sprintf(buf, "0%d.pkd", vga_id);
- } else {
- sprintf(buf, "0%d.VGA", vga_id);
- }
-
- in.open(buf);
- if (in.isOpen() == false)
- error("read_vga_from_datfile_1: can't open %s", buf);
- size = in.size();
-
- if (getFeatures() & GF_CRUNCHED) {
- byte *buffer = new byte[size];
- if (in.read(buffer, size) != size)
- error("read_vga_from_datfile_1: read failed");
- decrunchFile(buffer, _vgaBufferPointers[11].vgaFile2, size);
- delete [] buffer;
- } else {
- if (in.read(_vgaBufferPointers[11].vgaFile2, size) != size)
- error("read_vga_from_datfile_1: read failed");
- }
- in.close();
- } else {
- uint32 offs_a = _gameOffsetsPtr[vga_id];
- uint32 size = _gameOffsetsPtr[vga_id + 1] - offs_a;
-
- resfile_read(_vgaBufferPointers[11].vgaFile2, offs_a, size);
- }
-}
-
-byte *SimonEngine::read_vga_from_datfile_2(uint id, uint type) {
- // !!! HACK !!!
- // allocate more space for text to cope with foreign languages that use
- // up more space than english. I hope 6400 bytes are enough. This number
- // is base on: 2 (lines) * 320 (screen width) * 10 (textheight) -- olki
- int extraBuffer = (id == 5 ? 6400 : 0);
-
- if (getGameType() == GType_FF && getPlatform() != Common::kPlatformWindows) {
-#ifdef USE_ZLIB
- File in;
- char buf[15];
- byte *dst = NULL;
-
- uint32 file, offset, srcSize, dstSize;
- if (getPlatform() == Common::kPlatformAmiga) {
- loadOffsets((const char*)"gfxindex.dat", id / 2 * 3 + type, file, offset, srcSize, dstSize);
- } else {
- loadOffsets((const char*)"graphics.vga", id / 2 * 3 + type, file, offset, srcSize, dstSize);
- }
-
- if (getPlatform() == Common::kPlatformAmiga)
- sprintf(buf, "GFX%d.VGA", file);
- else
- sprintf(buf, "graphics.vga");
-
- in.open(buf);
- if (in.isOpen() == false)
- error("read_vga_from_datfile_2: can't open %s", buf);
-
- dst = allocBlock(dstSize);
-
- in.seek(offset, SEEK_SET);
- if (srcSize != dstSize) {
- byte *srcBuffer = (byte *)malloc(srcSize);
-
- if (in.read(srcBuffer, srcSize) != srcSize)
- error("read_vga_from_datfile_2: read failed");
-
- unsigned long decompressedSize = dstSize;
- int result = uncompress(dst, &decompressedSize, srcBuffer, srcSize);
- if (result != Z_OK)
- error("read_vga_from_datfile_2() Zlib uncompress error");
- free(srcBuffer);
- } else {
- if (in.read(dst, dstSize) != dstSize)
- error("read_vga_from_datfile_2: read failed");
- }
- in.close();
- return dst;
-#else
- error("Zlib support is required for Amiga and Macintosh versions");
- return NULL;
-#endif
- } else if (getFeatures() & GF_OLD_BUNDLE) {
- File in;
- char buf[15];
- uint32 size;
- byte *dst = NULL;
-
- if (getPlatform() == Common::kPlatformAmiga) {
- if (getFeatures() & GF_TALKIE)
- sprintf(buf, "%.3d%d.out", id / 2, type);
- else
- sprintf(buf, "%.3d%d.pkd", id / 2, type);
- } else {
- sprintf(buf, "%.3d%d.VGA", id / 2, type);
- }
-
- in.open(buf);
- if (in.isOpen() == false) {
- if (type == 3)
- return NULL;
- else
- error("read_vga_from_datfile_2: can't open %s", buf);
- }
- size = in.size();
-
- if (getFeatures() & GF_CRUNCHED) {
- byte *buffer = new byte[size];
- if (in.read(buffer, size) != size)
- error("read_vga_from_datfile_2: read failed");
- dst = allocBlock (READ_BE_UINT32(buffer + size - 4) + extraBuffer);
- decrunchFile(buffer, dst, size);
- delete[] buffer;
- } else {
- dst = allocBlock(size + extraBuffer);
- if (in.read(dst, size) != size)
- error("read_vga_from_datfile_2: read failed");
- }
- in.close();
-
- return dst;
- } else {
- uint32 offs_a = _gameOffsetsPtr[id];
- uint32 size = _gameOffsetsPtr[id + 1] - offs_a;
- byte *dst;
-
- dst = allocBlock(size + extraBuffer);
- resfile_read(dst, offs_a, size);
-
- return dst;
- }
-}
-
void SimonEngine::resfile_read(void *dst, uint32 offs, uint32 size) {
_gameFile->seek(offs, SEEK_SET);
if (_gameFile->read(dst, size) != size)
diff --git a/engines/simon/simon.h b/engines/simon/simon.h
index f067a716f8..17025aa856 100644
--- a/engines/simon/simon.h
+++ b/engines/simon/simon.h
@@ -480,7 +480,9 @@ protected:
void readItemChildren(Common::File *in, Item *item, uint tmp);
void readItemFromGamePc(Common::File *in, Item *item);
void loadGamePcFile(const char *filename);
+ void decompressData(const char *srcName, byte *dst, uint32 offset, uint32 srcSize, uint32 dstSize);
void loadOffsets(const char *filename, int number, uint32 &file, uint32 &offset, uint32 &compressedSize, uint32 &size);
+ void loadSound(uint sound, uint pan, uint vol, bool ambient);
void palette_fadeout(uint32 *pal_values, uint num);
diff --git a/engines/simon/sound.cpp b/engines/simon/sound.cpp
index b3a7b54502..88cc32b969 100644
--- a/engines/simon/sound.cpp
+++ b/engines/simon/sound.cpp
@@ -477,7 +477,6 @@ void Sound::playSoundData(byte *soundData, uint sound, uint pan, uint vol, bool
return;
}
- soundData += READ_LE_UINT32(soundData + sound * 4);
int size = READ_LE_UINT32(soundData + 4);
Common::MemoryReadStream stream(soundData, size);
if (!loadWAVFromStream(stream, size, rate, flags)) {
diff --git a/engines/simon/vga.cpp b/engines/simon/vga.cpp
index 940b0ce319..93ab4ebee9 100644
--- a/engines/simon/vga.cpp
+++ b/engines/simon/vga.cpp
@@ -1958,9 +1958,7 @@ void SimonEngine::vc52_playSound() {
if (getGameType() == GType_FF) {
uint16 pan = vcReadNextWord();
uint16 vol = vcReadNextWord();
-
- if (_curSfxFile != NULL)
- _sound->playSoundData(_curSfxFile, sound, pan, vol, ambient);
+ loadSound(sound, pan, vol, ambient);
} else if (getGameType() == GType_SIMON2) {
if (ambient) {
_sound->playAmbient(sound);