diff options
-rw-r--r-- | sky/intro.cpp | 7 | ||||
-rw-r--r-- | sky/logic.cpp | 6 | ||||
-rw-r--r-- | sky/logic.h | 3 | ||||
-rw-r--r-- | sky/musicbase.cpp | 2 | ||||
-rw-r--r-- | sky/musicbase.h | 2 | ||||
-rw-r--r-- | sky/sky.cpp | 4 | ||||
-rw-r--r-- | sky/sound.cpp | 56 | ||||
-rw-r--r-- | sky/sound.h | 14 |
8 files changed, 81 insertions, 13 deletions
diff --git a/sky/intro.cpp b/sky/intro.cpp index de26433e1e..edd55fde39 100644 --- a/sky/intro.cpp +++ b/sky/intro.cpp @@ -197,7 +197,8 @@ void SkyState::intro(void) { _skyDisk->prefetchFile(60112); // revolution screen _skyDisk->prefetchFile(60113); // revolution palette - _skyMusic->loadSectionMusic(0); + _skyMusic->loadSection(0); + _skySound->loadSection(0); delay(3000); //keep virgin screen up for 3 seconds CHECK_ESC @@ -475,12 +476,12 @@ void SkyState::removeText(uint32 *&cmdPtr) { void SkyState::introFx(uint32 *&cmdPtr) { - warning("introFx() not implemented yet"); + _skySound->playSound((uint16)cmdPtr[2], (uint16)cmdPtr[3]); cmdPtr += 4; } void SkyState::introVol(uint32 *&cmdPtr) { - warning("introVol() not implemented yet"); + _mixer->setVolume(((cmdPtr[2] & 0x7F) + 1) << 1); cmdPtr += 3; } diff --git a/sky/logic.cpp b/sky/logic.cpp index 3c730ef794..40b7951983 100644 --- a/sky/logic.cpp +++ b/sky/logic.cpp @@ -48,11 +48,12 @@ static const LogicTable logicTable[] = { &SkyLogic::simpleAnim, // 16 Module anim without x,y's }; -SkyLogic::SkyLogic(SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, uint32 gameVersion) { +SkyLogic::SkyLogic(SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, SkySound *skySound, uint32 gameVersion) { _skyDisk = skyDisk; _skyGrid = skyGrid; _skyText = skyText; _skyMusic = skyMusic; + _skySound = skySound; _skyMouse = skyMouse; _gameVersion = gameVersion; _skyAutoRoute = new SkyAutoRoute(_skyGrid); @@ -1552,7 +1553,8 @@ uint32 SkyLogic::fnEnterSection(uint32 sectionNo, uint32 b, uint32 c) { _saveCurrentSection = sectionNo; sectionNo++; - _skyMusic->loadSectionMusic((byte)sectionNo); + _skyMusic->loadSection((byte)sectionNo); + _skySound->loadSection((byte)sectionNo); _skyGrid->loadGrids(); } diff --git a/sky/logic.h b/sky/logic.h index b0cea353b3..85537aed1a 100644 --- a/sky/logic.h +++ b/sky/logic.h @@ -31,7 +31,7 @@ class SkyLogic { public: - SkyLogic(SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, uint32 gameVersion); + SkyLogic(SkyDisk *skyDisk, SkyGrid *skyGrid, SkyText *skyText, SkyMusicBase *skyMusic, SkyMouse *skyMouse, SkySound *skySound, uint32 gameVersion); void engine(); void lreturn(); @@ -196,6 +196,7 @@ protected: SkyGrid *_skyGrid; SkyText *_skyText; SkyMusicBase *_skyMusic; + SkySound *_skySound; SkyAutoRoute *_skyAutoRoute; SkyMouse *_skyMouse; }; diff --git a/sky/musicbase.cpp b/sky/musicbase.cpp index 39943057c3..48957f0407 100644 --- a/sky/musicbase.cpp +++ b/sky/musicbase.cpp @@ -34,7 +34,7 @@ SkyMusicBase::~SkyMusicBase(void) if (_musicData) free(_musicData); } -void SkyMusicBase::loadSectionMusic(uint8 pSection) +void SkyMusicBase::loadSection(uint8 pSection) { if (_currentMusic) stopMusic(); if (_musicData) free(_musicData); diff --git a/sky/musicbase.h b/sky/musicbase.h index 34c0f39e79..587d9d8a8d 100644 --- a/sky/musicbase.h +++ b/sky/musicbase.h @@ -45,7 +45,7 @@ class SkyMusicBase { public: SkyMusicBase(SkyDisk *pSkyDisk); virtual ~SkyMusicBase(void); - void loadSectionMusic(uint8 pSection); + void loadSection(uint8 pSection); void musicCommand(uint16 command); void startMusic(uint16 param) { _onNextPoll.musicToProcess = param & 0xF; }; // 4 diff --git a/sky/sky.cpp b/sky/sky.cpp index bf6dc1b319..1d45413d3f 100644 --- a/sky/sky.cpp +++ b/sky/sky.cpp @@ -106,8 +106,8 @@ void SkyState::initialise(void) { //initialise_memory(); - _skySound = new SkySound(_mixer); _skyDisk = new SkyDisk(_gameDataPath); + _skySound = new SkySound(_mixer, _skyDisk); if (_detector->getMidiDriverType() == MD_ADLIB) { _skyMusic = new SkyAdlibMusic(_mixer, _skyDisk); @@ -127,7 +127,7 @@ void SkyState::initialise(void) { //initialiseRouter(); loadFixedItems(); _skyGrid = new SkyGrid(_skyDisk); - _skyLogic = new SkyLogic(_skyDisk, _skyGrid, _skyText, _skyMusic, _skyMouse, _gameVersion); + _skyLogic = new SkyLogic(_skyDisk, _skyGrid, _skyText, _skyMusic, _skyMouse, _skySound, _gameVersion); _timer = Engine::_timer; // initialize timer *after* _skyScreen has been initialized. _timer->installProcedure(&timerHandler, 1000000 / 50); //call 50 times per second diff --git a/sky/sound.cpp b/sky/sound.cpp index 9951ad9f14..1447b8e937 100644 --- a/sky/sound.cpp +++ b/sky/sound.cpp @@ -23,11 +23,23 @@ #include "sky/sound.h" #include "sky/struc.h" -SkySound::SkySound(SoundMixer *mixer) { +#define SOUND_FILE_BASE 60203 +#define SFX_BASE 0xA60 + +SkySound::SkySound(SoundMixer *mixer, SkyDisk *pDisk) { + _skyDisk = pDisk; + _soundData = NULL; _mixer = mixer; _voiceHandle = 0; _effectHandle = 0; _bgSoundHandle = 0; + _ingameSound = 0; +} + +SkySound::~SkySound(void) { + + if (_ingameSound) _mixer->stop(_ingameSound - 1); + if (_soundData) free(_soundData); } int SkySound::playVoice(byte *sound, uint32 size) { @@ -52,3 +64,45 @@ int SkySound::playSound(byte *sound, uint32 size, PlayingSoundHandle *handle) { return _mixer->playRaw(handle, buffer, size, 11025, flags); } + +void SkySound::loadSection(uint8 pSection) { + + if (_ingameSound) _mixer->stop(_ingameSound - 1); + _ingameSound = 0; + if (_soundData) free(_soundData); + _soundData = _skyDisk->loadFile(pSection * 4 + SOUND_FILE_BASE, NULL); + _sampleRates = _soundData + 0xA4E; + _sfxInfo = _soundData + 0xA60; +} + +void SkySound::playSound(uint16 sound, uint16 volume) { + + if (!_soundData) { + warning("SkySound::playSound(%04X, %04X) called with a section having been loaded.\n", sound, volume); + return; + } + + if (sound > 2) { + if (sound & 0x80) warning("SkySound::playSound(%04X, %04X) not implemented.\n", sound, volume); + else warning("SkySound::playSound(%04X, %04X) ignored.\n", sound, volume); + return ; + } + + volume = ((volume & 0x7F) + 1) << 1; + sound &= 0xFF; + + // note: all those tables are big endian. Don't ask me why. *sigh* + uint16 sampleRate = (_sampleRates[sound << 2] << 8) | _sampleRates[(sound << 2) | 1]; + uint16 dataOfs = ((_sfxInfo[sound << 3] << 8) | _sfxInfo[(sound << 3) | 1]) << 4; + dataOfs += SFX_BASE; + uint16 dataSize = (_sfxInfo[(sound << 3) | 2] << 8) | _sfxInfo[(sound << 3) | 3]; + uint16 dataLoop = (_sfxInfo[(sound << 3) | 6] << 8) | _sfxInfo[(sound << 3) | 7]; + + byte flags = SoundMixer::FLAG_UNSIGNED; + if (dataSize == dataLoop) + flags |= SoundMixer::FLAG_LOOP; + + if (_ingameSound) _mixer->stop(_ingameSound - 1); + _mixer->setVolume(volume); + _mixer->playRaw(&_ingameSound, _soundData + dataOfs, dataSize, sampleRate, flags); +}
\ No newline at end of file diff --git a/sky/sound.h b/sky/sound.h index a1083a67bc..3f3ff84c34 100644 --- a/sky/sound.h +++ b/sky/sound.h @@ -19,8 +19,9 @@ * */ - #include "sound/mixer.h" +#include "sky/disk.h" +#include "common/engine.h" class SkySound { protected: @@ -31,15 +32,24 @@ public: PlayingSoundHandle _voiceHandle; PlayingSoundHandle _effectHandle; PlayingSoundHandle _bgSoundHandle; + PlayingSoundHandle _ingameSound; protected: int playSound(byte *sound, uint32 size, PlayingSoundHandle *handle); public: - SkySound(SoundMixer *mixer); + SkySound(SoundMixer *mixer, SkyDisk *pDisk); + ~SkySound(void); int playVoice(byte *sound, uint32 size); int playBgSound(byte *sound, uint32 size); + void loadSection(uint8 pSection); + void playSound(uint16 sound, uint16 volume); + +private: + SkyDisk *_skyDisk; + uint8 *_soundData; + uint8 *_sampleRates, *_sfxInfo; }; |