Most of Keymapper class complete

DefaultEventManager now initialises Keymapper and passes key press events to it

svn-id: r33227
This commit is contained in:
Stephen Kennedy 2008-07-23 08:45:12 +00:00
parent 0861fa4c00
commit 2f064da102
8 changed files with 177 additions and 14 deletions

View File

@ -1,7 +1,5 @@
#include "backends/common/keymap-manager.h" #include "backends/common/keymap-manager.h"
#define GLOBAL_ID_STR "___GLOBAL"
namespace Common { namespace Common {
@ -36,21 +34,61 @@ Keymap *KeymapManager::Domain::getKeymap(const String& name) {
void KeymapManager::registerDefaultGlobalKeymap(Keymap *map) { void KeymapManager::registerDefaultGlobalKeymap(Keymap *map) {
ConfigManager::Domain *dom = ConfMan.getDomain(ConfigManager::kApplicationDomain);
assert(dom);
initKeymap(dom, "default", map);
_globalDomain.addDefaultKeymap(map); _globalDomain.addDefaultKeymap(map);
} }
void KeymapManager::registerGlobalKeymap(const String& name, Keymap *map) { void KeymapManager::registerGlobalKeymap(const String& name, Keymap *map) {
ConfigManager::Domain *dom = ConfMan.getDomain(ConfigManager::kApplicationDomain);
assert(dom);
initKeymap(dom, name, map);
_globalDomain.addKeymap(name, map); _globalDomain.addKeymap(name, map);
} }
void KeymapManager::registerDefaultGameKeymap(Keymap *map) { void KeymapManager::registerDefaultGameKeymap(Keymap *map) {
ConfigManager::Domain *dom = ConfMan.getActiveDomain();
assert(dom);
initKeymap(dom, "default", map);
_gameDomain.addDefaultKeymap(map); _gameDomain.addDefaultKeymap(map);
} }
void KeymapManager::registerGameKeymap(const String& name, Keymap *map) { void KeymapManager::registerGameKeymap(const String& name, Keymap *map) {
ConfigManager::Domain *dom = ConfMan.getActiveDomain();
assert(dom);
initKeymap(dom, name, map);
_gameDomain.addKeymap(name, map); _gameDomain.addKeymap(name, map);
} }
void KeymapManager::initKeymap(ConfigManager::Domain *domain,
const String& name,
Keymap *map) {
if (!loadKeymap(domain, name, map))
return;
automaticMap(map);
}
bool KeymapManager::loadKeymap(ConfigManager::Domain *domain,
const String& name,
Keymap *map) {
return false;
}
void KeymapManager::saveKeymap(ConfigManager::Domain *domain,
const String& name,
Keymap *map) {
}
void KeymapManager::automaticMap(Keymap *map) {
}
void KeymapManager::unregisterAllGameKeymaps() { void KeymapManager::unregisterAllGameKeymaps() {
_gameDomain.deleteAllKeyMaps(); _gameDomain.deleteAllKeyMaps();
} }

View File

@ -2,6 +2,7 @@
#define COMMON_KEYMAP_MANAGER #define COMMON_KEYMAP_MANAGER
#include "backends/common/keymap.h" #include "backends/common/keymap.h"
#include "common/config-manager.h"
#include "common/hash-str.h" #include "common/hash-str.h"
#include "common/hashmap.h" #include "common/hashmap.h"
@ -13,6 +14,7 @@ public:
class Domain { class Domain {
public: public:
Domain() : _defaultKeymap(0) {} Domain() : _defaultKeymap(0) {}
~Domain() { deleteAllKeyMaps(); }
void addDefaultKeymap(Keymap *map); void addDefaultKeymap(Keymap *map);
void addKeymap(const String& name, Keymap *map); void addKeymap(const String& name, Keymap *map);
@ -42,6 +44,11 @@ public:
private: private:
void initKeymap(ConfigManager::Domain *domain, const String& name, Keymap *keymap);
bool loadKeymap(ConfigManager::Domain *domain, const String& name, Keymap *keymap);
void saveKeymap(ConfigManager::Domain *domain, const String& name, Keymap *keymap);
void automaticMap(Keymap *map);
Domain _globalDomain; Domain _globalDomain;
Domain _gameDomain; Domain _gameDomain;
}; };

View File

@ -71,7 +71,7 @@ const UserAction *Keymap::findUserAction(int32 id) const {
return 0; return 0;
} }
UserAction *Keymap::getMappedAction(KeyState ks) const { UserAction *Keymap::getMappedAction(const KeyState& ks) const {
HashMap<KeyState, UserAction*>::iterator it; HashMap<KeyState, UserAction*>::iterator it;
it = _keymap.find(ks); it = _keymap.find(ks);
if (it == _keymap.end()) if (it == _keymap.end())

View File

@ -69,7 +69,7 @@ public:
* @param key the key that is mapped to the required UserAction * @param key the key that is mapped to the required UserAction
* @return a pointer to the UserAction or 0 if no * @return a pointer to the UserAction or 0 if no
*/ */
UserAction *getMappedAction(KeyState key) const; UserAction *getMappedAction(const KeyState& ks) const;
private: private:

View File

@ -38,11 +38,11 @@ void Keymapper::initGame() {
error("Call to Keymapper::initGame when no game loaded\n"); error("Call to Keymapper::initGame when no game loaded\n");
if (_gameId.size() > 0) if (_gameId.size() > 0)
deInitGame(); cleanupGame();
_gameId = ConfMan.getActiveDomainName(); _gameId = ConfMan.getActiveDomainName();
} }
void Keymapper::deInitGame() { void Keymapper::cleanupGame() {
_keymapMan->unregisterAllGameKeymaps(); _keymapMan->unregisterAllGameKeymaps();
_gameId.clear(); _gameId.clear();
} }
@ -51,11 +51,61 @@ void Keymapper::deInitGame() {
bool Keymapper::switchKeymap(const String& name) { bool Keymapper::switchKeymap(const String& name) {
Keymap *new_map = _keymapMan->getKeymap(name); Keymap *new_map = _keymapMan->getKeymap(name);
if (!new_map) { if (!new_map) {
warning("Keymap '%s' could not be found\n", name.c_str()); warning("Keymap '%s' not registered\n", name.c_str());
return false; return false;
} }
_currentMap = new_map; _currentMap = new_map;
return true; return true;
} }
bool Keymapper::mapKeyDown(const KeyState& key) {
return mapKey(key, true);
}
bool Keymapper::mapKeyUp(const KeyState& key) {
return mapKey(key, false);
}
bool Keymapper::mapKey(const KeyState& key, bool isKeyDown) {
if (!_currentMap) return false;
UserAction *action = _currentMap->getMappedAction(key);
if (!action) return false;
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;
break;
case EVENT_KEYUP:
if (isKeyDown) evt.type = EVENT_KEYDOWN;
break;
case EVENT_LBUTTONDOWN:
if (!isKeyDown) evt.type = EVENT_LBUTTONUP;
break;
case EVENT_LBUTTONUP:
if (isKeyDown) evt.type = EVENT_LBUTTONDOWN;
break;
case EVENT_RBUTTONDOWN:
if (!isKeyDown) evt.type = EVENT_RBUTTONUP;
break;
case EVENT_RBUTTONUP:
if (isKeyDown) evt.type = EVENT_RBUTTONDOWN;
break;
case EVENT_MBUTTONDOWN:
if (!isKeyDown) evt.type = EVENT_MBUTTONUP;
break;
case EVENT_MBUTTONUP:
if (isKeyDown) evt.type = EVENT_MBUTTONDOWN;
break;
default:
// don't deliver other events on key up
if (!isKeyDown) pushEvent = false;
}
if (pushEvent) _eventMan->pushEvent(evt);
}
return true;
}
} // end of namespace Common } // end of namespace Common

View File

@ -13,19 +13,70 @@ public:
Keymapper(EventManager *eventMan); Keymapper(EventManager *eventMan);
/**
* Registers a HardwareKeySet with the Keymapper
* @note should only be called once (during backend initialisation)
*/
void registerHardwareKeySet(HardwareKeySet *keys); void registerHardwareKeySet(HardwareKeySet *keys);
/**
* Get the HardwareKeySet that is registered with the Keymapper
*/
const HardwareKeySet *getHardwareKeySet() const; const HardwareKeySet *getHardwareKeySet() const;
/**
* Add a 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.
* @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);
/**
* Initialise the keymapper for a new game
*/
void initGame(); void initGame();
void deInitGame();
/**
* Cleanup the keymapper after a game has ended
*/
void cleanupGame();
/**
* Switch the active keymap.
* @param name name of the new keymap
* @return true if successful
*/
bool switchKeymap(const String& name); bool switchKeymap(const String& name);
/**
* @brief Map a key press event.
* If the active keymap contains a UserAction mapped to the given key, then
* the UserAction'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
*/
bool mapKey(const KeyState& key, bool isKeyDown);
/**
* @brief Map a key down event.
* @see mapKey
*/
bool mapKeyDown(const KeyState& key);
/**
* @brief Map a key up event.
* @see mapKey
*/
bool mapKeyUp(const KeyState& key);
private: private:
typedef List<HardwareKey*>::iterator Iterator; typedef List<HardwareKey*>::iterator Iterator;

View File

@ -107,6 +107,7 @@ DefaultEventManager::DefaultEventManager(OSystem *boss) :
_eventCount = 0; _eventCount = 0;
_lastEventCount = 0; _lastEventCount = 0;
_lastMillis = 0; _lastMillis = 0;
_artificialEventCounter = 0;
Common::String recordModeString = ConfMan.get("record_mode"); Common::String recordModeString = ConfMan.get("record_mode");
if (recordModeString.compareToIgnoreCase("record") == 0) { if (recordModeString.compareToIgnoreCase("record") == 0) {
@ -193,7 +194,7 @@ DefaultEventManager::DefaultEventManager(OSystem *boss) :
} }
_vk = new Common::VirtualKeyboard(); _vk = new Common::VirtualKeyboard();
_artificialEventCounter = 0; _keyMapper = new Common::Keymapper(this);
} }
DefaultEventManager::~DefaultEventManager() { DefaultEventManager::~DefaultEventManager() {
@ -351,18 +352,32 @@ void DefaultEventManager::processMillis(uint32 &millis) {
bool DefaultEventManager::pollEvent(Common::Event &event) { bool DefaultEventManager::pollEvent(Common::Event &event) {
uint32 time = _boss->getMillis(); uint32 time = _boss->getMillis();
bool result; bool result = false;
// poll for pushed events
if (!_artificialEventQueue.empty()) { if (!_artificialEventQueue.empty()) {
// delay the feeding of artificial events // delay the feeding of artificial events
if (++_artificialEventCounter % kArtificialEventDelay == 0) { if (++_artificialEventCounter % kArtificialEventDelay == 0) {
event = _artificialEventQueue.pop(); event = _artificialEventQueue.pop();
result = true; result = true;
_artificialEventCounter = 0; _artificialEventCounter = 0;
} else }
result = _boss->pollEvent(event); }
} else
// poll for event from backend
if (!result) {
result = _boss->pollEvent(event); result = _boss->pollEvent(event);
if (result) {
// send key press events to keymapper
if (event.type == Common::EVENT_KEYDOWN) {
if (_keyMapper->mapKeyDown(event.kbd))
result = false;
} else if (event.type == Common::EVENT_KEYUP) {
if (_keyMapper->mapKeyUp(event.kbd))
result = false;
}
}
}
if (_recordMode != kPassthrough) { if (_recordMode != kPassthrough) {

View File

@ -29,6 +29,7 @@
#include "common/events.h" #include "common/events.h"
#include "common/queue.h" #include "common/queue.h"
#include "common/savefile.h" #include "common/savefile.h"
#include "backends/common/keymapper.h"
#include "backends/common/virtual-keyboard.h" #include "backends/common/virtual-keyboard.h"
/* /*
@ -47,11 +48,12 @@ class DefaultEventManager : public Common::EventManager {
OSystem *_boss; OSystem *_boss;
Common::VirtualKeyboard *_vk; Common::VirtualKeyboard *_vk;
Common::Keymapper *_keyMapper;
Common::Queue<Common::Event> _artificialEventQueue; Common::Queue<Common::Event> _artificialEventQueue;
int _artificialEventCounter; int _artificialEventCounter;
enum { enum {
kArtificialEventDelay = 10 kArtificialEventDelay = 5
}; };
Common::Point _mousePos; Common::Point _mousePos;