[Scummvm-git-logs] scummvm master -> 6c300519b15f3bdbbca6ecf149d70422f0ac494d
antoniou79
noreply at scummvm.org
Sun Apr 3 20:01:47 UTC 2022
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
b48c998d72 BLADERUNNER: Increase width of scrollable area in help KIA tab
6994d79e59 BLADERUNNER: Filter Delete key press if no selected saved game
6c300519b1 BLADERUNNER: Use keymapper with proper events for the game
Commit: b48c998d723cd7b90b4ad95b7e1f9a0035705cdf
https://github.com/scummvm/scummvm/commit/b48c998d723cd7b90b4ad95b7e1f9a0035705cdf
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-04-03T22:51:33+03:00
Commit Message:
BLADERUNNER: Increase width of scrollable area in help KIA tab
Changed paths:
engines/bladerunner/ui/kia_section_help.cpp
engines/bladerunner/ui/kia_section_load.cpp
engines/bladerunner/ui/kia_section_save.cpp
diff --git a/engines/bladerunner/ui/kia_section_help.cpp b/engines/bladerunner/ui/kia_section_help.cpp
index 170e5590faa..e9fdc9b3d8b 100644
--- a/engines/bladerunner/ui/kia_section_help.cpp
+++ b/engines/bladerunner/ui/kia_section_help.cpp
@@ -32,8 +32,13 @@ namespace BladeRunner {
KIASectionHelp::KIASectionHelp(BladeRunnerEngine *vm) : KIASectionBase(vm) {
_uiContainer = new UIContainer(_vm);
+#if BLADERUNNER_ORIGINAL_BUGS
_scrollBox = new UIScrollBox(_vm, nullptr, this, 1024, 0, false, Common::Rect(135, 145, 461, 385), Common::Rect(506, 160, 506, 350));
-
+#else
+ // Increase width of scollable area, to eliminate the (significant) area to the right,
+ // before the scroll bar, where scrolling would not work.
+ _scrollBox = new UIScrollBox(_vm, nullptr, this, 1024, 0, false, Common::Rect(135, 145, 502, 385), Common::Rect(506, 160, 506, 350));
+#endif
_uiContainer->add(_scrollBox);
}
diff --git a/engines/bladerunner/ui/kia_section_load.cpp b/engines/bladerunner/ui/kia_section_load.cpp
index d3000fd9d4c..a42fe075500 100644
--- a/engines/bladerunner/ui/kia_section_load.cpp
+++ b/engines/bladerunner/ui/kia_section_load.cpp
@@ -40,6 +40,10 @@ namespace BladeRunner {
KIASectionLoad::KIASectionLoad(BladeRunnerEngine *vm) : KIASectionBase(vm) {
_uiContainer = new UIContainer(_vm);
+ // There is a small area to the right of the save games list, before the scroll bar,
+ // where scrolling does not work.
+ // However, unlike kia_section_help, if we increase the width of the scrollable area here,
+ // we would noticeably mess with the centering of the title label and the saved game names in the list.
_scrollBox = new UIScrollBox(_vm, scrollBoxCallback, this, 1025, 0, true, Common::Rect(155, 158, 461, 346), Common::Rect(506, 160, 506, 350));
_uiContainer->add(_scrollBox);
diff --git a/engines/bladerunner/ui/kia_section_save.cpp b/engines/bladerunner/ui/kia_section_save.cpp
index 79471507060..168a9c26d34 100644
--- a/engines/bladerunner/ui/kia_section_save.cpp
+++ b/engines/bladerunner/ui/kia_section_save.cpp
@@ -45,6 +45,10 @@ namespace BladeRunner {
KIASectionSave::KIASectionSave(BladeRunnerEngine *vm) : KIASectionBase(vm) {
_uiContainer = new UIContainer(_vm);
+ // There is a small area to the right of the save games list, before the scroll bar,
+ // where scrolling does not work.
+ // However, unlike kia_section_help, if we increase the width of the scrollable area here,
+ // we would noticeably mess with the centering of the title label and the saved game names in the list.
_scrollBox = new UIScrollBox(_vm, scrollBoxCallback, this, 1024, 0, true, Common::Rect(155, 158, 461, 346), Common::Rect(506, 160, 506, 350));
_uiContainer->add(_scrollBox);
Commit: 6994d79e591439090ef3db7cf109a899c1093707
https://github.com/scummvm/scummvm/commit/6994d79e591439090ef3db7cf109a899c1093707
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-04-03T22:51:33+03:00
Commit Message:
BLADERUNNER: Filter Delete key press if no selected saved game
Also introduce a getValidChar() method to improve modularity and readability
Changed paths:
engines/bladerunner/ui/ui_input_box.cpp
engines/bladerunner/ui/ui_input_box.h
diff --git a/engines/bladerunner/ui/ui_input_box.cpp b/engines/bladerunner/ui/ui_input_box.cpp
index 3dbf9f5ae3b..62214804918 100644
--- a/engines/bladerunner/ui/ui_input_box.cpp
+++ b/engines/bladerunner/ui/ui_input_box.cpp
@@ -87,41 +87,52 @@ void UIInputBox::hide() {
}
void UIInputBox::handleKeyDown(const Common::KeyState &kbd) {
- if (kbd.ascii != 0) {
- // The above check for kbd.ascii > 0 gets rid of the tentative warning:
+ if (_isVisible) {
+ uint8 kc = 0;
+ if (getValidChar(kbd.ascii, kc) && _text.size() < _maxLength) {
+ _text += kc;
+ } else if (kbd.keycode == Common::KEYCODE_BACKSPACE) {
+ _text.deleteLastChar();
+ } else if ((kbd.keycode == Common::KEYCODE_RETURN || kbd.keycode == Common::KEYCODE_KP_ENTER)
+ && !_text.empty()) {
+ if (_valueChangedCallback) {
+ _valueChangedCallback(_callbackData, this);
+ }
+ }
+ }
+}
+
+bool UIInputBox::getValidChar(const uint16 &kAscii16bit, uint8 &targetAscii) {
+ if (kAscii16bit != 0) {
+ // The above check for kAscii16bit > 0 gets rid of the tentative warning:
// "Adding \0 to String. This is permitted, but can have unwanted consequences."
// which was triggered by the .encode(Common::kDos850) operation below.
//
// The values that the KeyState::ascii field receives from the SDL backend are actually ISO 8859-1 encoded. They need to be
// reencoded to DOS so as to match the game font encoding (although we currently use UIInputBox::charIsValid() to block most
// extra characters, so it might not make much of a difference).
- uint8 kc = (uint8)(Common::U32String(Common::String::format("%c", kbd.ascii), Common::kISO8859_1).encode(Common::kDos850).firstChar());
- if (_isVisible) {
- if (charIsValid(kc) && _text.size() < _maxLength) {
- _text += kc;
- } else if (kbd.keycode == Common::KEYCODE_BACKSPACE) {
- _text.deleteLastChar();
- } else if ((kbd.keycode == Common::KEYCODE_RETURN || kbd.keycode == Common::KEYCODE_KP_ENTER)
- && !_text.empty()) {
- if (_valueChangedCallback) {
- _valueChangedCallback(_callbackData, this);
- }
- }
- }
+ targetAscii = (uint8)(Common::U32String(Common::String::format("%c", kAscii16bit), Common::kISO8859_1).encode(Common::kDos850).firstChar());
+ return charIsValid(targetAscii);
}
+ return false;
}
-bool UIInputBox::charIsValid(uint8 kc) {
+bool UIInputBox::charIsValid(const uint8 &kc) {
// The in-game font for text input is KIA6PT which follows IBM PC Code page 437 (CCSID 437)
// This code page is identical to Code page 850 for the first 128 codes.
// This method is:
- // 1) filtering out characters not allowed in a DOS filename.
+ // 1) Filtering out characters not allowed in a DOS filename.
// Note, however, that it does allow ',', '.', ';', '=', '[' and ']'
// TODO Is that a bug?
- // 2) allowing codes for glyphs that exist in KIA6PT up to code 0xA8 (glyph '¿')
+ // 2) Allowing codes for glyphs that exist in KIA6PT up to code 0xA8 (glyph '¿')
// and also the extra codes for 0xAD (glyph '¡') and 0xE1 (glyph 'Ã')
// (in order for these extra extended ASCII codes to be included,
// the comparisons in the return clause should be between uint values).
+ // 3) Additionally disallows the '\x7F' character which caused a glyph 'â' to be printed
+ // when the Delete key was pressed with no saved game selected,
+ // ie. the highlighted line on the KIA save screen is "<< NEW SLOT >>".
+ // The original does not show this glyph either but seems to filter the key earlier (not in this method).
+ // It's more effective to completely block the glyph in this method, though.
return kc >= ' '
&& kc != '<'
&& kc != '>'
@@ -132,6 +143,7 @@ bool UIInputBox::charIsValid(uint8 kc) {
&& kc != '|'
&& kc != '?'
&& kc != '*'
+ && kc != (uint8)'\x7F'
&& (kc <= (uint8)'\xA8' || kc == (uint8)'\xAD' || kc == (uint8)'\xE1');
}
diff --git a/engines/bladerunner/ui/ui_input_box.h b/engines/bladerunner/ui/ui_input_box.h
index a5ac570ca7c..fe705b5e669 100644
--- a/engines/bladerunner/ui/ui_input_box.h
+++ b/engines/bladerunner/ui/ui_input_box.h
@@ -57,7 +57,8 @@ public:
void handleKeyDown(const Common::KeyState &kbd) override;
private:
- bool charIsValid(uint8 kc);
+ bool getValidChar(const uint16 &kc16bit, uint8 &kc8bit);
+ bool charIsValid(const uint8 &kc16bit);
};
} // End of namespace BladeRunner
Commit: 6c300519b15f3bdbbca6ecf149d70422f0ac494d
https://github.com/scummvm/scummvm/commit/6c300519b15f3bdbbca6ecf149d70422f0ac494d
Author: antoniou79 (a.antoniou79 at gmail.com)
Date: 2022-04-03T22:51:33+03:00
Commit Message:
BLADERUNNER: Use keymapper with proper events for the game
Changed paths:
engines/bladerunner/POTFILES
engines/bladerunner/bladerunner.cpp
engines/bladerunner/bladerunner.h
engines/bladerunner/metaengine.cpp
engines/bladerunner/ui/kia.cpp
engines/bladerunner/ui/kia.h
engines/bladerunner/ui/kia_section_base.h
engines/bladerunner/ui/kia_section_save.cpp
engines/bladerunner/ui/kia_section_save.h
engines/bladerunner/ui/scores.cpp
engines/bladerunner/ui/scores.h
diff --git a/engines/bladerunner/POTFILES b/engines/bladerunner/POTFILES
index dbadaf46213..6aaf1dfa895 100644
--- a/engines/bladerunner/POTFILES
+++ b/engines/bladerunner/POTFILES
@@ -1,3 +1,4 @@
engines/bladerunner/bladerunner.cpp
engines/bladerunner/detection.cpp
engines/bladerunner/detection_tables.h
+engines/bladerunner/metaengine.cpp
diff --git a/engines/bladerunner/bladerunner.cpp b/engines/bladerunner/bladerunner.cpp
index 85de2fa1160..560aed08dc6 100644
--- a/engines/bladerunner/bladerunner.cpp
+++ b/engines/bladerunner/bladerunner.cpp
@@ -76,6 +76,9 @@
#include "bladerunner/waypoints.h"
#include "bladerunner/zbuffer.h"
+#include "backends/keymapper/action.h"
+#include "backends/keymapper/keymapper.h"
+
#include "common/array.h"
#include "common/config-manager.h"
#include "common/error.h"
@@ -95,6 +98,10 @@
namespace BladeRunner {
+const char *BladeRunnerEngine::kGameplayKeymapId = "bladerunner-gameplay";
+const char *BladeRunnerEngine::kKiaKeymapId = "bladerunner-kia";
+const char *BladeRunnerEngine::kCommonKeymapId = "bladerunner-common";
+
BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *desc)
: Engine(syst),
_rnd("bladerunner") {
@@ -233,6 +240,10 @@ BladeRunnerEngine::BladeRunnerEngine(OSystem *syst, const ADGameDescription *des
_currentKeyDown.keycode = Common::KEYCODE_INVALID;
_keyRepeatTimeLast = 0;
_keyRepeatTimeDelay = 0;
+
+ _activeCustomEvents->clear();
+ _customEventRepeatTimeLast = 0;
+ _customEventRepeatTimeDelay = 0;
}
BladeRunnerEngine::~BladeRunnerEngine() {
@@ -380,6 +391,21 @@ Common::Error BladeRunnerEngine::run() {
}
// end of additional code for gracefully handling end-game
+ if (getEventManager()->getKeymapper() != nullptr) {
+ if (getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kCommonKeymapId) != nullptr)
+ getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kCommonKeymapId)->setEnabled(true);
+
+ if (getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kGameplayKeymapId) != nullptr)
+ getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kGameplayKeymapId)->setEnabled(true);
+
+ if (getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kKiaKeymapId) != nullptr) {
+ // When disabling a keymap, make sure all their active events in the _activeCustomEvents array
+ // are cleared, because as they won't get an explicit "EVENT_CUSTOM_ENGINE_ACTION_END" event.
+ cleanupPendingRepeatingEvents(BladeRunnerEngine::kKiaKeymapId);
+ getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kKiaKeymapId)->setEnabled(false);
+ }
+ }
+
if (_validBootParam) {
// clear the flag, so that after a possible game gameOver / end-game
// it won't be true again; just to be safe and avoid potential side-effects
@@ -1262,18 +1288,46 @@ void BladeRunnerEngine::walkingReset() {
_isInsideScriptActor = false;
}
+bool BladeRunnerEngine::isAllowedRepeatedCustomEvent(const Common::Event &currevent) {
+ switch (currevent.type) {
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
+ switch ((BladeRunnerEngineMappableAction)currevent.customType) {
+ case kMpblActionCutsceneSkip:
+ // fall through
+ case kMpActionDialogueSkip:
+ // fall through
+ case kMpActionToggleKiaOptions:
+ return true;
+
+ default:
+ return false;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
// The original allowed a few keyboard keys to be repeated ("key spamming")
// namely, Esc, Return and Space during normal gameplay.
-// "Space" spamming results in McCoy quickly switching between combat mode and normal mode,
-// which is not very useful but it's the original's behavior.
-// Spamming Space, backspace, latin letter keys and symbols is allowed
-// in KIA mode, particularly in the Save Panel when writing the name for a save game.
+// "Spacebar" spamming would result in McCoy quickly switching between combat mode and normal mode,
+// which is not very useful -- by introducing the keymapper with custom action events this behavior is no longer replicated.
+// Spamming Space, backspace, latin letter keys and symbols is allowed in KIA mode,
+// particularly in the Save Panel when typing in the name for a save game.
// For simplicity, we allow everything after the 0x20 (space ascii code) up to 0xFF.
// The UIInputBox::charIsValid() will filter out any unsupported characters.
// F-keys are not repeated.
bool BladeRunnerEngine::isAllowedRepeatedKey(const Common::KeyState &currKeyState) {
- return currKeyState.keycode == Common::KEYCODE_ESCAPE
- || currKeyState.keycode == Common::KEYCODE_RETURN
+ // Return and KP_Enter keys are repeatable in KIA.
+ // This is noticable when choosing an already saved game to overwrite
+ // and holding down Enter would cause the confirmation dialogue to pop up
+ // and it would subsequently confirm it as well.
+ // TODO if we introduce a custom confirm action for KIA, then that action should be repeatable
+ // and KEYCODE_RETURN and KEYCODE_KP_ENTER should be removed from this clause;
+ // the action should be added to the switch cases in isAllowedRepeatedCustomEvent()
+ return currKeyState.keycode == Common::KEYCODE_RETURN
|| currKeyState.keycode == Common::KEYCODE_KP_ENTER
|| currKeyState.keycode == Common::KEYCODE_BACKSPACE
|| currKeyState.keycode == Common::KEYCODE_SPACE
@@ -1295,7 +1349,7 @@ void BladeRunnerEngine::handleEvents() {
// even in the case when no save games for the game exist. In such case the game is supposed
// to immediately play the intro video and subsequently start a new game of medium difficulty.
// It does not expect the player to enter KIA beforehand, which causes side-effects and unforeseen behavior.
- // Note: eventually we will support the option to launch into KIA in any case,
+ // NOTE Eventually, we will support the option to launch into KIA in any case,
// but not via the "hack" way that is fixed here.
if (_gameJustLaunched) {
_gameJustLaunched = false;
@@ -1306,12 +1360,109 @@ void BladeRunnerEngine::handleEvents() {
Common::EventManager *eventMan = _system->getEventManager();
while (eventMan->pollEvent(event)) {
switch (event.type) {
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
+ if (shouldDropRogueCustomEvent(event)) {
+ return;
+ }
+ switch ((BladeRunnerEngineMappableAction)event.customType) {
+ case kMpActionToggleCombat:
+ handleMouseAction(event.mouse.x, event.mouse.y, false, false);
+ break;
+
+ case kMpblActionCutsceneSkip:
+ // fall through
+ case kMpActionDialogueSkip:
+ // fall through
+ case kMpActionToggleKiaOptions:
+ // fall through
+ case kMpActionOpenKiaDatabase:
+ // fall through
+ case kMpActionOpenKIATabHelp:
+ // fall through
+ case kMpActionOpenKIATabSaveGame:
+ // fall through
+ case kMpActionOpenKIATabLoadGame:
+ // fall through
+ case kMpActionOpenKIATabCrimeSceneDatabase:
+ // fall through
+ case kMpActionOpenKIATabSuspectDatabase:
+ // fall through
+ case kMpActionOpenKIATabClueDatabase:
+ // fall through
+ case kMpActionOpenKIATabQuitGame:
+ handleCustomEventStop(event);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
+ if (shouldDropRogueCustomEvent(event)) {
+ return;
+ }
+ // Process the initial/actual custom event only here, filter out repeats
+ // TODO Does this actually filter repeats?
+ if (!event.kbdRepeat) {
+ switch ((BladeRunnerEngineMappableAction)event.customType) {
+ case kMpActionToggleCombat:
+ handleMouseAction(event.mouse.x, event.mouse.y, false, true);
+ break;
+
+ case kMpblActionCutsceneSkip:
+ // fall through
+ case kMpActionDialogueSkip:
+ // fall through
+ case kMpActionToggleKiaOptions:
+ // fall through
+ case kMpActionOpenKiaDatabase:
+ // fall through
+ case kMpActionOpenKIATabHelp:
+ // fall through
+ case kMpActionOpenKIATabSaveGame:
+ // fall through
+ case kMpActionOpenKIATabLoadGame:
+ // fall through
+ case kMpActionOpenKIATabCrimeSceneDatabase:
+ // fall through
+ case kMpActionOpenKIATabSuspectDatabase:
+ // fall through
+ case kMpActionOpenKIATabClueDatabase:
+ // fall through
+ case kMpActionOpenKIATabQuitGame:
+ if (isAllowedRepeatedCustomEvent(event)
+ && _activeCustomEvents->size() < kMaxCustomConcurrentRepeatableEvents) {
+ if (_activeCustomEvents->empty()) {
+ _customEventRepeatTimeLast = _time->currentSystem();
+ _customEventRepeatTimeDelay = kKeyRepeatInitialDelay;
+ }
+ _activeCustomEvents->push_back(event);
+ }
+ handleCustomEventStart(event);
+ break;
+
+ case kMpActionScrollUp:
+ handleMouseAction(event.mouse.x, event.mouse.y, false, false, -1);
+ break;
+
+ case kMpActionScrollDown:
+ handleMouseAction(event.mouse.x, event.mouse.y, false, false, 1);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+
case Common::EVENT_KEYUP:
handleKeyUp(event);
break;
case Common::EVENT_KEYDOWN:
- // Process the actual key press only and filter out repeats
+ // Process the initial/actual key press only here, filter out repeats
+ // TODO Does this actually filter repeats?
if (!event.kbdRepeat) {
// Only for some keys, allow repeated firing emulation
// First hit (fire) has a bigger delay (kKeyRepeatInitialDelay) before repeated events are fired from the same key
@@ -1328,30 +1479,10 @@ void BladeRunnerEngine::handleEvents() {
handleMouseAction(event.mouse.x, event.mouse.y, true, false);
break;
- case Common::EVENT_RBUTTONUP:
- case Common::EVENT_MBUTTONUP:
- handleMouseAction(event.mouse.x, event.mouse.y, false, false);
- break;
-
case Common::EVENT_LBUTTONDOWN:
handleMouseAction(event.mouse.x, event.mouse.y, true, true);
break;
- case Common::EVENT_RBUTTONDOWN:
- case Common::EVENT_MBUTTONDOWN:
- handleMouseAction(event.mouse.x, event.mouse.y, false, true);
- break;
-
- // Added by ScummVM team
- case Common::EVENT_WHEELUP:
- handleMouseAction(event.mouse.x, event.mouse.y, false, false, -1);
- break;
-
- // Added by ScummVM team
- case Common::EVENT_WHEELDOWN:
- handleMouseAction(event.mouse.x, event.mouse.y, false, false, 1);
- break;
-
default:
; // nothing to do
}
@@ -1361,11 +1492,23 @@ void BladeRunnerEngine::handleEvents() {
// Some of those may lead to their own internal gameTick() loops (which will call handleEvents()).
// Thus, we need to get a new timeNow value here to ensure we're not comparing with a stale version.
uint32 timeNow = _time->currentSystem();
- if (isAllowedRepeatedKey(_currentKeyDown)
- && (timeNow - _keyRepeatTimeLast >= _keyRepeatTimeDelay)) {
+ if (!_activeCustomEvents->empty()
+ && (timeNow - _customEventRepeatTimeLast >= _customEventRepeatTimeDelay)) {
+ _customEventRepeatTimeLast = timeNow;
+ _customEventRepeatTimeDelay = kKeyRepeatSustainDelay;
+ for (ActiveCustomEventsArray::iterator it = _activeCustomEvents->begin(); it != _activeCustomEvents->end(); it++) {
+ // kbdRepeat field will be unused here since we emulate the kbd repeat behavior anyway,
+ // but maybe it's good to set it for consistency
+ it->kbdRepeat = true;
+ // reissue the custom start event
+ handleCustomEventStart(*it);
+ }
+ } else if (isAllowedRepeatedKey(_currentKeyDown)
+ && (timeNow - _keyRepeatTimeLast >= _keyRepeatTimeDelay)) {
// create a "new" keydown event
event.type = Common::EVENT_KEYDOWN;
- // kbdRepeat field will be unused here since we emulate the kbd repeat behavior anyway, but it's good to set it for consistency
+ // kbdRepeat field will be unused here since we emulate the kbd repeat behavior anyway,
+ // but it's good to set it for consistency
event.kbdRepeat = true;
event.kbd = _currentKeyDown;
_keyRepeatTimeLast = timeNow;
@@ -1391,42 +1534,122 @@ void BladeRunnerEngine::handleKeyUp(Common::Event &event) {
}
void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
- if (_vqaIsPlaying
- && (event.kbd.keycode == Common::KEYCODE_RETURN
- || event.kbd.keycode == Common::KEYCODE_KP_ENTER
- || event.kbd.keycode == Common::KEYCODE_SPACE
- || event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- // Note: Original allows Esc, Spacebar and Return/KP_Enter to skip cutscenes
+ if (!playerHasControl() || _isWalkingInterruptible || _actorIsSpeaking || _vqaIsPlaying) {
+ return;
+ }
+
+ if (_kia->isOpen()) {
+ _kia->handleKeyDown(event.kbd);
+ return;
+ }
+
+ if (_spinner->isOpen()) {
+ return;
+ }
+
+ if (_elevator->isOpen()) {
+ return;
+ }
+
+ if (_esper->isOpen()) {
+ return;
+ }
+
+ if (_vk->isOpen()) {
+ return;
+ }
+
+ if (_dialogueMenu->isOpen()) {
+ return;
+ }
+
+ if (_scores->isOpen()) {
+ _scores->handleKeyDown(event.kbd);
+ return;
+ }
+}
+
+// Check if an polled event belongs to a currently disabled keymap and, if so, drop it.
+bool BladeRunnerEngine::shouldDropRogueCustomEvent(const Common::Event &evt) {
+ if (getEventManager()->getKeymapper() != nullptr) {
+ Common::KeymapArray kmpsArr = getEventManager()->getKeymapper()->getKeymaps();
+ for (Common::KeymapArray::iterator kmpsIt = kmpsArr.begin(); kmpsIt != kmpsArr.end(); ++kmpsIt) {
+ if (!(*kmpsIt)->isEnabled()) {
+ Common::Keymap::ActionArray actionsInKm = (*kmpsIt)->getActions();
+ for (Common::Keymap::ActionArray::iterator kmIt = actionsInKm.begin(); kmIt != actionsInKm.end(); ++kmIt) {
+ if ((evt.type != Common::EVENT_INVALID) && (evt.customType == (*kmIt)->event.customType)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+void BladeRunnerEngine::cleanupPendingRepeatingEvents(const Common::String &keymapperId) {
+ // Also clean up any currently repeating key down here.
+ // This prevents a bug where holding down Enter key in save screen with a filled in save game
+ // or a selected game to overwrite, would complete the save and then maintain Enter as a repeating key
+ // in the main gameplay (without ever sending a key up event to stop it).
+ _currentKeyDown.keycode = Common::KEYCODE_INVALID;
+
+ if (getEventManager()->getKeymapper() != nullptr
+ && getEventManager()->getKeymapper()->getKeymap(keymapperId) != nullptr
+ && !_activeCustomEvents->empty()) {
+
+ Common::Keymap::ActionArray actionsInKm = getEventManager()->getKeymapper()->getKeymap(keymapperId)->getActions();
+ for (Common::Keymap::ActionArray::iterator kmIt = actionsInKm.begin(); kmIt != actionsInKm.end(); ++kmIt) {
+ for (ActiveCustomEventsArray::iterator actIt = _activeCustomEvents->begin(); actIt != _activeCustomEvents->end(); ++actIt) {
+ if ((actIt->type != Common::EVENT_INVALID) && (actIt->customType == (*kmIt)->event.customType)) {
+ _activeCustomEvents->erase(actIt);
+ if (actIt == _activeCustomEvents->end()) {
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void BladeRunnerEngine::handleCustomEventStop(Common::Event &event) {
+ if (!_activeCustomEvents->empty()) {
+ for (ActiveCustomEventsArray::iterator it = _activeCustomEvents->begin(); it != _activeCustomEvents->end(); it++) {
+ if ((it->type != Common::EVENT_INVALID) && (it->customType == event.customType)) {
+ _activeCustomEvents->erase(it);
+ break;
+ }
+ }
+ }
+
+ if (!playerHasControl() || _isWalkingInterruptible) {
+ return;
+ }
+
+ if (_kia->isOpen()) {
+ _kia->handleCustomEventStop(event);
+ return;
+ }
+}
+
+void BladeRunnerEngine::handleCustomEventStart(Common::Event &event) {
+ if (_vqaIsPlaying && (BladeRunnerEngineMappableAction)event.customType == kMpblActionCutsceneSkip) {
_vqaStopIsRequested = true;
_vqaIsPlaying = false;
-
return;
}
- if (_vqaStopIsRequested
- && (event.kbd.keycode == Common::KEYCODE_RETURN
- || event.kbd.keycode == Common::KEYCODE_KP_ENTER
- || event.kbd.keycode == Common::KEYCODE_SPACE
- || event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- return;
+ if (_vqaStopIsRequested && (BladeRunnerEngineMappableAction)event.customType == kMpblActionCutsceneSkip) {
+ return;
}
- if (_actorIsSpeaking
- && (event.kbd.keycode == Common::KEYCODE_RETURN
- || event.kbd.keycode == Common::KEYCODE_KP_ENTER
- || event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- // Note: Original only uses the Return/KP_Enter key here
+ if (_actorIsSpeaking && (BladeRunnerEngineMappableAction)event.customType == kMpActionDialogueSkip) {
_actorSpeakStopIsRequested = true;
_actorIsSpeaking = false;
-
- return;
}
- if (_actorSpeakStopIsRequested
- && (event.kbd.keycode == Common::KEYCODE_RETURN
- || event.kbd.keycode == Common::KEYCODE_KP_ENTER
- || event.kbd.keycode == Common::KEYCODE_ESCAPE)) {
- return;
+ if (_actorSpeakStopIsRequested && (BladeRunnerEngineMappableAction)event.customType == kMpActionDialogueSkip) {
+ return;
}
if (!playerHasControl() || _isWalkingInterruptible || _actorIsSpeaking || _vqaIsPlaying) {
@@ -1434,7 +1657,7 @@ void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
}
if (_kia->isOpen()) {
- _kia->handleKeyDown(event.kbd);
+ _kia->handleCustomEventStart(event);
return;
}
@@ -1459,41 +1682,38 @@ void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
}
if (_scores->isOpen()) {
- _scores->handleKeyDown(event.kbd);
+ _scores->handleCustomEventStart(event);
return;
}
- switch (event.kbd.keycode) {
- case Common::KEYCODE_F1:
+ switch ((BladeRunnerEngineMappableAction)event.customType) {
+ case kMpActionOpenKIATabHelp:
_kia->open(kKIASectionHelp);
break;
- case Common::KEYCODE_F2:
+ case kMpActionOpenKIATabSaveGame:
_kia->open(kKIASectionSave);
break;
- case Common::KEYCODE_F3:
+ case kMpActionOpenKIATabLoadGame:
_kia->open(kKIASectionLoad);
break;
- case Common::KEYCODE_F4:
+ case kMpActionOpenKIATabCrimeSceneDatabase:
_kia->open(kKIASectionCrimes);
break;
- case Common::KEYCODE_F5:
+ case kMpActionOpenKIATabSuspectDatabase:
_kia->open(kKIASectionSuspects);
break;
- case Common::KEYCODE_F6:
+ case kMpActionOpenKIATabClueDatabase:
_kia->open(kKIASectionClues);
break;
- case Common::KEYCODE_F10:
+ case kMpActionOpenKIATabQuitGame:
_kia->open(kKIASectionQuit);
break;
- case Common::KEYCODE_TAB:
+ case kMpActionOpenKiaDatabase:
_kia->openLastOpened();
break;
- case Common::KEYCODE_ESCAPE:
+ case kMpActionToggleKiaOptions:
_kia->open(kKIASectionSettings);
break;
- case Common::KEYCODE_SPACE:
- _combat->change();
- break;
default:
break;
}
diff --git a/engines/bladerunner/bladerunner.h b/engines/bladerunner/bladerunner.h
index 4bcf079ef1d..ca19a3d81c5 100644
--- a/engines/bladerunner/bladerunner.h
+++ b/engines/bladerunner/bladerunner.h
@@ -30,6 +30,7 @@
#include "common/sinetables.h"
#include "common/stream.h"
#include "common/keyboard.h"
+#include "common/events.h"
#include "engines/engine.h"
@@ -110,6 +111,7 @@ public:
static const int kArchiveCount = 12; // +2 to original value (10) to accommodate for SUBTITLES.MIX and one extra resource file, to allow for capability of loading all VQAx.MIX and the MODE.MIX file (debug purposes)
static const int kActorCount = 100;
static const int kActorVoiceOver = kActorCount - 1;
+ static const int kMaxCustomConcurrentRepeatableEvents = 20;
// Incremental number to keep track of significant revisions of the ScummVM bladerunner engine
// that could potentially introduce incompatibilities with old save files or require special actions to restore compatibility
@@ -120,6 +122,10 @@ public:
// 2: all time code uses uint32 (since July 17 2019),
static const int kBladeRunnerScummVMVersion = 2;
+ static const char *kGameplayKeymapId;
+ static const char *kKiaKeymapId;
+ static const char *kCommonKeymapId;
+
bool _gameIsRunning;
bool _windowIsActive;
int _playerLosesControlCounter;
@@ -265,6 +271,50 @@ public:
uint32 _keyRepeatTimeLast;
uint32 _keyRepeatTimeDelay;
+ uint32 _customEventRepeatTimeLast;
+ uint32 _customEventRepeatTimeDelay;
+ typedef Common::Array<Common::Event> ActiveCustomEventsArray;
+
+ // We do allow keys mapped to the same event,
+ // so eg. a key (Enter) could cause 2 or more events to fire,
+ // However, we should probably restrict the active events
+ // (that can be repeated while holding the mapped keys down)
+ // to a maximum of kMaxCustomConcurrentRepeatableEvents
+ ActiveCustomEventsArray _activeCustomEvents[kMaxCustomConcurrentRepeatableEvents];
+
+ // NOTE We still need keyboard functionality for naming saved games and also for the KIA Easter eggs.
+ // In KIA keyboard events should be accounted where possible - however some keymaps are still needed
+ // which is why we have the three separate common, gameplay-only and kia-only keymaps.
+ // If a valid keyboard key character eg. ("A") for text input (or Easter egg input)
+ // is also mapped to a common or KIA only custom event, then the custom event will be effected and not the key input.
+ // NOTE We don't use a custom action for left click -- we just use the standard left click action event (kStandardActionLeftClick)
+ // NOTE Dialogue Skip does not work for dialogue replayed when clicking on KIA clues (this is the original's behavior too)
+ // NOTE Toggle KIA options does not work when McCoy is walking towards a character when the player clicks on McCoy
+ // (this is the original's behavior too).
+ // "Esc" (by default) or the mapped key to this action still works though.
+ // NOTE A drawback of using customized keymapper for the game is that we can no longer replicate the original's behavior
+ // whereby holding down <SPACEBAR> would cause McCoy to keep switching quickly between combat mode and normal mode.
+ // This is because the original, when holding down right mouse button, would just toggle McCoy's mode once.
+ // We keep the behavior for "right mouse button".
+ // The continuous fast toggle behavior when holding down <SPACEBAR> feels more like a bug anyway.
+ enum BladeRunnerEngineMappableAction {
+// kMpActionLeftClick, // default <left click> (select, walk-to, run-to, look-at, talk-to, use, shoot (combat mode), KIA (click on McCoy))
+ kMpActionToggleCombat, // default <right click> or <Spacebar>
+ kMpblActionCutsceneSkip, // default <Return> or <KP_Enter> or <Esc> or <Spacebar>
+ kMpActionDialogueSkip, // default <Return> or <KP_Enter>
+ kMpActionToggleKiaOptions, // default <Esc> opens/closes KIA, in Options tab
+ kMpActionOpenKiaDatabase, // default <Tab> - only opens KIA (if closed), in one of the database tabs (the last active one, or else the first)
+ kMpActionOpenKIATabHelp, // default <F1>
+ kMpActionOpenKIATabSaveGame, // default <F2>
+ kMpActionOpenKIATabLoadGame, // default <F3>
+ kMpActionOpenKIATabCrimeSceneDatabase, // default <F4>
+ kMpActionOpenKIATabSuspectDatabase, // default <F5>
+ kMpActionOpenKIATabClueDatabase, // default <F6>
+ kMpActionOpenKIATabQuitGame, // default <F10>
+ kMpActionScrollUp, // ScummVM addition (scroll list up)
+ kMpActionScrollDown // ScummVM addition (scroll list down)
+ };
+
private:
MIXArchive _archives[kArchiveCount];
@@ -326,6 +376,13 @@ public:
bool isAllowedRepeatedKey(const Common::KeyState &currKeyState);
+ void handleCustomEventStart(Common::Event &event);
+ void handleCustomEventStop(Common::Event &event);
+ bool isAllowedRepeatedCustomEvent(const Common::Event &currEvent);
+
+ bool shouldDropRogueCustomEvent(const Common::Event &evt);
+ void cleanupPendingRepeatingEvents(const Common::String &keymapperId);
+
void gameWaitForActive();
void loopActorSpeaking();
void loopQueuedDialogueStillPlaying();
diff --git a/engines/bladerunner/metaengine.cpp b/engines/bladerunner/metaengine.cpp
index 2050d57bfbc..3f159b59681 100644
--- a/engines/bladerunner/metaengine.cpp
+++ b/engines/bladerunner/metaengine.cpp
@@ -23,10 +23,15 @@
#include "bladerunner/bladerunner.h"
#include "bladerunner/savefile.h"
+#include "backends/keymapper/action.h"
+#include "backends/keymapper/keymap.h"
+#include "backends/keymapper/standard-actions.h"
+
#include "common/config-manager.h"
#include "common/system.h"
#include "common/savefile.h"
#include "common/serializer.h"
+#include "common/translation.h"
#include "engines/advancedDetector.h"
@@ -36,6 +41,7 @@ public:
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
bool hasFeature(MetaEngineFeature f) const override;
+ Common::KeymapArray initKeymaps(const char *target) const override;
SaveStateList listSaves(const char *target) const override;
int getMaximumSaveSlot() const override;
@@ -66,6 +72,141 @@ bool BladeRunnerMetaEngine::hasFeature(MetaEngineFeature f) const {
f == kSimpleSavesNames;
}
+Common::KeymapArray BladeRunnerMetaEngine::initKeymaps(const char *target) const {
+ using namespace Common;
+ using namespace BladeRunner;
+
+ Common::String gameId = ConfMan.get("gameid", target);
+ Common::U32String gameDesc;
+ Keymap *commonKeymap;
+ Keymap *gameplayKeymap;
+ Keymap *kiaOnlyKeymap;
+
+ if (gameId == "bladerunner") {
+ gameDesc = "Blade Runner";
+ } else if (gameId == "bladerunner-final") {
+ gameDesc = "Blade Runner (Restored Content)";
+ }
+
+ if (gameDesc.empty()) {
+ return AdvancedMetaEngine::initKeymaps(target);
+ }
+
+ // We use 3 keymaps: common (main game and KIA), gameplay (main game only) and kia (KIA only).
+ // This helps us with disabling unneeded keymaps, which is especially useful in KIA, when typing in a saved game.
+ // In general, Blade Runner by default, can bind a key (eg. spacebar) to multiple actions
+ // (eg. skip cutscene, toggle combat, enter a blank space in save game input field).
+ // We need to be able to disable the conflicting keymaps, while keeping others that should still work in KIA
+ // (eg. "Esc" (by default) toggling KIA should work in normal gameplay and also within KIA).
+ // Another related issue we tackle is that a custom action event does not maintain the keycode and ascii value
+ // (if it was associated with a keyboard key), and there's no obvious way to retrieve those from it.
+ // Thus, a custom action event cannot be somehow utilised to produce keyboard key presses
+ // (again if a keyboard key is mapped to that action), so it cannot by itself be used
+ // for text entering in the save file name input field, or for typing the Easter Egg strings.
+ commonKeymap = new Keymap(Keymap::kKeymapTypeGame, BladeRunnerEngine::kCommonKeymapId, gameDesc + Common::U32String(" - ") + _("common shortcuts"));
+ gameplayKeymap = new Keymap(Keymap::kKeymapTypeGame, BladeRunnerEngine::kGameplayKeymapId, gameDesc + Common::U32String(" - ") + _("main game shortcuts"));
+ kiaOnlyKeymap = new Keymap(Keymap::kKeymapTypeGame, BladeRunnerEngine::kKiaKeymapId, gameDesc + Common::U32String(" - ") + _("KIA only shortcuts"));
+
+ Action *act;
+
+ // Look at backends\keymapper\hardware-input.cpp for the strings that can be used in InputMapping
+ act = new Action(kStandardActionLeftClick, _("Walk / Look / Talk / Select / Shoot"));
+ act->setLeftClickEvent();
+ act->addDefaultInputMapping("MOUSE_LEFT");
+ act->addDefaultInputMapping("JOY_A");
+ commonKeymap->addAction(act);
+
+ act = new Action("COMBAT", _("Toggle Combat"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionToggleCombat);
+ act->addDefaultInputMapping("MOUSE_RIGHT");
+ act->addDefaultInputMapping("MOUSE_MIDDLE");
+ act->addDefaultInputMapping("JOY_B");
+ act->addDefaultInputMapping("SPACE");
+ gameplayKeymap->addAction(act);
+
+ act = new Action("SKIPVIDEO", _("Skip cutscene"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpblActionCutsceneSkip);
+ act->addDefaultInputMapping("ESCAPE");
+ act->addDefaultInputMapping("RETURN");
+ act->addDefaultInputMapping("KP_ENTER");
+ act->addDefaultInputMapping("SPACE");
+ act->addDefaultInputMapping("JOY_Y");
+ gameplayKeymap->addAction(act);
+
+ act = new Action("SKIPDLG", _("Skip dialogue"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionDialogueSkip);
+ act->addDefaultInputMapping("RETURN");
+ act->addDefaultInputMapping("KP_ENTER");
+ act->addDefaultInputMapping("JOY_X");
+ gameplayKeymap->addAction(act);
+
+ act = new Action("KIAOPTS", _("Game Options"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionToggleKiaOptions);
+ act->addDefaultInputMapping("ESCAPE");
+ act->addDefaultInputMapping("JOY_Y");
+ commonKeymap->addAction(act);
+
+ act = new Action("KIADB", _("Open KIA Database"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKiaDatabase);
+ act->addDefaultInputMapping("TAB");
+ act->addDefaultInputMapping("JOY_LEFT_SHOULDER");
+ gameplayKeymap->addAction(act);
+
+ act = new Action("KIASCROLLUP", _("Scroll Up"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionScrollUp);
+ act->addDefaultInputMapping("MOUSE_WHEEL_UP");
+ act->addDefaultInputMapping("JOY_UP");
+ kiaOnlyKeymap->addAction(act);
+
+ act = new Action("KIASCROLLDOWN", _("Scroll Down"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionScrollDown);
+ act->addDefaultInputMapping("MOUSE_WHEEL_DOWN");
+ act->addDefaultInputMapping("JOY_DOWN");
+ kiaOnlyKeymap->addAction(act);
+
+ act = new Action("KIAHLP", _("Help"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKIATabHelp);
+ act->addDefaultInputMapping("F1");
+ commonKeymap->addAction(act);
+
+ act = new Action("KIASAVE", _("Save Game"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKIATabSaveGame);
+ act->addDefaultInputMapping("F2");
+ commonKeymap->addAction(act);
+
+ act = new Action("KIALOAD", _("Load Game"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKIATabLoadGame);
+ act->addDefaultInputMapping("F3");
+ commonKeymap->addAction(act);
+
+ act = new Action("KIACRIMES", _("Crime Scene Database"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKIATabCrimeSceneDatabase);
+ act->addDefaultInputMapping("F4");
+ commonKeymap->addAction(act);
+
+ act = new Action("KIASUSPECTS", _("Suspect Database"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKIATabSuspectDatabase);
+ act->addDefaultInputMapping("F5");
+ commonKeymap->addAction(act);
+
+ act = new Action("KIACLUES", _("Clue Database"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKIATabClueDatabase);
+ act->addDefaultInputMapping("F6");
+ commonKeymap->addAction(act);
+
+ act = new Action("KIAQUIT", _("Quit Game"));
+ act->setCustomEngineActionEvent(BladeRunnerEngine::kMpActionOpenKIATabQuitGame);
+ act->addDefaultInputMapping("F10");
+ commonKeymap->addAction(act);
+
+ KeymapArray keymaps(3);
+ keymaps[0] = commonKeymap;
+ keymaps[1] = gameplayKeymap;
+ keymaps[2] = kiaOnlyKeymap;
+
+ return keymaps;
+}
+
SaveStateList BladeRunnerMetaEngine::listSaves(const char *target) const {
return BladeRunner::SaveFileManager::list(this, target);
}
diff --git a/engines/bladerunner/ui/kia.cpp b/engines/bladerunner/ui/kia.cpp
index c573bedf226..48cbe73702d 100644
--- a/engines/bladerunner/ui/kia.cpp
+++ b/engines/bladerunner/ui/kia.cpp
@@ -56,6 +56,8 @@
#include "common/str.h"
#include "common/keyboard.h"
#include "common/debug.h"
+#include "backends/keymapper/keymap.h"
+#include "backends/keymapper/keymapper.h"
#include "graphics/scaler.h"
@@ -154,6 +156,18 @@ void KIA::openLastOpened() {
}
void KIA::open(KIASections sectionId) {
+ if (_vm->getEventManager()->getKeymapper() != nullptr) {
+ if ( _vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kGameplayKeymapId) != nullptr) {
+ // When disabling a keymap, make sure all their active events in the _activeCustomEvents array
+ // are cleared, because as they won't get an explicit "EVENT_CUSTOM_ENGINE_ACTION_END" event.
+ _vm->cleanupPendingRepeatingEvents(BladeRunnerEngine::kGameplayKeymapId);
+ _vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kGameplayKeymapId)->setEnabled(false);
+ }
+
+ if (_vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kKiaKeymapId) != nullptr)
+ _vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kKiaKeymapId)->setEnabled(true);
+ }
+
if (_currentSectionId == sectionId) {
return;
}
@@ -476,31 +490,56 @@ void KIA::handleKeyDown(const Common::KeyState &kbd) {
}
}
- switch (kbd.keycode) {
- case Common::KEYCODE_ESCAPE:
+ if (_currentSection) {
+ _currentSection->handleKeyDown(kbd);
+ }
+
+ if (_currentSection && _currentSection->_scheduledSwitch) {
+ open(kKIASectionNone);
+ }
+}
+
+void KIA::handleCustomEventStop(const Common::Event &evt) {
+ if (!isOpen()) {
+ return;
+ }
+
+ if (_currentSection) {
+ _currentSection->handleCustomEventStop(evt);
+ }
+}
+
+void KIA::handleCustomEventStart(const Common::Event &evt) {
+ if (!isOpen()) {
+ return;
+ }
+
+ switch ((BladeRunnerEngine::BladeRunnerEngineMappableAction)evt.customType) {
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionToggleKiaOptions:
if (!_forceOpen) {
open(kKIASectionNone);
}
break;
- case Common::KEYCODE_F1:
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionOpenKIATabHelp:
open(kKIASectionHelp);
break;
- case Common::KEYCODE_F2:
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionOpenKIATabSaveGame:
if (!_forceOpen) {
open(kKIASectionSave);
}
break;
- case Common::KEYCODE_F3:
+
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionOpenKIATabLoadGame:
open(kKIASectionLoad);
break;
- case Common::KEYCODE_F10:
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionOpenKIATabQuitGame:
open(kKIASectionQuit);
break;
- case Common::KEYCODE_F4:
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionOpenKIATabCrimeSceneDatabase:
if (_currentSectionId != kKIASectionCrimes) {
if (!_forceOpen) {
open(kKIASectionCrimes);
@@ -510,7 +549,7 @@ void KIA::handleKeyDown(const Common::KeyState &kbd) {
}
break;
- case Common::KEYCODE_F5:
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionOpenKIATabSuspectDatabase:
if (_currentSectionId != kKIASectionSuspects) {
if (!_forceOpen) {
open(kKIASectionSuspects);
@@ -520,7 +559,7 @@ void KIA::handleKeyDown(const Common::KeyState &kbd) {
}
break;
- case Common::KEYCODE_F6:
+ case BladeRunnerEngine::BladeRunnerEngineMappableAction::kMpActionOpenKIATabClueDatabase:
if (_currentSectionId != kKIASectionClues) {
if (!_forceOpen) {
open(kKIASectionClues);
@@ -532,7 +571,7 @@ void KIA::handleKeyDown(const Common::KeyState &kbd) {
default:
if (_currentSection) {
- _currentSection->handleKeyDown(kbd);
+ _currentSection->handleCustomEventStart(evt);
}
break;
}
@@ -759,6 +798,18 @@ void KIA::init() {
}
void KIA::unload() {
+ if (_vm->getEventManager()->getKeymapper() != nullptr) {
+ if ( _vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kGameplayKeymapId) != nullptr)
+ _vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kGameplayKeymapId)->setEnabled(true);
+
+ if (_vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kKiaKeymapId) != nullptr) {
+ // When disabling a keymap, make sure all their active events in the _activeCustomEvents array
+ // are cleared, because as they won't get an explicit "EVENT_CUSTOM_ENGINE_ACTION_END" event.
+ _vm->cleanupPendingRepeatingEvents(BladeRunnerEngine::kKiaKeymapId);
+ _vm->getEventManager()->getKeymapper()->getKeymap(BladeRunnerEngine::kKiaKeymapId)->setEnabled(false);
+ }
+ }
+
_thumbnail.free();
if (!isOpen()) {
diff --git a/engines/bladerunner/ui/kia.h b/engines/bladerunner/ui/kia.h
index f98bcd54d6f..51b10368cb8 100644
--- a/engines/bladerunner/ui/kia.h
+++ b/engines/bladerunner/ui/kia.h
@@ -28,6 +28,7 @@
namespace Common {
struct KeyState;
+struct Event;
}
namespace BladeRunner {
@@ -143,6 +144,8 @@ public:
void handleMouseScroll(int mouseX, int mouseY, int direction); // Added by ScummVM team
void handleKeyUp(const Common::KeyState &kbd);
void handleKeyDown(const Common::KeyState &kbd);
+ void handleCustomEventStop(const Common::Event &evt);
+ void handleCustomEventStart(const Common::Event &evt);
void playerReset();
void playActorDialogue(int actorId, int sentenceId);
diff --git a/engines/bladerunner/ui/kia_section_base.h b/engines/bladerunner/ui/kia_section_base.h
index 6751f13cdfc..6117eaf4370 100644
--- a/engines/bladerunner/ui/kia_section_base.h
+++ b/engines/bladerunner/ui/kia_section_base.h
@@ -26,6 +26,7 @@
namespace Common {
struct KeyState;
+struct Event;
}
namespace Graphics {
@@ -53,6 +54,10 @@ public:
virtual void handleKeyUp(const Common::KeyState &kbd) {}
virtual void handleKeyDown(const Common::KeyState &kbd) {}
+
+ virtual void handleCustomEventStart(const Common::Event &evt) {}
+ virtual void handleCustomEventStop(const Common::Event &evt) {}
+
virtual void handleMouseMove(int mouseX, int mouseY) {}
virtual void handleMouseDown(bool mainButton) {}
virtual void handleMouseUp(bool mainButton) {}
diff --git a/engines/bladerunner/ui/kia_section_save.cpp b/engines/bladerunner/ui/kia_section_save.cpp
index 168a9c26d34..c5893d4cbc7 100644
--- a/engines/bladerunner/ui/kia_section_save.cpp
+++ b/engines/bladerunner/ui/kia_section_save.cpp
@@ -225,6 +225,22 @@ void KIASectionSave::draw(Graphics::Surface &surface) {
_buttons->drawTooltip(surface, _mouseX, _mouseY);
}
+bool KIASectionSave::isKeyConfirmModalDialogue(const Common::KeyState &kbd) {
+ if (kbd.keycode == Common::KEYCODE_RETURN || kbd.keycode == Common::KEYCODE_KP_ENTER) {
+ return true;
+ }
+ return false;
+}
+
+bool KIASectionSave::isKeyRequestDeleteEntry(const Common::KeyState &kbd) {
+ if (_selectedLineId != _newSaveLineId
+ && ( kbd.keycode == Common::KEYCODE_DELETE
+ || (kbd.keycode == Common::KEYCODE_KP_PERIOD && !(kbd.flags & Common::KBD_NUM)))) {
+ return true;
+ }
+ return false;
+}
+
void KIASectionSave::handleKeyUp(const Common::KeyState &kbd) {
if (_state == kStateNormal) {
_uiContainer->handleKeyUp(kbd);
@@ -234,19 +250,17 @@ void KIASectionSave::handleKeyUp(const Common::KeyState &kbd) {
void KIASectionSave::handleKeyDown(const Common::KeyState &kbd) {
if (_state == kStateNormal) {
// Delete a saved game entry either with Delete key or numpad's (keypad's) Del key (when Num Lock Off)
- if (_selectedLineId != _newSaveLineId
- && ( kbd.keycode == Common::KEYCODE_DELETE
- || (kbd.keycode == Common::KEYCODE_KP_PERIOD && !(kbd.flags & Common::KBD_NUM)))) {
+ if (isKeyRequestDeleteEntry(kbd)) {
changeState(kStateDelete);
}
_uiContainer->handleKeyDown(kbd);
} else if (_state == kStateOverwrite) {
- if (kbd.keycode == Common::KEYCODE_RETURN || kbd.keycode == Common::KEYCODE_KP_ENTER) {
+ if (isKeyConfirmModalDialogue(kbd)) {
save();
changeState(kStateNormal);
}
} else if (_state == kStateDelete) {
- if (kbd.keycode == Common::KEYCODE_RETURN || kbd.keycode == Common::KEYCODE_KP_ENTER) {
+ if (isKeyConfirmModalDialogue(kbd)) {
deleteSave();
changeState(kStateNormal);
}
diff --git a/engines/bladerunner/ui/kia_section_save.h b/engines/bladerunner/ui/kia_section_save.h
index ba5978b89f2..77a71039ef2 100644
--- a/engines/bladerunner/ui/kia_section_save.h
+++ b/engines/bladerunner/ui/kia_section_save.h
@@ -93,6 +93,9 @@ private:
void changeState(State state);
void save();
void deleteSave();
+
+ bool isKeyConfirmModalDialogue(const Common::KeyState &kbd);
+ bool isKeyRequestDeleteEntry(const Common::KeyState &kbd);
};
} // End of namespace BladeRunner
diff --git a/engines/bladerunner/ui/scores.cpp b/engines/bladerunner/ui/scores.cpp
index 5fed6df71c8..674a54f6a94 100644
--- a/engines/bladerunner/ui/scores.cpp
+++ b/engines/bladerunner/ui/scores.cpp
@@ -105,6 +105,10 @@ void Scores::set(int index, int value) {
_lastScoreValue = value;
}
+void Scores::handleCustomEventStart(const Common::Event &evt) {
+ close();
+}
+
void Scores::handleKeyDown(const Common::KeyState &kbd) {
close();
}
diff --git a/engines/bladerunner/ui/scores.h b/engines/bladerunner/ui/scores.h
index 2d353832663..8430545beba 100644
--- a/engines/bladerunner/ui/scores.h
+++ b/engines/bladerunner/ui/scores.h
@@ -26,6 +26,7 @@
namespace Common {
struct KeyState;
+struct Event;
}
namespace BladeRunner {
@@ -64,6 +65,7 @@ public:
int query(int index) { return _scores[index]; }
void set(int index, int value);
+ void handleCustomEventStart(const Common::Event &evt);
void handleKeyDown(const Common::KeyState &kbd);
int handleMouseUp(int x, int y);
int handleMouseDown(int x, int y);
More information about the Scummvm-git-logs
mailing list