aboutsummaryrefslogtreecommitdiff
path: root/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/wintermute/base/gfx/osystem/base_render_osystem.cpp')
-rw-r--r--engines/wintermute/base/gfx/osystem/base_render_osystem.cpp94
1 files changed, 80 insertions, 14 deletions
diff --git a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
index 097ea7fa42..a5b251cea6 100644
--- a/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
+++ b/engines/wintermute/base/gfx/osystem/base_render_osystem.cpp
@@ -53,6 +53,8 @@ BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
_needsFlip = true;
_spriteBatch = false;
_batchNum = 0;
+ _skipThisFrame = false;
+ _previousTicket = NULL;
_borderLeft = _borderRight = _borderTop = _borderBottom = 0;
_ratioX = _ratioY = 1.0f;
@@ -67,6 +69,15 @@ BaseRenderOSystem::BaseRenderOSystem(BaseGame *inGame) : BaseRenderer(inGame) {
//////////////////////////////////////////////////////////////////////////
BaseRenderOSystem::~BaseRenderOSystem() {
+ RenderQueueIterator it = _renderQueue.begin();
+ while (it != _renderQueue.end()) {
+ RenderTicket *ticket = *it;
+ it = _renderQueue.erase(it);
+ delete ticket;
+ }
+
+ delete _dirtyRect;
+
_renderSurface->free();
delete _renderSurface;
_blankSurface->free();
@@ -155,6 +166,14 @@ bool BaseRenderOSystem::indicatorFlip() {
}
bool BaseRenderOSystem::flip() {
+ if (_skipThisFrame) {
+ _skipThisFrame = false;
+ delete _dirtyRect;
+ _dirtyRect = NULL;
+ g_system->updateScreen();
+ _needsFlip = false;
+ return true;
+ }
if (!_disableDirtyRects) {
drawTickets();
} else {
@@ -256,21 +275,23 @@ Graphics::PixelFormat BaseRenderOSystem::getPixelFormat() const {
}
void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::Surface *surf, Common::Rect *srcRect, Common::Rect *dstRect, bool mirrorX, bool mirrorY, bool disableAlpha) {
- // Skip rects that are completely outside the screen:
- if ((dstRect->left < 0 && dstRect->right < 0) || (dstRect->top < 0 && dstRect->bottom < 0)) {
- return;
- }
// Start searching from the beginning for the first and second items (since it's empty the first time around
// then keep incrementing the start-position, to avoid comparing against already used tickets.
if (_drawNum == 0 || _drawNum == 1) {
_lastAddedTicket = _renderQueue.begin();
}
+ // Skip rects that are completely outside the screen:
+ if ((dstRect->left < 0 && dstRect->right < 0) || (dstRect->top < 0 && dstRect->bottom < 0)) {
+ return;
+ }
+
if (owner) { // Fade-tickets are owner-less
RenderTicket compare(owner, NULL, srcRect, dstRect, mirrorX, mirrorY, disableAlpha);
compare._batchNum = _batchNum;
- if (_spriteBatch)
+ if (_spriteBatch) {
_batchNum++;
+ }
compare._colorMod = _colorMod;
RenderQueueIterator it;
// Avoid calling end() and operator* every time, when potentially going through
@@ -285,7 +306,7 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
drawFromSurface(compareTicket);
} else {
drawFromTicket(compareTicket);
- _lastAddedTicket++;
+ _previousTicket = compareTicket;
}
return;
}
@@ -295,14 +316,53 @@ void BaseRenderOSystem::drawSurface(BaseSurfaceOSystem *owner, const Graphics::S
ticket->_colorMod = _colorMod;
if (!_disableDirtyRects) {
drawFromTicket(ticket);
- drawFromSurface(ticket);
- _lastAddedTicket++;
+ _previousTicket = ticket;
} else {
ticket->_wantsDraw = true;
_renderQueue.push_back(ticket);
}
}
+void BaseRenderOSystem::repeatLastDraw(int offsetX, int offsetY, int numTimesX, int numTimesY) {
+ if (_previousTicket && _lastAddedTicket != _renderQueue.end()) {
+ RenderTicket *origTicket = _previousTicket;
+
+ // Make sure drawSurface WILL start from the correct _lastAddedTicket
+ if (*_lastAddedTicket != origTicket) {
+ RenderQueueIterator it;
+ RenderQueueIterator endIterator = _renderQueue.end();
+ for (it = _renderQueue.begin(); it != endIterator; ++it) {
+ if ((*it) == _previousTicket) {
+ _lastAddedTicket = it;
+ break;
+ }
+ }
+ }
+ Common::Rect srcRect(0, 0, 0, 0);
+ srcRect.setWidth(origTicket->getSrcRect()->width());
+ srcRect.setHeight(origTicket->getSrcRect()->height());
+
+ Common::Rect dstRect = origTicket->_dstRect;
+ int initLeft = dstRect.left;
+ int initRight = dstRect.right;
+
+ for (int i = 0; i < numTimesY; i++) {
+ if (i == 0) {
+ dstRect.translate(offsetX, 0);
+ }
+ for (int j = (i == 0 ? 1 : 0); j < numTimesX; j++) {
+ drawSurface(origTicket->_owner, origTicket->getSurface(), &srcRect, &dstRect, false, false);
+ dstRect.translate(offsetX, 0);
+ }
+ dstRect.left = initLeft;
+ dstRect.right = initRight;
+ dstRect.translate(0, offsetY);
+ }
+ } else {
+ error("Repeat-draw failed (did you forget to draw something before this?)");
+ }
+}
+
void BaseRenderOSystem::invalidateTicket(RenderTicket *renderTicket) {
addDirtyRect(renderTicket->_dstRect);
renderTicket->_isValid = false;
@@ -327,28 +387,31 @@ void BaseRenderOSystem::drawFromTicket(RenderTicket *renderTicket) {
renderTicket->_drawNum = _drawNum++;
_renderQueue.push_back(renderTicket);
addDirtyRect(renderTicket->_dstRect);
+ ++_lastAddedTicket;
} else {
// Before something
- Common::List<RenderTicket *>::iterator pos;
+ RenderQueueIterator pos;
for (pos = _renderQueue.begin(); pos != _renderQueue.end(); pos++) {
if ((*pos)->_drawNum >= _drawNum) {
break;
}
}
_renderQueue.insert(pos, renderTicket);
- Common::List<RenderTicket *>::iterator it;
renderTicket->_drawNum = _drawNum++;
// Increment the following tickets, so they still are in line
+ RenderQueueIterator it;
for (it = pos; it != _renderQueue.end(); ++it) {
(*it)->_drawNum++;
(*it)->_wantsDraw = false;
}
addDirtyRect(renderTicket->_dstRect);
+ _lastAddedTicket = pos;
}
} else {
// Was drawn last round, still in the same order
if (_drawNum == renderTicket->_drawNum) {
_drawNum++;
+ ++_lastAddedTicket;
} else {
// Remove the ticket from the list
RenderQueueIterator it = _renderQueue.begin();
@@ -473,10 +536,10 @@ void BaseRenderOSystem::drawFromSurface(RenderTicket *ticket, Common::Rect *dstR
//////////////////////////////////////////////////////////////////////////
bool BaseRenderOSystem::drawLine(int x1, int y1, int x2, int y2, uint32 color) {
- static bool hasWarned = false; // TODO: Fix this, this only avoids spamming warnings for now.
- if (!_disableDirtyRects && !hasWarned) {
- warning("BaseRenderOSystem::DrawLine - doesn't work for dirty rects yet");
- hasWarned = true;
+ // This function isn't used outside of indicator-displaying, and thus quite unused in
+ // BaseRenderOSystem when dirty-rects are enabled.
+ if (!_disableDirtyRects && !_indicatorDisplay) {
+ error("BaseRenderOSystem::DrawLine - doesn't work for dirty rects yet");
}
byte r = RGBCOLGetR(color);
@@ -583,6 +646,9 @@ void BaseRenderOSystem::endSaveLoad() {
it = _renderQueue.erase(it);
delete ticket;
}
+ // HACK: After a save the buffer will be drawn before the scripts get to update it,
+ // so just skip this single frame.
+ _skipThisFrame = true;
_drawNum = 1;
}