aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/engine/kyra_v1.cpp13
-rw-r--r--engines/kyra/graphics/screen.cpp42
-rw-r--r--engines/kyra/gui/gui_lok.cpp2
-rw-r--r--engines/kyra/script/script_lok.cpp13
-rw-r--r--engines/kyra/script/script_v1.cpp2
-rw-r--r--engines/kyra/sound/drivers/mlalf98.cpp4
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;