From 532faef82b20802502d54fabb7364c25eb7ac875 Mon Sep 17 00:00:00 2001 From: Stephen Kennedy Date: Wed, 13 Aug 2008 11:46:08 +0000 Subject: Keymapper WIP: * Improved automatic mapping algorithm * Remap dialog overhaul - now displays active keymap(s) svn-id: r33821 --- backends/keymapper/hardware-key.h | 12 +- backends/keymapper/keymap-manager.cpp | 71 ++++++++-- backends/keymapper/keymap-manager.h | 1 + backends/keymapper/keymap.cpp | 4 - backends/keymapper/keymap.h | 6 +- backends/keymapper/keymapper.cpp | 4 +- backends/keymapper/remap-dialog.cpp | 258 ++++++++++++++++++---------------- backends/keymapper/remap-dialog.h | 32 ++--- backends/platform/sdl/events.cpp | 30 ++-- backends/platform/sdl/sdl.cpp | 8 +- 10 files changed, 245 insertions(+), 181 deletions(-) (limited to 'backends') diff --git a/backends/keymapper/hardware-key.h b/backends/keymapper/hardware-key.h index 40fb2a0cbd..7ddb4dacd1 100644 --- a/backends/keymapper/hardware-key.h +++ b/backends/keymapper/hardware-key.h @@ -71,7 +71,7 @@ public: HardwareKeySet() {} virtual ~HardwareKeySet() { - List::iterator it; + List::iterator it; for (it = _keys.begin(); it != _keys.end(); it++) delete *it; } @@ -82,7 +82,7 @@ public: } const HardwareKey *findHardwareKey(int32 id) const { - List::iterator it; + List::iterator it; for (it = _keys.begin(); it != _keys.end(); it++) { if ((*it)->id == id) return (*it); @@ -91,7 +91,7 @@ public: } const HardwareKey *findHardwareKey(const KeyState& keystate) const { - List::iterator it; + List::iterator it; for (it = _keys.begin(); it != _keys.end(); it++) { if ((*it)->key == keystate) return (*it); @@ -99,7 +99,7 @@ public: return 0; } - List getHardwareKeys() const { + List getHardwareKeys() const { return _keys; } @@ -111,7 +111,7 @@ public: private: void checkForKey(HardwareKey *key) { - List::iterator it; + List::iterator it; for (it = _keys.begin(); it != _keys.end(); it++) { if ((*it)->id == key->id) error("Error adding HardwareKey '%s' - id of %d already in use!", key->description.c_str(), key->id); @@ -120,7 +120,7 @@ private: } } - List _keys; + List _keys; }; diff --git a/backends/keymapper/keymap-manager.cpp b/backends/keymapper/keymap-manager.cpp index 527d0a103a..93d7431ba7 100644 --- a/backends/keymapper/keymap-manager.cpp +++ b/backends/keymapper/keymap-manager.cpp @@ -95,22 +95,36 @@ void KeymapManager::initKeymap(ConfigManager::Domain *domain, void KeymapManager::automaticMap(Keymap *map) { List actions(map->getActions()), unmapped; List::iterator actIt; - List keys = _hardwareKeys->getHardwareKeys(); - List::iterator keyIt, selectedKey; + List keys = _hardwareKeys->getHardwareKeys(); + List::iterator keyIt, selectedKey; // sort by priority ActionPriorityComp priorityComp; sort(actions.begin(), actions.end(), priorityComp); - + for (actIt = actions.begin(); actIt != actions.end(); actIt++) { selectedKey = keys.end(); + int keyScore = 0; Action *act = *actIt; for (keyIt = keys.begin(); keyIt != keys.end(); keyIt++) { if ((*keyIt)->preferredType == act->type) { - selectedKey = keyIt; - break; - } else if ((*keyIt)->preferredCategory == act->category && selectedKey == keys.end()) { - selectedKey = keyIt; + Action *parentAct = getParentMappedAction(map, (*keyIt)->key); + if (!parentAct) { + selectedKey = keyIt; + break; + } else if (parentAct->priority <= act->priority && keyScore < 3) { + selectedKey = keyIt; + keyScore = 3; + } + } else if ((*keyIt)->preferredCategory == act->category && keyScore < 2) { + Action *parentAct = getParentMappedAction(map, (*keyIt)->key); + if (!parentAct) { + selectedKey = keyIt; + keyScore = 2; + } else if (parentAct->priority <= act->priority && keyScore < 1) { + selectedKey = keyIt; + keyScore = 1; + } } } if (selectedKey != keys.end()) { @@ -120,11 +134,46 @@ void KeymapManager::automaticMap(Keymap *map) { unmapped.push_back(act); } - actIt = unmapped.begin(); - keyIt = keys.begin(); - while (actIt != unmapped.end() && keyIt != keys.end()) - (*actIt)->mapKey(*keyIt); + for (actIt = unmapped.begin(); actIt != unmapped.end(); actIt++) { + selectedKey = keys.end(); + int keyScore = 0; + int lowestPriority = 0; //dummy value + Action *act = *actIt; + for (keyIt = keys.begin(); keyIt != keys.end(); keyIt++) { + Action *parentAct = getParentMappedAction(map, (*keyIt)->key); + if (!parentAct) { + selectedKey = keyIt; + break; + } else if (keyScore < 2) { + if (parentAct->priority <= act->priority) { + keyScore = 2; + selectedKey = keyIt; + } else if (parentAct->priority < lowestPriority || keyScore == 0) { + keyScore = 1; + lowestPriority = parentAct->priority; + selectedKey = keyIt; + } + } + } + if (selectedKey != keys.end()) { + act->mapKey(*selectedKey); + keys.erase(selectedKey); + } else // no keys left + return; + } +} +Action *KeymapManager::getParentMappedAction(Keymap *map, KeyState key) { + Keymap *parent = map->getParent(); + if (parent) { + Action *act = parent->getMappedAction(key); + if (act) + return act; + else + return getParentMappedAction(parent, key); + } else { + return 0; + } } Keymap *KeymapManager::getKeymap(const String& name) { diff --git a/backends/keymapper/keymap-manager.h b/backends/keymapper/keymap-manager.h index 6bcb71c0f5..b76273f124 100644 --- a/backends/keymapper/keymap-manager.h +++ b/backends/keymapper/keymap-manager.h @@ -92,6 +92,7 @@ private: void initKeymap(ConfigManager::Domain *domain, Keymap *keymap); void automaticMap(Keymap *map); + Action *getParentMappedAction(Keymap *map, KeyState key); Domain _globalDomain; Domain _gameDomain; diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp index 8af1d266e8..28d0afd51e 100644 --- a/backends/keymapper/keymap.cpp +++ b/backends/keymapper/keymap.cpp @@ -50,10 +50,6 @@ void Keymap::registerMapping(Action *action, const HardwareKey *hwKey) { it = _keymap.find(hwKey->key); // if key is already mapped to a different action then un-map it if (it != _keymap.end() && action != it->_value) { - HashMap::iterator it2; - for (it2 = _keymap.begin(); it2 != _keymap.end(); it2++) { - printf("%d\n", it2->_value); - } it->_value->mapKey(0); } diff --git a/backends/keymapper/keymap.h b/backends/keymapper/keymap.h index 349010ccf0..6b40bbab4f 100644 --- a/backends/keymapper/keymap.h +++ b/backends/keymapper/keymap.h @@ -51,7 +51,7 @@ template<> struct Hash class Keymap { public: - Keymap(const String& na) : _name(na) {} + Keymap(const String& name, Keymap *parent = 0) : _name(name), _parent(parent) {} Keymap(const Keymap& km); public: @@ -80,7 +80,7 @@ public: * @return a pointer to the Action or 0 if no */ Action *getMappedAction(const KeyState& ks) const; - + /** * Load this keymap's mappings from the given config domain and hardware key set * @param domain config domain to load keymap from @@ -101,6 +101,7 @@ public: bool isComplete(const HardwareKeySet *hwKeys); const String& getName() { return _name; } + Keymap *getParent() { return _parent; } private: friend struct Action; @@ -125,6 +126,7 @@ private: void internalMapKey(Action *action, HardwareKey *hwKey); String _name; + Keymap *_parent; List _actions; HashMap _keymap; diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp index c41d74c1cf..93b45e1d99 100644 --- a/backends/keymapper/keymapper.cpp +++ b/backends/keymapper/keymapper.cpp @@ -87,7 +87,7 @@ bool Keymapper::mapKey(const KeyState& key, bool isKeyDown) { if (_activeMaps.empty()) return false; Action *action = 0; - for (int i = _activeMaps.size() - 1; !action && i >= 0; i++) { + for (int i = _activeMaps.size() - 1; !action && i >= 0; --i) { MapRecord mr = _activeMaps[i]; action = mr.keymap->getMappedAction(key); if (mr.inherit == false) break; @@ -95,7 +95,7 @@ bool Keymapper::mapKey(const KeyState& key, bool isKeyDown) { if (!action) return false; List::iterator it; - for (it = action->events.begin(); it != action->events.end(); it++) { + for (it = action->events.begin(); it != action->events.end(); ++it) { Event evt = *it; bool pushEvent = true; switch (evt.type) { diff --git a/backends/keymapper/remap-dialog.cpp b/backends/keymapper/remap-dialog.cpp index ac048fc089..22d52575ca 100644 --- a/backends/keymapper/remap-dialog.cpp +++ b/backends/keymapper/remap-dialog.cpp @@ -35,7 +35,7 @@ enum { }; RemapDialog::RemapDialog() - : Dialog("remap"), _activeRemap(0), _currentActions(0), _topRow(0) { + : Dialog("remap"), _activeRemapAction(0), _topAction(0) { const int screenW = g_system->getOverlayWidth(); const int screenH = g_system->getOverlayHeight(); @@ -44,32 +44,32 @@ RemapDialog::RemapDialog() assert(_keymapper); _activeKeymaps = &_keymapper->_activeMaps; + + KeymapManager::Domain *_globalKeymaps = &_keymapper->_keymapMan->getGlobalDomain(); + KeymapManager::Domain *_gameKeymaps = 0; int keymapCount = 0; - _globalKeymaps = &_keymapper->_keymapMan->getGlobalDomain(); - if (_globalKeymaps->count() == 0) + if (_globalKeymaps->count() == 0) { _globalKeymaps = 0; - else + } else { keymapCount += _globalKeymaps->count(); + } if (ConfMan.getActiveDomain() != 0) { _gameKeymaps = &_keymapper->_keymapMan->getGameDomain(); - if (_gameKeymaps->count() == 0) + if (_gameKeymaps->count() == 0) { _gameKeymaps = 0; - else + } else { keymapCount += _gameKeymaps->count(); - } else - _gameKeymaps = 0; - + } + } _keymapTable = (Keymap**)malloc(sizeof(Keymap*) * keymapCount); int labelWidth = g_gui.evaluator()->getVar("remap_popup_labelW"); _kmPopUp = new GUI::PopUpWidget(this, "remap_popup", "Keymap: ", labelWidth); - if (_activeKeymaps->size() > 0) { _kmPopUp->appendEntry(_activeKeymaps->top().keymap->getName() + " (Active)"); } KeymapManager::Domain::iterator it; uint32 idx = 0; - if (_globalKeymaps) { _kmPopUp->appendEntry(""); for (it = _globalKeymaps->begin(); it != _globalKeymaps->end(); it++) { @@ -85,31 +85,7 @@ RemapDialog::RemapDialog() } } - int scrollbarWidth; - if (g_gui.getWidgetSize() == GUI::kBigWidgetSize) { - _buttonHeight = GUI::kBigButtonHeight; - scrollbarWidth = GUI::kBigScrollBarWidth; - } else { - _buttonHeight = GUI::kButtonHeight; - scrollbarWidth = GUI::kNormalScrollBarWidth; - } - - _colCount = g_gui.evaluator()->getVar("remap_col_count"); - _spacing = g_gui.evaluator()->getVar("remap_spacing"); - _keymapArea.left = g_gui.evaluator()->getVar("remap_keymap_area.x"); - _keymapArea.top = g_gui.evaluator()->getVar("remap_keymap_area.y"); - _keymapArea.setWidth(g_gui.evaluator()->getVar("remap_keymap_area.w")); - _keymapArea.setHeight(g_gui.evaluator()->getVar("remap_keymap_area.h")); - _colWidth = (_keymapArea.width() - scrollbarWidth - _colCount * _spacing) / _colCount; - _rowCount = (_keymapArea.height() + _spacing) / (_buttonHeight + _spacing); - _keymapArea.setHeight(_rowCount * (_buttonHeight + _spacing) - _spacing); - - _scrollBar = new GUI::ScrollBarWidget(this, - _keymapArea.right - scrollbarWidth, _keymapArea.top, - scrollbarWidth, _keymapArea.height()); - _scrollBar->_entriesPerPage = _rowCount; - _scrollBar->_numEntries = 1; - _scrollBar->recalc(); + setupWidgets(); } RemapDialog::~RemapDialog() { @@ -124,34 +100,37 @@ void RemapDialog::open() { } void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { - if (cmd >= kRemapCmd && cmd < kRemapCmd + _keymapMappings.size()) { - startRemapping(&_keymapMappings[cmd - kRemapCmd]); + if (cmd >= kRemapCmd && cmd < kRemapCmd + _keymapWidgets.size()) { + startRemapping(cmd - kRemapCmd); } else if (cmd == GUI::kPopUpItemSelectedCmd) { loadKeymap(); } else if (cmd == GUI::kSetPositionCmd) { - if (data != _topRow) refreshKeymap(); + refreshKeymap(); } else { GUI::Dialog::handleCommand(sender, cmd, data); } } -void RemapDialog::startRemapping(Mapping *remap) { - _activeRemap = remap; - _activeRemap->keyButton->setLabel("..."); +void RemapDialog::startRemapping(uint i) { + + _activeRemapAction = _currentActions[_topAction + i].action; + _keymapWidgets[i].keyButton->setLabel("..."); + _keymapWidgets[i].keyButton->draw(); + _keymapper->setEnabled(false); } void RemapDialog::stopRemapping() { refreshKeymap(); - _activeRemap = 0; + _activeRemapAction = 0; _keymapper->setEnabled(true); } -void RemapDialog::handleKeyDown(Common::KeyState state) { - if (_activeRemap) { +void RemapDialog::handleKeyUp(Common::KeyState state) { + if (_activeRemapAction) { const HardwareKey *hwkey = _keymapper->getHardwareKey(state); if (hwkey) { - _activeRemap->action->mapKey(hwkey); + _activeRemapAction->mapKey(hwkey); stopRemapping(); } } else { @@ -161,94 +140,135 @@ void RemapDialog::handleKeyDown(Common::KeyState state) { } void RemapDialog::loadKeymap() { + _currentActions.clear(); if (_activeKeymaps->size() > 0 && _kmPopUp->getSelected() == 0) { - // TODO: show active keymaps (with inherited mappings) + List freeKeys (_keymapper->_keymapMan->getHardwareKeySet()->getHardwareKeys()); + + // add most active keymap's keys + Keymapper::MapRecord top = _activeKeymaps->top(); + List::iterator actIt; + for (actIt = top.keymap->getActions().begin(); actIt != top.keymap->getActions().end(); ++actIt) { + Action *act = *actIt; + ActionInfo info = {act, false, act->description}; + _currentActions.push_back(info); + if (act->getMappedKey()) + freeKeys.remove(act->getMappedKey()); + } + + // loop through remaining finding mappings for unmapped keys + if (top.inherit) { + for (int i = _activeKeymaps->size() - 2; i >= 0; --i) { + Keymapper::MapRecord mr = (*_activeKeymaps)[i]; + List::iterator keyIt = freeKeys.begin(); + while (keyIt != freeKeys.end()) { + Action *act = mr.keymap->getMappedAction((*keyIt)->key); + if (act) { + ActionInfo info = {act, true, act->description + " (" + mr.keymap->getName() + ")"}; + _currentActions.push_back(info); + freeKeys.erase(keyIt++); + } else { + ++keyIt; + } + } + if (mr.inherit == false || freeKeys.empty()) break; + } + } + } else if (_kmPopUp->getSelected() != -1) { Keymap *km = _keymapTable[_kmPopUp->getSelectedTag()]; - _currentActions = &km->getActions(); - - int actionCount = _currentActions->size(); - int maxActions = _colCount * _rowCount; - if (actionCount < maxActions) - setupWidgets(actionCount); - else - setupWidgets(maxActions); - - // refresh scroll bar - _scrollBar->_currentPos = 0; - _scrollBar->_numEntries = (actionCount + _colCount - 1) / _colCount; - _scrollBar->recalc(); - _topRow = 0; - _topAction = _currentActions->begin(); - } else { - _currentActions = 0; - setupWidgets(0); + List::iterator it; + for (it = km->getActions().begin(); it != km->getActions().end(); it++) { + ActionInfo info = {*it, false, (*it)->description}; + _currentActions.push_back(info); + } } + // refresh scroll bar + _scrollBar->_currentPos = 0; + _scrollBar->_numEntries = (_currentActions.size() + _colCount - 1) / _colCount; + _scrollBar->recalc(); + // force refresh + _topAction = -1; refreshKeymap(); - } void RemapDialog::refreshKeymap() { - uint newTopRow = _scrollBar->_currentPos; - while (newTopRow < _topRow) { - for (uint i = 0; i < _colCount; i++) - _topAction--; - _topRow--; - } - while (newTopRow > _topRow) { - for (uint i = 0; i < _colCount; i++) - _topAction++; - _topRow++; - } - uint idx = 0; - uint max = _keymapMappings.size(); - List::iterator it; - for (it = _topAction; it != _currentActions->end() && idx < max; it++, idx++) { - Mapping& ma = _keymapMappings[idx]; - ma.action = *it; - ma.actionText->setLabel(ma.action->description + ": "); - const HardwareKey *mappedKey = ma.action->getMappedKey(); - if (mappedKey) - ma.keyButton->setLabel(mappedKey->description); - else - ma.keyButton->setLabel("-"); - _keymapMappings[idx].actionText->clearFlags(GUI::WIDGET_INVISIBLE); - _keymapMappings[idx].keyButton->clearFlags(GUI::WIDGET_INVISIBLE); - } - while (idx < max) { - _keymapMappings[idx].actionText->setFlags(GUI::WIDGET_INVISIBLE); - _keymapMappings[idx].keyButton->setFlags(GUI::WIDGET_INVISIBLE); - idx++; + int newTopAction = _scrollBar->_currentPos * _colCount; + if (newTopAction == _topAction) return; + _topAction = newTopAction; + + //_container->draw(); + _scrollBar->draw(); + + uint widgetI = 0; + uint actionI = _topAction; + for (uint widgetI = 0; widgetI < _keymapWidgets.size(); widgetI++) { + ActionWidgets& widg = _keymapWidgets[widgetI]; + if (actionI < _currentActions.size()) { + ActionInfo& info = _currentActions[actionI]; + widg.actionText->setLabel(info.description + ": "); + widg.actionText->setEnabled(!info.inherited); + const HardwareKey *mappedKey = info.action->getMappedKey(); + if (mappedKey) + widg.keyButton->setLabel(mappedKey->description); + else + widg.keyButton->setLabel("-"); + widg.actionText->clearFlags(GUI::WIDGET_INVISIBLE); + widg.keyButton->clearFlags(GUI::WIDGET_INVISIBLE); + actionI++; + } else { + widg.actionText->setFlags(GUI::WIDGET_INVISIBLE); + widg.keyButton->setFlags(GUI::WIDGET_INVISIBLE); + } + //widg.actionText->draw(); + //widg.keyButton->draw(); } + // need to redraw entire Dialog so that invisible + // widgets disappear draw(); } -void RemapDialog::setupWidgets(uint newNum) { - uint num = _keymapMappings.size(); - if (num == newNum) return; - - uint textYOff = (_buttonHeight - kLineHeight) / 2; - while (num < newNum) { - uint x = _keymapArea.left + (num % _colCount) * (_colWidth + _spacing); - uint y = _keymapArea.top + (num / _colCount) * (_buttonHeight + _spacing); - Mapping ma; - ma.action = 0; - ma.actionText = new GUI::StaticTextWidget(this, x, y + textYOff, - _colWidth / 2, kLineHeight, "", Graphics::kTextAlignRight); - ma.keyButton = new GUI::ButtonWidget(this, x + _colWidth / 2, - y, _colWidth / 2, _buttonHeight, "", kRemapCmd + num); - _keymapMappings.push_back(ma); - num++; +void RemapDialog::setupWidgets() { + + int scrollbarWidth, buttonHeight; + if (g_gui.getWidgetSize() == GUI::kBigWidgetSize) { + buttonHeight = GUI::kBigButtonHeight; + scrollbarWidth = GUI::kBigScrollBarWidth; + } else { + buttonHeight = GUI::kButtonHeight; + scrollbarWidth = GUI::kNormalScrollBarWidth; } - while (num > newNum) { - Mapping ma = _keymapMappings.remove_at(num - 1); - removeWidget(ma.actionText); - delete ma.actionText; - removeWidget(ma.keyButton); - delete ma.keyButton; - num--; + int areaX = g_gui.evaluator()->getVar("remap_keymap_area.x"); + int areaY = g_gui.evaluator()->getVar("remap_keymap_area.y"); + int areaW = g_gui.evaluator()->getVar("remap_keymap_area.w"); + int areaH = g_gui.evaluator()->getVar("remap_keymap_area.h"); + int spacing = g_gui.evaluator()->getVar("remap_spacing"); + + _colCount = g_gui.evaluator()->getVar("remap_col_count"); + _rowCount = (areaH + spacing) / (buttonHeight + spacing); + int colWidth = (areaW - scrollbarWidth - _colCount * spacing) / _colCount; + + //_container = new GUI::ContainerWidget(this, areaX, areaY, areaW, areaH); + //_container->setHints(GUI::THEME_HINT_USE_SHADOW); + + _scrollBar = new GUI::ScrollBarWidget(this, + areaX + areaW - scrollbarWidth, areaY, scrollbarWidth, areaH); + _scrollBar->_entriesPerPage = _rowCount; + _scrollBar->_numEntries = 1; + _scrollBar->recalc(); + + uint textYOff = (buttonHeight - kLineHeight) / 2; + int n = _rowCount * _colCount; + for (int i = 0; i < n; i++) { + uint x = areaX + (i % _colCount) * (colWidth + spacing); + uint y = areaY + (i / _colCount) * (buttonHeight + spacing); + ActionWidgets widg; + widg.actionText = new GUI::StaticTextWidget(this, x, y + textYOff, + colWidth / 2, kLineHeight, "", Graphics::kTextAlignRight); + widg.keyButton = new GUI::ButtonWidget(this, x + colWidth / 2, + y, colWidth / 2, buttonHeight, "", kRemapCmd + i); + _keymapWidgets.push_back(widg); } } diff --git a/backends/keymapper/remap-dialog.h b/backends/keymapper/remap-dialog.h index e1ca809e97..839455e74e 100644 --- a/backends/keymapper/remap-dialog.h +++ b/backends/keymapper/remap-dialog.h @@ -41,44 +41,42 @@ public: virtual ~RemapDialog(); virtual void open(); virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); - virtual void handleKeyDown(Common::KeyState state); + virtual void handleKeyUp(Common::KeyState state); protected: - struct Mapping { - Action *action; + struct ActionWidgets { GUI::StaticTextWidget *actionText; GUI::ButtonWidget *keyButton; }; + struct ActionInfo { + Action *action; + bool inherited; + String description; + }; void loadKeymap(); void refreshKeymap(); - void setupWidgets(uint num); - void startRemapping(Mapping *remap); + void setupWidgets(); + void startRemapping(uint i); void stopRemapping(); Keymapper *_keymapper; Stack *_activeKeymaps; - KeymapManager::Domain *_globalKeymaps; - KeymapManager::Domain *_gameKeymaps; + Keymap** _keymapTable; - List *_currentActions; - List::iterator _topAction; - uint _topRow; + Array _currentActions; + int _topAction; Rect _keymapArea; GUI::PopUpWidget *_kmPopUp; - Keymap** _keymapTable; - + //GUI::ContainerWidget *_container; GUI::ScrollBarWidget *_scrollBar; - uint _colWidth; uint _colCount, _rowCount; - uint _spacing; - uint _buttonHeight; - Mapping *_activeRemap; - Array _keymapMappings; + Array _keymapWidgets; + Action *_activeRemapAction; }; diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp index 1f287bf092..4731ae59c9 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/platform/sdl/events.cpp @@ -533,6 +533,7 @@ void OSystem_SDL::setupKeymapper() { mapper->registerHardwareKeySet(keySet); Keymap *global = new Keymap("global"); + Keymap *specific = new Keymap("specific"); Action *act; Event evt; @@ -549,33 +550,28 @@ void OSystem_SDL::setupKeymapper() { ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0); global->addAction(act); - - act = new Action('QUIY', "Quit", kGenericActionCategory, kQuitAction); - ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0); + act = new Action('MENQ', "Menu", kGenericActionCategory, kMenuAction); + ADD_KEYDOWN_EVENT(KEYCODE_F5, ASCII_F5, 0) global->addAction(act); - - act = new Action('QUIU', "Quit", kGenericActionCategory, kQuitAction); + act = new Action('QUIQ', "Quit", kGenericActionCategory, kQuitAction); ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0); global->addAction(act); + act = new Action('JUMP', "Jump"); + ADD_KEYDOWN_EVENT(KEYCODE_j, 'j', 0); + specific->addAction(act); - act = new Action('QUII', "Quit", kGenericActionCategory, kQuitAction); - ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0); - global->addAction(act); - - - act = new Action('QUIG', "Quit", kGenericActionCategory, kQuitAction); - ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0); - global->addAction(act); - - act = new Action('QUIH', "Quit", kGenericActionCategory, kQuitAction); - ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0); - global->addAction(act); + act = new Action('DUCK', "Duck"); + ADD_KEYDOWN_EVENT(KEYCODE_d, 'd', 0); + specific->addAction(act); #undef ADD_KEYDOWN_EVENT mapper->addGlobalKeymap(global); + mapper->addGlobalKeymap(specific); + mapper->pushKeymap("global"); + mapper->pushKeymap("specific", true); } diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 14668dac11..a8655ef5fd 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -134,6 +134,11 @@ void OSystem_SDL::initBackend() { setupMixer(); } + // Setup the keymapper with backend's set of keys + // NOTE: must be done before creating TimerManager + // to avoid race conditions in creating EventManager + setupKeymapper(); + // Create and hook up the timer manager, if none exists yet (we check for // this to allow subclasses to provide their own). if (_timer == 0) { @@ -148,9 +153,6 @@ void OSystem_SDL::initBackend() { _timerID = SDL_AddTimer(10, &timer_handler, _timer); } - // Provide the keymapper with backend's set of keys - setupKeymapper(); - // Invoke parent implementation of this method OSystem::initBackend(); -- cgit v1.2.3