aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Brown2002-04-29 08:28:27 +0000
committerJames Brown2002-04-29 08:28:27 +0000
commit5f9bd8343c6362f844bcdb5b207bafde5db75bf3 (patch)
tree986723d40aa03ad5452b7c6308c904bde3492b9f
parentc134803976bcaccd9fe76da14b81962ebc531e81 (diff)
downloadscummvm-rg350-5f9bd8343c6362f844bcdb5b207bafde5db75bf3.tar.gz
scummvm-rg350-5f9bd8343c6362f844bcdb5b207bafde5db75bf3.tar.bz2
scummvm-rg350-5f9bd8343c6362f844bcdb5b207bafde5db75bf3.zip
Small inSANE patch for the dig, and start of Dig Audio support.
It seems to crash using AUTOFREE for some reason. Can someone Valgrind/Purify this for me? svn-id: r4129
-rw-r--r--insane.cpp22
-rw-r--r--scumm.h10
-rw-r--r--sound.cpp160
-rw-r--r--sound/mixer.h6
-rw-r--r--sys.cpp40
5 files changed, 234 insertions, 4 deletions
diff --git a/insane.cpp b/insane.cpp
index eeb9d54ced..b258fbca35 100644
--- a/insane.cpp
+++ b/insane.cpp
@@ -234,7 +234,13 @@ void codec37_proc5(byte *dst, byte *src, int next_offs, int bw, int bh,
i = bw;
do {
code = *src++;
- if (code == 0xFF) {
+ if (code == 0xFD) {
+ // FIXME: Not implemented yet
+ } else if (code == 0xFE) {
+ // FIXME: Not implemented yet
+ src += 4;
+ dst += 4;
+ } else if (code == 0xFF) {
*(uint32 *)(dst + 0) = ((uint32 *)src)[0];
*(uint32 *)(dst + 320) = ((uint32 *)src)[1];
*(uint32 *)(dst + 320 * 2) = ((uint32 *)src)[2];
@@ -592,19 +598,33 @@ void SmushPlayer::setPalette()
{
int i;
+
+
byte palette_colors[1024];
+
byte *p = palette_colors;
+
+
byte *data = _fluPalette;
+
+
for (i = 0; i != 256; i++, data += 3, p+=4) {
+
p[0] = data[0];
+
p[1] = data[1];
+
p[2] = data[2];
+
p[3] = 0;
+
}
+
sm->_system->set_palette(palette_colors, 0, 256);
+
}
void SmushPlayer::startVideo(short int arg, byte *videoFile)
diff --git a/scumm.h b/scumm.h
index 8c01b1a194..ca4d80f863 100644
--- a/scumm.h
+++ b/scumm.h
@@ -1016,9 +1016,11 @@ public:
MP3OffsetTable *offset_table; // SO3 MP3 compressed audio
int num_sound_effects; // SO3 MP3 compressed audio
+ BundleAudioTable *bundle_table; // DIG/CMI bundles
void pauseSounds(bool pause);
bool isSfxFinished();
void playBundleSound(char *sound);
+ void decompressBundleSound(int index);
int playSfxSound(void *sound, uint32 size, uint rate);
int playSfxSound_MP3(void *sound, uint32 size);
void stopSfxSound();
@@ -1333,13 +1335,21 @@ public:
int fileReadByte();
uint32 fileReadDwordLE();
uint32 fileReadDwordBE();
+ int fileReadByte(void *handle);
+ uint32 fileReadDwordLE(void *handle);
+ uint32 fileReadDwordBE(void *handle);
+
#if defined(SCUMM_LITTLE_ENDIAN)
uint32 fileReadDword() { return fileReadDwordLE(); }
+ uint32 fileReadDword(void *handle) { return fileReadDwordLE(handle); }
#elif defined(SCUMM_BIG_ENDIAN)
uint32 fileReadDword() { return fileReadDwordBE(); }
+ uint32 fileReadDword(void *handle) {return fileReadDwordBE(handle);}
#endif
uint fileReadWordLE();
uint fileReadWordBE();
+ uint fileReadWordLE(void *handle);
+ uint fileReadWordBE(void *handle);
static byte *alloc(int size);
static byte *realloc(void *mem, int size);
diff --git a/sound.cpp b/sound.cpp
index d67f0558f9..632c1c58aa 100644
--- a/sound.cpp
+++ b/sound.cpp
@@ -534,10 +534,41 @@ void *Scumm::openSfxFile()
FILE *file = NULL;
if (_gameId == GID_DIG) {
+ int tag, offset, num_files;
+
sprintf(buf, "%s%svoice.bun", _gameDataPath, _exe_name);
file = fopen(buf, "rb");
- if (!file)
+ if (!file) {
warning("Unable to open DIG voice bundle: %s", buf);
+ return NULL;
+ }
+
+ tag = fileReadDwordBE(file);
+ offset = fileReadDwordBE(file);
+ num_files = fileReadDwordBE(file);
+
+ bundle_table = (BundleAudioTable *) malloc(num_files * sizeof(BundleAudioTable));
+ num_sound_effects = num_files;
+ fileSeek(file, offset, SEEK_SET);
+
+ for (int i=0; i < num_files; i++) {
+ char filename[13], c;
+ int z = 0;
+
+ /* Construct filename */
+ for (int z2=0;z2<8; z2++)
+ if ((c = fileReadByte(file)) != 0)
+ filename[z++] = c;
+ filename[z++] = '.';
+ for (z2=0;z2<4;z2++)
+ if ((c = fileReadByte(file)) != 0)
+ filename[z++] = c;
+ filename[z] = '\0';
+ strcpy(bundle_table[i].filename, filename);
+ bundle_table[i].offset = fileReadDwordBE(file);
+ bundle_table[i].size = fileReadDwordBE(file);
+ }
+
return file;
}
@@ -608,9 +639,134 @@ bool Scumm::isSfxFinished()
return !_mixer->has_active_channel();
}
+#define NextBit bit = mask&1; mask>>=1; if (!--bitsleft) {mask = *(unsigned short *)srcptr; srcptr+=2; bitsleft=16;}
+int CompDecode(unsigned char *src, unsigned char *dst)
+{
+ unsigned char *result, *srcptr = src, *dstptr = dst;
+ int data, size, bit, bitsleft = 16, mask = *(unsigned short *)srcptr;
+ srcptr+=2;
+
+ while(1) {
+ NextBit
+ if (bit) {
+ *dstptr++ = *srcptr++;
+ } else {
+ NextBit
+ if (!bit) {
+ NextBit size = bit<<1;
+ NextBit size = (size|bit) + 3;
+ data = *srcptr++ | 0xffffff00;
+ } else {
+ data = *srcptr++;
+ size = *srcptr++;
+
+ data |= 0xfffff000 + ((size & 0xf0) << 4);
+ size = (size & 0x0f) + 3;
+
+ if (size==3)
+ if (((*srcptr++)+1) == 1)
+ return dstptr - dst; /* End of buffer */
+ }
+ result = dstptr+data;
+ while (size--)
+ *dstptr++=*result++;
+ }
+ }
+}
+#undef NextBit
+
+typedef struct {int offset, size, codec;} COMP_table;
+void Scumm::decompressBundleSound(int index) {
+ int i, z;
+ COMP_table table[50];
+ unsigned char *CompInput, *CompOutput, *CompFinal;
+ int outputSize, finalSize;
+
+ fileSeek(_sfxFile, bundle_table[index].offset, SEEK_SET);
+
+ int tag = fileReadDwordBE(_sfxFile);
+ int num = fileReadDwordBE(_sfxFile);
+ fileReadDwordBE(_sfxFile); fileReadDwordBE(_sfxFile);
+
+ if (tag != 'COMP') {
+ warning("Compressed sound %d invalid (%c%c%c%c)", index, tag>>24, tag>>16, tag>>8, tag);
+ return;
+ }
+
+ /* Read compression table */
+ for (i=0; i<num; i++) {
+ table[i].offset = fileReadDwordBE(_sfxFile);
+ table[i].size = fileReadDwordBE(_sfxFile);
+ table[i].codec = fileReadDwordBE(_sfxFile);
+ fileReadDwordBE(_sfxFile);
+ }
+
+ CompFinal = (unsigned char *)alloc(1000000);
+ finalSize = 0;
+
+ /* Decompress data */
+ for (i=0; i<num; i++) {
+ unsigned char *p;
+ fileSeek(_sfxFile, bundle_table[index].offset + table[i].offset, SEEK_SET);
+
+ CompInput = (unsigned char *)alloc(table[i].size);
+ CompOutput = (unsigned char *)alloc(10000);
+
+ fileRead((FILE *)_sfxFile, CompInput, table[i].size);
+
+ switch(table[i].codec) {
+ case 0:
+ warning("Unimplemented bundle codec 1");
+ break;
+
+ case 1:
+ outputSize = CompDecode(&CompInput[0], &CompOutput[0]);
+ break;
+
+ case 2:
+ outputSize = CompDecode(&CompInput[0], &CompOutput[0]);
+ p = CompOutput;
+ for (z = 1; z < outputSize; z++)
+ p[z] += p[z - 1];
+ break;
+
+ case 3:
+ outputSize = CompDecode(&CompInput[0], &CompOutput[0]);
+ p = CompOutput;
+ for (z = 2; z < outputSize; z++)
+ p[z] += p[z - 1];
+ for (z = 1; z < outputSize; z++)
+ p[z] += p[z - 1];
+ break;
+
+ default:
+ printf("Unknown codec %d!\n", table[i].codec);
+ break;
+ }
+
+ memcpy(&CompFinal[finalSize], &CompOutput[0], outputSize);
+ finalSize+=outputSize;
+
+ free(CompInput); CompInput = NULL;
+ free(CompOutput); CompOutput= NULL;
+ }
+
+ /* FIXME: This is nasty. We are actually sending the whole
+ decompressed packet to the mixer.. but the packet
+ actually contains further subblocks! (eg, sync) */
+ _mixer->play_raw(NULL, CompFinal, finalSize,22050, SoundMixer::FLAG_AUTOFREE);
+}
+
void Scumm::playBundleSound(char *sound)
{
- warning("playBundleSound: %s", sound);
+ for (int i=0; i < num_sound_effects; i++) {
+ if (!stricmp(sound, bundle_table[i].filename)) {
+ decompressBundleSound(i);
+ return;
+ }
+ }
+
+ warning("playBundleSound can't find %s", sound);
}
int Scumm::playSfxSound(void *sound, uint32 size, uint rate)
diff --git a/sound/mixer.h b/sound/mixer.h
index 4334dc6ea4..6107d98ece 100644
--- a/sound/mixer.h
+++ b/sound/mixer.h
@@ -167,7 +167,11 @@ struct MP3OffsetTable { /* Compressed Sound (.SO3) */
int compressed_size;
};
-
+struct BundleAudioTable {
+ char filename[13];
+ int size;
+ int offset;
+};
#if 0
typedef enum { /* Mixer types */
diff --git a/sys.cpp b/sys.cpp
index 5c5d23e431..7ac1db91d6 100644
--- a/sys.cpp
+++ b/sys.cpp
@@ -161,6 +161,46 @@ uint32 Scumm::fileReadDwordBE()
return (b << 16) | a;
}
+/* Overloaded versions */
+int Scumm::fileReadByte(void *handle)
+{
+ byte b;
+
+ if (fread(&b, 1, 1, (FILE *) handle) != 1) {
+ clearerr((FILE *) handle);
+ _fileReadFailed = true;
+ }
+ return b ^ _encbyte;
+}
+
+uint Scumm::fileReadWordLE(void *handle)
+{
+ uint a = fileReadByte(handle);
+ uint b = fileReadByte(handle);
+ return a | (b << 8);
+}
+
+uint32 Scumm::fileReadDwordLE(void *handle)
+{
+ uint a = fileReadWordLE(handle);
+ uint b = fileReadWordLE(handle);
+ return (b << 16) | a;
+}
+
+uint Scumm::fileReadWordBE(void *handle)
+{
+ uint b = fileReadByte(handle);
+ uint a = fileReadByte(handle);
+ return a | (b << 8);
+}
+
+uint32 Scumm::fileReadDwordBE(void *handle)
+{
+ uint b = fileReadWordBE(handle);
+ uint a = fileReadWordBE(handle);
+ return (b << 16) | a;
+}
+
byte *Scumm::alloc(int size)
{
byte *me = (byte *)::calloc(size + 4, 1);