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
This commit is contained in:
James Brown 2002-04-29 08:28:27 +00:00
parent c134803976
commit 5f9bd8343c
5 changed files with 234 additions and 4 deletions

View File

@ -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)

10
scumm.h
View File

@ -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);

160
sound.cpp
View File

@ -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)

View File

@ -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 */

40
sys.cpp
View File

@ -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);