mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-18 07:53:12 +00:00
Patch #1183808 (GUI: Less CPU-intensive credits scroll), with some tweaks by me
svn-id: r17620
This commit is contained in:
parent
e9be61a465
commit
7aebedcc14
6
TODO
6
TODO
@ -196,12 +196,6 @@ GUI
|
||||
* 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
|
||||
========
|
||||
|
@ -120,16 +120,33 @@ void AboutDialog::open() {
|
||||
_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.copyToSurface(&_canvas, _x, _y, _w, _h);
|
||||
}
|
||||
|
||||
g_gui.drawSurface(_canvas, _x, _y);
|
||||
|
||||
// Draw text
|
||||
// TODO: Add a "fade" effect for the top/bottom text lines
|
||||
// TODO: Maybe prerender all of the text into another surface,
|
||||
// and then simply compose that over the screen surface
|
||||
// in the right way. Should be even faster...
|
||||
const int firstLine = _scrollPos / _lineHeight;
|
||||
const int lastLine = MIN((_scrollPos + _h) / _lineHeight + 1, (uint32)_lines.size());
|
||||
int y = _y + kYOff - (_scrollPos % _lineHeight);
|
||||
@ -212,13 +229,18 @@ void AboutDialog::handleTickle() {
|
||||
} 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. Reset the canvas, to ensure it gets
|
||||
// refreshed next time a redraw takes place.
|
||||
free(_canvas.pixels);
|
||||
_canvas.pixels = NULL;
|
||||
}
|
||||
|
||||
void AboutDialog::handleMouseUp(int x, int y, int button, int clickCount) {
|
||||
// Close upon any mouse click
|
||||
close();
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "gui/dialog.h"
|
||||
#include "common/str.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
namespace GUI {
|
||||
|
||||
@ -35,13 +36,16 @@ protected:
|
||||
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);
|
||||
|
@ -301,6 +301,54 @@ void NewGui::vLine(int x, int y, int y2, OverlayColor color) {
|
||||
_screen.vLine(x * _scaleFactor, y * _scaleFactor, y2 * _scaleFactor, color);
|
||||
}
|
||||
|
||||
void NewGui::copyToSurface(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::drawSurface(const 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;
|
||||
|
||||
assert(s.bytesPerPixel == sizeof(OverlayColor));
|
||||
|
||||
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);
|
||||
|
13
gui/newgui.h
13
gui/newgui.h
@ -134,6 +134,19 @@ public:
|
||||
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);
|
||||
|
||||
/**
|
||||
* Copy the specified screen rectangle into a new graphics surfaces.
|
||||
* New memory for the GFX data is allocated via malloc; it is the
|
||||
* callers responsibilty to free that data.
|
||||
*/
|
||||
void copyToSurface(Graphics::Surface *s, int x, int y, int w, int h);
|
||||
|
||||
/**
|
||||
* Draw the graphics contained in the given surface at the specified coordinates.
|
||||
*/
|
||||
void drawSurface(const 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user