- 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
This commit is contained in:
Filippos Karapetis 2008-12-06 18:23:34 +00:00
parent 5f2cd3c4a7
commit 065694dbb1
12 changed files with 207 additions and 90 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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];

View File

@ -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);

View File

@ -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++;

View File

@ -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

View File

@ -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();

View File

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

View File

@ -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

View File

@ -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();

View File

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