- proper init of virtual keyboard now implemented (involved added EventManager::init() which is called after screen has been initialised)

- changed HardwareKey / Action id field to an array of 4 chars instead of int32. Means that the keymap key/value pairs in config file are more readable.

svn-id: r33986
This commit is contained in:
Stephen Kennedy 2008-08-18 10:07:11 +00:00
parent 63c4a61032
commit d92909203b
13 changed files with 147 additions and 111 deletions

View file

@ -199,6 +199,8 @@ DefaultEventManager::DefaultEventManager(OSystem *boss) :
_vk = new Common::VirtualKeyboard();
_keymapper = new Common::Keymapper(this);
_remap = false;
//init();
}
DefaultEventManager::~DefaultEventManager() {
@ -259,6 +261,14 @@ DefaultEventManager::~DefaultEventManager() {
_boss->deleteMutex(_recorderMutex);
}
void DefaultEventManager::init() {
if (ConfMan.hasKey("vkeybd_pack_name")) {
_vk->loadKeyboardPack(ConfMan.get("vkeybd_pack_name"));
} else {
_vk->loadKeyboardPack("vkeybd");
}
}
bool DefaultEventManager::playback(Common::Event &event) {
if (!_hasPlaybackEvent) {
@ -418,23 +428,16 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_keyRepeatTime = time + kKeyRepeatInitialDelay;
#endif
// HACK to show/hide keyboard (keyboard is not shown if gui is active)
if (event.kbd.keycode == Common::KEYCODE_F6 && event.kbd.flags == 0) {
if (_vk->isDisplaying()) {
_vk->close(true);
} else {
static bool enabled = true;
if (enabled && _vk->isLoaded() == false) {
enabled = _vk->loadKeyboardPack("vkeybd");
}
if (enabled) {
bool isPaused = (g_engine) ? g_engine->isPaused() : true;
if (!isPaused) g_engine->pauseEngine(true);
_vk->show();
if (!isPaused) g_engine->pauseEngine(false);
result = false;
}
}
} else if (event.kbd.keycode == Common::KEYCODE_F7 && event.kbd.flags == 0) {
if (!_remap) {
_remap = true;

View file

@ -122,6 +122,7 @@ public:
DefaultEventManager(OSystem *boss);
~DefaultEventManager();
virtual void init();
virtual bool pollEvent(Common::Event &event);
virtual void pushEvent(const Common::Event &event);
virtual void registerRandomSource(Common::RandomSource &rnd, const char *name);

View file

@ -28,11 +28,15 @@
namespace Common {
Action::Action(Keymap *boss, int32 i, String des, ActionCategory cat,
Action::Action(Keymap *boss, const char *i, String des, ActionCategory cat,
ActionType typ, int pri, int grp, int flg)
: _boss(boss), id(i), description(des), category(cat), type(typ),
: _boss(boss), description(des), category(cat), type(typ),
priority(pri), group(grp), flags(flg), _hwKey(0) {
assert(i);
assert(_boss);
strncpy(id, i, ACTION_ID_SIZE);
_boss->addAction(this);
}

View file

@ -68,9 +68,11 @@ enum ActionCategory {
kActionCategoryMax
};
#define ACTION_ID_SIZE (4)
struct Action {
/** unique id used for saving/loading to config */
int32 id;
char id[ACTION_ID_SIZE];
/** Human readable description */
String description;
@ -88,7 +90,7 @@ private:
Keymap *_boss;
public:
Action(Keymap *boss, int32 id, String des = "",
Action(Keymap *boss, const char *id, String des = "",
ActionCategory cat = kGenericActionCategory,
ActionType typ = kGenericActionType,
int pri = 0, int grp = 0, int flg = 0 );

View file

@ -30,12 +30,14 @@
namespace Common {
#define HWKEY_ID_SIZE (4)
/**
* Describes an available hardware key
*/
struct HardwareKey {
/** unique id used for saving/loading to config */
int32 id;
char id[HWKEY_ID_SIZE];
/** Human readable description */
String description;
/**
@ -48,15 +50,12 @@ struct HardwareKey {
ActionType preferredType;
int16 group;
HardwareKey(int32 i, KeyState ks = KeyState(), String des = "",
HardwareKey(const char *i, KeyState ks = KeyState(), String des = "",
ActionCategory cat = kGenericActionCategory,
ActionType ty = kGenericActionType, int gr = 0) {
id = i;
key = ks;
description = des;
preferredCategory = cat;
preferredType = ty;
group = gr;
ActionType ty = kGenericActionType, int gr = 0)
: key(ks), description(des), preferredCategory(cat), preferredType(ty), group(gr) {
assert(i);
strncpy(id, i, HWKEY_ID_SIZE);
}
};
@ -82,10 +81,10 @@ public:
++_count;
}
const HardwareKey *findHardwareKey(int32 id) const {
const HardwareKey *findHardwareKey(const char *id) const {
List<const HardwareKey*>::iterator it;
for (it = _keys.begin(); it != _keys.end(); it++) {
if ((*it)->id == id)
if (strncmp((*it)->id, id, HWKEY_ID_SIZE) == 0)
return (*it);
}
return 0;

View file

@ -26,6 +26,8 @@
#include "backends/keymapper/keymap.h"
#include "backends/keymapper/hardware-key.h"
#define KEYMAP_KEY_PREFIX "keymap_"
namespace Common {
Keymap::Keymap(const Keymap& km) : _actions(km._actions), _keymap(), _configDomain(0) {
@ -68,23 +70,23 @@ void Keymap::unregisterMapping(Action *action) {
}
}
Action *Keymap::getAction(int32 id) {
Action *Keymap::getAction(const char *id) {
return findAction(id);
}
Action *Keymap::findAction(int32 id) {
Action *Keymap::findAction(const char *id) {
List<Action*>::iterator it;
for (it = _actions.begin(); it != _actions.end(); it++) {
if ((*it)->id == id)
if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
return *it;
}
return 0;
}
const Action *Keymap::findAction(int32 id) const {
const Action *Keymap::findAction(const char *id) const {
List<Action*>::const_iterator it;
for (it = _actions.begin(); it != _actions.end(); it++) {
if ((*it)->id == id)
if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
return *it;
}
return 0;
@ -106,37 +108,25 @@ void Keymap::setConfigDomain(ConfigManager::Domain *dom) {
void Keymap::loadMappings(const HardwareKeySet *hwKeys) {
if (!_configDomain) return;
ConfigManager::Domain::iterator it;
String prefix = "km_" + _name + "_";
String prefix = KEYMAP_KEY_PREFIX + _name + "_";
for (it = _configDomain->begin(); it != _configDomain->end(); it++) {
const String& key = it->_key;
if (!key.hasPrefix(prefix.c_str()))
continue;
// parse Action ID
const char *actionIdStart = key.c_str() + prefix.size();
char *err;
int32 actionId = (int32) strtol(actionIdStart, &err, 0);
if (err == actionIdStart) {
warning("'%s' is not a valid Action ID", err);
continue;
}
const char *actionId = key.c_str() + prefix.size();
Action *ua = getAction(actionId);
if (!ua) {
warning("'%s' keymap does not contain Action with ID %d",
_name.c_str(), (int)actionId);
warning("'%s' keymap does not contain Action with ID %s",
_name.c_str(), actionId);
_configDomain->erase(key);
continue;
}
// parse HardwareKey ID
int32 hwKeyId = (int32) strtol(it->_value.c_str(), &err, 0);
if (err == it->_value.c_str()) {
warning("'%s' is not a valid HardwareKey ID", err);
continue;
}
const HardwareKey *hwKey = hwKeys->findHardwareKey(hwKeyId);
const HardwareKey *hwKey = hwKeys->findHardwareKey(it->_value.c_str());
if (!hwKey) {
warning("HardwareKey with ID %d not known", (int)hwKeyId);
warning("HardwareKey with ID %s not known", it->_value.c_str());
_configDomain->erase(key);
continue;
}
@ -148,16 +138,17 @@ void Keymap::loadMappings(const HardwareKeySet *hwKeys) {
void Keymap::saveMappings() {
if (!_configDomain) return;
List<Action*>::const_iterator it;
char buf[12];
String prefix = "km_" + _name + "_";
String prefix = KEYMAP_KEY_PREFIX + _name + "_";
for (it = _actions.begin(); it != _actions.end(); it++) {
sprintf(buf, "%d", (*it)->id);
String key = prefix + buf;
if ((*it)->getMappedKey())
sprintf(buf, "%d", (*it)->getMappedKey()->id);
else
strcpy(buf, "");
_configDomain->setVal(key, buf);
uint actIdLen = strnlen((*it)->id, ACTION_ID_SIZE);
String actId((*it)->id, (*it)->id + actIdLen);
if ((*it)->getMappedKey()) {
uint hwIdLen = strnlen((*it)->getMappedKey()->id, HWKEY_ID_SIZE);
String hwId((*it)->getMappedKey()->id, (*it)->getMappedKey()->id + hwIdLen);
_configDomain->setVal(prefix + actId, hwId);
} else {
_configDomain->setVal(prefix + actId, "");
}
}
}

View file

@ -61,7 +61,7 @@ public:
* @param id id of Action to retrieve
* @return Pointer to the Action or 0 if not found
*/
Action *getAction(int32 id);
Action *getAction(const char *id);
/**
* Get the list of all the Actions contained in this Keymap
@ -124,8 +124,8 @@ private:
*/
void unregisterMapping(Action *action);
Action *findAction(int32 id);
const Action *findAction(int32 id) const;
Action *findAction(const char *id);
const Action *findAction(const char *id) const;
void internalMapKey(Action *action, HardwareKey *hwKey);

View file

@ -526,10 +526,10 @@ void OSystem_SDL::setupKeymapper() {
Keymapper *mapper = getEventManager()->getKeymapper();
HardwareKeySet *keySet = new HardwareKeySet();
keySet->addHardwareKey(new HardwareKey( 'a', KeyState(KEYCODE_a), "a" ));
keySet->addHardwareKey(new HardwareKey( 's', KeyState(KEYCODE_s), "s" ));
keySet->addHardwareKey(new HardwareKey( 'd', KeyState(KEYCODE_d), "d" ));
keySet->addHardwareKey(new HardwareKey( 'f', KeyState(KEYCODE_f), "f" ));
keySet->addHardwareKey(new HardwareKey( "a", KeyState(KEYCODE_a), "a" ));
keySet->addHardwareKey(new HardwareKey( "s", KeyState(KEYCODE_s), "s" ));
keySet->addHardwareKey(new HardwareKey( "d", KeyState(KEYCODE_d), "d" ));
keySet->addHardwareKey(new HardwareKey( "f", KeyState(KEYCODE_f), "f" ));
mapper->registerHardwareKeySet(keySet);
Keymap *global = new Keymap("global");
@ -542,25 +542,25 @@ void OSystem_SDL::setupKeymapper() {
evt.kbd = KeyState(kc, asc, flags); \
act->events.push_back(evt);
act = new Action(global, 'MENU', "Menu", kGenericActionCategory, kMenuAction);
act = new Action(global, "MENU", "Menu", kGenericActionCategory, kMenuAction);
ADD_KEYDOWN_EVENT(KEYCODE_F5, ASCII_F5, 0)
act = new Action(global, 'SKCT', "Skip");
act = new Action(global, "SKCT", "Skip");
ADD_KEYDOWN_EVENT(KEYCODE_ESCAPE, ASCII_ESCAPE, 0);
act = new Action(global, 'PAUS', "Pause");
act = new Action(global, "PAUS", "Pause");
ADD_KEYDOWN_EVENT(KEYCODE_SPACE, ' ', 0)
act = new Action(global, 'SKLI', "Skip line");
act = new Action(global, "SKLI", "Skip line");
ADD_KEYDOWN_EVENT(Common::KEYCODE_PERIOD, '.', 0);
act = new Action(specific, 'JUMP', "Jump");
act = new Action(specific, "JUMP", "Jump");
ADD_KEYDOWN_EVENT(KEYCODE_j, 'j', 0);
act = new Action(specific, 'DUCK', "Duck");
act = new Action(specific, "DUCK", "Duck");
ADD_KEYDOWN_EVENT(KEYCODE_d, 'd', 0);
act = new Action(specific, 'RUN_', "Run");
act = new Action(specific, "RUN_", "Run");
ADD_KEYDOWN_EVENT(KEYCODE_r, 'r', 0);
#undef ADD_KEYDOWN_EVENT

View file

@ -39,6 +39,9 @@ VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
_system = g_system;
_lastScreenChanged = _system->getScreenChangeID();
_screenW = _system->getOverlayWidth();
_screenH = _system->getOverlayHeight();
memset(_cursor, 0xFF, sizeof(_cursor));
}
@ -93,6 +96,11 @@ void VirtualKeyboardGUI::checkScreenChanged() {
screenChanged();
}
void VirtualKeyboardGUI::initSize(int16 w, int16 h) {
_screenW = w;
_screenH = h;
}
void VirtualKeyboardGUI::run() {
if (_firstRun) {
_firstRun = false;
@ -103,7 +111,7 @@ void VirtualKeyboardGUI::run() {
_system->showOverlay();
_system->clearOverlay();
}
_overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
_overlayBackup.create(_screenW, _screenH, sizeof(OverlayColor));
_system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
setupCursor();
@ -136,32 +144,31 @@ void VirtualKeyboardGUI::reset() {
void VirtualKeyboardGUI::moveToDefaultPosition()
{
int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight();
int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
int16 x = 0, y = 0;
if (scrW != kbdW) {
if (_screenW != kbdW) {
switch (_kbd->_hAlignment) {
case VirtualKeyboard::kAlignLeft:
x = 0;
break;
case VirtualKeyboard::kAlignCentre:
x = (scrW - kbdW) / 2;
x = (_screenW - kbdW) / 2;
break;
case VirtualKeyboard::kAlignRight:
x = scrW - kbdW;
x = _screenW - kbdW;
break;
}
}
if (scrH != kbdH) {
if (_screenH != kbdH) {
switch (_kbd->_vAlignment) {
case VirtualKeyboard::kAlignTop:
y = 0;
break;
case VirtualKeyboard::kAlignMiddle:
y = (scrH - kbdH) / 2;
y = (_screenH - kbdH) / 2;
break;
case VirtualKeyboard::kAlignBottom:
y = scrH - kbdH;
y = _screenH - kbdH;
break;
}
}
@ -170,17 +177,17 @@ void VirtualKeyboardGUI::moveToDefaultPosition()
void VirtualKeyboardGUI::move(int16 x, int16 y) {
// add old position to dirty area
extendDirtyRect(_kbdBound);
if (_displaying) extendDirtyRect(_kbdBound);
// snap to edge of screen
if (ABS(x) < SNAP_WIDTH)
x = 0;
int16 x2 = _system->getOverlayWidth() - _kbdBound.width();
int16 x2 = _screenW - _kbdBound.width();
if (ABS(x - x2) < SNAP_WIDTH)
x = x2;
if (ABS(y) < SNAP_WIDTH)
y = 0;
int16 y2 = _system->getOverlayHeight() - _kbdBound.height();
int16 y2 = _screenH - _kbdBound.height();
if (ABS(y - y2) < SNAP_WIDTH)
y = y2;
@ -188,20 +195,27 @@ void VirtualKeyboardGUI::move(int16 x, int16 y) {
_dispY += y - _kbdBound.top;
_kbdBound.moveTo(x, y);
if (_displaying) {
// add new position to dirty area
extendDirtyRect(_kbdBound);
redraw();
}
}
void VirtualKeyboardGUI::screenChanged() {
_lastScreenChanged = _system->getScreenChangeID();
int16 newScreenW = _system->getOverlayWidth();
int16 newScreenH = _system->getOverlayHeight();
if (_screenW != newScreenW || _screenH != newScreenH) {
_screenW = newScreenW;
_screenH = newScreenH;
if (!_kbd->checkModeResolutions()) {
_displaying = false;
return;
}
moveToDefaultPosition();
}
}
void VirtualKeyboardGUI::mainLoop() {

View file

@ -49,10 +49,12 @@ public:
void reset();
void startDrag(int16 x, int16 y);
void endDrag();
void initSize(int16 w, int16 h);
private:
OSystem *_system;
VirtualKeyboard *_kbd;
Rect _kbdBound;
Graphics::Surface *_kbdSurface;
@ -72,9 +74,11 @@ private:
uint _dispI;
OverlayColor _dispForeColor, _dispBackColor;
int _lastScreenChanged;
int16 _screenW, _screenH;
bool _displaying;
bool _firstRun;
int _lastScreenChanged;
void setupDisplayArea(Rect& r, OverlayColor forecolor);
void move(int16 x, int16 y);

View file

@ -44,7 +44,6 @@ VirtualKeyboard::VirtualKeyboard() : _currentMode(0) {
_kbdGUI = new VirtualKeyboardGUI(this);
_submitKeys = _loaded = false;
printf("\t\"%c\",\n",255);
}
VirtualKeyboard::~VirtualKeyboard() {
@ -75,6 +74,9 @@ void VirtualKeyboard::reset() {
}
bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
_kbdGUI->initSize(_system->getOverlayWidth(), _system->getOverlayHeight());
FilesystemNode *vkDir = 0;
if (ConfMan.hasKey("vkeybdpath")) {
vkDir = new FilesystemNode(ConfMan.get("vkeybdpath"));
@ -138,7 +140,7 @@ bool VirtualKeyboard::checkModeResolutions()
{
_parser->setParseMode(kParseCheckResolutions);
_loaded = _parser->parse();
_kbdGUI->initMode(_currentMode);
if (_currentMode) _kbdGUI->initMode(_currentMode);
return _loaded;
}
@ -215,7 +217,7 @@ void VirtualKeyboard::handleMouseUp(int16 x, int16 y) {
void VirtualKeyboard::show() {
if (_loaded) _kbdGUI->checkScreenChanged();
if (!_loaded) {
warning("Virtual keyboard not loaded!");
warning("Virtual keyboard not loaded");
return;
}

View file

@ -38,6 +38,7 @@
#include "base/version.h"
#include "common/config-manager.h"
#include "common/events.h"
#include "common/file.h"
#include "common/fs.h"
#include "common/system.h"
@ -54,20 +55,6 @@
static bool launcherDialog(OSystem &system) {
system.beginGFXTransaction();
// Set the user specified graphics mode (if any).
system.setGraphicsMode(ConfMan.get("gfx_mode").c_str());
system.initSize(320, 200);
system.endGFXTransaction();
// Set initial window caption
system.setWindowCaption(gScummVMFullVersion);
// Clear the main screen
system.clearScreen();
#if defined(_WIN32_WCE)
CELauncherDialog dlg;
#elif defined(__DC__)
@ -203,6 +190,21 @@ static int runGame(const EnginePlugin *plugin, OSystem &system, const Common::St
return 0;
}
static void setupGraphics(OSystem &system) {
system.beginGFXTransaction();
// Set the user specified graphics mode (if any).
system.setGraphicsMode(ConfMan.get("gfx_mode").c_str());
system.initSize(320, 200);
system.endGFXTransaction();
// Set initial window caption
system.setWindowCaption(gScummVMFullVersion);
// Clear the main screen
system.clearScreen();
}
extern "C" int scummvm_main(int argc, char *argv[]) {
Common::String specialDebug;
@ -259,6 +261,12 @@ extern "C" int scummvm_main(int argc, char *argv[]) {
// the command line params) was read.
system.initBackend();
setupGraphics(system);
// Init the event manager. As the virtual keyboard is loaded here, it must
// take place after the backend is initiated and the screen has been setup
system.getEventManager()->init();
// Unless a game was specified, show the launcher dialog
if (0 == ConfMan.getActiveDomain()) {
launcherDialog(system);
@ -304,6 +312,8 @@ extern "C" int scummvm_main(int argc, char *argv[]) {
warning("Could not find any engine capable of running the selected game");
}
// reset the graphics to default
setupGraphics(system);
launcherDialog(system);
}
PluginManager::instance().unloadPlugins();

View file

@ -136,6 +136,12 @@ public:
RBUTTON = 1 << 1
};
/**
* Initialise the event manager.
* @note called after graphics system has been set up
*/
virtual void init() {}
/**
* Get the next event in the event queue.
* @param event point to an Event struct, which will be filled with the event data.