diff options
28 files changed, 232 insertions, 111 deletions
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp index 331c850b1a..ff87e7a9f8 100644 --- a/audio/decoders/quicktime.cpp +++ b/audio/decoders/quicktime.cpp @@ -241,6 +241,15 @@ void QuickTimeAudioDecoder::QuickTimeAudioTrack::queueAudio(const Timestamp &len // If we have any samples that we need to skip (ie. we seeked into // the middle of a chunk), skip them here. if (_skipSamples != Timestamp()) { + if (_skipSamples > chunkLength) { + // If the amount we need to skip is greater than the size + // of the chunk, just skip it altogether. + _curMediaPos = _curMediaPos + chunkLength; + _skipSamples = _skipSamples - chunkLength; + delete stream; + continue; + } + skipSamples(_skipSamples, stream); _curMediaPos = _curMediaPos + _skipSamples; chunkLength = chunkLength - _skipSamples; diff --git a/engines/access/access.cpp b/engines/access/access.cpp index 7f59ae7ad6..0a4e519c91 100644 --- a/engines/access/access.cpp +++ b/engines/access/access.cpp @@ -94,6 +94,9 @@ AccessEngine::AccessEngine(OSystem *syst, const AccessGameDescription *gameDesc) _cheatFl = false; _restartFl = false; _printEnd = 0; + for (int i = 0; i < 100; i++) + _objectsTable[i] = nullptr; + _clearSummaryFlag = false; } AccessEngine::~AccessEngine() { diff --git a/engines/access/files.cpp b/engines/access/files.cpp index 42a7914638..4d734a67a9 100644 --- a/engines/access/files.cpp +++ b/engines/access/files.cpp @@ -40,6 +40,10 @@ void FileIdent::load(Common::SeekableReadStream &s) { /*------------------------------------------------------------------------*/ +CellIdent:: CellIdent() { + _cell = 0; +} + CellIdent::CellIdent(int cell, int fileNum, int subfile) { _cell = cell; _fileNum = fileNum; diff --git a/engines/access/files.h b/engines/access/files.h index 8b1aef0363..714ea44c75 100644 --- a/engines/access/files.h +++ b/engines/access/files.h @@ -46,7 +46,7 @@ struct FileIdent { struct CellIdent : FileIdent { byte _cell; - CellIdent() {} + CellIdent(); CellIdent(int cell, int fileNum, int subfile); }; 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/pmvplayer.cpp b/engines/made/pmvplayer.cpp index 3cac017e10..6ea0dc24d0 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(); 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..3f98cbb9ab 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() { 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/tsage/blue_force/blueforce_scenes8.cpp b/engines/tsage/blue_force/blueforce_scenes8.cpp index 6855fd41b9..337e73dad0 100644 --- a/engines/tsage/blue_force/blueforce_scenes8.cpp +++ b/engines/tsage/blue_force/blueforce_scenes8.cpp @@ -964,9 +964,10 @@ Scene810::Scene810(): SceneExt() { } void Scene810::synchronize(Serializer &s) { + int dummy = 0; SceneExt::synchronize(s); s.syncAsSint16LE(_fieldA70); - s.syncAsSint16LE(_fieldA72); + s.syncAsSint16LE(dummy); s.syncAsSint16LE(_fieldA74); } @@ -2220,6 +2221,7 @@ Scene840::Scene840(): PalettedScene() { _field1AC2 = 0; _field1AC4 = 0; _field1AC6 = (BF_GLOBALS._dayNumber > 3) ? 1 : 0; + _field1ABA = 0; } void Scene840::synchronize(Serializer &s) { diff --git a/engines/tsage/blue_force/blueforce_scenes8.h b/engines/tsage/blue_force/blueforce_scenes8.h index 140327e85d..09de14f150 100644 --- a/engines/tsage/blue_force/blueforce_scenes8.h +++ b/engines/tsage/blue_force/blueforce_scenes8.h @@ -229,7 +229,7 @@ public: Exit _exit; ASoundExt _sound1; Rect _rect1, _rect2, _rect3; - int _fieldA70, _fieldA72, _fieldA74; + int _fieldA70, _fieldA74; Scene810(); virtual void synchronize(Serializer &s); diff --git a/engines/tsage/blue_force/blueforce_scenes9.cpp b/engines/tsage/blue_force/blueforce_scenes9.cpp index 53000d6997..5ba82a4714 100644 --- a/engines/tsage/blue_force/blueforce_scenes9.cpp +++ b/engines/tsage/blue_force/blueforce_scenes9.cpp @@ -3521,7 +3521,7 @@ void Scene935::Action1::signal() { scene->_visualSpeaker.removeText(); scene->_visualSpeaker._textPos.y = scene->_sceneBounds.top + 80; scene->_visualSpeaker._color1 = 252; - scene->_visualSpeaker._color1 = 251; + scene->_visualSpeaker._color2 = 251; scene->_visualSpeaker.setText("Jake! Hide in the closet!"); setDelay(3); break; @@ -3538,7 +3538,7 @@ void Scene935::Action1::signal() { scene->_visualSpeaker.removeText(); scene->_visualSpeaker._textPos.y = scene->_sceneBounds.top + 150; scene->_visualSpeaker._color1 = 250; - scene->_visualSpeaker._color1 = 249; + scene->_visualSpeaker._color2 = 249; scene->_visualSpeaker.setText("Jake! Hide in the closet!"); setDelay(3); break; diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index f35aa583e2..3105a9008e 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -56,6 +56,9 @@ InvObject::InvObject(int sceneNumber, int rlbNum, int cursorNum, CursorType curs _bounds = s.getBounds(); DEALLOCATE(imgData); + _visage = 0; + _strip = 0; + _frame = 0; } InvObject::InvObject(int visage, int strip, int frame) { diff --git a/engines/tsage/ringworld/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp index d8556c691e..a515224964 100644 --- a/engines/tsage/ringworld/ringworld_scenes3.cpp +++ b/engines/tsage/ringworld/ringworld_scenes3.cpp @@ -494,7 +494,7 @@ void Scene2100::Action1::signal() { setDelay(1); else { setAction(&scene->_sequenceManager, this, 2102, &g_globals->_player, NULL); - scene->_sitFl = 0; + scene->_sitFl = false; } break; case 1: { @@ -1548,6 +1548,7 @@ Scene2100::Scene2100() : _area3._pt = Common::Point(200, 75); _area4.setup(2153, 1, 1, OBJECT_TRANSLATOR); _area4._pt = Common::Point(237, 77); + _sitFl = false; } void Scene2100::postInit(SceneObjectList *OwnerList) { @@ -1688,7 +1689,7 @@ void Scene2100::postInit(SceneObjectList *OwnerList) { g_globals->_player._moveDiff.x = 4; g_globals->_player.changeZoom(-1); g_globals->_player.disableControl(); - _sitFl = 0; + _sitFl = false; switch (g_globals->_sceneManager._previousScene) { case 2120: @@ -1824,7 +1825,7 @@ void Scene2100::postInit(SceneObjectList *OwnerList) { g_globals->_player.fixPriority(152); g_globals->_player.setStrip(2); - _sitFl = 1; + _sitFl = true; _object4.postInit(); _object4.setVisage(2102); @@ -1858,7 +1859,7 @@ void Scene2100::postInit(SceneObjectList *OwnerList) { g_globals->_player.fixPriority(152); g_globals->_player.setStrip(2); - _sitFl = 1; + _sitFl = true; setAction(&_action16); } break; @@ -1932,12 +1933,12 @@ void Scene2100::stripCallback(int v) { void Scene2100::signal() { switch (_sceneMode) { case 2101: - _sitFl = 1; + _sitFl = true; g_globals->_player._uiEnabled = true; g_globals->_events.setCursor(CURSOR_USE); break; case 2102: - _sitFl = 0; + _sitFl = false; g_globals->_player.enableControl(); break; case 2103: @@ -5789,6 +5790,7 @@ Scene2320::Scene2320() : _area3._pt = Common::Point(200, 75); _area4.setup(2153, 1, 1, 10); _area4._pt = Common::Point(237, 77); + _hotspotPtr = nullptr; } void Scene2320::postInit(SceneObjectList *OwnerList) { diff --git a/engines/tsage/ringworld/ringworld_scenes3.h b/engines/tsage/ringworld/ringworld_scenes3.h index a371f800b9..752b6acd48 100644 --- a/engines/tsage/ringworld/ringworld_scenes3.h +++ b/engines/tsage/ringworld/ringworld_scenes3.h @@ -283,7 +283,7 @@ public: Action15 _action15; Action16 _action16; Action17 _action17; - int _sitFl; + bool _sitFl; SceneArea _area1, _area2, _area3, _area4; Scene2100(); diff --git a/engines/voyeur/events.cpp b/engines/voyeur/events.cpp index 7ce7351e65..320c92283c 100644 --- a/engines/voyeur/events.cpp +++ b/engines/voyeur/events.cpp @@ -403,7 +403,7 @@ void EventsManager::vDoCycleInt() { int palIndex = READ_LE_UINT16(pSrc); pPal[palIndex * 3] = pSrc[3]; pPal[palIndex * 3 + 1] = pSrc[4]; - pPal[palIndex * 3 + 1] = pSrc[5]; + pPal[palIndex * 3 + 2] = pSrc[5]; pSrc += 6; if ((int16)READ_LE_UINT16(pSrc) >= 0) { diff --git a/engines/voyeur/files_threads.cpp b/engines/voyeur/files_threads.cpp index 0615c67ba0..53eb5ce3c5 100644 --- a/engines/voyeur/files_threads.cpp +++ b/engines/voyeur/files_threads.cpp @@ -1082,6 +1082,7 @@ int ThreadResource::doApt() { break; case 2: _vm->_voy->_aptLoadMode = 142; + break; case 5: _vm->_voy->_aptLoadMode = 141; break; diff --git a/engines/zvision/file/lzss_read_stream.cpp b/engines/zvision/file/lzss_read_stream.cpp index 6f27eaa765..ca10af7d72 100644 --- a/engines/zvision/file/lzss_read_stream.cpp +++ b/engines/zvision/file/lzss_read_stream.cpp @@ -31,8 +31,9 @@ LzssReadStream::LzssReadStream(Common::SeekableReadStream *source) // It's convention to set the starting cursor position to blockSize - 16 _windowCursor(0x0FEE), _eosFlag(false) { - // Clear the window to null - memset(_window, 0, BLOCK_SIZE); + // All values up to _windowCursor inits by 0x20 + memset(_window, 0x20, _windowCursor); + memset(_window + _windowCursor, 0, BLOCK_SIZE - _windowCursor); } uint32 LzssReadStream::decompressBytes(byte *destination, uint32 numberOfBytes) { diff --git a/engines/zvision/scripting/actions.cpp b/engines/zvision/scripting/actions.cpp index 758158817e..5238561149 100644 --- a/engines/zvision/scripting/actions.cpp +++ b/engines/zvision/scripting/actions.cpp @@ -79,8 +79,7 @@ ActionAssign::ActionAssign(ZVision *engine, int32 slotkey, const Common::String } ActionAssign::~ActionAssign() { - if (_value) - delete _value; + delete _value; } bool ActionAssign::execute() { @@ -103,8 +102,8 @@ ActionAttenuate::ActionAttenuate(ZVision *engine, int32 slotkey, const Common::S bool ActionAttenuate::execute() { ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_key); if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) { - MusicNode *mus = (MusicNode *)fx; - mus->setVolume(255 - (abs(_attenuation) >> 7)); + MusicNodeBASE *mus = (MusicNodeBASE *)fx; + mus->setVolume(255 * (10000 - abs(_attenuation)) / 10000 ); } return true; } @@ -154,7 +153,7 @@ bool ActionCrossfade::execute() { if (_keyOne) { ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_keyOne); if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) { - MusicNode *mus = (MusicNode *)fx; + MusicNodeBASE *mus = (MusicNodeBASE *)fx; if (_oneStartVolume >= 0) mus->setVolume((_oneStartVolume * 255) / 100); @@ -165,7 +164,7 @@ bool ActionCrossfade::execute() { if (_keyTwo) { ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_keyTwo); if (fx && fx->getType() == ScriptingEffect::SCRIPTING_EFFECT_AUDIO) { - MusicNode *mus = (MusicNode *)fx; + MusicNodeBASE *mus = (MusicNodeBASE *)fx; if (_twoStartVolume >= 0) mus->setVolume((_twoStartVolume * 255) / 100); @@ -445,16 +444,18 @@ bool ActionMenuBarEnable::execute() { ActionMusic::ActionMusic(ZVision *engine, int32 slotkey, const Common::String &line, bool global) : ResultAction(engine, slotkey), - _volume(255), _note(0), _prog(0), _universe(global) { uint type = 0; char fileNameBuffer[25]; uint loop = 0; - uint volume = 255; + char volumeBuffer[15]; - sscanf(line.c_str(), "%u %24s %u %u", &type, fileNameBuffer, &loop, &volume); + // Volume is optional. If it doesn't appear, assume full volume + strcpy(volumeBuffer, "100"); + + sscanf(line.c_str(), "%u %24s %u %14s", &type, fileNameBuffer, &loop, volumeBuffer); // Type 4 actions are MIDI commands, not files. These are only used by // Zork: Nemesis, for the flute and piano puzzles (tj4e and ve6f, as well @@ -463,26 +464,28 @@ ActionMusic::ActionMusic(ZVision *engine, int32 slotkey, const Common::String &l _midi = true; int note; int prog; - sscanf(line.c_str(), "%u %d %d %u", &type, &prog, ¬e, &volume); - _volume = volume; + sscanf(line.c_str(), "%u %d %d %14s", &type, &prog, ¬e, volumeBuffer); + _volume = new ValueSlot(_engine->getScriptManager(), volumeBuffer); _note = note; _prog = prog; } else { _midi = false; _fileName = Common::String(fileNameBuffer); _loop = loop == 1 ? true : false; - - // Volume is optional. If it doesn't appear, assume full volume - if (volume != 255) { - // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255] - _volume = volume * 255 / 100; + if (volumeBuffer[0] != '[' && atoi(volumeBuffer) > 100) { + // I thought I saw a case like this in Zork Nemesis, so + // let's guard against it. + warning("ActionMusic: Adjusting volume for %s from %s to 100", _fileName.c_str(), volumeBuffer); + strcpy(volumeBuffer, "100"); } + _volume = new ValueSlot(engine->getScriptManager(), volumeBuffer); } } ActionMusic::~ActionMusic() { if (!_universe) _engine->getScriptManager()->killSideFx(_slotKey); + delete _volume; } bool ActionMusic::execute() { @@ -491,13 +494,16 @@ bool ActionMusic::execute() { _engine->getScriptManager()->setStateValue(_slotKey, 2); } + uint volume = _volume->getValue(); + if (_midi) { - _engine->getScriptManager()->addSideFX(new MusicMidiNode(_engine, _slotKey, _prog, _note, _volume)); + _engine->getScriptManager()->addSideFX(new MusicMidiNode(_engine, _slotKey, _prog, _note, volume)); } else { if (!_engine->getSearchManager()->hasFile(_fileName)) return true; - _engine->getScriptManager()->addSideFX(new MusicNode(_engine, _slotKey, _fileName, _loop, _volume)); + // Volume in the script files is mapped to [0, 100], but the ScummVM mixer uses [0, 255] + _engine->getScriptManager()->addSideFX(new MusicNode(_engine, _slotKey, _fileName, _loop, volume * 255 / 100)); } return true; @@ -797,8 +803,7 @@ ActionRandom::ActionRandom(ZVision *engine, int32 slotkey, const Common::String } ActionRandom::~ActionRandom() { - if (_max) - delete _max; + delete _max; } bool ActionRandom::execute() { @@ -1037,8 +1042,7 @@ ActionTimer::ActionTimer(ZVision *engine, int32 slotkey, const Common::String &l } ActionTimer::~ActionTimer() { - if (_time) - delete _time; + delete _time; _engine->getScriptManager()->killSideFx(_slotKey); } diff --git a/engines/zvision/scripting/actions.h b/engines/zvision/scripting/actions.h index 8d43309b74..94c2d041fc 100644 --- a/engines/zvision/scripting/actions.h +++ b/engines/zvision/scripting/actions.h @@ -224,7 +224,7 @@ public: private: Common::String _fileName; bool _loop; - byte _volume; + ValueSlot *_volume; bool _universe; bool _midi; int8 _note; diff --git a/engines/zvision/scripting/effects/music_effect.cpp b/engines/zvision/scripting/effects/music_effect.cpp index 102f330305..ee2232d962 100644 --- a/engines/zvision/scripting/effects/music_effect.cpp +++ b/engines/zvision/scripting/effects/music_effect.cpp @@ -36,16 +36,33 @@ namespace ZVision { -MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, int8 volume) +static const uint8 dbMapLinear[256] = +{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, +2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, +4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, +8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, +14, 15, 15, 16, 16, 17, 18, 18, 19, 20, 21, 21, 22, 23, 24, 25, +26, 27, 28, 29, 30, 31, 32, 33, 34, 36, 37, 38, 40, 41, 43, 45, +46, 48, 50, 52, 53, 55, 57, 60, 62, 64, 67, 69, 72, 74, 77, 80, +83, 86, 89, 92, 96, 99, 103, 107, 111, 115, 119, 123, 128, 133, 137, 143, +148, 153, 159, 165, 171, 177, 184, 191, 198, 205, 212, 220, 228, 237, 245, 255}; + +MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool loop, uint8 volume) : MusicNodeBASE(engine, key, SCRIPTING_EFFECT_AUDIO) { _loop = loop; _volume = volume; + _deltaVolume = 0; + _balance = 0; _crossfade = false; _crossfadeTarget = 0; _crossfadeTime = 0; - _attenuate = 0; - _pantrack = false; - _pantrackPosition = 0; _sub = NULL; _stereo = false; _loaded = false; @@ -66,9 +83,9 @@ MusicNode::MusicNode(ZVision *engine, uint32 key, Common::String &filename, bool if (_loop) { Audio::LoopingAudioStream *loopingAudioStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES); - _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, _volume); + _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, loopingAudioStream, -1, dbMapLinear[_volume]); } else { - _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, _volume); + _engine->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, audioStream, -1, dbMapLinear[_volume]); } if (_key != StateKey_NotSet) @@ -97,17 +114,14 @@ MusicNode::~MusicNode() { debug(1, "MusicNode: %d destroyed\n", _key); } -void MusicNode::setPanTrack(int16 pos) { - if (!_stereo) { - _pantrack = true; - _pantrackPosition = pos; - setVolume(_volume); - } +void MusicNode::setDeltaVolume(uint8 volume) { + _deltaVolume = volume; + setVolume(_volume); } -void MusicNode::unsetPanTrack() { - _pantrack = false; - setVolume(_volume); +void MusicNode::setBalance(int8 balance) { + _balance = balance; + _engine->_mixer->setChannelBalance(_handle, _balance); } void MusicNode::setFade(int32 time, uint8 target) { @@ -134,7 +148,7 @@ bool MusicNode::process(uint32 deltaTimeInMillis) { } } - if (_pantrack || _volume != _newvol) + if (_volume != _newvol) setVolume(_newvol); if (_sub && _engine->getScriptManager()->getStateValue(StateKey_Subtitles) == 1) @@ -146,55 +160,86 @@ bool MusicNode::process(uint32 deltaTimeInMillis) { void MusicNode::setVolume(uint8 newVolume) { if (!_loaded) return; - if (_pantrack) { - int curX = _engine->getScriptManager()->getStateValue(StateKey_ViewPos); - curX -= _pantrackPosition; - int32 _width = _engine->getRenderManager()->getBkgSize().x; - if (curX < (-_width) / 2) - curX += _width; - else if (curX >= _width / 2) - curX -= _width; - - float norm = (float)curX / ((float)_width / 2.0); - float lvl = fabs(norm); - if (lvl > 0.5) - lvl = (lvl - 0.5) * 1.7; - else - lvl = 1.0; - float bal = sin(-norm * 3.1415926) * 127.0; + _volume = newVolume; - if (_engine->_mixer->isSoundHandleActive(_handle)) { - _engine->_mixer->setChannelBalance(_handle, bal); - _engine->_mixer->setChannelVolume(_handle, newVolume * lvl); - } - } else { - if (_engine->_mixer->isSoundHandleActive(_handle)) { - _engine->_mixer->setChannelBalance(_handle, 0); - _engine->_mixer->setChannelVolume(_handle, newVolume); - } - } + if (_deltaVolume >= _volume) + _engine->_mixer->setChannelVolume(_handle, 0); + else + _engine->_mixer->setChannelVolume(_handle, dbMapLinear[_volume - _deltaVolume]); +} - _volume = newVolume; +uint8 MusicNode::getVolume() { + return _volume; } PanTrackNode::PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos) : ScriptingEffect(engine, key, SCRIPTING_EFFECT_PANTRACK) { _slot = slot; + _position = pos; - ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(slot); - if (fx && fx->getType() == SCRIPTING_EFFECT_AUDIO) { - MusicNodeBASE *mus = (MusicNodeBASE *)fx; - mus->setPanTrack(pos); - } + // Try to set pan value for music node immediately + process(0); } PanTrackNode::~PanTrackNode() { - ScriptingEffect *fx = _engine->getScriptManager()->getSideFX(_slot); +} + +bool PanTrackNode::process(uint32 deltaTimeInMillis) { + ScriptManager * scriptManager = _engine->getScriptManager(); + ScriptingEffect *fx = scriptManager->getSideFX(_slot); if (fx && fx->getType() == SCRIPTING_EFFECT_AUDIO) { MusicNodeBASE *mus = (MusicNodeBASE *)fx; - mus->unsetPanTrack(); + + int curPos = scriptManager->getStateValue(StateKey_ViewPos); + int16 _width = _engine->getRenderManager()->getBkgSize().x; + int16 _halfWidth = _width / 2; + int16 _quarterWidth = _width / 4; + + int tmp = 0; + if (curPos <= _position) + tmp = _position - curPos; + else + tmp = _position - curPos + _width; + + int balance = 0; + + if (tmp > _halfWidth) + tmp -= _width; + + if (tmp > _quarterWidth) { + balance = 1; + tmp = _halfWidth - tmp; + } else if (tmp < -_quarterWidth) { + balance = -1; + tmp = -_halfWidth - tmp; + } + + // Originally it's value -90...90 but we use -127...127 and therefore 360 replaced by 508 + mus->setBalance( (508 * tmp) / _width ); + + tmp = (360 * tmp) / _width; + + int deltaVol = balance; + + // This value sets how fast volume goes off than sound source back of you + // By this value we can hack some "bugs" have place in originall game engine like beat sound in ZGI-dc10 + int volumeCorrection = 2; + + if (_engine->getGameId() == GID_GRANDINQUISITOR) { + Location loc = scriptManager->getCurrentLocation(); + if (loc.world == 'd' && loc.room == 'c' && loc.node == '1' && loc.view == '0') + volumeCorrection = 5; + } + + if (deltaVol != 0) + deltaVol = (mus->getVolume() * volumeCorrection) * (90 - tmp * balance) / 90; + if (deltaVol > 255) + deltaVol = 255; + + mus->setDeltaVolume(deltaVol); } + return false; } MusicMidiNode::MusicMidiNode(ZVision *engine, uint32 key, int8 program, int8 note, int8 volume) @@ -225,10 +270,10 @@ MusicMidiNode::~MusicMidiNode() { _engine->getScriptManager()->setStateValue(_key, 2); } -void MusicMidiNode::setPanTrack(int16 pos) { +void MusicMidiNode::setDeltaVolume(uint8 volume) { } -void MusicMidiNode::unsetPanTrack() { +void MusicMidiNode::setBalance(int8 balance) { } void MusicMidiNode::setFade(int32 time, uint8 target) { @@ -245,4 +290,8 @@ void MusicMidiNode::setVolume(uint8 newVolume) { _volume = newVolume; } +uint8 MusicMidiNode::getVolume() { + return _volume; +} + } // End of namespace ZVision diff --git a/engines/zvision/scripting/effects/music_effect.h b/engines/zvision/scripting/effects/music_effect.h index 31d538f668..7657be8e09 100644 --- a/engines/zvision/scripting/effects/music_effect.h +++ b/engines/zvision/scripting/effects/music_effect.h @@ -48,16 +48,16 @@ public: virtual bool process(uint32 deltaTimeInMillis) = 0; virtual void setVolume(uint8 volume) = 0; - - virtual void setPanTrack(int16 pos) = 0; - virtual void unsetPanTrack() = 0; + virtual uint8 getVolume() = 0; + virtual void setDeltaVolume(uint8 volume) = 0; + virtual void setBalance(int8 balance) = 0; virtual void setFade(int32 time, uint8 target) = 0; }; class MusicNode : public MusicNodeBASE { public: - MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, int8 volume); + MusicNode(ZVision *engine, uint32 key, Common::String &file, bool loop, uint8 volume); ~MusicNode(); /** @@ -70,17 +70,16 @@ public: bool process(uint32 deltaTimeInMillis); void setVolume(uint8 volume); - - void setPanTrack(int16 pos); - void unsetPanTrack(); + uint8 getVolume(); + void setDeltaVolume(uint8 volume); + void setBalance(int8 balance); void setFade(int32 time, uint8 target); private: - bool _pantrack; - int32 _pantrackPosition; - int32 _attenuate; uint8 _volume; + uint8 _deltaVolume; + int8 _balance; bool _loop; bool _crossfade; uint8 _crossfadeTarget; @@ -107,9 +106,9 @@ public: bool process(uint32 deltaTimeInMillis); void setVolume(uint8 volume); - - void setPanTrack(int16 pos); - void unsetPanTrack(); + uint8 getVolume(); + void setDeltaVolume(uint8 volume); + void setBalance(int8 balance); void setFade(int32 time, uint8 target); @@ -126,8 +125,11 @@ public: PanTrackNode(ZVision *engine, uint32 key, uint32 slot, int16 pos); ~PanTrackNode(); + bool process(uint32 deltaTimeInMillis); + private: uint32 _slot; + int16 _position; }; } // End of namespace ZVision diff --git a/icons/scummvm.info b/icons/scummvm.info Binary files differindex e30a7129ef..f603627122 100644 --- a/icons/scummvm.info +++ b/icons/scummvm.info diff --git a/icons/scummvm_drawer.info b/icons/scummvm_drawer.info Binary files differindex 26f6a8633d..03b62536a2 100644 --- a/icons/scummvm_drawer.info +++ b/icons/scummvm_drawer.info |