aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Kennedy2008-08-18 19:54:46 +0000
committerStephen Kennedy2008-08-18 19:54:46 +0000
commit34518951897d5b90d4d345f7f7465b4f86a67ed8 (patch)
tree309ced0bcf2107b821372a57711ed46db4a99528
parent12d649f0113befdb7098962eabb7dd70e194a88b (diff)
downloadscummvm-rg350-34518951897d5b90d4d345f7f7465b4f86a67ed8.tar.gz
scummvm-rg350-34518951897d5b90d4d345f7f7465b4f86a67ed8.tar.bz2
scummvm-rg350-34518951897d5b90d4d345f7f7465b4f86a67ed8.zip
Final changes to keymapper:
* HardwareKey's now have a type too, so that we can either match a key to an action or vice versa. * Better test keymaps - with special gui keymap that is activated when a dialog is opened svn-id: r34005
-rw-r--r--backends/keymapper/action.cpp8
-rw-r--r--backends/keymapper/action.h74
-rw-r--r--backends/keymapper/hardware-key.h20
-rw-r--r--backends/keymapper/keymap.cpp25
-rw-r--r--backends/keymapper/keymapper.cpp6
-rw-r--r--backends/keymapper/types.h71
-rw-r--r--backends/platform/sdl/events.cpp66
-rw-r--r--dists/msvc8/scummvm.vcproj4
-rw-r--r--gui/newgui.cpp4
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