diff options
-rw-r--r-- | backends/keymapper/action.cpp | 8 | ||||
-rw-r--r-- | backends/keymapper/action.h | 74 | ||||
-rw-r--r-- | backends/keymapper/hardware-key.h | 20 | ||||
-rw-r--r-- | backends/keymapper/keymap.cpp | 25 | ||||
-rw-r--r-- | backends/keymapper/keymapper.cpp | 6 | ||||
-rw-r--r-- | backends/keymapper/types.h | 71 | ||||
-rw-r--r-- | backends/platform/sdl/events.cpp | 66 | ||||
-rw-r--r-- | dists/msvc8/scummvm.vcproj | 4 | ||||
-rw-r--r-- | gui/newgui.cpp | 4 |
9 files changed, 181 insertions, 97 deletions
diff --git a/backends/keymapper/action.cpp b/backends/keymapper/action.cpp index f1566a75f2..8b2490861e 100644 --- a/backends/keymapper/action.cpp +++ b/backends/keymapper/action.cpp @@ -28,10 +28,10 @@ namespace Common { -Action::Action(Keymap *boss, const char *i, String des, ActionCategory cat, - ActionType typ, int pri, int grp, int flg) - : _boss(boss), description(des), category(cat), type(typ), - priority(pri), group(grp), flags(flg), _hwKey(0) { +Action::Action(Keymap *boss, const char *i, String des, ActionType typ, + KeyType prefKey, int pri, int flg) + : _boss(boss), description(des), type(typ), preferredKey(prefKey), + priority(pri), flags(flg), _hwKey(0) { assert(i); assert(_boss); diff --git a/backends/keymapper/action.h b/backends/keymapper/action.h index 835ae5007f..ef47930a71 100644 --- a/backends/keymapper/action.h +++ b/backends/keymapper/action.h @@ -26,6 +26,7 @@ #ifndef COMMON_ACTION #define COMMON_ACTION +#include "backends/keymapper/types.h" #include "common/events.h" #include "common/func.h" #include "common/list.h" @@ -36,38 +37,6 @@ namespace Common { struct HardwareKey; class Keymap; - -enum ActionType { - kGenericActionType, - - // common actions - kDirectionUpAction, - kDirectionDownAction, - kDirectionLeftAction, - kDirectionRightAction, - kLeftClickAction, - kRightClickAction, - kSaveAction, - kMenuAction, - kQuitAction, - kVirtualKeyboardAction, - kKeyRemapAction, - kVolumeUpAction, - kVolumeDownAction, - - - kActionTypeMax -}; - -enum ActionCategory { - kGenericActionCategory, - // classes of action - probably need to be slightly more specific than this - kInGameAction, // effects the actual gameplay - kSystemAction, //show a menu / change volume / etc - - kActionCategoryMax -}; - #define ACTION_ID_SIZE (4) struct Action { @@ -78,8 +47,8 @@ struct Action { /** Events to be sent when mapped key is pressed */ List<Event> events; - ActionCategory category; ActionType type; + KeyType preferredKey; int priority; int group; int flags; @@ -91,12 +60,43 @@ private: public: Action(Keymap *boss, const char *id, String des = "", - ActionCategory cat = kGenericActionCategory, ActionType typ = kGenericActionType, - int pri = 0, int grp = 0, int flg = 0 ); + KeyType prefKey = kGenericKeyType, + int pri = 0, int flg = 0 ); + + void addEvent(const Event &evt) { + events.push_back(evt); + } + + void addKeyEvent(const KeyState &ks) { + Event evt; + evt.type = EVENT_KEYDOWN; + evt.kbd = ks; + addEvent(evt); + } + + void addLeftClickEvent() { + Event evt; + evt.type = EVENT_LBUTTONDOWN; + addEvent(evt); + } + + void addMiddleClickEvent() { + Event evt; + evt.type = EVENT_MBUTTONDOWN; + addEvent(evt); + } + + void addRightClickEvent() { + Event evt; + evt.type = EVENT_RBUTTONDOWN; + addEvent(evt); + } + + Keymap *getBoss() { + return _boss; + } - void addEvent(const Event &evt) { events.push_back(evt); } - Keymap *getBoss() { return _boss; } void mapKey(const HardwareKey *key); const HardwareKey *getMappedKey() const; diff --git a/backends/keymapper/hardware-key.h b/backends/keymapper/hardware-key.h index 85badae3cc..082ecfc944 100644 --- a/backends/keymapper/hardware-key.h +++ b/backends/keymapper/hardware-key.h @@ -26,12 +26,12 @@ #ifndef COMMON_HARDWAREKEY #define COMMON_HARDWAREKEY -#include "backends/keymapper/action.h" +#include "backends/keymapper/types.h" namespace Common { -#define HWKEY_ID_SIZE (4) +#define HWKEY_ID_SIZE (4) /** * Describes an available hardware key */ @@ -46,14 +46,12 @@ struct HardwareKey { */ KeyState key; - ActionCategory preferredCategory; - ActionType preferredType; - int16 group; + KeyType type; + ActionType preferredAction; - HardwareKey(const char *i, KeyState ks = KeyState(), String des = "", - ActionCategory cat = kGenericActionCategory, - ActionType ty = kGenericActionType, int gr = 0) - : key(ks), description(des), preferredCategory(cat), preferredType(ty), group(gr) { + HardwareKey(const char *i, KeyState ky = KeyState(), String desc = "", + KeyType typ = kGenericKeyType, ActionType prefAct = kGenericActionType) + : key(ky), description(desc), type(typ), preferredAction(prefAct) { assert(i); strncpy(id, i, HWKEY_ID_SIZE); } @@ -113,8 +111,8 @@ private: void checkForKey(HardwareKey *key) { List<const HardwareKey*>::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); + if (strncmp((*it)->id, key->id, HWKEY_ID_SIZE) == 0) + error("Error adding HardwareKey '%s' - id of %s already in use!", key->description.c_str(), key->id); else if ((*it)->key == key->key) error("Error adding HardwareKey '%s' - key already in use!", key->description.c_str()); } diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp index 904495dc6f..ee07e36485 100644 --- a/backends/keymapper/keymap.cpp +++ b/backends/keymapper/keymap.cpp @@ -48,7 +48,7 @@ Keymap::~Keymap() { void Keymap::addAction(Action *action) { if (findAction(action->id)) - error("Action with id %d already in KeyMap!", action->id); + error("Action with id %s already in KeyMap!", action->id); _actions.push_back(action); } @@ -140,10 +140,12 @@ void Keymap::saveMappings() { List<Action*>::const_iterator it; String prefix = KEYMAP_KEY_PREFIX + _name + "_"; for (it = _actions.begin(); it != _actions.end(); it++) { - uint actIdLen = strnlen((*it)->id, ACTION_ID_SIZE); + uint actIdLen = strlen((*it)->id); + actIdLen = (actIdLen > ACTION_ID_SIZE) ? ACTION_ID_SIZE : actIdLen; String actId((*it)->id, (*it)->id + actIdLen); if ((*it)->getMappedKey()) { - uint hwIdLen = strnlen((*it)->getMappedKey()->id, HWKEY_ID_SIZE); + uint hwIdLen = strlen((*it)->getMappedKey()->id); + hwIdLen = (hwIdLen > HWKEY_ID_SIZE) ? HWKEY_ID_SIZE : hwIdLen; String hwId((*it)->getMappedKey()->id, (*it)->getMappedKey()->id + hwIdLen); _configDomain->setVal(prefix + actId, hwId); } else { @@ -167,9 +169,9 @@ bool Keymap::isComplete(const HardwareKeySet *hwKeys) { } // TODO: -// - current weaknesses: -// - if an action finds a key with required type / category but a parent -// action with higher priority is using it, that key is never used +// - current weakness: +// - 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) { // Create copies of action and key lists. List<Action*> actions(_actions); @@ -196,9 +198,10 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { sort(actions.begin(), actions.end(), priorityComp); // First mapping pass: - // - Match if a key's preferred type or category is same as the action's. + // - Match if a key's preferred action type is the same as the action's + // type, or vice versa. // - Priority is given to: - // - keys that match type over category. + // - keys that match action types over key types. // - keys that have not been used by parent maps. // - If a key has been used by a parent map the new action must have a // higher priority than the parent action. @@ -212,7 +215,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { int matchRank = 0; Action *act = *actIt; for (keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) { - if ((*keyIt)->preferredType == act->type) { + if ((*keyIt)->preferredAction == act->type && act->type != kGenericActionType) { Action *parentAct = getParentMappedAction((*keyIt)->key); if (!parentAct) { selectedKey = keyIt; @@ -221,7 +224,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { selectedKey = keyIt; matchRank = 3; } - } else if ((*keyIt)->preferredCategory == act->category && matchRank < 2) { + } else if ((*keyIt)->type == act->preferredKey && act->preferredKey != kGenericKeyType && matchRank < 2) { Action *parentAct = getParentMappedAction((*keyIt)->key); if (!parentAct) { selectedKey = keyIt; @@ -250,7 +253,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) { // - keys that have no parent action // - keys whose parent action has lower priority than the new action // - keys whose parent action has the lowest priority - // - is guarantees to match a key if one is available + // - is guaranteed to match a key if they are not all used up for (actIt = actions.begin(); actIt != actions.end(); ++actIt) { selectedKey = keys.end(); int matchRank = 0; diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp index acb706c70f..d453a875cc 100644 --- a/backends/keymapper/keymapper.cpp +++ b/backends/keymapper/keymapper.cpp @@ -159,7 +159,6 @@ bool Keymapper::mapKey(const KeyState& key, bool isKeyDown) { List<Event>::iterator it; for (it = action->events.begin(); it != action->events.end(); ++it) { Event evt = *it; - bool pushEvent = true; switch (evt.type) { case EVENT_KEYDOWN: if (!isKeyDown) evt.type = EVENT_KEYUP; @@ -187,9 +186,10 @@ bool Keymapper::mapKey(const KeyState& key, bool isKeyDown) { break; default: // don't deliver other events on key up - if (!isKeyDown) pushEvent = false; + if (!isKeyDown) continue; } - if (pushEvent) _eventMan->pushEvent(evt); + evt.mouse = _eventMan->getMousePos(); + _eventMan->pushEvent(evt); } return true; } diff --git a/backends/keymapper/types.h b/backends/keymapper/types.h new file mode 100644 index 0000000000..8031ab5e38 --- /dev/null +++ b/backends/keymapper/types.h @@ -0,0 +1,71 @@ +/* ScummVM - Graphic Adventure Engine +* +* ScummVM is the legal property of its developers, whose names +* are too numerous to list here. Please refer to the COPYRIGHT +* file distributed with this source distribution. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* $URL$ +* $Id$ +* +*/ + +#ifndef COMMON_TYPES +#define COMMON_TYPES + +namespace Common { + +enum KeyType { + kGenericKeyType, + kDirUpKeyType, + kDirDownKeyType, + kDirLeftKeyType, + kDirRightKeyType, + kActionKeyType, + kTriggerLeftKeyType, + kTriggerRightKeyType, + kStartKeyType, + kSelectKeyType, + /* ... */ + + kKeyTypeMax +}; + +enum ActionType { + kGenericActionType, + + // common actions + kDirUpActionType, + kDirDownActionType, + kDirLeftActionType, + kDirRightActionType, + kLeftClickActionType, + kRightClickActionType, + kSaveActionType, + kMenuActionType, + kQuitActionType, + kVirtualKeyboardActionType, + kKeyRemapActionType, + kVolumeUpActionType, + kVolumeDownActionType, + + + kActionTypeMax +}; + +} // end of namespace Common + +#endif diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp index 94c762f61b..a4863d833b 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/platform/sdl/events.cpp @@ -526,49 +526,55 @@ void OSystem_SDL::setupKeymapper() { Keymapper *mapper = getEventManager()->getKeymapper(); HardwareKeySet *keySet = new HardwareKeySet(); - keySet->addHardwareKey(new HardwareKey( "a", KeyState(KEYCODE_a), "a" )); - keySet->addHardwareKey(new HardwareKey( "s", KeyState(KEYCODE_s), "s" )); - keySet->addHardwareKey(new HardwareKey( "d", KeyState(KEYCODE_d), "d" )); - keySet->addHardwareKey(new HardwareKey( "f", KeyState(KEYCODE_f), "f" )); + keySet->addHardwareKey(new HardwareKey( "a", KeyState(KEYCODE_a), "a", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "s", KeyState(KEYCODE_s), "s", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "d", KeyState(KEYCODE_d), "d", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "f", KeyState(KEYCODE_f), "f", kActionKeyType )); + keySet->addHardwareKey(new HardwareKey( "n", KeyState(KEYCODE_n), "n (vk)", kTriggerLeftKeyType, kVirtualKeyboardActionType )); + keySet->addHardwareKey(new HardwareKey( "m", KeyState(KEYCODE_m), "m (remap)", kTriggerRightKeyType, kKeyRemapActionType )); + keySet->addHardwareKey(new HardwareKey( "[", KeyState(KEYCODE_LEFTBRACKET), "[ (select)", kSelectKeyType )); + keySet->addHardwareKey(new HardwareKey( "]", KeyState(KEYCODE_RIGHTBRACKET), "] (start)", kStartKeyType )); mapper->registerHardwareKeySet(keySet); - Keymap *global = new Keymap("global"); - Keymap *specific = new Keymap("specific"); + Keymap *globalMap = new Keymap("global"); + Keymap *guiMap = new Keymap("gui"); Action *act; - Event evt; + Event evt ; - #define ADD_KEYDOWN_EVENT(kc, asc, flags) \ - evt.type = EVENT_KEYDOWN; \ - evt.kbd = KeyState(kc, asc, flags); \ - act->events.push_back(evt); - - act = new Action(global, "MENU", "Menu", kGenericActionCategory, kMenuAction); - ADD_KEYDOWN_EVENT(KEYCODE_F5, ASCII_F5, 0) + act = new Action(globalMap, "MENU", "Menu", kGenericActionType, kSelectKeyType); + act->addKeyEvent(KeyState(KEYCODE_F5, ASCII_F5, 0)); - act = new Action(global, "SKCT", "Skip"); - ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0); + act = new Action(globalMap, "SKCT", "Skip", kGenericActionType, kActionKeyType); + act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0)); - act = new Action(global, "PAUS", "Pause"); - ADD_KEYDOWN_EVENT(KEYCODE_SPACE, ' ', 0) + act = new Action(globalMap, "PAUS", "Pause", kGenericActionType, kStartKeyType); + act->addKeyEvent(KeyState(KEYCODE_SPACE, ' ', 0)); - act = new Action(global, "SKLI", "Skip line"); - ADD_KEYDOWN_EVENT(Common::KEYCODE_PERIOD, '.', 0); + act = new Action(globalMap, "SKLI", "Skip line", kGenericActionType, kActionKeyType); + act->addKeyEvent(KeyState(KEYCODE_PERIOD, '.', 0)); + + act = new Action(globalMap, "VIRT", "Display keyboard", kVirtualKeyboardActionType); + act->addKeyEvent(KeyState(KEYCODE_F6, ASCII_F6, 0)); + + act = new Action(globalMap, "REMP", "Remap keys", kKeyRemapActionType); + act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0)); + + mapper->addGlobalKeymap(globalMap); - act = new Action(specific, "JUMP", "Jump"); - ADD_KEYDOWN_EVENT(KEYCODE_j, 'j', 0); + act = new Action(guiMap, "CLOS", "Close", kGenericActionType, kStartKeyType); + act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0)); - act = new Action(specific, "DUCK", "Duck"); - ADD_KEYDOWN_EVENT(KEYCODE_d, 'd', 0); + act = new Action(guiMap, "CLIK", "Mouse click"); + act->addLeftClickEvent(); - act = new Action(specific, "RUN_", "Run"); - ADD_KEYDOWN_EVENT(KEYCODE_r, 'r', 0); + act = new Action(guiMap, "VIRT", "Display keyboard", kVirtualKeyboardActionType); + act->addKeyEvent(KeyState(KEYCODE_F6, ASCII_F6, 0)); - #undef ADD_KEYDOWN_EVENT + act = new Action(guiMap, "REMP", "Remap keys", kKeyRemapActionType); + act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0)); - mapper->addGlobalKeymap(global); - mapper->addGlobalKeymap(specific); + mapper->addGlobalKeymap(guiMap); mapper->pushKeymap("global"); - //mapper->pushKeymap("specific", true); } diff --git a/dists/msvc8/scummvm.vcproj b/dists/msvc8/scummvm.vcproj index 2243a9d3a3..e1a872e191 100644 --- a/dists/msvc8/scummvm.vcproj +++ b/dists/msvc8/scummvm.vcproj @@ -1120,6 +1120,10 @@ RelativePath="..\..\backends\keymapper\remap-dialog.h" > </File> + <File + RelativePath="..\..\backends\keymapper\types.h" + > + </File> </Filter> </Filter> <Filter diff --git a/gui/newgui.cpp b/gui/newgui.cpp index 618c7bc873..6c42d8e9b2 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -22,6 +22,7 @@ * $Id$ */ +#include "backends/keymapper/keymapper.h" #include "common/events.h" #include "common/system.h" #include "common/util.h" @@ -235,7 +236,7 @@ void NewGui::runLoop() { } Common::EventManager *eventMan = _system->getEventManager(); - + eventMan->getKeymapper()->pushKeymap("gui"); while (!_dialogStack.empty() && activeDialog == getTopDialog()) { if (_needRedraw) { redraw(); @@ -326,6 +327,7 @@ void NewGui::runLoop() { // Delay for a moment _system->delayMillis(10); } + eventMan->getKeymapper()->popKeymap(); // HACK: since we reopen all dialogs anyway on redraw // we for now use Theme::closeAllDialogs here, until |