SKY: Implement keymapper integration

This commit is contained in:
Bastien Bouclet 2020-02-01 19:50:03 +01:00
parent 5c2f3f0569
commit eba793f3fd
7 changed files with 139 additions and 26 deletions

View File

@ -21,6 +21,8 @@
*/
#include "backends/keymapper/keymap.h"
#include "common/endian.h"
#include "common/config-manager.h"
#include "common/events.h"
@ -194,7 +196,7 @@ void ControlStatus::drawToScreen() {
_statusText->drawToScreen(WITH_MASK);
}
Control::Control(Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system) {
Control::Control(Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system, Common::Keymap *shortcutsKeymap) {
_saveFileMan = saveFileMan;
_skyScreen = screen;
@ -206,7 +208,9 @@ Control::Control(Common::SaveFileManager *saveFileMan, Screen *screen, Disk *dis
_skySound = sound;
_skyCompact = skyCompact;
_system = system;
_shortcutsKeymap = shortcutsKeymap;
_controlPanel = NULL;
_action = kSkyActionNone;
}
ConResource *Control::createResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, int16 pX, int16 pY, uint32 pText, uint8 pOnClick, uint8 panelType) {
@ -494,7 +498,7 @@ void Control::doControlPanel() {
delay(ANIM_DELAY);
if (!_controlPanel)
return;
if (_keyPressed.keycode == Common::KEYCODE_ESCAPE) { // escape pressed
if (_action == kSkyActionSkip) { // escape pressed
_mouseClicked = false;
quitPanel = true;
}
@ -838,6 +842,7 @@ bool Control::autoSaveExists() {
uint16 Control::saveRestorePanel(bool allowSave) {
_keyPressed.reset();
_action = kSkyActionNone;
_mouseWheel = 0;
buttonControl(NULL);
_text->drawToScreen(WITH_MASK); // flush text restore buffer
@ -849,6 +854,9 @@ uint16 Control::saveRestorePanel(bool allowSave) {
lookList = _savePanLookList;
lookListLen = 6;
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
// Disable the shortcuts keymap during text input to prevent letters from being mapped to action events
_shortcutsKeymap->setEnabled(false);
} else {
lookList = _restorePanLookList;
if (autoSaveExists())
@ -896,11 +904,11 @@ uint16 Control::saveRestorePanel(bool allowSave) {
delay(ANIM_DELAY);
if (!_controlPanel)
return clickRes;
if (_keyPressed.keycode == Common::KEYCODE_ESCAPE) { // escape pressed
if (_action == kSkyActionSkip) { // escape pressed
_mouseClicked = false;
clickRes = CANCEL_PRESSED;
quitPanel = true;
} else if ((_keyPressed.keycode == Common::KEYCODE_RETURN) || (_keyPressed.keycode == Common::KEYCODE_KP_ENTER)) {
} else if (_action == kSkyActionConfirm) { // enter pressed
clickRes = handleClick(lookList[0]);
if (!_controlPanel) //game state was destroyed
return clickRes;
@ -910,7 +918,7 @@ uint16 Control::saveRestorePanel(bool allowSave) {
displayMessage(0, "Could not save the game. (%s)", _saveFileMan->popErrorDesc().c_str());
quitPanel = true;
_mouseClicked = false;
_keyPressed.reset();
_action = kSkyActionNone;
} if (allowSave && _keyPressed.keycode) {
handleKeyPress(_keyPressed, saveGameTexts[_selectedGame]);
refreshNames = true;
@ -979,6 +987,7 @@ uint16 Control::saveRestorePanel(bool allowSave) {
free(textSprites[cnt]);
if (allowSave) {
_shortcutsKeymap->setEnabled(true);
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
}
@ -1495,11 +1504,15 @@ void Control::delay(unsigned int amount) {
uint32 start = _system->getMillis();
uint32 cur = start;
_keyPressed.reset();
_action = kSkyActionNone;
do {
Common::EventManager *eventMan = _system->getEventManager();
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
_action = event.customType;
break;
case Common::EVENT_KEYDOWN:
_keyPressed = event.kbd;
break;

View File

@ -180,7 +180,7 @@ private:
class Control {
public:
Control(Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system);
Control(Common::SaveFileManager *saveFileMan, Screen *screen, Disk *disk, Mouse *mouse, Text *text, MusicBase *music, Logic *logic, Sound *sound, SkyCompact *skyCompact, OSystem *system, Common::Keymap *shortcutsKeymap);
void doControlPanel();
void doLoadSavePanel();
void restartGame();
@ -248,7 +248,9 @@ private:
OSystem *_system;
bool _mouseClicked;
Common::KeyState _keyPressed;
Common::CustomEventType _action;
int _mouseWheel;
Common::Keymap *_shortcutsKeymap;
struct {
uint8 *controlPanel;

View File

@ -25,6 +25,9 @@
#include "base/plugins.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymap.h"
#include "backends/keymapper/standard-actions.h"
#include "common/config-manager.h"
#include "engines/advancedDetector.h"
#include "engines/metaengine.h"
@ -84,6 +87,7 @@ public:
const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const override;
PlainGameDescriptor findGame(const char *gameid) const override;
DetectedGames detectGames(const Common::FSList &fslist) const override;
Common::KeymapArray initKeymaps(const char *target) const override;
Common::Error createInstance(OSystem *syst, Engine **engine) const override;
@ -201,6 +205,73 @@ DetectedGames SkyMetaEngine::detectGames(const Common::FSList &fslist) const {
return detectedGames;
}
Common::KeymapArray SkyMetaEngine::initKeymaps(const char *target) const {
using namespace Common;
using namespace Sky;
Keymap *mainKeymap = new Keymap(Keymap::kKeymapTypeGame, "sky-main", "Beneath a Steel Sky");
Action *act;
act = new Action("LCLK", _("Walk / Look / Talk"));
act->setLeftClickEvent();
act->addDefaultInputMapping("MOUSE_LEFT");
act->addDefaultInputMapping("JOY_A");
mainKeymap->addAction(act);
act = new Action("RCLK", _("Use"));
act->setRightClickEvent();
act->addDefaultInputMapping("MOUSE_RIGHT");
act->addDefaultInputMapping("JOY_B");
mainKeymap->addAction(act);
act = new Action("CONFIRM", _("Confirm"));
act->setCustomEngineActionEvent(kSkyActionConfirm);
act->addDefaultInputMapping("RETURN");
act->addDefaultInputMapping("KP_ENTER");
mainKeymap->addAction(act);
act = new Action(kStandardActionSkip, _("Skip / Close"));
act->setCustomEngineActionEvent(kSkyActionSkip);
act->addDefaultInputMapping("ESCAPE");
act->addDefaultInputMapping("JOY_Y");
mainKeymap->addAction(act);
Keymap *shortcutsKeymap = new Keymap(Keymap::kKeymapTypeGame, SkyEngine::shortcutsKeymapId, "Beneath a Steel Sky - Shortcuts");
act = new Action(kStandardActionOpenMainMenu, _("Open control panel"));
act->setCustomEngineActionEvent(kSkyActionOpenControlPanel);
act->addDefaultInputMapping("F5");
act->addDefaultInputMapping("JOY_X");
shortcutsKeymap->addAction(act);
act = new Action("SKPL", _("Skip line"));
act->setCustomEngineActionEvent(kSkyActionSkipLine);
act->addDefaultInputMapping("PERIOD");
shortcutsKeymap->addAction(act);
act = new Action(kStandardActionPause, _("Pause"));
act->setCustomEngineActionEvent(kSkyActionPause);
act->addDefaultInputMapping("p");
shortcutsKeymap->addAction(act);
act = new Action("FAST", _("Toggle fast mode"));
act->setCustomEngineActionEvent(kSkyActionToggleFastMode);
act->addDefaultInputMapping("C+f");
shortcutsKeymap->addAction(act);
act = new Action("RFAST", _("Toggle really fast mode"));
act->setCustomEngineActionEvent(kSkyActionToggleReallyFastMode);
act->addDefaultInputMapping("C+g");
shortcutsKeymap->addAction(act);
KeymapArray keymaps(2);
keymaps[0] = mainKeymap;
keymaps[1] = shortcutsKeymap;
return keymaps;
}
Common::Error SkyMetaEngine::createInstance(OSystem *syst, Engine **engine) const {
assert(engine);
*engine = new Sky::SkyEngine(syst);

View File

@ -927,8 +927,8 @@ bool Intro::escDelay(uint32 msecs) {
int32 nDelay = 0;
do {
while (eventMan->pollEvent(event)) {
if (event.type == Common::EVENT_KEYDOWN) {
if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
if (event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
if (event.customType == kSkyActionSkip)
return false;
} else if (event.type == Common::EVENT_QUIT || event.type == Common::EVENT_RTL) {
return false;

View File

@ -185,8 +185,8 @@ void Mouse::waitMouseNotPressed(int minDelay) {
while (eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
if (event.customType == kSkyActionSkip) {
minDelay = 0;
mousePressed = false;
}

View File

@ -20,6 +20,8 @@
*
*/
#include "backends/keymapper/keymapper.h"
#include "common/config-manager.h"
#include "common/system.h"
#include "common/textconsole.h"
@ -70,6 +72,8 @@ void *SkyEngine::_itemList[300];
SystemVars SkyEngine::_systemVars = {0, 0, 0, 0, 4316, 0, 0, false, false };
const char *SkyEngine::shortcutsKeymapId = "sky-shortcuts";
SkyEngine::SkyEngine(OSystem *syst)
: Engine(syst), _fastMode(0), _debugger(0) {
}
@ -113,35 +117,34 @@ void SkyEngine::initVirgin() {
}
void SkyEngine::handleKey() {
if (_keyPressed.keycode && _systemVars.paused) {
if ((_action != kSkyActionNone || _keyPressed.keycode) && _systemVars.paused) {
_skySound->fnUnPauseFx();
_systemVars.paused = false;
_skyScreen->setPaletteEndian((uint8 *)_skyCompact->fetchCpt(SkyEngine::_systemVars.currentPalette));
} else if (_keyPressed.hasFlags(Common::KBD_CTRL)) {
if (_keyPressed.keycode == Common::KEYCODE_f)
} else {
switch (_action) {
case kSkyActionToggleFastMode:
_fastMode ^= 1;
else if (_keyPressed.keycode == Common::KEYCODE_g)
_fastMode ^= 2;
} else if (_keyPressed.keycode) {
switch (_keyPressed.keycode) {
case Common::KEYCODE_BACKQUOTE:
case Common::KEYCODE_HASH:
_debugger->attach();
break;
case Common::KEYCODE_F5:
case kSkyActionToggleReallyFastMode:
_fastMode ^= 2;
break;
case kSkyActionOpenControlPanel:
_skyControl->doControlPanel();
break;
case Common::KEYCODE_ESCAPE:
case kSkyActionSkip:
if (!_systemVars.pastIntro)
_skyControl->restartGame();
break;
case Common::KEYCODE_PERIOD:
case kSkyActionSkipLine:
_skyMouse->logicClick();
break;
case Common::KEYCODE_p:
case kSkyActionPause:
_skyScreen->halvePalette();
_skySound->fnPauseFx();
_systemVars.paused = true;
@ -151,11 +154,13 @@ void SkyEngine::handleKey() {
break;
}
}
_action = kSkyActionNone;
_keyPressed.reset();
}
Common::Error SkyEngine::go() {
_keyPressed.reset();
_action = kSkyActionNone;
uint16 result = 0;
if (ConfMan.hasKey("save_slot")) {
@ -285,7 +290,11 @@ Common::Error SkyEngine::init() {
_skyLogic = new Logic(_skyCompact, _skyScreen, _skyDisk, _skyText, _skyMusic, _skyMouse, _skySound);
_skyMouse->useLogicInstance(_skyLogic);
_skyControl = new Control(_saveFileMan, _skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _skyLogic, _skySound, _skyCompact, _system);
Common::Keymapper *keymapper = _system->getEventManager()->getKeymapper();
Common::Keymap *shortcutsKeymap = keymapper->getKeymap(shortcutsKeymapId);
assert(shortcutsKeymap);
_skyControl = new Control(_saveFileMan, _skyScreen, _skyDisk, _skyMouse, _skyText, _skyMusic, _skyLogic, _skySound, _skyCompact, _system, shortcutsKeymap);
_skyLogic->useControlInstance(_skyControl);
switch (Common::parseLanguage(ConfMan.get("language"))) {
@ -374,6 +383,7 @@ void SkyEngine::delay(int32 amount) {
Common::Event event;
uint32 start = _system->getMillis();
_action = kSkyActionNone;
_keyPressed.reset();
if (amount < 0)
@ -382,6 +392,9 @@ void SkyEngine::delay(int32 amount) {
do {
while (_eventMan->pollEvent(event)) {
switch (event.type) {
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
_action = (SkyAction)event.customType;
break;
case Common::EVENT_KEYDOWN:
_keyPressed = event.kbd;
break;

View File

@ -61,8 +61,20 @@ class MusicBase;
class Debugger;
class SkyCompact;
enum SkyAction {
kSkyActionNone,
kSkyActionToggleFastMode,
kSkyActionToggleReallyFastMode,
kSkyActionOpenControlPanel,
kSkyActionConfirm,
kSkyActionSkip,
kSkyActionSkipLine,
kSkyActionPause
};
class SkyEngine : public Engine {
protected:
SkyAction _action;
Common::KeyState _keyPressed;
Sound *_skySound;
@ -99,6 +111,8 @@ public:
static SystemVars _systemVars;
static const char *shortcutsKeymapId;
protected:
// Engine APIs
Common::Error init();