mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-11 03:34:13 +00:00
BLADERUNNER: Use keymapper with proper events for the game
This commit is contained in:
parent
6994d79e59
commit
6c300519b1
@ -1,3 +1,4 @@
|
||||
engines/bladerunner/bladerunner.cpp
|
||||
engines/bladerunner/detection.cpp
|
||||
engines/bladerunner/detection_tables.h
|
||||
engines/bladerunner/metaengine.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,44 +1534,6 @@ 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
|
||||
_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 (_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
|
||||
_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 (!playerHasControl() || _isWalkingInterruptible || _actorIsSpeaking || _vqaIsPlaying) {
|
||||
return;
|
||||
}
|
||||
@ -1462,38 +1567,153 @@ void BladeRunnerEngine::handleKeyDown(Common::Event &event) {
|
||||
_scores->handleKeyDown(event.kbd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (event.kbd.keycode) {
|
||||
case Common::KEYCODE_F1:
|
||||
// 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 && (BladeRunnerEngineMappableAction)event.customType == kMpblActionCutsceneSkip) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_actorIsSpeaking && (BladeRunnerEngineMappableAction)event.customType == kMpActionDialogueSkip) {
|
||||
_actorSpeakStopIsRequested = true;
|
||||
_actorIsSpeaking = false;
|
||||
}
|
||||
|
||||
if (_actorSpeakStopIsRequested && (BladeRunnerEngineMappableAction)event.customType == kMpActionDialogueSkip) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!playerHasControl() || _isWalkingInterruptible || _actorIsSpeaking || _vqaIsPlaying) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_kia->isOpen()) {
|
||||
_kia->handleCustomEventStart(event);
|
||||
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->handleCustomEventStart(event);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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) {}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user