diff options
Diffstat (limited to 'engines/made')
-rw-r--r-- | engines/made/database.cpp | 6 | ||||
-rw-r--r-- | engines/made/made.cpp | 2 | ||||
-rw-r--r-- | engines/made/music.cpp | 52 | ||||
-rw-r--r-- | engines/made/music.h | 3 | ||||
-rw-r--r-- | engines/made/pmvplayer.cpp | 20 | ||||
-rw-r--r-- | engines/made/redreader.cpp | 16 | ||||
-rw-r--r-- | engines/made/resource.cpp | 4 | ||||
-rw-r--r-- | engines/made/screenfx.cpp | 9 | ||||
-rw-r--r-- | engines/made/screenfx.h | 1 | ||||
-rw-r--r-- | engines/made/script.cpp | 5 | ||||
-rw-r--r-- | engines/made/script.h | 1 | ||||
-rw-r--r-- | engines/made/scriptfuncs.cpp | 2 | ||||
-rw-r--r-- | engines/made/sound.cpp | 26 | ||||
-rw-r--r-- | engines/made/sound.h | 17 |
14 files changed, 141 insertions, 23 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp index a9855ba1fe..3eab31acc2 100644 --- a/engines/made/database.cpp +++ b/engines/made/database.cpp @@ -252,6 +252,10 @@ byte *ObjectV3::getData() { GameDatabase::GameDatabase(MadeEngine *vm) : _vm(vm) { + _gameState = nullptr; + _gameStateSize = 0; + _mainCodeObjectIndex = 0; + _isRedSource = false; } GameDatabase::~GameDatabase() { @@ -595,6 +599,8 @@ const char *GameDatabaseV2::getString(uint16 offset) { /* GameDatabaseV3 */ GameDatabaseV3::GameDatabaseV3(MadeEngine *vm) : GameDatabase(vm) { + _gameText = nullptr; + _gameStateOffs = 0; } void GameDatabaseV3::load(Common::SeekableReadStream &sourceS) { diff --git a/engines/made/made.cpp b/engines/made/made.cpp index af8156fc3e..ab07ef757b 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -275,7 +275,7 @@ void MadeEngine::handleEvents() { } Common::Error MadeEngine::run() { - _music = new MusicPlayer(); + _music = new MusicPlayer(getGameID() == GID_RTZ); syncSoundSettings(); // Initialize backend diff --git a/engines/made/music.cpp b/engines/made/music.cpp index b2917b58ed..f57da833c2 100644 --- a/engines/made/music.cpp +++ b/engines/made/music.cpp @@ -25,27 +25,67 @@ // MIDI and digital music class #include "made/music.h" +#include "made/redreader.h" #include "made/resource.h" #include "audio/midiparser.h" +#include "audio/miles.h" + +#include "common/file.h" +#include "common/stream.h" namespace Made { -MusicPlayer::MusicPlayer() : _isGM(false) { - MidiPlayer::createDriver(); +MusicPlayer::MusicPlayer(bool milesAudio) : _isGM(false),_milesAudioMode(false) { + MusicType musicType = MT_INVALID; + if (milesAudio) { + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MT32); + musicType = MidiDriver::getMusicType(dev); + Common::SeekableReadStream *adLibInstrumentStream = nullptr; + switch (musicType) { + case MT_ADLIB: + _milesAudioMode = true; + if (Common::File::exists("rtzcd.red")) { + // Installing Return to Zork produces both a SAMPLE.AD and + // a SAMPLE.OPL file, but they are identical. The resource + // file appears to only contain SAMPLE.AD. + adLibInstrumentStream = RedReader::loadFromRed("rtzcd.red", "SAMPLE.AD"); + } + _driver = Audio::MidiDriver_Miles_AdLib_create("SAMPLE.AD", "SAMPLE.OPL", adLibInstrumentStream); + delete adLibInstrumentStream; + break; + case MT_MT32: + _milesAudioMode = true; + _driver = Audio::MidiDriver_Miles_MT32_create(""); + break; + default: + _milesAudioMode = false; + MidiPlayer::createDriver(); + break; + } + } else { + MidiPlayer::createDriver(); + } int ret = _driver->open(); if (ret == 0) { - if (_nativeMT32) - _driver->sendMT32Reset(); - else - _driver->sendGMReset(); + if (musicType != MT_ADLIB) { + if (_nativeMT32) + _driver->sendMT32Reset(); + else + _driver->sendGMReset(); + } _driver->setTimerCallback(this, &timerCallback); } } void MusicPlayer::send(uint32 b) { + if (_milesAudioMode) { + _driver->send(b); + return; + } + if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) { b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8; } diff --git a/engines/made/music.h b/engines/made/music.h index 95d1bd35c1..558b41c2e2 100644 --- a/engines/made/music.h +++ b/engines/made/music.h @@ -38,7 +38,7 @@ enum MusicFlags { class MusicPlayer : public Audio::MidiPlayer { public: - MusicPlayer(); + MusicPlayer(bool milesAudio); void playXMIDI(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL); void playSMF(GenericResource *midiResource, MusicFlags flags = MUSIC_NORMAL); @@ -51,6 +51,7 @@ public: protected: bool _isGM; + bool _milesAudioMode; }; } // End of namespace Made diff --git a/engines/made/pmvplayer.cpp b/engines/made/pmvplayer.cpp index 3cac017e10..453e2a4872 100644 --- a/engines/made/pmvplayer.cpp +++ b/engines/made/pmvplayer.cpp @@ -37,16 +37,18 @@ namespace Made { -PmvPlayer::PmvPlayer(MadeEngine *vm, Audio::Mixer *mixer) : _fd(NULL), _vm(vm), _mixer(mixer) { +PmvPlayer::PmvPlayer(MadeEngine *vm, Audio::Mixer *mixer) : _fd(nullptr), _vm(vm), _mixer(mixer) { + _audioStream = nullptr; + _surface = nullptr; + _aborted = false; } PmvPlayer::~PmvPlayer() { } bool PmvPlayer::play(const char *filename) { - _aborted = false; - _surface = NULL; + _surface = nullptr; _fd = new Common::File(); if (!_fd->open(filename)) { @@ -81,8 +83,11 @@ bool PmvPlayer::play(const char *filename) { // results to sound being choppy. Therefore, we set them to more // "common" values here (11025 instead of 11127 and 22050 instead // of 22254) - if (soundFreq == 11127) soundFreq = 11025; - if (soundFreq == 22254) soundFreq = 22050; + if (soundFreq == 11127) + soundFreq = 11025; + + if (soundFreq == 22254) + soundFreq = 22050; for (int i = 0; i < 22; i++) { int unk = _fd->readUint16LE(); @@ -113,6 +118,8 @@ bool PmvPlayer::play(const char *filename) { // get it to work well? _audioStream = Audio::makeQueuingAudioStream(soundFreq, false); + SoundDecoderData *soundDecoderData = new SoundDecoderData(); + while (!_vm->shouldQuit() && !_aborted && !_fd->eos() && frameNumber < frameCount) { int32 frameTime = _vm->_system->getMillis(); @@ -148,7 +155,7 @@ bool PmvPlayer::play(const char *filename) { soundSize = chunkCount * chunkSize; soundData = (byte *)malloc(soundSize); - decompressSound(audioData + 8, soundData, chunkSize, chunkCount); + decompressSound(audioData + 8, soundData, chunkSize, chunkCount, NULL, soundDecoderData); _audioStream->queueBuffer(soundData, soundSize, DisposeAfterUse::YES, Audio::FLAG_UNSIGNED); } @@ -208,6 +215,7 @@ bool PmvPlayer::play(const char *filename) { } + delete soundDecoderData; delete[] frameData; _audioStream->finish(); diff --git a/engines/made/redreader.cpp b/engines/made/redreader.cpp index f5e6ca85b3..f92ffd8dd8 100644 --- a/engines/made/redreader.cpp +++ b/engines/made/redreader.cpp @@ -76,6 +76,22 @@ bool RedReader::seekFile(Common::File &fd, FileEntry &fileEntry, const char *fil } LzhDecompressor::LzhDecompressor() { + freq = nullptr; + len_table = nullptr; + sortptr = nullptr; + _source = nullptr; + + _compSize = 0; + _blockPos = 0; + _bitbuf = 0; + _subbitbuf = 0; + _bitcount = 0; + _blocksize = 0; + tree_n = 0; + heapsize = 0; + decode_i = 0; + decode_j = 0; + count_len_depth = 0; } LzhDecompressor::~LzhDecompressor() { diff --git a/engines/made/resource.cpp b/engines/made/resource.cpp index 2c75965976..f8e763e74e 100644 --- a/engines/made/resource.cpp +++ b/engines/made/resource.cpp @@ -241,6 +241,7 @@ void AnimationResource::load(byte *source, int size) { /* SoundResource */ SoundResource::SoundResource() : _soundSize(0), _soundData(NULL) { + _soundEnergyArray = nullptr; } SoundResource::~SoundResource() { @@ -377,6 +378,9 @@ void GenericResource::load(byte *source, int size) { ResourceReader::ResourceReader() { _isV1 = false; _cacheDataSize = 0; + + _fd = _fdMusic = _fdPics = _fdSounds = nullptr; + _cacheCount = 0; } ResourceReader::~ResourceReader() { diff --git a/engines/made/screenfx.cpp b/engines/made/screenfx.cpp index 2a155d67ac..bae59f05cc 100644 --- a/engines/made/screenfx.cpp +++ b/engines/made/screenfx.cpp @@ -51,7 +51,12 @@ ScreenEffects::ScreenEffects(Screen *screen) : _screen(screen) { vfxHeight = 0; _fxPalette = new byte[768]; - + + _blendedPaletteStatus._active = false; + _blendedPaletteStatus._palette = _blendedPaletteStatus._newPalette = nullptr; + _blendedPaletteStatus._colorCount = 0; + _blendedPaletteStatus._value = _blendedPaletteStatus._maxValue = 0; + _blendedPaletteStatus._incr = 0; } ScreenEffects::~ScreenEffects() { @@ -196,7 +201,7 @@ void ScreenEffects::startBlendedPalette(byte *palette, byte *newPalette, int col } void ScreenEffects::stepBlendedPalette() { - if (_blendedPaletteStatus._active && _blendedPaletteStatus._value < _blendedPaletteStatus._maxValue) { + if (_blendedPaletteStatus._active && _blendedPaletteStatus._value <= _blendedPaletteStatus._maxValue) { setBlendedPalette(_blendedPaletteStatus._palette, _blendedPaletteStatus._newPalette, _blendedPaletteStatus._colorCount, _blendedPaletteStatus._value, _blendedPaletteStatus._maxValue); if (_blendedPaletteStatus._value == _blendedPaletteStatus._maxValue) diff --git a/engines/made/screenfx.h b/engines/made/screenfx.h index fd216bfd63..cedb059927 100644 --- a/engines/made/screenfx.h +++ b/engines/made/screenfx.h @@ -38,7 +38,6 @@ struct BlendedPaletteStatus { byte *_palette, *_newPalette; int _colorCount; int16 _value, _maxValue, _incr; - int cnt; }; class ScreenEffects { diff --git a/engines/made/script.cpp b/engines/made/script.cpp index 20fa026a40..f9f7acffde 100644 --- a/engines/made/script.cpp +++ b/engines/made/script.cpp @@ -122,6 +122,11 @@ ScriptInterpreter::ScriptInterpreter(MadeEngine *vm) : _vm(vm) { _functions = new ScriptFunctions(_vm); _functions->setupExternalsTable(); + _localStackPos = 0; + _runningScriptObjectIndex = 0; + _codeBase = nullptr; + _codeIp = nullptr; + #undef COMMAND } diff --git a/engines/made/script.h b/engines/made/script.h index bf75bc0875..f28425d13b 100644 --- a/engines/made/script.h +++ b/engines/made/script.h @@ -84,7 +84,6 @@ protected: int16 _localStackPos; int16 _runningScriptObjectIndex; byte *_codeBase, *_codeIp; - bool _terminated; ScriptFunctions *_functions; diff --git a/engines/made/scriptfuncs.cpp b/engines/made/scriptfuncs.cpp index efa765c7eb..bcc08e0dcc 100644 --- a/engines/made/scriptfuncs.cpp +++ b/engines/made/scriptfuncs.cpp @@ -42,6 +42,8 @@ ScriptFunctions::ScriptFunctions(MadeEngine *vm) : _vm(vm), _soundStarted(false) _pcSpeaker2 = new Audio::PCSpeaker(); _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_pcSpeakerHandle1, _pcSpeaker1); _vm->_system->getMixer()->playStream(Audio::Mixer::kMusicSoundType, &_pcSpeakerHandle2, _pcSpeaker2); + _soundResource = nullptr; + _musicRes = nullptr; } ScriptFunctions::~ScriptFunctions() { diff --git a/engines/made/sound.cpp b/engines/made/sound.cpp index 91e855cbf5..ad49031e7b 100644 --- a/engines/made/sound.cpp +++ b/engines/made/sound.cpp @@ -133,10 +133,10 @@ void ManholeEgaSoundDecompressor::update3() { _sample2 += _sample1; } -void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray) { +void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray, SoundDecoderData *soundDecoderData) { - int16 prevSample = 0, workSample = 0; - byte soundBuffer[1025]; + int16 prevSample, workSample; + byte* soundBuffer; byte deltaSoundBuffer[1024]; int16 soundBuffer2[16]; byte deltaType, type; @@ -159,6 +159,15 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou if (soundEnergyArray) soundEnergyArray->clear(); + if (soundDecoderData) { + soundBuffer = soundDecoderData->_soundBuffer; + prevSample = soundDecoderData->_prevSample; + } else { + soundBuffer = new byte[1025]; + memset(soundBuffer, 0x80, 1025); + prevSample = 0; + } + while (chunkCount--) { deltaType = (*source) >> 6; workChunkSize = chunkSize; @@ -233,6 +242,11 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou } if (deltaType > 0) { + // NB: The original did not add this extra value at the end (as far + // as I can tell), and so technically read past the filled part of + // soundBuffer. + soundBuffer[workChunkSize] = soundBuffer[workChunkSize - 1]; + if (deltaType == 1) { for (i = 0; i < chunkSize - 1; i += 2) { l = i / 2; @@ -255,9 +269,13 @@ void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCou prevSample = workSample; memcpy(dest, soundBuffer, chunkSize); dest += chunkSize; - } + if (soundDecoderData) { + soundDecoderData->_prevSample = prevSample; + } else { + delete[] soundBuffer; + } } } // End of namespace Made diff --git a/engines/made/sound.h b/engines/made/sound.h index 6ffca13aaa..72537322f9 100644 --- a/engines/made/sound.h +++ b/engines/made/sound.h @@ -53,7 +53,22 @@ struct SoundEnergyItem { typedef Common::Array<SoundEnergyItem> SoundEnergyArray; -void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray = NULL); + +// Persistent data for decompressSound(). When calling decompressSound() +// repeatedly (for the same stream), pass the same SoundDecoderData object to +// ensure decoding properly resumes. +class SoundDecoderData { +public: + SoundDecoderData() { + memset(_soundBuffer, 0x80, sizeof(_soundBuffer)); + _prevSample = 0; + } + + byte _soundBuffer[1025]; + int16 _prevSample; +}; + +void decompressSound(byte *source, byte *dest, uint16 chunkSize, uint16 chunkCount, SoundEnergyArray *soundEnergyArray = NULL, SoundDecoderData *decoderData = NULL); } // End of namespace Made |