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 | |
| 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
| -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;  	} | 
