[Scummvm-cvs-logs] SF.net SVN: scummvm:[33092] scummvm/branches/gsoc2008-gui
Tanoku at users.sourceforge.net
Tanoku at users.sourceforge.net
Thu Jul 17 23:58:46 CEST 2008
Revision: 33092
http://scummvm.svn.sourceforge.net/scummvm/?rev=33092&view=rev
Author: Tanoku
Date: 2008-07-17 21:58:43 +0000 (Thu, 17 Jul 2008)
Log Message:
-----------
Rendering pipeline (almost) fixed. This time for real.
Modified Paths:
--------------
scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp
scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.h
scummvm/branches/gsoc2008-gui/gui/dialog.cpp
scummvm/branches/gsoc2008-gui/gui/newgui.cpp
scummvm/branches/gsoc2008-gui/gui/newgui.h
scummvm/branches/gsoc2008-gui/gui/theme.h
Modified: scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp 2008-07-17 20:08:59 UTC (rev 33091)
+++ scummvm/branches/gsoc2008-gui/graphics/VectorRenderer.cpp 2008-07-17 21:58:43 UTC (rev 33092)
@@ -487,11 +487,7 @@
int real_radius = r;
int short_h = h - r + 2;
int long_h = h;
- PixelType color1, color2;
-
- if (fill_m == kFillForeground || fill_m == kFillBackground)
- color1 = color2 = color;
-
+
if (fill_m == kFillDisabled) {
while (sw++ < Base::_strokeWidth) {
colorFill(ptr_fill + sp + r, ptr_fill + w + 1 + sp - r, color);
@@ -543,6 +539,9 @@
}
} else {
__BE_RESET();
+
+ PixelType color1, color2;
+ color1 = color2 = color;
while (x++ < y) {
__BE_ALGORITHM();
Modified: scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp 2008-07-17 20:08:59 UTC (rev 33091)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.cpp 2008-07-17 21:58:43 UTC (rev 33092)
@@ -76,7 +76,8 @@
ThemeRenderer::ThemeRenderer(Common::String themeName, GraphicsMode mode) :
_vectorRenderer(0), _system(0), _graphicsMode(kGfxDisabled),
- _screen(0), _backBuffer(0), _bytesPerPixel(0), _initOk(false), _themeOk(false), _enabled(false) {
+ _screen(0), _backBuffer(0), _bytesPerPixel(0), _initOk(false),
+ _themeOk(false), _enabled(false), _dialogCount(0), _cachedDialog(0) {
_system = g_system;
_parser = new ThemeParser(this);
@@ -238,8 +239,11 @@
warning("Error when parsing custom theme '%s': Missing data assets.", themeName.c_str());
return false;
#endif
- } else if (_widgets[i]->_cached) {
- // draw the cached widget to the cache surface
+ } else {
+ calcBackgroundOffset((DrawData)i);
+
+ // TODO: draw the cached widget to the cache surface
+ if (_widgets[i]->_cached) {}
}
}
@@ -293,6 +297,14 @@
void ThemeRenderer::drawDD(DrawData type, const Common::Rect &r, uint32 dynamicData) {
if (_widgets[type] == 0)
return;
+
+ Common::Rect extendedRect = r;
+ extendedRect.grow(kDirtyRectangleThreshold);
+ extendedRect.right += _widgets[type]->_backgroundOffset;
+ extendedRect.bottom += _widgets[type]->_backgroundOffset;
+
+ restoreBackground(extendedRect);
+ addDirtyRect(extendedRect);
if (isWidgetCached(type, r)) {
drawCached(type, r);
@@ -312,6 +324,33 @@
}
}
+void ThemeRenderer::calcBackgroundOffset(DrawData type) {
+ uint maxShadow = 0;
+ for (Common::List<Graphics::DrawStep>::const_iterator step = _widgets[type]->_steps.begin();
+ step != _widgets[type]->_steps.end(); ++step) {
+ if (((*step).autoWidth || (*step).autoHeight) && (*step).shadow > maxShadow)
+ maxShadow = (*step).shadow;
+ }
+
+ _widgets[type]->_backgroundOffset = maxShadow;
+}
+
+void ThemeRenderer::restoreBackground(Common::Rect r, bool special) {
+/* const OverlayColor *src = (const OverlayColor*)_backBuffer->getBasePtr(r.left, r.top);
+ OverlayColor *dst = (OverlayColor*)_screen->getBasePtr(r.left, r.top);
+
+ int h = r.height();
+ int w = r.width();
+ while (h--) {
+ memcpy(dst, src, w * sizeof(OverlayColor));
+ src += _backBuffer->w;
+ dst += _screen->w;
+ }*/
+
+ debugWidgetPosition("", r);
+ printf(" BG_RESTORE ");
+}
+
void ThemeRenderer::drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, uint16 hints) {
if (!ready())
return;
@@ -327,8 +366,6 @@
drawDD(dd, r);
drawDDText(dd, r, str);
-
- addDirtyRect(r);
}
void ThemeRenderer::drawLineSeparator(const Common::Rect &r, WidgetStateInfo state) {
@@ -336,7 +373,6 @@
return;
drawDD(kDDSeparator, r);
- addDirtyRect(r);
}
void ThemeRenderer::drawCheckbox(const Common::Rect &r, const Common::String &str, bool checked, WidgetStateInfo state) {
@@ -355,8 +391,6 @@
r2.right = r.right;
drawDDText(checked ? kDDCheckboxEnabled : kDDCheckboxDisabled, r2, str);
-
- addDirtyRect(r);
}
void ThemeRenderer::drawSlider(const Common::Rect &r, int width, WidgetStateInfo state) {
@@ -369,8 +403,6 @@
r2.setWidth(MIN((int16)width, r.width()));
drawDD(kDDSliderFull, r2);
-
- addDirtyRect(r);
}
void ThemeRenderer::drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, ScrollbarState sb_state, WidgetStateInfo state) {
@@ -379,8 +411,6 @@
drawDD(kDDScrollbarBase, r);
// TODO: Need to find a scrollbar in the GUI for testing... :p
-
- addDirtyRect(r);
}
void ThemeRenderer::drawDialogBackground(const Common::Rect &r, uint16 hints, WidgetStateInfo state) {
@@ -396,8 +426,6 @@
} else {
drawDD(kDDDefaultBackground, r);
}
-
- addDirtyRect(r);
}
void ThemeRenderer::drawCaret(const Common::Rect &r, bool erase, WidgetStateInfo state) {
@@ -405,7 +433,6 @@
return;
debugWidgetPosition("Caret", r);
- addDirtyRect(r);
}
void ThemeRenderer::drawPopUpWidget(const Common::Rect &r, const Common::String &sel, int deltax, WidgetStateInfo state, TextAlign align) {
@@ -420,8 +447,6 @@
Common::Rect text(r.left, r.top, r.right - 16, r.bottom);
drawDDText(dd, text, sel);
}
-
- addDirtyRect(r);
}
void ThemeRenderer::drawSurface(const Common::Rect &r, const Graphics::Surface &surface, WidgetStateInfo state, int alpha, bool themeTrans) {
@@ -452,8 +477,6 @@
drawDD(kDDWidgetBackgroundDefault, r);
break;
}
-
- addDirtyRect(r);
}
void ThemeRenderer::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, const Common::Array<Common::String> &tabs, int active, uint16 hints, int titleVPad, WidgetStateInfo state) {
@@ -514,4 +537,24 @@
_dirtyScreen.clear();
}
+void ThemeRenderer::openDialog(bool top) {
+ if (_dialogCount++ == 0)
+ return;
+
+ _cachedDialog = _dialogCount - 1;
+ memcpy(_backBuffer->pixels, _screen->pixels, _screen->w * _screen->h * _screen->bytesPerPixel);
+}
+
+bool ThemeRenderer::closeDialog() {
+ assert(_dialogCount);
+
+ _dialogCount--;
+
+ if (_dialogCount != _cachedDialog)
+ return false;
+
+ memcpy(_screen->pixels, _backBuffer->pixels, _screen->w * _screen->h * _screen->bytesPerPixel);
+ return true;
+}
+
} // end of namespace GUI.
Modified: scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.h 2008-07-17 20:08:59 UTC (rev 33091)
+++ scummvm/branches/gsoc2008-gui/gui/ThemeRenderer.h 2008-07-17 21:58:43 UTC (rev 33092)
@@ -42,13 +42,23 @@
struct WidgetDrawData;
struct WidgetDrawData {
+ /** List of all the steps needed to draw this widget */
Common::List<Graphics::DrawStep> _steps;
+
+ /** Single step that defines the text shown inside the widget */
Graphics::TextStep _textStep;
bool _hasText;
+ /** Extra space that the widget occupies when it's drawn.
+ E.g. when taking into account rounded corners, drop shadows, etc
+ Used when restoring the widget background */
+ uint16 _backgroundOffset;
+
+ /** Sets whether the widget is cached beforehand. */
bool _cached;
+
+ /** Texture where the cached widget is stored. */
Graphics::Surface *_surfaceCache;
- uint32 _cachedW, _cachedH;
~WidgetDrawData() {
_steps.clear();
@@ -145,14 +155,18 @@
void refresh() {}
void enable();
void disable();
- void openDialog() {}
- void closeAllDialogs() {}
+
+ void closeAllDialogs() {
+ _dialogCount = 0;
+ _cachedDialog = 0;
+ }
void updateScreen(); //{}
void resetDrawArea() {}
- void openDialog(bool top) {}
+ void openDialog(bool top);// {}
+ bool closeDialog();// {}
/** Font management */
const Graphics::Font *getFont(FontStyle font) const { return _font; }
@@ -177,7 +191,7 @@
void drawChar(const Common::Rect &r, byte ch, const Graphics::Font *font, WidgetStateInfo state) {}
bool addDirtyRect(Common::Rect r, bool backup = false, bool special = false) {
- r.grow(kDirtyRectangleThreshold);
+// r.grow(kDirtyRectangleThreshold);
_dirtyScreen.push_back(r);
return true;
}
@@ -260,13 +274,14 @@
bool isWidgetCached(DrawData type, const Common::Rect &r);
void drawCached(DrawData type, const Common::Rect &r);
+ void calcBackgroundOffset(DrawData type);
inline void drawDD(DrawData type, const Common::Rect &r, uint32 dynamicData = 0);
inline void drawDDText(DrawData type, const Common::Rect &r, const Common::String &text);
inline void debugWidgetPosition(const char *name, const Common::Rect &r);
// TODO
- void restoreBackground(Common::Rect r, bool special = false) {}
+ void restoreBackground(Common::Rect r, bool special = false);
int getTabSpacing() const {
return 0;
@@ -295,6 +310,8 @@
Graphics::Surface *_screen;
Graphics::Surface *_backBuffer;
+ uint32 _dialogCount;
+ uint32 _cachedDialog;
int _bytesPerPixel;
GraphicsMode _graphicsMode;
Modified: scummvm/branches/gsoc2008-gui/gui/dialog.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/dialog.cpp 2008-07-17 20:08:59 UTC (rev 33091)
+++ scummvm/branches/gsoc2008-gui/gui/dialog.cpp 2008-07-17 21:58:43 UTC (rev 33092)
@@ -132,7 +132,11 @@
}
void Dialog::draw() {
- g_gui._needRedraw = true;
+ //TANOKU - FIXME when is this enabled? what does this do?
+ // Update: called on tab drawing, mainly...
+ // we can pass this as open a new dialog or something
+// g_gui._needRedraw = true;
+ g_gui._redrawStatus = GUI::NewGui::kRedrawTopDialog;
}
void Dialog::drawDialog() {
Modified: scummvm/branches/gsoc2008-gui/gui/newgui.cpp
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/newgui.cpp 2008-07-17 20:08:59 UTC (rev 33091)
+++ scummvm/branches/gsoc2008-gui/gui/newgui.cpp 2008-07-17 21:58:43 UTC (rev 33092)
@@ -81,7 +81,7 @@
}
// Constructor
-NewGui::NewGui() : _needRedraw(false),
+NewGui::NewGui() : _redrawStatus(kRedrawDisabled),
_stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) {
_theme = 0;
_useStdCursor = false;
@@ -187,29 +187,48 @@
void NewGui::redraw() {
int i;
- // Restore the overlay to its initial state, then draw all dialogs.
- // This is necessary to get the blending right.
- _theme->clearAll();
+ if (_redrawStatus == kRedrawDisabled)
+ return;
- _theme->closeAllDialogs();
- //for (i = 0; i < _dialogStack.size(); ++i)
- // _theme->closeDialog();
+ switch (_redrawStatus) {
+ case kRedrawCloseDialog:
+ printf("Dialog closed!\n");
+ if (_theme->closeDialog())
+ break;
- for (i = 0; i < _dialogStack.size(); i++) {
- // Special treatment when topmost dialog has dimsInactive() set to false
- // This is the case for PopUpWidget which should not dim a dialog
- // which it belongs to
- if ((i == _dialogStack.size() - 2) && !_dialogStack[i + 1]->dimsInactive())
+ case kRedrawFull:
+ _theme->clearAll();
+ _theme->closeAllDialogs();
+
+ for (i = 0; i < _dialogStack.size(); i++) {
+ if ((i == _dialogStack.size() - 2) && !_dialogStack[i + 1]->dimsInactive())
+ _theme->openDialog(true);
+ else if ((i != (_dialogStack.size() - 1)) || !_dialogStack[i]->dimsInactive())
+ _theme->openDialog(false);
+ else
+ _theme->openDialog(true);
+
+ _dialogStack[i]->drawDialog();
+ }
+ break;
+
+ case kRedrawTopDialog:
+ _dialogStack.top()->drawDialog();
+ printf("Top dialog redraw!\n");
+ break;
+
+ case kRedrawOpenDialog:
_theme->openDialog(true);
- else if ((i != (_dialogStack.size() - 1)) || !_dialogStack[i]->dimsInactive())
- _theme->openDialog(false);
- else
- _theme->openDialog(true);
+ _dialogStack.top()->drawDialog();
+ printf("Dialog opened!\n");
+ break;
- _dialogStack[i]->drawDialog();
+ default:
+ return;
}
_theme->updateScreen();
+ _redrawStatus = kRedrawDisabled;
}
Dialog *NewGui::getTopDialog() const {
@@ -240,10 +259,7 @@
Common::EventManager *eventMan = _system->getEventManager();
while (!_dialogStack.empty() && activeDialog == getTopDialog()) {
- if (_needRedraw) {
- redraw();
- _needRedraw = false;
- }
+ redraw();
// Don't "tickle" the dialog until the theme has had a chance
// to re-allocate buffers in case of a scaler change.
@@ -274,6 +290,7 @@
_theme->refresh();
_themeChange = false;
+ _redrawStatus = kRedrawFull;
redraw();
}
@@ -330,11 +347,6 @@
_system->delayMillis(10);
}
- // HACK: since we reopen all dialogs anyway on redraw
- // we for now use Theme::closeAllDialogs here, until
- // we properly add (and implement) Theme::closeDialog
- _theme->closeAllDialogs();
-
if (didSaveState) {
_theme->disable();
restoreState();
@@ -366,7 +378,7 @@
void NewGui::openDialog(Dialog *dialog) {
_dialogStack.push(dialog);
- _needRedraw = true;
+ _redrawStatus = kRedrawOpenDialog;
// We reflow the dialog just before opening it. If the screen changed
// since the last time we looked, also refresh the loaded theme,
@@ -393,7 +405,7 @@
// Remove the dialog from the stack
_dialogStack.pop();
- _needRedraw = true;
+ _redrawStatus = kRedrawCloseDialog;
}
void NewGui::setupCursor() {
@@ -451,6 +463,7 @@
// We need to redraw immediately. Otherwise
// some other event may cause a widget to be
// redrawn before redraw() has been called.
+ _redrawStatus = kRedrawFull;
redraw();
}
Modified: scummvm/branches/gsoc2008-gui/gui/newgui.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/newgui.h 2008-07-17 20:08:59 UTC (rev 33091)
+++ scummvm/branches/gsoc2008-gui/gui/newgui.h 2008-07-17 21:58:43 UTC (rev 33092)
@@ -90,12 +90,21 @@
void screenChange();
+ enum RedrawStatus {
+ kRedrawDisabled = 0,
+ kRedrawOpenDialog,
+ kRedrawCloseDialog,
+ kRedrawTopDialog,
+ kRedrawFull
+ };
+
protected:
OSystem *_system;
Theme *_theme;
- bool _needRedraw;
+// bool _needRedraw;
+ RedrawStatus _redrawStatus;
int _lastScreenChangeID;
DialogStack _dialogStack;
Modified: scummvm/branches/gsoc2008-gui/gui/theme.h
===================================================================
--- scummvm/branches/gsoc2008-gui/gui/theme.h 2008-07-17 20:08:59 UTC (rev 33091)
+++ scummvm/branches/gsoc2008-gui/gui/theme.h 2008-07-17 21:58:43 UTC (rev 33092)
@@ -239,6 +239,20 @@
virtual void closeAllDialogs() = 0;
/**
+ * Closes the topmost dialog, and redraws the screen
+ * accordingly.
+ *
+ * TODO: Make this purely virtual by making ThemeClassic
+ * and ThemeModern implement it too.
+ *
+ * @returns True if the dialog was sucessfully closed.
+ * If we weren't able to restore the screen after closing
+ * the dialog, we return false, which means we need to redraw
+ * the dialog stack from scratch.
+ */
+ virtual bool closeDialog() { return false; }
+
+ /**
* Clear the complete GUI screen.
*/
virtual void clearAll() = 0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list