aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/common/virtual-keyboard-parser.cpp26
-rw-r--r--backends/common/virtual-keyboard-parser.h3
-rw-r--r--backends/common/virtual-keyboard.cpp83
-rw-r--r--backends/common/virtual-keyboard.h40
-rw-r--r--backends/events/default/default-events.cpp4
5 files changed, 128 insertions, 28 deletions
diff --git a/backends/common/virtual-keyboard-parser.cpp b/backends/common/virtual-keyboard-parser.cpp
index 26da9f465a..8e788f53d4 100644
--- a/backends/common/virtual-keyboard-parser.cpp
+++ b/backends/common/virtual-keyboard-parser.cpp
@@ -143,8 +143,6 @@ bool VirtualKeyboardParser::parserCallback_Mode() {
_keyboard->_modes[name] = mode;
_mode = &(_keyboard->_modes[name]);
- // if this is the keyboard's initial mode
- // then set it to be the current mode
if (name == _initialModeName)
_keyboard->_initialMode = _mode;
} else
@@ -153,11 +151,14 @@ bool VirtualKeyboardParser::parserCallback_Mode() {
Common::String resolutions = modeNode->values["resolutions"];
Common::StringTokenizer tok (resolutions, " ,");
+ // select best resolution simply by minimising the difference between the
+ // overlay size and the resolution dimensions.
+ // TODO: improve this by giving preference to a resolution that is smaller
+ // than the overlay res (so the keyboard can't be too big for the screen)
uint16 scrW = g_system->getOverlayWidth(), scrH = g_system->getOverlayHeight();
uint32 diff = 0xFFFFFFFF;
Common::String newResolution;
for (Common::String res = tok.nextToken(); res.size() > 0; res = tok.nextToken()) {
- // TODO: improve the resolution selection
int resW, resH;
if (sscanf(res.c_str(), "%dx%d", &resW, &resH) != 2) {
return parserError("Invalid resolution specification");
@@ -166,7 +167,7 @@ bool VirtualKeyboardParser::parserCallback_Mode() {
newResolution = res;
break;
} else {
- uint16 newDiff = ABS(scrW - resW) + ABS(scrH - resH);
+ uint32 newDiff = ABS(scrW - resW) + ABS(scrH - resH);
if (newDiff < diff) {
diff = newDiff;
newResolution = res;
@@ -192,13 +193,15 @@ bool VirtualKeyboardParser::parserCallback_Mode() {
}
_mode->resolution = newResolution;
-
+ _layoutParsed = false;
+
return true;
}
bool VirtualKeyboardParser::parserCallback_ModeClosed() {
- if (!_mode->image)
+ if (!_layoutParsed) {
return parserError("'%s' layout missing from '%s' mode", _mode->resolution.c_str(), _mode->name.c_str());
+ }
return true;
}
@@ -287,13 +290,22 @@ bool VirtualKeyboardParser::parserCallback_Layout() {
_mode->bitmapName = layoutNode->values["bitmap"];
-
if (!ImageMan.registerSurface(_mode->bitmapName, 0))
return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());
_mode->image = ImageMan.getSurface(_mode->bitmapName);
if (!_mode->image)
return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());
+
+ if (layoutNode->values.contains("transparent_color")) {
+ int r, g, b;
+ if (!parseIntegerKey(layoutNode->values["transparent_color"].c_str(), 3, &r, &g, &b))
+ return parserError("Could not parse color value");
+ _mode->transparentColor = g_system->RGBToColor(r, g, b);
+ } else
+ _mode->transparentColor = g_system->RGBToColor(255, 0, 255); // default to purple
+
+ _layoutParsed = true;
return true;
}
diff --git a/backends/common/virtual-keyboard-parser.h b/backends/common/virtual-keyboard-parser.h
index c716d27733..69ca0a99a6 100644
--- a/backends/common/virtual-keyboard-parser.h
+++ b/backends/common/virtual-keyboard-parser.h
@@ -54,8 +54,9 @@ protected:
/** internal state variables of parser */
ParseMode _parseMode;
VirtualKeyboard::Mode *_mode; // pointer to mode currently being parsed
- Common::String _initialModeName; // name of initial keyboard mode
+ Common::String _initialModeName;
bool _kbdParsed;
+ bool _layoutParsed;
bool keyCallback(Common::String keyName);
bool closedKeyCallback(Common::String keyName);
diff --git a/backends/common/virtual-keyboard.cpp b/backends/common/virtual-keyboard.cpp
index 37fa922bd1..21d188dced 100644
--- a/backends/common/virtual-keyboard.cpp
+++ b/backends/common/virtual-keyboard.cpp
@@ -27,9 +27,11 @@
#include "backends/common/virtual-keyboard-parser.h"
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/unzip.h"
+#include "graphics/cursorman.h"
#include "graphics/imageman.h"
#include "graphics/surface-keycolored.h"
-#include "common/unzip.h"
+#include "gui/newgui.h"
namespace Common {
@@ -40,6 +42,8 @@ VirtualKeyboard::VirtualKeyboard() : _currentMode(0), _keyDown(0) {
_parser = new VirtualKeyboardParser(this);
_loaded = _displaying = _drag = false;
_lastScreenChanged = _system->getScreenChangeID();
+
+ memset(_cursor, 0xFF, sizeof(_cursor));
}
VirtualKeyboard::~VirtualKeyboard() {
@@ -76,9 +80,6 @@ void VirtualKeyboard::deleteEventData() {
bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
- if (ConfMan.hasKey("extrapath"))
- Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath"));
-
if (Common::File::exists(packName + ".xml")) {
// uncompressed keyboard pack
if (!_parser->loadFile(packName + ".xml"))
@@ -102,6 +103,7 @@ bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
return false;
}
} else {
+ warning("Could not find %s.xml file in %s.zip keyboard pack\n", packName.c_str(), packName.c_str());
unzClose(zipFile);
return false;
}
@@ -210,9 +212,9 @@ void VirtualKeyboard::processClick(const Common::String& area) {
}
void VirtualKeyboard::switchMode(Mode *newMode) {
+ _kbdBound.setWidth(newMode->image->w);
+ _kbdBound.setHeight(newMode->image->h);
_currentMode = newMode;
- _kbdBound.setWidth(_currentMode->image->w);
- _kbdBound.setHeight(_currentMode->image->h);
_needRedraw = true;
}
@@ -226,8 +228,11 @@ void VirtualKeyboard::switchMode(const Common::String& newMode) {
void VirtualKeyboard::show() {
if (!_loaded) {
- warning("Keyboard not loaded therefore can't be shown");
- return;
+ // if not loaded then load default "vkeybd" pack
+ if (!loadKeyboardPack("vkeybd")) {
+ warning("Keyboard not loaded therefore can't be shown");
+ return;
+ }
}
if (_lastScreenChanged != _system->getScreenChangeID())
screenChanged();
@@ -237,9 +242,22 @@ void VirtualKeyboard::show() {
_firstRun = false;
setDefaultPosition();
}
- _system->showOverlay();
+
+ if (!g_gui.isActive()) {
+ _system->showOverlay();
+ _system->clearOverlay();
+ }
+
+ _overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
+ _system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
+ setupCursor();
+
runLoop();
- _system->hideOverlay();
+
+ removeCursor();
+ _system->copyRectToOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h);
+ if (!g_gui.isActive()) _system->hideOverlay();
+ _overlayBackup.free();
}
void VirtualKeyboard::hide() {
@@ -258,6 +276,7 @@ void VirtualKeyboard::runLoop() {
while (_displaying) {
if (_needRedraw) redraw();
+ animateCursor();
_system->updateScreen();
Common::Event event;
while (eventMan->pollEvent(event)) {
@@ -317,10 +336,9 @@ void VirtualKeyboard::redraw() {
Graphics::SurfaceKeyColored surf;
surf.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor));
-
- _system->clearOverlay();
- _system->grabOverlay((OverlayColor*)surf.pixels, surf.w);
- surf.blit(_currentMode->image, _kbdBound.left, _kbdBound.top, _system->RGBToColor(0xff, 0, 0xff));
+
+ memcpy(surf.pixels, _overlayBackup.pixels, surf.w * surf.h * sizeof(OverlayColor));
+ surf.blit(_currentMode->image, _kbdBound.left, _kbdBound.top, _currentMode->transparentColor);
_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h);
@@ -329,4 +347,39 @@ void VirtualKeyboard::redraw() {
_needRedraw = false;
}
-} // end of namespace GUI
+void VirtualKeyboard::setupCursor() {
+ const byte palette[] = {
+ 255, 255, 255, 0,
+ 255, 255, 255, 0,
+ 171, 171, 171, 0,
+ 87, 87, 87, 0
+ };
+
+ CursorMan.pushCursorPalette(palette, 0, 4);
+ CursorMan.pushCursor(NULL, 0, 0, 0, 0);
+ CursorMan.showMouse(true);
+}
+
+void VirtualKeyboard::animateCursor() {
+ int time = _system->getMillis();
+ if (time > _cursorAnimateTimer + kCursorAnimateDelay) {
+ for (int i = 0; i < 15; i++) {
+ if ((i < 6) || (i > 8)) {
+ _cursor[16 * 7 + i] = _cursorAnimateCounter;
+ _cursor[16 * i + 7] = _cursorAnimateCounter;
+ }
+ }
+
+ CursorMan.replaceCursor(_cursor, 16, 16, 7, 7);
+
+ _cursorAnimateTimer = time;
+ _cursorAnimateCounter = (_cursorAnimateCounter + 1) % 4;
+ }
+}
+
+void VirtualKeyboard::removeCursor() {
+ CursorMan.popCursor();
+ CursorMan.popCursorPalette();
+}
+
+} // end of namespace Common
diff --git a/backends/common/virtual-keyboard.h b/backends/common/virtual-keyboard.h
index 74c3043a4c..fc2300c24c 100644
--- a/backends/common/virtual-keyboard.h
+++ b/backends/common/virtual-keyboard.h
@@ -43,7 +43,6 @@ class VirtualKeyboardParser;
class VirtualKeyboard {
- /** Type of key event */
enum EventType {
kEventKey,
kEventSwitchMode,
@@ -53,6 +52,7 @@ class VirtualKeyboard {
struct Event {
Common::String name;
EventType type;
+ Graphics::Surface *rollOverImage;
void *data;
};
@@ -63,6 +63,7 @@ class VirtualKeyboard {
Common::String resolution;
Common::String bitmapName;
Graphics::Surface *image;
+ OverlayColor transparentColor;
Common::ImageMap imageMap;
EventMap events;
Mode() : image(0) {}
@@ -85,13 +86,38 @@ class VirtualKeyboard {
public:
VirtualKeyboard();
virtual ~VirtualKeyboard();
-
+
+ /**
+ * Loads the keyboard pack with the given name.
+ * The system first looks for an uncompressed keyboard pack by searching
+ * for packName.xml in the filesystem, if this does not exist then it
+ * searches for a compressed keyboard pack by looking for packName.zip.
+ * @param packName name of the keyboard pack
+ */
bool loadKeyboardPack(Common::String packName);
+
+ /**
+ * Shows the keyboard, starting an event loop that will intercept all
+ * user input (like a modal GUI dialog).
+ * It is assumed that the game has been paused, before this is called
+ */
void show();
+
+ /**
+ * Hides the keyboard, ending the event loop.
+ */
void hide();
+
+ /**
+ * Returns true if the keyboard is currently being shown
+ */
bool isDisplaying() {
return _displaying;
}
+
+ /**
+ * Returns true if the keyboard is loaded and ready to be shown
+ */
bool isLoaded() {
return _loaded;
}
@@ -118,6 +144,8 @@ protected:
void runLoop();
void redraw();
+ Graphics::Surface _overlayBackup;
+
bool _loaded;
bool _displaying;
bool _needRedraw;
@@ -140,6 +168,14 @@ protected:
Common::Queue<Common::KeyState> _keyQueue;
Common::KeyState *_keyDown;
+ static const int kCursorAnimateDelay = 250;
+ int _cursorAnimateCounter;
+ int _cursorAnimateTimer;
+ byte _cursor[2048];
+ void setupCursor();
+ void removeCursor();
+ void animateCursor();
+
};
diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp
index d06edaec1b..6113f0e65c 100644
--- a/backends/events/default/default-events.cpp
+++ b/backends/events/default/default-events.cpp
@@ -31,7 +31,6 @@
#include "engines/engine.h"
#include "gui/message.h"
-#include "gui/newgui.h"
#define RECORD_SIGNATURE 0x54455354
#define RECORD_VERSION 1
@@ -397,8 +396,7 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
if (event.kbd.keycode == Common::KEYCODE_F6 && event.kbd.flags == 0) {
if (_vk->isDisplaying()) {
_vk->hide();
- } else if (!g_gui.isActive()) {
- if (!_vk->isLoaded()) _vk->loadKeyboardPack("test");
+ } else {
bool isPaused = (g_engine) ? g_engine->isPaused() : true;
if (!isPaused) g_engine->pauseEngine(true);
_vk->show();