From 963409192551f847d9222c570e7193982ab96bd4 Mon Sep 17 00:00:00 2001 From: Retro-Junk Date: Mon, 23 Jan 2017 02:13:32 +0300 Subject: CRYO: Add sound playback to HNM files (buggy yet) --- engines/cryo/bugs.txt | 2 ++ engines/cryo/eden.cpp | 17 ++++++++++++----- engines/cryo/eden.h | 2 +- engines/cryo/sound.cpp | 16 +++++++++++++--- engines/cryo/sound.h | 8 ++++++-- engines/cryo/video.cpp | 28 ++++++++++------------------ engines/cryo/video.h | 9 +++++---- 7 files changed, 49 insertions(+), 33 deletions(-) diff --git a/engines/cryo/bugs.txt b/engines/cryo/bugs.txt index aa1e61c6b7..12d0951737 100644 --- a/engines/cryo/bugs.txt +++ b/engines/cryo/bugs.txt @@ -16,3 +16,5 @@ E. Bogus hitbox in upper right corner of mirror screen (under mini-map) F. Wrong frescoes cursor on PC G. Junk on a valley entrance screen on PC H. On PC, no sound during first Mungo's dialogue, memory corruption after that +I. Crackling sound in HNM videos (ex. Mac intro video) +J. PC intro video is out of sync with background voice, crashes later diff --git a/engines/cryo/eden.cpp b/engines/cryo/eden.cpp index 50f9ecfc49..e44cfc7b25 100644 --- a/engines/cryo/eden.cpp +++ b/engines/cryo/eden.cpp @@ -5776,7 +5776,7 @@ void EdenGame::run() { word_378CE = 0; CRYOLib_ManagersInit(); - _vm->_video->setupSound(5, 0x2000, 8, 11025 * 65536.0 , 0); + _vm->_video->setupSound(11025, false, false); _vm->_video->setForceZero2Black(true); _vm->_video->setupTimer(12.5); _voiceSound = new Sound(0, 11025 * 65536.0, 8, 0); @@ -5885,7 +5885,7 @@ void EdenGame::intro() { // Play intro videos in HQ _hnmSoundChannel->stop(); _vm->_video->closeSound(); - _vm->_video->setupSound(5, 0x2000, 16, 22050 * 65536.0, 0); + _vm->_video->setupSound(22050, false, true); _hnmSoundChannel = _vm->_video->getSoundChannel(); playHNM(2012); playHNM(171); @@ -5894,13 +5894,20 @@ void EdenGame::intro() { playHNM(2001); _hnmSoundChannel->stop(); _vm->_video->closeSound(); - _vm->_video->setupSound(5, 0x2000, 8, 11025 * 65536.0, 0); + _vm->_video->setupSound(11025, false, false); _hnmSoundChannel = _vm->_video->getSoundChannel(); } else { - playHNM(98); // Cryo logo - playHNM(171); // Virgin logo + if (_vm->isDemo()) { + playHNM(171); // Virgin logo + playHNM(98); // Cryo logo + } + else { + playHNM(98); // Cryo logo + playHNM(171); // Virgin logo + } CLBlitter_FillScreenView(0); _specialTextMode = false; + startmusique(2); // INTRO.MUS is played during intro video playHNM(170); // Intro video } } diff --git a/engines/cryo/eden.h b/engines/cryo/eden.h index 4cc74494d3..33d9ffccde 100644 --- a/engines/cryo/eden.h +++ b/engines/cryo/eden.h @@ -641,7 +641,7 @@ private: CSoundChannel *_musicChannel; CSoundChannel *_voiceChannel; - SoundChannel *_hnmSoundChannel; + CSoundChannel *_hnmSoundChannel; Sound *_voiceSound; View *_view2; diff --git a/engines/cryo/sound.cpp b/engines/cryo/sound.cpp index 7b83072562..b653e60ec2 100644 --- a/engines/cryo/sound.cpp +++ b/engines/cryo/sound.cpp @@ -27,7 +27,10 @@ namespace Cryo { - CSoundChannel::CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo) : _mixer(mixer), _sampleRate(sampleRate), _stereo(stereo) { +CSoundChannel::CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo, bool is16bits) : _mixer(mixer), _sampleRate(sampleRate), _stereo(stereo) { + _bufferFlags = is16bits ? (Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_16BITS) : Audio::FLAG_UNSIGNED; + if (stereo) + _bufferFlags |= Audio::FLAG_STEREO; _audioStream = nullptr; _volumeLeft = _volumeRight = Audio::Mixer::kMaxChannelVolume; } @@ -38,12 +41,19 @@ CSoundChannel::~CSoundChannel() { delete _audioStream; } -void CSoundChannel::queueBuffer(byte *buffer, unsigned int size, bool playNow) { +void CSoundChannel::queueBuffer(byte *buffer, unsigned int size, bool playNow, bool playQueue) { if (playNow) stop(); if (!_audioStream) _audioStream = Audio::makeQueuingAudioStream(_sampleRate, _stereo); - _audioStream->queueBuffer(buffer, size, DisposeAfterUse::NO, Audio::FLAG_UNSIGNED); + _audioStream->queueBuffer(buffer, size, DisposeAfterUse::NO, _bufferFlags); + if (playNow || playQueue) + play(); +} + +void CSoundChannel::play() { + if (!_audioStream) + return; if (!_mixer->isSoundHandleActive(_soundHandle)) { _mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundHandle, _audioStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO); applyVolumeChange(); diff --git a/engines/cryo/sound.h b/engines/cryo/sound.h index b82cfcf403..2136c658a4 100644 --- a/engines/cryo/sound.h +++ b/engines/cryo/sound.h @@ -39,15 +39,19 @@ private: Audio::SoundHandle _soundHandle; unsigned int _sampleRate; bool _stereo; + unsigned int _bufferFlags; void applyVolumeChange(); public: - CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo); + CSoundChannel(Audio::Mixer *mixer, unsigned int sampleRate, bool stereo, bool is16bits = false); ~CSoundChannel(); // Queue a new buffer, cancel any previously queued buffers if playNow is set - void queueBuffer(byte *buffer, unsigned int size, bool playNow = false); + void queueBuffer(byte *buffer, unsigned int size, bool playNow = false, bool playQueue = true); + + // Play any queued buffers + void play(); // Stop playing and purge play queue void stop(); diff --git a/engines/cryo/video.cpp b/engines/cryo/video.cpp index cb8a00122d..88326e647e 100644 --- a/engines/cryo/video.cpp +++ b/engines/cryo/video.cpp @@ -32,9 +32,8 @@ HnmPlayer::HnmPlayer(CryoEngine *vm) : _vm(vm) { _expectedFrameTime = 0.0; _rate = 0.0; _useSoundSync = false; - _useSound = false; + _useSound = true; _soundChannel = nullptr; - _soundGroup = nullptr; _prevRight = _prevLeft = 0; _useAdpcm = false; _customChunkHandler = nullptr; @@ -89,6 +88,7 @@ void HnmPlayer::reset() { void HnmPlayer::init() { _customChunkHandler = nullptr; _preserveColor0 = false; + _useSound = true; } // Original name: CLHNM_SetForceZero2Black @@ -112,9 +112,8 @@ void HnmPlayer::wantsSound(bool sound) { } // Original name: CLHNM_SetupSound -void HnmPlayer::setupSound(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode) { - _soundChannel = new SoundChannel(mode); - _soundGroup = new SoundGroup(_vm, numSounds, length, sampleSize, rate, mode); +void HnmPlayer::setupSound(unsigned int rate, bool stereo, bool is16bits) { + _soundChannel = new CSoundChannel(_vm->_mixer, rate, stereo, is16bits); } // Original name: CLHNM_CloseSound @@ -124,11 +123,6 @@ void HnmPlayer::closeSound() { delete(_soundChannel); _soundChannel = nullptr; } - - if (_soundGroup) { - delete(_soundGroup); - _soundGroup = nullptr; - } } // Original name: CLHNM_LoadDecompTable @@ -484,8 +478,7 @@ bool HnmPlayer::nextElement() { } if (!_soundStarted) { - for (int16 i = 0; i < _pendingSounds; i++) - _soundGroup->playNextSample(_soundChannel); + _soundChannel->play(); _soundStarted = true; } @@ -510,12 +503,10 @@ bool HnmPlayer::nextElement() { if (!h6) { int sound_size = sz - 8; if (!_useAdpcm) { - _soundGroup->setDatas(_dataPtr, sound_size - 2, false); - if (_soundStarted) - _soundGroup->playNextSample(_soundChannel); - else - _pendingSounds++; + _soundChannel->queueBuffer(_dataPtr, sound_size - 2, false, _soundStarted); } else { +#if 0 + // Not used in Lost Eden int16 *sound_buffer = (int16 *)_soundGroup->getNextBuffer(); if (!_pendingSounds) { const int kDecompTableSize = 256 * sizeof(int16); @@ -529,6 +520,7 @@ bool HnmPlayer::nextElement() { _pendingSounds++; if (_soundStarted) _soundGroup->playNextSample(_soundChannel); +#endif } } else error("nextElement - unexpected flag"); @@ -545,7 +537,7 @@ bool HnmPlayer::nextElement() { } // Original name: CLHNM_GetSoundChannel -SoundChannel *HnmPlayer::getSoundChannel() { +CSoundChannel *HnmPlayer::getSoundChannel() { return _soundChannel; } diff --git a/engines/cryo/video.h b/engines/cryo/video.h index edd94c6d40..83eddfb9b1 100644 --- a/engines/cryo/video.h +++ b/engines/cryo/video.h @@ -23,6 +23,8 @@ #ifndef CRYO_VIDEO_H #define CRYO_VIDEO_H +#include "cryo/sound.h" + namespace Cryo { class CryoEngine; @@ -76,8 +78,7 @@ private: void (*_customChunkHandler)(byte *buffer, int size, int16 id, char h6, char h7); - SoundChannel *_soundChannel; - SoundGroup *_soundGroup; + CSoundChannel *_soundChannel; public: HnmPlayer(CryoEngine *vm); @@ -86,7 +87,7 @@ public: void closeSound(); void deallocMemory(); int getFrameNum(); - SoundChannel *getSoundChannel(); + CSoundChannel *getSoundChannel(); int16 getVersion(); bool nextElement(); void reset(); @@ -95,7 +96,7 @@ public: void setFile(Common::File *file); void setFinalBuffer(byte *buffer); void setForceZero2Black(bool forceblack); - void setupSound(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode); + void setupSound(unsigned int rate, bool stereo, bool is16bits); void setupTimer(float rate); void waitLoop(); }; -- cgit v1.2.3