moved to Sound class

svn-id: r4744
This commit is contained in:
Paweł Kołodziejski 2002-08-14 20:43:56 +00:00
parent f2faf9063b
commit 105f966c6a
17 changed files with 386 additions and 362 deletions

View file

@ -738,7 +738,7 @@ void Scumm::stopTalk()
{ {
int act; int act;
stopTalkSound(); _sound->stopTalkSound();
_haveMsg = 0; _haveMsg = 0;
_talkDelay = 0; _talkDelay = 0;
@ -787,7 +787,7 @@ void Scumm::playActorSounds()
a = derefActor(i); a = derefActor(i);
if (a->cost.animCounter2 && a->isInCurrentRoom() && a->sound) { if (a->cost.animCounter2 && a->isInCurrentRoom() && a->sound) {
_currentScript = 0xFF; _currentScript = 0xFF;
addSoundToQueue(a->sound[0]); _sound->addSoundToQueue(a->sound[0]);
for (i = 1; i < NUM_ACTORS; i++) { for (i = 1; i < NUM_ACTORS; i++) {
a = derefActor(i); a = derefActor(i);
a->cost.animCounter2 = 0; a->cost.animCounter2 = 0;

View file

@ -1409,7 +1409,7 @@ byte LoadedCostume::increaseAnim(Actor *a, int slot)
} else { } else {
if (_vm->_features & GF_AFTER_V6) { if (_vm->_features & GF_AFTER_V6) {
if (nc >= 0x71 && nc <= 0x78) { if (nc >= 0x71 && nc <= 0x78) {
_vm->addSoundToQueue2(a->sound[nc - 0x71]); _vm->_sound->addSoundToQueue2(a->sound[nc - 0x71]);
if (a->cost.start[slot] != end) if (a->cost.start[slot] != end)
continue; continue;
} }

32
gui.cpp
View file

@ -615,18 +615,18 @@ void Gui::handleSoundDialogCommand(int cmd)
if (cmd == 50) { if (cmd == 50) {
close(); close();
} else if (cmd == 40) { } else if (cmd == 40) {
_s->_sound_volume_master = _gui_variables[0]; // Master _s->_sound->_sound_volume_master = _gui_variables[0]; // Master
_s->_sound_volume_music = _gui_variables[1]; // Music _s->_sound->_sound_volume_music = _gui_variables[1]; // Music
_s->_sound_volume_sfx = _gui_variables[2]; // SFX _s->_sound->_sound_volume_sfx = _gui_variables[2]; // SFX
_s->_imuse->set_music_volume(_s->_sound_volume_music); _s->_imuse->set_music_volume(_s->_sound->_sound_volume_music);
_s->_imuse->set_master_volume(_s->_sound_volume_master); _s->_imuse->set_master_volume(_s->_sound->_sound_volume_master);
_s->_mixer->set_volume(_s->_sound_volume_sfx); _s->_mixer->set_volume(_s->_sound->_sound_volume_sfx);
_s->_mixer->set_music_volume(_s->_sound_volume_music); _s->_mixer->set_music_volume(_s->_sound->_sound_volume_music);
scummcfg->set("master_volume", _s->_sound_volume_master); scummcfg->set("master_volume", _s->_sound->_sound_volume_master);
scummcfg->set("music_volume", _s->_sound_volume_music); scummcfg->set("music_volume", _s->_sound->_sound_volume_music);
scummcfg->set("sfx_volume", _s->_sound_volume_sfx); scummcfg->set("sfx_volume", _s->_sound->_sound_volume_sfx);
scummcfg->flush(); scummcfg->flush();
close(); close();
@ -650,9 +650,9 @@ void Gui::handleOptionsDialogCommand(int cmd)
switch (cmd) { switch (cmd) {
case 1: case 1:
_widgets[0] = sound_dialog; _widgets[0] = sound_dialog;
_gui_variables[0] = _s->_sound_volume_master; _gui_variables[0] = _s->_sound->_sound_volume_master;
_gui_variables[1] = _s->_sound_volume_music; _gui_variables[1] = _s->_sound->_sound_volume_music;
_gui_variables[2] = _s->_sound_volume_sfx; _gui_variables[2] = _s->_sound->_sound_volume_sfx;
_active = true; _active = true;
_cur_page = 0; _cur_page = 0;
_dialog = SOUND_DIALOG; _dialog = SOUND_DIALOG;
@ -1052,8 +1052,8 @@ void Gui::loop()
if (_active && !_inited) { if (_active && !_inited) {
_inited = true; _inited = true;
draw(0, 200); // was 100 draw(0, 200); // was 100
_old_soundsPaused = _s->_soundsPaused; _old_soundsPaused = _s->_sound->_soundsPaused;
_s->pauseSounds(true); _s->_sound->pauseSounds(true);
// Backup old cursor // Backup old cursor
memcpy(_old_grabbedCursor, _s->_grabbedCursor, sizeof(_old_grabbedCursor)); memcpy(_old_grabbedCursor, _s->_grabbedCursor, sizeof(_old_grabbedCursor));
@ -1112,7 +1112,7 @@ void Gui::close()
_s->_system->show_mouse(_old_cursor_mode); _s->_system->show_mouse(_old_cursor_mode);
_s->pauseSounds(_old_soundsPaused); _s->_sound->pauseSounds(_old_soundsPaused);
_active = false; _active = false;
_inited = false; _inited = false;

View file

@ -447,9 +447,9 @@ void SoundDialog::open()
Dialog::open(); Dialog::open();
// get current variables // get current variables
_soundVolumeMaster = scumm->_sound_volume_master; _soundVolumeMaster = scumm->_sound->_sound_volume_master;
_soundVolumeMusic = scumm->_sound_volume_music; _soundVolumeMusic = scumm->_sound->_sound_volume_music;
_soundVolumeSfx = scumm->_sound_volume_sfx; _soundVolumeSfx = scumm->_sound->_sound_volume_sfx;
masterVolumeSlider->setValue(_soundVolumeMaster); masterVolumeSlider->setValue(_soundVolumeMaster);
musicVolumeSlider->setValue(_soundVolumeMusic); musicVolumeSlider->setValue(_soundVolumeMusic);
@ -483,9 +483,9 @@ void SoundDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data)
Scumm *scumm = _gui->getScumm(); Scumm *scumm = _gui->getScumm();
// FIXME: Look at Fingolfins comments in Gui::handleSoundDialogCommand(), gui.cpp // FIXME: Look at Fingolfins comments in Gui::handleSoundDialogCommand(), gui.cpp
scumm->_sound_volume_master = _soundVolumeMaster; // Master scumm->_sound->_sound_volume_master = _soundVolumeMaster; // Master
scumm->_sound_volume_music = _soundVolumeMusic; // Music scumm->_sound->_sound_volume_music = _soundVolumeMusic; // Music
scumm->_sound_volume_sfx = _soundVolumeSfx; // SFX scumm->_sound->_sound_volume_sfx = _soundVolumeSfx; // SFX
scumm->_imuse->set_music_volume(_soundVolumeMusic); scumm->_imuse->set_music_volume(_soundVolumeMusic);
scumm->_imuse->set_master_volume(_soundVolumeMaster); scumm->_imuse->set_master_volume(_soundVolumeMaster);

View file

@ -41,7 +41,7 @@ SmushPlayer::SmushPlayer(Scumm * parent) {
SmushPlayer::~SmushPlayer() { SmushPlayer::~SmushPlayer() {
} }
static void smush_handler (Scumm * _scumm) { static void smush_handler (Scumm * scumm) {
h_sp->update(); h_sp->update();
} }
@ -1430,7 +1430,7 @@ void SmushPlayer::startVideo(short int arg, byte *videoFile) {
memset (&pcd37, 0, sizeof (PersistentCodecData37)); memset (&pcd37, 0, sizeof (PersistentCodecData37));
_scumm->pauseBundleMusic(true); _scumm->_sound->pauseBundleMusic(true);
init(); init();
openFile(videoFile); openFile(videoFile);
@ -1505,5 +1505,5 @@ void SmushPlayer::startVideo(short int arg, byte *videoFile) {
_scumm->_insaneState = 0; _scumm->_insaneState = 0;
_scumm->exitCutscene(); _scumm->exitCutscene();
_scumm->pauseBundleMusic(false); _scumm->_sound->pauseBundleMusic(false);
} }

View file

@ -202,9 +202,9 @@ game settings!
g_scumm = scumm; g_scumm = scumm;
g_system = scumm->_system; g_system = scumm->_system;
g_mixer = &scumm->_mixer[0]; g_mixer = &scumm->_mixer[0];
scumm->_sound_volume_master = 0; scumm->_sound->_sound_volume_master = 0;
scumm->_sound_volume_music = detector._music_volume; scumm->_sound->_sound_volume_music = detector._music_volume;
scumm->_sound_volume_sfx = detector._sfx_volume; scumm->_sound->_sound_volume_sfx = detector._sfx_volume;
/* bind to Gui */ /* bind to Gui */
scumm->_gui = &gui; scumm->_gui = &gui;

View file

@ -200,8 +200,8 @@ void NewGui::loop()
void NewGui::saveState() void NewGui::saveState()
{ {
_old_soundsPaused = _s->_soundsPaused; _old_soundsPaused = _s->_sound->_soundsPaused;
_s->pauseSounds(true); _s->_sound->pauseSounds(true);
// Backup old cursor // Backup old cursor
memcpy(_old_grabbedCursor, _s->_grabbedCursor, sizeof(_old_grabbedCursor)); memcpy(_old_grabbedCursor, _s->_grabbedCursor, sizeof(_old_grabbedCursor));
@ -231,7 +231,7 @@ void NewGui::restoreState()
_s->_system->show_mouse(_old_cursor_mode); _s->_system->show_mouse(_old_cursor_mode);
_s->pauseSounds(_old_soundsPaused); _s->_sound->pauseSounds(_old_soundsPaused);
} }
void NewGui::openDialog(Dialog *dialog) void NewGui::openDialog(Dialog *dialog)

View file

@ -1030,7 +1030,7 @@ bool Scumm::isResourceInUse(int type, int i)
case rtCostume: case rtCostume:
return isCostumeInUse(i); return isCostumeInUse(i);
case rtSound: case rtSound:
return isSoundRunning(i) != 0; return _sound->isSoundRunning(i) != 0;
default: default:
return false; return false;
} }

View file

@ -108,7 +108,7 @@ bool Scumm::loadState(int slot, bool compat)
_current_version = hdr.ver; _current_version = hdr.ver;
memcpy(_saveLoadName, hdr.name, sizeof(hdr.name)); memcpy(_saveLoadName, hdr.name, sizeof(hdr.name));
pauseSounds(true); _sound->pauseSounds(true);
CHECK_HEAP openRoom(-1); CHECK_HEAP openRoom(-1);
memset(_inventory, 0, sizeof(_inventory[0]) * _numInventory); memset(_inventory, 0, sizeof(_inventory[0]) * _numInventory);
@ -159,7 +159,7 @@ bool Scumm::loadState(int slot, bool compat)
CHECK_HEAP debug(1, "State loaded from '%s'", filename); CHECK_HEAP debug(1, "State loaded from '%s'", filename);
pauseSounds(false); _sound->pauseSounds(false);
return true; return true;
} }

View file

@ -1532,7 +1532,7 @@ void Scumm::o5_isSoundRunning()
getResultPos(); getResultPos();
snd = getVarOrDirectByte(0x80); snd = getVarOrDirectByte(0x80);
if (snd) if (snd)
snd = isSoundRunning(snd); snd = _sound->isSoundRunning(snd);
setResult(snd); setResult(snd);
} }
@ -2221,13 +2221,12 @@ void Scumm::o5_soundKludge()
getWordVararg(items); getWordVararg(items);
soundKludge(items); _sound->soundKludge(items);
} }
void Scumm::o5_startMusic() void Scumm::o5_startMusic()
{ {
_sound->addSoundToQueue(getVarOrDirectByte(0x80));
addSoundToQueue(getVarOrDirectByte(0x80));
} }
void Scumm::o5_startObject() void Scumm::o5_startObject()
@ -2267,12 +2266,12 @@ void Scumm::o5_startSound()
_vars[VAR_MUSIC_FLAG] = 0; _vars[VAR_MUSIC_FLAG] = 0;
addSoundToQueue(getVarOrDirectByte(0x80)); _sound->addSoundToQueue(getVarOrDirectByte(0x80));
} }
void Scumm::o5_stopMusic() void Scumm::o5_stopMusic()
{ {
stopAllSounds(); _sound->stopAllSounds();
} }
void Scumm::o5_stopObjectCode() void Scumm::o5_stopObjectCode()
@ -2298,7 +2297,7 @@ void Scumm::o5_stopScript()
void Scumm::o5_stopSound() void Scumm::o5_stopSound()
{ {
stopSound(getVarOrDirectByte(0x80)); _sound->stopSound(getVarOrDirectByte(0x80));
} }
void Scumm::o5_stringOps() void Scumm::o5_stringOps()
@ -2714,12 +2713,12 @@ void Scumm::decodeParseString()
_vars[VAR_MI1_TIMER] = 0; _vars[VAR_MI1_TIMER] = 0;
if (offset == 0 && delay == 0) { if (offset == 0 && delay == 0) {
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (stopMP3CD() == -1) if (_sound->stopMP3CD() == -1)
#endif #endif
_system->stop_cdrom(); _system->stop_cdrom();
} else { } else {
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (playMP3CDTrack(1, 0, offset, delay) == -1) if (_sound->playMP3CDTrack(1, 0, offset, delay) == -1)
#endif #endif
_system->play_cdrom(1, 0, offset, delay); _system->play_cdrom(1, 0, offset, delay);
} }

View file

@ -1096,7 +1096,7 @@ void Scumm::o6_cutScene()
void Scumm::o6_stopMusic() void Scumm::o6_stopMusic()
{ {
stopAllSounds(); _sound->stopAllSounds();
} }
void Scumm::o6_freezeUnfreeze() void Scumm::o6_freezeUnfreeze()
@ -1249,17 +1249,17 @@ void Scumm::o6_getOwner()
void Scumm::o6_startSound() void Scumm::o6_startSound()
{ {
addSoundToQueue(pop()); _sound->addSoundToQueue(pop());
} }
void Scumm::o6_stopSound() void Scumm::o6_stopSound()
{ {
stopSound(pop()); _sound->stopSound(pop());
} }
void Scumm::o6_startMusic() void Scumm::o6_startMusic()
{ {
addSoundToQueue(pop()); _sound->addSoundToQueue(pop());
} }
void Scumm::o6_stopObjectScript() void Scumm::o6_stopObjectScript()
@ -1650,13 +1650,13 @@ void Scumm::o6_isSoundRunning()
// FIXME: This fixes wak-a-rat until we correctly implement // FIXME: This fixes wak-a-rat until we correctly implement
// sam and max iMUSE // sam and max iMUSE
if (_gameId == GID_SAMNMAX && _currentRoom == 18 && snd == 23) { if (_gameId == GID_SAMNMAX && _currentRoom == 18 && snd == 23) {
stopSound(snd); _sound->stopSound(snd);
push(0); push(0);
return; return;
} }
if (snd) if (snd)
snd = isSoundRunning(snd); snd = _sound->isSoundRunning(snd);
push(snd); push(snd);
} }
@ -2426,7 +2426,7 @@ void Scumm::o6_soundKludge()
if (list[1] == 163 && _gameId == GID_DIG) if (list[1] == 163 && _gameId == GID_DIG)
return; return;
soundKludge(list); _sound->soundKludge(list);
} }
void Scumm::o6_isAnyOf() void Scumm::o6_isAnyOf()
@ -2540,7 +2540,7 @@ void Scumm::o6_talkActor()
if (_scriptPointer[0] == '/') { if (_scriptPointer[0] == '/') {
char *pointer = strtok((char *)_scriptPointer, "/"); char *pointer = strtok((char *)_scriptPointer, "/");
int bunsize = strlen(pointer) + 2; int bunsize = strlen(pointer) + 2;
playBundleSound(pointer); _sound->playBundleSound(pointer);
_scriptPointer += bunsize; _scriptPointer += bunsize;
_messagePtr = _scriptPointer; _messagePtr = _scriptPointer;
} }
@ -2558,7 +2558,7 @@ void Scumm::o6_talkEgo()
if (_scriptPointer[0] == '/') { if (_scriptPointer[0] == '/') {
char *pointer = strtok((char *)_scriptPointer, "/"); char *pointer = strtok((char *)_scriptPointer, "/");
int bunsize = strlen(pointer) + 2; int bunsize = strlen(pointer) + 2;
playBundleSound(pointer); _sound->playBundleSound(pointer);
_scriptPointer += bunsize; _scriptPointer += bunsize;
_messagePtr = _scriptPointer; _messagePtr = _scriptPointer;
} }
@ -3077,7 +3077,7 @@ void Scumm::decodeParseString2(int m, int n)
if (_scriptPointer[0] == '/') { if (_scriptPointer[0] == '/') {
char *pointer = strtok((char *)_scriptPointer, "/"); char *pointer = strtok((char *)_scriptPointer, "/");
int bunsize = strlen(pointer) + 2; int bunsize = strlen(pointer) + 2;
playBundleSound(pointer); _sound->playBundleSound(pointer);
_scriptPointer += bunsize; _scriptPointer += bunsize;
_messagePtr = _scriptPointer; _messagePtr = _scriptPointer;
} }

106
scumm.h
View file

@ -26,6 +26,7 @@
#include "engine.h" #include "engine.h"
#include "bundle.h" #include "bundle.h"
#include "timer.h" #include "timer.h"
#include "sound.h"
#define SCUMMVM_VERSION "0.2.2 CVS" #define SCUMMVM_VERSION "0.2.2 CVS"
#define SCUMMVM_CVS "2002-08-03" #define SCUMMVM_CVS "2002-08-03"
@ -338,6 +339,7 @@ public:
ScummDebugger *_debugger; ScummDebugger *_debugger;
Bundle * _bundle; Bundle * _bundle;
Timer * _timer; Timer * _timer;
Sound * _sound;
struct { struct {
byte mode[rtNumTypes]; byte mode[rtNumTypes];
@ -599,7 +601,7 @@ public:
bool isResourceLoaded(int type, int index); bool isResourceLoaded(int type, int index);
void initRoomSubBlocks(); void initRoomSubBlocks();
void loadRoomObjects(); void loadRoomObjects();
void loadRoomObjectsSmall(); void loadRoomObjectsSmall();
void readArrayFromIndexFile(); void readArrayFromIndexFile();
void readMAXS(); void readMAXS();
bool isGlobInMemory(int type, int index); bool isGlobInMemory(int type, int index);
@ -696,98 +698,6 @@ public:
void runVerbCode(int script, int entry, int a, int b, int16 *vars); void runVerbCode(int script, int entry, int a, int b, int16 *vars);
void setVerbObject(uint room, uint object, uint verb); void setVerbObject(uint room, uint object, uint verb);
/* Should be in Sound class */
// MixerChannel _mixer_channel[NUM_MIXER];
byte _sfxMode;
bool _use_adlib;
int16 _sound_volume_master, _sound_volume_music, _sound_volume_sfx;
int _saveSound;
void *_sfxFile;
uint16 _soundParam, _soundParam2, _soundParam3;
uint32 _talk_sound_a, _talk_sound_b;
byte _talk_sound_mode;
bool _mouthSyncMode;
bool _endOfMouthSync;
uint16 _mouthSyncTimes[52];
uint _curSoundPos;
int current_cd_sound, _cd_loops, _cd_frame, _cd_track, _cd_end;
int tempMusic;
#ifdef COMPRESSED_SOUND_FILE
#define CACHE_TRACKS 10
/* used for mp3 CD music */
int _current_cache;
int _cached_tracks[CACHE_TRACKS];
struct mad_header _mad_header[CACHE_TRACKS];
long _mp3_size[CACHE_TRACKS];
FILE *_mp3_tracks[CACHE_TRACKS];
int _mp3_index;
bool _mp3_cd_playing;
int getCachedTrack(int track);
int playMP3CDTrack(int track, int num_loops, int start, int delay);
int stopMP3CD();
int updateMP3CD();
int pollMP3CD();
#endif
int16 _soundQuePos, _soundQue[0x100];
byte _soundQue2Pos, _soundQue2[10];
bool _soundsPaused, _soundsPaused2;
bool _soundVolumePreset;
int32 _numberBundleMusic;
int32 _currentSampleBundleMusic;
int32 _numberSamplesBundleMusic;
int32 _offsetSampleBundleMusic;
int32 _offsetBufBundleMusic;
byte * _musicBundleBufFinal;
byte * _musicBundleBufOutput;
bool _pauseBundleMusic;
void setupSound();
void processSoundQues();
void playSound(int sound);
void stopAllSounds();
void stopSound(int sound);
bool isSoundInQueue(int sound);
void clearSoundQue();
void talkSound(uint32 a, uint32 b, int mode);
void processSfxQueues();
int startTalkSound(uint32 a, uint32 b, int mode);
void stopTalkSound();
bool isMouthSyncOff(uint pos);
int startSfxSound(void *file, int size);
void *openSfxFile();
void addSoundToQueue(int sound);
void addSoundToQueue2(int sound);
void soundKludge(int16 *list);
MP3OffsetTable *offset_table; // SO3 MP3 compressed audio
int num_sound_effects; // SO3 MP3 compressed audio
void pauseSounds(bool pause);
bool isSfxFinished();
void playBundleSound(char *sound);
void playBundleMusic(int32 song);
void pauseBundleMusic(bool state);
void stopBundleMusic();
void bundleMusicHandler(Scumm * scumm);
void decompressBundleSound(int index);
int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned = false);
int playSfxSound_MP3(void *sound, uint32 size);
void stopSfxSound();
int _talkChannel; /* Mixer channel actor is talking on */
bool _useTalkAnims;
uint16 _defaultTalkDelay;
byte _haveMsg;
int isSoundRunning(int a);
/* Should be in Actor class */ /* Should be in Actor class */
Actor *derefActor(int id); Actor *derefActor(int id);
Actor *derefActorSafe(int id, const char *errmsg); Actor *derefActorSafe(int id, const char *errmsg);
@ -954,8 +864,14 @@ public:
byte _bkColor; byte _bkColor;
uint16 _lastXstart; uint16 _lastXstart;
byte _haveMsg;
bool _useTalkAnims;
uint16 _defaultTalkDelay;
bool _use_adlib;
int tempMusic;
int _saveSound;
uint16 _soundParam, _soundParam2, _soundParam3;
int current_cd_sound, _cd_loops, _cd_frame, _cd_track, _cd_end;
/* Walkbox / Navigation class */ /* Walkbox / Navigation class */
int _maxBoxVertexHeap, _boxPathVertexHeapIndex, _boxMatrixItem; int _maxBoxVertexHeap, _boxPathVertexHeapIndex, _boxMatrixItem;

View file

@ -38,7 +38,7 @@
extern void GraphicsOff(void); extern void GraphicsOff(void);
#endif #endif
void autosave(Scumm * scumm) /* Not in class to prevent being bound */ void autosave(Scumm * scumm)
{ {
scumm->_doAutosave = true; scumm->_doAutosave = true;
} }
@ -67,6 +67,7 @@ Scumm::Scumm (void) {
_newgui = new NewGui(this); _newgui = new NewGui(this);
_bundle = new Bundle(this); _bundle = new Bundle(this);
_timer = new Timer(this); _timer = new Timer(this);
_sound = new Sound(this);
} }
Scumm::~Scumm (void) { Scumm::~Scumm (void) {
@ -74,6 +75,7 @@ Scumm::~Scumm (void) {
delete _newgui; delete _newgui;
delete _bundle; delete _bundle;
delete _timer; delete _timer;
delete _sound;
} }
void Scumm::scummInit() void Scumm::scummInit()
@ -81,7 +83,7 @@ void Scumm::scummInit()
int i; int i;
Actor *a; Actor *a;
tempMusic=0; tempMusic = 0;
debug(9, "scummInit"); debug(9, "scummInit");
if (_features & GF_SMALL_HEADER) if (_features & GF_SMALL_HEADER)
@ -203,13 +205,9 @@ void Scumm::scummInit()
getGraphicsPerformance(); getGraphicsPerformance();
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
_current_cache = 0; _sound->_current_cache = 0;
#endif #endif
_numberBundleMusic = -1;
_musicBundleBufFinal = NULL;
_musicBundleBufOutput = NULL;
_timer->installProcedure(&autosave, 5 * 60 * 1000); _timer->installProcedure(&autosave, 5 * 60 * 1000);
} }
@ -342,7 +340,7 @@ int Scumm::scummLoop(int delta)
gdi._cursorActive = 0; gdi._cursorActive = 0;
CHARSET_1(); CHARSET_1();
drawDirtyScreenParts(); drawDirtyScreenParts();
processSoundQues(); _sound->processSoundQues();
camera._last = camera._cur; camera._last = camera._cur;
} else { } else {
walkActors(); walkActors();
@ -390,7 +388,7 @@ int Scumm::scummLoop(int delta)
if (!(_features & GF_AFTER_V6)) if (!(_features & GF_AFTER_V6))
playActorSounds(); playActorSounds();
processSoundQues(); _sound->processSoundQues();
camera._last = camera._cur; camera._last = camera._cur;
} }
@ -969,19 +967,19 @@ void Scumm::processKbd()
runScript(_vars[VAR_UNK_SCRIPT_2], 0, 0, 0); runScript(_vars[VAR_UNK_SCRIPT_2], 0, 0, 0);
} else if (_lastKeyHit == _vars[VAR_TALKSTOP_KEY]) { } else if (_lastKeyHit == _vars[VAR_TALKSTOP_KEY]) {
_talkDelay = 0; _talkDelay = 0;
if (_sfxMode == 2) if (_sound->_sfxMode == 2)
stopTalk(); stopTalk();
return; return;
} else if (_lastKeyHit == '[') { // [, eg volume down } else if (_lastKeyHit == '[') { // [, eg volume down
_sound_volume_master-=5; _sound->_sound_volume_master-=5;
if (_sound_volume_master < 0) if (_sound->_sound_volume_master < 0)
_sound_volume_master = 0; _sound->_sound_volume_master = 0;
_imuse->set_master_volume(_sound_volume_master); _imuse->set_master_volume(_sound->_sound_volume_master);
} else if (_lastKeyHit == ']') { // ], eg volume down } else if (_lastKeyHit == ']') { // ], eg volume down
_sound_volume_master+=5; _sound->_sound_volume_master+=5;
if (_sound_volume_master > 128) if (_sound->_sound_volume_master > 128)
_sound_volume_master = 128; _sound->_sound_volume_master = 128;
_imuse->set_master_volume(_sound_volume_master); _imuse->set_master_volume(_sound->_sound_volume_master);
} else if (_lastKeyHit == '-') { // -, eg text speed down } else if (_lastKeyHit == '-') { // -, eg text speed down
_defaultTalkDelay+=5; _defaultTalkDelay+=5;
if (_defaultTalkDelay > 90) if (_defaultTalkDelay > 90)
@ -1373,7 +1371,7 @@ void Scumm::waitForTimer(int msec_delay) {
} }
} }
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (updateMP3CD() == -1) if (_sound->updateMP3CD() == -1)
#endif #endif
_system->update_cdrom(); /* Loop CD Audio if needed */ _system->update_cdrom(); /* Loop CD Audio if needed */
if (_system->get_msecs() >= start_time + msec_delay) if (_system->get_msecs() >= start_time + msec_delay)
@ -1502,7 +1500,7 @@ void Scumm::launch()
if (_gameId == GID_MONKEY) if (_gameId == GID_MONKEY)
_vars[74] = 1225; _vars[74] = 1225;
setupSound(); _sound->setupSound();
runScript(1, 0, 0, &_bootParam); runScript(1, 0, 0, &_bootParam);
@ -1571,8 +1569,8 @@ Scumm *Scumm::createFromDetector(GameDetector *detector, OSystem *syst)
scumm->_noSubtitles = detector->_noSubtitles; scumm->_noSubtitles = detector->_noSubtitles;
scumm->_cdrom = detector->_cdrom; scumm->_cdrom = detector->_cdrom;
scumm->_defaultTalkDelay = detector->_talkSpeed; scumm->_defaultTalkDelay = detector->_talkSpeed;
scumm->_sound_volume_sfx = detector->_sfx_volume; scumm->_sound->_sound_volume_sfx = detector->_sfx_volume;
scumm->_sound_volume_music = detector->_music_volume; scumm->_sound->_sound_volume_music = detector->_music_volume;
{ {
IMuse *imuse; IMuse *imuse;
@ -1587,7 +1585,7 @@ Scumm *Scumm::createFromDetector(GameDetector *detector, OSystem *syst)
if (detector->_gameTempo != 0) if (detector->_gameTempo != 0)
imuse->property(IMuse::PROP_TEMPO_BASE, detector->_gameTempo); imuse->property(IMuse::PROP_TEMPO_BASE, detector->_gameTempo);
imuse->set_music_volume(scumm->_sound_volume_music); imuse->set_music_volume(scumm->_sound->_sound_volume_music);
scumm->_imuse = imuse; scumm->_imuse = imuse;
} }

View file

@ -605,6 +605,10 @@ SOURCE=.\smush.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\sound.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h SOURCE=.\StdAfx.h
# End Source File # End Source File
# Begin Source File # Begin Source File

342
sound.cpp
View file

@ -33,11 +33,20 @@ extern void *bsearch(const void *, const void *, size_t,
size_t, int (*x) (const void *, const void *)); size_t, int (*x) (const void *, const void *));
#endif #endif
void Scumm::addSoundToQueue(int sound) Sound::Sound(Scumm *parent) {
{ _scumm = parent;
if (!(_features & GF_AFTER_V7)) { _numberBundleMusic = -1;
_vars[VAR_LAST_SOUND] = sound; _musicBundleBufFinal = NULL;
ensureResourceLoaded(rtSound, sound); _musicBundleBufOutput = NULL;
}
Sound::~Sound() {
}
void Sound::addSoundToQueue(int sound) {
if (!(_scumm->_features & GF_AFTER_V7)) {
_scumm->_vars[_scumm->VAR_LAST_SOUND] = sound;
_scumm->ensureResourceLoaded(rtSound, sound);
addSoundToQueue2(sound); addSoundToQueue2(sound);
} }
@ -45,15 +54,13 @@ void Scumm::addSoundToQueue(int sound)
// warning("Requesting audio track: %d", sound); // warning("Requesting audio track: %d", sound);
} }
void Scumm::addSoundToQueue2(int sound) void Sound::addSoundToQueue2(int sound) {
{
if (_soundQue2Pos < 10) { if (_soundQue2Pos < 10) {
_soundQue2[_soundQue2Pos++] = sound; _soundQue2[_soundQue2Pos++] = sound;
} }
} }
void Scumm::processSoundQues() void Sound::processSoundQues() {
{
byte d; byte d;
int i, j; int i, j;
int num; int num;
@ -81,7 +88,7 @@ void Scumm::processSoundQues()
data[j] = _soundQue[i + j]; data[j] = _soundQue[i + j];
i += num; i += num;
se = _imuse; se = _scumm->_imuse;
#if 0 #if 0
debug(1, "processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)", debug(1, "processSoundQues(%d,%d,%d,%d,%d,%d,%d,%d,%d)",
data[0] >> 8, data[0] >> 8,
@ -90,12 +97,12 @@ void Scumm::processSoundQues()
); );
#endif #endif
if ((_gameId == GID_DIG) && (data[0] == 4096)){ if ((_scumm->_gameId == GID_DIG) && (data[0] == 4096)){
playBundleMusic(data[1] - 1); playBundleMusic(data[1] - 1);
} }
if ((_gameId == GID_DIG) && ((data[0] == 12) || (data[0] == 14))){ if ((_scumm->_gameId == GID_DIG) && ((data[0] == 12) || (data[0] == 14))){
uint32 size = 0, rate = 0, tag, chan = 0, bits = 0; uint32 size = 0, rate = 0, tag, chan = 0, bits = 0;
uint8 * ptr = getResourceAddress(rtSound, data[1]); uint8 * ptr = _scumm->getResourceAddress(rtSound, data[1]);
if (ptr != NULL) { if (ptr != NULL) {
ptr+=16; /* Skip header */ ptr+=16; /* Skip header */
for (;;) { for (;;) {
@ -125,42 +132,27 @@ void Scumm::processSoundQues()
byte * buffer = (byte*)malloc (size); byte * buffer = (byte*)malloc (size);
memcpy(buffer, ptr, size); memcpy(buffer, ptr, size);
if (chan == 1) { if (chan == 1) {
_mixer->play_raw(NULL, buffer, size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED); _scumm->_mixer->play_raw(NULL, buffer, size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED);
} }
else if (chan == 2) { else if (chan == 2) {
_mixer->play_raw(NULL, buffer, size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_STEREO); _scumm->_mixer->play_raw(NULL, buffer, size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_STEREO);
} }
} else if (bits == 12) { } else if (bits == 12) {
uint32 s_size = (size * 4) / 3; byte * buffer = NULL;
byte * buffer = (byte*)malloc (s_size + 4); uint32 final_size = decode12BitsSample(ptr, &buffer, size);
uint32 l = 0, r = 0, tmp;
for (; l < size; l += 3)
{
tmp = (ptr[l + 1] & 0x0f) << 8;
tmp = (tmp | ptr[l + 0]) << 4;
tmp -= 0x8000;
buffer[r++] = (uint8)((tmp >> 8) & 0xff);
buffer[r++] = (uint8)(tmp & 0xff);
tmp = (ptr[l + 1] & 0xf0) << 4;
tmp = (tmp | ptr[l + 2]) << 4;
tmp -= 0x8000;
buffer[r++] = (uint8)((tmp >> 8) & 0xff);
buffer[r++] = (uint8)(tmp & 0xff);
}
if (chan == 1) { if (chan == 1) {
_mixer->play_raw(NULL, buffer, s_size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS); _scumm->_mixer->play_raw(NULL, buffer, final_size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS);
} }
else if (chan == 2) { else if (chan == 2) {
_mixer->play_raw(NULL, buffer, s_size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO); _scumm->_mixer->play_raw(NULL, buffer, final_size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO);
} }
} }
} }
} }
if (!(_features & GF_AFTER_V7)) { if (!(_scumm->_features & GF_AFTER_V7)) {
if (se) if (se)
_vars[VAR_SOUNDRESULT] = _scumm->_vars[_scumm->VAR_SOUNDRESULT] =
(short)se->do_command(data[0], data[1], data[2], data[3], data[4], (short)se->do_command(data[0], data[1], data[2], data[3], data[4],
data[5], data[6], data[7]); data[5], data[6], data[7]);
} }
@ -170,23 +162,22 @@ void Scumm::processSoundQues()
_soundQuePos = 0; _soundQuePos = 0;
} }
void Scumm::playSound(int sound) void Sound::playSound(int sound) {
{
byte *ptr; byte *ptr;
IMuse *se = _imuse; IMuse *se = _scumm->_imuse;
ptr = getResourceAddress(rtSound, sound); ptr = _scumm->getResourceAddress(rtSound, sound);
if (ptr != NULL && READ_UINT32_UNALIGNED(ptr) == MKID('SOUN')) { if (ptr != NULL && READ_UINT32_UNALIGNED(ptr) == MKID('SOUN')) {
ptr += 8; ptr += 8;
_vars[VAR_MI1_TIMER] = 0; _scumm->_vars[_scumm->VAR_MI1_TIMER] = 0;
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if ((playMP3CDTrack(ptr[16], ptr[17] == 0xff ? -1 : ptr[17], if ((playMP3CDTrack(ptr[16], ptr[17] == 0xff ? -1 : ptr[17],
(ptr[18] * 60 + ptr[19]) * 75 + ptr[20], 0)) == -1) (ptr[18] * 60 + ptr[19]) * 75 + ptr[20], 0)) == -1)
#endif #endif
_system->play_cdrom(ptr[16], ptr[17] == 0xff ? -1 : ptr[17], _scumm->_system->play_cdrom(ptr[16], ptr[17] == 0xff ? -1 : ptr[17],
(ptr[18] * 60 + ptr[19]) * 75 + ptr[20], 0); (ptr[18] * 60 + ptr[19]) * 75 + ptr[20], 0);
current_cd_sound = sound; _scumm->current_cd_sound = sound;
return; return;
} }
@ -205,7 +196,7 @@ void Scumm::playSound(int sound)
// Allocate a sound buffer, copy the data into it, and play // Allocate a sound buffer, copy the data into it, and play
char *sound = (char*)malloc(size); char *sound = (char*)malloc(size);
memcpy(sound, ptr, size); memcpy(sound, ptr, size);
_mixer->play_raw(NULL, sound, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); _scumm->_mixer->play_raw(NULL, sound, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
return; return;
} }
// Support for Putt-Putt sounds - very hackish, too 8-) // Support for Putt-Putt sounds - very hackish, too 8-)
@ -222,11 +213,11 @@ void Scumm::playSound(int sound)
// Allocate a sound buffer, copy the data into it, and play // Allocate a sound buffer, copy the data into it, and play
char *sound = (char*)malloc(size); char *sound = (char*)malloc(size);
memcpy(sound, ptr+8, size); memcpy(sound, ptr+8, size);
_mixer->play_raw(NULL, sound, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); _scumm->_mixer->play_raw(NULL, sound, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
return; return;
} }
if ((_features & GF_OLD256) && (ptr != NULL)) { if ((_scumm->_features & GF_OLD256) && (ptr != NULL)) {
char *sound; char *sound;
int size = READ_LE_UINT32(ptr); int size = READ_LE_UINT32(ptr);
@ -272,20 +263,20 @@ void Scumm::playSound(int sound)
int result = 0; int result = 0;
int track = *ptr; int track = *ptr;
if (track == current_cd_sound) if (track == _scumm->current_cd_sound)
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (pollMP3CD()) if (pollMP3CD())
result = 1; result = 1;
else else
#endif #endif
result = _system->poll_cdrom(); result = _scumm->_system->poll_cdrom();
if (result == 1) return; if (result == 1) return;
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (playMP3CDTrack(track, 1, 0, 0) == -1) if (playMP3CDTrack(track, 1, 0, 0) == -1)
#endif #endif
_system->play_cdrom(track, 0, 0, 0); _scumm->_system->play_cdrom(track, 0, 0, 0);
current_cd_sound = track; _scumm->current_cd_sound = track;
return; return;
} }
@ -298,21 +289,20 @@ void Scumm::playSound(int sound)
// FIXME: Something in the header signifies looping. Need to track it down and add a // FIXME: Something in the header signifies looping. Need to track it down and add a
// mixer flag or something. // mixer flag or something.
_mixer->play_raw(NULL, sound, size, 11000, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); _scumm->_mixer->play_raw(NULL, sound, size, 11000, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
return; return;
} }
if (_gameId == GID_MONKEY_VGA) if (_scumm->_gameId == GID_MONKEY_VGA)
return; /* FIXME */ return; /* FIXME */
if (se) { if (se) {
getResourceAddress(rtSound, sound); _scumm->getResourceAddress(rtSound, sound);
se->start_sound(sound); se->start_sound(sound);
} }
} }
void Scumm::processSfxQueues() void Sound::processSfxQueues() {
{
Actor *a; Actor *a;
int act; int act;
bool b, finished; bool b, finished;
@ -325,19 +315,19 @@ void Scumm::processSfxQueues()
_talk_sound_mode = 0; _talk_sound_mode = 0;
} }
if (_vars[VAR_TALK_ACTOR]) { //_sfxMode == 2) { if (_scumm->_vars[_scumm->VAR_TALK_ACTOR]) { //_sfxMode == 2) {
act = _vars[VAR_TALK_ACTOR]; act = _scumm->_vars[_scumm->VAR_TALK_ACTOR];
if (_talkChannel < 0) if (_talkChannel < 0)
finished = false; finished = false;
else if (_mixer->_channels[_talkChannel] == NULL) else if (_scumm->_mixer->_channels[_talkChannel] == NULL)
finished = true; finished = true;
else else
finished = false; finished = false;
if (act != 0 && (uint) act < 0x80 && !string[0].no_talk_anim) { if (act != 0 && (uint) act < 0x80 && !_scumm->string[0].no_talk_anim) {
a = derefActorSafe(act, "processSfxQueues"); a = _scumm->derefActorSafe(act, "processSfxQueues");
if (a->room == _currentRoom && (finished || !_endOfMouthSync)) { if (a->room == _scumm->_currentRoom && (finished || !_endOfMouthSync)) {
b = true; b = true;
if (!finished) if (!finished)
b = isMouthSyncOff(_curSoundPos); b = isMouthSyncOff(_curSoundPos);
@ -348,8 +338,8 @@ void Scumm::processSfxQueues()
} }
} }
if (finished && _talkDelay == 0) { if (finished && _scumm->_talkDelay == 0) {
stopTalk(); _scumm->stopTalk();
_sfxMode = 0; _sfxMode = 0;
_talkChannel = -1; _talkChannel = -1;
} }
@ -370,8 +360,7 @@ static int compar(const void *a, const void *b)
} }
#endif #endif
int Scumm::startTalkSound(uint32 offset, uint32 b, int mode) int Sound::startTalkSound(uint32 offset, uint32 b, int mode) {
{
int num = 0, i; int num = 0, i;
byte file_byte, file_byte_2; byte file_byte, file_byte_2;
int size; int size;
@ -410,11 +399,11 @@ int Scumm::startTalkSound(uint32 offset, uint32 b, int mode)
size = -1; size = -1;
} }
fileSeek((FILE *) _sfxFile, offset, SEEK_SET); _scumm->fileSeek((FILE *) _sfxFile, offset, SEEK_SET);
i = 0; i = 0;
while (num > 0) { while (num > 0) {
fileRead((FILE *) _sfxFile, &file_byte, sizeof(file_byte)); _scumm->fileRead((FILE *) _sfxFile, &file_byte, sizeof(file_byte));
fileRead((FILE *) _sfxFile, &file_byte_2, sizeof(file_byte_2)); _scumm->fileRead((FILE *) _sfxFile, &file_byte_2, sizeof(file_byte_2));
_mouthSyncTimes[i++] = file_byte | (file_byte_2 << 8); _mouthSyncTimes[i++] = file_byte | (file_byte_2 << 8);
num--; num--;
} }
@ -426,16 +415,14 @@ int Scumm::startTalkSound(uint32 offset, uint32 b, int mode)
return startSfxSound(_sfxFile, size); return startSfxSound(_sfxFile, size);
} }
void Scumm::stopTalkSound() void Sound::stopTalkSound() {
{
if (_sfxMode == 2) { if (_sfxMode == 2) {
stopSfxSound(); stopSfxSound();
_sfxMode = 0; _sfxMode = 0;
} }
} }
bool Scumm::isMouthSyncOff(uint pos) bool Sound::isMouthSyncOff(uint pos) {
{
uint j; uint j;
bool val = true; bool val = true;
uint16 *ms = _mouthSyncTimes; uint16 *ms = _mouthSyncTimes;
@ -453,18 +440,17 @@ bool Scumm::isMouthSyncOff(uint pos)
} }
int Scumm::isSoundRunning(int sound) int Sound::isSoundRunning(int sound) {
{
IMuse *se; IMuse *se;
int i; int i;
if (sound == current_cd_sound) if (sound == _scumm->current_cd_sound)
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (pollMP3CD()) if (pollMP3CD())
return 1; return 1;
else else
#endif #endif
return _system->poll_cdrom(); return _scumm->_system->poll_cdrom();
i = _soundQue2Pos; i = _soundQue2Pos;
while (i--) { while (i--) {
@ -475,17 +461,16 @@ int Scumm::isSoundRunning(int sound)
if (isSoundInQueue(sound)) if (isSoundInQueue(sound))
return 1; return 1;
if (!isResourceLoaded(rtSound, sound)) if (!_scumm->isResourceLoaded(rtSound, sound))
return 0; return 0;
se = _imuse; se = _scumm->_imuse;
if (!se) if (!se)
return 0; return 0;
return se->get_sound_status(sound); return se->get_sound_status(sound);
} }
bool Scumm::isSoundInQueue(int sound) bool Sound::isSoundInQueue(int sound) {
{
int i = 0, j, num; int i = 0, j, num;
int16 table[16]; int16 table[16];
@ -505,20 +490,19 @@ bool Scumm::isSoundInQueue(int sound)
return 0; return 0;
} }
void Scumm::stopSound(int a) void Sound::stopSound(int a) {
{
IMuse *se; IMuse *se;
int i; int i;
if (a != 0 && a == current_cd_sound) { if (a != 0 && a == _scumm->current_cd_sound) {
current_cd_sound = 0; _scumm->current_cd_sound = 0;
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (stopMP3CD() == -1) if (stopMP3CD() == -1)
#endif #endif
_system->stop_cdrom(); _scumm->_system->stop_cdrom();
} }
se = _imuse; se = _scumm->_imuse;
if (se) if (se)
se->stop_sound(a); se->stop_sound(a);
@ -527,16 +511,16 @@ void Scumm::stopSound(int a)
_soundQue2[i] = 0; _soundQue2[i] = 0;
} }
void Scumm::stopAllSounds() void Sound::stopAllSounds()
{ {
IMuse *se = _imuse; IMuse *se = _scumm->_imuse;
if (current_cd_sound != 0) { if (_scumm->current_cd_sound != 0) {
current_cd_sound = 0; _scumm->current_cd_sound = 0;
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (stopMP3CD() == -1) if (stopMP3CD() == -1)
#endif #endif
_system->stop_cdrom(); _scumm->_system->stop_cdrom();
} }
if (se) { if (se) {
@ -547,14 +531,12 @@ void Scumm::stopAllSounds()
stopSfxSound(); stopSfxSound();
} }
void Scumm::clearSoundQue() void Sound::clearSoundQue() {
{
_soundQue2Pos = 0; _soundQue2Pos = 0;
memset(_soundQue2, 0, sizeof(_soundQue2)); memset(_soundQue2, 0, sizeof(_soundQue2));
} }
void Scumm::soundKludge(int16 * list) void Sound::soundKludge(int16 * list) {
{
int16 *ptr; int16 *ptr;
int i; int i;
@ -573,8 +555,7 @@ void Scumm::soundKludge(int16 * list)
error("Sound que buffer overflow"); error("Sound que buffer overflow");
} }
void Scumm::talkSound(uint32 a, uint32 b, int mode) void Sound::talkSound(uint32 a, uint32 b, int mode) {
{
_talk_sound_a = a; _talk_sound_a = a;
_talk_sound_b = b; _talk_sound_b = b;
_talk_sound_mode = mode; _talk_sound_mode = mode;
@ -587,41 +568,32 @@ void Scumm::talkSound(uint32 a, uint32 b, int mode)
* is needed. * is needed.
*/ */
void Scumm::setupSound() void Sound::setupSound() {
{ if (_scumm->_imuse) {
if (_imuse) { _scumm->_imuse->setBase(_scumm->res.address[rtSound]);
_imuse->setBase(res.address[rtSound]);
_sound_volume_music = scummcfg->getInt("music_volume", kDefaultMusicVolume); _sound_volume_music = scummcfg->getInt("music_volume", kDefaultMusicVolume);
_sound_volume_master = scummcfg->getInt("master_volume", kDefaultMasterVolume); _sound_volume_master = scummcfg->getInt("master_volume", kDefaultMasterVolume);
_sound_volume_sfx = scummcfg->getInt("sfx_volume", kDefaultSFXVolume); _sound_volume_sfx = scummcfg->getInt("sfx_volume", kDefaultSFXVolume);
_imuse->set_master_volume(_sound_volume_master); _scumm->_imuse->set_master_volume(_sound_volume_master);
_imuse->set_music_volume(_sound_volume_music); _scumm->_imuse->set_music_volume(_sound_volume_music);
_mixer->set_volume(_sound_volume_sfx); _scumm->_mixer->set_volume(_sound_volume_sfx);
_mixer->set_music_volume(_sound_volume_music); _scumm->_mixer->set_music_volume(_sound_volume_music);
} }
_sfxFile = openSfxFile(); _sfxFile = openSfxFile();
} }
void Scumm::pauseSounds(bool pause) void Sound::pauseSounds(bool pause) {
{ IMuse *se = _scumm->_imuse;
IMuse *se = _imuse;
if (se) if (se)
se->pause(pause); se->pause(pause);
_soundsPaused = pause; _soundsPaused = pause;
_mixer->pause(pause); _scumm->_mixer->pause(pause);
} }
enum { int Sound::startSfxSound(void *file, int file_size) {
SOUND_HEADER_SIZE = 26,
SOUND_HEADER_BIG_SIZE = 26 + 8,
};
int Scumm::startSfxSound(void *file, int file_size)
{
char ident[8]; char ident[8];
int block_type; int block_type;
byte work[8]; byte work[8];
@ -688,8 +660,7 @@ int Scumm::startSfxSound(void *file, int file_size)
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
static int get_int(FILE * f) static int get_int(FILE * f) {
{
int ret = 0; int ret = 0;
for (int size = 0; size < 4; size++) { for (int size = 0; size < 4; size++) {
int c = fgetc(f); int c = fgetc(f);
@ -703,8 +674,7 @@ static int get_int(FILE * f)
} }
#endif #endif
void *Scumm::openSfxFile() void * Sound::openSfxFile() {
{
char buf[256]; char buf[256];
FILE *file = NULL; FILE *file = NULL;
@ -714,10 +684,10 @@ void *Scumm::openSfxFile()
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
offset_table = NULL; offset_table = NULL;
sprintf(buf, "%s%s.so3", _gameDataPath, _exe_name); sprintf(buf, "%s%s.so3", _scumm->_gameDataPath, _scumm->_exe_name);
file = fopen(buf, "rb"); file = fopen(buf, "rb");
if (!file) { if (!file) {
sprintf(buf, "%smonster.so3", _gameDataPath); sprintf(buf, "%smonster.so3", _scumm->_gameDataPath);
file = fopen(buf, "rb"); file = fopen(buf, "rb");
} }
if (file != NULL) { if (file != NULL) {
@ -755,38 +725,58 @@ void *Scumm::openSfxFile()
return file; return file;
} }
#endif #endif
sprintf(buf, "%s%s.sou", _gameDataPath, _exe_name); sprintf(buf, "%s%s.sou", _scumm->_gameDataPath, _scumm->_exe_name);
file = fopen(buf, "rb"); file = fopen(buf, "rb");
if (!file) { if (!file) {
sprintf(buf, "%smonster.sou", _gameDataPath); sprintf(buf, "%smonster.sou", _scumm->_gameDataPath);
file = fopen(buf, "rb"); file = fopen(buf, "rb");
} }
return file; return file;
} }
void Scumm::stopSfxSound() void Sound::stopSfxSound() {
{ _scumm->_mixer->stop_all();
_mixer->stop_all();
} }
bool Scumm::isSfxFinished() bool Sound::isSfxFinished() {
{ return !_scumm->_mixer->has_active_channel();
return !_mixer->has_active_channel(); }
uint32 Sound::decode12BitsSample(byte * src, byte ** dst, uint32 size) {
uint32 s_size = (size * 4) / 3;
byte * ptr = *dst = (byte*)malloc (s_size + 4);
uint32 r = 0, tmp, l;
for (l = 0; l < size; l += 3) {
tmp = (src[l + 1] & 0x0f) << 8;
tmp = (tmp | src[l + 0]) << 4;
tmp -= 0x8000;
ptr[r++] = (byte)((tmp >> 8) & 0xff);
ptr[r++] = (byte)(tmp & 0xff);
tmp = (src[l + 1] & 0xf0) << 4;
tmp = (tmp | src[l + 2]) << 4;
tmp -= 0x8000;
ptr[r++] = (byte)((tmp >> 8) & 0xff);
ptr[r++] = (byte)(tmp & 0xff);
}
return r;
} }
static void music_handler (Scumm * scumm) { static void music_handler (Scumm * scumm) {
scumm->bundleMusicHandler(scumm); scumm->_sound->bundleMusicHandler(scumm);
} }
#define OUTPUT_SIZE 66150 // ((22050 * 2 * 2) / 4) * 3 #define OUTPUT_SIZE 66150 // ((22050 * 2 * 2) / 4) * 3
void Scumm::playBundleMusic(int32 song) { void Sound::playBundleMusic(int32 song) {
char buf[256]; char buf[256];
if (_numberBundleMusic == -1) { if (_numberBundleMusic == -1) {
sprintf(buf, "%s%smusic.bun", _gameDataPath, _exe_name); sprintf(buf, "%s%smusic.bun", _scumm->_gameDataPath, _scumm->_exe_name);
if (_bundle->openMusicFile((char*)&buf) == false) if (_scumm->_bundle->openMusicFile((char*)&buf) == false)
return; return;
_musicBundleBufFinal = (byte*)malloc(OUTPUT_SIZE); _musicBundleBufFinal = (byte*)malloc(OUTPUT_SIZE);
_musicBundleBufOutput = (byte*)malloc(10 * 0x2000); _musicBundleBufOutput = (byte*)malloc(10 * 0x2000);
@ -794,13 +784,13 @@ void Scumm::playBundleMusic(int32 song) {
_offsetSampleBundleMusic = 0; _offsetSampleBundleMusic = 0;
_offsetBufBundleMusic = 0; _offsetBufBundleMusic = 0;
_pauseBundleMusic = false; _pauseBundleMusic = false;
_numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByIndex(song); _numberSamplesBundleMusic = _scumm->_bundle->getNumberOfMusicSamplesByIndex(song);
_numberBundleMusic = song; _numberBundleMusic = song;
_timer->installProcedure(&music_handler, 1000); _scumm->_timer->installProcedure(&music_handler, 1000);
return; return;
} }
if (_numberBundleMusic != song) { if (_numberBundleMusic != song) {
_numberSamplesBundleMusic = _bundle->getNumberOfMusicSamplesByIndex(song); _numberSamplesBundleMusic = _scumm->_bundle->getNumberOfMusicSamplesByIndex(song);
_numberBundleMusic = song; _numberBundleMusic = song;
_currentSampleBundleMusic = 0; _currentSampleBundleMusic = 0;
_offsetSampleBundleMusic = 0; _offsetSampleBundleMusic = 0;
@ -808,12 +798,12 @@ void Scumm::playBundleMusic(int32 song) {
} }
} }
void Scumm::pauseBundleMusic(bool state) { void Sound::pauseBundleMusic(bool state) {
_pauseBundleMusic = state; _pauseBundleMusic = state;
} }
void Scumm::stopBundleMusic() { void Sound::stopBundleMusic() {
_timer->releaseProcedure(&music_handler); _scumm->_timer->releaseProcedure(&music_handler);
_numberBundleMusic = -1; _numberBundleMusic = -1;
if (_musicBundleBufFinal) { if (_musicBundleBufFinal) {
free(_musicBundleBufFinal); free(_musicBundleBufFinal);
@ -825,7 +815,7 @@ void Scumm::stopBundleMusic() {
} }
} }
void Scumm::bundleMusicHandler(Scumm * scumm) { void Sound::bundleMusicHandler(Scumm * scumm) {
byte * ptr; byte * ptr;
int32 l, num = _numberSamplesBundleMusic, length, k; int32 l, num = _numberSamplesBundleMusic, length, k;
int32 rate = 22050; int32 rate = 22050;
@ -837,7 +827,7 @@ void Scumm::bundleMusicHandler(Scumm * scumm) {
return; return;
for (k = 0, l = _currentSampleBundleMusic; l < num; k++) { for (k = 0, l = _currentSampleBundleMusic; l < num; k++) {
length = _bundle->decompressMusicSampleByIndex(_numberBundleMusic, l, (_musicBundleBufOutput + ((k * 0x2000) + _offsetBufBundleMusic))); length = _scumm->_bundle->decompressMusicSampleByIndex(_numberBundleMusic, l, (_musicBundleBufOutput + ((k * 0x2000) + _offsetBufBundleMusic)));
_offsetSampleBundleMusic += length; _offsetSampleBundleMusic += length;
if (l == 0) { if (l == 0) {
@ -894,35 +884,19 @@ void Scumm::bundleMusicHandler(Scumm * scumm) {
size = OUTPUT_SIZE; size = OUTPUT_SIZE;
ptr = _musicBundleBufFinal; ptr = _musicBundleBufFinal;
uint32 s_size = (size * 4) / 3; byte * buffer = NULL;
byte * buffer = (byte*)malloc (s_size + 4); uint32 final_size = decode12BitsSample(ptr, &buffer, size);
uint32 r = 0, tmp; _scumm->_mixer->play_raw(NULL, buffer, final_size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO);
for (l = 0; l < size; l += 3) {
tmp = (ptr[l + 1] & 0x0f) << 8;
tmp = (tmp | ptr[l + 0]) << 4;
tmp -= 0x8000;
buffer[r++] = (uint8)((tmp >> 8) & 0xff);
buffer[r++] = (uint8)(tmp & 0xff);
tmp = (ptr[l + 1] & 0xf0) << 4;
tmp = (tmp | ptr[l + 2]) << 4;
tmp -= 0x8000;
buffer[r++] = (uint8)((tmp >> 8) & 0xff);
buffer[r++] = (uint8)(tmp & 0xff);
}
_mixer->play_raw(NULL, buffer, s_size, rate, SoundMixer::FLAG_AUTOFREE | SoundMixer::FLAG_16BITS | SoundMixer::FLAG_STEREO);
} }
void Scumm::playBundleSound(char *sound) void Sound::playBundleSound(char *sound) {
{
char buf[256]; char buf[256];
byte * ptr; byte * ptr;
sprintf(buf, "%s%svoice.bun", _gameDataPath, _exe_name); sprintf(buf, "%s%svoice.bun", _scumm->_gameDataPath, _scumm->_exe_name);
_bundle->openVoiceFile((char*)&buf); _scumm->_bundle->openVoiceFile((char*)&buf);
ptr = (byte *)malloc(1000000); ptr = (byte *)malloc(1000000);
if (_bundle->decompressVoiceSampleByName(sound, ptr) == 0) { if (_scumm->_bundle->decompressVoiceSampleByName(sound, ptr) == 0) {
delete ptr; delete ptr;
return; return;
} }
@ -969,32 +943,30 @@ void Scumm::playBundleSound(char *sound)
byte * final = (byte *)malloc(size); byte * final = (byte *)malloc(size);
memcpy(final, ptr, size); memcpy(final, ptr, size);
_mixer->play_raw(NULL, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE); _scumm->_mixer->play_raw(NULL, final, size, rate, SoundMixer::FLAG_UNSIGNED | SoundMixer::FLAG_AUTOFREE);
} }
int Scumm::playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned) int Sound::playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned) {
{
if (_soundsPaused) if (_soundsPaused)
return -1; return -1;
byte flags = SoundMixer::FLAG_AUTOFREE; byte flags = SoundMixer::FLAG_AUTOFREE;
if (isUnsigned) if (isUnsigned)
flags |= SoundMixer::FLAG_UNSIGNED; flags |= SoundMixer::FLAG_UNSIGNED;
return _mixer->play_raw(NULL, sound, size, rate, flags); return _scumm->_mixer->play_raw(NULL, sound, size, rate, flags);
} }
int Scumm::playSfxSound_MP3(void *sound, uint32 size) int Sound::playSfxSound_MP3(void *sound, uint32 size) {
{
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
if (_soundsPaused) if (_soundsPaused)
return -1; return -1;
return _mixer->play_mp3(NULL, sound, size, SoundMixer::FLAG_AUTOFREE); return _scumm->_mixer->play_mp3(NULL, sound, size, SoundMixer::FLAG_AUTOFREE);
#endif #endif
return -1; return -1;
} }
#ifdef COMPRESSED_SOUND_FILE #ifdef COMPRESSED_SOUND_FILE
int Scumm::getCachedTrack(int track) { int Sound::getCachedTrack(int track) {
int i; int i;
char track_name[1024]; char track_name[1024];
FILE* file; FILE* file;
@ -1017,7 +989,7 @@ int Scumm::getCachedTrack(int track) {
_current_cache %= CACHE_TRACKS; _current_cache %= CACHE_TRACKS;
// Not found, see if it exists // Not found, see if it exists
sprintf(track_name, "%strack%d.mp3", _gameDataPath, track); sprintf(track_name, "%strack%d.mp3", _scumm->_gameDataPath, track);
file = fopen(track_name, "rb"); file = fopen(track_name, "rb");
_cached_tracks[current_index] = track; _cached_tracks[current_index] = track;
@ -1096,11 +1068,11 @@ int Scumm::getCachedTrack(int track) {
return -1; return -1;
} }
int Scumm::playMP3CDTrack(int track, int num_loops, int start, int delay) { int Sound::playMP3CDTrack(int track, int num_loops, int start, int delay) {
int index; int index;
unsigned int offset; unsigned int offset;
mad_timer_t duration; mad_timer_t duration;
_vars[VAR_MI1_TIMER] = 0; _scumm->_vars[_scumm->VAR_MI1_TIMER] = 0;
if (_soundsPaused) if (_soundsPaused)
return 0; return 0;
@ -1128,37 +1100,37 @@ int Scumm::playMP3CDTrack(int track, int num_loops, int start, int delay) {
fseek(_mp3_tracks[index], offset, SEEK_SET); fseek(_mp3_tracks[index], offset, SEEK_SET);
if (_mp3_cd_playing == true) if (_mp3_cd_playing == true)
_mixer->stop(_mp3_index); _scumm->_mixer->stop(_mp3_index);
_mp3_index = _mixer->play_mp3_cdtrack(NULL, _mp3_tracks[index], duration); _mp3_index = _scumm->_mixer->play_mp3_cdtrack(NULL, _mp3_tracks[index], duration);
_mp3_cd_playing = true; _mp3_cd_playing = true;
return 0; return 0;
} }
int Scumm::stopMP3CD() { int Sound::stopMP3CD() {
if (_mp3_cd_playing == true) { if (_mp3_cd_playing == true) {
_mixer->stop(_mp3_index); _scumm->_mixer->stop(_mp3_index);
_mp3_cd_playing = false; _mp3_cd_playing = false;
return 0; return 0;
} }
return -1; return -1;
} }
int Scumm::pollMP3CD() { int Sound::pollMP3CD() {
if (_mp3_cd_playing == true) if (_mp3_cd_playing == true)
return 1; return 1;
return 0; return 0;
} }
int Scumm::updateMP3CD() { int Sound::updateMP3CD() {
if (_mp3_cd_playing == false) if (_mp3_cd_playing == false)
return -1; return -1;
if (_mixer->_channels[_mp3_index] == NULL) { if (_scumm->_mixer->_channels[_mp3_index] == NULL) {
warning("Error in MP3 decoding"); warning("Error in MP3 decoding");
return -1; return -1;
} }
if (_mixer->_channels[_mp3_index]->sound_finished()) if (_scumm->_mixer->_channels[_mp3_index]->sound_finished())
stopMP3CD(); stopMP3CD();
return 0; return 0;
} }

135
sound.h Normal file
View file

@ -0,0 +1,135 @@
/* 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 SOUND_H
#define SOUND_H
#include "scummsys.h"
class Scumm;
class Sound {
private:
enum {
SOUND_HEADER_SIZE = 26,
SOUND_HEADER_BIG_SIZE = 26 + 8,
};
int16 _soundQuePos, _soundQue[0x100];
byte _soundQue2Pos, _soundQue2[10];
bool _soundsPaused2;
bool _soundVolumePreset;
int32 _numberBundleMusic;
int32 _currentSampleBundleMusic;
int32 _numberSamplesBundleMusic;
int32 _offsetSampleBundleMusic;
int32 _offsetBufBundleMusic;
byte * _musicBundleBufFinal;
byte * _musicBundleBufOutput;
bool _pauseBundleMusic;
int _talkChannel; /* Mixer channel actor is talking on */
void *_sfxFile;
uint32 _talk_sound_a, _talk_sound_b;
byte _talk_sound_mode;
bool _mouthSyncMode;
bool _endOfMouthSync;
uint16 _mouthSyncTimes[52];
uint _curSoundPos;
MP3OffsetTable *offset_table; // SO3 MP3 compressed audio
int num_sound_effects; // SO3 MP3 compressed audio
#ifdef COMPRESSED_SOUND_FILE
#define CACHE_TRACKS 10
/* used for mp3 CD music */
int _cached_tracks[CACHE_TRACKS];
struct mad_header _mad_header[CACHE_TRACKS];
long _mp3_size[CACHE_TRACKS];
FILE *_mp3_tracks[CACHE_TRACKS];
int _mp3_index;
bool _mp3_cd_playing;
#endif
Scumm * _scumm;
public:
#ifdef COMPRESSED_SOUND_FILE
int _current_cache;
#endif
bool _soundsPaused;
int16 _sound_volume_master, _sound_volume_music, _sound_volume_sfx;
byte _sfxMode;
Sound(Scumm *parent);
~Sound();
void addSoundToQueue(int sound);
void addSoundToQueue2(int sound);
void processSoundQues();
void playSound(int sound);
void processSfxQueues();
int startTalkSound(uint32 offset, uint32 b, int mode);
void stopTalkSound();
bool isMouthSyncOff(uint pos);
int isSoundRunning(int sound);
bool isSoundInQueue(int sound);
void stopSound(int a);
void stopAllSounds();
void clearSoundQue();
void soundKludge(int16 * list);
void talkSound(uint32 a, uint32 b, int mode);
void setupSound();
void pauseSounds(bool pause);
int startSfxSound(void *file, int file_size);
void * openSfxFile();
void stopSfxSound();
bool isSfxFinished();
uint32 decode12BitsSample(byte * src, byte ** dst, uint32 size);
void playBundleMusic(int32 song);
void pauseBundleMusic(bool state);
void bundleMusicHandler(Scumm * scumm);
void stopBundleMusic();
void playBundleSound(char *sound);
int playSfxSound(void *sound, uint32 size, uint rate, bool isUnsigned);
int playSfxSound_MP3(void *sound, uint32 size);
#ifdef COMPRESSED_SOUND_FILE
int getCachedTrack(int track);
int playMP3CDTrack(int track, int num_loops, int start, int delay);
int stopMP3CD();
int pollMP3CD();
int updateMP3CD();
#endif
};
#endif

View file

@ -173,7 +173,7 @@ void Scumm::unkMessage1()
a = buffer[2] | (buffer[3] << 8) | (buffer[6] << 16) | (buffer[7] << 24); a = buffer[2] | (buffer[3] << 8) | (buffer[6] << 16) | (buffer[7] << 24);
b = buffer[10] | (buffer[11] << 8) | (buffer[14] << 16) | (buffer[15] << 24); b = buffer[10] | (buffer[11] << 8) | (buffer[14] << 16) | (buffer[15] << 24);
// if (_saveSound != 1) // if (_saveSound != 1)
talkSound(a, b, 1); _sound->talkSound(a, b, 1);
} }
// warning("unkMessage1(\"%s\")", buffer); // warning("unkMessage1(\"%s\")", buffer);
} }
@ -283,7 +283,7 @@ void Scumm::CHARSET_1()
return; return;
if (_haveMsg != 0xFF && _haveMsg != 0xFE) { if (_haveMsg != 0xFF && _haveMsg != 0xFE) {
if (_sfxMode == 0) if (_sound->_sfxMode == 0)
stopTalk(); stopTalk();
return; return;
} }
@ -403,7 +403,7 @@ void Scumm::CHARSET_1()
tmpA = buffer[0] | (buffer[1] << 8) | (buffer[4] << 16) | (buffer[5] << 24); tmpA = buffer[0] | (buffer[1] << 8) | (buffer[4] << 16) | (buffer[5] << 24);
tmpB = buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] << 24); tmpB = buffer[8] | (buffer[9] << 8) | (buffer[12] << 16) | (buffer[13] << 24);
talkSound(tmpA, tmpB, 2); _sound->talkSound(tmpA, tmpB, 2);
buffer += 14; buffer += 14;
// Set flag that speech variant exist of this msg // Set flag that speech variant exist of this msg