aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti2008-08-09 18:34:16 +0000
committerVicent Marti2008-08-09 18:34:16 +0000
commit103a4f66813df8f806467ad6f27cd0831ae0abf4 (patch)
tree7f09914cd0a658d2301e567d544826eb0a347877
parentea69217a136210347689e9536d67e1dda883f45a (diff)
downloadscummvm-rg350-103a4f66813df8f806467ad6f27cd0831ae0abf4.tar.gz
scummvm-rg350-103a4f66813df8f806467ad6f27cd0831ae0abf4.tar.bz2
scummvm-rg350-103a4f66813df8f806467ad6f27cd0831ae0abf4.zip
Added support for image loading/blitting.
Added support for loading theme files. (Make sure to grab the sample theme "scummodern.zip" from the gui/themes/ directory to try it out) Misc fixes. svn-id: r33718
-rw-r--r--common/xmlparser.h6
-rw-r--r--graphics/VectorRenderer.h55
-rw-r--r--gui/ThemeParser.cpp21
-rw-r--r--gui/ThemeParser.h12
-rw-r--r--gui/ThemeRenderer.cpp94
-rw-r--r--gui/ThemeRenderer.h49
-rw-r--r--gui/launcher.cpp2
-rw-r--r--gui/newgui.cpp57
-rw-r--r--gui/theme.h2
-rw-r--r--gui/themes/default.inc4
-rw-r--r--gui/themes/modern.stx5
-rw-r--r--gui/themes/scummodern.zipbin0 -> 29651 bytes
12 files changed, 250 insertions, 57 deletions
diff --git a/common/xmlparser.h b/common/xmlparser.h
index b7a7093bc5..e3d39bfb82 100644
--- a/common/xmlparser.h
+++ b/common/xmlparser.h
@@ -371,6 +371,12 @@ public:
_fileName = "Memory Stream";
return true;
}
+
+ bool loadStream(MemoryReadStream *stream) {
+ _text.loadStream(stream);
+ _fileName = "Compressed File Stream";
+ return true;
+ }
/**
* The actual parsing function.
diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h
index a2352762a7..7eff0a9c50 100644
--- a/graphics/VectorRenderer.h
+++ b/graphics/VectorRenderer.h
@@ -71,6 +71,7 @@ struct DrawStep {
uint32 scale; /** scale of all the coordinates in FIXED POINT with 16 bits mantissa */
void (VectorRenderer::*drawingCall)(const Common::Rect &, const DrawStep &); /** Pointer to drawing function */
+ Graphics::Surface *blitSrc;
};
VectorRenderer *createRenderer(int mode);
@@ -412,6 +413,12 @@ public:
stepGetPositions(step, area, x, y, w, h);
drawTab(x, y, stepGetRadius(step, area), w, h);
}
+
+ void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step) {
+ uint16 x, y, w, h;
+ stepGetPositions(step, area, x, y, w, h);
+ blitAlphaBitmap(step.blitSrc, Common::Rect(x, y, w, h));
+ }
void drawCallback_VOID(const Common::Rect &area, const DrawStep &step) {}
@@ -464,6 +471,8 @@ public:
*/
virtual void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) = 0;
+ virtual void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) = 0;
+
/**
* Draws a string into the screen. Wrapper for the Graphics::Font string drawing
* method.
@@ -554,6 +563,11 @@ class VectorRendererSpec : public VectorRenderer {
typedef VectorRenderer Base;
public:
+ VectorRendererSpec() {
+ _bitmapAlphaColor = RGBToColor<PixelFormat>(255, 0, 255);
+ }
+
+
/**
* @see VectorRenderer::drawLine()
*/
@@ -672,6 +686,8 @@ public:
* @see VectorRenderer::blitSurface()
*/
virtual void blitSurface(const Graphics::Surface *source, const Common::Rect &r) {
+ assert(source->w == _activeSurface->w && source->h == _activeSurface->h);
+
PixelType *dst_ptr = (PixelType *)_activeSurface->getBasePtr(r.left, r.top);
PixelType *src_ptr = (PixelType *)source->getBasePtr(r.left, r.top);
@@ -703,6 +719,43 @@ public:
}
}
+ virtual void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) {
+ assert(r.width() >= source->w && r.height() >= source->h);
+
+ int16 x = r.left;
+ int16 y = r.top;
+
+ if (r.width() > source->w)
+ x = x + (r.width() >> 1) - (source->w >> 1);
+
+ if (r.height() > source->h)
+ y = y + (r.height() >> 1) - (source->h >> 1);
+
+ PixelType *dst_ptr = (PixelType *)_activeSurface->getBasePtr(x, y);
+ PixelType *src_ptr = (PixelType *)source->getBasePtr(0, 0);
+
+ int dst_pitch = surfacePitch();
+ int src_pitch = source->pitch / source->bytesPerPixel;
+
+ int w, h = source->h;
+
+ while (h--) {
+ w = source->w;
+
+ while (w--) {
+ if (*src_ptr != _bitmapAlphaColor)
+ *dst_ptr = *src_ptr;
+
+ dst_ptr++;
+ src_ptr++;
+ }
+
+ dst_ptr = dst_ptr - source->w + dst_pitch;
+ src_ptr = src_ptr - source->w + src_pitch;
+ }
+
+ }
+
virtual void applyScreenShading(GUI::Theme::ShadingStyle shadingStyle) {
int pixels = _activeSurface->w * _activeSurface->h;
PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(0, 0);
@@ -935,6 +988,8 @@ protected:
PixelType _gradientEnd; /** End color for the fill gradient */
PixelType _bevelColor;
+
+ PixelType _bitmapAlphaColor;
};
/**
diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp
index 21554f4c7a..df36ad6c7c 100644
--- a/gui/ThemeParser.cpp
+++ b/gui/ThemeParser.cpp
@@ -51,6 +51,7 @@ ThemeParser::ThemeParser(ThemeRenderer *parent) : XMLParser() {
_drawFunctions["fill"] = &Graphics::VectorRenderer::drawCallback_FILLSURFACE;
_drawFunctions["tab"] = &Graphics::VectorRenderer::drawCallback_TAB;
_drawFunctions["void"] = &Graphics::VectorRenderer::drawCallback_VOID;
+ _drawFunctions["bitmap"] = &Graphics::VectorRenderer::drawCallback_BITMAP;
_defaultStepGlobal = defaultDrawStep();
_defaultStepLocal = 0;
@@ -149,6 +150,18 @@ bool ThemeParser::parserCallback_fonts(ParserNode *node) {
return true;
}
+bool ThemeParser::parserCallback_bitmap(ParserNode *node) {
+ if (resolutionCheck(node->values["resolution"])) {
+ node->ignore = true;
+ return true;
+ }
+
+ if (!_theme->addBitmap(node->values["filename"]))
+ return parserError("Error when loading Bitmap file '%s'", node->values["filename"].c_str());
+
+ return true;
+}
+
bool ThemeParser::parserCallback_text(ParserNode *node) {
GUI::Theme::TextAlign alignH;
GUI::Theme::TextAlignVertical alignV;
@@ -319,6 +332,14 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst
if (functionSpecific) {
assert(stepNode->values.contains("func"));
Common::String functionName = stepNode->values["func"];
+
+ if (functionName == "bitmap") {
+ if (!stepNode->values.contains("filename"))
+ return parserError("Need to specify a filename for Bitmap blitting.");
+
+ if (!_theme->getBitmap(stepNode->values["filename"]))
+ return parserError("The given filename hasn't been loaded into the GUI.");
+ }
if (functionName == "roundedsq" || functionName == "circle" || functionName == "tab") {
if (stepNode->values.contains("radius") && stepNode->values["radius"] == "auto") {
diff --git a/gui/ThemeParser.h b/gui/ThemeParser.h
index 78423652bc..b9fa69179d 100644
--- a/gui/ThemeParser.h
+++ b/gui/ThemeParser.h
@@ -308,7 +308,7 @@ namespace GUI {
using namespace Graphics;
using namespace Common;
-class ThemeRenderer;
+class ThemeRenderer;
class ThemeParser : public XMLParser {
typedef void (VectorRenderer::*DrawingFunctionCallback)(const Common::Rect &, const DrawStep &);
@@ -354,6 +354,13 @@ protected:
XML_PROP(resolution, false)
KEY_END()
KEY_END()
+
+ XML_KEY(bitmaps)
+ XML_KEY(bitmap)
+ XML_PROP(filename, true)
+ XML_PROP(resolution, false)
+ KEY_END()
+ KEY_END()
XML_KEY(defaults)
XML_PROP(stroke, false)
@@ -408,6 +415,7 @@ protected:
XML_PROP(xpos, false)
XML_PROP(ypos, false)
XML_PROP(orientation, false)
+ XML_PROP(bitmap, false)
KEY_END()
XML_KEY(text)
@@ -489,6 +497,8 @@ protected:
bool parserCallback_color(ParserNode *node);
bool parserCallback_drawstep(ParserNode *node);
bool parserCallback_drawdata(ParserNode *node);
+ bool parserCallback_bitmaps(ParserNode *node) { return true; }
+ bool parserCallback_bitmap(ParserNode *node);
/** Layout info callbacks */
bool parserCallback_layout_info(ParserNode *node);
diff --git a/gui/ThemeRenderer.cpp b/gui/ThemeRenderer.cpp
index 679db6c3e7..6cfdb777ad 100644
--- a/gui/ThemeRenderer.cpp
+++ b/gui/ThemeRenderer.cpp
@@ -29,6 +29,7 @@
#include "common/system.h"
#include "common/events.h"
#include "common/config-manager.h"
+#include "graphics/imageman.h"
#include "gui/launcher.h"
@@ -118,6 +119,8 @@ ThemeRenderer::ThemeRenderer(Common::String themeName, GraphicsMode mode) :
} else {
_font = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
}
+
+ ImageMan.addArchive(themeName + ".zip");
_initOk = true;
_themeName = themeName;
@@ -130,6 +133,13 @@ ThemeRenderer::~ThemeRenderer() {
unloadTheme();
delete _parser;
delete _themeEval;
+
+ for (ImagesMap::iterator i = _bitmaps.begin(); i != _bitmaps.end(); ++i) {
+// delete i->_value;
+ ImageMan.unregisterSurface(i->_key);
+ }
+
+ ImageMan.remArchive(_stylefile + ".zip");
}
bool ThemeRenderer::init() {
@@ -269,6 +279,18 @@ bool ThemeRenderer::addFont(const Common::String &fontId, const Common::String &
}
+bool ThemeRenderer::addBitmap(const Common::String &filename) {
+ if (_bitmaps.contains(filename)) {
+ delete _bitmaps[filename];
+ ImageMan.unregisterSurface(filename);
+ }
+
+ ImageMan.registerSurface(filename, 0);
+ _bitmaps[filename] = ImageMan.getSurface(filename);
+
+ return _bitmaps[filename] != 0;
+}
+
bool ThemeRenderer::addDrawData(const Common::String &data, bool cached) {
DrawData data_id = getDrawDataId(data);
@@ -346,9 +368,41 @@ bool ThemeRenderer::loadThemeXML(Common::String themeName) {
if (ConfMan.hasKey("extrapath"))
Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath"));
-
- if (!parser()->loadFile(themeName + ".xml"))
+
+ if (!parser()->loadFile(themeName + ".stx")){
+#ifdef USE_ZLIB
+ unzFile zipFile = unzOpen((themeName + ".zip").c_str());
+
+ if (zipFile && unzLocateFile(zipFile, (themeName + ".stx").c_str(), 2) == UNZ_OK) {
+
+ unz_file_info fileInfo;
+ unzOpenCurrentFile(zipFile);
+ unzGetCurrentFileInfo(zipFile, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
+ uint8 *buffer = new uint8[fileInfo.uncompressed_size+1];
+ assert(buffer);
+ memset(buffer, 0, (fileInfo.uncompressed_size+1)*sizeof(uint8));
+ unzReadCurrentFile(zipFile, buffer, fileInfo.uncompressed_size);
+ unzCloseCurrentFile(zipFile);
+
+ Common::MemoryReadStream *stream = new Common::MemoryReadStream(buffer, fileInfo.uncompressed_size+1, true);
+
+ if (!parser()->loadStream(stream)) {
+ unzClose(zipFile);
+ delete stream;
+ return false;
+ }
+
+// delete[] buffer;
+ buffer = 0;
+ } else {
+ unzClose(zipFile);
+ return false;
+ }
+ unzClose(zipFile);
+#else
return false;
+#endif
+ }
return parser()->parse();
}
@@ -411,6 +465,19 @@ void ThemeRenderer::queueDDText(TextData type, const Common::Rect &r, const Comm
}
}
+void ThemeRenderer::queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &area, bool alpha) {
+ BitmapQueue q;
+ q.bitmap = bitmap;
+ q.area = area;
+ q.alpha = alpha;
+
+ if (_buffering) {
+ _bitmapQueue.push_back(q);
+ } else {
+ drawBitmap(q);
+ }
+}
+
void ThemeRenderer::drawDD(const DrawQueue &q, bool draw, bool restore) {
Common::Rect extendedRect = q.area;
extendedRect.grow(kDirtyRectangleThreshold);
@@ -442,6 +509,16 @@ void ThemeRenderer::drawDDText(const DrawQueueText &q) {
addDirtyRect(q.area);
}
+void ThemeRenderer::drawBitmap(const BitmapQueue &q) {
+
+ if (q.alpha)
+ _vectorRenderer->blitAlphaBitmap(q.bitmap, q.area);
+ else
+ _vectorRenderer->blitSubSurface(q.bitmap, q.area);
+
+ addDirtyRect(q.area);
+}
+
void ThemeRenderer::calcBackgroundOffset(DrawData type) {
uint maxShadow = 0;
for (Common::List<Graphics::DrawStep>::const_iterator step = _widgets[type]->_steps.begin();
@@ -597,8 +674,10 @@ void ThemeRenderer::drawSurface(const Common::Rect &r, const Graphics::Surface &
if (!ready())
return;
- _vectorRenderer->blitSubSurface(&surface, r);
- addDirtyRect(r);
+ queueBitmap(&surface, r, themeTrans);
+
+// _vectorRenderer->blitSubSurface(&surface, r);
+// addDirtyRect(r);
}
void ThemeRenderer::drawWidgetBackground(const Common::Rect &r, uint16 hints, WidgetBackground background, WidgetStateInfo state) {
@@ -726,6 +805,13 @@ void ThemeRenderer::updateScreen() {
_screenQueue.clear();
}
+ if (!_bitmapQueue.empty()) {
+ for (Common::List<BitmapQueue>::const_iterator q = _bitmapQueue.begin(); q != _bitmapQueue.end(); ++q)
+ drawBitmap(*q);
+
+ _bitmapQueue.clear();
+ }
+
if (!_textQueue.empty()) {
for (Common::List<DrawQueueText>::const_iterator q = _textQueue.begin(); q != _textQueue.end(); ++q)
drawDDText(*q);
diff --git a/gui/ThemeRenderer.h b/gui/ThemeRenderer.h
index 55c75bd76e..cb68b9ca5c 100644
--- a/gui/ThemeRenderer.h
+++ b/gui/ThemeRenderer.h
@@ -88,6 +88,7 @@ class ThemeRenderer : public Theme {
protected:
typedef Common::String String;
typedef GUI::Dialog Dialog;
+ typedef Common::HashMap<Common::String, Graphics::Surface*> ImagesMap;
friend class GUI::Dialog;
friend class GUI::GuiObject;
@@ -197,6 +198,12 @@ protected:
int deltax;
};
+ struct BitmapQueue {
+ const Graphics::Surface *bitmap;
+ Common::Rect area;
+ bool alpha;
+ };
+
public:
/** Graphics mode enumeration.
* Each item represents a set of BPP and Renderer modes for a given
@@ -390,8 +397,27 @@ public:
* @param cached Whether this DD set will be cached beforehand.
*/
bool addDrawData(const Common::String &data, bool cached);
+
+
+ /**
+ * Interface for the ThemeParser class: Loads a font to use on the GUI from the given
+ * filename.
+ *
+ * @param fontName Identifier name for the font.
+ * @param file Name of the font file.
+ * @param r, g, b Color of the font.
+ */
bool addFont(const Common::String &fontName, const Common::String &file, int r, int g, int b);
+
+ /**
+ * Interface for the ThemeParser class: Loads a bitmap file to use on the GUI.
+ * The filename is also used as its identifier.
+ *
+ * @param filename Name of the bitmap file.
+ */
+ bool addBitmap(const Common::String &filename);
+
/**
* Adds a new TextStep from the ThemeParser. This will be deprecated/removed once the
* new Font API is in place.
@@ -433,6 +459,19 @@ public:
void *evaluator() { return _themeEval; }
bool supportsImages() const { return true; }
+
+ Graphics::Surface *getBitmap(const Common::String &name) {
+ return _bitmaps.contains(name) ? _bitmaps[name] : 0;
+ }
+
+ const Graphics::Surface *getImageSurface(const kThemeImages n) const {
+ if (n == kImageLogo)
+ return _bitmaps.contains("logo.bmp") ? _bitmaps["logo.bmp"] : 0;
+
+ return 0;
+ }
+
+ const Common::String &getThemeName() { return _themeName; }
protected:
@@ -487,7 +526,9 @@ protected:
* Not implemented yet.
* TODO: reload themes, reload the renderer, recheck everything
*/
- void screenChange() {}
+ void screenChange() {
+ error("Screen Changes are not supported yet. Fix this!");
+ }
/**
* Actual Dirty Screen handling function.
@@ -570,6 +611,7 @@ protected:
*/
inline void drawDD(const DrawQueue &q, bool draw = true, bool restore = false);
inline void drawDDText(const DrawQueueText &q);
+ inline void drawBitmap(const BitmapQueue &q);
/**
* Generates a DrawQueue item and enqueues it so it's drawn to the screen
@@ -585,6 +627,7 @@ protected:
inline void queueDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0);
inline void queueDDText(TextData type, const Common::Rect &r, const Common::String &text, bool restoreBg,
bool elipsis, TextAlign alignH = kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0);
+ inline void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha);
/**
* DEBUG: Draws a white square around the given position and writes the given next to it.
@@ -646,6 +689,8 @@ protected:
/** Array of all the text fonts that can be drawn. */
TextDrawData *_texts[kTextDataMAX];
+ ImagesMap _bitmaps;
+
/** List of all the dirty screens that must be blitted to the overlay. */
Common::List<Common::Rect> _dirtyScreen;
@@ -657,6 +702,8 @@ protected:
/** Queue with all the text drawing that must be done to the screen */
Common::List<DrawQueueText> _textQueue;
+
+ Common::List<BitmapQueue> _bitmapQueue;
bool _initOk; /** Class and renderer properly initialized */
bool _themeOk; /** Theme data successfully loaded. */
diff --git a/gui/launcher.cpp b/gui/launcher.cpp
index 62f1daf244..3d35420326 100644
--- a/gui/launcher.cpp
+++ b/gui/launcher.cpp
@@ -880,7 +880,7 @@ void LauncherDialog::updateButtons() {
void LauncherDialog::reflowLayout() {
#ifndef DISABLE_FANCY_THEMES
if (g_gui.xmlEval()->getVar("Globals.ShowLauncherLogo") == 1 && g_gui.theme()->supportsImages()) {
- StaticTextWidget *ver = (StaticTextWidget*)findWidget("lLauncher.Version");
+ StaticTextWidget *ver = (StaticTextWidget*)findWidget("Launcher.Version");
if (ver) {
ver->setAlign((Graphics::TextAlignment)g_gui.xmlEval()->getVar("Launcher.Version.Align", Graphics::kTextAlignCenter));
ver->setLabel(gScummVMVersionDate);
diff --git a/gui/newgui.cpp b/gui/newgui.cpp
index c89937595b..e83c86a451 100644
--- a/gui/newgui.cpp
+++ b/gui/newgui.cpp
@@ -91,31 +91,16 @@ NewGui::NewGui() : _redrawStatus(kRedrawDisabled),
// Clear the cursor
memset(_cursor, 0xFF, sizeof(_cursor));
- bool loadClassicTheme = true;
-#ifndef DISABLE_FANCY_THEMES
+
ConfMan.registerDefault("gui_theme", "default");
Common::String style(ConfMan.get("gui_theme"));
- // The default theme for now is the 'modern' theme.
if (style.compareToIgnoreCase("default") == 0)
- style = "modern";
-
- Common::String styleType;
- Common::ConfigFile cfg;
- if (loadNewTheme(style)) {
- loadClassicTheme = false;
- } else {
- loadClassicTheme = true;
- warning("falling back to classic style");
- }
-#endif
+ style = "builtin";
+
+ //DEBUG:
+ style = "scummodern";
- if (loadClassicTheme) {
- _theme = new ThemeClassic(_system);
- assert(_theme);
- if (!_theme->init()) {
- error("Couldn't initialize classic theme");
- }
- }
+ loadNewTheme(style);
_theme->resetDrawArea();
_themeChange = false;
@@ -129,7 +114,7 @@ bool NewGui::loadNewTheme(const Common::String &style) {
Common::String styleType;
Common::ConfigFile cfg;
- Common::String oldTheme = (_theme != 0) ? _theme->getStylefileName() : "";
+ Common::String oldTheme = (_theme != 0) ? _theme->getThemeName() : "";
if (_theme)
_theme->disable();
@@ -142,38 +127,12 @@ bool NewGui::loadNewTheme(const Common::String &style) {
delete _theme;
_theme = 0;
-/* if (style.compareToIgnoreCase("classic (builtin)") == 0 ||
- style.compareToIgnoreCase("classic") == 0) {
- _theme = new ThemeClassic(_system, style);
- } else {
- if (Theme::themeConfigUseable(style, "", &styleType, &cfg)) {
- if (0 == styleType.compareToIgnoreCase("classic"))
- _theme = new ThemeClassic(_system, style, &cfg);
-#ifndef DISABLE_FANCY_THEMES
- else if (0 == styleType.compareToIgnoreCase("modern"))
- _theme = new ThemeModern(_system, style, &cfg);
-#endif
- else
- warning("Unsupported theme type '%s'", styleType.c_str());
- } else {
- warning("Config '%s' is NOT usable for themes or not found", style.c_str());
- }
- }
- cfg.clear(); */
-
_theme = new ThemeRenderer(style, GUI::ThemeRenderer::kGfxAntialias16bit);
-// _theme = new ThemeRenderer(style, GUI::ThemeRenderer::kGfxStandard16bit);
if (!_theme)
return (!oldTheme.empty() ? loadNewTheme(oldTheme) : false);
- if (!_theme->init()) {
- warning("Could not initialize your preferred theme");
- delete _theme;
- _theme = 0;
- loadNewTheme(oldTheme);
- return false;
- }
+ _theme->init();
_theme->resetDrawArea();
if (!oldTheme.empty())
diff --git a/gui/theme.h b/gui/theme.h
index 0d0fadb8ad..74158f473c 100644
--- a/gui/theme.h
+++ b/gui/theme.h
@@ -371,7 +371,7 @@ public:
static bool themeConfigUseable(const Common::String &file, const Common::String &style="", Common::String *cStyle=0, Common::ConfigFile *cfg=0);
const Common::String &getStylefileName() const { return _stylefile; }
- const Common::String &getThemeName() const { return _stylename; }
+ virtual const Common::String &getThemeName() const { return _stylename; }
virtual bool isDynamic() {
return false;
diff --git a/gui/themes/default.inc b/gui/themes/default.inc
index 961917b05e..262260a7fc 100644
--- a/gui/themes/default.inc
+++ b/gui/themes/default.inc
@@ -28,6 +28,10 @@
"rgb = '63, 60, 17' "
"/> "
"</palette> "
+"<bitmaps> "
+"<bitmap filename = 'logo.bmp'/> "
+"<bitmap filename = 'cursor.bmp'/> "
+"</bitmaps> "
"<fonts> "
"<font id = 'text_default' "
"file = 'default' "
diff --git a/gui/themes/modern.stx b/gui/themes/modern.stx
index 33f557b366..671e9d0856 100644
--- a/gui/themes/modern.stx
+++ b/gui/themes/modern.stx
@@ -56,6 +56,11 @@
rgb = '63, 60, 17'
/>
</palette>
+
+ <bitmaps>
+ <bitmap filename = 'logo.bmp'/>
+ <bitmap filename = 'cursor.bmp'/>
+ </bitmaps>
<fonts>
<font id = 'text_default'
diff --git a/gui/themes/scummodern.zip b/gui/themes/scummodern.zip
new file mode 100644
index 0000000000..67b89951ed
--- /dev/null
+++ b/gui/themes/scummodern.zip
Binary files differ