diff options
author | Filippos Karapetis | 2008-12-06 18:23:34 +0000 |
---|---|---|
committer | Filippos Karapetis | 2008-12-06 18:23:34 +0000 |
commit | 065694dbb166d2fb113ba36b9340d91f9c71fdbe (patch) | |
tree | c986e2dfb4c30027ce444397cb27f09f2c8b7f67 /engines/saga | |
parent | 5f2cd3c4a7e771a30e132fa90936b1da72fa21ab (diff) | |
download | scummvm-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.cpp | 2 | ||||
-rw-r--r-- | engines/saga/font.cpp | 20 | ||||
-rw-r--r-- | engines/saga/gfx.cpp | 25 | ||||
-rw-r--r-- | engines/saga/gfx.h | 74 | ||||
-rw-r--r-- | engines/saga/interface.cpp | 80 | ||||
-rw-r--r-- | engines/saga/isomap.cpp | 9 | ||||
-rw-r--r-- | engines/saga/objectmap.cpp | 7 | ||||
-rw-r--r-- | engines/saga/render.cpp | 32 | ||||
-rw-r--r-- | engines/saga/render.h | 22 | ||||
-rw-r--r-- | engines/saga/scene.cpp | 8 | ||||
-rw-r--r-- | engines/saga/sfuncs.cpp | 2 | ||||
-rw-r--r-- | engines/saga/sprite.cpp | 16 |
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; } |