diff options
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; |