diff options
Diffstat (limited to 'engines/kyra')
-rw-r--r-- | engines/kyra/engine/kyra_v1.cpp | 13 | ||||
-rw-r--r-- | engines/kyra/graphics/screen.cpp | 42 | ||||
-rw-r--r-- | engines/kyra/gui/gui_lok.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/script/script_lok.cpp | 13 | ||||
-rw-r--r-- | engines/kyra/script/script_v1.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/sound/drivers/mlalf98.cpp | 4 |
6 files changed, 67 insertions, 9 deletions
diff --git a/engines/kyra/engine/kyra_v1.cpp b/engines/kyra/engine/kyra_v1.cpp index fc43919b57..c708756b19 100644 --- a/engines/kyra/engine/kyra_v1.cpp +++ b/engines/kyra/engine/kyra_v1.cpp @@ -235,6 +235,19 @@ void KyraEngine_v1::setMousePos(int x, int y) { y <<= 1; } _system->warpMouse(x, y); + + // Feed the event manager an artficial mouse move event, since warpMouse() won't generate one. + // From the warpMouse comments I gather that this behavior is intentional due to requirements of + // the SCUMM engine. In KYRA we need to get the same coordinates from _eventMan->getMousePos() + // that we send via warpMouse(). We have script situations in Kyra (like the Alchemists' crystals + // scene) where a new mouse cursor position is set and then immediately read. This function would + // then get wrong coordinates. + Common::Event event; + event.type = Common::EVENT_MOUSEMOVE; + event.mouse.x = x; + event.mouse.y = y; + _eventMan->pushEvent(event); + updateInput(); } int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag) { diff --git a/engines/kyra/graphics/screen.cpp b/engines/kyra/graphics/screen.cpp index 148f2d8f37..bbcada5991 100644 --- a/engines/kyra/graphics/screen.cpp +++ b/engines/kyra/graphics/screen.cpp @@ -3170,13 +3170,43 @@ void Screen::rectClip(int &x, int &y, int w, int h) { } void Screen::shakeScreen(int times) { + static const int8 _shakeParaPC[] = { 32, 0, -4, 32, 0, 0 }; + static const int8 _shakeParaFMTOWNS[] = { 32, 0, -4, 48, 0, 4, 32, -4, 0, 32, 4, 0, 32, 0, 0 }; + + const int8 *data = _shakeParaPC; + int steps = ARRAYSIZE(_shakeParaPC) / 3; + + // The FM-TOWNS version has a slightly better shake animation + // TODO: check PC-98 version + if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { + data = _shakeParaFMTOWNS; + steps = ARRAYSIZE(_shakeParaFMTOWNS) / 3; + } + + Common::Event event; + while (times--) { - // seems to be 1 line (320 pixels) offset in the original - // 4 looks more like dosbox though, maybe check this again - _system->setShakePos(0, 4); - _system->updateScreen(); - _system->setShakePos(0, 0); - _system->updateScreen(); + for (int i = 0; i < steps; ++i) { + // The original PC version did not need an artificial delay, but we do or the shake will be + // too fast to be actually seen. + uint32 end = _system->getMillis() + data[0]; + _system->setShakePos(data[1], data[2]); + + for (uint32 now = _system->getMillis(); now < end; ) { + // Update the event manager to keep smooth mouse pointer movement. + while (_vm->getEventManager()->pollEvent(event)) { + if (event.type == Common::EVENT_KEYDOWN) { + // This is really the only thing that should be handled. + if (event.kbd.keycode == Common::KEYCODE_q && event.kbd.hasFlags(Common::KBD_CTRL)) + _vm->quitGame(); + } + } + _system->updateScreen(); + now = _system->getMillis(); + _system->delayMillis(MIN<uint>(end - now, 10)); + } + data += 3; + } } } diff --git a/engines/kyra/gui/gui_lok.cpp b/engines/kyra/gui/gui_lok.cpp index 96a10f0bab..b2971757ce 100644 --- a/engines/kyra/gui/gui_lok.cpp +++ b/engines/kyra/gui/gui_lok.cpp @@ -209,7 +209,7 @@ void GUI_LoK::createScreenThumbnail(Graphics::Surface &dst) { if (_screen->isInterfacePaletteEnabled()) { for (int y = 0; y < 64; ++y) { for (int x = 0; x < 320; ++x) { - screen[(y + 136) * Screen::SCREEN_W + x] += 32; + screen[(y + 136) * Screen::SCREEN_W + x] |= 0x20; } } } diff --git a/engines/kyra/script/script_lok.cpp b/engines/kyra/script/script_lok.cpp index 325ee67c9e..2efa159f0b 100644 --- a/engines/kyra/script/script_lok.cpp +++ b/engines/kyra/script/script_lok.cpp @@ -362,6 +362,19 @@ int KyraEngine_LoK::o1_forceBrandonToNormal(EMCState *script) { int KyraEngine_LoK::o1_poisonDeathNow(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_poisonDeathNow(%p) ()", (const void *)script); seq_poisonDeathNow(1); + + // WORKAROUND for the poison animation after drinking the green potion + // that can be made at the alchemists' crystals. + // The next animator update from inside delay() after completing the + // poison animation would cause invalid memory access (tryin to draw the + // already freed special anim shape 142). + // I can definitely confirm that for the FM-TOWNS version. I don't know + // about the DOS-CD version. Maybe this has been fixed there somehow. + // I simply repeat the same steps that are done after the potion animation + // when bitten by the snake (scene_lok.cpp, lines 964, 966). + _characterList[0].currentAnimFrame = 7; + _animator->animRefreshNPC(0); + return 0; } diff --git a/engines/kyra/script/script_v1.cpp b/engines/kyra/script/script_v1.cpp index 2fbd2f22f4..356460dae0 100644 --- a/engines/kyra/script/script_v1.cpp +++ b/engines/kyra/script/script_v1.cpp @@ -65,7 +65,7 @@ int KyraEngine_v1::o1_showMouse(EMCState *script) { int KyraEngine_v1::o1_setMousePos(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - _system->warpMouse(stackPos(0), stackPos(1)); + setMousePos(stackPos(0), stackPos(1)); return 0; } diff --git a/engines/kyra/sound/drivers/mlalf98.cpp b/engines/kyra/sound/drivers/mlalf98.cpp index b2cb6d909c..1474589032 100644 --- a/engines/kyra/sound/drivers/mlalf98.cpp +++ b/engines/kyra/sound/drivers/mlalf98.cpp @@ -436,7 +436,7 @@ bool SoundChannel::_globalBlock = false; SoundChannel::SoundChannel(PC98AudioCore *pc98a, int part, int regOffset, int type) : _pc98a(pc98a), _regOffset(regOffset), _part(part), _ticksLeft(0), _program(0), _volume(0), _algorithm(0), _envRR(0), _vbrDelay(0), _vbrRem(0), _vbrRate(0), _vbrTicker(0), _vbrStepSize(0), _vbrModifier(0), _vbrDepth(0), _vbrState(0), _duration(0), _frequency(0), _flags2(0), _note(0), _flags(0), -_transpose(0), _envCurLvl(0), _fadeVolModifier(0), _fadeProgress(0), _fadeTicker(0), _trmCarrier(1), +_transpose(0), _envCurLvl(0), _fadeVolModifier(0), _fadeProgress(0), _fadeTicker(16), _trmCarrier(1), _dataPtr(0), _dataEnd(0), _loopStartPtr(0), _instrBuffer(0), _backupData(0), _mute(false), _type(type) { _subOpcodes[0].reserve(8); _subOpcodes[1].reserve(8); @@ -510,6 +510,8 @@ void SoundChannel::updateFadeOut() { if (--_fadeTicker) return; + _fadeTicker = 16; + if (!_fadeProgress) return; |