diff options
55 files changed, 1444 insertions, 739 deletions
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index 1fb43e96bb..dd5d30bd39 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 7637605dcd..cbc9272e80 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -23,7 +23,6 @@ * */ - #include "base/plugins.h" #include "common/advancedDetector.h" diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 2a4732954c..8a7de9bdaa 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 959a064b7d..9a78769d41 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "graphics/cursorman.h" @@ -31,9 +30,9 @@ #include "gob/draw.h" #include "gob/global.h" #include "gob/util.h" -#include "gob/cdrom.h" #include "gob/game.h" #include "gob/scenery.h" +#include "gob/sound/sound.h" namespace Gob { @@ -170,7 +169,7 @@ void Draw_v1::printTotText(int16 id) { int16 spriteRight, spriteBottom; char buf[20]; - _vm->_cdrom->playMultMusic(); + _vm->_sound->cdPlayMultMusic(); if (!_vm->_game->_totTextData || !_vm->_game->_totTextData->dataPtr) return; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 88d30b8e8a..8c429b1c1e 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "graphics/cursorman.h" diff --git a/engines/gob/driver_vga.cpp b/engines/gob/driver_vga.cpp index 08235f16e2..c4861ca146 100644 --- a/engines/gob/driver_vga.cpp +++ b/engines/gob/driver_vga.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "graphics/primitives.h" diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 666f46fde1..9bdcae567d 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" @@ -35,7 +34,7 @@ #include "gob/parse.h" #include "gob/draw.h" #include "gob/mult.h" -#include "gob/music.h" +#include "gob/sound/sound.h" namespace Gob { @@ -60,9 +59,6 @@ Game::Game(GobEngine *vm) : _vm(vm) { _collStackElemSizes[i] = 0; } - _infIns = 0; - _infogrames = 0; - _curTotFile[0] = 0; _curExtFile[0] = 0; _totToLoad[0] = 0; @@ -105,10 +101,6 @@ Game::Game(GobEngine *vm) : _vm(vm) { } Game::~Game() { - delete _infIns; - - for (int i = 0; i < 60; i++) - _soundSamples[i].free(); } byte *Game::loadExtData(int16 itemId, int16 *pResWidth, @@ -295,16 +287,7 @@ void Game::freeSoundSlot(int16 slot) { if (slot == -1) slot = _vm->_parse->parseValExpr(); - if ((slot < 0) || (slot >= 60) || _soundSamples[slot].empty()) - return; - - SoundDesc &sample = _soundSamples[slot]; - - if (sample.getType() == SOUND_ADL) - if (_vm->_adlib && (_vm->_adlib->getIndex() == slot)) - _vm->_adlib->stopPlay(); - - _vm->_snd->freeSample(sample); + _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot)); } void Game::evaluateScroll(int16 x, int16 y) { @@ -380,7 +363,7 @@ int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY, if ((_vm->_inter->_soundEndTimeKey != 0) && (_vm->_util->getTimeKey() >= _vm->_inter->_soundEndTimeKey)) { - _vm->_snd->stopSound(_vm->_inter->_soundStopVal); + _vm->_sound->blasterStop(_vm->_inter->_soundStopVal); _vm->_inter->_soundEndTimeKey = 0; } diff --git a/engines/gob/game.h b/engines/gob/game.h index 5cf5e1bea6..bca55cd4dc 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -26,10 +26,6 @@ #ifndef GOB_GAME_H #define GOB_GAME_H -#include "sound/mods/infogrames.h" - -#include "gob/sound.h" - namespace Gob { class Game { @@ -119,12 +115,6 @@ public: int16 _extHandle; - SoundDesc _soundSamples[60]; - - Audio::Infogrames::Instruments *_infIns; - Audio::Infogrames *_infogrames; - Audio::SoundHandle _infHandle; - char _totToLoad[20]; int32 _startTimeKey; diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index e9e37a027b..435decd9f2 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "common/stream.h" @@ -32,15 +31,13 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/dataio.h" -#include "gob/music.h" -#include "gob/cdrom.h" #include "gob/draw.h" #include "gob/inter.h" #include "gob/mult.h" #include "gob/video.h" #include "gob/parse.h" -#include "gob/sound.h" #include "gob/scenery.h" +#include "gob/sound/sound.h" namespace Gob { @@ -74,11 +71,11 @@ void Game_v1::playTot(int16 skipPlay) { _vm->_draw->_fontToSprite[i].height = -1; } - if (_vm->_platform == Common::kPlatformMacintosh) { - if (_vm->_adlib) - _vm->_adlib->stopPlay(); - } else - _vm->_cdrom->stopPlaying(); + if (_vm->getPlatform() == Common::kPlatformMacintosh) + _vm->_sound->adlibStop(); + else + _vm->_sound->cdStop(); + _vm->_draw->animateCursor(4); _vm->_inter->initControlVars(1); _vm->_mult->initAll(); @@ -229,7 +226,7 @@ void Game_v1::playTot(int16 skipPlay) { for (int i = 0; i < SPRITES_COUNT; i++) _vm->_draw->freeSprite(i); - _vm->_snd->stopSound(0); + _vm->_sound->blasterStop(0); for (int i = 0; i < 20; i++) freeSoundSlot(i); diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 45542541e3..ff444f4a69 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "common/stream.h" @@ -38,9 +37,9 @@ #include "gob/mult.h" #include "gob/parse.h" #include "gob/scenery.h" -#include "gob/sound.h" #include "gob/video.h" #include "gob/videoplayer.h" +#include "gob/sound/sound.h" namespace Gob { @@ -265,11 +264,14 @@ void Game_v2::playTot(int16 skipPlay) { if (skipPlay != -1) { _vm->_goblin->freeObjects(); - _vm->_snd->stopSound(0); + _vm->_sound->blasterStop(0); + + for (int i = 0; i < Sound::kSoundsCount; i++) { + SoundDesc *sound = _vm->_sound->sampleGetBySlot(i); - for (int i = 0; i < 60; i++) - if (_soundSamples[i].getType() == SOUND_SND) - _vm->_snd->freeSample(_soundSamples[i]); + if (sound && (sound->getType() == SOUND_SND)) + _vm->_sound->sampleFree(sound); + } } _vm->_vidPlayer->primaryClose(); diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 863665357b..951f331cbe 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "common/events.h" @@ -37,18 +36,16 @@ #include "gob/util.h" #include "gob/dataio.h" #include "gob/game.h" -#include "gob/sound.h" +#include "gob/sound/sound.h" #include "gob/init.h" #include "gob/inter.h" #include "gob/draw.h" -#include "gob/cdrom.h" #include "gob/goblin.h" #include "gob/map.h" #include "gob/mult.h" #include "gob/palanim.h" #include "gob/parse.h" #include "gob/scenery.h" -#include "gob/music.h" #include "gob/videoplayer.h" #include "gob/saveload.h" @@ -71,13 +68,12 @@ const Common::Language GobEngine::_gobToScummVMLang[] = { GobEngine::GobEngine(OSystem *syst) : Engine(syst) { _vm = this; - _snd = 0; _adlib = 0; _mult = 0; - _game = 0; _global = 0; _cdrom = 0; - _dataIO = 0; _goblin = 0; _vidPlayer = 0; - _init = 0; _inter = 0; _map = 0; - _palAnim = 0; _parse = 0; _scenery = 0; - _draw = 0; _util = 0; _video = 0; - _saveLoad = 0; + _sound = 0; _mult = 0; _game = 0; + _global = 0; _dataIO = 0; _goblin = 0; + _vidPlayer = 0; _init = 0; _inter = 0; + _map = 0; _palAnim = 0; _parse = 0; + _scenery = 0; _draw = 0; _util = 0; + _video = 0; _saveLoad = 0; // Setup mixer _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); @@ -118,6 +114,12 @@ void GobEngine::shutdown() { _quitRequested = true; } +const char *GobEngine::getLangDesc(int16 language) const { + if ((language < 0) || (language > 8)) + language = 2; + return Common::getLanguageDescription(_gobToScummVMLang[language]); +} + void GobEngine::validateLanguage() { if (_vm->_global->_languageWanted != _vm->_global->_language) { warning("Your game version doesn't support the requested language %s", @@ -140,6 +142,30 @@ void GobEngine::validateVideoMode(int16 videoMode) { error("Video mode 0x%X is not supported!", videoMode); } +Common::Platform GobEngine::getPlatform() const { + return _platform; +} + +GameType GobEngine::getGameType() const { + return _gameType; +} + +bool GobEngine::isCD() const { + return (_features & kFeaturesCD) != 0; +} + +bool GobEngine::isEGA() const { + return (_features & kFeaturesEGA) != 0; +} + +bool GobEngine::is640() const { + return (_features & kFeatures640) != 0; +} + +bool GobEngine::hasAdlib() const { + return (_features & kFeaturesAdlib) != 0; +} + int GobEngine::init() { if (!initGameParts()) { GUIErrorMessage("GobEngine::init(): Unknown version of game engine"); @@ -220,7 +246,8 @@ int GobEngine::init() { } bool GobEngine::initGameParts() { - _adlib = 0; + _noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL; + _saveLoad = 0; _global = new Global(this); @@ -228,8 +255,7 @@ bool GobEngine::initGameParts() { _dataIO = new DataIO(this); _palAnim = new PalAnim(this); _vidPlayer = new VideoPlayer(this); - _cdrom = new CDROM(this); - _snd = new Snd(this); + _sound = new Sound(this); switch (_gameType) { case kGameTypeGob1: @@ -336,10 +362,6 @@ bool GobEngine::initGameParts() { break; } - _noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL; - if (!_noMusic && hasAdlib()) - _adlib = new Adlib(this); - if (is640()) { _video->_surfWidth = _width = 640; _video->_surfHeight = _video->_splitHeight1 = _height = 480; @@ -360,12 +382,9 @@ bool GobEngine::initGameParts() { } void GobEngine::deinitGameParts() { - delete _snd; _snd = 0; - delete _adlib; _adlib = 0; delete _mult; _mult = 0; delete _game; _game = 0; delete _global; _global = 0; - delete _cdrom; _cdrom = 0; delete _dataIO; _dataIO = 0; delete _goblin; _goblin = 0; delete _vidPlayer; _vidPlayer = 0; @@ -379,6 +398,7 @@ void GobEngine::deinitGameParts() { delete _util; _util = 0; delete _video; _video = 0; delete _saveLoad; _saveLoad = 0; + delete _sound; _sound = 0; } } // End of namespace Gob diff --git a/engines/gob/gob.h b/engines/gob/gob.h index e23e917a7c..e1d75bd2a4 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -35,11 +35,10 @@ namespace Gob { class Game; -class Snd; +class Sound; class Video; class Global; class Draw; -class CDROM; class DataIO; class Goblin; class VideoPlayer; @@ -52,7 +51,6 @@ class Parse; class Scenery; class Util; class SaveLoad; -class Adlib; #define VARP(offs) (_vm->_global->_inter_variables + (offs)) #define WRITE_VARO_UINT32(offs, val) _vm->_global->writeVar(offs, (uint32) (val)) @@ -171,9 +169,13 @@ private: struct GOBGameDescription; class GobEngine : public Engine { -protected: +private: GobEngine *_vm; + GameType _gameType; + int32 _features; + Common::Platform _platform; + int go(); int init(); @@ -185,11 +187,7 @@ public: Common::RandomSource _rnd; - GameType _gameType; - int32 _features; Common::Language _language; - Common::Platform _platform; - uint16 _width; uint16 _height; uint8 _mode; @@ -204,10 +202,9 @@ public: Util *_util; DataIO *_dataIO; Game *_game; - Snd *_snd; + Sound *_sound; Video *_video; Draw *_draw; - CDROM *_cdrom; Goblin *_goblin; Init *_init; Map *_map; @@ -217,24 +214,20 @@ public: Scenery *_scenery; Inter *_inter; SaveLoad *_saveLoad; - Adlib *_adlib; VideoPlayer *_vidPlayer; void shutdown(); - const char *getLangDesc(int16 language) { - if ((language < 0) || (language > 8)) - language = 2; - return Common::getLanguageDescription(_gobToScummVMLang[language]); - } + const char *getLangDesc(int16 language) const; void validateLanguage(); void validateVideoMode(int16 videoMode); - GameType getGameType() { return _gameType; } - bool isCD() { return (_features & kFeaturesCD) != 0; } - bool isEGA() { return (_features & kFeaturesEGA) != 0; } - bool is640() { return (_features & kFeatures640) != 0; } - bool hasAdlib() { return (_features & kFeaturesAdlib) != 0; } + Common::Platform getPlatform() const; + GameType getGameType() const; + bool isCD() const; + bool isEGA() const; + bool is640() const; + bool hasAdlib() const; GobEngine(OSystem *syst); virtual ~GobEngine(); diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp index f97bd14fed..d3857e2066 100644 --- a/engines/gob/goblin.cpp +++ b/engines/gob/goblin.cpp @@ -32,7 +32,7 @@ #include "gob/map.h" #include "gob/mult.h" #include "gob/scenery.h" -#include "gob/sound.h" +#include "gob/sound/sound.h" namespace Gob { @@ -255,8 +255,8 @@ void Goblin::sortByOrder(Util::List *list) { void Goblin::playSound(SoundDesc &snd, int16 repCount, int16 freq) { if (!snd.empty()) { - _vm->_snd->stopSound(0); - _vm->_snd->playSample(snd, repCount, freq); + _vm->_sound->blasterStop(0); + _vm->_sound->blasterPlay(&snd, repCount, freq); } } @@ -1216,7 +1216,7 @@ void Goblin::zeroObjects(void) { _objects[i] = 0; for (int i = 0; i < 16; i++) - _vm->_snd->freeSample(_soundData[i]); + _vm->_sound->sampleFree(&_soundData[i]); } void Goblin::freeAllObjects(void) { @@ -1717,12 +1717,12 @@ void Goblin::playSounds(Mult::Mult_Object *obj) { if (!speaker) { sndSlot = obj->goblinStates[animData->state][i].sndItem; - _vm->_snd->stopSound(0); + _vm->_sound->blasterStop(0); if (sndSlot < _soundSlotsCount) - _vm->_snd->playSample(_vm->_game->_soundSamples[_soundSlots[sndSlot] & 0x7FFF], + _vm->_sound->blasterPlay(_vm->_sound->sampleGetBySlot(_soundSlots[sndSlot] & 0x7FFF), repCount, frequency); } else - _vm->_snd->speakerOn(frequency, repCount * 10); + _vm->_sound->speakerOn(frequency, repCount * 10); } } diff --git a/engines/gob/goblin.h b/engines/gob/goblin.h index f7ac4aa549..3fd8a9f93b 100644 --- a/engines/gob/goblin.h +++ b/engines/gob/goblin.h @@ -27,8 +27,8 @@ #define GOB_GOBLIN_H #include "gob/util.h" -#include "gob/sound.h" #include "gob/mult.h" +#include "gob/sound/sounddesc.h" namespace Gob { diff --git a/engines/gob/goblin_v1.cpp b/engines/gob/goblin_v1.cpp index f7bdbf10a5..6ac086767b 100644 --- a/engines/gob/goblin_v1.cpp +++ b/engines/gob/goblin_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" @@ -32,7 +31,7 @@ #include "gob/map.h" #include "gob/mult.h" #include "gob/scenery.h" -#include "gob/sound.h" +#include "gob/sound/sound.h" namespace Gob { @@ -48,7 +47,7 @@ void Goblin_v1::freeObjects(void) { int16 col; for (int i = 0; i < 16; i++) - _vm->_snd->freeSample(_soundData[i]); + _vm->_sound->sampleFree(&_soundData[i]); for (int i = 0; i < 4; i++) { if (_goblins[i] == 0) @@ -488,19 +487,19 @@ void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, if ((gobDesc->state >= 0) && (gobDesc->state < 10) && (gobDesc->stateMach == gobDesc->realStateMach) && ((gobDesc->curFrame == 3) || (gobDesc->curFrame == 6))) { - _vm->_snd->speakerOn(10 * _vm->_util->getRandom(3) + 50, 5); + _vm->_sound->speakerOn(10 * _vm->_util->getRandom(3) + 50, 5); } if ((_currentGoblin == 0) && (gobDesc->stateMach == gobDesc->realStateMach) && ((gobDesc->state == 10) || (gobDesc->state == 11)) && (gobDesc->curFrame == 9)) { - _vm->_snd->stopSound(0); + _vm->_sound->blasterStop(0); if (_itemIndInPocket != -1) - _vm->_snd->playSample(_soundData[14], 1, 9000); + _vm->_sound->blasterPlay(&_soundData[14], 1, 9000); else - _vm->_snd->playSample(_soundData[14], 1, 5000); + _vm->_sound->blasterPlay(&_soundData[14], 1, 5000); } if (_boreCounter++ == 120) { diff --git a/engines/gob/goblin_v2.cpp b/engines/gob/goblin_v2.cpp index c9e155ad08..93c4c74ecc 100644 --- a/engines/gob/goblin_v2.cpp +++ b/engines/gob/goblin_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 4d184c53d3..b1e31b34c2 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" @@ -31,13 +30,12 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/dataio.h" -#include "gob/cdrom.h" #include "gob/draw.h" #include "gob/game.h" #include "gob/palanim.h" -#include "gob/sound.h" #include "gob/video.h" #include "gob/videoplayer.h" +#include "gob/sound/sound.h" namespace Gob { @@ -51,8 +49,8 @@ void Init::cleanup(void) { _vm->_video->freeDriver(); _vm->_global->_primarySurfDesc = 0; - _vm->_snd->speakerOff(); - _vm->_snd->stopSound(0); + _vm->_sound->speakerOff(); + _vm->_sound->blasterStop(0); _vm->_dataIO->closeDataFile(); } @@ -169,8 +167,8 @@ void Init::initGame(const char *totName) { strcpy(_vm->_game->_curTotFile, buffer); - _vm->_cdrom->testCD(1, "GOB"); - _vm->_cdrom->readLIC("gob.lic"); + _vm->_sound->cdTest(1, "GOB"); + _vm->_sound->cdLoadLIC("gob.lic"); // Search for a Coktel logo animation or image to display imdHandle = _vm->_dataIO->openData("coktel.imd"); @@ -213,8 +211,8 @@ void Init::initGame(const char *totName) { _vm->_game->start(); - _vm->_cdrom->stopPlaying(); - _vm->_cdrom->freeLICbuffer(); + _vm->_sound->cdStop(); + _vm->_sound->cdUnloadLIC(); delete[] _vm->_global->_inter_variables; delete[] _vm->_global->_inter_variablesSizes; diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp index 8065c4dc8c..90456f927c 100644 --- a/engines/gob/init_v1.cpp +++ b/engines/gob/init_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp index bb29f4e8fd..b468c15c25 100644 --- a/engines/gob/init_v2.cpp +++ b/engines/gob/init_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" @@ -50,8 +49,8 @@ void Init_v2::initVideo() { _vm->_global->_inVM = 0; _vm->_global->_colorCount = 16; - if (((_vm->_platform == Common::kPlatformPC) || - (_vm->_platform == Common::kPlatformMacintosh)) && + if (((_vm->getPlatform() == Common::kPlatformPC) || + (_vm->getPlatform() == Common::kPlatformMacintosh)) && ((_vm->_global->_videoMode == 0x13) || (_vm->_global->_videoMode == 0x14))) _vm->_global->_colorCount = 256; diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index de3ac4b1f5..dd3fdf3684 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" @@ -34,7 +33,7 @@ #include "gob/game.h" #include "gob/parse.h" #include "gob/scenery.h" -#include "gob/sound.h" +#include "gob/sound/sound.h" #include <time.h> // FIXME: for Inter::renewTimeInVars() @@ -154,7 +153,7 @@ void Inter::storeKey(int16 key) { WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->_startTimeKey); storeMouse(); - WRITE_VAR(1, _vm->_snd->_playingSound); + WRITE_VAR(1, _vm->_sound->blasterPlayingSound()); if (key == 0x4800) key = 0x0B; diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index 702950d539..d493fb00d3 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" @@ -34,9 +33,9 @@ #include "gob/draw.h" #include "gob/game.h" #include "gob/palanim.h" -#include "gob/sound.h" #include "gob/video.h" #include "gob/videoplayer.h" +#include "gob/sound/sound.h" namespace Gob { @@ -768,9 +767,9 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { return; for (i = 0; i < 4; i++) - _vm->_snd->loadSample(samples[i], sndFiles[i]); - _vm->_snd->playComposition(comp, 0, samples, 4); - _vm->_snd->waitEndPlay(true, false); + _vm->_sound->sampleLoad(&samples[i], sndFiles[i]); + _vm->_sound->blasterPlayComposition(comp, 0, samples, 4); + _vm->_sound->blasterWaitEndPlay(true, false); _vm->_palAnim->fade(0, 0, 0); _vm->_video->clearSurf(_vm->_draw->_frontSurface); } @@ -787,12 +786,12 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { static const char *palFiles[] = {"2ou2.clt", "2ou3.clt", "2ou4.clt", "2ou5.clt"}; for (int i = 0; i < 2; i++) - _vm->_snd->loadSample(samples[i], sndFiles[i]); + _vm->_sound->sampleLoad(&samples[i], sndFiles[i]); for (int i = 0; i < 4; i++) palettes[i] = _vm->_dataIO->getData(palFiles[i]); palBak = _vm->_global->_pPaletteDesc->vgaPal; - _vm->_snd->playComposition(comp, 0, samples, 2); + _vm->_sound->blasterPlayComposition(comp, 0, samples, 2); for (int i = 0; i < 20; i++) { for (int j = 0; j < 4; j++) { _vm->_global->_pPaletteDesc->vgaPal = (Video::Color *) palettes[j]; @@ -801,7 +800,7 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { } if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || _vm->_quitRequested) { - _vm->_snd->stopSound(10); + _vm->_sound->blasterStop(10); _vm->_palAnim->fade(0, -2, 0); _vm->_video->clearSurf(_vm->_draw->_frontSurface); memset((char *) _vm->_draw->_vgaPalette, 0, 768); @@ -811,7 +810,7 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { break; } } - _vm->_snd->waitEndPlay(false, false); + _vm->_sound->blasterWaitEndPlay(false, false); _vm->_global->_pPaletteDesc->vgaPal = palBak; for (int i = 0; i < 4; i++) diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 9707a628b4..a809a44b40 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "common/file.h" @@ -32,8 +31,6 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/dataio.h" -#include "gob/music.h" -#include "gob/cdrom.h" #include "gob/draw.h" #include "gob/game.h" #include "gob/goblin.h" @@ -43,8 +40,8 @@ #include "gob/palanim.h" #include "gob/parse.h" #include "gob/scenery.h" -#include "gob/sound.h" #include "gob/video.h" +#include "gob/sound/sound.h" namespace Gob { @@ -1071,12 +1068,8 @@ void Inter_v1::o1_loadCurLayer() { void Inter_v1::o1_playCDTrack() { evalExpr(0); - if (_vm->_platform == Common::kPlatformMacintosh) { - if (_vm->_adlib) - _vm->_adlib->playTrack(_vm->_global->_inter_resStr); - } else - // Used in gob1 CD - _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); + _vm->_sound->adlibPlayBgMusic(); // Mac version + _vm->_sound->cdPlay(_vm->_global->_inter_resStr); // PC CD version } void Inter_v1::o1_getCDTrackPos() { @@ -1088,19 +1081,15 @@ void Inter_v1::o1_getCDTrackPos() { _vm->_util->longDelay(1); - int pos = _vm->_cdrom->getTrackPos(); + int pos = _vm->_sound->cdGetTrackPos(); if (pos == -1) pos = 32767; WRITE_VAR(5, pos); } void Inter_v1::o1_stopCD() { - if (_vm->_platform == Common::kPlatformMacintosh) { - if (_vm->_adlib) - _vm->_adlib->stopPlay(); - } else - // Used in gob1 CD - _vm->_cdrom->stopPlaying(); + _vm->_sound->adlibStop(); // Mac version + _vm->_sound->cdStop(); // PC CD version } void Inter_v1::o1_loadFontToSprite() { @@ -1685,7 +1674,7 @@ bool Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { break; default: - _vm->_snd->speakerOnUpdate(cmd); + _vm->_sound->speakerOnUpdate(cmd); if (cmd < 20) { _vm->_util->delay(cmd); _noBusyWait = true; @@ -1759,12 +1748,12 @@ bool Inter_v1::o1_renewTimeInVars(OpFuncParams ¶ms) { } bool Inter_v1::o1_speakerOn(OpFuncParams ¶ms) { - _vm->_snd->speakerOn(_vm->_parse->parseValExpr(), -1); + _vm->_sound->speakerOn(_vm->_parse->parseValExpr(), -1); return false; } bool Inter_v1::o1_speakerOff(OpFuncParams ¶ms) { - _vm->_snd->speakerOff(); + _vm->_sound->speakerOff(); return false; } @@ -1978,10 +1967,10 @@ bool Inter_v1::o1_playSound(OpFuncParams ¶ms) { repCount = _vm->_parse->parseValExpr(); frequency = _vm->_parse->parseValExpr(); - SoundDesc &sample = _vm->_game->_soundSamples[index]; + SoundDesc *sample = _vm->_sound->sampleGetBySlot(index); _soundEndTimeKey = 0; - if (sample.empty()) + if (!sample || sample->empty()) return false; if (repCount < 0) { @@ -1991,31 +1980,28 @@ bool Inter_v1::o1_playSound(OpFuncParams ¶ms) { repCount = -repCount; _soundEndTimeKey = _vm->_util->getTimeKey(); - freq2 = frequency ? frequency : sample._frequency; + freq2 = frequency ? frequency : sample->_frequency; endRep = MAX(repCount - 1, 1); - _soundStopVal = sample.calcFadeOutLength(freq2); - _soundEndTimeKey += sample.calcLength(endRep, freq2, true); + _soundStopVal = sample->calcFadeOutLength(freq2); + _soundEndTimeKey += sample->calcLength(endRep, freq2, true); } - if (sample.getType() == SOUND_ADL) { - if (_vm->_adlib) { - _vm->_adlib->load(sample.getData(), sample.size(), index); - _vm->_adlib->setRepeating(repCount - 1); - _vm->_adlib->startPlay(); - } + if (sample->getType() == SOUND_ADL) { + _vm->_sound->adlibLoad(sample->getData(), sample->size(), index); + _vm->_sound->adlibSetRepeating(repCount - 1); + _vm->_sound->adlibPlay(); } else { - _vm->_snd->stopSound(0); - _vm->_snd->playSample(sample, repCount - 1, frequency); + _vm->_sound->blasterStop(0); + _vm->_sound->blasterPlay(sample, repCount - 1, frequency); } return false; } bool Inter_v1::o1_stopSound(OpFuncParams ¶ms) { - if (_vm->_adlib) - _vm->_adlib->stopPlay(); - _vm->_snd->stopSound(_vm->_parse->parseValExpr()); + _vm->_sound->adlibStop(); + _vm->_sound->blasterStop(_vm->_parse->parseValExpr()); _soundEndTimeKey = 0; return false; @@ -2032,7 +2018,7 @@ bool Inter_v1::o1_freeSoundSlot(OpFuncParams ¶ms) { } bool Inter_v1::o1_waitEndPlay(OpFuncParams ¶ms) { - _vm->_snd->waitEndPlay(); + _vm->_sound->blasterWaitEndPlay(); return false; } @@ -2046,7 +2032,7 @@ bool Inter_v1::o1_playComposition(OpFuncParams ¶ms) { for (int i = 0; i < 50; i++) composition[i] = (int16) VAR_OFFSET(dataVar + i * 4); - _vm->_snd->playComposition(composition, freqVal); + _vm->_sound->blasterPlayComposition(composition, freqVal); return false; } @@ -2803,11 +2789,9 @@ void Inter_v1::o1_animateObjects(OpGobParams ¶ms) { void Inter_v1::o1_drawObjects(OpGobParams ¶ms) { _vm->_goblin->drawObjects(); - if (_vm->_platform == Common::kPlatformMacintosh) { - if (_vm->_adlib) - _vm->_adlib->playBgMusic(); - } else if (_vm->_cdrom->getTrackPos() == -1) - _vm->_cdrom->playBgMusic(); + _vm->_sound->adlibPlayBgMusic(); // Mac version + if (_vm->_sound->cdGetTrackPos() == -1) + _vm->_sound->cdPlayBgMusic(); // PC CD version } void Inter_v1::o1_loadMap(OpGobParams ¶ms) { @@ -2993,9 +2977,11 @@ int16 Inter_v1::loadSound(int16 slot) { dataSize = (uint32) ((int32) totSize); } - if (dataPtr) - _vm->_game->_soundSamples[slot].load(SOUND_SND, source, - dataPtr, dataSize); + if (dataPtr) { + SoundDesc *sample = _vm->_sound->sampleGetBySlot(slot); + if (sample) + sample->load(SOUND_SND, source, dataPtr, dataSize); + } return 0; } diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 2442e4dcf2..36f33e6553 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "sound/mixer.h" #include "sound/mods/infogrames.h" @@ -33,8 +32,6 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/dataio.h" -#include "gob/music.h" -#include "gob/cdrom.h" #include "gob/draw.h" #include "gob/game.h" #include "gob/goblin.h" @@ -42,10 +39,10 @@ #include "gob/mult.h" #include "gob/parse.h" #include "gob/scenery.h" -#include "gob/sound.h" #include "gob/video.h" #include "gob/saveload.h" #include "gob/videoplayer.h" +#include "gob/sound/sound.h" namespace Gob { @@ -1086,16 +1083,16 @@ void Inter_v2::o2_playCDTrack() { _vm->_draw->blitInvalidated(); evalExpr(0); - _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); + _vm->_sound->cdPlay(_vm->_global->_inter_resStr); } void Inter_v2::o2_waitCDTrackEnd() { - while (_vm->_cdrom->getTrackPos() >= 0) + while (_vm->_sound->cdGetTrackPos() >= 0) _vm->_util->longDelay(1); } void Inter_v2::o2_stopCD() { - _vm->_cdrom->stopPlaying(); + _vm->_sound->cdStop(); } void Inter_v2::o2_readLIC() { @@ -1105,11 +1102,11 @@ void Inter_v2::o2_readLIC() { strncpy0(path, _vm->_global->_inter_resStr, 35); strcat(path, ".LIC"); - _vm->_cdrom->readLIC(path); + _vm->_sound->cdLoadLIC(path); } void Inter_v2::o2_freeLIC() { - _vm->_cdrom->freeLICbuffer(); + _vm->_sound->cdUnloadLIC(); } void Inter_v2::o2_getCDTrackPos() { @@ -1121,8 +1118,8 @@ void Inter_v2::o2_getCDTrackPos() { varPos = _vm->_parse->parseVarIndex(); varName = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(varPos, _vm->_cdrom->getTrackPos(GET_VARO_STR(varName))); - WRITE_VARO_STR(varName, _vm->_cdrom->getCurTrack()); + WRITE_VAR_OFFSET(varPos, _vm->_sound->cdGetTrackPos(GET_VARO_STR(varName))); + WRITE_VARO_STR(varName, _vm->_sound->cdGetCurrentTrack()); } void Inter_v2::o2_loadFontToSprite() { @@ -1883,10 +1880,9 @@ bool Inter_v2::o2_stopSound(OpFuncParams ¶ms) { expr = _vm->_parse->parseValExpr(); if (expr < 0) { - if (_vm->_adlib) - _vm->_adlib->stopPlay(); + _vm->_sound->adlibStop(); } else - _vm->_snd->stopSound(expr); + _vm->_sound->blasterStop(expr); _soundEndTimeKey = 0; return false; @@ -2009,7 +2005,7 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) { WRITE_VAR(59, stream->readUint32LE()); // The scripts in some versions divide through 256^3 then, // effectively doing a LE->BE conversion - if ((_vm->_platform != Common::kPlatformPC) && (VAR(59) < 256)) + if ((_vm->getPlatform() != Common::kPlatformPC) && (VAR(59) < 256)) WRITE_VAR(59, SWAP_BYTES_32(VAR(59))); } else retSize = stream->read(buf, size); @@ -2054,29 +2050,11 @@ void Inter_v2::o2_loadInfogramesIns(OpGobParams ¶ms) { varName = load16(); - if (_vm->_noMusic) - return; - strncpy0(fileName, GET_VAR_STR(varName), 15); strcat(fileName, ".INS"); - debugC(1, kDebugMusic, "Loading Infogrames instrument file \"%s\"", - fileName); - - if (_vm->_game->_infogrames) { - _vm->_mixer->stopHandle(_vm->_game->_infHandle); - delete _vm->_game->_infogrames; - _vm->_game->_infogrames = 0; - } + debugC(1, kDebugMusic, "Loading Infogrames instrument file \"%s\"", fileName); - if (_vm->_game->_infIns) - delete _vm->_game->_infIns; - - _vm->_game->_infIns = new Audio::Infogrames::Instruments; - if (!_vm->_game->_infIns->load(fileName)) { - warning("Couldn't load instruments file"); - delete _vm->_game->_infIns; - _vm->_game->_infIns = 0; - } + _vm->_sound->infogramesLoadInstruments(fileName); } void Inter_v2::o2_playInfogrames(OpGobParams ¶ms) { @@ -2085,58 +2063,24 @@ void Inter_v2::o2_playInfogrames(OpGobParams ¶ms) { varName = load16(); - if (_vm->_noMusic) - return; - strncpy0(fileName, GET_VAR_STR(varName), 15); strcat(fileName, ".DUM"); debugC(1, kDebugMusic, "Playing Infogrames music file \"%s\"", fileName); - if (!_vm->_game->_infIns) { - _vm->_game->_infIns = new Audio::Infogrames::Instruments; - - if (!_vm->_game->_infIns->load("i1.ins")) { - warning("Couldn't load instruments file"); - delete _vm->_game->_infIns; - _vm->_game->_infIns = 0; - } - } - - if (_vm->_game->_infIns) { - _vm->_mixer->stopHandle(_vm->_game->_infHandle); - delete _vm->_game->_infogrames; - _vm->_game->_infogrames = - new Audio::Infogrames(*_vm->_game->_infIns, true, - _vm->_mixer->getOutputRate(), - _vm->_mixer->getOutputRate() / 75); - - if (!_vm->_game->_infogrames->load(fileName)) { - warning("Couldn't load infogrames music"); - delete _vm->_game->_infogrames; - _vm->_game->_infogrames = 0; - } else - _vm->_mixer->playInputStream(Audio::Mixer::kMusicSoundType, - &_vm->_game->_infHandle, _vm->_game->_infogrames, - -1, 255, 0, false); - } + _vm->_sound->infogramesLoadSong(fileName); + _vm->_sound->infogramesPlay(); } void Inter_v2::o2_startInfogrames(OpGobParams ¶ms) { load16(); - if (_vm->_game->_infogrames && - !_vm->_mixer->isSoundHandleActive(_vm->_game->_infHandle)) { - _vm->_game->_infogrames->restart(); - _vm->_mixer->playInputStream(Audio::Mixer::kMusicSoundType, - &_vm->_game->_infHandle, _vm->_game->_infogrames, - -1, 255, 0, false); - } + _vm->_sound->infogramesPlay(); } void Inter_v2::o2_stopInfogrames(OpGobParams ¶ms) { load16(); - _vm->_mixer->stopHandle(_vm->_game->_infHandle); + _vm->_sound->infogramesStop(); } void Inter_v2::o2_handleGoblins(OpGobParams ¶ms) { @@ -2172,15 +2116,15 @@ int16 Inter_v2::loadSound(int16 search) { } else { id = load16(); - for (slot = 0; slot < 60; slot++) - if (_vm->_game->_soundSamples[slot].isId(id)) { + for (slot = 0; slot < Sound::kSoundsCount; slot++) + if (_vm->_sound->sampleGetBySlot(slot)->isId(id)) { slotIdMask = 0x8000; break; } - if (slot == 60) { - for (slot = 59; slot >= 0; slot--) { - if (_vm->_game->_soundSamples[slot].empty()) + if (slot == Sound::kSoundsCount) { + for (slot = (Sound::kSoundsCount - 1); slot >= 0; slot--) { + if (_vm->_sound->sampleGetBySlot(slot)->empty()) break; } @@ -2192,7 +2136,9 @@ int16 Inter_v2::loadSound(int16 search) { } } - _vm->_game->freeSoundSlot(slot); + SoundDesc *sample = _vm->_sound->sampleGetBySlot(slot); + + _vm->_sound->sampleFree(sample, true, slot); if (id == -1) { char sndfile[14]; @@ -2224,8 +2170,8 @@ int16 Inter_v2::loadSound(int16 search) { } if (dataPtr) { - _vm->_game->_soundSamples[slot].load(type, source, dataPtr, dataSize); - _vm->_game->_soundSamples[slot]._id = id; + sample->load(type, source, dataPtr, dataSize); + sample->_id = id; } return slot | slotIdMask; diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp index b24e54ffbd..6ed05af690 100644 --- a/engines/gob/inter_v4.cpp +++ b/engines/gob/inter_v4.cpp @@ -640,8 +640,9 @@ void Inter_v4::setupOpcodes() { } void Inter_v4::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s) - %s, %ld", + i, i, getOpcodeDrawDesc(i), + _vm->_game->_curTotFile, _vm->_global->_inter_execPtr - _vm->_game->_totFileData); OpcodeDrawProcV4 op = _opcodesDrawV4[i].proc; @@ -652,8 +653,9 @@ void Inter_v4::executeDrawOpcode(byte i) { } bool Inter_v4::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", - i, j, i, j, getOpcodeFuncDesc(i, j)); + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s) - %s, %ld", + i, j, i, j, getOpcodeFuncDesc(i, j), + _vm->_game->_curTotFile, _vm->_global->_inter_execPtr - _vm->_game->_totFileData); if ((i > 4) || (j > 15)) { warning("unimplemented opcodeFunc: %d.%d", i, j); @@ -671,8 +673,9 @@ bool Inter_v4::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { } void Inter_v4::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s) - %s, %ld", + i, i, getOpcodeGoblinDesc(i), + _vm->_game->_curTotFile, _vm->_global->_inter_execPtr - _vm->_game->_totFileData); OpcodeGoblinProcV4 op = NULL; diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp index cd8f9e3758..75867aaa6c 100644 --- a/engines/gob/map.cpp +++ b/engines/gob/map.cpp @@ -23,8 +23,6 @@ * */ - - #include "gob/gob.h" #include "gob/map.h" #include "gob/goblin.h" diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp index c4b68fad85..4ac99d2465 100644 --- a/engines/gob/map_v1.cpp +++ b/engines/gob/map_v1.cpp @@ -23,15 +23,14 @@ * */ - #include "common/stream.h" #include "gob/gob.h" #include "gob/map.h" #include "gob/dataio.h" #include "gob/goblin.h" -#include "gob/sound.h" #include "gob/mult.h" +#include "gob/sound/sound.h" namespace Gob { @@ -160,7 +159,7 @@ void Map_v1::loadSounds(Common::SeekableReadStream &data) { strcpy(sndNames[i], buf); } - _vm->_snd->loadSample(_vm->_goblin->_soundData[14], "diamant1.snd"); + _vm->_sound->sampleLoad(&_vm->_goblin->_soundData[14], "diamant1.snd"); for (int i = 0; i < count; i++) { handle = _vm->_dataIO->openData(sndNames[i]); @@ -168,7 +167,7 @@ void Map_v1::loadSounds(Common::SeekableReadStream &data) { continue; _vm->_dataIO->closeData(handle); - _vm->_snd->loadSample(_vm->_goblin->_soundData[i], sndNames[i]); + _vm->_sound->sampleLoad(&_vm->_goblin->_soundData[i], sndNames[i]); } } diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp index 2c383f5bb2..668b4d2e97 100644 --- a/engines/gob/map_v2.cpp +++ b/engines/gob/map_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/stream.h" #include "gob/gob.h" diff --git a/engines/gob/module.mk b/engines/gob/module.mk index aa2a235327..4ff9bdf920 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -1,7 +1,13 @@ MODULE := engines/gob MODULE_OBJS := \ - cdrom.o \ + sound/sound.o \ + sound/sounddesc.o \ + sound/pcspeaker.o \ + sound/adlib.o \ + sound/infogrames.o \ + sound/soundblaster.o \ + sound/cdrom.o \ dataio.o \ detection.o \ draw.o \ @@ -38,7 +44,6 @@ MODULE_OBJS := \ mult.o \ mult_v1.o \ mult_v2.o \ - music.o \ palanim.o \ parse.o \ parse_v1.o \ @@ -49,7 +54,6 @@ MODULE_OBJS := \ scenery.o \ scenery_v1.o \ scenery_v2.o \ - sound.o \ util.o \ video.o \ video_v1.o \ diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index 70b6d33136..bc9fe4dc11 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" @@ -34,9 +33,9 @@ #include "gob/game.h" #include "gob/palanim.h" #include "gob/scenery.h" -#include "gob/sound.h" #include "gob/video.h" #include "gob/videoplayer.h" +#include "gob/sound/sound.h" namespace Gob { @@ -188,7 +187,7 @@ void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape, if (_frame >= endFrame) stopNoClear = true; - if (_vm->_snd->_playingSound) + if (_vm->_sound->blasterPlayingSound()) stop = false; _vm->_util->processInput(); @@ -225,8 +224,8 @@ void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape, _animDataAllocated = false; } - if (_vm->_snd->_playingSound) - _vm->_snd->stopSound(10); + if (_vm->_sound->blasterPlayingSound()) + _vm->_sound->blasterStop(10); WRITE_VAR(57, (uint32) -1); } else @@ -415,21 +414,24 @@ void Mult::doSoundAnim(bool &stop, int16 frame) { if (sndKey->cmd != -1) { if ((sndKey->cmd == 1) || (sndKey->cmd == 4)) { - SoundDesc &sample = _vm->_game->_soundSamples[sndKey->soundIndex]; + SoundDesc *sample = _vm->_sound->sampleGetBySlot(sndKey->soundIndex); - _vm->_snd->stopSound(0); - if (!sample.empty()) - _vm->_snd->playSample(sample, sndKey->repCount, + _vm->_sound->blasterStop(0); + if (sample && !sample->empty()) + _vm->_sound->blasterPlay(sample, sndKey->repCount, sndKey->freq, sndKey->fadeLength); } } else { - if (_vm->_snd->_playingSound) - _vm->_snd->stopSound(sndKey->fadeLength); + if (_vm->_sound->blasterPlayingSound()) + _vm->_sound->blasterStop(sndKey->fadeLength); } } } void Mult::clearObjectVideos() { + if (!_objects) + return; + for (int i = 0; i < _objCount; i++) if (_objects[i].videoSlot > 0) _vm->_vidPlayer->slotClose(_objects[i].videoSlot - 1); diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index 78071f1dd8..22683437e7 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "common/stream.h" diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 5ff0612497..3b561837ee 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "common/stream.h" diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp index af12626c83..5d7cef0341 100644 --- a/engines/gob/parse.cpp +++ b/engines/gob/parse.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/parse_v1.cpp b/engines/gob/parse_v1.cpp index 2b84ac5cee..f18f63de4f 100644 --- a/engines/gob/parse_v1.cpp +++ b/engines/gob/parse_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp index 65315c083a..463a3870ee 100644 --- a/engines/gob/parse_v2.cpp +++ b/engines/gob/parse_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp index 62a4dbad2f..4dc1236ad6 100644 --- a/engines/gob/scenery.cpp +++ b/engines/gob/scenery.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "common/stream.h" diff --git a/engines/gob/scenery_v1.cpp b/engines/gob/scenery_v1.cpp index 5d3eb15a95..605b098693 100644 --- a/engines/gob/scenery_v1.cpp +++ b/engines/gob/scenery_v1.cpp @@ -23,13 +23,12 @@ * */ - #include "common/endian.h" #include "gob/gob.h" #include "gob/scenery.h" #include "gob/util.h" -#include "gob/cdrom.h" +#include "gob/sound/sound.h" namespace Gob { @@ -37,11 +36,11 @@ Scenery_v1::Scenery_v1(GobEngine *vm) : Scenery(vm) { } int16 Scenery_v1::loadAnim(char search) { - if (_vm->_cdrom->_cdPlaying) { - while (_vm->_cdrom->getTrackPos() != -1) + if (_vm->_sound->cdIsPlaying()) { + while (_vm->_sound->cdGetTrackPos() != -1) _vm->_util->longDelay(50); - _vm->_cdrom->_cdPlaying = false; + _vm->_sound->cdStop(); } return Scenery::loadAnim(search); diff --git a/engines/gob/scenery_v2.cpp b/engines/gob/scenery_v2.cpp index 6ed377af64..1a0de6f291 100644 --- a/engines/gob/scenery_v2.cpp +++ b/engines/gob/scenery_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/music.cpp b/engines/gob/sound/adlib.cpp index 7be046c02a..fb0d9d58c1 100644 --- a/engines/gob/music.cpp +++ b/engines/gob/sound/adlib.cpp @@ -24,91 +24,55 @@ */ #include "common/file.h" - #include "common/endian.h" #include "gob/gob.h" -#include "gob/music.h" -#include "gob/game.h" -#include "gob/util.h" +#include "gob/sound/adlib.h" namespace Gob { -const char *Adlib::_tracks[][2] = { - {"avt00.tot", "mine"}, - {"avt001.tot", "nuit"}, - {"avt002.tot", "campagne"}, - {"avt003.tot", "extsor1"}, - {"avt004.tot", "interieure"}, - {"avt005.tot", "zombie"}, - {"avt006.tot", "zombie"}, - {"avt007.tot", "campagne"}, - {"avt008.tot", "campagne"}, - {"avt009.tot", "extsor1"}, - {"avt010.tot", "extsor1"}, - {"avt011.tot", "interieure"}, - {"avt012.tot", "zombie"}, - {"avt014.tot", "nuit"}, - {"avt015.tot", "interieure"}, - {"avt016.tot", "statue"}, - {"avt017.tot", "zombie"}, - {"avt018.tot", "statue"}, - {"avt019.tot", "mine"}, - {"avt020.tot", "statue"}, - {"avt021.tot", "mine"}, - {"avt022.tot", "zombie"} -}; - -const char *Adlib::_trackFiles[] = { -// "musmac1.adl", // TODO: This track isn't played correctly at all yet - "musmac2.adl", - "musmac3.adl", - "musmac4.adl", - "musmac5.adl", - "musmac6.adl" -}; - -const unsigned char Adlib::_operators[] = {0, 1, 2, 8, 9, 10, 16, 17, 18}; -const unsigned char Adlib::_volRegNums[] = { +const unsigned char AdLib::_operators[] = {0, 1, 2, 8, 9, 10, 16, 17, 18}; +const unsigned char AdLib::_volRegNums[] = { 3, 4, 5, 11, 12, 13, 19, 20, 21 }; -Adlib::Adlib(GobEngine *vm) : _vm(vm) { - int i; - +AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer) { _index = -1; _data = 0; _playPos = 0; _dataSize = 0; - _rate = _vm->_mixer->getOutputRate(); + + _rate = _mixer->getOutputRate(); _opl = makeAdlibOPL(_rate); + _first = true; _ended = false; _playing = false; _needFree = false; + _repCount = -1; _samplesTillPoll = 0; - for (i = 0; i < 16; i ++) + for (int i = 0; i < 16; i ++) _pollNotes[i] = 0; setFreqs(); - _vm->_mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_handle, + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_handle, this, -1, 255, 0, false, true); } -Adlib::~Adlib() { +AdLib::~AdLib() { Common::StackLock slock(_mutex); - _vm->_mixer->stopHandle(_handle); + _mixer->stopHandle(_handle); OPLDestroy(_opl); if (_data && _needFree) delete[] _data; } -int Adlib::readBuffer(int16 *buffer, const int numSamples) { +int AdLib::readBuffer(int16 *buffer, const int numSamples) { Common::StackLock slock(_mutex); int samples; int render; @@ -160,12 +124,12 @@ int Adlib::readBuffer(int16 *buffer, const int numSamples) { return numSamples; } -void Adlib::writeOPL(byte reg, byte val) { +void AdLib::writeOPL(byte reg, byte val) { debugC(6, kDebugMusic, "writeOPL(%02X, %02X)", reg, val); OPLWriteReg(_opl, reg, val); } -void Adlib::setFreqs() { +void AdLib::setFreqs() { byte lin; byte col; long val = 0; @@ -191,7 +155,7 @@ void Adlib::setFreqs() { } } -void Adlib::reset() { +void AdLib::reset() { _first = true; OPLResetChip(_opl); _samplesTillPoll = 0; @@ -209,13 +173,13 @@ void Adlib::reset() { writeOPL(0x01, 0x20); } -void Adlib::setVoices() { +void AdLib::setVoices() { // Definitions of the 9 instruments for (int i = 0; i < 9; i++) setVoice(i, i, true); } -void Adlib::setVoice(byte voice, byte instr, bool set) { +void AdLib::setVoice(byte voice, byte instr, bool set) { int i; int j; uint16 strct[27]; @@ -251,7 +215,7 @@ void Adlib::setVoice(byte voice, byte instr, bool set) { } } -void Adlib::setKey(byte voice, byte note, bool on, bool spec) { +void AdLib::setKey(byte voice, byte note, bool on, bool spec) { short freq = 0; short octa = 0; @@ -317,12 +281,12 @@ void Adlib::setKey(byte voice, byte note, bool on, bool spec) { warning("Voice %d, note %02X unknown\n", voice, note); } -void Adlib::setVolume(byte voice, byte volume) { +void AdLib::setVolume(byte voice, byte volume) { volume = 0x3F - (volume * 0x7E + 0x7F) / 0xFE; writeOPL(0x40 + _volRegNums[voice], volume); } -void Adlib::pollMusic() { +void AdLib::pollMusic() { unsigned char instr; byte channel; byte note; @@ -419,24 +383,7 @@ void Adlib::pollMusic() { _samplesTillPoll = tempo * (_rate / 1000); } -void Adlib::playBgMusic() { - for (int i = 0; i < ARRAYSIZE(_tracks); i++) - if (!scumm_stricmp(_vm->_game->_curTotFile, _tracks[i][0])) { - playTrack(_tracks[i][1]); - break; - } -} - -void Adlib::playTrack(const char *trackname) { - if (_playing) return; - - debugC(1, kDebugMusic, "Adlib::playTrack(%s)", trackname); - unload(); - load(_trackFiles[_vm->_util->getRandom(ARRAYSIZE(_trackFiles))]); - startPlay(); -} - -bool Adlib::load(const char *fileName) { +bool AdLib::load(const char *fileName) { Common::File song; unload(); @@ -457,7 +404,7 @@ bool Adlib::load(const char *fileName) { return true; } -void Adlib::load(byte *data, uint32 size, int index) { +bool AdLib::load(byte *data, uint32 size, int index) { unload(); _repCount = 0; @@ -468,9 +415,11 @@ void Adlib::load(byte *data, uint32 size, int index) { reset(); setVoices(); _playPos = _data + 3 + (_data[1] + 1) * 0x38; + + return true; } -void Adlib::unload() { +void AdLib::unload() { _playing = false; _index = -1; @@ -480,4 +429,29 @@ void Adlib::unload() { _needFree = false; } +bool AdLib::isPlaying() const { + return _playing; +} + +bool AdLib::getRepeating() const { + return _repCount != 0; +} + +void AdLib::setRepeating(int32 repCount) { + _repCount = repCount; +} + +int AdLib::getIndex() const { + return _index; +} + +void AdLib::startPlay() { + if (_data) _playing = true; +} + +void AdLib::stopPlay() { + Common::StackLock slock(_mutex); + _playing = false; +} + } // End of namespace Gob diff --git a/engines/gob/music.h b/engines/gob/sound/adlib.h index 199ea515b0..4cd83d5883 100644 --- a/engines/gob/music.h +++ b/engines/gob/sound/adlib.h @@ -23,8 +23,8 @@ * */ -#ifndef GOB_MUSIC_H -#define GOB_MUSIC_H +#ifndef GOB_SOUND_ADLIB_H +#define GOB_SOUND_ADLIB_H #include "common/mutex.h" #include "sound/audiostream.h" @@ -35,61 +35,63 @@ namespace Gob { class GobEngine; -class Adlib : public Audio::AudioStream { +class AdLib : public Audio::AudioStream { public: - Adlib(GobEngine *vm); - ~Adlib(); - - void lock() { _mutex.lock(); } - void unlock() { _mutex.unlock(); } - bool playing() const { return _playing; } - bool getRepeating() const { return _repCount != 0; } - void setRepeating (int32 repCount) { _repCount = repCount; } - int getIndex() const { return _index; } - void startPlay() { if (_data) _playing = true; } - void stopPlay() { - Common::StackLock slock(_mutex); - _playing = false; - } - void playTrack(const char *trackname); - void playBgMusic(); + AdLib(Audio::Mixer &mixer); + ~AdLib(); + + bool isPlaying() const; + int getIndex() const; + bool getRepeating() const; + + void setRepeating(int32 repCount); + + void startPlay(); + void stopPlay(); + bool load(const char *fileName); - void load(byte *data, uint32 size, int index = -1); + bool load(byte *data, uint32 size, int index = -1); void unload(); // AudioStream API - int readBuffer(int16 *buffer, const int numSamples); - bool isStereo() const { return false; } - bool endOfData() const { return !_playing; } - bool endOfStream() const { return false; } - int getRate() const { return _rate; } + int readBuffer(int16 *buffer, const int numSamples); + bool isStereo() const { return false; } + bool endOfData() const { return !_playing; } + bool endOfStream() const { return false; } + int getRate() const { return _rate; } protected: - static const char *_tracks[][2]; - static const char *_trackFiles[]; static const unsigned char _operators[]; static const unsigned char _volRegNums []; + + Audio::Mixer *_mixer; Audio::SoundHandle _handle; FM_OPL *_opl; - int _index; + + Common::Mutex _mutex; + + uint32 _rate; + byte *_data; byte *_playPos; uint32 _dataSize; - uint32 _rate; + short _freqs[25][12]; byte _notes[11]; byte _notCol[11]; byte _notLin[11]; bool _notOn[11]; byte _pollNotes[16]; + int _samplesTillPoll; int32 _repCount; + bool _playing; bool _first; bool _ended; bool _needFree; - Common::Mutex _mutex; - GobEngine *_vm; + + int _index; void writeOPL(byte reg, byte val); void setFreqs(); @@ -103,4 +105,4 @@ protected: } // End of namespace Gob -#endif // GOB_MUSIC_H +#endif // GOB_SOUND_ADLIB_H diff --git a/engines/gob/cdrom.cpp b/engines/gob/sound/cdrom.cpp index c037d24bbe..f3bc70807e 100644 --- a/engines/gob/cdrom.cpp +++ b/engines/gob/sound/cdrom.cpp @@ -23,20 +23,16 @@ * */ - #include "common/endian.h" +#include "common/util.h" #include "sound/audiocd.h" #include "gob/gob.h" -#include "gob/cdrom.h" -#include "gob/global.h" -#include "gob/util.h" -#include "gob/dataio.h" -#include "gob/game.h" +#include "gob/sound/cdrom.h" namespace Gob { -CDROM::CDROM(GobEngine *vm) : _vm(vm) { +CDROM::CDROM() { _cdPlaying = false; _LICbuffer = 0; @@ -47,110 +43,42 @@ CDROM::CDROM(GobEngine *vm) : _vm(vm) { _startTime = 0; } -void CDROM::readLIC(const char *fname) { - char tmp[80]; - int handle; - uint16 version, startChunk, pos; +CDROM::~CDROM() { +} - freeLICbuffer(); +void CDROM::readLIC(DataStream &stream) { + uint16 version, startChunk, pos; + freeLICBuffer(); *_curTrack = 0; - strncpy0(tmp, fname, 79); - - handle = _vm->_dataIO->openData(tmp); - - if (handle == -1) - return; - - _vm->_dataIO->closeData(handle); - - _vm->_dataIO->getUnpackedData(tmp); - - handle = _vm->_dataIO->openData(tmp); - DataStream *stream = _vm->_dataIO->openAsStream(handle, true); - - version = stream->readUint16LE(); - startChunk = stream->readUint16LE(); - _numTracks = stream->readUint16LE(); + version = stream.readUint16LE(); + startChunk = stream.readUint16LE(); + _numTracks = stream.readUint16LE(); if (version != 3) - error("%s: Unknown version %d", fname, version); + error("Unknown version %d while reading LIC", version); - stream->seek(50); + stream.seek(50); for (int i = 0; i < startChunk; i++) { - pos = stream->readUint16LE(); + pos = stream.readUint16LE(); if (!pos) break; - stream->skip(pos); + stream.skip(pos); } _LICbuffer = new byte[_numTracks * 22]; - stream->read(_LICbuffer, _numTracks * 22); - - delete stream; + stream.read(_LICbuffer, _numTracks * 22); } -void CDROM::freeLICbuffer() { +void CDROM::freeLICBuffer() { delete[] _LICbuffer; _LICbuffer = 0; } -void CDROM::playBgMusic() { - static const char *tracks[][2] = { - {"avt00.tot", "mine"}, - {"avt001.tot", "nuit"}, - {"avt002.tot", "campagne"}, - {"avt003.tot", "extsor1"}, - {"avt004.tot", "interieure"}, - {"avt005.tot", "zombie"}, - {"avt006.tot", "zombie"}, - {"avt007.tot", "campagne"}, - {"avt008.tot", "campagne"}, - {"avt009.tot", "extsor1"}, - {"avt010.tot", "extsor1"}, - {"avt011.tot", "interieure"}, - {"avt012.tot", "zombie"}, - {"avt014.tot", "nuit"}, - {"avt015.tot", "interieure"}, - {"avt016.tot", "statue"}, - {"avt017.tot", "zombie"}, - {"avt018.tot", "statue"}, - {"avt019.tot", "mine"}, - {"avt020.tot", "statue"}, - {"avt021.tot", "mine"}, - {"avt022.tot", "zombie"} - }; - - for (int i = 0; i < ARRAYSIZE(tracks); i++) - if (!scumm_stricmp(_vm->_game->_curTotFile, tracks[i][0])) { - startTrack(tracks[i][1]); - break; - } -} - -void CDROM::playMultMusic() { - static const char *tracks[][6] = { - {"avt005.tot", "fra1", "all1", "ang1", "esp1", "ita1"}, - {"avt006.tot", "fra2", "all2", "ang2", "esp2", "ita2"}, - {"avt012.tot", "fra3", "all3", "ang3", "esp3", "ita3"}, - {"avt016.tot", "fra4", "all4", "ang4", "esp4", "ita4"}, - {"avt019.tot", "fra5", "all5", "ang5", "esp5", "ita5"}, - {"avt022.tot", "fra6", "all6", "ang6", "esp6", "ita6"} - }; - - // Default to "ang?" for other languages (including EN_USA) - int language = _vm->_global->_language <= 4 ? _vm->_global->_language : 2; - for (int i = 0; i < ARRAYSIZE(tracks); i++) - if (!scumm_stricmp(_vm->_game->_curTotFile, tracks[i][0])) { - startTrack(tracks[i][language + 1]); - break; - } -} - void CDROM::startTrack(const char *trackName) { if (!_LICbuffer) return; @@ -175,7 +103,7 @@ void CDROM::startTrack(const char *trackName) { play(start, end); - _startTime = _vm->_util->getTimeKey(); + _startTime = g_system->getMillis(); _trackStop = _startTime + (end - start + 1 + 150) * 40 / 3; } @@ -192,11 +120,15 @@ void CDROM::play(uint32 from, uint32 to) { _cdPlaying = true; } -int32 CDROM::getTrackPos(const char *keyTrack) { +bool CDROM::isPlaying() const { + return _cdPlaying; +} + +int32 CDROM::getTrackPos(const char *keyTrack) const { byte *keyBuffer = getTrackBuffer(keyTrack); - uint32 curPos = (_vm->_util->getTimeKey() - _startTime) * 3 / 40; + uint32 curPos = (g_system->getMillis() - _startTime) * 3 / 40; - if (_cdPlaying && (_vm->_util->getTimeKey() < _trackStop)) { + if (_cdPlaying && (g_system->getMillis() < _trackStop)) { if (keyBuffer && _curTrackBuffer && (keyBuffer != _curTrackBuffer)) { uint32 kStart = READ_LE_UINT32(keyBuffer + 12); uint32 kEnd = READ_LE_UINT32(keyBuffer + 16); @@ -216,7 +148,7 @@ int32 CDROM::getTrackPos(const char *keyTrack) { return -1; } -const char *CDROM::getCurTrack() { +const char *CDROM::getCurTrack() const { return _curTrack; } @@ -248,7 +180,7 @@ void CDROM::testCD(int trySubst, const char *label) { // CD secor reading } -byte *CDROM::getTrackBuffer(const char *trackName) { +byte *CDROM::getTrackBuffer(const char *trackName) const { if (!_LICbuffer || !trackName) return 0; diff --git a/engines/gob/cdrom.h b/engines/gob/sound/cdrom.h index 25490de5dc..201f7adb75 100644 --- a/engines/gob/cdrom.h +++ b/engines/gob/sound/cdrom.h @@ -23,29 +23,30 @@ * */ -#ifndef GOB_CDROM_H -#define GOB_CDROM_H +#ifndef GOB_SOUND_CDROM_H +#define GOB_SOUND_CDROM_H + +#include "gob/dataio.h" namespace Gob { class CDROM { public: - bool _cdPlaying; + CDROM(); + ~CDROM(); - void readLIC(const char *fname); - void freeLICbuffer(); + void readLIC(DataStream &stream); + void freeLICBuffer(); void startTrack(const char *trackName); - void playBgMusic(); - void playMultMusic(); - void play(uint32 from, uint32 to); - int32 getTrackPos(const char *keyTrack = 0); - const char *getCurTrack(); void stopPlaying(); - void stop(); - void testCD(int trySubst, const char *label); - CDROM(GobEngine *vm); + bool isPlaying() const; + + int32 getTrackPos(const char *keyTrack = 0) const; + const char *getCurTrack() const; + + void testCD(int trySubst, const char *label); protected: byte *_LICbuffer; @@ -54,11 +55,14 @@ protected: uint16 _numTracks; uint32 _trackStop; uint32 _startTime; - GobEngine *_vm; + bool _cdPlaying; + + void play(uint32 from, uint32 to); + void stop(); - byte *getTrackBuffer(const char *trackName); + byte *getTrackBuffer(const char *trackName) const; }; } // End of namespace Gob -#endif // GOB_CDROM_H +#endif // GOB_SOUND_CDROM_H diff --git a/engines/gob/sound/infogrames.cpp b/engines/gob/sound/infogrames.cpp new file mode 100644 index 0000000000..0b46f3485c --- /dev/null +++ b/engines/gob/sound/infogrames.cpp @@ -0,0 +1,103 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "gob/sound/infogrames.h" + +namespace Gob { + +Infogrames::Infogrames(Audio::Mixer &mixer) : _mixer(&mixer) { + _instruments = 0; + _song = 0; +} + +Infogrames::~Infogrames() { + clearSong(); + clearInstruments(); +} + +bool Infogrames::loadInstruments(const char *fileName) { + clearSong(); + clearInstruments(); + + return loadInst(fileName); +} + +bool Infogrames::loadSong(const char *fileName) { + clearSong(); + + if (!_instruments) + if (!loadInst("i1.ins")) + return false; + + _song = new Audio::Infogrames(*_instruments, true, + _mixer->getOutputRate(), _mixer->getOutputRate() / 75); + + if (!_song->load(fileName)) { + warning("Couldn't load infogrames music"); + clearSong(); + return false; + } + + return true; +} + +void Infogrames::play() { + if (_song && !_mixer->isSoundHandleActive(_handle)) { + _song->restart(); + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, + &_handle, _song, -1, 255, 0, false); + } +} + +void Infogrames::stop() { + _mixer->stopHandle(_handle); +} + +void Infogrames::clearInstruments() { + delete _instruments; + _instruments = 0; +} + +void Infogrames::clearSong() { + if (_song) { + _mixer->stopHandle(_handle); + + delete _song; + _song = 0; + } +} + +bool Infogrames::loadInst(const char *fileName) { + _instruments = new Audio::Infogrames::Instruments; + if (!_instruments->load(fileName)) { + warning("Couldn't load instruments file"); + clearInstruments(); + return false; + } + + return true; +} + +} // End of namespace Gob diff --git a/engines/gob/sound/infogrames.h b/engines/gob/sound/infogrames.h new file mode 100644 index 0000000000..4a20dceb22 --- /dev/null +++ b/engines/gob/sound/infogrames.h @@ -0,0 +1,60 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GOB_SOUND_INFOGRAMES_H +#define GOB_SOUND_INFOGRAMES_H + +#include "sound/mixer.h" +#include "sound/mods/infogrames.h" + +namespace Gob { + +class Infogrames { +public: + Infogrames(Audio::Mixer &mixer); + ~Infogrames(); + + bool loadInstruments(const char *fileName); + bool loadSong(const char *fileName); + + void play(); + void stop(); + +private: + Audio::Mixer *_mixer; + + Audio::Infogrames::Instruments *_instruments; + Audio::Infogrames *_song; + Audio::SoundHandle _handle; + + void clearInstruments(); + void clearSong(); + + bool loadInst(const char *fileName); +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_INFOGRAMES_H diff --git a/engines/gob/sound/pcspeaker.cpp b/engines/gob/sound/pcspeaker.cpp new file mode 100644 index 0000000000..0d1fc0a6db --- /dev/null +++ b/engines/gob/sound/pcspeaker.cpp @@ -0,0 +1,55 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "gob/sound/pcspeaker.h" + +namespace Gob { + +PCSpeaker::PCSpeaker(Audio::Mixer &mixer) : _mixer(&mixer) { + + _stream = new Audio::PCSpeaker(_mixer->getOutputRate()); + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, + &_handle, _stream, -1, 50, 0, false, true); +} + +PCSpeaker::~PCSpeaker() { + _mixer->stopHandle(_handle); + delete _stream; +} + +void PCSpeaker::speakerOn(int16 frequency, int32 length) { + _stream->play(Audio::PCSpeaker::kWaveFormSquare, frequency, length); +} + +void PCSpeaker::speakerOff() { + _stream->stop(); +} + +void PCSpeaker::onUpdate(uint32 millis) { + if (_stream->isPlaying()) + _stream->stop(millis); +} + +} // End of namespace Gob diff --git a/engines/gob/sound/pcspeaker.h b/engines/gob/sound/pcspeaker.h new file mode 100644 index 0000000000..8c4fb08021 --- /dev/null +++ b/engines/gob/sound/pcspeaker.h @@ -0,0 +1,52 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GOB_SOUND_PCSPEAKER_H +#define GOB_SOUND_PCSPEAKER_H + +#include "sound/mixer.h" +#include "sound/softsynth/pcspk.h" + +namespace Gob { + +class PCSpeaker { +public: + PCSpeaker(Audio::Mixer &mixer); + ~PCSpeaker(); + + void speakerOn(int16 frequency, int32 length = -1); + void speakerOff(); + void onUpdate(uint32 millis); + +private: + Audio::Mixer *_mixer; + + Audio::PCSpeaker *_stream; + Audio::SoundHandle _handle; +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_PCSPEAKER_H diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp new file mode 100644 index 0000000000..5c375c260a --- /dev/null +++ b/engines/gob/sound/sound.cpp @@ -0,0 +1,461 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "gob/gob.h" +#include "gob/sound/sound.h" +#include "gob/global.h" +#include "gob/util.h" +#include "gob/dataio.h" +#include "gob/game.h" + +namespace Gob { + +Sound::Sound(GobEngine *vm) : _vm(vm) { + _pcspeaker = new PCSpeaker(*_vm->_mixer); + _blaster = new SoundBlaster(*_vm->_mixer); + + _adlib = 0; + _infogrames = 0; + _cdrom = 0; + + if (!_vm->_noMusic && _vm->hasAdlib()) + _adlib = new AdLib(*_vm->_mixer); + if (!_vm->_noMusic && (_vm->getPlatform() == Common::kPlatformAmiga)) + _infogrames = new Infogrames(*_vm->_mixer); + if (_vm->isCD()) + _cdrom = new CDROM; +} + +Sound::~Sound() { + delete _pcspeaker; + delete _blaster; + delete _adlib; + delete _infogrames; + + for (int i = 0; i < kSoundsCount; i++) + _sounds[i].free(); +} + +void Sound::convToSigned(byte *buffer, int length) { + while (length-- > 0) + *buffer++ ^= 0x80; +} + +SoundDesc *Sound::sampleGetBySlot(int slot) { + if ((slot < 0) || (slot >= kSoundsCount)) + return 0; + + return &_sounds[slot]; +} + +const SoundDesc *Sound::sampleGetBySlot(int slot) const { + if ((slot < 0) || (slot >= kSoundsCount)) + return 0; + + return &_sounds[slot]; +} + +int Sound::sampleGetNextFreeSlot() const { + for (int i = 0; i < kSoundsCount; i++) + if (_sounds[i].empty()) + return i; + + return -1; +} + +bool Sound::sampleLoad(SoundDesc *sndDesc, const char *fileName) { + if (!sndDesc) + return false; + + byte *data; + uint32 size; + + data = (byte *) _vm->_dataIO->getData(fileName); + if (!data) + return false; + + size = _vm->_dataIO->getDataSize(fileName); + sndDesc->load(SOUND_SND, SOUND_FILE, data, size); + + return true; +} + +void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdlib, int index) { + if (!sndDesc || sndDesc->empty()) + return; + + if (sndDesc->getType() == SOUND_ADL) { + + if (_adlib && noteAdlib) + if ((index == -1) || (_adlib->getIndex() == index)) + _adlib->stopPlay(); + + } else { + + if (_blaster) + _blaster->stopSound(0, sndDesc); + + } + + sndDesc->free(); +} + +void Sound::speakerOn(int16 frequency, int32 length) { + if (!_pcspeaker) + return; + + _pcspeaker->speakerOn(frequency, length); +} + +void Sound::speakerOff() { + if (!_pcspeaker) + return; + + _pcspeaker->speakerOff(); +} + +void Sound::speakerOnUpdate(uint32 millis) { + if (!_pcspeaker) + return; + + _pcspeaker->onUpdate(millis); +} + +bool Sound::infogramesLoadInstruments(const char *fileName) { + if (!_infogrames) + return false; + + return _infogrames->loadInstruments(fileName); +} + +bool Sound::infogramesLoadSong(const char *fileName) { + if (!_infogrames) + return false; + + return _infogrames->loadSong(fileName); +} + +void Sound::infogramesPlay() { + if (!_infogrames) + return; + + _infogrames->play(); +} + +void Sound::infogramesStop() { + if (!_infogrames) + return; + + _infogrames->stop(); +} + +bool Sound::adlibLoad(const char *fileName) { + if (!_adlib) + return false; + + return _adlib->load(fileName); +} + +bool Sound::adlibLoad(byte *data, uint32 size, int index) { + if (!_adlib) + return false; + + return _adlib->load(data, size, index); +} + +void Sound::adlibUnload() { + if (!_adlib) + return; + + _adlib->unload(); +} + +void Sound::adlibPlayTrack(const char *trackname) { + if (!_adlib || _adlib->isPlaying()) + return; + + debugC(1, kDebugMusic, "Adlib::playTrack(%s)", trackname); + + _adlib->unload(); + _adlib->load(trackname); + _adlib->startPlay(); +} + +void Sound::adlibPlayBgMusic() { + if (!_adlib) + return; + + static const char *tracks[] = { +// "musmac1.adl", // TODO: This track isn't played correctly at all yet + "musmac2.adl", + "musmac3.adl", + "musmac4.adl", + "musmac5.adl", + "musmac6.adl" + }; + + int track = _vm->_util->getRandom(ARRAYSIZE(tracks)); + adlibPlayTrack(tracks[track]); +} + +void Sound::adlibPlay() { + if (!_adlib) + return; + + _adlib->startPlay(); +} + +void Sound::adlibStop() { + if (!_adlib) + return; + + _adlib->stopPlay(); +} + +bool Sound::adlibIsPlaying() const { + if (!_adlib) + return false; + + return _adlib->isPlaying(); +} + +int Sound::adlibGetIndex() const { + if (!_adlib) + return -1; + + return _adlib->getIndex(); +} + +bool Sound::adlibGetRepeating() const { + if (!_adlib) + return false; + + return _adlib->getRepeating(); +} + +void Sound::adlibSetRepeating(int32 repCount) { + if (!_adlib) + return; + + _adlib->setRepeating(repCount); +} + +void Sound::blasterPlay(SoundDesc *sndDesc, int16 repCount, + int16 frequency, int16 fadeLength) { + if (!_blaster || !sndDesc) + return; + + _blaster->playSample(*sndDesc, repCount, frequency, fadeLength); +} + +void Sound::blasterStop(int16 fadeLength, SoundDesc *sndDesc) { + if (!_blaster) + return; + + _blaster->stopSound(fadeLength, sndDesc); +} + +void Sound::blasterPlayComposition(int16 *composition, int16 freqVal, + SoundDesc *sndDescs, int8 sndCount) { + if (!_blaster) + return; + + blasterWaitEndPlay(); + _blaster->stopComposition(); + + if (!sndDescs) + sndDescs = _sounds; + + _blaster->playComposition(composition, freqVal, sndDescs, sndCount); +} + +void Sound::blasterStopComposition() { + if (!_blaster) + return; + + _blaster->stopComposition(); +} + +char Sound::blasterPlayingSound() const { + if (!_blaster) + return 0; + + return _blaster->getPlayingSound(); +} + +void Sound::blasterSetRepeating(int32 repCount) { + if (!_blaster) + return; + + _blaster->setRepeating(repCount); +} + +void Sound::blasterWaitEndPlay(bool interruptible, bool stopComp) { + if (!_blaster) + return; + + if (stopComp) + _blaster->endComposition(); + + while (_blaster->isPlaying() && !_vm->_quitRequested) { + if (interruptible && (_vm->_util->checkKey() == 0x11B)) { + WRITE_VAR(57, -1); + return; + } + _vm->_util->longDelay(200); + } + + _blaster->stopSound(0); +} + +void Sound::cdLoadLIC(const char *fname) { + if (!_cdrom) + return; + + int handle = _vm->_dataIO->openData(fname); + + if (handle == -1) + return; + + _vm->_dataIO->closeData(handle); + + _vm->_dataIO->getUnpackedData(fname); + + handle = _vm->_dataIO->openData(fname); + DataStream *stream = _vm->_dataIO->openAsStream(handle, true); + + _cdrom->readLIC(*stream); + + delete stream; +} + +void Sound::cdUnloadLIC() { + if (!_cdrom) + return; + + _cdrom->freeLICBuffer(); +} + +void Sound::cdPlayBgMusic() { + if (!_cdrom) + return; + + static const char *tracks[][2] = { + {"avt00.tot", "mine"}, + {"avt001.tot", "nuit"}, + {"avt002.tot", "campagne"}, + {"avt003.tot", "extsor1"}, + {"avt004.tot", "interieure"}, + {"avt005.tot", "zombie"}, + {"avt006.tot", "zombie"}, + {"avt007.tot", "campagne"}, + {"avt008.tot", "campagne"}, + {"avt009.tot", "extsor1"}, + {"avt010.tot", "extsor1"}, + {"avt011.tot", "interieure"}, + {"avt012.tot", "zombie"}, + {"avt014.tot", "nuit"}, + {"avt015.tot", "interieure"}, + {"avt016.tot", "statue"}, + {"avt017.tot", "zombie"}, + {"avt018.tot", "statue"}, + {"avt019.tot", "mine"}, + {"avt020.tot", "statue"}, + {"avt021.tot", "mine"}, + {"avt022.tot", "zombie"} + }; + + for (int i = 0; i < ARRAYSIZE(tracks); i++) + if (!scumm_stricmp(_vm->_game->_curTotFile, tracks[i][0])) { + _cdrom->startTrack(tracks[i][1]); + break; + } +} + +void Sound::cdPlayMultMusic() { + if (!_cdrom) + return; + + static const char *tracks[][6] = { + {"avt005.tot", "fra1", "all1", "ang1", "esp1", "ita1"}, + {"avt006.tot", "fra2", "all2", "ang2", "esp2", "ita2"}, + {"avt012.tot", "fra3", "all3", "ang3", "esp3", "ita3"}, + {"avt016.tot", "fra4", "all4", "ang4", "esp4", "ita4"}, + {"avt019.tot", "fra5", "all5", "ang5", "esp5", "ita5"}, + {"avt022.tot", "fra6", "all6", "ang6", "esp6", "ita6"} + }; + + // Default to "ang?" for other languages (including EN_USA) + int language = _vm->_global->_language <= 4 ? _vm->_global->_language : 2; + for (int i = 0; i < ARRAYSIZE(tracks); i++) + if (!scumm_stricmp(_vm->_game->_curTotFile, tracks[i][0])) { + _cdrom->startTrack(tracks[i][language + 1]); + break; + } +} + +void Sound::cdPlay(const char *trackName) { + if (!_cdrom) + return; + + _cdrom->startTrack(trackName); +} + +void Sound::cdStop() { + if (!_cdrom) + return; + + _cdrom->stopPlaying(); +} + +bool Sound::cdIsPlaying() const { + if (!_cdrom) + return false; + + return _cdrom->isPlaying(); +} + +int32 Sound::cdGetTrackPos(const char *keyTrack) const { + if (!_cdrom) + return -1; + + return _cdrom->getTrackPos(keyTrack); +} + +const char *Sound::cdGetCurrentTrack() const { + if (!_cdrom) + return ""; + + return _cdrom->getCurTrack(); +} + +void Sound::cdTest(int trySubst, const char *label) { + if (!_cdrom) + return; + + _cdrom->testCD(trySubst, label); +} + +} // End of namespace Gob diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h new file mode 100644 index 0000000000..81b48688c4 --- /dev/null +++ b/engines/gob/sound/sound.h @@ -0,0 +1,135 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GOB_SOUND_SOUND_H +#define GOB_SOUND_SOUND_H + +#include "gob/sound/sounddesc.h" +#include "gob/sound/pcspeaker.h" +#include "gob/sound/soundblaster.h" +#include "gob/sound/adlib.h" +#include "gob/sound/infogrames.h" +#include "gob/sound/cdrom.h" + +namespace Gob { + +class Sound { +public: + static const int kSoundsCount = 60; + + Sound(GobEngine *vm); + ~Sound(); + + static void convToSigned(byte *buffer, int length); + + // Samples + SoundDesc *sampleGetBySlot(int slot); + const SoundDesc *sampleGetBySlot(int slot) const; + int sampleGetNextFreeSlot() const; + + bool sampleLoad(SoundDesc *sndDesc, const char *fileName); + void sampleFree(SoundDesc *sndDesc, bool noteAdlib = false, int index = -1); + + + // SoundBlaster + void blasterPlay(SoundDesc *sndDesc, int16 repCount, + int16 frequency, int16 fadeLength = 0); + void blasterStop(int16 fadeLength, SoundDesc *sndDesc = 0); + + void blasterPlayComposition(int16 *composition, int16 freqVal, + SoundDesc *sndDescs = 0, int8 sndCount = kSoundsCount); + void blasterStopComposition(); + + char blasterPlayingSound() const; + + void blasterSetRepeating(int32 repCount); + void blasterWaitEndPlay(bool interruptible = false, bool stopComp = true); + + + // PCSpeaker + void speakerOn(int16 frequency, int32 length = -1); + void speakerOff(); + void speakerOnUpdate(uint32 millis); + + + // AdLib + bool adlibLoad(const char *fileName); + bool adlibLoad(byte *data, uint32 size, int index = -1); + void adlibUnload(); + + void adlibPlayTrack(const char *trackname); + void adlibPlayBgMusic(); + + void adlibPlay(); + void adlibStop(); + + bool adlibIsPlaying() const; + + int adlibGetIndex() const; + bool adlibGetRepeating() const; + + void adlibSetRepeating(int32 repCount); + + + // Infogrames + bool infogramesLoadInstruments(const char *fileName); + bool infogramesLoadSong(const char *fileName); + + void infogramesPlay(); + void infogramesStop(); + + + // CD-ROM + void cdLoadLIC(const char *fname); + void cdUnloadLIC(); + + void cdPlayBgMusic(); + void cdPlayMultMusic(); + + void cdPlay(const char *trackName); + void cdStop(); + + bool cdIsPlaying() const; + + int32 cdGetTrackPos(const char *keyTrack = 0) const; + const char *cdGetCurrentTrack() const; + + void cdTest(int trySubst, const char *label); + +private: + GobEngine *_vm; + + SoundDesc _sounds[kSoundsCount]; + + PCSpeaker *_pcspeaker; + SoundBlaster *_blaster; + AdLib *_adlib; + Infogrames *_infogrames; + CDROM *_cdrom; +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_H diff --git a/engines/gob/sound.cpp b/engines/gob/sound/soundblaster.cpp index 6b227cfb0e..f5339404b4 100644 --- a/engines/gob/sound.cpp +++ b/engines/gob/sound/soundblaster.cpp @@ -23,81 +23,15 @@ * */ - -#include "common/endian.h" - -#include "gob/gob.h" -#include "gob/sound.h" -#include "gob/global.h" -#include "gob/util.h" -#include "gob/dataio.h" -#include "gob/game.h" +#include "gob/sound/sound.h" namespace Gob { -void SoundDesc::set(SoundType type, SoundSource src, - byte *data, uint32 dSize) { - - free(); - - _type = type; - _source = src; - _data = _dataPtr = data; - _size = dSize; -} - -void SoundDesc::load(SoundType type, SoundSource src, - byte *data, uint32 dSize) { - - free(); - - _source = src; - switch (type) { - case SOUND_ADL: - loadADL(data, dSize); - break; - case SOUND_SND: - loadSND(data, dSize); - break; - } -} - -void SoundDesc::free() { - if (_source != SOUND_TOT) - delete[] _data; - _data = _dataPtr = 0; - _id = 0; -} - -void SoundDesc::convToSigned() { - if ((_type == SOUND_SND) && _data && _dataPtr) - for (uint32 i = 0; i < _size; i++) - _dataPtr[i] ^= 0x80; -} - -void SoundDesc::loadSND(byte *data, uint32 dSize) { - assert(dSize > 6); - - _type = SOUND_SND; - _data = data; - _dataPtr = data + 6; - _frequency = MAX((int16) READ_BE_UINT16(data + 4), (int16) 4700); - _flag = data[0] ? (data[0] & 0x7F) : 8; - data[0] = 0; - _size = MIN(READ_BE_UINT32(data), dSize - 6); -} - -void SoundDesc::loadADL(byte *data, uint32 dSize) { - _type = SOUND_ADL; - _data = _dataPtr = data; - _size = dSize; -} - -Snd::Snd(GobEngine *vm) : _vm(vm) { +SoundBlaster::SoundBlaster(Audio::Mixer &mixer) : _mixer(&mixer) { _playingSound = 0; _curSoundDesc = 0; - _rate = _vm->_mixer->getOutputRate(); + _rate = _mixer->getOutputRate(); _end = true; _data = 0; _length = 0; @@ -121,39 +55,23 @@ Snd::Snd(GobEngine *vm) : _vm(vm) { _compositionSampleCount = 0; _compositionPos = -1; - _speakerStream = new Audio::PCSpeaker(_vm->_mixer->getOutputRate()); - - _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle, + _mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_handle, this, -1, 255, 0, false, true); - _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_speakerHandle, - _speakerStream, -1, 50, 0, false, true); } -Snd::~Snd() { - // stop permanent streams manually: - - // First the speaker stream - _vm->_mixer->stopHandle(_speakerHandle); - delete _speakerStream; - - // Next, this stream (class Snd is an AudioStream, too) - _vm->_mixer->stopHandle(_handle); +SoundBlaster::~SoundBlaster() { + _mixer->stopHandle(_handle); } -void Snd::speakerOn(int16 frequency, int32 length) { - _speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, frequency, length); +bool SoundBlaster::isPlaying() const { + return !_end; } -void Snd::speakerOff() { - _speakerStream->stop(); +char SoundBlaster::getPlayingSound() const { + return _playingSound; } -void Snd::speakerOnUpdate(uint32 milis) { - if (_speakerStream->isPlaying()) - _speakerStream->stop(milis); -} - -void Snd::stopSound(int16 fadeLength, SoundDesc *sndDesc) { +void SoundBlaster::stopSound(int16 fadeLength, SoundDesc *sndDesc) { Common::StackLock slock(_mutex); if (sndDesc && (sndDesc != _curSoundDesc)) @@ -174,33 +92,24 @@ void Snd::stopSound(int16 fadeLength, SoundDesc *sndDesc) { _curFadeSamples = 0; } -void Snd::setRepeating(int32 repCount) { +void SoundBlaster::setRepeating(int32 repCount) { Common::StackLock slock(_mutex); _repCount = repCount; } -void Snd::waitEndPlay(bool interruptible, bool stopComp) { - if (stopComp) - _compositionPos = -1; - while (!_end && !_vm->_quitRequested) { - if (interruptible && (_vm->_util->checkKey() == 0x11B)) { - WRITE_VAR(57, -1); - return; - } - _vm->_util->longDelay(200); - } - stopSound(0); -} - -void Snd::stopComposition() { +void SoundBlaster::stopComposition() { if (_compositionPos != -1) { stopSound(0); _compositionPos = -1; } } -void Snd::nextCompositionPos() { +void SoundBlaster::endComposition() { + _compositionPos = -1; +} + +void SoundBlaster::nextCompositionPos() { int8 slot; while ((++_compositionPos < 50) && @@ -218,17 +127,13 @@ void Snd::nextCompositionPos() { _compositionPos = -1; } -void Snd::playComposition(int16 *composition, int16 freqVal, +void SoundBlaster::playComposition(int16 *composition, int16 freqVal, SoundDesc *sndDescs, int8 sndCount) { - int i; - - waitEndPlay(); - stopComposition(); - _compositionSamples = sndDescs ? sndDescs : _vm->_game->_soundSamples; - _compositionSampleCount = sndCount; + _compositionSamples = sndDescs; + _compositionSampleCount = sndCount; - i = -1; + int i = -1; do { i++; _composition[i] = composition[i]; @@ -238,7 +143,7 @@ void Snd::playComposition(int16 *composition, int16 freqVal, nextCompositionPos(); } -void Snd::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, +void SoundBlaster::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { if (frequency <= 0) @@ -277,26 +182,7 @@ void Snd::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, } } -bool Snd::loadSample(SoundDesc &sndDesc, const char *fileName) { - byte *data; - uint32 size; - - data = (byte *) _vm->_dataIO->getData(fileName); - if (!data) - return false; - - size = _vm->_dataIO->getDataSize(fileName); - sndDesc.load(SOUND_SND, SOUND_FILE, data, size); - - return true; -} - -void Snd::freeSample(SoundDesc &sndDesc) { - stopSound(0, &sndDesc); - sndDesc.free(); -} - -void Snd::playSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, +void SoundBlaster::playSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength) { Common::StackLock slock(_mutex); @@ -306,7 +192,7 @@ void Snd::playSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, setSample(sndDesc, repCount, frequency, fadeLength); } -void Snd::checkEndSample() { +void SoundBlaster::checkEndSample() { if (_compositionPos != -1) nextCompositionPos(); else if ((_repCount == -1) || (--_repCount > 0)) { @@ -320,7 +206,7 @@ void Snd::checkEndSample() { } } -int Snd::readBuffer(int16 *buffer, const int numSamples) { +int SoundBlaster::readBuffer(int16 *buffer, const int numSamples) { Common::StackLock slock(_mutex); for (int i = 0; i < numSamples; i++) { diff --git a/engines/gob/sound.h b/engines/gob/sound/soundblaster.h index 6780c201b5..575d4994be 100644 --- a/engines/gob/sound.h +++ b/engines/gob/sound/soundblaster.h @@ -23,8 +23,8 @@ * */ -#ifndef GOB_SOUND_H -#define GOB_SOUND_H +#ifndef GOB_SOUND_SOUNDBLASTER_H +#define GOB_SOUND_SOUNDBLASTER_H #include "common/mutex.h" #include "common/frac.h" @@ -34,81 +34,28 @@ namespace Gob { -enum SoundType { - SOUND_SND, - SOUND_ADL -}; - -enum SoundSource { - SOUND_FILE, - SOUND_TOT, - SOUND_EXT -}; - -class SoundDesc { -public: - int16 _repCount; - int16 _frequency; - int16 _flag; - int16 _id; - - byte *getData() { return _dataPtr; } - uint32 size() { return _size; } - bool empty() { return !_dataPtr; } - bool isId(int16 id) { return _dataPtr && _id == id; } - SoundType getType() { return _type; } - - void set(SoundType type, SoundSource src, byte *data, uint32 dSize); - void load(SoundType type, SoundSource src, byte *data, uint32 dSize); - void free(); - void convToSigned(); - - // Which fade out length to use when the fade starts half-way through? - int16 calcFadeOutLength(int16 frequency) { - return (10 * (_size / 2)) / frequency; - } - uint32 calcLength(int16 repCount, int16 frequency, bool fade) { - uint32 fadeSize = fade ? _size / 2 : 0; - return ((_size * repCount - fadeSize) * 1000) / frequency; - } - - SoundDesc() : _data(0), _dataPtr(0), _size(0), _type(SOUND_SND), - _source(SOUND_FILE), _repCount(0), _frequency(0), - _flag(0), _id(0) {} - ~SoundDesc() { free(); } - -private: - byte *_data; - byte *_dataPtr; - uint32 _size; - - SoundType _type; - SoundSource _source; - - void loadSND(byte *data, uint32 dSize); - void loadADL(byte *data, uint32 dSize); -}; - -class Snd : public Audio::AudioStream { +class SoundBlaster : public Audio::AudioStream { public: char _playingSound; - Snd(GobEngine *vm); - ~Snd(); - - void speakerOn(int16 frequency, int32 length); - void speakerOff(); - void speakerOnUpdate(uint32 milis); - void stopSound(int16 fadeLength, SoundDesc *sndDesc = 0); + SoundBlaster(Audio::Mixer &mixer); + ~SoundBlaster(); bool loadSample(SoundDesc &sndDesc, const char *fileName); void freeSample(SoundDesc &sndDesc); + void playSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength = 0); + void stopSound(int16 fadeLength, SoundDesc *sndDesc = 0); void playComposition(int16 *composition, int16 freqVal, SoundDesc *sndDescs = 0, int8 sndCount = 60); void stopComposition(); + void endComposition(); + + bool isPlaying() const; + char getPlayingSound() const; + void setRepeating(int32 repCount); void waitEndPlay(bool interruptible = false, bool stopComp = true); @@ -124,8 +71,7 @@ public: int getRate() const { return _rate; } protected: - Audio::PCSpeaker *_speakerStream; - Audio::SoundHandle _speakerHandle; + Audio::Mixer *_mixer; Audio::SoundHandle *_activeHandle; Audio::SoundHandle _compositionHandle; @@ -159,8 +105,6 @@ protected: uint32 _fadeSamples; uint32 _curFadeSamples; - GobEngine *_vm; - void setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, int16 fadeLength); void checkEndSample(); @@ -169,4 +113,4 @@ protected: } // End of namespace Gob -#endif // GOB_SOUND_H +#endif // GOB_SOUND_SOUNDBLASTER_H diff --git a/engines/gob/sound/sounddesc.cpp b/engines/gob/sound/sounddesc.cpp new file mode 100644 index 0000000000..e0885d9faa --- /dev/null +++ b/engines/gob/sound/sounddesc.cpp @@ -0,0 +1,116 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/util.h" + +#include "gob/sound/sounddesc.h" + +namespace Gob { + +SoundDesc::SoundDesc() { + _data = _dataPtr = 0; + _size = 0; + + _type = SOUND_SND; + _source = SOUND_FILE; + + _repCount = 0; + _frequency = 0; + _flag = 0; + _id = 0; +} + +SoundDesc::~SoundDesc() { + free(); +} + +void SoundDesc::set(SoundType type, SoundSource src, + byte *data, uint32 dSize) { + + free(); + + _type = type; + _source = src; + _data = _dataPtr = data; + _size = dSize; +} + +void SoundDesc::load(SoundType type, SoundSource src, + byte *data, uint32 dSize) { + + free(); + + _source = src; + switch (type) { + case SOUND_ADL: + loadADL(data, dSize); + break; + case SOUND_SND: + loadSND(data, dSize); + break; + } +} + +void SoundDesc::free() { + if (_source != SOUND_TOT) + delete[] _data; + _data = _dataPtr = 0; + _id = 0; +} + +void SoundDesc::convToSigned() { + if ((_type == SOUND_SND) && _data && _dataPtr) + for (uint32 i = 0; i < _size; i++) + _dataPtr[i] ^= 0x80; +} + +int16 SoundDesc::calcFadeOutLength(int16 frequency) { + return (10 * (_size / 2)) / frequency; +} + +uint32 SoundDesc::calcLength(int16 repCount, int16 frequency, bool fade) { + uint32 fadeSize = fade ? _size / 2 : 0; + return ((_size * repCount - fadeSize) * 1000) / frequency; +} + +void SoundDesc::loadSND(byte *data, uint32 dSize) { + assert(dSize > 6); + + _type = SOUND_SND; + _data = data; + _dataPtr = data + 6; + _frequency = MAX((int16) READ_BE_UINT16(data + 4), (int16) 4700); + _flag = data[0] ? (data[0] & 0x7F) : 8; + data[0] = 0; + _size = MIN(READ_BE_UINT32(data), dSize - 6); +} + +void SoundDesc::loadADL(byte *data, uint32 dSize) { + _type = SOUND_ADL; + _data = _dataPtr = data; + _size = dSize; +} + +} // End of namespace Gob diff --git a/engines/gob/sound/sounddesc.h b/engines/gob/sound/sounddesc.h new file mode 100644 index 0000000000..ed4447254c --- /dev/null +++ b/engines/gob/sound/sounddesc.h @@ -0,0 +1,85 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef GOB_SOUND_SOUNDDESC_H +#define GOB_SOUND_SOUNDDESC_H + +#include "common/endian.h" + +namespace Gob { + +enum SoundType { + SOUND_SND, + SOUND_ADL +}; + +enum SoundSource { + SOUND_FILE, + SOUND_TOT, + SOUND_EXT +}; + +class SoundDesc { +public: + int16 _repCount; + int16 _frequency; + int16 _flag; + int16 _id; + + byte *getData() { return _dataPtr; } + + uint32 size() const { return _size; } + bool empty() const { return !_dataPtr; } + SoundType getType() const { return _type; } + + bool isId(int16 id) const { return _dataPtr && (_id == id); } + + void set(SoundType type, SoundSource src, byte *data, uint32 dSize); + void load(SoundType type, SoundSource src, byte *data, uint32 dSize); + void free(); + void convToSigned(); + + // Which fade out length to use when the fade starts half-way through? + int16 calcFadeOutLength(int16 frequency); + uint32 calcLength(int16 repCount, int16 frequency, bool fade); + + SoundDesc(); + ~SoundDesc(); + +private: + byte *_data; + byte *_dataPtr; + uint32 _size; + + SoundType _type; + SoundSource _source; + + void loadSND(byte *data, uint32 dSize); + void loadADL(byte *data, uint32 dSize); +}; + +} // End of namespace Gob + +#endif // GOB_SOUND_SOUNDDESC_H diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 8e573ddb1a..4987426fe0 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -23,7 +23,6 @@ * */ - #include "common/events.h" #include "gob/gob.h" @@ -32,8 +31,8 @@ #include "gob/dataio.h" #include "gob/draw.h" #include "gob/game.h" -#include "gob/sound.h" #include "gob/video.h" +#include "gob/sound/sound.h" namespace Gob { @@ -60,7 +59,7 @@ void Util::beep(int16 freq) { if (_vm->_global->_soundFlags == 0) return; - _vm->_snd->speakerOn(freq, 50); + _vm->_sound->speakerOn(freq, 50); } void Util::delay(uint16 msecs) { diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 9a004318b8..e1777681df 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "graphics/cursorman.h" diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp index 4ed3b04bad..3c9627c041 100644 --- a/engines/gob/video_v1.cpp +++ b/engines/gob/video_v1.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp index 52b349ca67..ab0c7e52db 100644 --- a/engines/gob/video_v2.cpp +++ b/engines/gob/video_v2.cpp @@ -23,7 +23,6 @@ * */ - #include "common/endian.h" #include "gob/gob.h" |