aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorStephen Kennedy2008-08-06 14:21:05 +0000
committerStephen Kennedy2008-08-06 14:21:05 +0000
commit57b13141af10c5e0773c2e1606daca8e08410ed5 (patch)
treea890e33f430cbff65f99a4512058667e4cfb343e /backends
parent1caf48b08435b4077843cb7ebfe14ee45180f8ee (diff)
downloadscummvm-rg350-57b13141af10c5e0773c2e1606daca8e08410ed5.tar.gz
scummvm-rg350-57b13141af10c5e0773c2e1606daca8e08410ed5.tar.bz2
scummvm-rg350-57b13141af10c5e0773c2e1606daca8e08410ed5.zip
Keymapper WIP:
* Implemented stack-based active map in Keymapper * Started proper testing by adding code to OSystem_SDL to set up simple HardwareKeySet and Keymap svn-id: r33660
Diffstat (limited to 'backends')
-rw-r--r--backends/common/action.cpp14
-rw-r--r--backends/common/action.h21
-rw-r--r--backends/common/hardware-key.h23
-rw-r--r--backends/common/keymap-manager.cpp29
-rw-r--r--backends/common/keymap-manager.h5
-rw-r--r--backends/common/keymapper.cpp67
-rw-r--r--backends/common/keymapper.h58
-rw-r--r--backends/events/default/default-events.cpp7
-rw-r--r--backends/events/default/default-events.h4
-rw-r--r--backends/platform/sdl/events.cpp34
-rw-r--r--backends/platform/sdl/sdl.cpp3
-rw-r--r--backends/platform/sdl/sdl.h3
12 files changed, 195 insertions, 73 deletions
diff --git a/backends/common/action.cpp b/backends/common/action.cpp
index d6cb820b73..49d63fafd4 100644
--- a/backends/common/action.cpp
+++ b/backends/common/action.cpp
@@ -28,14 +28,16 @@
namespace Common {
-Action::Action(String des, ActionCategory cat, ActionType ty,
- int pr, int gr, int fl) {
+Action::Action(int32 i, String des,
+ ActionCategory cat, ActionType typ,
+ int pri, int grp, int flg) {
+ id = i;
description = des;
category = cat;
- type = ty;
- priority = pr;
- group = gr;
- flags = fl;
+ type = typ;
+ priority = pri;
+ group = grp;
+ flags = flg;
_hwKey = 0;
_parent = 0;
}
diff --git a/backends/common/action.h b/backends/common/action.h
index a9e9356af8..d9ecb873b3 100644
--- a/backends/common/action.h
+++ b/backends/common/action.h
@@ -49,8 +49,12 @@ enum ActionType {
kRightClickAction,
kSaveAction,
kMenuAction,
+ kQuitAction,
kVirtualKeyboardAction,
- kRemapKeysAction,
+ kKeyRemapAction,
+ kVolumeUpAction,
+ kVolumeDownAction,
+
kActionTypeMax
};
@@ -69,9 +73,9 @@ struct Action {
int32 id;
/** Human readable description */
String description;
+
/** Events to be sent when mapped key is pressed */
List<Event> events;
-
ActionCategory category;
ActionType type;
int priority;
@@ -84,16 +88,17 @@ private:
Keymap *_parent;
public:
- Action( String des = "",
- ActionCategory cat = kGenericActionCategory,
- ActionType ty = kGenericActionType,
- int pr = 0, int gr = 0, int fl = 0 );
+ Action( int32 id,
+ String des = "",
+ ActionCategory cat = kGenericActionCategory,
+ ActionType typ = kGenericActionType,
+ int pri = 0, int grp = 0, int flg = 0 );
+ void addEvent(const Event &evt) { events.push_back(evt); }
void setParent(Keymap *parent);
-
void mapKey(const HardwareKey *key);
-
const HardwareKey *getMappedKey() const;
+
};
struct ActionPriorityComp : public BinaryFunction<Action, Action, bool> {
diff --git a/backends/common/hardware-key.h b/backends/common/hardware-key.h
index 4aba5280bf..1442dbd728 100644
--- a/backends/common/hardware-key.h
+++ b/backends/common/hardware-key.h
@@ -48,14 +48,15 @@ struct HardwareKey {
ActionType preferredType;
int16 group;
- HardwareKey(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(int32 i, KeyState ks = KeyState(), String des = "",
+ ActionCategory cat = kGenericActionCategory,
+ ActionType ty = kGenericActionType, int gr = 0) {
+ id = i;
+ key = ks;
+ description = des;
+ preferredCategory = cat;
+ preferredType = ty;
+ group = gr;
}
};
@@ -69,7 +70,7 @@ class HardwareKeySet {
public:
HardwareKeySet() {}
- ~HardwareKeySet() {
+ virtual ~HardwareKeySet() {
List<HardwareKey*>::iterator it;
for (it = _keys.begin(); it != _keys.end(); it++)
delete *it;
@@ -113,9 +114,9 @@ private:
List<HardwareKey*>::iterator it;
for (it = _keys.begin(); it != _keys.end(); it++) {
if ((*it)->id == key->id)
- error("HardwareKey with id %d already given!", key->id);
+ error("Error adding HardwareKey '%s' - id of %d already in use!", key->description.c_str(), key->id);
else if ((*it)->key == key->key)
- error("HardwareKey with same KeyState already given!");
+ error("Error adding HardwareKey '%s' - key already in use!", key->description.c_str());
}
}
diff --git a/backends/common/keymap-manager.cpp b/backends/common/keymap-manager.cpp
index 7af74f4edc..81a42507c5 100644
--- a/backends/common/keymap-manager.cpp
+++ b/backends/common/keymap-manager.cpp
@@ -28,13 +28,14 @@
namespace Common {
-
-void KeymapManager::Domain::addDefaultKeymap(Keymap *map) {
+void KeymapManager::Domain::setDefaultKeymap(Keymap *map) {
+ delete _defaultKeymap;
_defaultKeymap = map;
}
void KeymapManager::Domain::addKeymap(const String& name, Keymap *map) {
- if (_keymaps.contains(name))
+ KeymapMap::iterator it = _keymaps.find(name);
+ if (it != _keymaps.end())
delete _keymaps[name];
_keymaps[name] = map;
}
@@ -44,6 +45,7 @@ void KeymapManager::Domain::deleteAllKeyMaps() {
for (it = _keymaps.begin(); it != _keymaps.end(); it++)
delete it->_value;
_keymaps.clear();
+ delete _defaultKeymap;
}
Keymap *KeymapManager::Domain::getDefaultKeymap() {
@@ -58,6 +60,15 @@ Keymap *KeymapManager::Domain::getKeymap(const String& name) {
return 0;
}
+KeymapManager::KeymapManager() {
+ _hardwareKeys = 0;
+}
+
+KeymapManager::~KeymapManager() {
+ delete _hardwareKeys;
+}
+
+
void KeymapManager::registerHardwareKeySet(HardwareKeySet *keys) {
if (_hardwareKeys)
error("Hardware key set already registered!");
@@ -68,7 +79,7 @@ void KeymapManager::registerDefaultGlobalKeymap(Keymap *map) {
ConfigManager::Domain *dom = ConfMan.getDomain(ConfigManager::kApplicationDomain);
assert(dom);
initKeymap(dom, "default", map);
- _globalDomain.addDefaultKeymap(map);
+ _globalDomain.setDefaultKeymap(map);
}
void KeymapManager::registerGlobalKeymap(const String& name, Keymap *map) {
@@ -84,7 +95,7 @@ void KeymapManager::registerDefaultGameKeymap(Keymap *map) {
assert(dom);
initKeymap(dom, "default", map);
- _gameDomain.addDefaultKeymap(map);
+ _gameDomain.setDefaultKeymap(map);
}
void KeymapManager::registerGameKeymap(const String& name, Keymap *map) {
@@ -99,8 +110,7 @@ void KeymapManager::initKeymap(ConfigManager::Domain *domain,
const String& name,
Keymap *map) {
if (!loadKeymap(domain, name, map))
- return;
- automaticMap(map);
+ automaticMap(map);
}
bool KeymapManager::loadKeymap(ConfigManager::Domain *domain,
@@ -155,10 +165,9 @@ bool KeymapManager::isMapComplete(const Keymap *map) {
numberMapped++;
} else {
allMapped = false;
- break;
}
}
- return (allMapped || numberMapped == _hardwareKeys->count());
+ return allMapped || (numberMapped == _hardwareKeys->count());
}
void KeymapManager::saveKeymap(ConfigManager::Domain *domain,
@@ -196,7 +205,7 @@ void KeymapManager::automaticMap(Keymap *map) {
if ((*keyIt)->preferredType == act->type) {
selectedKey = keyIt;
break;
- } else if ((*keyIt)->preferredCategory == act->category) {
+ } else if ((*keyIt)->preferredCategory == act->category && selectedKey == keys.end()) {
selectedKey = keyIt;
}
}
diff --git a/backends/common/keymap-manager.h b/backends/common/keymap-manager.h
index cc126c3284..a911bc8d61 100644
--- a/backends/common/keymap-manager.h
+++ b/backends/common/keymap-manager.h
@@ -42,7 +42,7 @@ public:
Domain() : _defaultKeymap(0) {}
~Domain() { deleteAllKeyMaps(); }
- void addDefaultKeymap(Keymap *map);
+ void setDefaultKeymap(Keymap *map);
void addKeymap(const String& name, Keymap *map);
void deleteAllKeyMaps();
@@ -58,6 +58,9 @@ public:
KeymapMap _keymaps;
};
+ KeymapManager();
+ ~KeymapManager();
+
void registerHardwareKeySet(HardwareKeySet *keys);
void registerDefaultGlobalKeymap(Keymap *map);
diff --git a/backends/common/keymapper.cpp b/backends/common/keymapper.cpp
index b31333aebb..70664b80d9 100644
--- a/backends/common/keymapper.cpp
+++ b/backends/common/keymapper.cpp
@@ -24,31 +24,50 @@
*/
#include "backends/common/keymapper.h"
-#include "backends/common/keymap-manager.h"
#include "common/config-manager.h"
namespace Common {
Keymapper::Keymapper(EventManager *evtMgr) {
_eventMan = evtMgr;
_keymapMan = new KeymapManager();
- _currentMap = 0;
+}
+
+Keymapper::~Keymapper() {
+ delete _keymapMan;
}
void Keymapper::registerHardwareKeySet(HardwareKeySet *keys) {
_keymapMan->registerHardwareKeySet(keys);
}
-void Keymapper::addGlobalKeyMap(const String& name, Keymap *keymap) {
+void Keymapper::addGlobalKeymap(const String& name, Keymap *keymap) {
_keymapMan->registerGlobalKeymap(name, keymap);
}
-void Keymapper::addGameKeyMap(const String& name, Keymap *keymap) {
- if (_gameId.size() == 0) {
+void Keymapper::setDefaultGlobalKeymap(Keymap *keymap) {
+ _keymapMan->registerDefaultGlobalKeymap(keymap);
+ pushKeymap(keymap, false);
+}
+
+void Keymapper::addGameKeymap(const String& name, Keymap *keymap) {
+ if (checkGameInit())
+ _keymapMan->registerGameKeymap(name, keymap);
+}
+
+void Keymapper::setDefaultGameKeymap(Keymap *keymap) {
+ if (checkGameInit()) {
+ _keymapMan->registerDefaultGameKeymap(keymap);
+ pushKeymap(keymap, true);
+ }
+}
+
+bool Keymapper::checkGameInit() {
+ if (_gameId.empty()) {
initGame();
- if (_gameId.size() == 0)
- return;
+ if (_gameId.empty())
+ return false;
}
- _keymapMan->registerGameKeymap(name, keymap);
+ return true;
}
void Keymapper::initGame() {
@@ -65,17 +84,28 @@ void Keymapper::cleanupGame() {
_gameId.clear();
}
-
-bool Keymapper::switchKeymap(const String& name) {
- Keymap *new_map = _keymapMan->getKeymap(name);
- if (!new_map) {
+bool Keymapper::pushKeymap(const String& name, bool inherit) {
+ Keymap *newMap = _keymapMan->getKeymap(name);
+ if (!newMap) {
warning("Keymap '%s' not registered", name.c_str());
return false;
}
- _currentMap = new_map;
+ pushKeymap(newMap, inherit);
return true;
}
+void Keymapper::pushKeymap(Keymap *newMap, bool inherit) {
+ MapRecord mr;
+ mr.inherit = inherit;
+ mr.keymap = newMap;
+ _activeMaps.push(mr);
+}
+
+void Keymapper::popKeymap() {
+ if (!_activeMaps.empty())
+ _activeMaps.pop();
+}
+
bool Keymapper::mapKeyDown(const KeyState& key) {
return mapKey(key, true);
}
@@ -85,9 +115,16 @@ bool Keymapper::mapKeyUp(const KeyState& key) {
}
bool Keymapper::mapKey(const KeyState& key, bool isKeyDown) {
- if (!_currentMap) return false;
- Action *action = _currentMap->getMappedAction(key);
+ if (_activeMaps.empty()) return false;
+
+ Action *action = 0;
+ for (int i = _activeMaps.size() - 1; !action && i >= 0; i++) {
+ MapRecord mr = _activeMaps[i];
+ action = mr.keymap->getMappedAction(key);
+ if (mr.inherit == false) break;
+ }
if (!action) return false;
+
List<Event>::iterator it;
for (it = action->events.begin(); it != action->events.end(); it++) {
Event evt = *it;
diff --git a/backends/common/keymapper.h b/backends/common/keymapper.h
index a7d5386171..ff9e476739 100644
--- a/backends/common/keymapper.h
+++ b/backends/common/keymapper.h
@@ -28,19 +28,18 @@
#include "common/events.h"
#include "common/list.h"
-
+#include "common/stack.h"
+#include "backends/common/hardware-key.h"
+#include "backends/common/keymap.h"
+#include "backends/common/keymap-manager.h"
namespace Common {
-struct HardwareKey;
-class HardwareKeySet;
-class KeymapManager;
-class Keymap;
-
class Keymapper {
public:
Keymapper(EventManager *eventMan);
+ ~Keymapper();
/**
* Registers a HardwareKeySet with the Keymapper
@@ -48,19 +47,30 @@ public:
*/
void registerHardwareKeySet(HardwareKeySet *keys);
+
/**
- * Add a keymap to the global domain.
+ * Add a general keymap to the global domain.
* If a saved key setup exists for it in the ini file it will be used.
* Else, the key setup will be automatically mapped.
*/
- void addGlobalKeyMap(const String& name, Keymap *keymap);
+ void addGlobalKeymap(const String& name, Keymap *keymap);
/**
- * Add a keymap to the game domain.
+ * Sets the default keymap for the global domain.
+ */
+ void setDefaultGlobalKeymap(Keymap *keymap);
+
+ /**
+ * Add a general keymap to the game domain.
* @see addGlobalKeyMap
* @note initGame() should be called before any game keymaps are added.
*/
- void addGameKeyMap(const String& name, Keymap *keymap);
+ void addGameKeymap(const String& name, Keymap *keymap);
+
+ /**
+ * Sets the default keymap for the game domain.
+ */
+ void setDefaultGameKeymap(Keymap *keymap);
/**
* Initialise the keymapper for a new game
@@ -73,19 +83,25 @@ public:
void cleanupGame();
/**
- * Switch the active keymap.
- * @param name name of the new keymap
+ * Push a new keymap to the top of the active stack, activating it for use.
+ * @param name name of the keymap to push
+ * @param inherit if true
* @return true if successful
*/
- bool switchKeymap(const String& name);
+ bool pushKeymap(const String& name, bool inherit = false);
+
+ /**
+ * Pop the active keymap off the stack.
+ */
+ void popKeymap();
/**
* @brief Map a key press event.
* If the active keymap contains a Action mapped to the given key, then
* the Action's events are pushed into the EventManager's event queue.
- * @param key key that was pressed
- * @param isKeyDown true for key down, false for key up
- * @return true if key was mapped
+ * @param key key that was pressed
+ * @param isKeyDown true for key down, false for key up
+ * @return true if key was mapped
*/
bool mapKey(const KeyState& key, bool isKeyDown);
@@ -103,6 +119,9 @@ public:
private:
+ void pushKeymap(Keymap *newMap, bool inherit);
+ bool checkGameInit();
+
typedef List<HardwareKey*>::iterator Iterator;
EventManager *_eventMan;
@@ -110,7 +129,12 @@ private:
String _gameId;
- Keymap *_currentMap;
+ struct MapRecord {
+ Keymap* keymap;
+ bool inherit;
+ };
+
+ Stack<MapRecord> _activeMaps;
};
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index fa9ff38330..9bafdd9e4f 100644
--- a/backends/events/default/default-events.cpp
+++ b/backends/events/default/default-events.cpp
@@ -196,10 +196,11 @@ DefaultEventManager::DefaultEventManager(OSystem *boss) :
}
_vk = new Common::VirtualKeyboard();
- _keyMapper = new Common::Keymapper(this);
+ _keymapper = new Common::Keymapper(this);
}
DefaultEventManager::~DefaultEventManager() {
+ delete _keymapper;
delete _vk;
_boss->lockMutex(_timeMutex);
_boss->lockMutex(_recorderMutex);
@@ -372,10 +373,10 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
if (result) {
// send key press events to keymapper
if (event.type == Common::EVENT_KEYDOWN) {
- if (_keyMapper->mapKeyDown(event.kbd))
+ if (_keymapper->mapKeyDown(event.kbd))
result = false;
} else if (event.type == Common::EVENT_KEYUP) {
- if (_keyMapper->mapKeyUp(event.kbd))
+ if (_keymapper->mapKeyUp(event.kbd))
result = false;
}
}
diff --git a/backends/events/default/default-events.h b/backends/events/default/default-events.h
index 2dd3ccc6e2..8e24120ad0 100644
--- a/backends/events/default/default-events.h
+++ b/backends/events/default/default-events.h
@@ -32,7 +32,6 @@
namespace Common {
class VirtualKeyboard;
- class Keymapper;
}
/*
@@ -51,7 +50,7 @@ class DefaultEventManager : public Common::EventManager {
OSystem *_boss;
Common::VirtualKeyboard *_vk;
- Common::Keymapper *_keyMapper;
+ Common::Keymapper *_keymapper;
Common::Queue<Common::Event> _artificialEventQueue;
int _artificialEventCounter;
@@ -130,6 +129,7 @@ public:
virtual int getButtonState() const { return _buttonState; }
virtual int getModifierState() const { return _modifierState; }
virtual int shouldQuit() const { return _shouldQuit; }
+ virtual Common::Keymapper *getKeymapper() { return _keymapper; }
};
#endif
diff --git a/backends/platform/sdl/events.cpp b/backends/platform/sdl/events.cpp
index a4a72ca380..830555e514 100644
--- a/backends/platform/sdl/events.cpp
+++ b/backends/platform/sdl/events.cpp
@@ -24,6 +24,7 @@
*/
#include "backends/platform/sdl/sdl.h"
+#include "backends/common/keymapper.h"
#include "common/util.h"
#include "common/events.h"
@@ -520,3 +521,36 @@ bool OSystem_SDL::remapKey(SDL_Event &ev, Common::Event &event) {
return false;
}
+void OSystem_SDL::setupKeymapper() {
+ using namespace Common;
+ 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" ));
+ mapper->registerHardwareKeySet(keySet);
+
+ Keymap *global = new Keymap();
+ Action *act;
+ 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('MENU', "Menu", kGenericActionCategory, kMenuAction);
+ ADD_KEYDOWN_EVENT(KEYCODE_F5, ASCII_F5, 0)
+ global->addAction(act);
+
+ act = new Action('QUIT', "Quit", kGenericActionCategory, kQuitAction);
+ ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0);
+ global->addAction(act);
+
+ #undef ADD_KEYDOWN_EVENT
+
+ mapper->setDefaultGlobalKeymap(global);
+}
+
diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp
index d8394b5c9c..14668dac11 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -148,6 +148,9 @@ 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();
diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h
index 4ad588f5f5..3fbfa8ba0d 100644
--- a/backends/platform/sdl/sdl.h
+++ b/backends/platform/sdl/sdl.h
@@ -142,6 +142,9 @@ public:
// Returns true if an event was retrieved.
virtual bool pollEvent(Common::Event &event); // overloaded by CE backend
+ // Sets up the keymapper with the backends hardware key set
+ virtual void setupKeymapper();
+
// Set function that generates samples
virtual void setupMixer();
static void mixCallback(void *s, byte *samples, int len);