diff -ur --exclude=CVS --exclude=Makefile ScummVM/TODO ScummVM+hack/TODO
--- ScummVM/TODO	2005-04-15 12:14:46.044921500 +0200
+++ ScummVM+hack/TODO	2005-04-15 16:33:48.875427500 +0200
@@ -196,12 +196,6 @@
 * Maybe add the ScummVM logo (+typeface?) to the about dialog
 * Unify DirBrowserDialog and FileBrowserDialog.
 * MacOS X version of FileBrowserDialog, since there is one of DirBrowserDialog.
-* The credits scroll is too CPU intensive. This is because for each time the
-  text is redrawn it has to do a full redraw, which causes blendRect() to be
-  called twice. Perhaps AboutDialog could keep a private copy of the blended
-  background so that it wouldn't have to be re-generated each time? Of course
-  we'd probably have to take screen changes into account, but there already is
-  a mechanism for that, I believe.
 
 Launcher
 ========
diff -ur --exclude=CVS --exclude=Makefile ScummVM/gui/about.cpp ScummVM+hack/gui/about.cpp
--- ScummVM/gui/about.cpp	2005-01-10 23:35:40.000000000 +0100
+++ ScummVM+hack/gui/about.cpp	2005-04-15 16:37:02.465171600 +0200
@@ -120,13 +120,27 @@
 	_scrollPos = 0;
 	_modifiers = 0;
 	_willClose = false;
+	_canvas.pixels = NULL;
 
 	Dialog::open();
 }
 
+void AboutDialog::close() {
+	free(_canvas.pixels);
+	Dialog::close();
+}
+
 void AboutDialog::drawDialog() {
-	// Blend over the background
-	g_gui.blendRect(_x, _y, _w, _h, g_gui._bgcolor);
+	if (!_canvas.pixels) {
+		// Blend over the background. Since we can't afford to do that
+		// every time the text is updated (it's horribly CPU intensive)
+		// we do it just once and then use a copy of the result as our
+		// static background for the remainder of the credits.
+		g_gui.blendRect(_x, _y, _w, _h, g_gui._bgcolor);
+		g_gui.getRect(&_canvas, _x, _y, _w, _h);
+	}
+
+	g_gui.putRect(&_canvas, _x, _y);
 
 	// Draw text
 	// TODO: Add a "fade" effect for the top/bottom text lines
@@ -212,13 +226,19 @@
 		} else if ((uint32)_scrollPos > _lines.size() * _lineHeight) {
 			_scrollPos = 0;
 			_scrollTime += kScrollStartDelay;
-		} else {
-			g_gui.addDirtyRect(_x, _y, _w, _h);
 		}
-		draw();	// Issue a full redraw
+		drawDialog();
 	}
 }
 
+void AboutDialog::handleScreenChanged() {
+	// The screen has changed. Do a full redraw to ensure that the canvas
+	// we draw the text on will still have the correct background image.
+	free(_canvas.pixels);
+	_canvas.pixels = NULL;
+	draw();
+}
+
 void AboutDialog::handleMouseUp(int x, int y, int button, int clickCount) {
 	// Close upon any mouse click
 	close();
diff -ur --exclude=CVS --exclude=Makefile ScummVM/gui/about.h ScummVM+hack/gui/about.h
--- ScummVM/gui/about.h	2005-01-01 17:09:06.000000000 +0100
+++ ScummVM+hack/gui/about.h	2005-04-15 16:01:26.427475200 +0200
@@ -23,6 +23,7 @@
 
 #include "gui/dialog.h"
 #include "common/str.h"
+#include "graphics/surface.h"
 
 namespace GUI {
 
@@ -35,13 +36,16 @@
 	uint32		_lineHeight;
 	byte		_modifiers;
 	bool		_willClose;
+	Graphics::Surface	_canvas;
 
 public:
 	AboutDialog();
 
 	void open();
+	void close();
 	void drawDialog();
 	void handleTickle();
+	void handleScreenChanged();
 	void handleMouseUp(int x, int y, int button, int clickCount);
 	void handleKeyDown(uint16 ascii, int keycode, int modifiers);
 	void handleKeyUp(uint16 ascii, int keycode, int modifiers);
diff -ur --exclude=CVS --exclude=Makefile ScummVM/gui/newgui.cpp ScummVM+hack/gui/newgui.cpp
--- ScummVM/gui/newgui.cpp	2005-04-03 21:43:31.612737700 +0200
+++ ScummVM+hack/gui/newgui.cpp	2005-04-15 16:26:11.947769600 +0200
@@ -301,6 +301,52 @@
 	_screen.vLine(x * _scaleFactor, y * _scaleFactor, y2 * _scaleFactor, color);
 }
 
+void NewGui::getRect(Graphics::Surface *s, int x, int y, int w, int h) {
+	Common::Rect rect(x * _scaleFactor, y * _scaleFactor, (x + w) * _scaleFactor, (y + h) * _scaleFactor);
+	rect.clip(_screen.w, _screen.h);
+
+	if (!rect.isValidRect())
+		return;
+
+	s->w = rect.width();
+	s->h = rect.height();
+	s->bytesPerPixel = sizeof(OverlayColor);
+	s->pitch = s->w * s->bytesPerPixel;
+	s->pixels = (OverlayColor *)malloc(s->pitch * s->h);
+
+	w = s->w;
+	h = s->h;
+
+	OverlayColor *dst = (OverlayColor *)s->pixels;
+	OverlayColor *src = getBasePtr(rect.left, rect.top);
+
+	while (h--) {
+		memcpy(dst, src, s->pitch);
+		src += _screenPitch;
+		dst += s->w;
+	}
+}
+
+void NewGui::putRect(Graphics::Surface *s, int x, int y) {
+	Common::Rect rect(x * _scaleFactor, y * _scaleFactor, x * _scaleFactor + s->w, y * _scaleFactor + s->h);
+	rect.clip(_screen.w, _screen.h);
+
+	if (!rect.isValidRect())
+		return;
+
+	OverlayColor *src = (OverlayColor *)s->pixels;
+	OverlayColor *dst = getBasePtr(rect.left, rect.top);
+
+	int w = rect.width();
+	int h = rect.height();
+
+	while (h--) {
+		memcpy(dst, src, s->pitch);
+		src += w;
+		dst += _screenPitch;
+	}
+}
+
 void NewGui::blendRect(int x, int y, int w, int h, OverlayColor color, int level) {
 #ifdef NEWGUI_256
 	fillRect(x, y, w, h, color);
diff -ur --exclude=CVS --exclude=Makefile ScummVM/gui/newgui.h ScummVM+hack/gui/newgui.h
--- ScummVM/gui/newgui.h	2005-01-10 23:05:38.000000000 +0100
+++ ScummVM+hack/gui/newgui.h	2005-04-15 15:44:11.130147300 +0200
@@ -134,6 +134,8 @@
 	void box(int x, int y, int width, int height, OverlayColor colorA, OverlayColor colorB);
 	void hLine(int x, int y, int x2, OverlayColor color);
 	void vLine(int x, int y, int y2, OverlayColor color);
+	void getRect(Graphics::Surface *s, int x, int y, int w, int h);
+	void putRect(Graphics::Surface *s, int x, int y);
 	void blendRect(int x, int y, int w, int h, OverlayColor color, int level = 3);
 	void fillRect(int x, int y, int w, int h, OverlayColor color);
 	void frameRect(int x, int y, int w, int h, OverlayColor color);
