[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