aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/keymapper/keymap.cpp2
-rw-r--r--backends/keymapper/keymapper.cpp4
-rw-r--r--backends/keymapper/keymapper.h2
-rw-r--r--backends/keymapper/remap-dialog.cpp72
-rw-r--r--backends/keymapper/remap-dialog.h2
-rw-r--r--base/main.cpp2
-rw-r--r--common/keyboard.h3
-rw-r--r--engines/engine.h5
-rw-r--r--engines/kyra/lol.cpp67
-rw-r--r--engines/kyra/lol.h4
-rw-r--r--gui/dialog.cpp1
-rw-r--r--gui/gui-manager.cpp25
-rw-r--r--gui/gui-manager.h2
-rw-r--r--po/POTFILES1
14 files changed, 170 insertions, 22 deletions
diff --git a/backends/keymapper/keymap.cpp b/backends/keymapper/keymap.cpp
index 1518cba693..d2c9b9b572 100644
--- a/backends/keymapper/keymap.cpp
+++ b/backends/keymapper/keymap.cpp
@@ -199,6 +199,7 @@ bool Keymap::isComplete(const HardwareKeySet *hwKeys) {
// - if an action finds a key with required type but a parent action with
// higher priority is using it, that key is never used
void Keymap::automaticMapping(HardwareKeySet *hwKeys) {
+#if 0 //disabling the broken automapper for now
// Create copies of action and key lists.
List<Action*> actions(_actions);
List<const HardwareKey*> keys(hwKeys->getHardwareKeys());
@@ -318,6 +319,7 @@ void Keymap::automaticMapping(HardwareKeySet *hwKeys) {
break;
}
}
+#endif
}
Action *Keymap::getParentMappedAction(KeyState key) {
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
index f5f29a2940..29f495cd53 100644
--- a/backends/keymapper/keymapper.cpp
+++ b/backends/keymapper/keymapper.cpp
@@ -192,10 +192,10 @@ bool Keymapper::mapKey(const KeyState& key, bool keyDown) {
// Search for key in active keymap stack
for (int i = _activeMaps.size() - 1; i >= 0; --i) {
MapRecord mr = _activeMaps[i];
-
+ debug(5, "Keymapper::mapKey keymap: %s", mr.keymap->getName().c_str());
action = mr.keymap->getMappedAction(key);
- if (action || mr.inherit == false)
+ if (action || !mr.inherit)
break;
}
diff --git a/backends/keymapper/keymapper.h b/backends/keymapper/keymapper.h
index fcb444aa64..c5a2558964 100644
--- a/backends/keymapper/keymapper.h
+++ b/backends/keymapper/keymapper.h
@@ -36,6 +36,8 @@
namespace Common {
+const char *const kGuiKeymapName = "gui";
+
class Keymapper : public Common::EventMapper, private Common::ArtificialEventSource {
public:
diff --git a/backends/keymapper/remap-dialog.cpp b/backends/keymapper/remap-dialog.cpp
index 7f2df2f0fe..b0f42fe426 100644
--- a/backends/keymapper/remap-dialog.cpp
+++ b/backends/keymapper/remap-dialog.cpp
@@ -28,13 +28,13 @@
#include "gui/widgets/popup.h"
#include "gui/widgets/scrollbar.h"
#include "gui/ThemeEval.h"
-
#include "common/translation.h"
namespace Common {
enum {
kRemapCmd = 'REMP',
+ kClearCmd = 'CLER',
kCloseCmd = 'CLOS'
};
@@ -60,7 +60,7 @@ void RemapDialog::open() {
bool divider = false;
const Stack<Keymapper::MapRecord> &activeKeymaps = _keymapper->getActiveStack();
- if (!(activeKeymaps.size() > 0)) {
+ if (activeKeymaps.size() > 0) {
_kmPopUp->appendEntry(activeKeymaps.top().keymap->getName() + _(" (Active)"));
divider = true;
}
@@ -84,7 +84,7 @@ void RemapDialog::open() {
keymapCount += _gameKeymaps->size();
}
- debug(3, "keymaps: %d", keymapCount);
+ debug(3, "RemapDialog::open keymaps: %d", keymapCount);
_keymapTable = (Keymap **)malloc(sizeof(Keymap*) * keymapCount);
@@ -140,8 +140,10 @@ void RemapDialog::reflowLayout() {
uint16 areaW, areaH;
int spacing = g_gui.xmlEval()->getVar("Globals.KeyMapper.Spacing");
int labelWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.LabelWidth");
- int buttonWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.ButtonWidth");
- int colWidth = labelWidth + buttonWidth + spacing;
+ int keyButtonWidth = g_gui.xmlEval()->getVar("Globals.KeyMapper.ButtonWidth");
+ int clearButtonWidth = g_gui.xmlEval()->getVar("Globals.Line.Height");
+ int clearButtonHeight = g_gui.xmlEval()->getVar("Globals.Line.Height");
+ int colWidth = labelWidth + keyButtonWidth + clearButtonWidth + spacing;
g_gui.xmlEval()->getWidgetData((const String&)String("KeyMapper.KeymapArea"), areaX, areaY, areaW, areaH);
@@ -156,6 +158,7 @@ void RemapDialog::reflowLayout() {
_scrollBar->recalc();
uint textYOff = (buttonHeight - kLineHeight) / 2;
+ uint clearButtonYOff = (buttonHeight - clearButtonHeight) / 2;
uint oldSize = _keymapWidgets.size();
uint newSize = _rowCount * _colCount;
@@ -169,6 +172,16 @@ void RemapDialog::reflowLayout() {
new GUI::StaticTextWidget(this, 0, 0, 0, 0, "", Graphics::kTextAlignRight);
widg.keyButton =
new GUI::ButtonWidget(this, 0, 0, 0, 0, "", 0, kRemapCmd + i);
+#ifndef DISABLE_FANCY_THEMES
+ if (g_gui.xmlEval()->getVar("Globals.ShowSearchPic") == 1 && g_gui.theme()->supportsImages()) {
+ widg.clearButton = new GUI::PicButtonWidget(this, 0, 0, clearButtonWidth, clearButtonHeight, _("Clear value"), kClearCmd + i);
+ ((GUI::PicButtonWidget *)widg.clearButton)->useThemeTransparency(true);
+ ((GUI::PicButtonWidget *)widg.clearButton)->setGfx(g_gui.theme()->getImageSurface(GUI::ThemeEngine::kImageEraser));
+ }
+ else
+#endif
+ widg.clearButton = new GUI::ButtonWidget(this, 0, 0, 0, 0, "C", _("Clear value"), kClearCmd + i);
+
_keymapWidgets.push_back(widg);
} else {
widg = _keymapWidgets[i];
@@ -178,7 +191,8 @@ void RemapDialog::reflowLayout() {
uint y = areaY + (i / _colCount) * (buttonHeight + spacing);
widg.actionText->resize(x, y + textYOff, labelWidth, kLineHeight);
- widg.keyButton->resize(x + labelWidth, y, buttonWidth, buttonHeight);
+ widg.keyButton->resize(x + labelWidth, y, keyButtonWidth, buttonHeight);
+ widg.clearButton->resize(x + labelWidth + keyButtonWidth + spacing, y + clearButtonYOff, clearButtonWidth, clearButtonHeight);
}
while (oldSize > newSize) {
ActionWidgets widg = _keymapWidgets.remove_at(--oldSize);
@@ -188,14 +202,19 @@ void RemapDialog::reflowLayout() {
removeWidget(widg.keyButton);
delete widg.keyButton;
+
+ removeWidget(widg.clearButton);
+ delete widg.clearButton;
}
}
void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
- debug(0, "Command!");
+ debug(3, "RemapDialog::handleCommand %u %u", cmd, data);
if (cmd >= kRemapCmd && cmd < kRemapCmd + _keymapWidgets.size()) {
startRemapping(cmd - kRemapCmd);
+ } else if (cmd >= kClearCmd && cmd < kClearCmd + _keymapWidgets.size()) {
+ clearMapping(cmd - kClearCmd);
} else if (cmd == GUI::kPopUpItemSelectedCmd) {
loadKeymap();
} else if (cmd == GUI::kSetPositionCmd) {
@@ -207,6 +226,23 @@ void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 d
}
}
+void RemapDialog::clearMapping(uint i) {
+ if (_topAction + i >= _currentActions.size())
+ return;
+
+ debug(3, "clear the mapping %u", i);
+ _activeRemapAction = _currentActions[_topAction + i].action;
+ _activeRemapAction->mapKey(0);
+ _activeRemapAction->getParent()->saveMappings();
+ _changes = true;
+
+ // force refresh
+ _topAction = -1;
+ refreshKeymap();
+
+ _activeRemapAction = 0;
+}
+
void RemapDialog::startRemapping(uint i) {
if (_topAction + i >= _currentActions.size())
return;
@@ -240,7 +276,7 @@ void RemapDialog::handleKeyUp(Common::KeyState state) {
if (_activeRemapAction) {
const HardwareKey *hwkey = _keymapper->findHardwareKey(state);
- debug(0, "Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags);
+ debug(4, "RemapDialog::handleKeyUp Key: %d, %d (%c), %x", state.keycode, state.ascii, (state.ascii ? state.ascii : ' '), state.flags);
if (hwkey) {
_activeRemapAction->mapKey(hwkey);
@@ -270,15 +306,23 @@ void RemapDialog::loadKeymap() {
_currentActions.clear();
const Stack<Keymapper::MapRecord> &activeKeymaps = _keymapper->getActiveStack();
+ debug(3, "RemapDialog::loadKeymap active keymaps: %u", activeKeymaps.size());
+
if (!activeKeymaps.empty() && _kmPopUp->getSelected() == 0) {
// load active keymaps
List<const HardwareKey*> freeKeys(_keymapper->getHardwareKeys());
+ int topIndex = activeKeymaps.size() - 1;
+ // skip the top gui keymap since it is for the keymapper itself
+ // TODO: Don't use the keymap name as a way to discriminate GUI maps
+ if (topIndex > 0 && activeKeymaps[topIndex].keymap->getName().equals(kGuiKeymapName))
+ --topIndex;
+
// add most active keymap's keys
- Keymapper::MapRecord top = activeKeymaps.top();
+ Keymapper::MapRecord top = activeKeymaps[topIndex];
List<Action*>::iterator actIt;
-
+ debug(3, "RemapDialog::loadKeymap top keymap: %s", top.keymap->getName().c_str());
for (actIt = top.keymap->getActions().begin(); actIt != top.keymap->getActions().end(); ++actIt) {
Action *act = *actIt;
ActionInfo info = {act, false, act->description};
@@ -290,9 +334,10 @@ void RemapDialog::loadKeymap() {
}
// loop through remaining finding mappings for unmapped keys
- if (top.inherit) {
- for (int i = activeKeymaps.size() - 2; i >= 0; --i) {
+ if (top.inherit && topIndex >= 0) {
+ for (int i = topIndex - 1; i >= 0; --i) {
Keymapper::MapRecord mr = activeKeymaps[i];
+ debug(3, "RemapDialog::loadKeymap keymap: %s", mr.keymap->getName().c_str());
List<const HardwareKey*>::iterator keyIt = freeKeys.begin();
while (keyIt != freeKeys.end()) {
@@ -351,6 +396,7 @@ void RemapDialog::refreshKeymap() {
ActionWidgets& widg = _keymapWidgets[widgetI];
if (actionI < _currentActions.size()) {
+ debug(8, "RemapDialog::refreshKeymap actionI=%u", actionI);
ActionInfo& info = _currentActions[actionI];
widg.actionText->setLabel(info.description + ": ");
@@ -365,11 +411,13 @@ void RemapDialog::refreshKeymap() {
widg.actionText->setVisible(true);
widg.keyButton->setVisible(true);
+ widg.clearButton->setVisible(true);
actionI++;
} else {
widg.actionText->setVisible(false);
widg.keyButton->setVisible(false);
+ widg.clearButton->setVisible(false);
}
//widg.actionText->draw();
//widg.keyButton->draw();
diff --git a/backends/keymapper/remap-dialog.h b/backends/keymapper/remap-dialog.h
index f587ae515d..25e336c4fe 100644
--- a/backends/keymapper/remap-dialog.h
+++ b/backends/keymapper/remap-dialog.h
@@ -55,6 +55,7 @@ protected:
struct ActionWidgets {
GUI::StaticTextWidget *actionText;
GUI::ButtonWidget *keyButton;
+ GUI::ButtonWidget *clearButton;
};
struct ActionInfo {
Action *action;
@@ -64,6 +65,7 @@ protected:
void loadKeymap();
void refreshKeymap();
+ void clearMapping(uint i);
void startRemapping(uint i);
void stopRemapping();
diff --git a/base/main.cpp b/base/main.cpp
index 5d0c0ea09a..61a05154c1 100644
--- a/base/main.cpp
+++ b/base/main.cpp
@@ -288,7 +288,7 @@ static void setupKeymapper(OSystem &system) {
mapper->addGlobalKeymap(globalMap);
- mapper->pushKeymap("global");
+ mapper->pushKeymap("global", true);
#endif
}
diff --git a/common/keyboard.h b/common/keyboard.h
index bdd0a2d4af..ead6ed427b 100644
--- a/common/keyboard.h
+++ b/common/keyboard.h
@@ -292,7 +292,8 @@ struct KeyState {
}
bool operator==(const KeyState &x) const {
- return keycode == x.keycode && ascii == x.ascii && flags == x.flags;
+ // intentionally ignore ascii
+ return keycode == x.keycode && flags == x.flags;
}
};
diff --git a/engines/engine.h b/engines/engine.h
index 2796df5c4f..d508b4ed18 100644
--- a/engines/engine.h
+++ b/engines/engine.h
@@ -180,6 +180,11 @@ public:
*/
virtual void syncSoundSettings();
+ /*
+ * Initialize the engine-specific keymap
+ */
+ virtual void initKeymap() {}
+
/**
* Flip mute all sound option.
*/
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 43859ddfbb..aed8f5c965 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -34,9 +34,14 @@
#include "common/config-manager.h"
#include "common/system.h"
+#include "common/translation.h"
+
+#include "backends/keymapper/keymapper.h"
namespace Kyra {
+const char *const LoLEngine::kKeymapName = "lol";
+
LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
_screen = 0;
_gui = 0;
@@ -246,6 +251,10 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy
LoLEngine::~LoLEngine() {
setupPrologueData(false);
+#ifdef ENABLE_KEYMAPPER
+ _eventMan->getKeymapper()->cleanupGameKeymaps();
+#endif
+
delete[] _landsFile;
delete[] _levelLangFile;
@@ -541,9 +550,67 @@ Common::Error LoLEngine::init() {
_debugger = new Debugger_LoL(this);
assert(_debugger);
+ initKeymap();
+
return Common::kNoError;
}
+void LoLEngine::initKeymap() {
+#ifdef ENABLE_KEYMAPPER
+
+ bool tmp;
+ Common::Keymapper *mapper = _eventMan->getKeymapper();
+
+ // Do not try to recreate same keymap over again
+ if (mapper->getKeymap(kKeymapName, tmp) != 0)
+ return;
+
+ Common::Action *act;
+ Common::Keymap *engineKeyMap = new Common::Keymap(kKeymapName);
+
+ act = new Common::Action(engineKeyMap, "AT1", _("Attack 1"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_F1, Common::ASCII_F1 , 0));
+
+ act = new Common::Action(engineKeyMap, "AT2", _("Attack 2"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_F2, Common::ASCII_F2 , 0));
+
+ act = new Common::Action(engineKeyMap, "AT3", _("Attack 3"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_F3, Common::ASCII_F3 , 0));
+
+ act = new Common::Action(engineKeyMap, "MVF", _("Move Forward"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_UP));
+
+ act = new Common::Action(engineKeyMap, "MVB", _("Move Back"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_DOWN));
+
+ act = new Common::Action(engineKeyMap, "SLL", _("Slide Left"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_LEFT));
+
+ act = new Common::Action(engineKeyMap, "SLR", _("Slide Right"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_RIGHT));
+
+ act = new Common::Action(engineKeyMap, "TL", _("Turn Left"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_HOME));
+
+ act = new Common::Action(engineKeyMap, "TR", _("Turn Right"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_PAGEUP));
+
+ act = new Common::Action(engineKeyMap, "RST", _("Rest"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_r));
+
+ act = new Common::Action(engineKeyMap, "OPT", _("Options"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_o));
+
+ act = new Common::Action(engineKeyMap, "SPL", _("Choose Spell"), Common::kGenericActionType, Common::kActionKeyType);
+ act->addKeyEvent(Common::KeyState(Common::KEYCODE_SLASH));
+
+ mapper->addGameKeymap(engineKeyMap);
+
+ mapper->pushKeymap(kKeymapName, true);
+
+#endif
+}
+
Common::Error LoLEngine::go() {
int action = -1;
diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h
index 5f6be61d64..eb2f6cf2d7 100644
--- a/engines/kyra/lol.h
+++ b/engines/kyra/lol.h
@@ -307,6 +307,8 @@ public:
LoLEngine(OSystem *system, const GameFlags &flags);
~LoLEngine();
+ virtual void initKeymap();
+
Screen *screen();
GUI *gui() const;
@@ -333,6 +335,8 @@ private:
void writeSettings();
void readSettings();
+ static const char *const kKeymapName;
+
const char *const *_pakFileList;
int _pakFileListSize;
diff --git a/gui/dialog.cpp b/gui/dialog.cpp
index 2ec8641257..0522b40b46 100644
--- a/gui/dialog.cpp
+++ b/gui/dialog.cpp
@@ -75,7 +75,6 @@ int Dialog::runModal() {
}
void Dialog::open() {
-
_result = 0;
_visible = true;
g_gui.openDialog(this);
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp
index 212d68430c..98840e6daf 100644
--- a/gui/gui-manager.cpp
+++ b/gui/gui-manager.cpp
@@ -107,11 +107,11 @@ void GuiManager::initKeymap() {
Keymapper *mapper = _system->getEventManager()->getKeymapper();
// Do not try to recreate same keymap over again
- if (mapper->getKeymap("gui", tmp) != 0)
+ if (mapper->getKeymap(kGuiKeymapName, tmp) != 0)
return;
Action *act;
- Keymap *guiMap = new Keymap("gui");
+ Keymap *guiMap = new Keymap(kGuiKeymapName);
act = new Action(guiMap, "CLOS", _("Close"), kGenericActionType, kStartKeyType);
act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
@@ -127,6 +127,22 @@ void GuiManager::initKeymap() {
mapper->addGlobalKeymap(guiMap);
}
+
+void GuiManager::pushKeymap() {
+ _system->getEventManager()->getKeymapper()->pushKeymap(Common::kGuiKeymapName);
+}
+
+void GuiManager::popKeymap() {
+ Common::Keymapper *keymapper = _system->getEventManager()->getKeymapper();
+ if (!keymapper->getActiveStack().empty()) {
+ Common::Keymapper::MapRecord topKeymap = keymapper->getActiveStack().top();
+ // TODO: Don't use the keymap name as a way to discriminate GUI maps
+ if(topKeymap.keymap->getName().equals(Common::kGuiKeymapName))
+ keymapper->popKeymap();
+ else
+ warning("An attempt to pop non-gui keymap %s was blocked", topKeymap.keymap->getName().c_str());
+ }
+}
#endif
bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx, bool forced) {
@@ -276,8 +292,7 @@ void GuiManager::runLoop() {
// try to do it on every launch, checking whether the
// map is already existing
initKeymap();
-
- eventMan->getKeymapper()->pushKeymap("gui");
+ pushKeymap();
#endif
bool tooltipCheck = false;
@@ -392,7 +407,7 @@ void GuiManager::runLoop() {
}
#ifdef ENABLE_KEYMAPPER
- eventMan->getKeymapper()->popKeymap();
+ popKeymap();
#endif
if (didSaveState) {
diff --git a/gui/gui-manager.h b/gui/gui-manager.h
index 10f9e6a29f..addd2e6611 100644
--- a/gui/gui-manager.h
+++ b/gui/gui-manager.h
@@ -126,6 +126,8 @@ protected:
byte _cursor[2048];
void initKeymap();
+ void pushKeymap();
+ void popKeymap();
void saveState();
void restoreState();
diff --git a/po/POTFILES b/po/POTFILES
index 6ce26a0539..dcc501ae0e 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -36,6 +36,7 @@ engines/gob/inter_playtoons.cpp
engines/gob/inter_v2.cpp
engines/gob/inter_v5.cpp
engines/groovie/script.cpp
+engines/kyra/lol.cpp
engines/kyra/sound_midi.cpp
engines/m4/m4_menus.cpp
engines/sky/compact.cpp