diff options
author | Stephen Kennedy | 2008-07-07 21:10:58 +0000 |
---|---|---|
committer | Stephen Kennedy | 2008-07-07 21:10:58 +0000 |
commit | 641e3d752e9fc3b631474773a815b019f8d507e7 (patch) | |
tree | e9d477999b603e56787437cd56178294893ab856 | |
parent | 43c0fb8d895654394ac3a047947d15703a4557fa (diff) | |
download | scummvm-rg350-641e3d752e9fc3b631474773a815b019f8d507e7.tar.gz scummvm-rg350-641e3d752e9fc3b631474773a815b019f8d507e7.tar.bz2 scummvm-rg350-641e3d752e9fc3b631474773a815b019f8d507e7.zip |
MILESTONE: bitmap showing with key color transparency implemented!
- SurfaceKeyColored class handles blitting of keycolor transparency data
- ImageMap tested - Rect and Polygon areas seem to be working as expected
svn-id: r32950
-rw-r--r-- | backends/common/virtual-keyboard-parser.cpp | 36 | ||||
-rw-r--r-- | backends/common/virtual-keyboard-parser.h | 5 | ||||
-rw-r--r-- | backends/common/virtual-keyboard.cpp | 49 | ||||
-rw-r--r-- | common/image-map.cpp | 49 | ||||
-rw-r--r-- | common/image-map.h | 20 | ||||
-rw-r--r-- | dists/msvc8/scummvm.vcproj | 8 | ||||
-rw-r--r-- | graphics/module.mk | 3 | ||||
-rw-r--r-- | graphics/surface-keycolored.cpp | 28 | ||||
-rw-r--r-- | graphics/surface-keycolored.h | 17 |
9 files changed, 165 insertions, 50 deletions
diff --git a/backends/common/virtual-keyboard-parser.cpp b/backends/common/virtual-keyboard-parser.cpp index 9c2adb4dc2..e1eef3505c 100644 --- a/backends/common/virtual-keyboard-parser.cpp +++ b/backends/common/virtual-keyboard-parser.cpp @@ -40,6 +40,9 @@ VirtualKeyboardParser::VirtualKeyboardParser(VirtualKeyboard *kbd) : XMLParser() _callbacks["layout"] = &VirtualKeyboardParser::parserCallback_Layout; _callbacks["map"] = &VirtualKeyboardParser::parserCallback_Map; _callbacks["area"] = &VirtualKeyboardParser::parserCallback_Area; + + _closedCallbacks["keyboard"] = &VirtualKeyboardParser::parserCallback_KeyboardClosed; + _closedCallbacks["mode"] = &VirtualKeyboardParser::parserCallback_ModeClosed; } bool VirtualKeyboardParser::keyCallback(Common::String keyName) { @@ -49,6 +52,13 @@ bool VirtualKeyboardParser::keyCallback(Common::String keyName) { return (this->*(_callbacks[_activeKey.top()->name]))(); } +bool VirtualKeyboardParser::closedKeyCallback(Common::String keyName) { + if (!_closedCallbacks.contains(_activeKey.top()->name)) + return true; + + return (this->*(_closedCallbacks[_activeKey.top()->name]))(); +} + bool VirtualKeyboardParser::parserCallback_Keyboard() { ParserNode *kbdNode = getActiveNode(); @@ -59,7 +69,6 @@ bool VirtualKeyboardParser::parserCallback_Keyboard() { if (_kbdParsed) return parserError("Only a single keyboard element is allowed"); - _kbdParsed = true; if (!kbdNode->values.contains("initial_mode")) return parserError("Keyboard element must contain initial_mode attribute"); @@ -89,6 +98,13 @@ bool VirtualKeyboardParser::parserCallback_Keyboard() { return true; } +bool VirtualKeyboardParser::parserCallback_KeyboardClosed() { + _kbdParsed = true; + if (!_keyboard->_initialMode) + return parserError("Initial mode of keyboard pack not defined"); + return true; +} + bool VirtualKeyboardParser::parserCallback_Mode() { ParserNode *modeNode = getActiveNode(); @@ -146,6 +162,12 @@ bool VirtualKeyboardParser::parserCallback_Mode() { return true; } +bool VirtualKeyboardParser::parserCallback_ModeClosed() { + if (!_mode->image) + return parserError("'%s' layout missing from '%s' mode", _mode->resolution.c_str(), _mode->name.c_str()); + return true; +} + bool VirtualKeyboardParser::parserCallback_Event() { ParserNode *evtNode = getActiveNode(); @@ -262,15 +284,14 @@ bool VirtualKeyboardParser::parserCallback_Area() { Common::String shape = areaNode->values["shape"]; if (shape == "rect") { + Common::Rect *rect = _mode->imageMap.createRectArea(areaNode->values["target"]); int x1, y1, x2, y2; if (!parseIntegerKey(areaNode->values["coords"].c_str(), 4, &x1, &y1, &x2, &y2)) return parserError("Invalid coords for rect area"); - - Common::Rect rect(x1, y1, x2, y2); - _mode->imageMap.addRectMapArea(rect, areaNode->values["target"]); + rect->left = x1; rect->top = y1; rect->right = x2; rect->bottom = y2; } else if (shape == "poly") { Common::StringTokenizer tok (areaNode->values["coords"], ", "); - Common::Polygon poly; + Common::Polygon *poly = _mode->imageMap.createPolygonArea(areaNode->values["target"]); for (Common::String st = tok.nextToken(); !st.empty(); st = tok.nextToken()) { int x, y; if (sscanf(st.c_str(), "%d", &x) != 1) @@ -278,11 +299,10 @@ bool VirtualKeyboardParser::parserCallback_Area() { st = tok.nextToken(); if (sscanf(st.c_str(), "%d", &y) != 1) return parserError("Invalid coords for polygon area"); - poly.addPoint(x, y); + poly->addPoint(x, y); } - if (poly.getPointCount() < 3) + if (poly->getPointCount() < 3) return parserError("Invalid coords for polygon area"); - _mode->imageMap.addPolygonMapArea(poly, areaNode->values["target"]); } else return parserError("Area shape '%s' not known", shape.c_str()); diff --git a/backends/common/virtual-keyboard-parser.h b/backends/common/virtual-keyboard-parser.h index 4423ae7b35..98ec5cd0b7 100644 --- a/backends/common/virtual-keyboard-parser.h +++ b/backends/common/virtual-keyboard-parser.h @@ -49,6 +49,7 @@ protected: bool _kbdParsed; bool keyCallback(Common::String keyName); + bool closedKeyCallback(Common::String keyName); void cleanup() { _mode = 0; _kbdParsed = _modeParsed = false; @@ -62,7 +63,11 @@ protected: bool parserCallback_Map(); bool parserCallback_Area(); + bool parserCallback_KeyboardClosed(); + bool parserCallback_ModeClosed(); + Common::HashMap<Common::String, ParserCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _callbacks; + Common::HashMap<Common::String, ParserCallback, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _closedCallbacks; }; } // end of namespace GUI diff --git a/backends/common/virtual-keyboard.cpp b/backends/common/virtual-keyboard.cpp index f45769940a..e87d10ab3c 100644 --- a/backends/common/virtual-keyboard.cpp +++ b/backends/common/virtual-keyboard.cpp @@ -28,6 +28,7 @@ #include "common/config-manager.h" #include "common/events.h" #include "graphics/imageman.h" +#include "graphics/surface-keycolored.h" #include "common/unzip.h" namespace Common { @@ -101,24 +102,10 @@ bool VirtualKeyboard::loadKeyboardPack(Common::String packName) { return false; } - if (!_parser->parse()) - return false; - - if (!_initialMode) - warning("Initial mode of keyboard pack not defined"); - - ModeMap::iterator it; - for (it = _modes.begin(); it != _modes.end(); it++) { - // if no image then it means layout tag for the - // required resolution was missing from the mode tag. - if (!it->_value.image) { - warning("'%s' layout missing from '%s' mode", it->_value.resolution.c_str(), it->_value.name.c_str()); - return false; - } - } - - _loaded = true; - return true; + _loaded = _parser->parse(); + if (_loaded) + printf("Keyboard pack '%s' loaded successfully!\n", packName.c_str()); + return _loaded; } void VirtualKeyboard::reposition() @@ -159,10 +146,11 @@ void VirtualKeyboard::processClick(int16 x, int16 y) if (x < 0 || x > _currentMode->image->w) return; if (y < 0 || y > _currentMode->image->h) return; - Common::MapArea *area = _currentMode->imageMap.findMapArea(x, y); - if (!area) return; - if (!_currentMode->events.contains(area->getTarget())) return; - Event evt = _currentMode->events[area->getTarget()]; + Common::String area = _currentMode->imageMap.findMapArea(x, y); + if (area.empty()) return; + printf("Map area found! - %s\n", area.c_str()); + if (!_currentMode->events.contains(area)) return; + Event evt = _currentMode->events[area]; switch (evt.type) { case kEventKey: @@ -214,6 +202,7 @@ void VirtualKeyboard::runLoop() { while (_displaying) { if (_needRedraw) redraw(); + _system->updateScreen(); Common::Event event; while (eventMan->pollEvent(event)) { switch (event.type) { @@ -238,12 +227,18 @@ void VirtualKeyboard::runLoop() { } void VirtualKeyboard::redraw() { + Graphics::SurfaceKeyColored surf; + + surf.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); + + _system->grabOverlay((OverlayColor*)surf.pixels, surf.w); + + surf.blit(_currentMode->image, _pos.x, _pos.y, _system->RGBToColor(0xff, 0, 0xff)); + _system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h); + + surf.free(); + _needRedraw = false; - _system->clearOverlay(); - _system->copyRectToOverlay((OverlayColor*)_currentMode->image->pixels, - _currentMode->image->w, _pos.x, _pos.y, - _currentMode->image->w, _currentMode->image->h); - _system->updateScreen(); } bool VirtualKeyboard::pollEvent(Common::Event &event) { diff --git a/common/image-map.cpp b/common/image-map.cpp index 4e8df6cc50..54b4858dd5 100644 --- a/common/image-map.cpp +++ b/common/image-map.cpp @@ -27,6 +27,41 @@ namespace Common { +ImageMap::~ImageMap() { + HashMap<String, Shape*>::iterator it; + for (it = _areas.begin(); it != _areas.end(); it++) { + delete it->_value; + } +} + +Rect *ImageMap::createRectArea(const String& id) { + if (_areas.contains(id)) { + warning("Image map already contains an area with target of '%s'"); + return 0; + } + Rect *r = new Rect(); + _areas[id] = r; + return r; +} + +Polygon *ImageMap::createPolygonArea(const String& id) { + if (_areas.contains(id)) { + warning("Image map already contains an area with target of '%s'"); + return 0; + } + Polygon *p = new Polygon(); + _areas[id] = p; + return p; +} + +/* +void ImageMap::addMapArea(Shape *shape, const String& target) { + if (_areas.contains(target)) { + warning("Image map already contains an area with target of '%s'"); + return; + } + _areas[target] = shape; +} void ImageMap::addRectMapArea(const Rect& rect, const String& target) { areas.push_back(MapArea(rect, target)); } @@ -34,14 +69,14 @@ void ImageMap::addRectMapArea(const Rect& rect, const String& target) { void ImageMap::addPolygonMapArea(const Polygon& poly, const String& target) { areas.push_back(MapArea(poly, target)); } - -MapArea *ImageMap::findMapArea(int16 x, int16 y) { - Array<MapArea>::iterator it; - for (it = areas.begin(); it != areas.end(); it++) { - if (it->contains(x, y)) - return it; +*/ +String ImageMap::findMapArea(int16 x, int16 y) { + HashMap<String, Shape*>::iterator it; + for (it = _areas.begin(); it != _areas.end(); it++) { + if (it->_value->contains(x, y)) + return it->_key; } - return 0; + return ""; } diff --git a/common/image-map.h b/common/image-map.h index b6a1ad36f4..eabc54adf3 100644 --- a/common/image-map.h +++ b/common/image-map.h @@ -26,7 +26,8 @@ #ifndef COMMON_IMAGEMAP_H #define COMMON_IMAGEMAP_H -#include "common/array.h" +#include "common/hashmap.h" +#include "common/hash-str.h" #include "common/rect.h" #include "common/polygon.h" @@ -54,8 +55,7 @@ public: protected: /* shape defining the MapArea's boundary */ Shape *_shape; - /* generalised flags for the area - * TODO: change this */ + /* string describing the target of MapArea */ String _target; }; @@ -63,13 +63,19 @@ class ImageMap { public: - void addRectMapArea(const Rect& rect, const String& target); - void addPolygonMapArea(const Polygon& poly, const String& target); + ~ImageMap(); + + Rect *createRectArea(const String& id); + Polygon *createPolygonArea(const String& id); - MapArea *findMapArea(int16 x, int16 y); + //void addMapArea(Shape *shape, const String& target); + /*void addRectMapArea(const Rect& rect, const String& target); + void addPolygonMapArea(const Polygon& poly, const String& target); +*/ + String findMapArea(int16 x, int16 y); protected: - Array<MapArea> areas; + HashMap<String, Shape*> _areas; }; diff --git a/dists/msvc8/scummvm.vcproj b/dists/msvc8/scummvm.vcproj index 4a6906eda2..8f7f42f9e4 100644 --- a/dists/msvc8/scummvm.vcproj +++ b/dists/msvc8/scummvm.vcproj @@ -1362,6 +1362,14 @@ > </File> <File + RelativePath="..\..\graphics\surface-keycolored.cpp" + > + </File> + <File + RelativePath="..\..\graphics\surface-keycolored.h" + > + </File> + <File RelativePath="..\..\graphics\surface.cpp" > </File> diff --git a/graphics/module.mk b/graphics/module.mk index 93e2db26c5..a44042a044 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -16,7 +16,8 @@ MODULE_OBJS := \ primitives.o \ scaler.o \ scaler/thumbnail.o \ - surface.o + surface.o \ + surface-keycolored.o ifndef DISABLE_SCALERS MODULE_OBJS += \ diff --git a/graphics/surface-keycolored.cpp b/graphics/surface-keycolored.cpp new file mode 100644 index 0000000000..79beb5d5b5 --- /dev/null +++ b/graphics/surface-keycolored.cpp @@ -0,0 +1,28 @@ +#include "graphics/surface-keycolored.h" + +namespace Graphics { + +void SurfaceKeyColored::blit(Surface *surf_src, int16 x, int16 y, OverlayColor trans) { + + if (bytesPerPixel != sizeof(OverlayColor) || surf_src->bytesPerPixel != sizeof(OverlayColor)) return ; + + OverlayColor *dst = (OverlayColor*) getBasePtr(x, y); + const OverlayColor *src = (const OverlayColor*)surf_src->pixels; + + int blitW = (surf_src->w + x > w) ? w - x : surf_src->w; + int blitH = (surf_src->h + y > h) ? h - y : surf_src->h; + int dstAdd = w - blitW; + int srcAdd = surf_src->w - blitW; + + for (int i = 0; i < blitH; ++i) { + for (int j = 0; j < blitW; ++j, ++dst, ++src) { + OverlayColor col = *src; + if (col != trans) + *dst = col; + } + dst += dstAdd; + src += srcAdd; + } +} + +} // end of namespace Graphics
\ No newline at end of file diff --git a/graphics/surface-keycolored.h b/graphics/surface-keycolored.h new file mode 100644 index 0000000000..d2788b204e --- /dev/null +++ b/graphics/surface-keycolored.h @@ -0,0 +1,17 @@ + +#ifndef GRAPHICS_SURFACE_KEYCOLORED_H +#define GRAPHICS_SURFACE_KEYCOLORED_H + +#include "graphics/surface.h" + +namespace Graphics { + +struct SurfaceKeyColored : Surface { + + void blit(Surface *surf_src, int16 x, int16 y, OverlayColor trans); +}; + + +} // end of namespace Graphics + +#endif
\ No newline at end of file |