aboutsummaryrefslogtreecommitdiff
path: root/engines/saga
diff options
context:
space:
mode:
authorFilippos Karapetis2008-12-06 18:23:34 +0000
committerFilippos Karapetis2008-12-06 18:23:34 +0000
commit065694dbb166d2fb113ba36b9340d91f9c71fdbe (patch)
treec986e2dfb4c30027ce444397cb27f09f2c8b7f67 /engines/saga
parent5f2cd3c4a7e771a30e132fa90936b1da72fa21ab (diff)
downloadscummvm-rg350-065694dbb166d2fb113ba36b9340d91f9c71fdbe.tar.gz
scummvm-rg350-065694dbb166d2fb113ba36b9340d91f9c71fdbe.tar.bz2
scummvm-rg350-065694dbb166d2fb113ba36b9340d91f9c71fdbe.zip
- Prevented direct reference to the back buffer in many cases (apart from a few, where it's modified directly)
- Added skeleton code for dirty rectangle handling (still unfinished and non-working) - Added wrapper functions to access the back buffer, which add the appropriate dirty rectangles automatically svn-id: r35264
Diffstat (limited to 'engines/saga')
-rw-r--r--engines/saga/events.cpp2
-rw-r--r--engines/saga/font.cpp20
-rw-r--r--engines/saga/gfx.cpp25
-rw-r--r--engines/saga/gfx.h74
-rw-r--r--engines/saga/interface.cpp80
-rw-r--r--engines/saga/isomap.cpp9
-rw-r--r--engines/saga/objectmap.cpp7
-rw-r--r--engines/saga/render.cpp32
-rw-r--r--engines/saga/render.h22
-rw-r--r--engines/saga/scene.cpp8
-rw-r--r--engines/saga/sfuncs.cpp2
-rw-r--r--engines/saga/sprite.cpp16
12 files changed, 207 insertions, 90 deletions
diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp
index a456e81f96..b42ea97765 100644
--- a/engines/saga/events.cpp
+++ b/engines/saga/events.cpp
@@ -522,7 +522,7 @@ int Events::handleOneShot(Event *event) {
rect.bottom = event->param3;
rect.left = event->param4;
rect.right = event->param5;
- ((Surface *)event->data)->drawRect(rect, event->param);
+ _vm->_gfx->drawRect(rect, event->param);
break;
case kEventSetFlag:
_vm->_render->setFlag(event->param);
diff --git a/engines/saga/font.cpp b/engines/saga/font.cpp
index 1361e310d6..d9d8a4ab8a 100644
--- a/engines/saga/font.cpp
+++ b/engines/saga/font.cpp
@@ -310,7 +310,6 @@ void Font::outFont(const FontStyle &drawFont, const char *text, size_t count, co
byte *outputPointer;
byte *outputPointer_min;
byte *outputPointer_max;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
int row;
int rowLimit;
@@ -320,7 +319,7 @@ void Font::outFont(const FontStyle &drawFont, const char *text, size_t count, co
int c_bit;
int ct;
- if ((point.x > backBuffer->w) || (point.y > backBuffer->h)) {
+ if ((point.x > _vm->_gfx->getBackBufferWidth()) || (point.y > _vm->_gfx->getBackBufferHeight())) {
// Output string can't be visible
return;
}
@@ -373,7 +372,7 @@ void Font::outFont(const FontStyle &drawFont, const char *text, size_t count, co
// Get length of character in bytes
c_byte_len = ((drawFont.fontCharEntry[c_code].width - 1) / 8) + 1;
- rowLimit = (backBuffer->h < (textPoint.y + drawFont.header.charHeight)) ? backBuffer->h : textPoint.y + drawFont.header.charHeight;
+ rowLimit = (_vm->_gfx->getBackBufferHeight() < (textPoint.y + drawFont.header.charHeight)) ? _vm->_gfx->getBackBufferHeight() : textPoint.y + drawFont.header.charHeight;
charRow = 0;
for (row = textPoint.y; row < rowLimit; row++, charRow++) {
@@ -382,9 +381,9 @@ void Font::outFont(const FontStyle &drawFont, const char *text, size_t count, co
continue;
}
- outputPointer = (byte *)backBuffer->pixels + (backBuffer->pitch * row) + textPoint.x;
- outputPointer_min = (byte *)backBuffer->pixels + (backBuffer->pitch * row) + (textPoint.x > 0 ? textPoint.x : 0);
- outputPointer_max = outputPointer + (backBuffer->pitch - textPoint.x);
+ outputPointer = _vm->_gfx->getBackBufferPixels() + (_vm->_gfx->getBackBufferPitch() * row) + textPoint.x;
+ outputPointer_min = _vm->_gfx->getBackBufferPixels() + (_vm->_gfx->getBackBufferPitch() * row) + (textPoint.x > 0 ? textPoint.x : 0);
+ outputPointer_max = outputPointer + (_vm->_gfx->getBackBufferPitch() - textPoint.x);
// If character starts off the screen, jump to next character
if (outputPointer < outputPointer_min) {
@@ -415,7 +414,6 @@ void Font::textDraw(FontId fontId, const char *text, const Common::Point &point,
int textLength;
int fitWidth;
Common::Point textPoint(point);
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
textLength = strlen(text);
@@ -431,8 +429,8 @@ void Font::textDraw(FontId fontId, const char *text, const Common::Point &point,
textPoint.x = TEXT_CENTERLIMIT;
}
- if (textPoint.x > backBuffer->w - TEXT_CENTERLIMIT) {
- textPoint.x = backBuffer->w - TEXT_CENTERLIMIT;
+ if (textPoint.x > _vm->_gfx->getBackBufferWidth() - TEXT_CENTERLIMIT) {
+ textPoint.x = _vm->_gfx->getBackBufferWidth() - TEXT_CENTERLIMIT;
}
if (textPoint.x < (TEXT_MARGIN * 2)) {
@@ -442,12 +440,12 @@ void Font::textDraw(FontId fontId, const char *text, const Common::Point &point,
textWidth = getStringWidth(fontId, text, textLength, flags);
- if (textPoint.x < (backBuffer->w / 2)) {
+ if (textPoint.x < (_vm->_gfx->getBackBufferWidth() / 2)) {
// Fit to right side
fitWidth = (textPoint.x - TEXT_MARGIN) * 2;
} else {
// Fit to left side
- fitWidth = ((backBuffer->w - TEXT_MARGIN) - textPoint.x) * 2;
+ fitWidth = ((_vm->_gfx->getBackBufferWidth() - TEXT_MARGIN) - textPoint.x) * 2;
}
if (fitWidth < textWidth) {
diff --git a/engines/saga/gfx.cpp b/engines/saga/gfx.cpp
index 285a33b656..eac1d871ae 100644
--- a/engines/saga/gfx.cpp
+++ b/engines/saga/gfx.cpp
@@ -30,6 +30,7 @@
#include "saga/interface.h"
#include "saga/rscfile.h"
#include "saga/scene.h"
+#include "saga/render.h"
#include "common/system.h"
#include "graphics/cursorman.h"
@@ -561,4 +562,28 @@ bool hitTestPoly(const Point *points, unsigned int npoints, const Point& test_po
return inside_flag;
}
+// This method adds a dirty rectangle automatically
+void Gfx::drawFrame(const Common::Point &p1, const Common::Point &p2, int color) {
+ _backBuffer.drawFrame(p1, p2, color);
+ _vm->_render->addDirtyRect(Common::Rect(p1.x, p1.y, p2.x, p2.y));
+}
+
+// This method adds a dirty rectangle automatically
+void Gfx::drawRect(const Common::Rect &destRect, int color) {
+ _backBuffer.drawRect(destRect, color);
+ _vm->_render->addDirtyRect(destRect);
+}
+
+// This method adds a dirty rectangle automatically
+void Gfx::fillRect(const Common::Rect &destRect, uint32 color) {
+ _backBuffer.fillRect(destRect, color);
+ _vm->_render->addDirtyRect(destRect);
+}
+
+// This method adds a dirty rectangle automatically
+void Gfx::drawRegion(const Common::Rect &destRect, const byte *sourceBuffer) {
+ _backBuffer.blit(destRect, sourceBuffer);
+ _vm->_render->addDirtyRect(destRect);
+}
+
} // End of namespace Saga
diff --git a/engines/saga/gfx.h b/engines/saga/gfx.h
index 7894dfaff3..6cd5d2469b 100644
--- a/engines/saga/gfx.h
+++ b/engines/saga/gfx.h
@@ -138,9 +138,6 @@ public:
Gfx(SagaEngine *vm, OSystem *system, int width, int height);
~Gfx();
- Surface *getBackBuffer() {
- return &_backBuffer;
- }
void initPalette();
void setPalette(const PalEntry *pal, bool full = false);
@@ -154,6 +151,77 @@ public:
void showCursor(bool state);
void setCursor(CursorType cursorType = kCursorNormal);
+ // Back buffer access methods. These all take care of adding the necessary dirty rectangles
+ // APART FROM setPixelColor() and getBackBufferPixels()
+
+ // This method adds a dirty rectangle automatically
+ void drawFrame(const Common::Point &p1, const Common::Point &p2, int color);
+
+ // This method adds a dirty rectangle automatically
+ void drawRect(const Common::Rect &destRect, int color);
+
+ // This method adds a dirty rectangle automatically
+ void fillRect(const Common::Rect &destRect, uint32 color);
+
+ // This method adds a dirty rectangle automatically
+ void drawRegion(const Common::Rect &destRect, const byte *sourceBuffer);
+
+ // Used for testing
+ void drawPalette() {
+ _backBuffer.drawPalette();
+ }
+
+ // WARNING: This method does not add a dirty rectangle automatically.
+ // Whenever it gets called, the corresponding caller must take care
+ // to add the corresponding dirty rectangle itself
+ void hLine(int x, int y, int x2, uint32 color) {
+ _backBuffer.hLine(x, y, x2, color);
+ }
+
+ // WARNING: This method does not add a dirty rectangle automatically.
+ // Whenever it gets called, the corresponding caller must take care
+ // to add the corresponding dirty rectangle itself
+ void vLine(int x, int y, int y2, uint32 color) {
+ _backBuffer.vLine(x, y, y2, color);
+ }
+
+ // WARNING: This method does not add a dirty rectangle automatically.
+ // Whenever it gets called, the corresponding caller must take care
+ // to add the corresponding dirty rectangle itself
+ void setPixelColor(int x, int y, byte color) {
+ ((byte *)_backBuffer.getBasePtr(x, y))[0] = color;
+ }
+
+ // WARNING: This method does not add a dirty rectangle automatically.
+ // Whenever it gets called, the corresponding caller must take care
+ // to add the corresponding dirty rectangle itself
+ void drawPolyLine(Common::Point *points, int count, int color) {
+ _backBuffer.drawPolyLine(points, count, color);
+ }
+
+ // WARNING: This method allows direct modification of the back buffer
+ // Whenever it gets called, the corresponding caller must take care
+ // to add the corresponding dirty rectangle itself
+ byte *getBackBufferPixels() {
+ return (byte *)_backBuffer.pixels;
+ }
+
+ uint16 getBackBufferWidth() {
+ return _backBuffer.w;
+ }
+
+ uint16 getBackBufferHeight() {
+ return _backBuffer.h;
+ }
+
+ uint16 getBackBufferPitch() {
+ return _backBuffer.pitch;
+ }
+
+ void getBackBufferRect(Common::Rect &rect) {
+ _backBuffer.getRect(rect);
+ }
+
private:
Surface _backBuffer;
byte _currentPal[PAL_ENTRIES * 4];
diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp
index e6c6921784..e18e1654a0 100644
--- a/engines/saga/interface.cpp
+++ b/engines/saga/interface.cpp
@@ -799,7 +799,7 @@ void Interface::draw() {
if (_panelMode == kPanelMain || _panelMode == kPanelMap ||
(_panelMode == kPanelNull && _vm->getGameId() == GID_IHNM_DEMO)) {
_mainPanel.getRect(rect);
- _vm->_gfx->getBackBuffer()->blit(rect, _mainPanel.image);
+ _vm->_gfx->drawRegion(rect, _mainPanel.image);
for (int i = 0; i < kVerbTypeIdsMax; i++) {
if (_verbTypeToPanelButton[i] != NULL) {
@@ -808,7 +808,7 @@ void Interface::draw() {
}
} else if (_panelMode == kPanelConverse) {
_conversePanel.getRect(rect);
- _vm->_gfx->getBackBuffer()->blit(rect, _conversePanel.image);
+ _vm->_gfx->drawRegion(rect, _conversePanel.image);
converseDisplayTextLines();
}
@@ -941,10 +941,9 @@ void Interface::drawOption() {
Point point;
Point sliderPoint;
int spritenum = 0;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
_optionPanel.getRect(rect);
- backBuffer->blit(rect, _optionPanel.image);
+ _vm->_gfx->drawRegion(rect, _optionPanel.image);
for (int i = 0; i < _optionPanel.buttonsCount; i++) {
panelButton = &_optionPanel.buttons[i];
@@ -964,7 +963,7 @@ void Interface::drawOption() {
if (_optionSaveRectTop.height() > 0) {
if (_vm->getGameType() == GType_ITE)
- backBuffer->drawRect(_optionSaveRectTop, kITEColorDarkGrey);
+ _vm->_gfx->drawRect(_optionSaveRectTop, kITEColorDarkGrey);
}
if (_vm->getGameType() == GType_ITE) {
@@ -978,7 +977,7 @@ void Interface::drawOption() {
}
if (_optionSaveRectBottom.height() > 0) {
- backBuffer->drawRect(_optionSaveRectBottom, kITEColorDarkGrey);
+ _vm->_gfx->drawRect(_optionSaveRectBottom, kITEColorDarkGrey);
}
_optionPanel.calcPanelButtonRect(_optionSaveFilePanel, rect);
@@ -999,7 +998,7 @@ void Interface::drawOption() {
if (idx < _vm->getSaveFilesCount()) {
rect2.top = rect.top + j * (fontHeight + 1);
rect2.bottom = rect2.top + fontHeight;
- backBuffer->fillRect(rect2, bgColor);
+ _vm->_gfx->fillRect(rect2, bgColor);
text = _vm->getSaveFile(idx)->name;
textPoint.x = rect.left + 1;
textPoint.y = rect2.top;
@@ -1021,7 +1020,7 @@ void Interface::drawQuit() {
if (_vm->getGameType() == GType_ITE)
drawButtonBox(rect, kButton, false);
else
- _vm->_gfx->getBackBuffer()->blit(rect, _quitPanel.image);
+ _vm->_gfx->drawRegion(rect, _quitPanel.image);
for (i = 0; i < _quitPanel.buttonsCount; i++) {
panelButton = &_quitPanel.buttons[i];
@@ -1085,7 +1084,7 @@ void Interface::drawLoad() {
if (_vm->getGameType() == GType_ITE)
drawButtonBox(rect, kButton, false);
else
- _vm->_gfx->getBackBuffer()->blit(rect, _loadPanel.image);
+ _vm->_gfx->drawRegion(rect, _loadPanel.image);
for (i = 0; i < _loadPanel.buttonsCount; i++) {
panelButton = &_loadPanel.buttons[i];
@@ -1266,7 +1265,6 @@ void Interface::drawTextInput(InterfacePanel *panel, PanelButton *panelButton) {
char ch[2];
int fgColor;
uint i;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
ch[1] = 0;
panel->calcPanelButtonRect(panelButton, rect);
@@ -1280,7 +1278,7 @@ void Interface::drawTextInput(InterfacePanel *panel, PanelButton *panelButton) {
rect.setWidth(_vm->_font->getStringWidth(kKnownFontSmall, ch, 0, kFontNormal));
if ((i == _textInputPos) && _textInput) {
fgColor = _vm->KnownColor2ColorId(kKnownColorBlack);
- backBuffer->fillRect(rect, _vm->KnownColor2ColorId(kKnownColorWhite));
+ _vm->_gfx->fillRect(rect, _vm->KnownColor2ColorId(kKnownColorWhite));
} else {
fgColor = _vm->KnownColor2ColorId(kKnownColorWhite);
}
@@ -1293,7 +1291,7 @@ void Interface::drawTextInput(InterfacePanel *panel, PanelButton *panelButton) {
if (_textInput && (_textInputPos >= i)) {
ch[0] = ' ';
rect.setWidth(_vm->_font->getStringWidth(kKnownFontSmall, ch, 0, kFontNormal));
- backBuffer->fillRect(rect, _vm->KnownColor2ColorId(kKnownColorWhite));
+ _vm->_gfx->fillRect(rect, _vm->KnownColor2ColorId(kKnownColorWhite));
}
}
@@ -1306,7 +1304,7 @@ void Interface::drawSave() {
if (_vm->getGameType() == GType_ITE)
drawButtonBox(rect, kButton, false);
else
- _vm->_gfx->getBackBuffer()->blit(rect, _savePanel.image);
+ _vm->_gfx->drawRegion(rect, _savePanel.image);
for (i = 0; i < _savePanel.buttonsCount; i++) {
panelButton = &_savePanel.buttons[i];
@@ -1882,7 +1880,7 @@ void Interface::drawStatusBar() {
rect.right = rect.left + _vm->getDisplayWidth();
rect.bottom = rect.top + _vm->getDisplayInfo().statusHeight;
- _vm->_gfx->getBackBuffer()->drawRect(rect, _vm->getDisplayInfo().statusBGColor - offset);
+ _vm->_gfx->drawRect(rect, _vm->getDisplayInfo().statusBGColor - offset);
stringWidth = _vm->_font->getStringWidth(kKnownFontSmall, _statusText, 0, kFontNormal);
@@ -2097,7 +2095,6 @@ void Interface::drawInventory() {
Rect rect;
int ci = _inventoryStart;
ObjectData *obj;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
if (_inventoryStart != 0) {
drawPanelButtonArrow(&_mainPanel, _inventoryUpButton);
@@ -2113,9 +2110,9 @@ void Interface::drawInventory() {
_mainPanel.calcPanelButtonRect(&_mainPanel.buttons[i], rect);
if (_vm->getGameType() == GType_ITE)
- backBuffer->drawRect(rect, kITEColorDarkGrey);
+ _vm->_gfx->drawRect(rect, kITEColorDarkGrey);
else
- backBuffer->drawRect(rect, _vm->KnownColor2ColorId(kKnownColorBlack));
+ _vm->_gfx->drawRect(rect, _vm->KnownColor2ColorId(kKnownColorBlack));
if (ci < _inventoryCount) {
obj = _vm->_actor->getObj(_inventory[ci]);
@@ -2142,7 +2139,6 @@ void Interface::drawButtonBox(const Rect& rect, ButtonKind kind, bool down) {
byte fillColor;
byte solidColor;
byte odl, our, idl, iur;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
switch (kind ) {
case kSlider:
@@ -2190,14 +2186,11 @@ void Interface::drawButtonBox(const Rect& rect, ButtonKind kind, bool down) {
int xe = rect.right - 1;
int ye = rect.bottom - 1;
- ((byte *)backBuffer->getBasePtr(x, y))[0] = cornerColor;
- ((byte *)backBuffer->getBasePtr(x, ye))[0] = cornerColor;
- ((byte *)backBuffer->getBasePtr(xe, y))[0] = cornerColor;
- ((byte *)backBuffer->getBasePtr(xe, ye))[0] = cornerColor;
- backBuffer->hLine(x + 1, y, x + w - 2, frameColor);
- backBuffer->hLine(x + 1, ye, x + w - 2, frameColor);
- backBuffer->vLine(x, y + 1, y + h - 2, frameColor);
- backBuffer->vLine(xe, y + 1, y + h - 2, frameColor);
+ _vm->_gfx->drawRect(Common::Rect(x, y, x + w, y + h), frameColor);
+ _vm->_gfx->setPixelColor(x, y, cornerColor);
+ _vm->_gfx->setPixelColor(x, ye, cornerColor);
+ _vm->_gfx->setPixelColor(xe, y, cornerColor);
+ _vm->_gfx->setPixelColor(xe, ye, cornerColor);
x++;
y++;
@@ -2205,10 +2198,11 @@ void Interface::drawButtonBox(const Rect& rect, ButtonKind kind, bool down) {
ye--;
w -= 2;
h -= 2;
- backBuffer->vLine(x, y, y + h - 1, odl);
- backBuffer->hLine(x, ye, x + w - 1, odl);
- backBuffer->vLine(xe, y, y + h - 2, our);
- backBuffer->hLine(x + 1, y, x + 1 + w - 2, our);
+ // drawRect() above added a dirty rectangle automatically for these
+ _vm->_gfx->vLine(x, y, y + h - 1, odl);
+ _vm->_gfx->hLine(x, ye, x + w - 1, odl);
+ _vm->_gfx->vLine(xe, y, y + h - 2, our);
+ _vm->_gfx->hLine(x + 1, y, x + 1 + w - 2, our);
x++;
y++;
@@ -2216,18 +2210,19 @@ void Interface::drawButtonBox(const Rect& rect, ButtonKind kind, bool down) {
ye--;
w -= 2;
h -= 2;
- ((byte *)backBuffer->getBasePtr(x, y))[0] = fillColor;
- ((byte *)backBuffer->getBasePtr(xe, ye))[0] = fillColor;
- backBuffer->vLine(x, y + 1, y + 1 + h - 2, idl);
- backBuffer->hLine(x + 1, ye, x + 1 + w - 2, idl);
- backBuffer->vLine(xe, y, y + h - 2, iur);
- backBuffer->hLine(x + 1, y, x + 1 + w - 2, iur);
+ // drawRect() above added a dirty rectangle automatically for these
+ _vm->_gfx->setPixelColor(x, y, fillColor);
+ _vm->_gfx->setPixelColor(xe, ye, fillColor);
+ _vm->_gfx->vLine(x, y + 1, y + 1 + h - 2, idl);
+ _vm->_gfx->hLine(x + 1, ye, x + 1 + w - 2, idl);
+ _vm->_gfx->vLine(xe, y, y + h - 2, iur);
+ _vm->_gfx->hLine(x + 1, y, x + 1 + w - 2, iur);
x++; y++;
w -= 2; h -= 2;
Common::Rect fill(x, y, x + w, y + h);
- backBuffer->fillRect(fill, solidColor);
+ _vm->_gfx->fillRect(fill, solidColor);
}
static const int readingSpeeds[] = { kTextClick, kTextSlow, kTextMid, kTextFast };
@@ -2519,7 +2514,6 @@ void Interface::converseDisplayTextLines() {
};
Rect rect(8, _vm->getDisplayInfo().converseTextLines * _vm->getDisplayInfo().converseTextHeight);
Point textPoint;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
assert(_conversePanel.buttonsCount >= 6);
@@ -2536,9 +2530,9 @@ void Interface::converseDisplayTextLines() {
_conversePanel.y + _conversePanel.buttons[0].yOffset);
if (_vm->getGameType() == GType_ITE)
- backBuffer->drawRect(rect, kITEColorDarkGrey); //fill bullet place
+ _vm->_gfx->drawRect(rect, kITEColorDarkGrey); //fill bullet place
else
- backBuffer->drawRect(rect, _vm->KnownColor2ColorId(kKnownColorBlack)); //fill bullet place
+ _vm->_gfx->drawRect(rect, _vm->KnownColor2ColorId(kKnownColorBlack)); //fill bullet place
for (int i = 0; i < _vm->getDisplayInfo().converseTextLines; i++) {
relPos = _converseStartPos + i;
@@ -2567,7 +2561,7 @@ void Interface::converseDisplayTextLines() {
_conversePanel.calcPanelButtonRect(&_conversePanel.buttons[i], rect);
rect.left += 8;
- backBuffer->drawRect(rect, backgnd);
+ _vm->_gfx->drawRect(rect, backgnd);
str = _converseText[relPos].text;
@@ -2743,7 +2737,7 @@ void Interface::mapPanelShow() {
rect.setWidth(imageWidth);
rect.setHeight(imageHeight);
- _vm->_gfx->getBackBuffer()->blit(rect, image);
+ _vm->_gfx->drawRegion(rect, image);
// Evil Evil
for (i = 0; i < 6 ; i++) {
@@ -2847,7 +2841,7 @@ void Interface::keyBoss() {
cPal[i].blue = 128;
}
- _vm->_gfx->getBackBuffer()->blit(rect, image);
+ _vm->_gfx->drawRegion(rect, image);
_vm->_gfx->setPalette(cPal);
diff --git a/engines/saga/isomap.cpp b/engines/saga/isomap.cpp
index 6a4b5110dd..dd481f00e5 100644
--- a/engines/saga/isomap.cpp
+++ b/engines/saga/isomap.cpp
@@ -378,7 +378,7 @@ int16 IsoMap::findMulti(int16 tileIndex, int16 absU, int16 absV, int16 absH) {
void IsoMap::draw() {
_tileClip = _vm->_scene->getSceneClip();
- _vm->_gfx->getBackBuffer()->drawRect(_tileClip, 0);
+ _vm->_gfx->drawRegion(_tileClip, 0);
drawTiles(NULL);
}
@@ -708,7 +708,6 @@ void IsoMap::drawTile(uint16 tileIndex, const Point &point, const Location *loca
int row, col, count, lowBound;
int bgRunCount;
int fgRunCount;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
if (tileIndex >= _tilesCount) {
error("IsoMap::drawTile wrong tileIndex");
@@ -832,7 +831,7 @@ void IsoMap::drawTile(uint16 tileIndex, const Point &point, const Location *loca
for (row = drawPoint.y; row < lowBound; row++) {
widthCount = 0;
if (row >= _tileClip.top) {
- drawPointer = (byte *)backBuffer->pixels + drawPoint.x + (row * backBuffer->pitch);
+ drawPointer = _vm->_gfx->getBackBufferPixels() + drawPoint.x + (row * _vm->_gfx->getBackBufferPitch());
col = drawPoint.x;
for (;;) {
bgRunCount = *readPointer++;
@@ -852,8 +851,8 @@ void IsoMap::drawTile(uint16 tileIndex, const Point &point, const Location *loca
col++;
}
while ((col < _tileClip.right) && (count < fgRunCount)) {
- assert((byte *)backBuffer->pixels <= (byte *)(drawPointer + count));
- assert((byte *)((byte *)backBuffer->pixels + (_vm->getDisplayWidth() *
+ assert(_vm->_gfx->getBackBufferPixels() <= (byte *)(drawPointer + count));
+ assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayWidth() *
_vm->getDisplayHeight())) > (byte *)(drawPointer + count));
drawPointer[count] = readPointer[count];
count++;
diff --git a/engines/saga/objectmap.cpp b/engines/saga/objectmap.cpp
index 17256a67d9..d10c4ffaa7 100644
--- a/engines/saga/objectmap.cpp
+++ b/engines/saga/objectmap.cpp
@@ -149,7 +149,6 @@ void HitZone::draw(SagaEngine *vm, int color) {
Point *points;
Point specialPoint1;
Point specialPoint2;
- Surface *backBuffer = vm->_gfx->getBackBuffer();
for (i = 0; i < _clickAreasCount; i++) {
clickArea = &_clickAreas[i];
@@ -168,11 +167,11 @@ void HitZone::draw(SagaEngine *vm, int color) {
if (pointsCount == 2) {
// 2 points represent a box
- backBuffer->drawFrame(points[0], points[1], color);
+ vm->_gfx->drawFrame(points[0], points[1], color);
} else {
if (pointsCount > 2) {
// Otherwise draw a polyline
- backBuffer->drawPolyLine(points, pointsCount, color);
+ vm->_gfx->drawPolyLine(points, pointsCount, color);
}
}
if (vm->_scene->getFlags() & kSceneFlagISO) {
@@ -186,7 +185,7 @@ void HitZone::draw(SagaEngine *vm, int color) {
specialPoint1.y--;
specialPoint2.x++;
specialPoint2.y++;
- backBuffer->drawFrame(specialPoint1, specialPoint2, color);
+ vm->_gfx->drawFrame(specialPoint1, specialPoint2, color);
}
}
#endif
diff --git a/engines/saga/render.cpp b/engines/saga/render.cpp
index fa84188a78..e78e6f9947 100644
--- a/engines/saga/render.cpp
+++ b/engines/saga/render.cpp
@@ -77,18 +77,18 @@ bool Render::initialized() {
}
void Render::drawScene() {
- Surface *backBufferSurface;
Point mousePoint;
Point textPoint;
int curMode = _vm->_interface->getMode();
assert(_initialized);
+ // TODO: Remove this
+ _fullRefresh = true;
+
#ifdef SAGA_DEBUG
_renderedFrameCount++;
#endif
- backBufferSurface = _vm->_gfx->getBackBuffer();
-
// Get mouse coordinates
mousePoint = _vm->mousePos();
@@ -165,7 +165,7 @@ void Render::drawScene() {
if (_flags & RF_SHOW_FPS) {
char txtBuffer[20];
sprintf(txtBuffer, "%d", _fps);
- textPoint.x = backBufferSurface->w - _vm->_font->getStringWidth(kKnownFontSmall, txtBuffer, 0, kFontOutline);
+ textPoint.x = _vm->_gfx->getBackBufferWidth() - _vm->_font->getStringWidth(kKnownFontSmall, txtBuffer, 0, kFontOutline);
textPoint.y = 2;
_vm->_font->textDraw(kKnownFontSmall, txtBuffer, textPoint, kITEColorBrightWhite, kITEColorBlack, kFontOutline);
@@ -175,7 +175,7 @@ void Render::drawScene() {
// Display "paused game" message, if applicable
if (_flags & RF_RENDERPAUSE) {
const char *pauseString = (_vm->getGameType() == GType_ITE) ? pauseStringITE : pauseStringIHNM;
- textPoint.x = (backBufferSurface->w - _vm->_font->getStringWidth(kKnownFontPause, pauseString, 0, kFontOutline)) / 2;
+ textPoint.x = (_vm->_gfx->getBackBufferWidth() - _vm->_font->getStringWidth(kKnownFontPause, pauseString, 0, kFontOutline)) / 2;
textPoint.y = 90;
_vm->_font->textDraw(kKnownFontPause, pauseString, textPoint,
@@ -195,16 +195,32 @@ void Render::drawScene() {
// Display palette test, if applicable
if (_flags & RF_PALETTE_TEST) {
- backBufferSurface->drawPalette();
+ _vm->_gfx->drawPalette();
}
#endif
- _system->copyRectToScreen((byte *)backBufferSurface->pixels, backBufferSurface->w, 0, 0,
- backBufferSurface->w, backBufferSurface->h);
+ drawDirtyRects();
_system->updateScreen();
}
+void Render::drawDirtyRects() {
+ if (_fullRefresh) {
+ _system->copyRectToScreen(_vm->_gfx->getBackBufferPixels(), _vm->_gfx->getBackBufferWidth(), 0, 0,
+ _vm->_gfx->getBackBufferWidth(), _vm->_gfx->getBackBufferHeight());
+ } else {
+
+ // TODO: check if dirty rectangles are intersecting or contained within each other
+
+ Common::List<Common::Rect>::const_iterator it;
+ for (it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
+ g_system->copyRectToScreen(_vm->_gfx->getBackBufferPixels(), it->width(), it->left, it->top, it->width(), it->height());
+ }
+ }
+
+ _dirtyRects.clear();
+}
+
#ifdef SAGA_DEBUG
void Render::fpsTimerCallback(void *refCon) {
((Render *)refCon)->fpsTimer();
diff --git a/engines/saga/render.h b/engines/saga/render.h
index fe4ce7f890..772bbca1a6 100644
--- a/engines/saga/render.h
+++ b/engines/saga/render.h
@@ -29,6 +29,8 @@
#define SAGA_RENDER_H
#include "saga/sprite.h"
+#include "saga/gfx.h"
+#include "common/list.h"
namespace Saga {
@@ -77,6 +79,24 @@ public:
return &_backGroundSurface;
}
+ void addDirtyRect(Common::Rect rect) {
+ _dirtyRects.push_back(rect);
+ }
+
+ void clearDirtyRects() {
+ _dirtyRects.clear();
+ }
+
+ void setFullRefresh(bool flag) {
+ _fullRefresh = flag;
+ }
+
+ bool isFullRefresh() {
+ return _fullRefresh;
+ }
+
+ void drawDirtyRects();
+
private:
#ifdef SAGA_DEBUG
static void fpsTimerCallback(void *refCon);
@@ -88,6 +108,8 @@ private:
SagaEngine *_vm;
OSystem *_system;
bool _initialized;
+ Common::List<Common::Rect> _dirtyRects;
+ bool _fullRefresh;
// Module data
Surface _backGroundSurface;
diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp
index de7ad727de..5a7a7446e1 100644
--- a/engines/saga/scene.cpp
+++ b/engines/saga/scene.cpp
@@ -468,7 +468,7 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy
colors = pal;
rect.setWidth(bbmBuffer.w);
rect.setHeight(bbmBuffer.h);
- _vm->_gfx->getBackBuffer()->blit(rect, (const byte*)bbmBuffer.pixels);
+ _vm->_gfx->drawRegion(rect, (const byte*)bbmBuffer.pixels);
for (int j = 0; j < PAL_ENTRIES; j++) {
cPal[j].red = *pal++;
cPal[j].green = *pal++;
@@ -1151,7 +1151,7 @@ void Scene::draw() {
Rect rect;
_vm->_render->getBackGroundSurface()->getRect(rect);
rect.bottom = (_sceneClip.bottom < rect.bottom) ? getHeight() : rect.bottom;
- _vm->_gfx->getBackBuffer()->blit(rect, (const byte *)_vm->_render->getBackGroundSurface()->pixels);
+ _vm->_gfx->drawRegion(rect, (const byte *)_vm->_render->getBackGroundSurface()->pixels);
}
}
@@ -1181,8 +1181,8 @@ void Scene::endScene() {
_vm->_scene->getBGInfo(bgInfo);
_vm->_render->getBackGroundSurface()->blit(bgInfo.bounds, bgInfo.buffer);
} else {
- _vm->_gfx->getBackBuffer()->getRect(rect);
- _vm->_render->getBackGroundSurface()->blit(rect, (const byte *)_vm->_gfx->getBackBuffer()->pixels);
+ _vm->_gfx->getBackBufferRect(rect);
+ _vm->_render->getBackGroundSurface()->blit(rect, (const byte *)_vm->_gfx->getBackBufferPixels());
}
// Free scene background
diff --git a/engines/saga/sfuncs.cpp b/engines/saga/sfuncs.cpp
index c2d7096153..54cded5d25 100644
--- a/engines/saga/sfuncs.cpp
+++ b/engines/saga/sfuncs.cpp
@@ -1171,7 +1171,6 @@ void Script::sfSimulSpeech2(SCRIPTFUNC_PARAMS) {
// Param1: string rid
void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
int stringId = thread->pop();
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
static PalEntry cur_pal[PAL_ENTRIES];
PalEntry *pal;
Event event;
@@ -1216,7 +1215,6 @@ void Script::sfPlacard(SCRIPTFUNC_PARAMS) {
event.type = kEvTOneshot;
event.code = kGraphicsEvent;
event.op = kEventFillRect;
- event.data = backBuffer;
event.param = 138;
event.param2 = 0;
event.param3 = _vm->_scene->getHeight();
diff --git a/engines/saga/sprite.cpp b/engines/saga/sprite.cpp
index 2723ce7d7f..200b0af206 100644
--- a/engines/saga/sprite.cpp
+++ b/engines/saga/sprite.cpp
@@ -218,9 +218,8 @@ void Sprite::drawClip(const Rect &clipRect, const Point &spritePointer, int widt
int i, j, jo, io;
byte *bufRowPointer;
const byte *srcRowPointer;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
- bufRowPointer = (byte *)backBuffer->pixels + backBuffer->pitch * spritePointer.y;
+ bufRowPointer = _vm->_gfx->getBackBufferPixels() + _vm->_gfx->getBackBufferPitch() * spritePointer.y;
srcRowPointer = spriteBuffer;
clipWidth = CLIP(width, 0, clipRect.right - spritePointer.x);
@@ -233,14 +232,14 @@ void Sprite::drawClip(const Rect &clipRect, const Point &spritePointer, int widt
}
if (spritePointer.y < clipRect.top) {
io = clipRect.top - spritePointer.y;
- bufRowPointer += backBuffer->pitch * io;
+ bufRowPointer += _vm->_gfx->getBackBufferPitch() * io;
srcRowPointer += width * io;
}
for (i = io; i < clipHeight; i++) {
for (j = jo; j < clipWidth; j++) {
- assert((byte *)backBuffer->pixels <= (byte *)(bufRowPointer + j + spritePointer.x));
- assert(((byte *)backBuffer->pixels + (_vm->getDisplayWidth() *
+ assert(_vm->_gfx->getBackBufferPixels() <= (byte *)(bufRowPointer + j + spritePointer.x));
+ assert((_vm->_gfx->getBackBufferPixels() + (_vm->getDisplayWidth() *
_vm->getDisplayHeight())) > (byte *)(bufRowPointer + j + spritePointer.x));
assert((const byte *)spriteBuffer <= (const byte *)(srcRowPointer + j));
assert(((const byte *)spriteBuffer + (width * height)) > (const byte *)(srcRowPointer + j));
@@ -249,7 +248,7 @@ void Sprite::drawClip(const Rect &clipRect, const Point &spritePointer, int widt
*(bufRowPointer + j + spritePointer.x) = *(srcRowPointer + j);
}
}
- bufRowPointer += backBuffer->pitch;
+ bufRowPointer += _vm->_gfx->getBackBufferPitch();
srcRowPointer += width;
}
}
@@ -333,7 +332,6 @@ void Sprite::drawOccluded(const Rect &clipRect, SpriteList &spriteList, int spri
int height = 0;
int xAlign = 0;
int yAlign = 0;
- Surface *backBuffer = _vm->_gfx->getBackBuffer();
ClipData clipData;
@@ -371,7 +369,7 @@ void Sprite::drawOccluded(const Rect &clipRect, SpriteList &spriteList, int spri
// Finally, draw the occluded sprite
sourceRowPointer = spriteBuffer + clipData.drawSource.x + (clipData.drawSource.y * width);
- destRowPointer = (byte *)backBuffer->pixels + clipData.drawDest.x + (clipData.drawDest.y * backBuffer->pitch);
+ destRowPointer = _vm->_gfx->getBackBufferPixels() + clipData.drawDest.x + (clipData.drawDest.y * _vm->_gfx->getBackBufferPitch());
maskRowPointer = maskBuffer + clipData.drawDest.x + (clipData.drawDest.y * maskWidth);
for (y = 0; y < clipData.drawHeight; y++) {
@@ -389,7 +387,7 @@ void Sprite::drawOccluded(const Rect &clipRect, SpriteList &spriteList, int spri
destPointer++;
maskPointer++;
}
- destRowPointer += backBuffer->pitch;
+ destRowPointer += _vm->_gfx->getBackBufferPitch();
maskRowPointer += maskWidth;
sourceRowPointer += width;
}