Ticket #8711: backends-lib.v5.6.patch

File backends-lib.v5.6.patch, 54.9 KB (added by SF/sbatyuk, 13 years ago)

key mapper patch

  • backends/events/default/default-events.cpp

     
    3737        _boss(boss),
    3838        _buttonState(0),
    3939        _modifierState(0),
    40         _shouldQuit(false) {
     40        _shouldQuit(false),
     41        _keyMapper(boss->getKeyMapper()) {
    4142
    4243        assert(_boss);
    4344
     
    4546        _currentKeyDown.keycode = 0;
    4647}
    4748
     49Mapping::KeyMapper *DefaultEventManager::getKeyMapper() {
     50        return _keyMapper;
     51}
     52
    4853bool DefaultEventManager::pollEvent(Common::Event &event) {
    4954        uint32 time = _boss->getMillis();
    5055        bool result;
     
    5257        result = _boss->pollEvent(event);
    5358       
    5459        if (result) {
     60                // check if we have to resolve key mapping
     61                if (_keyMapper) {
     62                        bool isMapped = _keyMapper->resolve(event);
     63                        if (!isMapped) {
     64                                return false;
     65                        }
     66                }
     67
    5568                event.synthetic = false;
    5669                switch (event.type) {
    5770                case Common::EVENT_KEYDOWN:
  • backends/events/default/default-events.h

     
    4848        int _buttonState;
    4949        int _modifierState;
    5050        bool _shouldQuit;
     51        Mapping::KeyMapper *_keyMapper;
    5152
    5253        // for continuous events (keyDown)
    5354        enum {
     
    7071        virtual Common::Point getMousePos() const { return _mousePos; }
    7172        virtual int getButtonState() const { return _buttonState; }
    7273        virtual int getModifierState() const { return _modifierState; }
     74        virtual Mapping::KeyMapper *getKeyMapper();
    7375        virtual int shouldQuit() const { return _shouldQuit; }
    7476};
    7577
  • backends/platform/sdl/sdl.cpp

     
    170170        memset(&_mouseCurState, 0, sizeof(_mouseCurState));
    171171
    172172        _inited = false;
     173
     174        _keyMapper = NULL;
    173175}
    174176
    175177OSystem_SDL::~OSystem_SDL() {
  • backends/platform/sdl/sdl.h

     
    410410        virtual bool remapKey(SDL_Event &ev, Common::Event &event);
    411411
    412412        void handleScalerHotkeys(const SDL_KeyboardEvent &key);
     413
     414        // backend lib methods
     415       
     416private:
     417        Mapping::KeyMapper *_keyMapper;
     418
     419public:
     420        virtual Common::String keyNameResolve(Common::KeyCode key) {
     421                return Common::String(SDL_GetKeyName((SDLKey)key));
     422        }
     423       
     424        virtual Mapping::KeyMapper *getKeyMapper() {
     425                if(_keyMapper == NULL) {
     426                        _keyMapper = new Mapping::KeyMapper();
     427                }
     428                return _keyMapper;
     429        }
    413430};
    414431
    415432#endif
  • backends/platform/common/key-mapper.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11 *
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 */
     22
     23#ifndef COMMON_KEY_MAPPER_H
     24#define COMMON_KEY_MAPPER_H
     25
     26#include "common/hashmap.h"
     27#include "backends/platform/common/gameactions.h"
     28
     29namespace Mapping {
     30
     31typedef Common::HashMap<Common::KeyState, Common::UserAction, Common::KeyState_Hash> KeyActionMap;
     32typedef Common::HashMap<Common::UserAction, Common::KeysList, Common::UserAction_Hash> ActionKeysMap;
     33
     34enum Errors {
     35        NOERRORS = 0,
     36        ACTIONS_WITH_SAME_KEY = 1,
     37        PRIORITY_ERROR = 2,
     38        MEMORY_ALLOCATION_ERROR = 3,
     39        BAD_KEY_MAPPER_VERSION = 4,
     40        SAVE_ERROR = 5,
     41        GAME_NOT_FOUND = 6
     42};
     43
     44/**
     45 * Default key mapper implementation, base class for custom extensions.
     46 */
     47class KeyMapper {
     48
     49public:
     50
     51        KeyMapper();
     52
     53        virtual Mapping::Errors setGame(Common::String domain);
     54
     55        virtual Mapping::Errors editMapping(const Common::KeyState, const Common::UserAction);
     56
     57        virtual Mapping::Errors saveKeyMaps();
     58
     59        virtual Mapping::ActionKeysMap getKeyMaps();
     60
     61        virtual Mapping::ActionKeysMap getDefaultKeyMaps();
     62
     63        virtual Mapping::Errors switchKeyMaps(uint active);
     64
     65        virtual bool enabled();
     66
     67        virtual bool enabled(bool f);
     68
     69        virtual uint getKeyMapsNumber() {return _keyMaps;}
     70
     71        virtual uint32 getCurrentKeyMap() {return _active;}
     72
     73        /**
     74         * Tries to find a corresponding mapping for event.kbd. If successful,
     75         * replaces the event.kbd with a defaultKey from mapped action. If the actionType of
     76         * mapped action type is not Common::ACTION_INVALID, also substitutes the event.actionType.
     77         */
     78        virtual bool resolve(Common::Event &event);
     79
     80private:
     81
     82        Mapping::KeyActionMap _mapKeyAction[Mapping::maxKeyMaps]; // action mappings
     83        Mapping::ActionKeysMap _mapActionKeys[Mapping::maxKeyMaps]; // default action mappings
     84        bool _loaded;
     85        bool _enabled;
     86        bool _error;
     87        uint _active;
     88        uint _keyMaps;
     89        Common::String _domain;
     90        Mapping::gameID _game;
     91        Mapping::Errors loadKeyMaps(bool defaultKeyMaps = false);
     92        bool checkKeyMaps();
     93
     94};
     95} //end namespace Mapping
     96
     97#endif
     98 No newline at end of file
  • backends/platform/common/gameactions.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11 *
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 */
     22
     23#ifndef MAPPING_GAMEACTIONS_H
     24#define MAPPING_GAMEACTIONS_H
     25
     26#include "common/stdafx.h"
     27#include "common/events.h"
     28
     29namespace Mapping {
     30
     31const unsigned int maxKeyMaps = 2;
     32
     33enum engineID {
     34        AGI = 0x0000,
     35        AGOS = 0x0100,
     36        SKY = 0x0200,
     37        UNKNOWN_ENGINE = 0xff00
     38};
     39
     40//first part of 0xffff is engine ID
     41//second part is game ID
     42enum gameID {
     43        game_agi = 0x0000,
     44        game2_agi = 0x0001,
     45        game_agos = 0x0100,
     46        GAME_SKY  = 0x0200,
     47        UNKNOWN_GAME = 0xffff
     48};
     49
     50Mapping::gameID getGameIDFromDomain(Common::String domain);
     51Common::Array<Common::UserAction> mergeUserActions(Common::Array<Common::UserAction> base, Common::Array<Common::UserAction> add);
     52Common::Array<Common::Array<Common::UserAction>> getActions(Mapping::gameID game);
     53int findActionNumber(Common::Array<Common::UserAction> actions, Common::UserAction action);
     54
     55}
     56
     57#endif
     58 No newline at end of file
  • backends/platform/common/module.mk

     
     1MODULE := backends/platform/common
     2
     3MODULE_OBJS := \
     4        key-mapper.o \
     5        gameactions.o
     6
     7MODULE_DIRS += \
     8        backends/platform/common/
     9
     10# We don't use the rules.mk here on purpose
     11OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) $(OBJS)
  • backends/platform/common/gameactions.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11 *
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 */
     22
     23#include "backends/platform/common/gameactions.h"
     24
     25Mapping::gameID Mapping::getGameIDFromDomain(Common::String domain){
     26        if (domain.equals("sky")) {
     27                return Mapping::GAME_SKY;
     28        }
     29        return Mapping::UNKNOWN_GAME;
     30}
     31
     32int Mapping::findActionNumber(Common::Array<Common::UserAction> actions, Common::UserAction action){
     33        Common::Array<Common::UserAction>::const_iterator i;
     34        int c = 0;
     35        for(i = actions.begin();i != actions.end();i++,c++){
     36                if(i->actionType != Common::ACTION_INVALID && i->actionType == action.actionType){
     37                        return c;
     38                }
     39        }
     40        return -1;
     41}
     42
     43Common::Array<Common::UserAction> Mapping::mergeUserActions(Common::Array<Common::UserAction> base, Common::Array<Common::UserAction> add){
     44        Common::Array<Common::UserAction>::const_iterator i;
     45        for(i = add.begin(); i != add.end(); i++) {
     46                if (findActionNumber(base, *i) == -1) {
     47                        base.push_back(*i);
     48                }
     49        }
     50        return base;
     51}
     52
     53Common::Array<Common::Array<Common::UserAction>> Mapping::getActions(Mapping::gameID game){
     54        Common::Array<Common::UserAction> globalActions;
     55        globalActions.push_back(Common::UserAction(Common::KEYCODE_ESCAPE,Common::ACTION_QUIT,"Quit",Common::PRIORITY_CRITICAL));
     56
     57        Common::Array<Common::UserAction> engineActions;
     58        Mapping::engineID engine = (Mapping::engineID)(game & 0xff00);
     59        switch(engine) {
     60                case SKY:
     61                        engineActions.push_back(Common::UserAction(Common::KEYCODE_p,Common::ACTION_INVALID,"Pause",Common::PRIORITY_OPTIONAL));
     62                        engineActions.push_back(Common::UserAction(Common::KEYCODE_s,Common::ACTION_INVALID,"Switch",Common::PRIORITY_OPTIONAL));
     63                        break;
     64        }//end of switch(engine)
     65       
     66        Common::Array<Common::UserAction> gameActions[maxKeyMaps];
     67        switch (game) {
     68                case GAME_SKY:
     69                        gameActions[0].push_back(Common::UserAction(Common::KEYCODE_F5,Common::ACTION_INVALID,"Menu",Common::PRIORITY_PREFERRED));
     70                        gameActions[1].push_back(Common::UserAction(Common::KEYCODE_a,Common::ACTION_INVALID,"Action",Common::PRIORITY_OPTIONAL));
     71                        gameActions[1].push_back(Common::UserAction(Common::KEYCODE_x,Common::ACTION_QUIT,"Quit",Common::PRIORITY_CRITICAL));
     72                        break;
     73        } //end of switch(game)
     74       
     75
     76        Common::Array<Common::Array<Common::UserAction>> actions;
     77        for (int i = 0; !gameActions[i].empty() && i < maxKeyMaps; i++) {
     78                if (!engineActions.empty()) {
     79                        gameActions[i] = mergeUserActions(gameActions[i], engineActions);
     80                }
     81                if (!globalActions.empty()) {
     82                        gameActions[i] = mergeUserActions(gameActions[i], globalActions);
     83                }
     84                actions.push_back(gameActions[i]);
     85        }
     86       
     87        return actions;
     88}
     89 No newline at end of file
  • backends/platform/common/key-mapper.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11 *
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16 *
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 */
     22
     23#include "backends/platform/common/key-mapper.h"
     24#include "common/config-manager.h"
     25
     26#define version 1 // TODO add backend identification here
     27namespace Mapping {
     28KeyMapper::KeyMapper()
     29:_active(0), _loaded(false), _enabled(false), _game(Mapping::UNKNOWN_GAME),
     30        _keyMaps(0), _error(false)
     31{
     32}
     33
     34Mapping::Errors KeyMapper::setGame(Common::String domain) {
     35        _domain = domain;
     36        _game = getGameIDFromDomain(_domain);
     37        if (_game == Mapping::UNKNOWN_GAME){
     38                _error = true;
     39                return Mapping::GAME_NOT_FOUND;
     40        }
     41        loadKeyMaps();
     42        _loaded = true;
     43        _enabled = false;
     44        _active = 0;
     45        return Mapping::NOERRORS;
     46}
     47
     48Mapping::Errors KeyMapper::editMapping(const Common::KeyState key, const Common::UserAction action) {
     49        if (_error){
     50                return Mapping::GAME_NOT_FOUND;
     51        }
     52        if (!_loaded) {
     53                loadKeyMaps();
     54                _loaded = true;
     55        }
     56        if (_mapKeyAction[_active][key] == action) {
     57                return Mapping::NOERRORS;
     58        }
     59        if (key.keycode == Common::KEYCODE_INVALID) {
     60                _mapKeyAction[_active].erase(*_mapActionKeys[_active][action].begin());
     61                _mapActionKeys[_active][action].clear();
     62                _mapActionKeys[_active][action].push_back(key);
     63                return Mapping::NOERRORS;
     64        }
     65        Common::UserAction act = _mapKeyAction[_active][key];
     66        if (_mapKeyAction[_active][key] == Common::UserAction()) {
     67                _mapKeyAction[_active][key] = action;
     68                _mapKeyAction[_active].erase(*_mapActionKeys[_active][action].begin());
     69                _mapActionKeys[_active][action].clear();
     70                _mapActionKeys[_active][action].push_back(key);
     71                return Mapping::NOERRORS;
     72        }
     73        if (_mapKeyAction[_active].contains(key) && !(_mapKeyAction[_active][key] == action)) {
     74                if (action.priority <= _mapKeyAction[_active][key].priority){
     75                        _mapKeyAction[_active].erase(*_mapActionKeys[_active][action].begin());
     76                        _mapActionKeys[_active][_mapKeyAction[_active][key]].clear();
     77                        Common::KeyState ks;
     78                        ks.keycode = Common::KEYCODE_INVALID;
     79                        _mapActionKeys[_active][_mapKeyAction[_active][key]].push_back(ks);
     80                        _mapActionKeys[_active][action].clear();
     81                        _mapActionKeys[_active][action].push_back(key);
     82                        _mapKeyAction[_active][key] = action;
     83                } else {
     84                        return Mapping::PRIORITY_ERROR;
     85                }
     86        }
     87        return Mapping::NOERRORS;
     88}
     89
     90Mapping::Errors KeyMapper::saveKeyMaps() {
     91        if (_error){
     92                return Mapping::GAME_NOT_FOUND;
     93        }
     94        if (!_loaded) {
     95                return Mapping::SAVE_ERROR;
     96        }
     97        if (!checkKeyMaps()){
     98                return Mapping::PRIORITY_ERROR;
     99        }
     100        ConfMan.setInt("action_mapping_version", version, ConfMan.kApplicationDomain);
     101        ConfMan.setInt("keyMaps", _keyMaps, _domain);
     102        for (uint32 i = 0; i < _keyMaps; i++) {
     103                char *tempo = (char *) malloc(_mapKeyAction[i].size() * 15 + 1); // 15 is the size required to write one mapping
     104                if (tempo == NULL) {
     105                        return Mapping::MEMORY_ALLOCATION_ERROR;
     106                }
     107                tempo[0] = '\0';
     108                int c=0;
     109                for (ActionKeysMap::const_iterator mIt = _mapActionKeys[i].begin(); mIt != _mapActionKeys[i].end(); ++mIt) {
     110                        char s[15];
     111                        Common::UserAction ac = mIt->_key;
     112                        Common::KeyState key = *(mIt->_value.begin());
     113                        /*if (mIt->_value == Common::UserAction()) {
     114                                continue;
     115                        }*/
     116                        sprintf(s, "%.4x%.2x,%.4x%.2x;", key.keycode, key.flags, ac.defaultKey.keycode, ac.defaultKey.flags);
     117                        strcat(tempo, s);
     118                        c++;
     119                }
     120                char st[25];
     121                sprintf(st, "%s_%u", "keyMapSize", i);
     122                ConfMan.setInt(Common::String(st), c, _domain);
     123                sprintf(st, "%s_%u", "keyMap", i);
     124                ConfMan.set(Common::String(st), tempo, _domain);
     125                free(tempo);
     126                ConfMan.flushToDisk();
     127        }
     128        return Mapping::NOERRORS;
     129}
     130
     131Mapping::ActionKeysMap KeyMapper::getKeyMaps() {
     132        if (_error){
     133                return Mapping::ActionKeysMap();
     134        }
     135        if (!_loaded) {
     136                        loadKeyMaps();
     137                        _loaded = true;
     138        }
     139        return _mapActionKeys[_active];
     140}
     141
     142Mapping::ActionKeysMap KeyMapper::getDefaultKeyMaps() {
     143        if (_error){
     144                return Mapping::ActionKeysMap();
     145        }
     146        loadKeyMaps(true);
     147        _loaded = true;
     148        _active = 0;
     149        return _mapActionKeys[_active];
     150}
     151
     152Mapping::Errors KeyMapper::switchKeyMaps(uint32 active) {
     153        if (_error){
     154                return Mapping::GAME_NOT_FOUND;
     155        }
     156        if (active < _keyMaps) {
     157                _active = active;
     158        }
     159        return Mapping::NOERRORS;
     160}
     161
     162bool KeyMapper::enabled() {
     163        return _enabled;
     164}
     165
     166bool KeyMapper::enabled(bool enabled) {
     167        if (_error){
     168                return _enabled;
     169        }
     170        return _enabled = enabled;
     171}
     172bool KeyMapper::resolve(Common::Event &event) {
     173        if(_enabled){
     174                if (!_loaded) {
     175                        loadKeyMaps();
     176                        _loaded = true;
     177                }
     178               
     179                bool result = true;
     180                bool keyEvent = (event.type == Common::EVENT_KEYDOWN) || (event.type == Common::EVENT_KEYUP);
     181                if (keyEvent) {
     182                        // FIXME fix hashmap contains method
     183                        // if (_mapKeyAction[_active].contains(event.kbd)) {
     184                        if (!(_mapKeyAction[_active][event.kbd] == Common::UserAction())) {
     185                                event.kbd = _mapKeyAction[_active][event.kbd].defaultKey;
     186                                Common::ActionType actionType = _mapKeyAction[_active][event.kbd].actionType;
     187                                if (actionType != Common::ACTION_INVALID) {
     188                                        event.actionType = actionType;
     189                                }
     190                        } else {
     191                                result = false;
     192                        }
     193                }
     194                return result;
     195        }
     196        return true;
     197}
     198
     199Mapping::Errors KeyMapper::loadKeyMaps(bool defaultKeyMaps) {
     200        if (_loaded) {
     201                for(int i=0; i < maxKeyMaps; i++) {
     202                        _mapKeyAction[i].clear();
     203                        _mapActionKeys[i].clear();
     204                }
     205                _keyMaps = 0;
     206        }
     207
     208        Common::Array<Common::Array<Common::UserAction>> actions;
     209        actions = getActions(_game);
     210        Common::Array<Common::Array<Common::UserAction>>::iterator i;
     211        for (i = actions.begin(); i != actions.end(); i++) {
     212                Common::Array<Common::UserAction>::iterator j;
     213                for (j = i->begin(); j != i->end(); j++) {
     214                        _mapKeyAction[_keyMaps][j->defaultKey] = *j;
     215                        _mapActionKeys[_keyMaps][*j].push_back(j->defaultKey);
     216                }
     217                if (!i->empty()) {
     218                        _keyMaps++;
     219                }
     220        }
     221
     222
     223        int current_version = ConfMan.getInt("action_mapping_version", ConfMan.kApplicationDomain);
     224        if (!defaultKeyMaps && current_version != 0){
     225               
     226                if (current_version != version) {
     227                        return BAD_KEY_MAPPER_VERSION;
     228                }
     229
     230                _keyMaps = ConfMan.getInt("keyMaps", _domain);
     231                if (_keyMaps != 0 && _keyMaps <= maxKeyMaps) {
     232                        int size = 0;
     233                        for (uint32 kMap = 0; kMap < _keyMaps; kMap++){
     234                                // clear current mappings
     235                                _mapKeyAction[kMap].clear();
     236                                Common::List<Common::UserAction> list;
     237                                for (ActionKeysMap::const_iterator mIt = _mapActionKeys[kMap].begin(); mIt != _mapActionKeys[kMap].end(); ++mIt) {
     238                                        list.push_back(mIt->_key);
     239                                }
     240                                for (Common::List<Common::UserAction>::iterator it = list.begin(); it != list.end(); ++it) {
     241                                        _mapActionKeys[kMap][*it].clear();
     242                                }
     243                                char st[25];
     244                                sprintf(st, "%s_%u", "keyMapSize", kMap);
     245                                size = ConfMan.getInt(Common::String(st), _domain);
     246                                sprintf(st, "%s_%u", "keyMap", kMap);
     247                                const char *tempo = ConfMan.get(st, _domain).c_str();
     248                                if (tempo && strlen(tempo)) {
     249                                        for (int i = 0; i < size; i++) {
     250                                                char x[4];
     251                                                int offset = 14 * i;
     252                                                uint32 buf;
     253                                                Common::KeyState key;
     254                                                Common::KeyState defaultKey;
     255
     256                                                memset(x, 0, sizeof(uint32));
     257                                                memcpy(x, tempo + offset, 4);
     258                                                sscanf(x, "%x", &buf);
     259                                                key.keycode = (Common::KeyCode) buf;
     260
     261                                                memset(x, 0, sizeof(uint32));
     262                                                memcpy(x, tempo + offset + 4, 2);
     263                                                sscanf(x, "%x", &buf);
     264                                                key.flags = (byte) buf;
     265
     266                                                // TODO write comment
     267                                                /*if (_mapKeyAction[kMap].contains(key)) {
     268                                                        continue;
     269                                                }*/
     270
     271                                                memset(x, 0, sizeof(uint32));
     272                                                memcpy(x, tempo + offset + 7, 4);
     273                                                sscanf(x, "%x", &buf);
     274                                                defaultKey.keycode = (Common::KeyCode) buf;
     275
     276                                                memset(x, 0, sizeof(uint32));
     277                                                memcpy(x, tempo + offset + 11, 2);
     278                                                sscanf(x, "%x", &buf);
     279                                                defaultKey.flags = (byte) buf;
     280
     281                                                // TODO can actions have the same default keys? here it is assumed that they can not
     282                                                Common::UserAction action;
     283                                                for (ActionKeysMap::const_iterator mIt = _mapActionKeys[kMap].begin(); mIt != _mapActionKeys[kMap].end(); ++mIt) {
     284                                                        if (mIt->_key.defaultKey == defaultKey) {
     285                                                                action = mIt->_key;
     286                                                                break;
     287                                                        }
     288                                                }
     289                                                _mapKeyAction[kMap][key] = action;
     290                                                _mapActionKeys[kMap][action].push_back(key);
     291                                        }
     292                                }
     293                        }
     294               
     295                }
     296        }
     297
     298        return Mapping::NOERRORS;
     299}
     300
     301bool KeyMapper::checkKeyMaps() {
     302        bool emptyCritical = false;
     303        bool emptyPreferred = false;
     304        bool emptyOptional = false;
     305        Mapping::ActionKeysMap::const_iterator i;
     306        for (uint kMap = 0; kMap < _keyMaps; kMap++){
     307                for (i = _mapActionKeys[kMap].begin(); i != _mapActionKeys[kMap].end(); ++i) {
     308                        if (i->_value.begin()->keycode == Common::KEYCODE_INVALID) {
     309                                switch (i->_key.priority) {
     310                                        case Common::PRIORITY_CRITICAL:
     311                                                emptyCritical = true;                   
     312                                                break;
     313                                        case Common::PRIORITY_OPTIONAL:
     314                                                emptyPreferred = true;
     315                                                break;
     316                                        case Common::PRIORITY_PREFERRED:
     317                                                emptyOptional = true;
     318                                                break;
     319
     320                                }
     321                        }
     322                }
     323                if (emptyCritical && (!emptyOptional || !emptyPreferred)) {
     324                        return false;
     325                }
     326                if (emptyOptional && !emptyPreferred) {
     327                        return false;
     328                }
     329        }
     330        return true;
     331}
     332
     333} //end namespace Mapping
     334 No newline at end of file
  • common/event-manager.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 */
     22
     23#ifndef COMMON_EVENT_MANAGER_H
     24#define COMMON_EVENT_MANAGER_H
     25
     26#include "common/events.h"
     27#include "backends/platform/common/key-mapper.h"
     28
     29namespace Common {
     30
     31/**
     32 * The EventManager provides user input events to the client code.
     33 * In addition, it keeps track of the state of various input devices,
     34 * like keys, mouse position and buttons.
     35 */
     36class EventManager : NonCopyable {
     37public:
     38        EventManager() {}
     39        virtual ~EventManager() {}
     40       
     41        enum {
     42                LBUTTON = 1 << 0,
     43                RBUTTON = 1 << 1
     44        };
     45
     46        /**
     47         * Get the next event in the event queue.
     48         * @param event point to an Event struct, which will be filled with the event data.
     49         * @return true if an event was retrieved.
     50         */
     51        virtual bool pollEvent(Common::Event &event) = 0;
     52
     53
     54        /** Return the current key state */
     55        virtual Common::Point getMousePos() const = 0;
     56       
     57        /**
     58         * Return a bitmask with the button states:
     59         * - bit 0: left button up=1, down=0
     60         * - bit 1: right button up=1, down=0
     61         */
     62        virtual int getButtonState() const = 0;
     63       
     64        /** Get a bitmask with the current modifier state */
     65        virtual int getModifierState() const = 0;
     66
     67        /**
     68         * Should the application terminate? Set to true if we
     69         * received an EVENT_QUIT.
     70         */
     71        virtual int shouldQuit() const = 0;
     72       
     73        // Optional: check whether a given key is currently pressed ????
     74        //virtual bool isKeyPressed(int keycode) = 0;
     75
     76        // TODO: Keyboard repeat support?
     77       
     78        // TODO: Consider removing OSystem::getScreenChangeID and
     79        // replacing it by a generic getScreenChaneID method here
     80
     81        virtual Mapping::KeyMapper *getKeyMapper() = 0;
     82};
     83
     84} // End of namespace Common
     85
     86#endif
     87 No newline at end of file
  • common/keyboard.h

     
    2727#define COMMON_KEYBOARD_H
    2828
    2929#include "common/scummsys.h"
     30#include "common/list.h"
    3031
    3132namespace Common {
    3233
     
    259260                keycode = KEYCODE_INVALID;
    260261                ascii = flags = 0;
    261262        }
     263
     264        bool operator <(const KeyState keyState) const {
     265                bool result;
     266                if (keycode != keyState.keycode) {
     267                        result = keycode < keyState.keycode;
     268                } else {
     269                        result = flags < keyState.flags;
     270                }
     271
     272                return result;
     273        }
     274
     275        bool operator ==(const KeyState keyState) const {
     276                return (keycode == keyState.keycode) && (flags == keyState.flags);
     277        }
     278
     279        uint hash() const {
     280                uint hash = 7;
     281                hash = hash * 31 + keycode;
     282                hash = hash * 31 + flags;
     283                return hash;
     284        }
    262285};
    263286
     287typedef Common::List<Common::KeyState> KeysList;
     288
     289struct KeyState_Hash {
     290        uint operator()(const KeyState& ks) const { return ks.hash(); }
     291};
    264292} // End of namespace Common
    265293
    266294#endif
  • common/system.h

     
    3030#include "common/mutex.h"
    3131#include "common/noncopyable.h"
    3232#include "common/rect.h"
     33#include "common/event-manager.h"
     34#include "common/keyboard.h"
     35#include "backends/platform/common/key-mapper.h"
    3336
    3437namespace Audio {
    3538        class Mixer;
     
    733736         */
    734737        virtual Common::EventManager *getEventManager();
    735738
     739        virtual Mapping::KeyMapper *getKeyMapper() { return NULL; }
     740
    736741        //@}
    737742
    738743
     
    885890         */
    886891        virtual Common::SaveFileManager *getSavefileManager() = 0;
    887892
     893        virtual Common::String keyNameResolve(Common::KeyCode key){
     894                return "";
     895        }
    888896        //@}
    889897};
    890898
  • common/events.h

     
    2828
    2929#include "common/keyboard.h"
    3030#include "common/rect.h"
    31 #include "common/system.h"
    3231#include "common/noncopyable.h"
    3332
     33#include "common/list.h"
     34
    3435namespace Common {
    3536
     37
     38enum ActionType {
     39
     40        ACTION_INVALID = 0,
     41        ACTION_QUIT = 1,
     42        ACTION_SAVE = 2,
     43        ACTION_LOAD = 3
     44
     45};
     46
    3647/**
    3748 * The types of events backends may generate.
    3849 * @see Event
     
    115126         * screen area as defined by the most recent call to initSize().
    116127         */
    117128        Common::Point mouse;
     129        /**
     130         * Event type like quit, save/load, etc.
     131         */
     132        Common::ActionType actionType;
    118133};
    119134
    120135
    121 /**
    122  * The EventManager provides user input events to the client code.
    123  * In addition, it keeps track of the state of various input devices,
    124  * like keys, mouse position and buttons.
    125  */
    126 class EventManager : NonCopyable {
    127 public:
    128         EventManager() {}
    129         virtual ~EventManager() {}
    130        
    131         enum {
    132                 LBUTTON = 1 << 0,
    133                 RBUTTON = 1 << 1
    134         };
     136enum Priority {
     137        PRIORITY_CRITICAL = 1,
     138        PRIORITY_PREFERRED = 2,
     139        PRIORITY_OPTIONAL = 3
     140};
    135141
     142
     143struct UserAction {
     144
    136145        /**
    137          * Get the next event in the event queue.
    138          * @param event point to an Event struct, which will be filled with the event data.
    139          * @return true if an event was retrieved.
     146         * Default key used in the egines an games for this action.
    140147         */
    141         virtual bool pollEvent(Common::Event &event) = 0;
     148        Common::KeyState defaultKey;
    142149
     150        /**
     151         * Event type like quit, save/load, etc.
     152         */
     153        Common::ActionType actionType;
    143154
    144         /** Return the current key state */
    145         virtual Common::Point getMousePos() const = 0;
    146        
    147155        /**
    148          * Return a bitmask with the button states:
    149          * - bit 0: left button up=1, down=0
    150          * - bit 1: right button up=1, down=0
     156         * Human readable description for a GUI keymapping config dialog
    151157         */
    152         virtual int getButtonState() const = 0;
    153        
    154         /** Get a bitmask with the current modifier state */
    155         virtual int getModifierState() const = 0;
     158        String description;
    156159
    157160        /**
    158          * Should the application terminate? Set to true if we
    159          * received an EVENT_QUIT.
     161         * Mapping priority. Actions with higher priority will be given preference for mapping
     162         * in case of limited inputs.
    160163         */
    161         virtual int shouldQuit() const = 0;
    162        
    163         // Optional: check whether a given key is currently pressed ????
    164         //virtual bool isKeyPressed(int keycode) = 0;
     164        Common::Priority priority;
    165165
    166         // TODO: Keyboard repeat support?
    167        
    168         // TODO: Consider removing OSystem::getScreenChangeID and
    169         // replacing it by a generic getScreenChangeID method here
     166        UserAction(Common::KeyState ks = Common::KeyState(Common::KEYCODE_ESCAPE),
     167                Common::ActionType at = Common::ACTION_INVALID,
     168                String d = "Action name", Common::Priority p = Common::PRIORITY_OPTIONAL) {
     169               
     170                defaultKey = ks;
     171                actionType = at;
     172                description = d;
     173                priority = p;
     174        }
     175
     176        UserAction(Common::KeyState ks, String d, Common::Priority p = Common::PRIORITY_OPTIONAL) {
     177                defaultKey = ks;
     178                actionType = Common::ACTION_INVALID;
     179                description = d;
     180                priority = p;
     181        }
     182
     183        bool operator ==(const UserAction action) const {
     184                return (defaultKey == action.defaultKey) && (actionType == action.actionType) && (description == action.description);
     185        }
     186
     187        bool operator <(const UserAction action) const {
     188                return priority < action.priority;
     189        }
     190
     191        uint hash() const {
     192                uint hash = 7;
     193                hash = hash * 31 + defaultKey.hash();
     194                hash = hash * 31 + actionType;
     195                hash = hash * 31 + description.hash();
     196                hash = hash * 31 + priority;
     197                return hash;
     198        }
     199
    170200};
    171201
     202struct UserAction_Hash {
     203        uint operator()(const UserAction& ua) const { return ua.hash(); }
     204};
     205
     206typedef Common::List<Common::UserAction> ActionList;
     207
     208
    172209} // End of namespace Common
    173210
    174211#endif
  • engines/sword1/sword1.cpp

     
    3131#include "common/file.h"
    3232#include "common/fs.h"
    3333#include "common/timer.h"
    34 #include "common/events.h"
     34#include "common/event-manager.h"
    3535#include "common/system.h"
    3636
    3737#include "sword1/resman.h"
  • engines/sword1/credits.cpp

     
    3535
    3636#include "common/file.h"
    3737#include "common/util.h"
    38 #include "common/events.h"
     38#include "common/event-manager.h"
    3939#include "common/system.h"
    4040
    4141
  • engines/sword1/animation.cpp

     
    3434#include "common/config-manager.h"
    3535#include "common/endian.h"
    3636#include "common/str.h"
    37 #include "common/events.h"
     37#include "common/event-manager.h"
    3838#include "common/system.h"
    3939
    4040namespace Sword1 {
  • engines/sword1/control.cpp

     
    2727#include "common/file.h"
    2828#include "common/util.h"
    2929#include "common/savefile.h"
    30 #include "common/events.h"
     30#include "common/event-manager.h"
    3131#include "common/system.h"
    3232
    3333#include "gui/message.h"
  • engines/sword2/animation.cpp

     
    2828#include "common/stdafx.h"
    2929#include "common/config-manager.h"
    3030#include "common/file.h"
    31 #include "common/events.h"
     31#include "common/event-manager.h"
    3232#include "common/system.h"
    3333
    3434#include "sword2/sword2.h"
  • engines/scumm/input.cpp

     
    2626#include "common/stdafx.h"
    2727
    2828#include "common/config-manager.h"
    29 #include "common/events.h"
     29#include "common/event-manager.h"
    3030#include "common/system.h"
    3131
    3232#include "gui/message.h"
  • engines/touche/touche.cpp

     
    2525
    2626#include "common/stdafx.h"
    2727#include "common/config-manager.h"
    28 #include "common/events.h"
     28#include "common/event-manager.h"
    2929#include "common/system.h"
    3030
    3131#include "graphics/cursorman.h"
  • engines/touche/ui.cpp

     
    2424 */
    2525
    2626#include "common/stdafx.h"
    27 #include "common/events.h"
     27#include "common/event-manager.h"
    2828#include "common/system.h"
    2929#include "common/savefile.h"
    3030
  • engines/agos/cursor.cpp

     
    2525
    2626#include "common/stdafx.h"
    2727
    28 #include "common/events.h"
     28#include "common/event-manager.h"
    2929#include "common/system.h"
    3030
    3131#include "graphics/cursorman.h"
  • engines/agos/event.cpp

     
    2929#include "agos/debugger.h"
    3030#include "agos/intern.h"
    3131
    32 #include "common/events.h"
     32#include "common/event-manager.h"
    3333#include "common/system.h"
    3434
    3535#include "gui/about.h"
  • engines/agos/animation.cpp

     
    2626#include "common/stdafx.h"
    2727
    2828#include "common/endian.h"
    29 #include "common/events.h"
     29#include "common/event-manager.h"
    3030#include "common/system.h"
    3131
    3232#include "graphics/cursorman.h"
  • engines/cruise/cruise_main.cpp

     
    2525
    2626#include "common/stdafx.h"
    2727#include "common/endian.h"
    28 #include "common/events.h"
     28#include "common/event-manager.h"
     29#include "common/system.h"
    2930
    3031#include "cruise/cruise_main.h"
    3132#include "cruise/cell.h"
  • engines/drascula/drascula.cpp

     
    2525
    2626#include "common/stdafx.h"
    2727
    28 #include "common/events.h"
     28#include "common/event-manager.h"
    2929#include "common/keyboard.h"
    3030#include "common/file.h"
    3131#include "common/savefile.h"
  • engines/kyra/kyra.cpp

     
    2626#include "common/stdafx.h"
    2727
    2828#include "common/config-manager.h"
     29#include "common/event-manager.h"
    2930
    3031#include "sound/mididrv.h"
    3132#include "sound/mixer.h"
  • engines/kyra/vqa.cpp

     
    3232// The jung2.vqa movie does work, but only thanks to a grotesque hack.
    3333
    3434#include "common/stdafx.h"
    35 #include "common/events.h"
     35#include "common/event-manager.h"
    3636#include "common/system.h"
    3737#include "sound/audiostream.h"
    3838#include "sound/mixer.h"
  • engines/kyra/text_v1.cpp

     
    2929#include "kyra/animator_v1.h"
    3030#include "kyra/sprites.h"
    3131#include "kyra/timer.h"
     32#include "common/event-manager.h"
    3233
    3334namespace Kyra {
    3435
  • engines/kyra/sequences_v1.cpp

     
    3434#include "kyra/text.h"
    3535#include "kyra/timer.h"
    3636
    37 #include "common/events.h"
     37#include "common/event-manager.h"
    3838#include "common/system.h"
    3939#include "common/savefile.h"
    4040
  • engines/kyra/kyra.h

     
    3030#include "common/rect.h"
    3131#include "common/array.h"
    3232#include "common/events.h"
     33#include "common/system.h"
    3334
    3435#include "kyra/util.h"
    3536
  • engines/kyra/kyra_v1.cpp

     
    2626#include "kyra/kyra_v1.h"
    2727
    2828#include "common/file.h"
    29 #include "common/events.h"
     29#include "common/event-manager.h"
    3030#include "common/system.h"
    3131#include "common/savefile.h"
    3232
  • engines/kyra/kyra_v2.cpp

     
    3434#include "kyra/timer.h"
    3535
    3636#include "common/system.h"
     37#include "common/event-manager.h"
    3738
    3839namespace Kyra {
    3940
  • engines/kyra/gui_v1.cpp

     
    3232
    3333#include "common/config-manager.h"
    3434#include "common/savefile.h"
    35 #include "common/events.h"
     35#include "common/event-manager.h"
    3636#include "common/system.h"
    3737
    3838namespace Kyra {
  • engines/kyra/gui_v2.cpp

     
    2626#include "kyra/kyra.h"
    2727#include "kyra/kyra_v2.h"
    2828#include "kyra/screen.h"
     29#include "common/event-manager.h"
    2930
    3031namespace Kyra {
    3132
  • engines/sky/mouse.cpp

     
    2424 */
    2525
    2626#include "common/stdafx.h"
    27 #include "common/events.h"
     27#include "common/event-manager.h"
    2828#include "common/system.h"
    2929#include "graphics/cursorman.h"
    3030#include "sky/disk.h"
  • engines/sky/intro.cpp

     
    2626#include "common/stdafx.h"
    2727#include "common/endian.h"
    2828#include "common/util.h"
    29 #include "common/events.h"
     29#include "common/event-manager.h"
    3030#include "common/system.h"
    3131
    3232#include "sky/disk.h"
  • engines/sky/sky.cpp

     
    3030#include "common/config-manager.h"
    3131#include "common/file.h"
    3232#include "common/fs.h"
    33 #include "common/events.h"
     33#include "common/event-manager.h"
    3434#include "common/system.h"
    3535#include "common/timer.h"
    3636
     
    217217
    218218void SkyEngine::handleKey(void) {
    219219
     220        if (_keyPressed.keycode == Common::KEYCODE_s) {
     221                uint current = _system->getKeyMapper()->getCurrentKeyMap();
     222                uint kMaps = _system->getKeyMapper()->getKeyMapsNumber();
     223                current = ++current % kMaps;
     224                _system->getKeyMapper()->switchKeyMaps(current);
     225        }
     226
    220227        if (_keyPressed.keycode && _systemVars.paused) {
    221228                _skySound->fnUnPauseFx();
    222229                _systemVars.paused = false;
  • engines/sky/screen.cpp

     
    2525
    2626#include "common/stdafx.h"
    2727#include "common/endian.h"
    28 #include "common/events.h"
     28#include "common/event-manager.h"
    2929#include "common/system.h"
    3030
    3131#include "sky/disk.h"
  • engines/sky/control.cpp

     
    2727#include "common/endian.h"
    2828#include "common/config-manager.h"
    2929#include "common/file.h"
    30 #include "common/events.h"
     30#include "common/event-manager.h"
    3131#include "common/system.h"
    3232#include "common/savefile.h"
    3333#include "common/util.h"
  • engines/gob/util.cpp

     
    2424 */
    2525
    2626#include "common/stdafx.h"
    27 #include "common/events.h"
     27#include "common/event-manager.h"
    2828
    2929#include "gob/gob.h"
    3030#include "gob/util.h"
  • engines/lure/events.cpp

     
    2424 */
    2525
    2626#include "common/stdafx.h"
    27 #include "common/events.h"
     27#include "common/event-manager.h"
    2828
    2929#include "graphics/cursorman.h"
    3030
  • engines/parallaction/parallaction.cpp

     
    2727
    2828#include "common/config-manager.h"
    2929#include "common/events.h"
     30#include "common/system.h"
    3031#include "common/file.h"
    3132#include "common/util.h"
    3233
  • engines/saga/input.cpp

     
    3333#include "saga/script.h"
    3434#include "saga/isomap.h"
    3535
    36 #include "common/events.h"
     36#include "common/event-manager.h"
    3737#include "common/system.h"
    3838
    3939namespace Saga {
  • engines/saga/ihnm_introproc.cpp

     
    3838
    3939#include "saga/scene.h"
    4040
    41 #include "common/events.h"
     41#include "common/event-manager.h"
     42#include "common/system.h"
    4243
    4344namespace Saga {
    4445
  • engines/queen/input.h

     
    2828
    2929#include "common/util.h"
    3030#include "common/rect.h"
    31 #include "common/events.h"
     31#include "common/event-manager.h"
    3232#include "queen/defs.h"
    3333
    3434class OSystem;
  • engines/queen/journal.cpp

     
    2424 */
    2525
    2626#include "common/stdafx.h"
    27 #include "common/events.h"
     27#include "common/event-manager.h"
    2828#include "common/system.h"
    2929#include "queen/journal.h"
    3030
  • engines/cine/main_loop.cpp

     
    2525
    2626#include "common/stdafx.h"
    2727#include "common/scummsys.h"
    28 #include "common/events.h"
     28#include "common/event-manager.h"
    2929#include "common/system.h"
    3030
    3131#include "cine/main_loop.h"
  • gui/themes/modern.ini

     Index: gui/themes/modern.ini
     
    333333gameoptions_platform=prev.x opYoffset prev.w prev.h
    334334opYoffset=(opYoffset + prev.h + ySeparation)
    335335
     336# keys tab
     337KeyInputDialog=180 150 250 30
     338KeyInput=10 7 250 30
     339gameoptions_defaultkeys=(parent.w - buttonWidth - 10) 10 buttonWidth buttonHeight
     340gameoptions_switchkey=prev.x (prev.y2 + 10) prev.w prev.h
     341gameoptions_clearkey=prev.x (prev.y2 + 10) prev.w prev.h
     342gameoptions_actionslist=10 10 (parent.w - buttonWidth - 3 * 10) (parent.h - 3 * buttonHeight - 2 * 10)
     343
    336344# paths tab
    337345opYoffset=optionsVPad
    338346goOff=((buttonHeight - kLineHeight) / 2 + 2)
  • gui/themes/classic080.ini

     
    171171gameoptions_platform=prev.x opYoffset prev.w prev.h
    172172opYoffset=(opYoffset + prev.h + 5)
    173173
     174# keys tab
     175KeyInputDialog=180 150 250 30
     176KeyInput=10 7 250 30
     177gameoptions_defaultkeys=(parent.w - buttonWidth - 10) 10 buttonWidth buttonHeight
     178gameoptions_switchkey=prev.x (prev.y2 + 10) prev.w prev.h
     179gameoptions_clearkey=prev.x (prev.y2 + 10) prev.w prev.h
     180gameoptions_actionslist=10 10 (parent.w - buttonWidth - 3 * 10) (parent.h - 3 * buttonHeight - 2 * 10)
     181
    174182# paths tab
    175183opYoffset=vBorder
    176184goOff=((buttonHeight - kLineHeight) / 2 + 2)
  • gui/launcher.h

     
    7676        void selectGame(const String &name);
    7777};
    7878
     79class KeyInputDialog : public Dialog {
     80public:
     81        KeyInputDialog(Common::UserAction action);
     82        virtual void handleKeyUp(Common::KeyState state);
     83        virtual void handleKeyDown(Common::KeyState state) {}
     84private:
     85        GUI::StaticTextWidget *_input;
     86        Common::KeyState _key;
     87        Common::UserAction _action;
     88};
     89
    7990} // End of namespace GUI
    8091
    8192#endif
  • gui/widget.h

     
    148148        int getHints() const            { return _hints; }
    149149
    150150        void setEnabled(bool e)         { if (e) setFlags(WIDGET_ENABLED); else clearFlags(WIDGET_ENABLED); }
    151         bool isEnabled() const          { return _flags & WIDGET_ENABLED; }
     151        bool isEnabled() const;
    152152        bool isVisible() const;
    153153
    154154protected:
  • gui/launcher.cpp

     
    3434#include "common/fs.h"
    3535#include "common/util.h"
    3636#include "common/system.h"
     37#include "common/keyboard.h"
    3738
    3839#include "gui/about.h"
    3940#include "gui/browser.h"
     
    7677
    7778        kCmdExtraBrowser = 'PEXT',
    7879        kCmdGameBrowser = 'PGME',
    79         kCmdSaveBrowser = 'PSAV'
     80        kCmdSaveBrowser = 'PSAV',
     81       
     82        kCmdUseDefaultKeys = 'DFTK',
     83        kCmdSwitchKey = 'SWTK',
     84        kCmdClearKey = 'CLRK',
    8085};
    8186
    8287/*
     
    143148        CheckboxWidget *_globalAudioOverride;
    144149        CheckboxWidget *_globalMIDIOverride;
    145150        CheckboxWidget *_globalVolumeOverride;
     151
     152        ListWidget *_actionsList;
     153
     154private:
     155        void fillActionsList();
    146156};
    147157
    148158EditGameDialog::EditGameDialog(const String &domain, const String &desc)
     
    197207        }
    198208
    199209        //
     210        // 2) The keys tab
     211        //
     212        Mapping::KeyMapper *kMapper = g_system->getKeyMapper();
     213        if (kMapper->setGame(domain) != Mapping::GAME_NOT_FOUND) {     
     214                tab->addTab("Keys");
     215                ButtonWidget *defaultKeys = new ButtonWidget(tab, "gameoptions_defaultkeys", "Use default", kCmdUseDefaultKeys, 0);
     216                ButtonWidget *switchKey = new ButtonWidget(tab, "gameoptions_switchkey", "Switch map", kCmdSwitchKey, 0);
     217                if (g_system->getKeyMapper()->getKeyMapsNumber() <= 1) {
     218                        switchKey->setEnabled(false);
     219                }
     220                ButtonWidget *clearKey = new ButtonWidget(tab, "gameoptions_clearkey", "Clear", kCmdClearKey, 0);
     221
     222                _actionsList = new ListWidget(tab, "gameoptions_actionslist");
     223                Mapping::KeyMapper *kMapper = g_system->getKeyMapper();
     224                kMapper->setGame(domain);
     225                this->fillActionsList();
     226                _actionsList->setSelected(0);
     227        }
     228
     229
     230        //
    200231        // 3) The graphics tab
    201232        //
    202233        tab->addTab("Graphics");
     
    448479                draw();
    449480                break;
    450481        }
    451 
     482        case kCmdUseDefaultKeys: {             
     483                g_system->getKeyMapper()->getDefaultKeyMaps();
     484                this->fillActionsList();
     485                _actionsList->setSelected(0);
     486                break;
     487        }
     488        case kCmdSwitchKey: {
     489                uint current = g_system->getKeyMapper()->getCurrentKeyMap();
     490                uint kMaps = g_system->getKeyMapper()->getKeyMapsNumber();
     491                current = ++current % kMaps;
     492                g_system->getKeyMapper()->switchKeyMaps(current);
     493                this->fillActionsList();
     494                _actionsList->setSelected(0);
     495                break;
     496        }
     497        case kCmdClearKey: {
     498                Mapping::ActionKeysMap _actionKeysMap = g_system->getKeyMapper()->getKeyMaps();
     499                Mapping::ActionKeysMap::const_iterator it = _actionKeysMap.begin();
     500                int n = _actionsList->getSelected();
     501                for(int i = 0; i < n; i++) {
     502                        ++it;
     503                }
     504                Common::UserAction action = it->_key;
     505                g_system->getKeyMapper()->editMapping(Common::KeyState(), action);
     506                GUI::ListWidget::StringList s = _actionsList->getList();
     507                char st[50];
     508                sprintf(st, "%s\t\t\t\t\t\t%s", action.description.c_str(), g_system->keyNameResolve(Common::KEYCODE_INVALID).c_str());
     509                s.remove_at(n);
     510                s.insert_at(n,st);
     511                _actionsList->setList(s);
     512                _actionsList->draw();
     513                _actionsList->setSelected(n);
     514                break;
     515        }
     516        case kListItemDoubleClickedCmd: {
     517                Mapping::ActionKeysMap _actionKeysMap = g_system->getKeyMapper()->getKeyMaps();
     518                Mapping::ActionKeysMap::const_iterator it = _actionKeysMap.begin();
     519                int n = _actionsList->getSelected();
     520                for(int i = 0; i < n; i++) {
     521                        ++it;
     522                }
     523                Common::UserAction action = it->_key;
     524                KeyInputDialog *dlg = new KeyInputDialog(action);
     525                dlg->runModal();
     526                this->fillActionsList();
     527                _actionsList->setSelected(n);
     528                break;
     529        }
    452530        case kOKCmd: {
    453531                // Write back changes made to config object
    454532                String newDomain(_domainWidget->getEditString());
     
    461539                        ConfMan.renameGameDomain(_domain, newDomain);
    462540                        _domain = newDomain;
    463541                }
     542                if (g_system->getKeyMapper()->saveKeyMaps() == Mapping::PRIORITY_ERROR) {
     543                        GUI::MessageDialog("You must map all critical actions.").runModal();
    464544                }
     545        }
    465546                // FALL THROUGH to default case
    466547        default:
    467548                OptionsDialog::handleCommand(sender, cmd, data);
    468549        }
    469550}
    470551
     552void EditGameDialog::fillActionsList() {
     553        Mapping::ActionKeysMap _actionKeysMap = g_system->getKeyMapper()->getKeyMaps();
     554        Mapping::ActionKeysMap::const_iterator it = _actionKeysMap.begin();
     555        _actionKeysMap = g_system->getKeyMapper()->getKeyMaps();
     556        Common::StringList *s = new Common::StringList();
     557        char st[50];
     558        for (it = _actionKeysMap.begin(); it != _actionKeysMap.end(); ++it) {
     559                Common::UserAction action = it->_key;
     560                Common::KeysList keys = it->_value;
     561                sprintf(st, "%s\t\t\t\t\t\t%s", action.description.c_str(), g_system->keyNameResolve(keys.begin()->keycode).c_str());
     562                s->push_back(st);
     563        }
     564        _actionsList->setList(*s);
     565        _actionsList->draw();
     566}
    471567
    472568#pragma mark -
    473569
     
    9171013        Dialog::reflowLayout();
    9181014}
    9191015
     1016KeyInputDialog::KeyInputDialog(Common::UserAction action)
     1017        : Dialog("KeyInputDialog") {
     1018                _key.keycode = Common::KEYCODE_INVALID;
     1019                _action = action;
     1020                char st[50];
     1021        sprintf(st, "Key for %s action: ", _action.description.c_str());
     1022        _input = new GUI::StaticTextWidget(this, "KeyInput", Common::String(st));
     1023}
     1024
     1025void KeyInputDialog::handleKeyUp(Common::KeyState state) {
     1026        if ((state.keycode == Common::KEYCODE_RETURN && _key.keycode == Common::KEYCODE_RETURN) ||
     1027                        (state.keycode == Common::KEYCODE_RETURN && _key.keycode != Common::KEYCODE_INVALID) ) {
     1028                if (g_system->getKeyMapper()->editMapping(_key, _action) == Mapping::PRIORITY_ERROR) {
     1029                        GUI::MessageDialog("A higher priority action has this key mapped.").runModal();
     1030                }
     1031                this->close();
     1032        }
     1033        _key = state;
     1034        char st[50];
     1035        sprintf(st, "Key for %s action: %s", _action.description.c_str(), g_system->keyNameResolve(_key.keycode).c_str());
     1036        _input->setLabel(Common::String(st));
     1037        _input->draw();
     1038}
     1039
    9201040} // End of namespace GUI
  • gui/theme-config.cpp

     
    252252"gameoptions_platform=prev.x opYoffset prev.w prev.h\n"
    253253"opYoffset=(opYoffset + prev.h + 5)\n"
    254254"\n"
     255"# keys tab\n"
     256"KeyInputDialog=180 150 250 30\n"
     257"KeyInput=10 7 250 30\n"
     258"gameoptions_defaultkeys=(parent.w - buttonWidth - 10) 10 buttonWidth buttonHeight\n"
     259"gameoptions_switchkey=prev.x (prev.y2 + 10) prev.w prev.h\n"
     260"gameoptions_clearkey=prev.x (prev.y2 + 10) prev.w prev.h\n"
     261"gameoptions_actionslist=10 10 (parent.w - buttonWidth - 3 * 10) (parent.h - 3 * buttonHeight - 2 * 10)\n"
     262"\n"
    255263"# paths tab\n"
    256264"opYoffset=vBorder\n"
    257265"goOff=((buttonHeight - kLineHeight) / 2 + 2)\n"
  • gui/widget.cpp

     
    135135        return 0;
    136136}
    137137
     138
     139bool Widget::isEnabled() const {
     140        if (g_gui.evaluator()->getVar(_name + ".enabled") == 0) {
     141                return false;
     142        }
     143        return _flags & WIDGET_ENABLED;
     144}
     145
    138146bool Widget::isVisible() const {
    139147        if (g_gui.evaluator()->getVar(_name + ".visible") == 0)
    140148                return false;