CRYO: Add sound playback to HNM files (buggy yet)

This commit is contained in:
Retro-Junk 2017-01-23 02:13:32 +03:00 committed by Eugene Sandulenko
parent d23bb8860b
commit 9634091925
7 changed files with 49 additions and 33 deletions

View File

@ -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

View File

@ -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
}
}

View File

@ -641,7 +641,7 @@ private:
CSoundChannel *_musicChannel;
CSoundChannel *_voiceChannel;
SoundChannel *_hnmSoundChannel;
CSoundChannel *_hnmSoundChannel;
Sound *_voiceSound;
View *_view2;

View File

@ -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();

View File

@ -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();

View File

@ -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;
}

View File

@ -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();
};