[Scummvm-git-logs] scummvm master -> f28808007b9a97f694d5b7df3f584b16a026512e
npjg
nathanael.gentrydb8 at gmail.com
Wed Aug 12 06:35:49 UTC 2020
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
07166de33f GRAPHICS: MACGUI: Add dirty rect handling to MacWindow
59dd1716b1 GRAPHICS: MACGUI: Put pause token on heap
a639ae4002 GRAPHICS: MACGUI: Add WM direct copy mode
f28808007b DIRECTOR: Eliminate intermediate surface
Commit: 07166de33fcbf0c0438c7e1944b2f3063eba223a
https://github.com/scummvm/scummvm/commit/07166de33fcbf0c0438c7e1944b2f3063eba223a
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-08-12T02:34:24-04:00
Commit Message:
GRAPHICS: MACGUI: Add dirty rect handling to MacWindow
The Director engine, which relied on this functionality in its Window class, is
also updated.
Changed paths:
engines/director/window.cpp
engines/director/window.h
graphics/macgui/macwindow.cpp
graphics/macgui/macwindow.h
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 8d786c4735..3759920451 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -132,44 +132,6 @@ void Window::reset() {
_contentIsDirty = true;
}
-void Window::addDirtyRect(const Common::Rect &r) {
- if (!r.isValidRect())
- return;
-
- Common::Rect bounds = r;
- bounds.clip(Common::Rect(_innerDims.width(), _innerDims.height()));
-
- if (bounds.width() > 0 && bounds.height() > 0)
- _dirtyRects.push_back(bounds);
-}
-
-void Window::markAllDirty() {
- _dirtyRects.clear();
- _dirtyRects.push_back(Common::Rect(_composeSurface->w, _composeSurface->h));
-}
-
-void Window::mergeDirtyRects() {
- Common::List<Common::Rect>::iterator rOuter, rInner;
-
- // Process the dirty rect list to find any rects to merge
- for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
- rInner = rOuter;
- while (++rInner != _dirtyRects.end()) {
-
- if ((*rOuter).intersects(*rInner)) {
- // These two rectangles overlap, so merge them
- rOuter->extend(*rInner);
-
- // remove the inner rect from the list
- _dirtyRects.erase(rInner);
-
- // move back to beginning of list
- rInner = rOuter;
- }
- }
- }
-}
-
void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo) {
Common::Rect srcRect = channel->getBbox();
destRect.clip(srcRect);
diff --git a/engines/director/window.h b/engines/director/window.h
index 98cd140398..d80e080b07 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -98,9 +98,6 @@ class Window : public Graphics::MacWindow, public Object<Window> {
void setStageColor(uint stageColor, bool forceReset = false);
int getStageColor() { return _stageColor; }
- void addDirtyRect(const Common::Rect &r);
- void markAllDirty();
- void mergeDirtyRects();
void reset();
// transitions.cpp
@@ -164,7 +161,6 @@ class Window : public Graphics::MacWindow, public Object<Window> {
virtual bool setField(int field, const Datum &value);
public:
- Common::List<Common::Rect> _dirtyRects;
Common::List<Channel *> _dirtyChannels;
TransParams *_puppetTransition;
diff --git a/graphics/macgui/macwindow.cpp b/graphics/macgui/macwindow.cpp
index 428910d168..861f8447d8 100644
--- a/graphics/macgui/macwindow.cpp
+++ b/graphics/macgui/macwindow.cpp
@@ -669,4 +669,42 @@ void MacWindow::setBorderType(int borderType) {
}
}
+void MacWindow::addDirtyRect(const Common::Rect &r) {
+ if (!r.isValidRect())
+ return;
+
+ Common::Rect bounds = r;
+ bounds.clip(Common::Rect(_innerDims.width(), _innerDims.height()));
+
+ if (bounds.width() > 0 && bounds.height() > 0)
+ _dirtyRects.push_back(bounds);
+}
+
+void MacWindow::markAllDirty() {
+ _dirtyRects.clear();
+ _dirtyRects.push_back(Common::Rect(_composeSurface->w, _composeSurface->h));
+}
+
+void MacWindow::mergeDirtyRects() {
+ Common::List<Common::Rect>::iterator rOuter, rInner;
+
+ // Process the dirty rect list to find any rects to merge
+ for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
+ rInner = rOuter;
+ while (++rInner != _dirtyRects.end()) {
+
+ if ((*rOuter).intersects(*rInner)) {
+ // These two rectangles overlap, so merge them
+ rOuter->extend(*rInner);
+
+ // remove the inner rect from the list
+ _dirtyRects.erase(rInner);
+
+ // move back to beginning of list
+ rInner = rOuter;
+ }
+ }
+ }
+}
+
} // End of namespace Graphics
diff --git a/graphics/macgui/macwindow.h b/graphics/macgui/macwindow.h
index ac9dfe779f..515c5cee8b 100644
--- a/graphics/macgui/macwindow.h
+++ b/graphics/macgui/macwindow.h
@@ -302,6 +302,11 @@ public:
*/
int getBorderType() { return _borderType; };
+
+ void addDirtyRect(const Common::Rect &r);
+ void markAllDirty();
+ void mergeDirtyRects();
+
private:
void prepareBorderSurface(ManagedSurface *g);
void drawSimpleBorder(ManagedSurface *g);
@@ -327,6 +332,8 @@ protected:
bool _borderIsDirty;
Common::Rect _innerDims;
+ Common::List<Common::Rect> _dirtyRects;
+
private:
MacWindowBorder _macBorder;
@@ -351,8 +358,6 @@ private:
int _borderType;
};
-
-
} // End of namespace Graphics
#endif
Commit: 59dd1716b1734a1e2c8c55f95b7c6a4b9dfd1f6d
https://github.com/scummvm/scummvm/commit/59dd1716b1734a1e2c8c55f95b7c6a4b9dfd1f6d
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-08-12T02:34:24-04:00
Commit Message:
GRAPHICS: MACGUI: Put pause token on heap
Changed paths:
graphics/macgui/macwindowmanager.cpp
graphics/macgui/macwindowmanager.h
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index 58e0257e2c..a739787ccd 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -177,6 +177,7 @@ MacWindowManager::MacWindowManager(uint32 mode, MacPatterns *patterns) {
_engineP = nullptr;
_engineR = nullptr;
_redrawEngineCallback = nullptr;
+ _screenCopyPauseToken = nullptr;
_colorBlack = kColorBlack;
_colorGray80 = kColorGray80;
@@ -237,7 +238,7 @@ void MacWindowManager::setScreen(ManagedSurface *screen) {
_desktop->free();
else
_desktop = new ManagedSurface();
-
+
_desktop->create(_screen->w, _screen->h, PixelFormat::createFormatCLUT8());
drawDesktop();
}
@@ -331,11 +332,19 @@ void MacWindowManager::activateScreenCopy() {
else
*_screenCopy = *_screen;
- _screenCopyPauseToken = pauseEngine();
+ _screenCopyPauseToken = new PauseToken(pauseEngine());
}
void MacWindowManager::disableScreenCopy() {
- _screenCopyPauseToken.clear();
+ if (!_screen)
+ return;
+
+ if (_screenCopyPauseToken) {
+ _screenCopyPauseToken->clear();
+ delete _screenCopyPauseToken;
+ _screenCopyPauseToken = nullptr;
+ }
+
*_screen = *_screenCopy; // restore screen
g_system->copyRectToScreen(_screenCopy->getBasePtr(0, 0), _screenCopy->pitch, 0, 0, _screenCopy->w, _screenCopy->h);
}
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index e4ac87c80e..e176029110 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -355,7 +355,7 @@ private:
MacWidget *_activeWidget;
- PauseToken _screenCopyPauseToken;
+ PauseToken *_screenCopyPauseToken;
Common::Array<ZoomBox *> _zoomBoxes;
Common::HashMap<uint32, uint> _colorHash;
Commit: a639ae4002ffa9497e2e60b3b2382a67d618f32a
https://github.com/scummvm/scummvm/commit/a639ae4002ffa9497e2e60b3b2382a67d618f32a
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-08-12T02:34:45-04:00
Commit Message:
GRAPHICS: MACGUI: Add WM direct copy mode
This does not keep the current screen state cached in a surface, but re-creates
the screen from its various components each time something changes. This avoids
an intermediate blitting.
The mode is enabled just by not providing a surface to the WM, and instead
providing a width and height.
Changed paths:
graphics/macgui/macmenu.h
graphics/macgui/macwindow.cpp
graphics/macgui/macwindow.h
graphics/macgui/macwindowmanager.cpp
graphics/macgui/macwindowmanager.h
diff --git a/graphics/macgui/macmenu.h b/graphics/macgui/macmenu.h
index b579fd21fc..b41d081683 100644
--- a/graphics/macgui/macmenu.h
+++ b/graphics/macgui/macmenu.h
@@ -52,6 +52,10 @@ public:
MacMenu(int id, const Common::Rect &bounds, MacWindowManager *wm);
~MacMenu();
+ virtual ManagedSurface *getBorderSurface() override { return nullptr; }
+ virtual const Common::Rect &getInnerDimensions() override { return _dims; }
+ virtual bool isDirty() override { return _contentIsDirty || _dimensionsDirty; }
+
static Common::StringArray *readMenuFromResource(Common::SeekableReadStream *res);
static MacMenu *createMenuFromPEexe(Common::PEResources *exe, MacWindowManager *wm);
diff --git a/graphics/macgui/macwindow.cpp b/graphics/macgui/macwindow.cpp
index 861f8447d8..922a9452e9 100644
--- a/graphics/macgui/macwindow.cpp
+++ b/graphics/macgui/macwindow.cpp
@@ -191,7 +191,7 @@ void MacWindow::center(bool toCenter) {
if (!_wm)
return;
- Common::Rect screen = _wm->_screen->getBounds();
+ Common::Rect screen = _wm->getScreenBounds();
if (toCenter) {
move((screen.width() - _dims.width()) / 2, (screen.height() - _dims.height()) / 2);
diff --git a/graphics/macgui/macwindow.h b/graphics/macgui/macwindow.h
index 515c5cee8b..7f87a34f1c 100644
--- a/graphics/macgui/macwindow.h
+++ b/graphics/macgui/macwindow.h
@@ -115,6 +115,28 @@ public:
*/
ManagedSurface *getWindowSurface() { return _composeSurface; }
+ /**
+ * Method to access the border surface of the window.
+ * @return A pointer to the border surface of the window.
+ */
+ virtual ManagedSurface *getBorderSurface() = 0;
+
+ /**
+ * Accessor to retrieve the dimensions of the inner surface of the window
+ * (i.e. without taking borders into account).
+ * Note that the returned dimensions' position is relative to the WM's
+ * screen, just like in getDimensions().
+ * @return The inner dimensions of the window.
+ */
+ virtual const Common::Rect &getInnerDimensions() = 0;
+
+ /**
+ * Method called to internally draw the window. This relies on the window
+ * being marked as dirty unless otherwise specified.
+ * @param forceRedraw Its behavior depends on the subclass.
+ */
+ virtual bool draw(bool forceRedraw = false) = 0;
+
/**
* Method called to draw the window into the target surface.
* This method is most often called by the WM, and relies on
@@ -133,6 +155,11 @@ public:
*/
virtual bool processEvent(Common::Event &event) = 0;
+ /**
+ * Method that checks if the window is needs redrawing.
+ */
+ virtual bool isDirty() = 0;
+
/**
* Set the callback that will be used when an event needs to be processed.
* @param callback A function pointer to a function that accepts:
@@ -196,15 +223,6 @@ public:
*/
virtual void setDimensions(const Common::Rect &r) override;
- /**
- * Accessor to retrieve the dimensions of the inner surface of the window
- * (i.e. without taking borders into account).
- * Note that the returned dimensions' position is relative to the WM's
- * screen, just like in getDimensions().
- * @return The inner dimensions of the window.
- */
- const Common::Rect &getInnerDimensions() { return _innerDims; }
-
/**
* Set a background pattern for the window.
* @param pattern
@@ -221,6 +239,9 @@ public:
virtual bool draw(bool forceRedraw = false) override;
virtual void blit(ManagedSurface *g, Common::Rect &dest) override;
+ virtual const Common::Rect &getInnerDimensions() override { return _innerDims; }
+ virtual ManagedSurface *getBorderSurface() override { return &_borderSurface; }
+
/**
* Centers the window using the dimensions of the parent window manager, or undoes this; does
* nothing if WM is null.
@@ -307,6 +328,8 @@ public:
void markAllDirty();
void mergeDirtyRects();
+ virtual bool isDirty() override { return _borderIsDirty || _contentIsDirty; }
+
private:
void prepareBorderSurface(ManagedSurface *g);
void drawSimpleBorder(ManagedSurface *g);
diff --git a/graphics/macgui/macwindowmanager.cpp b/graphics/macgui/macwindowmanager.cpp
index a739787ccd..2524c646ce 100644
--- a/graphics/macgui/macwindowmanager.cpp
+++ b/graphics/macgui/macwindowmanager.cpp
@@ -156,7 +156,7 @@ static const byte macCursorCrossBar[] = {
static void menuTimerHandler(void *refCon);
MacWindowManager::MacWindowManager(uint32 mode, MacPatterns *patterns) {
- _screen = 0;
+ _screen = nullptr;
_screenCopy = nullptr;
_desktopBmp = nullptr;
_desktop = nullptr;
@@ -243,6 +243,17 @@ void MacWindowManager::setScreen(ManagedSurface *screen) {
drawDesktop();
}
+void MacWindowManager::setScreen(int w, int h) {
+ if (_desktop)
+ _desktop->free();
+ else
+ _desktop = new ManagedSurface();
+
+ _screenDims = Common::Rect(w, h);
+ _desktop->create(w, h, PixelFormat::createFormatCLUT8());
+ drawDesktop();
+}
+
void MacWindowManager::setMode(uint32 mode) {
_mode = mode;
@@ -300,7 +311,7 @@ MacMenu *MacWindowManager::addMenu() {
delete _menu;
}
- _menu = new MacMenu(getNextId(), _screen->getBounds(), this);
+ _menu = new MacMenu(getNextId(), getScreenBounds(), this);
_windows[_menu->getId()] = _menu;
@@ -327,6 +338,9 @@ void MacWindowManager::activateMenu() {
}
void MacWindowManager::activateScreenCopy() {
+ if (!_screen)
+ return;
+
if (!_screenCopy)
_screenCopy = new ManagedSurface(*_screen); // Create a copy
else
@@ -463,19 +477,22 @@ void MacWindowManager::drawDesktop() {
}
void MacWindowManager::draw() {
- assert(_screen);
-
removeMarked();
if (_fullRefresh) {
- if (!(_mode & kWMModeNoDesktop)) {
- if (_desktop->w != _screen->w || _desktop->h != _screen->h) {
- _desktop->free();
- _desktop->create(_screen->w, _screen->h, PixelFormat::createFormatCLUT8());
- drawDesktop();
- }
+ Common::Rect screen = getScreenBounds();
+ if (_desktop->w != screen.width() || _desktop->h != screen.height()) {
+ _desktop->free();
+ _desktop->create(screen.width(), screen.height(), PixelFormat::createFormatCLUT8());
+ drawDesktop();
+ }
+
+ if (_screen) {
_screen->blitFrom(*_desktop, Common::Point(0, 0));
g_system->copyRectToScreen(_screen->getPixels(), _screen->pitch, 0, 0, _screen->w, _screen->h);
+ } else {
+ _screenCopyPauseToken = new PauseToken(pauseEngine());
+ g_system->copyRectToScreen(_desktop->getPixels(), _desktop->pitch, 0, 0, _desktop->w, _desktop->h);
}
if (_redrawEngineCallback != nullptr)
@@ -489,7 +506,7 @@ void MacWindowManager::draw() {
continue;
Common::Rect clip = w->getDimensions();
- clip.clip(_screen->getBounds());
+ clip.clip(getScreenBounds());
clip.clip(Common::Rect(0, 0, g_system->getWidth() - 1, g_system->getHeight() - 1));
if (clip.isEmpty())
@@ -505,7 +522,26 @@ void MacWindowManager::draw() {
}
}
- if (w->draw(_screen, forceRedraw)) {
+ if (!_screen) {
+ if (w->isDirty() || forceRedraw) {
+ w->draw(forceRedraw);
+
+ Common::Rect dims = w->getDimensions();
+ Common::Rect innerDims = w->getInnerDimensions();
+
+ g_system->copyRectToScreen(w->getBorderSurface()->getBasePtr(0, 0), w->getBorderSurface()->pitch, clip.left, clip.top, dims.width(), dims.height());
+
+ g_system->copyRectToScreen(w->getWindowSurface()->getBasePtr(MAX(clip.left - innerDims.left, 0), MAX(clip.top - innerDims.top, 0)), w->getWindowSurface()->pitch, clip.left + (-dims.left + innerDims.left), clip.top + (-dims.top + innerDims.top), innerDims.width(), innerDims.height());
+
+ dirtyRects.push_back(clip);
+ }
+
+ if (_screenCopyPauseToken) {
+ _screenCopyPauseToken->clear();
+ delete _screenCopyPauseToken;
+ _screenCopyPauseToken = nullptr;
+ }
+ } else if (w->draw(_screen, forceRedraw)) {
w->setDirty(false);
g_system->copyRectToScreen(_screen->getBasePtr(clip.left, clip.top), _screen->pitch, clip.left, clip.top, clip.width(), clip.height());
dirtyRects.push_back(clip);
@@ -513,8 +549,13 @@ void MacWindowManager::draw() {
}
// Menu is drawn on top of everything and always
- if (_menu && !(_mode & kWMModeFullscreen))
- _menu->draw(_screen, _fullRefresh);
+ if (_menu && !(_mode & kWMModeFullscreen)) {
+ if (_screen) {
+ _menu->draw(_screen, _fullRefresh);
+ } else {
+ g_system->copyRectToScreen(_menu->getWindowSurface()->getBasePtr(_menu->_dims.left, _menu->_dims.top), _menu->getWindowSurface()->pitch, _menu->_dims.left, _menu->_dims.top, _menu->_dims.width(), _menu->_dims.height());
+ }
+ }
_fullRefresh = false;
}
diff --git a/graphics/macgui/macwindowmanager.h b/graphics/macgui/macwindowmanager.h
index e176029110..3da91e72e7 100644
--- a/graphics/macgui/macwindowmanager.h
+++ b/graphics/macgui/macwindowmanager.h
@@ -147,6 +147,14 @@ public:
* @param screen Surface on which the desktop will be drawn.
*/
void setScreen(ManagedSurface *screen);
+
+ /**
+ * Mutator to indicate the dimensions of the desktop, when a backing surface is not used.
+ * Note that this method should be called as soon as the WM is created.
+ * @param screen Surface on which the desktop will be drawn.
+ */
+ void setScreen(int w, int h);
+
/**
* Create a window with the given parameters.
* Note that this method allocates the necessary memory for the window.
@@ -258,6 +266,8 @@ public:
MacWidget *getActiveWidget() { return _activeWidget; }
+ Common::Rect getScreenBounds() { return _screen ? _screen->getBounds() : _screenDims; }
+
void clearWidgetRefs(MacWidget *widget);
void pushCursor(MacCursorType type, Cursor *cursor = nullptr);
@@ -325,6 +335,7 @@ public:
ManagedSurface *_screen;
ManagedSurface *_screenCopy;
+ Common::Rect _screenDims;
private:
Common::List<BaseMacWindow *> _windowStack;
Commit: f28808007b9a97f694d5b7df3f584b16a026512e
https://github.com/scummvm/scummvm/commit/f28808007b9a97f694d5b7df3f584b16a026512e
Author: Nathanael Gentry (nathanael.gentrydb8 at gmail.com)
Date: 2020-08-12T02:35:26-04:00
Commit Message:
DIRECTOR: Eliminate intermediate surface
Changed paths:
engines/director/director.cpp
engines/director/director.h
engines/director/movie.cpp
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 26fe59cd28..e276eb0e54 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -88,7 +88,6 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
_version = getDescriptionVersion();
_wm = nullptr;
- _surface = nullptr;
_gameDataDir = Common::FSNode(ConfMan.get("path"));
@@ -113,7 +112,6 @@ DirectorEngine::~DirectorEngine() {
delete _soundManager;
delete _lingo;
delete _wm;
- delete _surface;
for (Common::HashMap<Common::String, Archive *, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo>::iterator it = _openResFiles.begin(); it != _openResFiles.end(); ++it) {
delete it->_value;
@@ -167,8 +165,7 @@ Common::Error DirectorEngine::run() {
if (!debugChannelSet(-1, kDebugDesktop))
_stage->disableBorder();
- _surface = new Graphics::ManagedSurface;
- _wm->setScreen(_surface);
+ _wm->setScreen(1, 1);
_wm->addWindowInitialized(_stage);
_wm->setActiveWindow(_stage->getId());
setPalette(-1);
diff --git a/engines/director/director.h b/engines/director/director.h
index 38f2afe3f8..57fc52c288 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -222,7 +222,6 @@ public:
public:
RandomState _rnd;
- Graphics::ManagedSurface *_surface;
Graphics::MacWindowManager *_wm;
public:
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 61ea27dcb9..d812ecf741 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -25,6 +25,8 @@
#include "engines/util.h"
+#include "graphics/macgui/macwindowmanager.h"
+
#include "director/director.h"
#include "director/archive.h"
#include "director/cast.h"
@@ -117,9 +119,8 @@ bool Movie::loadArchive() {
if (_window == _vm->getStage()) {
uint16 windowWidth = debugChannelSet(-1, kDebugDesktop) ? 1024 : _movieRect.width();
uint16 windowHeight = debugChannelSet(-1, kDebugDesktop) ? 768 : _movieRect.height();
- if (_vm->_surface->w != windowWidth || _vm->_surface->h != windowHeight) {
- _vm->_surface->free();
- _vm->_surface->create(windowWidth, windowHeight, Graphics::PixelFormat::createFormatCLUT8());
+ if (_vm->_wm->_screenDims.width() != windowWidth || _vm->_wm->_screenDims.height() != windowHeight) {
+ _vm->_wm->_screenDims = Common::Rect(windowWidth, windowHeight);
initGraphics(windowWidth, windowHeight);
}
More information about the Scummvm-git-logs
mailing list