aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mads/debugger.cpp2
-rw-r--r--engines/mads/dialogs.cpp50
-rw-r--r--engines/mads/dragonsphere/dragonsphere_scenes.cpp2
-rw-r--r--engines/mads/events.cpp6
-rw-r--r--engines/mads/font.cpp21
-rw-r--r--engines/mads/game.cpp5
-rw-r--r--engines/mads/mads.cpp4
-rw-r--r--engines/mads/mads.h2
-rw-r--r--engines/mads/menu_views.cpp30
-rw-r--r--engines/mads/msurface.cpp343
-rw-r--r--engines/mads/msurface.h142
-rw-r--r--engines/mads/nebular/dialogs_nebular.cpp32
-rw-r--r--engines/mads/nebular/menu_nebular.cpp4
-rw-r--r--engines/mads/nebular/nebular_scenes.cpp4
-rw-r--r--engines/mads/nebular/nebular_scenes3.cpp18
-rw-r--r--engines/mads/phantom/phantom_scenes.cpp2
-rw-r--r--engines/mads/rails.cpp2
-rw-r--r--engines/mads/scene.cpp9
-rw-r--r--engines/mads/scene_data.cpp13
-rw-r--r--engines/mads/screen.cpp106
-rw-r--r--engines/mads/screen.h36
-rw-r--r--engines/mads/sequence.cpp4
-rw-r--r--engines/mads/sprites.cpp26
-rw-r--r--engines/mads/user_interface.cpp46
-rw-r--r--engines/mads/user_interface.h2
25 files changed, 378 insertions, 533 deletions
diff --git a/engines/mads/debugger.cpp b/engines/mads/debugger.cpp
index 740c19abad..b9731b1d31 100644
--- a/engines/mads/debugger.cpp
+++ b/engines/mads/debugger.cpp
@@ -158,7 +158,7 @@ bool Debugger::Cmd_ShowCodes(int argc, const char **argv) {
Scene &scene = _vm->_game->_scene;
// Copy the depth/walk surface to the background and flag for screen refresh
- scene._depthSurface.copyTo(&scene._backgroundSurface);
+ scene._depthSurface.blitFrom(scene._backgroundSurface);
scene._spriteSlots.fullRefresh();
// Draw the locations of scene nodes onto the background
diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp
index d9a1e53964..fa656a90c1 100644
--- a/engines/mads/dialogs.cpp
+++ b/engines/mads/dialogs.cpp
@@ -54,21 +54,19 @@ Dialog::~Dialog() {
void Dialog::save() {
_savedSurface = new MSurface(_width, _height);
- _vm->_screen.copyTo(_savedSurface,
+ _savedSurface->blitFrom(*_vm->_screen,
Common::Rect(_position.x, _position.y, _position.x + _width, _position.y + _height),
Common::Point());
- _vm->_screen.copyRectToScreen(getBounds());
+// _vm->_screen->copyRectToScreen(getBounds());
}
void Dialog::restore() {
if (_savedSurface) {
- _savedSurface->copyTo(&_vm->_screen, _position);
+ _vm->_screen->blitFrom(*_savedSurface, _position);
delete _savedSurface;
_savedSurface = nullptr;
- _vm->_screen.copyRectToScreen(getBounds());
-
Common::copy(&_dialogPalette[0], &_dialogPalette[8 * 3],
&_vm->_palette->_mainPalette[248 * 3]);
_vm->_palette->setPalette(&_vm->_palette->_mainPalette[248 * 3], 248, 8);
@@ -87,16 +85,16 @@ void Dialog::draw() {
// Draw the dialog
// Fill entire content of dialog
Common::Rect bounds = getBounds();
- _vm->_screen.fillRect(bounds, TEXTDIALOG_BACKGROUND);
+ _vm->_screen->fillRect(bounds, TEXTDIALOG_BACKGROUND);
// Draw the outer edge lines
- _vm->_screen.hLine(_position.x + 1, _position.y + _height - 2,
+ _vm->_screen->hLine(_position.x + 1, _position.y + _height - 2,
_position.x + _width - 2, TEXTDIALOG_EDGE);
- _vm->_screen.hLine(_position.x, _position.y + _height - 1,
+ _vm->_screen->hLine(_position.x, _position.y + _height - 1,
_position.x + _width - 1, TEXTDIALOG_EDGE);
- _vm->_screen.vLine(_position.x + _width - 2, _position.y + 2,
+ _vm->_screen->vLine(_position.x + _width - 2, _position.y + 2,
_position.y + _height - 2, TEXTDIALOG_EDGE);
- _vm->_screen.vLine(_position.x + _width - 1, _position.y + 1,
+ _vm->_screen->vLine(_position.x + _width - 1, _position.y + 1,
_position.y + _height - 1, TEXTDIALOG_EDGE);
// Draw the gravelly dialog content
@@ -125,8 +123,9 @@ void Dialog::calculateBounds() {
void Dialog::drawContent(const Common::Rect &r, int seed, byte color1, byte color2) {
uint16 currSeed = seed ? seed : 0xB78E;
+ Graphics::Surface dest = _vm->_screen->getSubArea(r);
for (int yp = 0; yp < r.height(); ++yp) {
- byte *destP = _vm->_screen.getBasePtr(r.left, r.top + yp);
+ byte *destP = (byte *)dest.getBasePtr(0, yp);
for (int xp = 0; xp < r.width(); ++xp) {
uint16 seedAdjust = currSeed;
@@ -326,7 +325,7 @@ void TextDialog::draw() {
for (int lineNum = 0; lineNum <= _numLines; ++lineNum) {
if (_lineXp[lineNum] == -1) {
// Draw a line across the entire dialog
- _vm->_screen.hLine(_position.x + 2,
+ _vm->_screen->hLine(_position.x + 2,
lineYp + (_font->getHeight() + 1) / 2,
_position.x + _width - 4, TEXTDIALOG_BLACK);
} else {
@@ -336,21 +335,19 @@ void TextDialog::draw() {
if (_lineXp[lineNum] & 0x40)
++yp;
- _font->writeString(&_vm->_screen, _lines[lineNum],
+ _font->writeString(_vm->_screen, _lines[lineNum],
Common::Point(xp, yp), 1);
if (_lineXp[lineNum] & 0x80) {
// Draw an underline under the text
int lineWidth = _font->getWidth(_lines[lineNum], 1);
- _vm->_screen.hLine(xp, yp + _font->getHeight(), xp + lineWidth,
+ _vm->_screen->hLine(xp, yp + _font->getHeight(), xp + lineWidth,
TEXTDIALOG_BLACK);
}
}
lineYp += _font->getHeight() + 1;
}
-
- _vm->_screen.copyRectToScreen(getBounds());
}
void TextDialog::calculateBounds() {
@@ -360,10 +357,10 @@ void TextDialog::calculateBounds() {
if (_position.y == -1)
_position.y = 100 - (_height / 2);
- if ((_position.x + _width) > _vm->_screen.getWidth())
- _position.x = _vm->_screen.getWidth() - (_position.x + _width);
- if ((_position.y + _height) > _vm->_screen.getHeight())
- _position.y = _vm->_screen.getHeight() - (_position.y + _height);
+ if ((_position.x + _width) > _vm->_screen->w)
+ _position.x = _vm->_screen->w - (_position.x + _width);
+ if ((_position.y + _height) > _vm->_screen->h)
+ _position.y = _vm->_screen->h - (_position.y + _height);
}
void TextDialog::drawWithInput() {
@@ -452,7 +449,7 @@ FullScreenDialog::FullScreenDialog(MADSEngine *vm) : _vm(vm) {
}
FullScreenDialog::~FullScreenDialog() {
- _vm->_screen.resetClipBounds();
+ _vm->_screen->resetClipBounds();
_vm->_game->_scene.restrictScene();
}
@@ -491,16 +488,13 @@ void FullScreenDialog::display() {
game._trigger = 0;
// Clear the screen and draw the upper and lower horizontal lines
- _vm->_screen.empty();
+ _vm->_screen->clear();
_vm->_palette->setLowRange();
- _vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2);
- _vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2);
- _vm->_screen.resetClipBounds();
- _vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+ _vm->_screen->hLine(0, 20, MADS_SCREEN_WIDTH, 2);
+ _vm->_screen->hLine(0, 179, MADS_SCREEN_WIDTH, 2);
// Restrict the screen to the area between the two lines
- _vm->_screen.setClipBounds(Common::Rect(0, DIALOG_TOP, MADS_SCREEN_WIDTH,
- DIALOG_TOP + MADS_SCENE_HEIGHT));
+ _vm->_screen->setClipBounds(Common::Rect(0, DIALOG_TOP, MADS_SCREEN_WIDTH, DIALOG_TOP + MADS_SCENE_HEIGHT));
_vm->_game->_scene.restrictScene();
if (_screenId > 0)
diff --git a/engines/mads/dragonsphere/dragonsphere_scenes.cpp b/engines/mads/dragonsphere/dragonsphere_scenes.cpp
index 938931e80d..a18d03d143 100644
--- a/engines/mads/dragonsphere/dragonsphere_scenes.cpp
+++ b/engines/mads/dragonsphere/dragonsphere_scenes.cpp
@@ -218,7 +218,7 @@ void SceneInfoDragonsphere::loadCodes(MSurface &depthSurface, int variant) {
}
void SceneInfoDragonsphere::loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream) {
- byte *destP = depthSurface.getData();
+ byte *destP = (byte *)depthSurface.getPixels();
byte *walkMap = new byte[stream->size()];
stream->read(walkMap, stream->size());
diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp
index 7463704c4b..de83260b0f 100644
--- a/engines/mads/events.cpp
+++ b/engines/mads/events.cpp
@@ -98,7 +98,7 @@ void EventsManager::changeCursor() {
// Check for hotspot indication pixels along the right-hand and bottom
// row. Put together, these give the cursor's hotspot x,y
int hotspotX = 0, hotspotY = 0;
- byte *cursorData = cursor->getData();
+ const byte *cursorData = (const byte *)cursor->getPixels();
for (int idx = 0; idx < cursor->w; ++idx) {
if (cursorData[(cursor->h - 1) * cursor->w + idx] != transIndex)
hotspotX = idx;
@@ -110,7 +110,7 @@ void EventsManager::changeCursor() {
// Reduce the cursor data to remove the last column from each row, since
// the cursor routines don't have a pitch option
byte *destCursor = new byte[(cursor->w - 1) * (cursor->h - 1)];
- byte *srcP = cursorData;
+ const byte *srcP = cursorData;
byte *destP = destCursor;
for (int idx = 0; idx < (cursor->h - 1); ++idx) {
@@ -217,7 +217,7 @@ bool EventsManager::checkForNextFrameCounter() {
_vm->_debugger->onFrame();
// Display the frame
- _vm->_screen.updateScreen();
+ _vm->_screen->update();
// Signal the ScummVM debugger
_vm->_debugger->onFrame();
diff --git a/engines/mads/font.cpp b/engines/mads/font.cpp
index 3e6d23fe6f..3828c3df8e 100644
--- a/engines/mads/font.cpp
+++ b/engines/mads/font.cpp
@@ -167,16 +167,13 @@ int Font::writeString(MSurface *surface, const Common::String &msg, const Common
return x;
int bottom = y + height - 1;
- if (bottom > surface->getHeight() - 1) {
- height -= MIN(height, bottom - (surface->getHeight() - 1));
+ if (bottom > surface->h - 1) {
+ height -= MIN(height, bottom - (surface->h - 1));
}
if (height <= 0)
return x;
- byte *destPtr = surface->getBasePtr(x, y);
- uint8 *oldDestPtr = destPtr;
-
int xPos = x;
const char *text = msg.c_str();
@@ -185,10 +182,11 @@ int Font::writeString(MSurface *surface, const Common::String &msg, const Common
int charWidth = _charWidths[(byte)theChar];
if (charWidth > 0) {
-
if (xPos + charWidth > xEnd)
return xPos;
+ Graphics::Surface dest = surface->getSubArea(
+ Common::Rect(xPos, y, xPos + charWidth, y + height));
uint8 *charData = &_charData[_charOffs[(byte)theChar]];
int bpp = getBpp(charWidth);
@@ -196,6 +194,8 @@ int Font::writeString(MSurface *surface, const Common::String &msg, const Common
charData += bpp * skipY;
for (int i = 0; i < height; i++) {
+ byte *destPtr = (byte *)dest.getBasePtr(0, i);
+
for (int j = 0; j < bpp; j++) {
if (*charData & 0xc0)
*destPtr = _fontColors[(*charData & 0xc0) >> 6];
@@ -211,22 +211,13 @@ int Font::writeString(MSurface *surface, const Common::String &msg, const Common
destPtr++;
charData++;
}
-
- destPtr += surface->getWidth() - bpp * 4;
-
}
-
- destPtr = oldDestPtr + charWidth + spaceWidth;
- oldDestPtr = destPtr;
-
}
xPos += charWidth + spaceWidth;
-
}
return xPos;
-
}
int Font::getWidth(const Common::String &msg, int spaceWidth) {
diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp
index 8ebea2a3b2..0a6741ba7a 100644
--- a/engines/mads/game.cpp
+++ b/engines/mads/game.cpp
@@ -498,7 +498,7 @@ void Game::loadGame(int slotNumber) {
_scene._currentSceneId = -2;
_sectionNumber = _scene._nextSceneId / 100;
_scene._frameStartTime = _vm->_events->getFrameCounter();
- _vm->_screen._shakeCountdown = -1;
+ _vm->_screen->_shakeCountdown = -1;
// Default the selected inventory item to the first one, if the player has any
_scene._userInterface._selectedInvIndex = _objects._inventoryList.size() > 0 ? 0 : -1;
@@ -600,7 +600,8 @@ void Game::createThumbnail() {
uint8 thumbPalette[PALETTE_SIZE];
_vm->_palette->grabPalette(thumbPalette, 0, PALETTE_COUNT);
_saveThumb = new Graphics::Surface();
- ::createThumbnail(_saveThumb, _vm->_screen.getData(), MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT, thumbPalette);
+ ::createThumbnail(_saveThumb, (const byte *)_vm->_screen->getPixels(),
+ MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT, thumbPalette);
}
void Game::syncTimers(SyncType slaveType, int slaveId, SyncType masterType, int masterId) {
diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp
index deccb5ba4f..29bcd10094 100644
--- a/engines/mads/mads.cpp
+++ b/engines/mads/mads.cpp
@@ -94,7 +94,7 @@ void MADSEngine::initialize() {
_palette = new Palette(this);
Font::init(this);
_font = new Font();
- _screen.init();
+ _screen = new Screen();
_sound = new SoundManager(this, _mixer);
_audio = new AudioPlayer(_mixer, getGameID());
_game = Game::init(this);
@@ -102,7 +102,7 @@ void MADSEngine::initialize() {
loadOptions();
- _screen.empty();
+ _screen->clear();
}
void MADSEngine::loadOptions() {
diff --git a/engines/mads/mads.h b/engines/mads/mads.h
index eb808de32f..52f71f7c79 100644
--- a/engines/mads/mads.h
+++ b/engines/mads/mads.h
@@ -100,7 +100,7 @@ public:
GameConversations * _gameConv;
Palette *_palette;
Resources *_resources;
- ScreenSurface _screen;
+ Screen *_screen;
SoundManager *_sound;
AudioPlayer *_audio;
bool _easyMouse;
diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp
index 10d5a2179a..9050ca6081 100644
--- a/engines/mads/menu_views.cpp
+++ b/engines/mads/menu_views.cpp
@@ -253,7 +253,7 @@ void TextView::processCommand() {
SceneInfo *sceneInfo = SceneInfo::init(_vm);
sceneInfo->_width = MADS_SCREEN_WIDTH;
sceneInfo->_height = MADS_SCENE_HEIGHT;
- _spareScreens[spareIndex].setSize(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
+ _spareScreens[spareIndex].create(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
sceneInfo->loadMadsV1Background(screenId, "", SCENEFLAG_TRANSLATE,
_spareScreens[spareIndex]);
@@ -346,9 +346,11 @@ void TextView::doFrame() {
// If a screen transition is in progress and it's time for another column, handle it
if (_spareScreen) {
- byte *srcP = _spareScreen->getBasePtr(_translationX, 0);
- byte *bgP = scene._backgroundSurface.getBasePtr(_translationX, 0);
- byte *screenP = (byte *)_vm->_screen.getBasePtr(_translationX, 0);
+ const byte *srcP = (const byte *)_spareScreen->getBasePtr(_translationX, 0);
+ byte *bgP = (byte *)scene._backgroundSurface.getBasePtr(_translationX, 0);
+
+ Graphics::Surface dest = _vm->_screen->getSubArea(Common::Rect(_translationX, 0, _translationX + 1, 0));
+ byte *screenP = (byte *)dest.getBasePtr(0, 0);
for (int y = 0; y < MADS_SCENE_HEIGHT; ++y, srcP += MADS_SCREEN_WIDTH,
bgP += MADS_SCREEN_WIDTH, screenP += MADS_SCREEN_WIDTH) {
@@ -356,10 +358,6 @@ void TextView::doFrame() {
*screenP = *srcP;
}
- // Flag the column of the screen is modified
- _vm->_screen.copyRectToScreen(Common::Rect(_translationX, 0,
- _translationX + 1, MADS_SCENE_HEIGHT));
-
// Keep moving the column to copy to the right
if (++_translationX == MADS_SCREEN_WIDTH) {
// Surface transition is complete
@@ -571,6 +569,7 @@ void AnimationView::doFrame() {
void AnimationView::loadNextResource() {
Scene &scene = _vm->_game->_scene;
Palette &palette = *_vm->_palette;
+ Screen &screen = *_vm->_screen;
ResourceEntry &resEntry = _resources[_resourceIndex];
Common::Array<PaletteCycle> paletteCycles;
@@ -587,12 +586,15 @@ void AnimationView::loadNextResource() {
// Handle the bars at the top/bottom
if (resEntry._showWhiteBars) {
// For animations the screen has been clipped to the middle 156 rows.
- // So although it's slightly messy, bypass our screen class entirely,
- // and draw the horizontal lines directly on the physiacl screen surface
- Graphics::Surface *s = g_system->lockScreen();
- s->hLine(0, 20, MADS_SCREEN_WIDTH, 253);
- s->hLine(0, 179, MADS_SCREEN_WIDTH, 253);
- g_system->unlockScreen();
+ // So although it's slightly messy, temporarily reset clip bounds
+ // so we can redraw the white lines
+ Common::Rect clipBounds = screen.getClipBounds();
+ screen.resetClipBounds();
+
+ screen.hLine(0, 20, MADS_SCREEN_WIDTH, 253);
+ screen.hLine(0, 179, MADS_SCREEN_WIDTH, 253);
+
+ screen.setClipBounds(clipBounds);
}
// Load the new animation
diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp
index f768624278..40c69c0f08 100644
--- a/engines/mads/msurface.cpp
+++ b/engines/mads/msurface.cpp
@@ -32,37 +32,6 @@ namespace MADS {
MADSEngine *MSurface::_vm = nullptr;
-MSurface::MSurface() {
- pixels = nullptr;
- _freeFlag = false;
-}
-
-MSurface::MSurface(int width, int height) {
- pixels = nullptr;
- _freeFlag = false;
- setSize(width, height);
-}
-
-MSurface::~MSurface() {
- if (_freeFlag)
- Graphics::Surface::free();
-}
-
-void MSurface::setSize(int width, int height) {
- if (_freeFlag)
- Graphics::Surface::free();
- Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- _freeFlag = true;
-}
-
-void MSurface::setPixels(byte *pData, int horizSize, int vertSize) {
- _freeFlag = false;
- pixels = pData;
- w = pitch = horizSize;
- h = vertSize;
- format.bytesPerPixel = 1;
-}
-
int MSurface::scaleValue(int value, int scale, int err) {
int scaled = 0;
while (value--) {
@@ -76,7 +45,6 @@ int MSurface::scaleValue(int value, int scale, int err) {
}
void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Common::Rect &clipRect) {
-
enum {
kStatusSkip,
kStatusScale,
@@ -116,8 +84,8 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo
return;
int heightAmt = scaledHeight;
- byte *src = info.sprite->getData();
- byte *dst = getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY);
+ const byte *src = (const byte *)info.sprite->getPixels();
+ byte *dst = (byte *)getBasePtr(x - info.hotX - clipX, y - info.hotY - clipY);
int status = kStatusSkip;
byte *scaledLineBuf = new byte[scaledWidth];
@@ -138,7 +106,7 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo
byte *lineDst = scaledLineBuf;
int curErrX = errX;
int width = scaledWidth;
- byte *tempSrc = src;
+ const byte *tempSrc = src;
int startX = clipX;
while (width > 0) {
byte pixel = *tempSrc++;
@@ -201,63 +169,136 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo
}
delete[] scaledLineBuf;
-
}
-void MSurface::empty() {
- Common::fill(getBasePtr(0, 0), getBasePtr(0, h), 0);
+void MSurface::scrollX(int xAmount) {
+ if (xAmount == 0)
+ return;
+
+ byte buffer[80];
+ int direction = (xAmount > 0) ? -1 : 1;
+ int xSize = ABS(xAmount);
+ assert(xSize <= 80);
+
+ byte *srcP = (byte *)getBasePtr(0, 0);
+
+ for (int y = 0; y < this->h; ++y, srcP += pitch) {
+ if (direction < 0) {
+ // Copy area to be overwritten
+ Common::copy(srcP, srcP + xSize, &buffer[0]);
+ // Shift the remainder of the line over the given area
+ Common::copy(srcP + xSize, srcP + this->w, srcP);
+ // Move buffered area to the end of the line
+ Common::copy(&buffer[0], &buffer[xSize], srcP + this->w - xSize);
+ } else {
+ // Copy area to be overwritten
+ Common::copy_backward(srcP + this->w - xSize, srcP + this->w, &buffer[80]);
+ // Shift the remainder of the line over the given area
+ Common::copy_backward(srcP, srcP + this->w - xSize, srcP + this->w);
+ // Move buffered area to the start of the line
+ Common::copy_backward(&buffer[80 - xSize], &buffer[80], srcP + xSize);
+ }
+ }
+
+ markAllDirty();
}
-void MSurface::copyFrom(MSurface *src, const Common::Rect &srcBounds,
- const Common::Point &destPos, int transparentColor) {
- // Validation of the rectangle and position
- int destX = destPos.x, destY = destPos.y;
- if ((destX >= w) || (destY >= h))
+void MSurface::scrollY(int yAmount) {
+ if (yAmount == 0)
return;
- Common::Rect copyRect = srcBounds;
- if (destX < 0) {
- copyRect.left += -destX;
- destX = 0;
- } else if (destX + copyRect.width() > w) {
- copyRect.right -= destX + copyRect.width() - w;
- }
- if (destY < 0) {
- copyRect.top += -destY;
- destY = 0;
- } else if (destY + copyRect.height() > h) {
- copyRect.bottom -= destY + copyRect.height() - h;
+ int direction = (yAmount > 0) ? 1 : -1;
+ int ySize = ABS(yAmount);
+ assert(ySize < (this->h / 2));
+ assert(this->w == pitch);
+
+ int blockSize = ySize * this->w;
+ byte *tempData = new byte[blockSize];
+ byte *pixelsP = (byte *)getBasePtr(0, 0);
+
+ if (direction > 0) {
+ // Buffer the lines to be overwritten
+ byte *srcP = (byte *)getBasePtr(0, this->h - ySize);
+ Common::copy(srcP, srcP + (pitch * ySize), tempData);
+ // Vertically shift all the lines
+ Common::copy_backward(pixelsP, pixelsP + (pitch * (this->h - ySize)),
+ pixelsP + (pitch * this->h));
+ // Transfer the buffered lines top the top of the screen
+ Common::copy(tempData, tempData + blockSize, pixelsP);
+ } else {
+ // Buffer the lines to be overwritten
+ Common::copy(pixelsP, pixelsP + (pitch * ySize), tempData);
+ // Vertically shift all the lines
+ Common::copy(pixelsP + (pitch * ySize), pixelsP + (pitch * this->h), pixelsP);
+ // Transfer the buffered lines to the bottom of the screen
+ Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (this->h - ySize)));
}
- if (!copyRect.isValidRect())
- return;
+ markAllDirty();
+ delete[] tempData;
+}
- // Copy the specified area
+void MSurface::translate(Common::Array<RGB6> &palette) {
+ for (int y = 0; y < this->h; ++y) {
+ byte *pDest = (byte *)getBasePtr(0, y);
+
+ for (int x = 0; x < this->w; ++x, ++pDest) {
+ if (*pDest < 255) // scene 752 has some palette indices of 255
+ *pDest = palette[*pDest]._palIndex;
+ }
+ }
- byte *data = src->getData();
- byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left);
- byte *destPtr = (byte *)pixels + (destY * getWidth()) + destX;
+ markAllDirty();
+}
- for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
- if (transparentColor == -1) {
- // No transparency, so copy line over
- Common::copy(srcPtr, srcPtr + copyRect.width(), destPtr);
- } else {
- // Copy each byte one at a time checking for the transparency color
- for (int xCtr = 0; xCtr < copyRect.width(); ++xCtr)
- if (srcPtr[xCtr] != transparentColor) destPtr[xCtr] = srcPtr[xCtr];
+void MSurface::translate(byte map[PALETTE_COUNT]) {
+ for (int y = 0; y < this->h; ++y) {
+ byte *pDest = (byte *)getBasePtr(0, y);
+
+ for (int x = 0; x < this->w; ++x, ++pDest) {
+ *pDest = map[*pDest];
}
+ }
+
+ markAllDirty();
+}
+
+MSurface *MSurface::flipHorizontal() const {
+ MSurface *dest = new MSurface(this->w, this->h);
+
+ for (int y = 0; y < this->h; ++y) {
+ const byte *srcP = getBasePtr(this->w - 1, y);
+ byte *destP = dest->getBasePtr(0, y);
- srcPtr += src->getWidth();
- destPtr += getWidth();
+ for (int x = 0; x < this->w; ++x)
+ *destP++ = *srcP--;
+ }
+
+ return dest;
+}
+
+void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
+ const Common::Point &destPos, const Common::Rect &srcRect) {
+ // Loop through the lines
+ for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) {
+ const byte *srcP = (const byte *)srcSurface.getBasePtr(srcRect.left, srcRect.top + yCtr);
+ byte *destP = (byte *)getBasePtr(destPos.x, destPos.y + yCtr);
+
+ // Copy the line over
+ for (int xCtr = 0; xCtr < srcRect.width(); ++xCtr, ++srcP, ++destP) {
+ *destP = paletteMap[*srcP];
+ }
}
+
+ addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + srcRect.width(),
+ destPos.y + srcRect.height()));
}
-void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
+void MSurface::copyFrom(MSurface &src, const Common::Point &destPos, int depth,
DepthSurface *depthSurface, int scale, bool flipped, int transparentColor) {
int destX = destPos.x, destY = destPos.y;
- int frameWidth = src->getWidth();
- int frameHeight = src->getHeight();
+ int frameWidth = src.w;
+ int frameHeight = src.h;
int direction = flipped ? -1 : 1;
int highestDim = MAX(frameWidth, frameHeight);
@@ -271,7 +312,8 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
distCtr += scale;
if (distCtr < 100) {
lineDist[distIndex] = false;
- } else {
+ }
+ else {
lineDist[distIndex] = true;
distCtr -= 100;
@@ -290,18 +332,20 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
// Special case for quicker drawing of non-scaled images
if (scale == 100 || scale == -1) {
// Copy the specified area
- Common::Rect copyRect(0, 0, src->getWidth(), src->getHeight());
+ Common::Rect copyRect(0, 0, src.w, src.h);
if (destX < 0) {
copyRect.left += -destX;
destX = 0;
- } else if (destX + copyRect.width() > w) {
+ }
+ else if (destX + copyRect.width() > w) {
copyRect.right -= destX + copyRect.width() - w;
}
if (destY < 0) {
copyRect.top += -destY;
destY = 0;
- } else if (destY + copyRect.height() > h) {
+ }
+ else if (destY + copyRect.height() > h) {
copyRect.bottom -= destY + copyRect.height() - h;
}
@@ -311,9 +355,9 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
if (flipped)
copyRect.moveTo(0, copyRect.top);
- byte *data = src->getData();
- byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left);
- byte *destPtr = (byte *)pixels + (destY * pitch) + destX;
+ byte *data = src.getPixels();
+ byte *srcPtr = data + (src.w * copyRect.top + copyRect.left);
+ byte *destPtr = (byte *)getPixels() + (destY * pitch) + destX;
if (flipped)
srcPtr += copyRect.width() - 1;
@@ -329,18 +373,18 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
destPtr[xCtr] = *srcP;
}
- srcPtr += src->getWidth();
- destPtr += getWidth();
+ srcPtr += src.w;
+ destPtr += this->w;
}
return;
}
// Start of draw logic for scaled sprites
- const byte *srcPixelsP = src->getData();
+ const byte *srcPixelsP = src.getPixels();
- int destRight = this->getWidth() - 1;
- int destBottom = this->getHeight() - 1;
+ int destRight = this->w - 1;
+ int destBottom = this->h - 1;
// Check x bounding area
int spriteLeft = 0;
@@ -387,7 +431,7 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
spriteLeft = spriteLeft * direction;
// Loop through the lines of the sprite
- for (int yp = 0, sprY = -1; yp < frameHeight; ++yp, srcPixelsP += src->pitch) {
+ for (int yp = 0, sprY = -1; yp < frameHeight; ++yp, srcPixelsP += src.pitch) {
if (!lineDist[yp])
// Not a display line, so skip it
continue;
@@ -411,8 +455,8 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
continue;
// Get depth of current output pixel in depth surface
- Common::Point pt((destP - (byte *)this->pixels) % this->pitch,
- (destP - (byte *)this->pixels) / this->pitch);
+ Common::Point pt((destP - (byte *)getPixels()) % this->pitch,
+ (destP - (byte *)getPixels()) / this->pitch);
int pixelDepth = (depthSurface == nullptr) ? 15 : depthSurface->getDepth(pt);
if ((*srcP != transparentColor) && (depth <= pixelDepth))
@@ -424,119 +468,8 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth,
// Move to the next destination line
destPixelsP += this->pitch;
}
-}
-
-void MSurface::scrollX(int xAmount) {
- if (xAmount == 0)
- return;
-
- byte buffer[80];
- int direction = (xAmount > 0) ? -1 : 1;
- int xSize = ABS(xAmount);
- assert(xSize <= 80);
-
- byte *srcP = getBasePtr(0, 0);
-
- for (int y = 0; y < this->h; ++y, srcP += pitch) {
- if (direction < 0) {
- // Copy area to be overwritten
- Common::copy(srcP, srcP + xSize, &buffer[0]);
- // Shift the remainder of the line over the given area
- Common::copy(srcP + xSize, srcP + this->w, srcP);
- // Move buffered area to the end of the line
- Common::copy(&buffer[0], &buffer[xSize], srcP + this->w - xSize);
- } else {
- // Copy area to be overwritten
- Common::copy_backward(srcP + this->w - xSize, srcP + this->w, &buffer[80]);
- // Shift the remainder of the line over the given area
- Common::copy_backward(srcP, srcP + this->w - xSize, srcP + this->w);
- // Move buffered area to the start of the line
- Common::copy_backward(&buffer[80 - xSize], &buffer[80], srcP + xSize);
- }
- }
-}
-
-void MSurface::scrollY(int yAmount) {
- if (yAmount == 0)
- return;
-
- int direction = (yAmount > 0) ? 1 : -1;
- int ySize = ABS(yAmount);
- assert(ySize < (this->h / 2));
- assert(this->w == pitch);
-
- int blockSize = ySize * this->w;
- byte *tempData = new byte[blockSize];
- byte *pixelsP = getBasePtr(0, 0);
-
- if (direction > 0) {
- // Buffer the lines to be overwritten
- byte *srcP = (byte *)getBasePtr(0, this->h - ySize);
- Common::copy(srcP, srcP + (pitch * ySize), tempData);
- // Vertically shift all the lines
- Common::copy_backward(pixelsP, pixelsP + (pitch * (this->h - ySize)),
- pixelsP + (pitch * this->h));
- // Transfer the buffered lines top the top of the screen
- Common::copy(tempData, tempData + blockSize, pixelsP);
- } else {
- // Buffer the lines to be overwritten
- Common::copy(pixelsP, pixelsP + (pitch * ySize), tempData);
- // Vertically shift all the lines
- Common::copy(pixelsP + (pitch * ySize), pixelsP + (pitch * this->h), pixelsP);
- // Transfer the buffered lines to the bottom of the screen
- Common::copy(tempData, tempData + blockSize, pixelsP + (pitch * (this->h - ySize)));
- }
-
- delete[] tempData;
-}
-
-void MSurface::translate(Common::Array<RGB6> &palette) {
- for (int y = 0; y < this->h; ++y) {
- byte *pDest = getBasePtr(0, y);
-
- for (int x = 0; x < this->w; ++x, ++pDest) {
- if (*pDest < 255) // scene 752 has some palette indices of 255
- *pDest = palette[*pDest]._palIndex;
- }
- }
-}
-
-void MSurface::translate(byte map[PALETTE_COUNT]) {
- for (int y = 0; y < this->h; ++y) {
- byte *pDest = getBasePtr(0, y);
-
- for (int x = 0; x < this->w; ++x, ++pDest) {
- *pDest = map[*pDest];
- }
- }
-}
-
-MSurface *MSurface::flipHorizontal() const {
- MSurface *dest = new MSurface(this->w, this->h);
-
- for (int y = 0; y < this->h; ++y) {
- const byte *srcP = getBasePtr(this->w - 1, y);
- byte *destP = dest->getBasePtr(0, y);
-
- for (int x = 0; x < this->w; ++x)
- *destP++ = *srcP--;
- }
-
- return dest;
-}
-
-void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
- const Common::Point &destPos, const Common::Rect &srcRect) {
- // Loop through the lines
- for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) {
- const byte *srcP = srcSurface.getBasePtr(srcRect.left, srcRect.top + yCtr);
- byte *destP = getBasePtr(destPos.x, destPos.y + yCtr);
- // Copy the line over
- for (int xCtr = 0; xCtr < srcRect.width(); ++xCtr, ++srcP, ++destP) {
- *destP = paletteMap[*srcP];
- }
- }
+ addDirtyRect(Common::Rect(destX, destY, destX + frameWidth, destY + frameHeight));
}
/*------------------------------------------------------------------------*/
@@ -544,26 +477,26 @@ void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
int DepthSurface::getDepth(const Common::Point &pt) {
if (_depthStyle == 2) {
int bits = (3 - (pt.x % 4)) * 2;
- byte v = *getBasePtr(pt.x >> 2, pt.y);
+ byte v = *(const byte *)getBasePtr(pt.x >> 2, pt.y);
return v >> bits;
} else {
if (pt.x < 0 || pt.y < 0 || pt.x >= this->w || pt.y >= this->h)
return 0;
- return *getBasePtr(pt.x, pt.y) & 0xF;
+ return *(const byte *)getBasePtr(pt.x, pt.y) & 0xF;
}
}
int DepthSurface::getDepthHighBit(const Common::Point &pt) {
if (_depthStyle == 2) {
int bits = (3 - (pt.x % 4)) * 2;
- byte v = *getBasePtr(pt.x >> 2, pt.y);
+ byte v = *(const byte *)getBasePtr(pt.x >> 2, pt.y);
return (v >> bits) & 2;
} else {
if (pt.x < 0 || pt.y < 0 || pt.x >= this->w || pt.y >= this->h)
return 0;
- return *getBasePtr(pt.x, pt.y) & 0x80;
+ return *(const byte *)getBasePtr(pt.x, pt.y) & 0x80;
}
}
diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h
index 8930737b0a..e92770900d 100644
--- a/engines/mads/msurface.h
+++ b/engines/mads/msurface.h
@@ -25,7 +25,7 @@
#include "common/scummsys.h"
#include "common/rect.h"
-#include "graphics/surface.h"
+#include "graphics/managed_surface.h"
#include "mads/palette.h"
namespace MADS {
@@ -50,10 +50,14 @@ struct SpriteInfo {
/*
* MADS graphics surface
*/
-class MSurface : public Graphics::Surface {
+class MSurface : virtual public Graphics::ManagedSurface {
+private:
+ /**
+ * Helper method for calculating new dimensions when scaling a sprite
+ */
+ int scaleValue(int value, int scale, int err);
protected:
static MADSEngine *_vm;
- bool _freeFlag;
public:
/**
* Sets the engine reference used all surfaces
@@ -61,11 +65,6 @@ public:
static void setVm(MADSEngine *vm) { _vm = vm; }
/**
- * Helper method for calculating new dimensions when scaling a sprite
- */
- static int scaleValue(int value, int scale, int err);
-
- /**
* Base method for descendents to load their contents
*/
virtual void load(const Common::String &resName) {}
@@ -73,126 +72,50 @@ public:
/**
* Basic constructor
*/
- MSurface();
+ MSurface() : Graphics::ManagedSurface() {}
/**
* Constructor for a surface with fixed dimensions
*/
- MSurface(int width, int height);
+ MSurface(int width, int height) : Graphics::ManagedSurface(width, height) {}
/**
* Destructor
*/
- virtual ~MSurface();
-
- /**
- * Reinitializes a surface to have a given set of dimensions
- */
- void setSize(int width, int height);
-
- /**
- * Sets the pixels the surface is associated with
- * @remarks The surface will not free the data block
- */
- void setPixels(byte *pData, int horizSize, int vertSize);
-
- /**
- * Draws an arbitrary line on the screen using a specified color
- * @param startPos Starting position
- * @param endPos Ending position
- * @param color Color to use
- */
- void line(const Common::Point &startPos, const Common::Point &endPos, byte color);
-
- /**
- * Draws a sprite
- * @param pt Position to draw sprite at
- * @param info General sprite details
- * @param clipRect Clipping rectangle to constrain sprite drawing within
- */
- void drawSprite(const Common::Point &pt, SpriteInfo &info, const Common::Rect &clipRect);
-
- /**
- * Returns the width of the surface
- */
- int getWidth() const { return w; }
-
- /**
- * Returns the height of the surface
- */
- int getHeight() const { return h; }
+ virtual ~MSurface() {}
/**
- * Returns the size of the surface as a Rect
+ * Return a rect containing the bounds of the surface
*/
- Common::Rect getBounds() const {
- return Common::Rect(0, 0, w, h);
- }
+ Common::Rect getBounds() { return Common::Rect(0, 0, this->w, this->h); }
/**
- * Returns a pointer to the surface data
+ * Return the pixels for the surface
*/
- byte *getData() { return (byte *)Graphics::Surface::getPixels(); }
+ inline byte *getPixels() { return (byte *)Graphics::ManagedSurface::getPixels(); }
/**
- * Returns a pointer to a given position within the surface
+ * Return the pixels for the surface
*/
- byte *getBasePtr(int x, int y) { return (byte *)Graphics::Surface::getBasePtr(x, y); }
+ inline const void *getPixels() const { return (const byte *)Graphics::ManagedSurface::getPixels(); }
/**
- * Returns a pointer to a given position within the surface
- */
- const byte *getBasePtr(int x, int y) const { return (const byte *)Graphics::Surface::getBasePtr(x, y); }
-
- /**
- * Clears the surface
- */
- void empty();
-
- /**
- * Copys a sub-section of another surface into the current one.
- * @param src Source surface
- * @param srcBounds Area of source surface to copy
- * @param destPos Destination position to draw in current surface
- * @param transparentColor Transparency palette index
- */
- void copyFrom(MSurface *src, const Common::Rect &srcBounds, const Common::Point &destPos,
- int transparentColor = -1);
-
- /**
- * Copys a sub-section of another surface into the current one.
- * @param src Source surface
- * @param destPos Destination position to draw in current surface
- * @param depth Depth of sprite
- * @param depthSurface Depth surface to use with sprite depth
- * @param scale Scale for image
- * @param flipped Flag for whether image is to be flipped
- * @param transparentColor Transparency palette index
- */
- void copyFrom(MSurface *src, const Common::Point &destPos, int depth, DepthSurface *depthSurface,
- int scale, bool flipped, int transparentColor = -1);
-
- /**
- * Copies the surface to a given destination surface
+ * Return a pointer to a given position on the surface
*/
- void copyTo(MSurface *dest, int transparentColor = -1) {
- dest->copyFrom(this, Common::Rect(w, h), Common::Point(), transparentColor);
- }
+ byte *getBasePtr(int x, int y) { return (byte *)Graphics::ManagedSurface::getBasePtr(x, y); }
/**
- * Copies the surface to a given destination surface
+ * Return a pointer to a given position on the surface
*/
- void copyTo(MSurface *dest, const Common::Point &pt, int transparentColor = -1) {
- dest->copyFrom(this, Common::Rect(w, h), pt, transparentColor);
- }
+ inline const byte *getBasePtr(int x, int y) const { return (const byte *)Graphics::ManagedSurface::getBasePtr(x, y); }
/**
- * Copies the surface to a given destination surface
+ * Draws a sprite
+ * @param pt Position to draw sprite at
+ * @param info General sprite details
+ * @param clipRect Clipping rectangle to constrain sprite drawing within
*/
- void copyTo(MSurface *dest, const Common::Rect &srcBounds, const Common::Point &destPos,
- int transparentColor = -1) {
- dest->copyFrom(this, srcBounds, destPos, transparentColor);
- }
+ void drawSprite(const Common::Point &pt, SpriteInfo &info, const Common::Rect &clipRect);
/**
* Scroll the screen horizontally by a given amount
@@ -227,6 +150,19 @@ public:
*/
void copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
const Common::Point &destPos, const Common::Rect &srcRect);
+
+ /**
+ * Copys a sub-section of another surface into the current one.
+ * @param src Source surface
+ * @param destPos Destination position to draw in current surface
+ * @param depth Depth of sprite
+ * @param depthSurface Depth surface to use with sprite depth
+ * @param scale Scale for image
+ * @param flipped Flag for whether image is to be flipped
+ * @param transparentColor Transparency palette index
+ */
+ void copyFrom(MSurface &src, const Common::Point &destPos, int depth, DepthSurface *depthSurface,
+ int scale, bool flipped, int transparentColor = -1);
};
class DepthSurface : public MSurface {
@@ -239,7 +175,7 @@ public:
/**
* Constructor
*/
- DepthSurface() : _depthStyle(0) {}
+ DepthSurface() : MSurface(), _depthStyle(0) {}
/**
* Returns the depth at a given position
diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp
index 58e60fe323..2af80f517e 100644
--- a/engines/mads/nebular/dialogs_nebular.cpp
+++ b/engines/mads/nebular/dialogs_nebular.cpp
@@ -438,11 +438,10 @@ void CopyProtectionDialog::show() {
Common::KeyState curKey;
const Common::Rect inputArea(110, 165, 210, 175);
MSurface *origInput = new MSurface(inputArea.width(), inputArea.height());
- _vm->_screen.frameRect(inputArea, TEXTDIALOG_BLACK);
- _vm->_screen.copyTo(origInput, inputArea, Common::Point(0, 0));
- _font->setColors(TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE);
- _vm->_screen.copyRectToScreen(inputArea);
- _vm->_screen.updateScreen();
+ _vm->_screen->frameRect(inputArea, TEXTDIALOG_BLACK);
+ origInput->blitFrom(*_vm->_screen, inputArea, Common::Point(0, 0));
+ _font->setColors(TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE);
+ _vm->_screen->update();
bool firstTime = true;
@@ -470,11 +469,10 @@ void CopyProtectionDialog::show() {
_textInput = _hogEntry._word[0];
}
- _vm->_screen.copyFrom(origInput, Common::Rect(0, 0, inputArea.width(), inputArea.height()), Common::Point(inputArea.left, inputArea.top));
- _font->writeString(&_vm->_screen, _textInput,
+ _vm->_screen->blitFrom(*origInput, Common::Point(inputArea.left, inputArea.top));
+ _font->writeString(_vm->_screen, _textInput,
Common::Point(inputArea.left + 2, inputArea.top + 1), 1);
- _vm->_screen.copyRectToScreen(inputArea);
- _vm->_screen.updateScreen();
+ _vm->_screen->update();
}
origInput->free();
@@ -537,7 +535,7 @@ void PictureDialog::save() {
// Save the entire screen
_savedSurface = new MSurface(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT);
- _vm->_screen.copyTo(_savedSurface);
+ _savedSurface->blitFrom(*_vm->_screen);
// Save palette information
Common::copy(&palette._mainPalette[0], &palette._mainPalette[PALETTE_SIZE], &_palette[0]);
@@ -568,7 +566,7 @@ void PictureDialog::save() {
// Remap the greyed out screen to use the small greyscale range
// at the top end of the palette
- _vm->_screen.translate(map);
+ _vm->_screen->translate(map);
// Load the inventory picture
Common::String setName = Common::String::format("*OB%.3d.SS", _objectId);
@@ -578,13 +576,12 @@ void PictureDialog::save() {
// Get the inventory frame, and adjust the dialog position to allow for it
MSprite *frame = asset->getFrame(0);
_position.y = frame->h + 12;
- if ((_position.y + _height) > _vm->_screen.getHeight())
- _position.y -= (_position.y + _height) - _vm->_screen.getHeight();
+ if ((_position.y + _height) > _vm->_screen->h)
+ _position.y -= (_position.y + _height) - _vm->_screen->h;
// Draw the inventory picture
- frame->copyTo(&_vm->_screen, Common::Point(160 - frame->w / 2, 6),
+ _vm->_screen->transBlitFrom(*frame, Common::Point(160 - frame->w / 2, 6),
frame->getTransparencyIndex());
- _vm->_screen.copyRectToScreen(_vm->_screen.getBounds());
// Adjust the dialog colors to use
TEXTDIALOG_CONTENT1 -= 10;
@@ -598,13 +595,11 @@ void PictureDialog::save() {
void PictureDialog::restore() {
if (_savedSurface) {
- _savedSurface->copyTo(&_vm->_screen);
+ _vm->_screen->blitFrom(*_savedSurface);
_savedSurface->free();
delete _savedSurface;
_savedSurface = nullptr;
- _vm->_screen.copyRectToScreen(_vm->_screen.getBounds());
-
// Restore palette information
Palette &palette = *_vm->_palette;
Common::copy(&_palette[0], &_palette[PALETTE_SIZE], &palette._mainPalette[0]);
@@ -691,7 +686,6 @@ void GameDialog::display() {
}
GameDialog::~GameDialog() {
- _vm->_screen.resetClipBounds();
_vm->_game->_scene._currentSceneId = RETURNING_FROM_DIALOG;
}
diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp
index 0520294b29..cd81efe0f0 100644
--- a/engines/mads/nebular/menu_nebular.cpp
+++ b/engines/mads/nebular/menu_nebular.cpp
@@ -384,8 +384,8 @@ void AdvertView::show() {
// Load the advert background onto the screen
SceneInfo *sceneInfo = SceneInfo::init(_vm);
sceneInfo->load(screenId, 0, Common::String(), 0, _vm->_game->_scene._depthSurface,
- _vm->_screen);
- _vm->_screen.copyRectToScreen(_vm->_screen.getBounds());
+ *_vm->_screen);
+ _vm->_screen->markAllDirty();
_vm->_palette->setFullPalette(_vm->_palette->_mainPalette);
delete sceneInfo;
diff --git a/engines/mads/nebular/nebular_scenes.cpp b/engines/mads/nebular/nebular_scenes.cpp
index da419a70a2..40228b4b7d 100644
--- a/engines/mads/nebular/nebular_scenes.cpp
+++ b/engines/mads/nebular/nebular_scenes.cpp
@@ -323,8 +323,8 @@ void SceneInfoNebular::loadCodes(MSurface &depthSurface, int variant) {
}
void SceneInfoNebular::loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream) {
- byte *destP = depthSurface.getData();
- byte *endP = depthSurface.getBasePtr(0, depthSurface.h);
+ byte *destP = (byte *)depthSurface.getPixels();
+ byte *endP = (byte *)depthSurface.getBasePtr(0, depthSurface.h);
byte runLength = stream->readByte();
while (destP < endP && runLength > 0) {
diff --git a/engines/mads/nebular/nebular_scenes3.cpp b/engines/mads/nebular/nebular_scenes3.cpp
index 0fb13a706c..7323ee893d 100644
--- a/engines/mads/nebular/nebular_scenes3.cpp
+++ b/engines/mads/nebular/nebular_scenes3.cpp
@@ -2818,7 +2818,7 @@ void Scene318::step() {
if (_internCounter >= 3600) {
_vm->_sound->command(59);
- _vm->_screen._shakeCountdown = 20;
+ _vm->_screen->_shakeCountdown = 20;
_internWalkingFl = true;
}
}
@@ -3288,22 +3288,22 @@ void Scene319::step() {
if (_animMode == 2) {
if (_animFrame == 13)
- _vm->_screen._shakeCountdown = 40;
+ _vm->_screen->_shakeCountdown = 40;
if (_animFrame == 16)
- _vm->_screen._shakeCountdown = 1;
+ _vm->_screen->_shakeCountdown = 1;
}
if (_animMode == 3) {
if (_animFrame == 11)
- _vm->_screen._shakeCountdown = 60;
+ _vm->_screen->_shakeCountdown = 60;
if (_animFrame == 18)
- _vm->_screen._shakeCountdown = 1;
+ _vm->_screen->_shakeCountdown = 1;
}
if ((_animMode == 4) && (_animFrame == 16))
- _vm->_screen._shakeCountdown = 80;
+ _vm->_screen->_shakeCountdown = 80;
if ((nextFrame >= 0) && (nextFrame != _scene->_animation[0]->getCurrentFrame())) {
_scene->_animation[0]->setCurrentFrame(nextFrame);
@@ -3326,7 +3326,7 @@ void Scene319::step() {
_animFrame = _scene->_animation[0]->getCurrentFrame();
_slacheTalkingFl = true;
- _vm->_screen._shakeCountdown = 1;
+ _vm->_screen->_shakeCountdown = 1;
for (int i = 0; i <= 1; i++) {
int oldIdx = _globals._sequenceIndexes[i];
@@ -3350,7 +3350,7 @@ void Scene319::step() {
_vm->_palette->setColorValues(0, 0, 0);
_vm->_palette->fadeOut(_vm->_palette->_mainPalette, nullptr, 18, 228,
248, 0, 1, 16);
- _vm->_screen._shakeCountdown = 1;
+ _vm->_screen->_shakeCountdown = 1;
_scene->_reloadSceneFlag = true;
break;
@@ -3731,7 +3731,7 @@ void Scene320::step() {
case 417:
case 457:
- _vm->_screen._shakeCountdown = 40;
+ _vm->_screen->_shakeCountdown = 40;
_vm->_sound->command(59);
break;
diff --git a/engines/mads/phantom/phantom_scenes.cpp b/engines/mads/phantom/phantom_scenes.cpp
index f7a7153fbe..7ef627ceeb 100644
--- a/engines/mads/phantom/phantom_scenes.cpp
+++ b/engines/mads/phantom/phantom_scenes.cpp
@@ -191,7 +191,7 @@ void SceneInfoPhantom::loadCodes(MSurface &depthSurface, int variant) {
}
void SceneInfoPhantom::loadCodes(MSurface &depthSurface, Common::SeekableReadStream *stream) {
- byte *destP = depthSurface.getData();
+ byte *destP = (byte *)depthSurface.getPixels();
byte *walkMap = new byte[stream->size()];
stream->read(walkMap, stream->size());
diff --git a/engines/mads/rails.cpp b/engines/mads/rails.cpp
index ee0ca98cd3..46d9e0ebd3 100644
--- a/engines/mads/rails.cpp
+++ b/engines/mads/rails.cpp
@@ -149,7 +149,7 @@ int Rails::scanPath(const Common::Point &srcPos, const Common::Point &destPos) {
++xDiff;
++yDiff;
- const byte *srcP = _depthSurface->getBasePtr(srcPos.x, srcPos.y);
+ const byte *srcP = (const byte *)_depthSurface->getBasePtr(srcPos.x, srcPos.y);
int index = xAmount;
// Outer loop
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index 83ab1151a9..66f56f9407 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -89,8 +89,7 @@ Scene::~Scene() {
}
void Scene::restrictScene() {
- _sceneSurface.init(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT, MADS_SCREEN_WIDTH,
- _vm->_screen.getPixels(), Graphics::PixelFormat::createFormatCLUT8());
+ _sceneSurface.create(*_vm->_screen, Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT));
}
void Scene::clearVocab() {
@@ -517,7 +516,7 @@ void Scene::drawElements(ScreenTransition transitionType, bool surfaceFlag) {
if (_posAdjust != Common::Point(0, 0))
warning("Adjust used %d %d", _posAdjust.x, _posAdjust.y);
// Copy background for the dirty areas to the screen
- _dirtyAreas.copy(&_backgroundSurface, &_vm->_screen, _posAdjust);
+ _dirtyAreas.copy(&_backgroundSurface, _vm->_screen, _posAdjust);
// Handle dirty areas for foreground objects
_spriteSlots.setDirtyAreas();
@@ -528,11 +527,11 @@ void Scene::drawElements(ScreenTransition transitionType, bool surfaceFlag) {
_spriteSlots.drawSprites(&_sceneSurface);
// Draw text elements onto the view
- _textDisplay.draw(&_vm->_screen);
+ _textDisplay.draw(_vm->_screen);
if (transitionType) {
// Fading in the screen
- _vm->_screen.transition(transitionType, surfaceFlag);
+ _vm->_screen->transition(transitionType, surfaceFlag);
_vm->_sound->startQueuedCommands();
} else {
// Copy dirty areas to the screen
diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp
index 7b0e64c1fe..5323178ec7 100644
--- a/engines/mads/scene_data.cpp
+++ b/engines/mads/scene_data.cpp
@@ -242,13 +242,13 @@ void SceneInfo::load(int sceneId, int variant, const Common::String &resName,
int height = _height;
if (!bgSurface.getPixels() || (bgSurface.w != width) || (bgSurface.h != height)) {
- bgSurface.setSize(width, height);
+ bgSurface.create(width, height);
}
if (_depthStyle == 2)
width >>= 2;
if (!depthSurface.getPixels()) {
- depthSurface.setSize(width, height);
+ depthSurface.create(width, height);
}
loadCodes(depthSurface, variant);
@@ -288,7 +288,7 @@ void SceneInfo::load(int sceneId, int variant, const Common::String &resName,
assert(asset && _depthStyle != 2);
MSprite *spr = asset->getFrame(si._frameNumber);
- bgSurface.copyFrom(spr, si._position, si._depth, &depthSurface,
+ bgSurface.copyFrom(*spr, si._position, si._depth, &depthSurface,
si._scale, false, spr->getTransparencyIndex());
}
@@ -455,7 +455,7 @@ void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName,
newHeight = tileCount * tileHeight;
if (bgSurface.w != newWidth || bgSurface.h != newHeight)
- bgSurface.setSize(newWidth, newHeight);
+ bgSurface.create(newWidth, newHeight);
// --------------------------------------------------------------------------------
@@ -477,7 +477,7 @@ void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName,
//debugCN(kDebugGraphics, "Tile: %i, compressed size: %i\n", i, compressedTileDataSize);
- newTile->empty();
+ newTile->clear();
byte *compressedTileData = new byte[compressedTileDataSize];
@@ -503,7 +503,8 @@ void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName,
TileSetIterator tile = tileSet.begin();
for (int i = 0; i < tileIndex; i++)
++tile;
- ((*tile).get())->copyTo(&bgSurface, Common::Point(x * tileWidth, y * tileHeight));
+
+ bgSurface.blitFrom(*(*tile).get(), Common::Point(x * tileWidth, y * tileHeight));
((*tile).get())->free();
}
}
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
index 90fbbe7e2a..05f9de61e2 100644
--- a/engines/mads/screen.cpp
+++ b/engines/mads/screen.cpp
@@ -69,7 +69,6 @@ void DirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) {
_active = true;
}
-
void DirtyArea::setSpriteSlot(const SpriteSlot *spriteSlot) {
int width, height;
Scene &scene = _vm->_game->_scene;
@@ -215,12 +214,13 @@ void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common:
Common::Point destPos(srcBounds.left, srcBounds.top);
if ((*this)[i]._active && bounds.isValidRect()) {
- srcSurface->copyTo(destSurface, bounds, destPos);
+ destSurface->blitFrom(*srcSurface, bounds, destPos);
}
}
}
void DirtyAreas::copyToScreen() {
+/*
for (uint i = 0; i < size(); ++i) {
const Common::Rect &bounds = (*this)[i]._bounds;
@@ -229,9 +229,10 @@ void DirtyAreas::copyToScreen() {
continue;
if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) {
- _vm->_screen.copyRectToScreen(bounds);
+ _vm->_screen->copyRectToScreen(bounds);
}
}
+ */
}
void DirtyAreas::reset() {
@@ -554,38 +555,17 @@ void ScreenObjects::synchronize(Common::Serializer &s) {
/*------------------------------------------------------------------------*/
-ScreenSurface::ScreenSurface() {
+Screen::Screen(): Graphics::Screen(), MSurface() {
+ // Create the screen surface separately on another surface, since the screen
+ // surface will be subject to change as the clipping area is altered
+ _rawSurface.create(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT);
+ resetClipBounds();
+
_shakeCountdown = -1;
_random = 0x4D2;
- _surfacePixels = nullptr;
-}
-
-void ScreenSurface::init() {
- // Set the size for the screen
- setSize(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT);
-
- // Store a copy of the raw pixels pointer for the screen, since the surface
- // itself may be later changed to only a subset of the screen
- _surfacePixels = (byte *)getPixels();
- _freeFlag = false;
-}
-
-ScreenSurface::~ScreenSurface() {
- ::free(_surfacePixels);
}
-void ScreenSurface::copyRectToScreen(const Common::Rect &bounds) {
- const byte *buf = getBasePtr(bounds.left, bounds.top);
-
- Common::Rect destBounds = bounds;
- destBounds.translate(_clipBounds.left, _clipBounds.top);
-
- if (bounds.width() != 0 && bounds.height() != 0)
- g_system->copyRectToScreen(buf, this->pitch, destBounds.left, destBounds.top,
- destBounds.width(), destBounds.height());
-}
-
-void ScreenSurface::updateScreen() {
+void Screen::update() {
if (_shakeCountdown >= 0) {
_random = _random * 5 + 1;
int offset = (_random >> 8) & 3;
@@ -596,27 +576,42 @@ void ScreenSurface::updateScreen() {
// offset width shown at the very right. The offset changes to give
// an effect of shaking the screen
offset *= 4;
- const byte *buf = getBasePtr(offset, 0);
- g_system->copyRectToScreen(buf, this->pitch, 0, 0,
- this->pitch - offset, this->h);
+ const byte *buf = (const byte *)getBasePtr(offset, 0);
+ g_system->copyRectToScreen(buf, this->pitch, 0, 0, this->pitch - offset, this->h);
if (offset > 0)
- g_system->copyRectToScreen(this->pixels, this->pitch,
+ g_system->copyRectToScreen(getPixels(), this->pitch,
this->pitch - offset, 0, offset, this->h);
+ return;
}
- g_system->updateScreen();
+ // Reset any clip bounds if active whilst the screen is updated
+ Common::Rect clipBounds = getClipBounds();
+ resetClipBounds();
+
+ // Update the screen
+ Graphics::Screen::update();
+
+ // Revert back to whatever clipping is active
+ setClipBounds(clipBounds);
}
-void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag) {
+void Screen::transition(ScreenTransition transitionType, bool surfaceFlag) {
Palette &pal = *_vm->_palette;
Scene &scene = _vm->_game->_scene;
byte palData[PALETTE_SIZE];
+ // The original loads the new scene to the screen surface for some of the
+ // transition types like fade out/in, so we need to clear the dirty rects so
+ // it doesn't prematurely get blitted to the physical screen before fade out
+ Common::Rect clipBounds = getClipBounds();
+ clearDirtyRects();
+
switch (transitionType) {
case kTransitionFadeIn:
- case kTransitionFadeOutIn:
+ case kTransitionFadeOutIn: {
Common::fill(&pal._colorValues[0], &pal._colorValues[3], 0);
Common::fill(&pal._colorFlags[0], &pal._colorFlags[3], false);
+ resetClipBounds();
if (transitionType == kTransitionFadeOutIn) {
// Fade out
@@ -628,9 +623,11 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag
Common::fill(&palData[0], &palData[PALETTE_SIZE], 0);
pal.setFullPalette(palData);
- copyRectToScreen(getBounds());
+ markAllDirty();
+ update();
pal.fadeIn(palData, pal._mainPalette, 0, 256, 0, 1, 1, 16);
break;
+ }
case kTransitionBoxInBottomLeft:
case kTransitionBoxInBottomRight:
@@ -666,19 +663,13 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag
// Quick transitions
break;
}
-}
-void ScreenSurface::setClipBounds(const Common::Rect &r) {
- _clipBounds = r;
- setPixels(_surfacePixels + pitch * r.top + r.left, r.width(), r.height());
- this->pitch = MADS_SCREEN_WIDTH;
+ // Reset clipping
+ markAllDirty();
+ setClipBounds(clipBounds);
}
-void ScreenSurface::resetClipBounds() {
- setClipBounds(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
-}
-
-void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entrySide,
+void Screen::panTransition(MSurface &newScreen, byte *palData, int entrySide,
const Common::Point &srcPos, const Common::Point &destPos,
ThroughBlack throughBlack, bool setPalette, int numTicks) {
EventsManager &events = *_vm->_events;
@@ -735,8 +726,6 @@ void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entryS
srcPos.x + xAt + 1, srcPos.y + size.y));
}
- copyRectToScreen(Common::Rect(xAt, destPos.y, xAt + 1, destPos.y + size.y));
-
// Slight delay
events.pollEvents();
g_system->delayMillis(1);
@@ -747,16 +736,18 @@ void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entryS
}
if (throughBlack == THROUGH_BLACK2) {
+ /*
Common::Rect r(srcPos.x, srcPos.y, srcPos.x + size.x, srcPos.y + size.y);
copyRectToSurface(newScreen, destPos.x, destPos.y, r);
copyRectToScreen(r);
+ */
}
}
/**
* Translates the current screen from the old palette to the new palette
*/
-void ScreenSurface::swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap) {
+void Screen::swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap) {
Palette &palette = *_vm->_palette;
byte oldPalette[PALETTE_SIZE];
byte oldMap[PALETTE_COUNT];
@@ -775,7 +766,7 @@ void ScreenSurface::swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteM
destP += 2 * RGB_SIZE;
}
- Common::Rect oldClip = _clipBounds;
+ Common::Rect oldClip = getClipBounds();
resetClipBounds();
copyRectTranslate(*this, oldMap, Common::Point(0, 0),
@@ -790,7 +781,7 @@ void ScreenSurface::swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteM
* Palettes consist of 128 RGB entries for the foreground and background
* respectively, with the two interleaved together. So the start
*/
-void ScreenSurface::swapPalette(const byte *palData, byte swapTable[PALETTE_COUNT],
+void Screen::swapPalette(const byte *palData, byte swapTable[PALETTE_COUNT],
bool foreground) {
int start = foreground ? 1 : 0;
const byte *dynamicList = &palData[start * RGB_SIZE];
@@ -815,5 +806,12 @@ void ScreenSurface::swapPalette(const byte *palData, byte swapTable[PALETTE_COUN
}
}
+void Screen::setClipBounds(const Common::Rect &r) {
+ create(_rawSurface, r);
+}
+
+void Screen::resetClipBounds() {
+ setClipBounds(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+}
} // End of namespace MADS
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
index d910e88633..626080580e 100644
--- a/engines/mads/screen.h
+++ b/engines/mads/screen.h
@@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "common/array.h"
+#include "graphics/screen.h"
#include "mads/msurface.h"
#include "mads/action.h"
@@ -207,11 +208,10 @@ public:
void synchronize(Common::Serializer &s);
};
-class ScreenSurface : public MSurface {
+class Screen : virtual public Graphics::Screen, virtual public MSurface {
private:
uint16 _random;
- byte *_surfacePixels;
- Common::Rect _clipBounds;
+ MSurface _rawSurface;
void panTransition(MSurface &newScreen, byte *palData, int entrySide,
const Common::Point &srcPos, const Common::Point &destPos,
@@ -226,36 +226,40 @@ public:
/**
* Constructor
*/
- ScreenSurface();
+ Screen();
/**
* Destructor
*/
- ~ScreenSurface();
+ virtual ~Screen() {}
/**
- * Initialize the surface
+ * Updates the physical screen with contents of the internal surface
*/
- void init();
+ virtual void update();
/**
- * Copys an area of the screen surface to the ScmmVM physical screen buffer
- * @param bounds Area of screen surface to copy
+ * Transition to a new screen with a given effect
*/
- void copyRectToScreen(const Common::Rect &bounds);
+ void transition(ScreenTransition transitionType, bool surfaceFlag);
/**
- * Updates the screen with the contents of the surface
+ * Set the screen drawing area to a sub-section of the real screen
*/
- void updateScreen();
-
- void transition(ScreenTransition transitionType, bool surfaceFlag);
-
void setClipBounds(const Common::Rect &r);
+ /**
+ * Reset back to drawing on the entirety of the screen
+ */
void resetClipBounds();
- const Common::Rect &getClipBounds() { return _clipBounds; }
+ /**
+ * Return the current drawing/clip area
+ */
+ const Common::Rect getClipBounds() const {
+ const Common::Point pt = getOffsetFromOwner();
+ return Common::Rect(pt.x, pt.y, pt.x + this->w, pt.y + this->h);
+ }
};
} // End of namespace MADS
diff --git a/engines/mads/sequence.cpp b/engines/mads/sequence.cpp
index 50b37de7ea..2afe089d4a 100644
--- a/engines/mads/sequence.cpp
+++ b/engines/mads/sequence.cpp
@@ -237,8 +237,8 @@ bool SequenceList::loadSprites(int seqIndex) {
if ((seqEntry._flags != 0) || (seqEntry._dynamicHotspotIndex >= 0)) {
SpriteAsset &spriteSet = *scene._sprites[seqEntry._spritesIndex];
MSprite *frame = spriteSet.getFrame(seqEntry._frameIndex - 1);
- int width = frame->getWidth() * seqEntry._scale / 200;
- int height = frame->getHeight() * seqEntry._scale / 100;
+ int width = frame->w * seqEntry._scale / 200;
+ int height = frame->h * seqEntry._scale / 100;
Common::Point pt = spriteSlot._position;
// Handle sprite movement, if present
diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp
index 0a1c0b710d..fc8ddf22d2 100644
--- a/engines/mads/sprites.cpp
+++ b/engines/mads/sprites.cpp
@@ -59,10 +59,10 @@ MSprite::MSprite() : MSurface() {
}
MSprite::MSprite(Common::SeekableReadStream *source, const Common::Array<RGB6> &palette,
- const Common::Rect &bounds)
- : MSurface(bounds.width(), bounds.height()),
- _offset(Common::Point(bounds.left, bounds.top)), _transparencyIndex(TRANSPARENT_COLOR_INDEX) {
+ const Common::Rect &bounds): MSurface(), _transparencyIndex(TRANSPARENT_COLOR_INDEX),
+ _offset(Common::Point(bounds.left, bounds.top)) {
// Load the sprite data
+ create(bounds.width(), bounds.height());
loadSprite(source, palette);
}
@@ -74,8 +74,8 @@ void MSprite::loadSprite(Common::SeekableReadStream *source,
byte *outp, *lineStart;
bool newLine = false;
- outp = getData();
- lineStart = getData();
+ outp = getPixels();
+ lineStart = getPixels();
int spriteSize = this->w * this->h;
byte transIndex = getTransparencyIndex();
Common::fill(outp, outp + spriteSize, transIndex);
@@ -84,7 +84,7 @@ void MSprite::loadSprite(Common::SeekableReadStream *source,
byte cmd1, cmd2, count, pixel;
if (newLine) {
- outp = lineStart + getWidth();
+ outp = lineStart + this->w;
lineStart = outp;
newLine = false;
}
@@ -126,7 +126,7 @@ void MSprite::loadSprite(Common::SeekableReadStream *source,
// Do a final iteration over the sprite to convert it's pixels to
// the final positions in the main palette
spriteSize = this->w * this->h;
- for (outp = getData(); spriteSize > 0; --spriteSize, ++outp) {
+ for (outp = getPixels(); spriteSize > 0; --spriteSize, ++outp) {
if (*outp != transIndex)
*outp = palette[*outp]._palIndex;
}
@@ -257,12 +257,12 @@ void SpriteSlots::drawBackground() {
}
if (spriteSlot._depth <= 1) {
- frame->copyTo(&scene._backgroundSurface, pt, frame->getTransparencyIndex());
+ scene._backgroundSurface.transBlitFrom(*frame, pt, frame->getTransparencyIndex());
} else if (scene._depthStyle == 0) {
- scene._backgroundSurface.copyFrom(frame, pt, spriteSlot._depth, &scene._depthSurface,
+ scene._backgroundSurface.copyFrom(*frame, pt, spriteSlot._depth, &scene._depthSurface,
-1, false, frame->getTransparencyIndex());
} else {
- frame->copyTo(&scene._backgroundSurface, pt, frame->getTransparencyIndex());
+ scene._backgroundSurface.transBlitFrom(*frame, pt, frame->getTransparencyIndex());
}
}
}
@@ -319,7 +319,7 @@ void SpriteSlots::drawSprites(MSurface *s) {
if ((slot._scale < 100) && (slot._scale != -1)) {
// Scaled drawing
- s->copyFrom(sprite, slot._position, slot._depth, &scene._depthSurface,
+ s->copyFrom(*sprite, slot._position, slot._depth, &scene._depthSurface,
slot._scale, flipped, sprite->getTransparencyIndex());
} else {
int xp, yp;
@@ -334,7 +334,7 @@ void SpriteSlots::drawSprites(MSurface *s) {
if (slot._depth > 1) {
// Draw the frame with depth processing
- s->copyFrom(sprite, Common::Point(xp, yp), slot._depth, &scene._depthSurface,
+ s->copyFrom(*sprite, Common::Point(xp, yp), slot._depth, &scene._depthSurface,
-1, flipped, sprite->getTransparencyIndex());
} else {
MSurface *spr = sprite;
@@ -344,7 +344,7 @@ void SpriteSlots::drawSprites(MSurface *s) {
}
// No depth, so simply draw the image
- spr->copyTo(s, Common::Point(xp, yp), sprite->getTransparencyIndex());
+ s->transBlitFrom(*spr, Common::Point(xp, yp), sprite->getTransparencyIndex());
// Free sprite if it was a flipped one
if (flipped) {
diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp
index e4b09ff54c..8f7cb0a24b 100644
--- a/engines/mads/user_interface.cpp
+++ b/engines/mads/user_interface.cpp
@@ -112,7 +112,7 @@ void UISlots::draw(bool updateFlag, bool delFlag) {
Common::Point(dirtyArea._bounds.left, dirtyArea._bounds.top));
} else {
// Copy area
- userInterface._surface.copyTo(&userInterface, dirtyArea._bounds,
+ userInterface.blitFrom(userInterface._surface, dirtyArea._bounds,
Common::Point(dirtyArea._bounds.left, dirtyArea._bounds.top));
}
}
@@ -155,7 +155,7 @@ void UISlots::draw(bool updateFlag, bool delFlag) {
if (slot._segmentId == IMG_SPINNING_OBJECT) {
MSprite *sprite = asset->getFrame(frameNumber - 1);
- sprite->copyTo(&userInterface, slot._position,
+ userInterface.transBlitFrom(*sprite, slot._position,
sprite->getTransparencyIndex());
} else {
MSprite *sprite = asset->getFrame(frameNumber - 1);
@@ -185,7 +185,7 @@ void UISlots::draw(bool updateFlag, bool delFlag) {
// Flag area of screen as needing update
Common::Rect r = dirtyArea._bounds;
r.translate(0, scene._interfaceY);
- _vm->_screen.copyRectToScreen(r);
+ //_vm->_screen->copyRectToScreen(r);
}
}
}
@@ -339,10 +339,10 @@ UserInterface::UserInterface(MADSEngine *vm) : _vm(vm), _dirtyAreas(vm),
Common::fill(&_categoryIndexes[0], &_categoryIndexes[7], 0);
// Map the user interface to the bottom of the game's screen surface
- byte *pData = _vm->_screen.getBasePtr(0, MADS_SCENE_HEIGHT);
- setPixels(pData, MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT);
+ create(*_vm->_screen, Common::Rect(0, MADS_SCENE_HEIGHT, MADS_SCREEN_WIDTH,
+ MADS_SCREEN_HEIGHT));
- _surface.setSize(MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT);
+ _surface.create(MADS_SCREEN_WIDTH, MADS_INTERFACE_HEIGHT);
}
void UserInterface::load(const Common::String &resName) {
@@ -367,7 +367,7 @@ void UserInterface::load(const Common::String &resName) {
// Read in the surface data
Common::SeekableReadStream *pixelsStream = madsPack.getItemStream(1);
- pixelsStream->read(_surface.getData(), MADS_SCREEN_WIDTH * MADS_INTERFACE_HEIGHT);
+ pixelsStream->read(_surface.getPixels(), MADS_SCREEN_WIDTH * MADS_INTERFACE_HEIGHT);
delete pixelsStream;
}
@@ -390,7 +390,7 @@ void UserInterface::setup(InputMode inputMode) {
resName += ".INT";
load(resName);
- _surface.copyTo(this);
+ blitFrom(_surface);
}
_vm->_game->_screenObjects._inputMode = inputMode;
@@ -455,9 +455,9 @@ void UserInterface::mergeFrom(MSurface *src, const Common::Rect &srcBounds,
// Copy the specified area
- byte *data = src->getData();
- byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left);
- byte *destPtr = (byte *)this->pixels + (destY * getWidth()) + destX;
+ byte *data = src->getPixels();
+ byte *srcPtr = data + (src->w * copyRect.top + copyRect.left);
+ byte *destPtr = (byte *)getPixels() + (destY * this->w) + destX;
for (int rowCtr = 0; rowCtr < copyRect.height(); ++rowCtr) {
// Process each line of the area
@@ -468,8 +468,8 @@ void UserInterface::mergeFrom(MSurface *src, const Common::Rect &srcBounds,
destPtr[xCtr] = srcPtr[xCtr];
}
- srcPtr += src->getWidth();
- destPtr += getWidth();
+ srcPtr += src->w;
+ destPtr += this->w;
}
}
@@ -593,7 +593,7 @@ void UserInterface::scrollbarChanged() {
_uiSlots.add(r);
_uiSlots.draw(false, false);
drawScroller();
- updateRect(r);
+// updateRect(r);
}
void UserInterface::writeVocab(ScrCategory category, int id) {
@@ -1012,7 +1012,7 @@ void UserInterface::selectObject(int invIndex) {
_uiSlots.add(bounds);
_uiSlots.draw(false, false);
drawItemVocabList();
- updateRect(bounds);
+ //updateRect(bounds);
}
}
@@ -1036,7 +1036,7 @@ void UserInterface::updateSelection(ScrCategory category, int newIndex, int *idx
_uiSlots.add(bounds);
_uiSlots.draw(false, false);
drawInventoryList();
- updateRect(bounds);
+ //updateRect(bounds);
_inventoryChanged = false;
if (invList.size() < 2) {
@@ -1052,25 +1052,19 @@ void UserInterface::updateSelection(ScrCategory category, int newIndex, int *idx
if (oldIndex >= 0) {
writeVocab(category, oldIndex);
- if (getBounds(category, oldIndex, bounds))
- updateRect(bounds);
+/* if (getBounds(category, oldIndex, bounds))
+ updateRect(bounds); */
}
if (newIndex >= 0) {
writeVocab(category, newIndex);
- if (getBounds(category, newIndex, bounds))
- updateRect(bounds);
+/* if (getBounds(category, newIndex, bounds))
+ updateRect(bounds); */
}
}
}
-void UserInterface::updateRect(const Common::Rect &bounds) {
- Common::Rect r = bounds;
- r.translate(0, MADS_SCENE_HEIGHT);
- _vm->_screen.copyRectToScreen(r);
-}
-
void UserInterface::scrollerChanged() {
warning("TODO: scrollerChanged");
}
diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h
index 60cc1f736d..9232dc1bb1 100644
--- a/engines/mads/user_interface.h
+++ b/engines/mads/user_interface.h
@@ -190,8 +190,6 @@ private:
* Draw a UI textual element
*/
void writeVocab(ScrCategory category, int id);
-
- void updateRect(const Common::Rect &bounds);
public:
MSurface _surface;
UISlots _uiSlots;