aboutsummaryrefslogtreecommitdiff
path: root/graphics
diff options
context:
space:
mode:
Diffstat (limited to 'graphics')
-rw-r--r--graphics/managed_surface.cpp28
-rw-r--r--graphics/managed_surface.h33
-rw-r--r--graphics/screen.h13
3 files changed, 52 insertions, 22 deletions
diff --git a/graphics/managed_surface.cpp b/graphics/managed_surface.cpp
index 45db0bc52e..e493ab9f4e 100644
--- a/graphics/managed_surface.cpp
+++ b/graphics/managed_surface.cpp
@@ -30,30 +30,30 @@ const int SCALE_THRESHOLD = 0x100;
ManagedSurface::ManagedSurface() :
w(_innerSurface.w), h(_innerSurface.h), pitch(_innerSurface.pitch), format(_innerSurface.format),
- _isManaged(false), _owner(nullptr) {
+ _disposeAfterUse(DisposeAfterUse::NO), _owner(nullptr) {
}
ManagedSurface::ManagedSurface(const ManagedSurface &surf) :
w(_innerSurface.w), h(_innerSurface.h), pitch(_innerSurface.pitch), format(_innerSurface.format),
- _isManaged(false), _owner(nullptr) {
+ _disposeAfterUse(DisposeAfterUse::NO), _owner(nullptr) {
*this = surf;
}
ManagedSurface::ManagedSurface(int width, int height) :
w(_innerSurface.w), h(_innerSurface.h), pitch(_innerSurface.pitch), format(_innerSurface.format),
- _isManaged(false), _owner(nullptr) {
+ _disposeAfterUse(DisposeAfterUse::NO), _owner(nullptr) {
create(width, height);
}
ManagedSurface::ManagedSurface(int width, int height, const Graphics::PixelFormat &pixelFormat) :
w(_innerSurface.w), h(_innerSurface.h), pitch(_innerSurface.pitch), format(_innerSurface.format),
- _isManaged(false), _owner(nullptr) {
+ _disposeAfterUse(DisposeAfterUse::NO), _owner(nullptr) {
create(width, height, format);
}
ManagedSurface::ManagedSurface(ManagedSurface &surf, const Common::Rect &bounds) :
w(_innerSurface.w), h(_innerSurface.h), pitch(_innerSurface.pitch), format(_innerSurface.format),
- _isManaged(false), _owner(nullptr) {
+ _disposeAfterUse(DisposeAfterUse::NO), _owner(nullptr) {
create(surf, bounds);
}
@@ -62,17 +62,18 @@ ManagedSurface::~ManagedSurface() {
}
ManagedSurface &ManagedSurface::operator=(const ManagedSurface &surf) {
- if (surf._isManaged) {
+ // Free any current surface
+ free();
+
+ if (surf._disposeAfterUse == DisposeAfterUse::YES) {
// Create a new surface and copy the pixels from the source surface
create(surf.w, surf.h, surf.format);
Common::copy((const byte *)surf.getPixels(), (const byte *)surf.getPixels() +
surf.w * surf.h * surf.format.bytesPerPixel, (byte *)this->getPixels());
} else {
- // Source isn't managed, so simply copy it's fields
- _isManaged = false;
+ // Source isn't managed, so simply copy its fields
_owner = surf._owner;
_offsetFromOwner = surf._offsetFromOwner;
-
void *srcPixels = (void *)surf._innerSurface.getPixels();
_innerSurface.setPixels(srcPixels);
_innerSurface.w = surf.w;
@@ -97,7 +98,7 @@ void ManagedSurface::create(uint16 width, uint16 height, const PixelFormat &pixe
free();
_innerSurface.create(width, height, pixelFormat);
- _isManaged = true;
+ _disposeAfterUse = DisposeAfterUse::YES;
markAllDirty();
}
@@ -111,14 +112,14 @@ void ManagedSurface::create(ManagedSurface &surf, const Common::Rect &bounds) {
_innerSurface.w = bounds.width();
_innerSurface.h = bounds.height();
_owner = &surf;
- _isManaged = false;
+ _disposeAfterUse = DisposeAfterUse::NO;
}
void ManagedSurface::free() {
- if (_isManaged)
+ if (_disposeAfterUse == DisposeAfterUse::YES)
_innerSurface.free();
- _isManaged = false;
+ _disposeAfterUse = DisposeAfterUse::NO;
_owner = nullptr;
_offsetFromOwner = Common::Point(0, 0);
}
@@ -246,6 +247,7 @@ void ManagedSurface::markAllDirty() {
void ManagedSurface::addDirtyRect(const Common::Rect &r) {
if (_owner) {
Common::Rect bounds = r;
+ bounds.clip(Common::Rect(0, 0, this->w, this->h));
bounds.translate(_offsetFromOwner.x, _offsetFromOwner.y);
_owner->addDirtyRect(bounds);
}
diff --git a/graphics/managed_surface.h b/graphics/managed_surface.h
index 1d837fd8cd..bd0632a493 100644
--- a/graphics/managed_surface.h
+++ b/graphics/managed_surface.h
@@ -26,6 +26,7 @@
#include "graphics/pixelformat.h"
#include "graphics/surface.h"
#include "common/rect.h"
+#include "common/types.h"
namespace Graphics {
@@ -38,9 +39,27 @@ class Font;
class ManagedSurface {
friend class Font;
private:
+ /**
+ * The Graphics::Surface that the managed surface encapsulates
+ */
Surface _innerSurface;
- bool _isManaged;
+
+ /**
+ * If set, the inner surface will be freed when the surface is recreated,
+ * as well as when the surface is destroyed
+ */
+ DisposeAfterUse::Flag _disposeAfterUse;
+
+ /**
+ * Stores the owning surface if this If this managed surface represents
+ * a sub-section of another
+ */
ManagedSurface *_owner;
+
+ /**
+ * For sub-section areas of an owning parent managed surface, this represents
+ * the offset from the parent's top-left corner this sub-surface starts at
+ */
Common::Point _offsetFromOwner;
protected:
/**
@@ -65,8 +84,10 @@ public:
ManagedSurface();
/**
- * Create a managed surface from another one
- * Note that if the source has a managed surface, it will be duplicated
+ * Create a managed surface from another one.
+ * If the source surface is maintaining it's own surface data, then
+ * this surface will create it's own surface of the same size and copy
+ * the contents from the source surface
*/
ManagedSurface(const ManagedSurface &surf);
@@ -111,9 +132,9 @@ public:
bool empty() const { return w == 0 || h == 0 || _innerSurface.getPixels() == nullptr; }
/**
- * Returns true if the surface is managing it's own pixels
+ * Returns true if the surface is managing its own pixels
*/
- bool isManaged() const { return _isManaged; }
+ DisposeAfterUse::Flag disposeAfterUse() const { return _disposeAfterUse; }
/**
* Return a pointer to the pixel at the specified point.
@@ -304,7 +325,7 @@ public:
*/
void drawThickLine(int x0, int y0, int x1, int y1, int penX, int penY, uint32 color) {
_innerSurface.drawThickLine(x0, y0, x1, y1, penX, penY, color);
- addDirtyRect(Common::Rect(x0, y0, x1, y1));
+ addDirtyRect(Common::Rect(x0, y0, x1 + penX, y1 + penY));
}
/**
diff --git a/graphics/screen.h b/graphics/screen.h
index 3479ce847e..29816120f1 100644
--- a/graphics/screen.h
+++ b/graphics/screen.h
@@ -33,6 +33,12 @@ namespace Graphics {
#define PALETTE_COUNT 256
#define PALETTE_SIZE (256 * 3)
+/**
+ * Implements a specialised surface that represents the screen.
+ * It keeps track of any areas of itself that are updated by drawing
+ * calls, and provides an update that method that blits the affected
+ * areas to the physical screen
+ */
class Screen : virtual public ManagedSurface {
private:
/**
@@ -61,12 +67,13 @@ public:
Screen(int width, int height, PixelFormat pixelFormat);
/**
- * Returns true if there are any pending screen updates
+ * Returns true if there are any pending screen updates (dirty areas)
*/
- bool isDirty() const { return _dirtyRects.empty(); }
+ bool isDirty() const { return !_dirtyRects.empty(); }
/**
- * Makes the whole screen dirty
+ * Marks the whole screen as dirty. This forces the next call to update
+ * to copy the entire screen contents
*/
void makeAllDirty();