moved file bundle stuff into class Bundle

svn-id: r4671
This commit is contained in:
Paweł Kołodziejski 2002-07-28 15:35:26 +00:00
parent 6dd5de48f9
commit 0b3c263857
9 changed files with 659 additions and 378 deletions

View File

@ -16,7 +16,7 @@ OBJS += util.o newgui.o gui/widget.o gui/dialog.o \
v3/resource_v3.o v4/resource_v4.o scaler.o main.o \
simon/midi.o simon/simon.o simon/simonsys.o simon/simonvga.o \
simon/simondebug.o simon/simonres.o simon/simonitems.o simon/simonverb.o \
sound/mididrv.o config-file.o
sound/mididrv.o config-file.o bundle.o
DISTFILES=$(OBJS:.o=.cpp) Makefile scumm.h scummsys.h stdafx.h stdafx.cpp \
debugrl.h whatsnew.txt readme.txt copying.txt \

535
bundle.cpp Normal file
View File

@ -0,0 +1,535 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2002 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header:
*/
#include "stdafx.h"
#include "scumm.h"
#include "scummsys.h"
#include "bundle.h"
Bundle::Bundle(Scumm * parent) {
_voiceFile = NULL;
_musicFile = NULL;
_scumm = parent;
}
Bundle::~Bundle() {
if (_voiceFile != NULL)
fclose (_voiceFile);
if (_musicFile != NULL)
fclose (_musicFile);
}
int32 Bundle::openVoiceFile(char * filename) {
int32 tag, offset;
if (_voiceFile != NULL) {
return false;
}
_voiceFile = fopen(filename, "rb");
if (_voiceFile == NULL) {
printf("Bundle: Can't open voice bundle file: %s\n", filename);
return false;
}
tag = _scumm->fileReadDwordBE(_voiceFile);
offset = _scumm->fileReadDwordBE(_voiceFile);
_numVoiceFiles = _scumm->fileReadDwordBE(_voiceFile);
_bundleVoiceTable = (BundleAudioTable *) malloc(_numVoiceFiles * sizeof(BundleAudioTable));
_scumm->fileSeek(_voiceFile, offset, SEEK_SET);
for (int32 i = 0; i < _numVoiceFiles; i++) {
char name[13], c;
int32 z = 0;
int32 z2;
for (z2 = 0; z2 < 8; z2++)
if ((c = _scumm->fileReadByte(_voiceFile)) != 0)
name[z++] = c;
name[z++] = '.';
for (z2 = 0; z2 < 4; z2++)
if ((c = _scumm->fileReadByte(_voiceFile)) != 0)
name[z++] = c;
name[z] = '\0';
strcpy(_bundleVoiceTable[i].filename, name);
_bundleVoiceTable[i].offset = _scumm->fileReadDwordBE(_voiceFile);
_bundleVoiceTable[i].size = _scumm->fileReadDwordBE(_voiceFile);
}
return true;
}
int32 Bundle::openMusicFile(char * filename) {
int32 tag, offset;
if (_musicFile != NULL) {
return false;
}
_musicFile = fopen(filename, "rb");
if (_musicFile == NULL) {
printf("Bundle: Can't open music bundle file: %s\n", filename);
return false;
}
tag = _scumm->fileReadDwordBE(_musicFile);
offset = _scumm->fileReadDwordBE(_musicFile);
_numMusicFiles = _scumm->fileReadDwordBE(_musicFile);
_bundleMusicTable = (BundleAudioTable *) malloc(_numMusicFiles * sizeof(BundleAudioTable));
_scumm->fileSeek(_musicFile, offset, SEEK_SET);
for (int32 i = 0; i < _numMusicFiles; i++) {
char name[13], c;
int z = 0;
int z2;
for (z2 = 0;z2 < 8; z2++)
if ((c = _scumm->fileReadByte(_musicFile)) != 0)
name[z++] = c;
name[z++] = '.';
for (z2 = 0;z2 < 4; z2++)
if ((c = _scumm->fileReadByte(_musicFile)) != 0)
name[z++] = c;
name[z] = '\0';
strcpy(_bundleVoiceTable[i].filename, name);
_bundleVoiceTable[i].offset = _scumm->fileReadDwordBE(_musicFile);
_bundleVoiceTable[i].size = _scumm->fileReadDwordBE(_musicFile);
}
return true;
}
int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte * comp_final) {
int32 i, tag, num, final_size, output_size;
byte * comp_input, * comp_output;
if (_voiceFile == NULL) {
printf("Bundle: voice file is not open !\n");
return 0;
}
_scumm->fileSeek(_voiceFile, _bundleVoiceTable[index].offset, SEEK_SET);
tag = _scumm->fileReadDwordBE(_voiceFile);
num = _scumm->fileReadDwordBE(_voiceFile);
_scumm->fileReadDwordBE(_voiceFile);
_scumm->fileReadDwordBE(_voiceFile);
if (tag != MKID_BE('COMP')) {
warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag>>24, tag>>16, tag>>8, tag);
return 0;
}
for (i = 0; i < num; i++) {
_compVoiceTable[i].offset = _scumm->fileReadDwordBE(_voiceFile);
_compVoiceTable[i].size = _scumm->fileReadDwordBE(_voiceFile);
_compVoiceTable[i].codec = _scumm->fileReadDwordBE(_voiceFile);
_scumm->fileReadDwordBE(_voiceFile);
}
final_size = 0;
comp_output = (byte *)malloc(10000);
for (i = 0; i < num; i++) {
comp_input = (byte *)malloc(_compVoiceTable[i].size);
_scumm->fileSeek(_voiceFile, _bundleVoiceTable[index].offset + _compVoiceTable[i].offset, SEEK_SET);
_scumm->fileRead(_voiceFile, comp_input, _compVoiceTable[i].size);
output_size = decompressCodec(_compVoiceTable[i].codec, comp_input, comp_output, _compVoiceTable[i].size);
memcpy((byte *)&comp_final[final_size], comp_output, output_size);
final_size += output_size;
free(comp_input);
}
free(comp_output);
return final_size;
}
int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte * comp_final) {
int32 i, tag, num, final_size;
byte * comp_input;
if (_musicFile == NULL) {
printf("Bundle: music file is not open !\n");
return 0;
}
_scumm->fileSeek(_musicFile, _bundleMusicTable[index].offset, SEEK_SET);
tag = _scumm->fileReadDwordBE(_musicFile);
num = _scumm->fileReadDwordBE(_musicFile);
_scumm->fileReadDwordBE(_musicFile);
_scumm->fileReadDwordBE(_musicFile);
if (tag != MKID_BE('COMP')) {
warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag>>24, tag>>16, tag>>8, tag);
return 0;
}
for (i = 0; i < num; i++) {
_compMusicTable[i].offset = _scumm->fileReadDwordBE(_musicFile);
_compMusicTable[i].size = _scumm->fileReadDwordBE(_musicFile);
_compMusicTable[i].codec = _scumm->fileReadDwordBE(_musicFile);
_scumm->fileReadDwordBE(_musicFile);
}
comp_input = (byte *)malloc(_compMusicTable[i].size);
_scumm->fileSeek(_musicFile, _bundleMusicTable[index].offset + _compMusicTable[i].offset, SEEK_SET);
_scumm->fileRead(_musicFile, comp_input, _compMusicTable[i].size);
final_size = decompressCodec(_compMusicTable[i].codec, comp_input, comp_final, _compMusicTable[i].size);
free(comp_input);
return final_size;
}
int32 Bundle::decompressVoiceSampleByName(char * name, byte * comp_final) {
int32 final_size = 0, i;
if (_voiceFile == NULL) {
printf("Bundle: voice file is not open !\n");
return 0;
}
for (i = 0; i < _numVoiceFiles; i++) {
if (!scumm_stricmp(name, _bundleVoiceTable[i].filename)) {
final_size = decompressVoiceSampleByIndex(i, comp_final);
return final_size;
}
}
return final_size;
}
int32 Bundle::decompressMusicSampleByName(char * name, int32 number, byte * comp_final) {
int32 final_size = 0, i;
if (_voiceFile == NULL) {
printf("Bundle: voice file is not open !\n");
return 0;
}
for (i = 0; i < _numMusicFiles; i++) {
if (!scumm_stricmp(name, _bundleMusicTable[i].filename)) {
final_size = decompressMusicSampleByIndex(i, number, comp_final);
return final_size;
}
}
return final_size;
}
int32 Bundle::getNumberOfMusicSamplesByIndex(int32 index)
{
if (_musicFile == NULL) {
printf("Bundle: music file is not open !\n");
return 0;
}
_scumm->fileSeek(_musicFile, _bundleMusicTable[index].offset, SEEK_SET);
_scumm->fileReadDwordBE(_musicFile);
return _scumm->fileReadDwordBE(_musicFile);
}
int32 Bundle::getNumberOfMusicSamplesByName(char * name) {
int32 number = 0, i;
if (_musicFile == NULL) {
printf("Bundle: music file is not open !\n");
return 0;
}
for (i = 0; i < _numMusicFiles; i++) {
if (!scumm_stricmp(name, _bundleMusicTable[i].filename)) {
number = getNumberOfMusicSamplesByIndex (i);
return number;
}
}
return number;
}
#define NextBit bit = mask & 1; mask >>= 1; if (!--bitsleft) {mask = READ_LE_UINT16(srcptr); srcptr += 2; bitsleft=16;}
int32 Bundle::compDecode(byte * src, byte * dst) {
byte * result, * srcptr = src, * dstptr = dst;
int data, size, bit, bitsleft = 16, mask = READ_LE_UINT16(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;
}
result = dstptr+data;
while (size--)
*dstptr++ = *result++;
}
}
}
#undef NextBit
int32 Bundle::decompressCodec(int32 codec, byte * comp_input, byte * comp_output, int32 input_size) {
int32 output_size = input_size;
int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z;
byte * src, * t_table, * p;
byte t_tmp1, t_tmp2;
switch(codec) {
case 0:
memcpy(comp_input, comp_output, output_size);
break;
case 1:
output_size = compDecode(comp_input, comp_output);
break;
case 2:
output_size = compDecode(comp_input, comp_output);
p = comp_output;
for (z = 1; z < output_size; z++)
p[z] += p[z - 1];
break;
case 3:
output_size = compDecode(comp_input, comp_output);
p = comp_output;
for (z = 2; z < output_size; z++)
p[z] += p[z - 1];
for (z = 1; z < output_size; z++)
p[z] += p[z - 1];
break;
case 4:
output_size = compDecode(comp_input, comp_output);
// FIXME: not implemented yet
memset (comp_output, 0, output_size);
break;
case 5:
output_size = compDecode(comp_input, comp_output);
// FIXME: not implemented yet
memset (comp_output, 0, output_size);
break;
case 6:
output_size = compDecode(comp_input, comp_output);
// FIXME: not implemented yet
memset (comp_output, 0, output_size);
break;
case 10:
output_size = compDecode(comp_input, comp_output);
p = comp_output;
for (z = 2; z < output_size; z++)
p[z] += p[z - 1];
for (z = 1; z < output_size; z++)
p[z] += p[z - 1];
t_table = (byte*)malloc(output_size);
memcpy (t_table, p, output_size);
offset1 = output_size / 3;
offset2 = offset1 * 2;
offset3 = offset2;
src = comp_output;
do {
if (offset1 == 0) break;
offset1--;
offset2 -= 2;
offset3--;
*(t_table + offset2 + 0) = *(src + offset1);
*(t_table + offset2 + 1) = *(src + offset3);
} while(1);
src = comp_output;
length = (output_size * 8) / 12;
k = 0;
if (length > 0)
{
c = -12;
s = 0;
do {
j = length + (k / 2);
if (k & 1) {
r = c / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j + 1);
*(src + r + 2) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
*(src + r + 1) = (*(src + r + 1)) | (t_tmp1 & 0xf0);
} else {
r = s / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j);
*(src + r + 0) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
*(src + r + 1) = ((t_tmp1 & 0xf0) >> 4);
}
s += 12;
k++;
c += 12;
} while (k <= length);
}
free (t_table);
break;
case 11:
output_size = compDecode(comp_input, comp_output);
p = comp_output;
for (z = 2; z < output_size; z++)
p[z] += p[z - 1];
for (z = 1; z < output_size; z++)
p[z] += p[z - 1];
t_table = (byte*)malloc(output_size);
memcpy (t_table, p, output_size);
offset1 = output_size / 3;
offset2 = offset1 * 2;
offset3 = offset2;
src = comp_output;
do {
if (offset1 == 0) break;
offset1--;
offset2 -= 2;
offset3--;
*(t_table + offset2 + 0) = *(src + offset1);
*(t_table + offset2 + 1) = *(src + offset3);
} while(1);
src = comp_output;
length = (output_size * 8) / 12;
k = 1;
c = 0;
s = 12;
t_tmp1 = (*(t_table + length)) >> 4;
*(src) = t_tmp1;
t = length + k;
if (t > k) {
do {
j = length + (k / 2);
if (k & 1) {
r = c / 8;
t_tmp1 = *(t_table + k - 1);
t_tmp2 = *(t_table + j);
*(src + r + 0) = (*(src + r)) | (t_tmp1 & 0xf0);
*(src + r + 1) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
} else {
r = s / 8;
t_tmp1 = *(t_table + k - 1);
t_tmp2 = *(t_table + j);
*(src + r + 0) = (t_tmp1 & 0xf0) >> 4;
*(src + r - 1) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
}
s += 12;
k++;
c += 12;
} while (k < t);
}
free (t_table);
break;
case 12:
output_size = compDecode(comp_input, comp_output);
p = comp_output;
for (z = 2; z < output_size; z++)
p[z] += p[z - 1];
for (z = 1; z < output_size; z++)
p[z] += p[z - 1];
t_table = (byte*)malloc(output_size);
memcpy (t_table, p, output_size);
offset1 = output_size / 3;
offset2 = offset1 * 2;
offset3 = offset2;
src = comp_output;
do {
if (offset1 == 0) break;
offset1--;
offset2 -= 2;
offset3--;
*(t_table + offset2 + 0) = *(src + offset1);
*(t_table + offset2 + 1) = *(src + offset3);
} while(1);
src = comp_output;
length = (output_size * 8) / 12;
k = 0;
c = 0;
s = -12;
*(src) = *(output_size + t_table - 1);
*(src + output_size - 1) = *(t_table + length - 1);
t = length - 1;
if (t > 0) {
do {
j = length + (k / 2);
if (k & 1) {
r = s / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j);
*(src + r + 2) = (*(src + r + 2)) | (t_tmp1 & 0xf0);
*(src + r + 3) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
} else {
r = c / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j);
*(src + r + 2) = (t_tmp1 & 0xf0) >> 4;
*(src + r + 1) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
}
s += 12;
k++;
c += 12;
} while (k < t);
}
free (t_table);
break;
default:
printf("Bundle: Unknown codec %d!\n", codec);
output_size = 0;
break;
}
return output_size;
}

71
bundle.h Normal file
View File

@ -0,0 +1,71 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2002 The ScummVM project
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header:
*/
#ifndef BUNDLE_H
#define BUNDLE_H
#include "scummsys.h"
struct CompTable {
int32 offset;
int32 size;
int32 codec;
};
struct BundleAudioTable {
char filename[13];
int32 size;
int32 offset;
};
class Scumm;
class Bundle {
protected:
private:
int32 compDecode(byte * src, byte * dst);
int32 decompressCodec(int32 codec, byte * comp_input, byte * comp_output, int32 size);
CompTable _compVoiceTable[50];
CompTable _compMusicTable[2500];
FILE * _voiceFile;
FILE * _musicFile;
BundleAudioTable * _bundleVoiceTable;
BundleAudioTable * _bundleMusicTable;
int32 _numVoiceFiles;
int32 _numMusicFiles;
Scumm * _scumm;
public:
Bundle(Scumm * parent);
~Bundle();
int32 openVoiceFile(char * filename);
int32 openMusicFile(char * filename);
int32 decompressVoiceSampleByName(char * name, byte * comp_final);
int32 decompressVoiceSampleByIndex(int32 index, byte * comp_final);
int32 decompressMusicSampleByName(char * name, int32 number, byte * comp_final);
int32 decompressMusicSampleByIndex(int32 index, int32 number, byte * comp_final);
int32 getNumberOfMusicSamplesByIndex(int32 index);
int32 getNumberOfMusicSamplesByName(char * name);
};
#endif

View File

@ -21,7 +21,7 @@ OBJS = actor.o akos.o boxes.o config-file.o costume.o gfx.o object.o resource.o
morphos.o morphos_sound.o morphos_start.o script_v1.o script_v2.o debug.o gui.o \
imuse.o fmopl.o mixer.o mididrv.o debugrl.o vars.o insane.o \
gameDetector.o init.o resource_v3.o resource_v4.o util.o main.o \
$(GUIOBJS) $(SIMONOBJS)
bundle.o $(GUIOBJS) $(SIMONOBJS)
DISTFILES=$(OBJS:.o=.cpp) Makefile scumm.h scummsys.h stdafx.h stdafx.cpp \
windows.cpp debugrl.h whatsnew.txt readme.txt copying.txt \

View File

@ -26,6 +26,7 @@
#include "scummsys.h"
#include "system.h"
#include "sound/mixer.h"
#include "bundle.h"
#define SCUMMVM_VERSION "0.2.2 CVS"
#define SCUMMVM_CVS "2002-07-16"
@ -337,6 +338,7 @@ public:
VerbSlot *_verbs;
ObjectData *_objs;
ScummDebugger *_debugger;
Bundle * _bundle;
struct {
byte mode[rtNumTypes];
@ -765,7 +767,6 @@ 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);

View File

@ -84,6 +84,7 @@ void Scumm::scummInit()
setShake(0);
setupCursor();
_bundle = new Bundle(this);
/* Allocate and initilise actors */
_actors = new Actor[MAX_ACTORS];
for (i = 1, a = getFirstActor(); ++a, i < NUM_ACTORS; i++) {
@ -1582,6 +1583,7 @@ void Scumm::go() {
launch();
setupGUIColors();
mainRun();
delete _bundle;
}

View File

@ -297,6 +297,10 @@ SOURCE=.\boxes.cpp
# End Source File
# Begin Source File
SOURCE=.\bundle.cpp
# End Source File
# Begin Source File
SOURCE=".\config-file.cpp"
# End Source File
# Begin Source File
@ -557,6 +561,10 @@ SOURCE=.\boxes.h
# End Source File
# Begin Source File
SOURCE=.\bundle.h
# End Source File
# Begin Source File
SOURCE=.\cdmusic.h
# End Source File
# Begin Source File

409
sound.cpp
View File

@ -710,46 +710,6 @@ void *Scumm::openSfxFile()
char buf[256];
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) {
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;
int z2;
/* Construct filename */
for (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;
}
/* Try opening the file <_exe_name>.sou first, eg tentacle.sou.
* That way, you can keep .sou files for multiple games in the
* same directory */
@ -817,353 +777,62 @@ bool Scumm::isSfxFinished()
return !_mixer->has_active_channel();
}
#define NextBit bit = mask&1; mask>>=1; if (!--bitsleft) {mask = READ_LE_UINT16(srcptr); srcptr+=2; bitsleft=16;}
int CompDecode(unsigned char *src, unsigned char *dst)
void Scumm::playBundleSound(char *sound)
{
unsigned char *result, *srcptr = src, *dstptr = dst;
int data, size, bit, bitsleft = 16, mask = READ_LE_UINT16(srcptr);
srcptr+=2;
char buf[256];
byte * ptr;
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, *Final;
int outputSize, finalSize;
int32 offset1, offset2, offset3, length, k, c, s, j, r, t;
byte * src, * t_table;
byte t_tmp1, t_tmp2;
fileSeek(_sfxFile, bundle_table[index].offset, SEEK_SET);
int tag = fileReadDwordBE(_sfxFile);
int num = fileReadDwordBE(_sfxFile);
fileReadDwordBE(_sfxFile); fileReadDwordBE(_sfxFile);
// DO -NOT- change these MKID_BE calls to MKID! If you have
// to do so, then your ScummSys.H file is detecting the
// wrong endian. - Ender
if (tag != MKID_BE('COMP')) {
warning("Compressed sound %d invalid (%c%c%c%c)", index, tag>>24, tag>>16, tag>>8, tag);
sprintf(buf, "%s%svoice.bun", _gameDataPath, _exe_name);
_bundle->openVoiceFile((char*)&buf);
ptr = (byte *)malloc(1000000);
if (_bundle->decompressVoiceSampleByName(sound, ptr) == 0) {
delete ptr;
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);
int rate = 22050;
int tag, size = -1;
tag = READ_BE_UINT32(ptr); ptr+=4;
if (tag != MKID_BE('iMUS')) {
warning("Decompression of bundle sound failed");
free(ptr);
return;
}
CompFinal = (unsigned char *)malloc(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 *)malloc(table[i].size);
CompOutput = (unsigned char *)malloc(10000);
fileRead((FILE *)_sfxFile, CompInput, table[i].size);
switch(table[i].codec) {
case 0:
outputSize = table[i].size;
memcpy(&CompOutput[0], &CompInput[0], outputSize);
ptr += 12;
while(tag != MKID_BE('DATA')) {
tag = READ_BE_UINT32(ptr); ptr+=4;
switch(tag) {
case MKID_BE('FRMT'):
size = READ_BE_UINT32(ptr); ptr+=16;
rate = READ_BE_UINT32(ptr); ptr+=8;
break;
case MKID_BE('TEXT'):
case MKID_BE('REGN'):
case MKID_BE('STOP'):
case MKID_BE('JUMP'):
size = READ_BE_UINT32(ptr); ptr+=size+4;
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;
case 10:
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];
t_table = (byte*)malloc(outputSize);
memcpy (t_table, p, outputSize);
offset1 = outputSize / 3;
offset2 = offset1 * 2;
offset3 = offset2;
src = CompOutput;
do {
if (offset1 == 0) break;
offset1--;
offset2 -= 2;
offset3--;
*(t_table + offset2 + 0) = *(src + offset1);
*(t_table + offset2 + 1) = *(src + offset3);
} while(1);
src = CompOutput;
length = (outputSize * 8) / 12;
k = 0;
if (length > 0)
{
c = -12;
s = 0;
do {
j = length + (k / 2);
if (k & 1) {
r = c / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j + 1);
*(src + r + 2) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
*(src + r + 1) = (*(src + r + 1)) | (t_tmp1 & 0xf0);
} else {
r = s / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j);
*(src + r + 0) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
*(src + r + 1) = ((t_tmp1 & 0xf0) >> 4);
}
s += 12;
k++;
c += 12;
} while (k <= length);
}
break;
case 11:
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];
t_table = (byte*)malloc(outputSize);
memcpy (t_table, p, outputSize);
offset1 = outputSize / 3;
offset2 = offset1 * 2;
offset3 = offset2;
src = CompOutput;
do {
if (offset1 == 0) break;
offset1--;
offset2 -= 2;
offset3--;
*(t_table + offset2 + 0) = *(src + offset1);
*(t_table + offset2 + 1) = *(src + offset3);
} while(1);
src = CompOutput;
length = (outputSize * 8) / 12;
k = 1;
c = 0;
s = 12;
t_tmp1 = (*(t_table + length)) >> 4;
*(src) = t_tmp1;
t = length + k;
if (t > k) {
do {
j = length + (k / 2);
if (k & 1) {
r = c / 8;
t_tmp1 = *(t_table + k - 1);
t_tmp2 = *(t_table + j);
*(src + r + 0) = (*(src + r)) | (t_tmp1 & 0xf0);
*(src + r + 1) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
} else {
r = s / 8;
t_tmp1 = *(t_table + k - 1);
t_tmp2 = *(t_table + j);
*(src + r + 0) = (t_tmp1 & 0xf0) >> 4;
*(src + r - 1) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
}
s += 12;
k++;
c += 12;
} while (k < t);
}
break;
case 12:
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];
t_table = (byte*)malloc(outputSize);
memcpy (t_table, p, outputSize);
offset1 = outputSize / 3;
offset2 = offset1 * 2;
offset3 = offset2;
src = CompOutput;
do {
if (offset1 == 0) break;
offset1--;
offset2 -= 2;
offset3--;
*(t_table + offset2 + 0) = *(src + offset1);
*(t_table + offset2 + 1) = *(src + offset3);
} while(1);
src = CompOutput;
length = (outputSize * 8) / 12;
k = 0;
c = 0;
s = -12;
*(src) = *(outputSize + t_table - 1);
*(src + outputSize - 1) = *(t_table + length - 1);
t = length - 1;
if (t > 0) {
do {
j = length + (k / 2);
if (k & 1) {
r = s / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j);
*(src + r + 2) = (*(src + r + 2)) | (t_tmp1 & 0xf0);
*(src + r + 3) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
} else {
r = c / 8;
t_tmp1 = *(t_table + k);
t_tmp2 = *(t_table + j);
*(src + r + 2) = (t_tmp1 & 0xf0) >> 4;
*(src + r + 1) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
}
s += 12;
k++;
c += 12;
} while (k < t);
}
case MKID_BE('DATA'):
size = READ_BE_UINT32(ptr); ptr+=4;
break;
default:
printf("Unknown codec %d!\n", table[i].codec);
outputSize = 0;
break;
error("Unknown sound header %c%c%c%c", tag>>24, tag>>16, tag>>8, tag);
}
memcpy(&CompFinal[finalSize], &CompOutput[0], outputSize);
finalSize+=outputSize;
free(CompInput); CompInput = NULL;
free(CompOutput); CompOutput= NULL;
}
{ /* Parse decompressed data */
int rate = 22050;
byte *ptr = CompFinal;
int tag, size = -1;
tag = READ_BE_UINT32(ptr); ptr+=4;
if (tag != MKID_BE('iMUS')) {
warning("Decompression of bundle sound failed");
free(CompFinal);
return;
}
ptr+=12; /* Skip header */
while(tag != MKID_BE('DATA')) {
tag = READ_BE_UINT32(ptr); ptr+=4;
switch(tag) {
case MKID_BE('FRMT'):
size = READ_BE_UINT32(ptr); ptr+=16;
rate = READ_BE_UINT32(ptr); ptr+=8;
break;
case MKID_BE('TEXT'):
case MKID_BE('REGN'):
case MKID_BE('STOP'):
size = READ_BE_UINT32(ptr); ptr+=size+4;
break;
case MKID_BE('DATA'):
size = READ_BE_UINT32(ptr); ptr+=4;
break;
default:
error("Unknown bundle header %c%c%c%c", tag>>24, tag>>16, tag>>8, tag);
}
}
if (size < 0) {
warning("Decompression of bundle sound failed (no size field)");
free(CompFinal);
return;
}
Final = (unsigned char *)malloc(size);
memcpy(&Final[0], &ptr[0], size);
_mixer->play_raw(NULL, Final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
free(CompFinal);
}
}
void Scumm::playBundleSound(char *sound)
{
if (!_sfxFile) {
warning("playBundleSound: SFX file is not open");
if (size < 0) {
warning("Decompression sound failed (no size field)");
free(ptr);
return;
}
for (int i=0; i < num_sound_effects; i++) {
if (!scumm_stricmp(sound, bundle_table[i].filename)) {
decompressBundleSound(i);
return;
}
}
warning("playBundleSound can't find %s", sound);
byte * final = (byte *)malloc(size);
memcpy(final, ptr, size);
_mixer->play_raw(NULL, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
}
int Scumm::playSfxSound(void *sound, uint32 size, uint rate)

View File

@ -207,9 +207,4 @@ struct MP3OffsetTable { /* Compressed Sound (.SO3) */
int compressed_size;
};
struct BundleAudioTable { /* Dig/CMI .bun audio */
char filename[13];
int size;
int offset;
};
#endif /* _mixer_h_included */