diff options
-rw-r--r-- | backends/keymapper/keymap.cpp | 2 | ||||
-rw-r--r-- | backends/keymapper/keymapper.cpp | 4 | ||||
-rw-r--r-- | backends/keymapper/keymapper.h | 2 | ||||
-rw-r--r-- | backends/keymapper/remap-dialog.cpp | 72 | ||||
-rw-r--r-- | backends/keymapper/remap-dialog.h | 2 | ||||
-rw-r--r-- | base/main.cpp | 2 | ||||
-rw-r--r-- | common/keyboard.h | 3 | ||||
-rw-r--r-- | engines/engine.h | 5 | ||||
-rw-r--r-- | engines/kyra/lol.cpp | 67 | ||||
-rw-r--r-- | engines/kyra/lol.h | 4 | ||||
-rw-r--r-- | gui/dialog.cpp | 1 | ||||
-rw-r--r-- | gui/gui-manager.cpp | 25 | ||||
-rw-r--r-- | gui/gui-manager.h | 2 | ||||
-rw-r--r-- | po/POTFILES | 1 |
14 files changed, 170 insertions, 22 deletions
diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp index 1518cba693..d2c9b9b572 100644 --- a/backends/keymapper/keymap.cpp +++ b/backends/keymapper/keymap.cpp @@ -199,6 +199,7 @@ bool Keymap::isComplete(const HardwareKeySet *hwKeys) { // - if an action finds a key with required type but a parent action with // higher priority is using it, that key is never used void Keymap::automaticMapping(HardwareKeySet *hwKeys) { +#if 0 //disabling the broken automapper for now // Create copies of action and key lists. List<Action*> actions(_actions); List<const HardwareKey*> keys(hwKeys->getHardwareKeys()); @@ -318,6 +319,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { break; } } +#endif } Action *Keymap::getParentMappedAction(KeyState key) { diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp index f5f29a2940..29f495cd53 100644 --- a/backends/keymapper/keymapper.cpp +++ b/backends/keymapper/keymapper.cpp @@ -192,10 +192,10 @@ bool Keymapper::mapKey(const KeyState& key, bool keyDown) { // Search for key in active keymap stack for (int i = _activeMaps.size() - 1; i >= 0; --i) { MapRecord mr = _activeMaps[i]; - + debug(5, "Keymapper::mapKey keymap: %s", mr.keymap->getName().c_str()); action = mr.keymap->getMappedAction(key); - if (action || mr.inherit == false) + if (action || !mr.inherit) break; } diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h index fcb444aa64..c5a2558964 100644 --- a/backends/keymapper/keymapper.h +++ b/backends/keymapper/keymapper.h @@ -36,6 +36,8 @@ namespace Common { +const char *const kGuiKeymapName = "gui"; + class Keymapper : public Common::EventMapper, private Common::ArtificialEventSource { public: diff --git a/backends/keymapper/remap-dialog.cpp b/backends/keymapper/remap-dialog.cpp index 7f2df2f0fe..b0f42fe426 100644 --- a/backends/keymapper/remap-dialog.cpp +++ b/backends/keymapper/remap-dialog.cpp @@ -28,13 +28,13 @@ #include "gui/widgets/popup.h" #include "gui/widgets/scrollbar.h" #include "gui/ThemeEval.h" - #include "common/translation.h" namespace Common { enum { kRemapCmd = 'REMP', + kClearCmd = 'CLER', kCloseCmd = 'CLOS' }; @@ -60,7 +60,7 @@ void RemapDialog::open() { bool divider = false; const Stack<Keymapper::MapRecord> &activeKeymaps = _keymapper->getActiveStack(); - if (!(activeKeymaps.size() > 0)) { + if (activeKeymaps.size() > 0) { _kmPopUp->appendEntry(activeKeymaps.top().keymap->getName() + _(" (Active)")); divider = true; } @@ -84,7 +84,7 @@ void RemapDialog::open() { keymapCount += _gameKeymaps->size(); } - debug(3, "keymaps: %d", keymapCount); + debug(3, "RemapDialog::open keymaps: %d", keymapCount); _keymapTable = (Keymap **)malloc(sizeof(Keymap*) * keymapCount); @@ -140,8 +140,10 @@ void RemapDialog::reflowLayout() { uint16 areaW, areaH; int spacing = g_gui.xmlEval()->getVar("Globals.KeyMapper.Spacing"); int labelWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.LabelWidth"); - int buttonWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.ButtonWidth"); - int colWidth = labelWidth + buttonWidth + spacing; + int keyButtonWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.ButtonWidth"); + int clearButtonWidth = g_gui.xmlEval()->getVar("Globals.Line.Height"); + int clearButtonHeight = g_gui.xmlEval()->getVar("Globals.Line.Height"); + int colWidth = labelWidth + keyButtonWidth + clearButtonWidth + spacing; g_gui.xmlEval()->getWidgetData((const String&)String("KeyMapper.KeymapArea"), areaX, areaY, areaW, areaH); @@ -156,6 +158,7 @@ void RemapDialog::reflowLayout() { _scrollBar->recalc(); uint textYOff = (buttonHeight - kLineHeight) / 2; + uint clearButtonYOff = (buttonHeight - clearButtonHeight) / 2; uint oldSize = _keymapWidgets.size(); uint newSize = _rowCount * _colCount; @@ -169,6 +172,16 @@ void RemapDialog::reflowLayout() { new GUI::StaticTextWidget(this, 0, 0, 0, 0, "", Graphics::kTextAlignRight); widg.keyButton = new GUI::ButtonWidget(this, 0, 0, 0, 0, "", 0, kRemapCmd + i); +#ifndef DISABLE_FANCY_THEMES + if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) { + widg.clearButton = new GUI::PicButtonWidget(this, 0, 0, clearButtonWidth, clearButtonHeight, _("Clear value"), kClearCmd + i); + ((GUI::PicButtonWidget *)widg.clearButton)->useThemeTransparency(true); + ((GUI::PicButtonWidget *)widg.clearButton)->setGfx(g_gui.theme()->getImageSurface(GUI::ThemeEngine::kImageEraser)); + } + else +#endif + widg.clearButton = new GUI::ButtonWidget(this, 0, 0, 0, 0, "C", _("Clear value"), kClearCmd + i); + _keymapWidgets.push_back(widg); } else { widg = _keymapWidgets[i]; @@ -178,7 +191,8 @@ void RemapDialog::reflowLayout() { uint y = areaY + (i / _colCount) * (buttonHeight + spacing); widg.actionText->resize(x, y + textYOff, labelWidth, kLineHeight); - widg.keyButton->resize(x + labelWidth, y, buttonWidth, buttonHeight); + widg.keyButton->resize(x + labelWidth, y, keyButtonWidth, buttonHeight); + widg.clearButton->resize(x + labelWidth + keyButtonWidth + spacing, y + clearButtonYOff, clearButtonWidth, clearButtonHeight); } while (oldSize > newSize) { ActionWidgets widg = _keymapWidgets.remove_at(--oldSize); @@ -188,14 +202,19 @@ void RemapDialog::reflowLayout() { removeWidget(widg.keyButton); delete widg.keyButton; + + removeWidget(widg.clearButton); + delete widg.clearButton; } } void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { - debug(0, "Command!"); + debug(3, "RemapDialog::handleCommand %u %u", cmd, data); if (cmd >= kRemapCmd && cmd < kRemapCmd + _keymapWidgets.size()) { startRemapping(cmd - kRemapCmd); + } else if (cmd >= kClearCmd && cmd < kClearCmd + _keymapWidgets.size()) { + clearMapping(cmd - kClearCmd); } else if (cmd == GUI::kPopUpItemSelectedCmd) { loadKeymap(); } else if (cmd == GUI::kSetPositionCmd) { @@ -207,6 +226,23 @@ void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 d } } +void RemapDialog::clearMapping(uint i) { + if (_topAction + i >= _currentActions.size()) + return; + + debug(3, "clear the mapping %u", i); + _activeRemapAction = _currentActions[_topAction + i].action; + _activeRemapAction->mapKey(0); + _activeRemapAction->getParent()->saveMappings(); + _changes = true; + + // force refresh + _topAction = -1; + refreshKeymap(); + + _activeRemapAction = 0; +} + void RemapDialog::startRemapping(uint i) { if (_topAction + i >= _currentActions.size()) return; @@ -240,7 +276,7 @@ void RemapDialog::handleKeyUp(Common::KeyState state) { if (_activeRemapAction) { const HardwareKey *hwkey = _keymapper->findHardwareKey(state); - debug(0, "Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags); + debug(4, "RemapDialog::handleKeyUp Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags); if (hwkey) { _activeRemapAction->mapKey(hwkey); @@ -270,15 +306,23 @@ void RemapDialog::loadKeymap() { _currentActions.clear(); const Stack<Keymapper::MapRecord> &activeKeymaps = _keymapper->getActiveStack(); + debug(3, "RemapDialog::loadKeymap active keymaps: %u", activeKeymaps.size()); + if (!activeKeymaps.empty() && _kmPopUp->getSelected() == 0) { // load active keymaps List<const HardwareKey*> freeKeys(_keymapper->getHardwareKeys()); + int topIndex = activeKeymaps.size() - 1; + // skip the top gui keymap since it is for the keymapper itself + // TODO: Don't use the keymap name as a way to discriminate GUI maps + if (topIndex > 0 && activeKeymaps[topIndex].keymap->getName().equals(kGuiKeymapName)) + --topIndex; + // add most active keymap's keys - Keymapper::MapRecord top = activeKeymaps.top(); + Keymapper::MapRecord top = activeKeymaps[topIndex]; List<Action*>::iterator actIt; - + debug(3, "RemapDialog::loadKeymap top keymap: %s", top.keymap->getName().c_str()); for (actIt = top.keymap->getActions().begin(); actIt != top.keymap->getActions().end(); ++actIt) { Action *act = *actIt; ActionInfo info = {act, false, act->description}; @@ -290,9 +334,10 @@ void RemapDialog::loadKeymap() { } // loop through remaining finding mappings for unmapped keys - if (top.inherit) { - for (int i = activeKeymaps.size() - 2; i >= 0; --i) { + if (top.inherit && topIndex >= 0) { + for (int i = topIndex - 1; i >= 0; --i) { Keymapper::MapRecord mr = activeKeymaps[i]; + debug(3, "RemapDialog::loadKeymap keymap: %s", mr.keymap->getName().c_str()); List<const HardwareKey*>::iterator keyIt = freeKeys.begin(); while (keyIt != freeKeys.end()) { @@ -351,6 +396,7 @@ void RemapDialog::refreshKeymap() { ActionWidgets& widg = _keymapWidgets[widgetI]; if (actionI < _currentActions.size()) { + debug(8, "RemapDialog::refreshKeymap actionI=%u", actionI); ActionInfo& info = _currentActions[actionI]; widg.actionText->setLabel(info.description + ": "); @@ -365,11 +411,13 @@ void RemapDialog::refreshKeymap() { widg.actionText->setVisible(true); widg.keyButton->setVisible(true); + widg.clearButton->setVisible(true); actionI++; } else { widg.actionText->setVisible(false); widg.keyButton->setVisible(false); + widg.clearButton->setVisible(false); } //widg.actionText->draw(); //widg.keyButton->draw(); diff --git a/backends/keymapper/remap-dialog.h b/backends/keymapper/remap-dialog.h index f587ae515d..25e336c4fe 100644 --- a/backends/keymapper/remap-dialog.h +++ b/backends/keymapper/remap-dialog.h @@ -55,6 +55,7 @@ protected: struct ActionWidgets { GUI::StaticTextWidget *actionText; GUI::ButtonWidget *keyButton; + GUI::ButtonWidget *clearButton; }; struct ActionInfo { Action *action; @@ -64,6 +65,7 @@ protected: void loadKeymap(); void refreshKeymap(); + void clearMapping(uint i); void startRemapping(uint i); void stopRemapping(); diff --git a/base/main.cpp b/base/main.cpp index 5d0c0ea09a..61a05154c1 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -288,7 +288,7 @@ static void setupKeymapper(OSystem &system) { mapper->addGlobalKeymap(globalMap); - mapper->pushKeymap("global"); + mapper->pushKeymap("global", true); #endif } diff --git a/common/keyboard.h b/common/keyboard.h index bdd0a2d4af..ead6ed427b 100644 --- a/common/keyboard.h +++ b/common/keyboard.h @@ -292,7 +292,8 @@ struct KeyState { } bool operator==(const KeyState &x) const { - return keycode == x.keycode && ascii == x.ascii && flags == x.flags; + // intentionally ignore ascii + return keycode == x.keycode && flags == x.flags; } }; diff --git a/engines/engine.h b/engines/engine.h index 2796df5c4f..d508b4ed18 100644 --- a/engines/engine.h +++ b/engines/engine.h @@ -180,6 +180,11 @@ public: */ virtual void syncSoundSettings(); + /* + * Initialize the engine-specific keymap + */ + virtual void initKeymap() {} + /** * Flip mute all sound option. */ diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 43859ddfbb..aed8f5c965 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -34,9 +34,14 @@ #include "common/config-manager.h" #include "common/system.h" +#include "common/translation.h" + +#include "backends/keymapper/keymapper.h" namespace Kyra { +const char *const LoLEngine::kKeymapName = "lol"; + LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) { _screen = 0; _gui = 0; @@ -246,6 +251,10 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy LoLEngine::~LoLEngine() { setupPrologueData(false); +#ifdef ENABLE_KEYMAPPER + _eventMan->getKeymapper()->cleanupGameKeymaps(); +#endif + delete[] _landsFile; delete[] _levelLangFile; @@ -541,9 +550,67 @@ Common::Error LoLEngine::init() { _debugger = new Debugger_LoL(this); assert(_debugger); + initKeymap(); + return Common::kNoError; } +void LoLEngine::initKeymap() { +#ifdef ENABLE_KEYMAPPER + + bool tmp; + Common::Keymapper *mapper = _eventMan->getKeymapper(); + + // Do not try to recreate same keymap over again + if (mapper->getKeymap(kKeymapName, tmp) != 0) + return; + + Common::Action *act; + Common::Keymap *engineKeyMap = new Common::Keymap(kKeymapName); + + act = new Common::Action(engineKeyMap, "AT1", _("Attack 1"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_F1, Common::ASCII_F1 , 0)); + + act = new Common::Action(engineKeyMap, "AT2", _("Attack 2"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_F2, Common::ASCII_F2 , 0)); + + act = new Common::Action(engineKeyMap, "AT3", _("Attack 3"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_F3, Common::ASCII_F3 , 0)); + + act = new Common::Action(engineKeyMap, "MVF", _("Move Forward"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_UP)); + + act = new Common::Action(engineKeyMap, "MVB", _("Move Back"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_DOWN)); + + act = new Common::Action(engineKeyMap, "SLL", _("Slide Left"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_LEFT)); + + act = new Common::Action(engineKeyMap, "SLR", _("Slide Right"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_RIGHT)); + + act = new Common::Action(engineKeyMap, "TL", _("Turn Left"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_HOME)); + + act = new Common::Action(engineKeyMap, "TR", _("Turn Right"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_PAGEUP)); + + act = new Common::Action(engineKeyMap, "RST", _("Rest"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_r)); + + act = new Common::Action(engineKeyMap, "OPT", _("Options"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_o)); + + act = new Common::Action(engineKeyMap, "SPL", _("Choose Spell"), Common::kGenericActionType, Common::kActionKeyType); + act->addKeyEvent(Common::KeyState(Common::KEYCODE_SLASH)); + + mapper->addGameKeymap(engineKeyMap); + + mapper->pushKeymap(kKeymapName, true); + +#endif +} + Common::Error LoLEngine::go() { int action = -1; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 5f6be61d64..eb2f6cf2d7 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -307,6 +307,8 @@ public: LoLEngine(OSystem *system, const GameFlags &flags); ~LoLEngine(); + virtual void initKeymap(); + Screen *screen(); GUI *gui() const; @@ -333,6 +335,8 @@ private: void writeSettings(); void readSettings(); + static const char *const kKeymapName; + const char *const *_pakFileList; int _pakFileListSize; diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 2ec8641257..0522b40b46 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -75,7 +75,6 @@ int Dialog::runModal() { } void Dialog::open() { - _result = 0; _visible = true; g_gui.openDialog(this); diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp index 212d68430c..98840e6daf 100644 --- a/gui/gui-manager.cpp +++ b/gui/gui-manager.cpp @@ -107,11 +107,11 @@ void GuiManager::initKeymap() { Keymapper *mapper = _system->getEventManager()->getKeymapper(); // Do not try to recreate same keymap over again - if (mapper->getKeymap("gui", tmp) != 0) + if (mapper->getKeymap(kGuiKeymapName, tmp) != 0) return; Action *act; - Keymap *guiMap = new Keymap("gui"); + Keymap *guiMap = new Keymap(kGuiKeymapName); act = new Action(guiMap, "CLOS", _("Close"), kGenericActionType, kStartKeyType); act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0)); @@ -127,6 +127,22 @@ void GuiManager::initKeymap() { mapper->addGlobalKeymap(guiMap); } + +void GuiManager::pushKeymap() { + _system->getEventManager()->getKeymapper()->pushKeymap(Common::kGuiKeymapName); +} + +void GuiManager::popKeymap() { + Common::Keymapper *keymapper = _system->getEventManager()->getKeymapper(); + if (!keymapper->getActiveStack().empty()) { + Common::Keymapper::MapRecord topKeymap = keymapper->getActiveStack().top(); + // TODO: Don't use the keymap name as a way to discriminate GUI maps + if(topKeymap.keymap->getName().equals(Common::kGuiKeymapName)) + keymapper->popKeymap(); + else + warning("An attempt to pop non-gui keymap %s was blocked", topKeymap.keymap->getName().c_str()); + } +} #endif bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx, bool forced) { @@ -276,8 +292,7 @@ void GuiManager::runLoop() { // try to do it on every launch, checking whether the // map is already existing initKeymap(); - - eventMan->getKeymapper()->pushKeymap("gui"); + pushKeymap(); #endif bool tooltipCheck = false; @@ -392,7 +407,7 @@ void GuiManager::runLoop() { } #ifdef ENABLE_KEYMAPPER - eventMan->getKeymapper()->popKeymap(); + popKeymap(); #endif if (didSaveState) { diff --git a/gui/gui-manager.h b/gui/gui-manager.h index 10f9e6a29f..addd2e6611 100644 --- a/gui/gui-manager.h +++ b/gui/gui-manager.h @@ -126,6 +126,8 @@ protected: byte _cursor[2048]; void initKeymap(); + void pushKeymap(); + void popKeymap(); void saveState(); void restoreState(); diff --git a/po/POTFILES b/po/POTFILES index 6ce26a0539..dcc501ae0e 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -36,6 +36,7 @@ engines/gob/inter_playtoons.cpp engines/gob/inter_v2.cpp engines/gob/inter_v5.cpp engines/groovie/script.cpp +engines/kyra/lol.cpp engines/kyra/sound_midi.cpp engines/m4/m4_menus.cpp engines/sky/compact.cpp |