diff --git a/insane.cpp b/insane.cpp index eeb9d54ced9..b258fbca35a 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 8c01b1a1940..ca4d80f8639 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 d67f0558f99..632c1c58aac 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; iplay_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 4334dc6ea4d..6107d98ece6 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 5c5d23e4312..7ac1db91d6e 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);