diff options
Diffstat (limited to 'engines')
161 files changed, 2970 insertions, 3871 deletions
diff --git a/engines/access/access.cpp b/engines/access/access.cpp index bc9bcb4b08..c12761af4a 100644 --- a/engines/access/access.cpp +++ b/engines/access/access.cpp @@ -436,20 +436,9 @@ void AccessEngine::copyBF1BF2() { } void AccessEngine::copyBF2Vid() { - const byte *srcP = (const byte *)_buffer2.getPixels(); - byte *destP = (byte *)_screen->getBasePtr(_screen->_windowXAdd, - _screen->_windowYAdd + _screen->_screenYOff); - - for (int yp = 0; yp < _screen->_vWindowLinesTall; ++yp) { - Common::copy(srcP, srcP + _screen->_vWindowBytesWide, destP); - srcP += _buffer2.pitch; - destP += _screen->pitch; - } - - // Add dirty rect for affected area - Common::Rect r(_screen->_vWindowBytesWide, _screen->_vWindowLinesTall); - r.moveTo(_screen->_windowXAdd, _screen->_windowYAdd + _screen->_screenYOff); - _screen->addDirtyRect(r); + _screen->blitFrom(_buffer2, + Common::Rect(0, 0, _screen->_vWindowBytesWide, _screen->_vWindowLinesTall), + Common::Point(_screen->_windowXAdd, _screen->_windowYAdd)); } void AccessEngine::playVideo(int videoNum, const Common::Point &pt) { diff --git a/engines/access/asurface.cpp b/engines/access/asurface.cpp index f693e6a3a0..2518ff6ad8 100644 --- a/engines/access/asurface.cpp +++ b/engines/access/asurface.cpp @@ -110,7 +110,7 @@ void ImageEntryList::addToList(ImageEntry &ie) { int ASurface::_clipWidth; int ASurface::_clipHeight; -ASurface::ASurface(): Graphics::Surface() { +ASurface::ASurface(): Graphics::ManagedSurface() { _leftSkip = _rightSkip = 0; _topSkip = _bottomSkip = 0; _lastBoundsX = _lastBoundsY = 0; @@ -122,65 +122,14 @@ ASurface::ASurface(): Graphics::Surface() { } ASurface::~ASurface() { - free(); _savedBlock.free(); } -void ASurface::create(uint16 width, uint16 height) { - Graphics::Surface::create(width, height, Graphics::PixelFormat::createFormatCLUT8()); -} - void ASurface::clearBuffer() { byte *pSrc = (byte *)getPixels(); Common::fill(pSrc, pSrc + w * h, 0); } -bool ASurface::clip(Common::Rect &r) { - int skip; - _leftSkip = _rightSkip = 0; - _topSkip = _bottomSkip = 0; - - if (r.left > _clipWidth || r.left < 0) { - if (r.left >= 0) - return true; - - skip = -r.left; - r.setWidth(r.width() - skip); - _leftSkip = skip; - r.moveTo(0, r.top); - } - - int right = r.right - 1; - if (right < 0) - return true; - else if (right > _clipWidth) { - skip = right - _clipWidth; - r.setWidth(r.width() - skip); - _rightSkip = skip; - } - - if (r.top > _clipHeight || r.top < 0) { - if (r.top >= 0) - return true; - - skip = -r.top; - r.setHeight(r.height() - skip); - _topSkip = skip; - r.moveTo(r.left, 0); - } - - int bottom = r.bottom - 1; - if (bottom < 0) - return true; - else if (bottom > _clipHeight) { - skip = bottom - _clipHeight; - _bottomSkip = skip; - r.setHeight(r.height() - skip); - } - - return false; -} - void ASurface::plotImage(SpriteResource *sprite, int frameNum, const Common::Point &pt) { SpriteFrame *frame = sprite->getFrame(frameNum); Common::Rect r(pt.x, pt.y, pt.x + frame->w, pt.y + frame->h); @@ -195,81 +144,7 @@ void ASurface::plotImage(SpriteResource *sprite, int frameNum, const Common::Poi } } -void ASurface::transBlitFrom(ASurface *src, const Common::Point &destPos) { - if (getPixels() == nullptr) - create(w, h); - - for (int yp = 0; yp < src->h; ++yp) { - const byte *srcP = (const byte *)src->getBasePtr(0, yp); - byte *destP = (byte *)getBasePtr(destPos.x, destPos.y + yp); - - for (int xp = 0; xp < this->w; ++xp, ++srcP, ++destP) { - if (*srcP != TRANSPARENCY) - *destP = *srcP; - } - } -} - -void ASurface::transBlitFrom(ASurface *src, const Common::Rect &bounds) { - const int SCALE_LIMIT = 0x100; - int scaleX = SCALE_LIMIT * bounds.width() / src->w; - int scaleY = SCALE_LIMIT * bounds.height() / src->h; - int scaleXCtr = 0, scaleYCtr = 0; - - for (int yCtr = 0, destY = bounds.top; yCtr < src->h; ++yCtr) { - // Handle skipping lines if Y scaling - scaleYCtr += scaleY; - if (scaleYCtr < SCALE_LIMIT) - continue; - scaleYCtr -= SCALE_LIMIT; - - // Handle off-screen lines - if (destY >= this->h) - break; - - if (destY >= 0) { - // Handle drawing the line - const byte *pSrc = (const byte *)src->getBasePtr(0, yCtr); - byte *pDest = (byte *)getBasePtr(bounds.left, destY); - scaleXCtr = 0; - int x = bounds.left; - - for (int xCtr = 0; xCtr < src->w; ++xCtr, ++pSrc) { - // Handle horizontal scaling - scaleXCtr += scaleX; - if (scaleXCtr < SCALE_LIMIT) - continue; - scaleXCtr -= SCALE_LIMIT; - - // Only handle on-screen pixels - if (x >= this->w) - break; - if (x >= 0 && *pSrc != 0) - *pDest = *pSrc; - - ++pDest; - ++x; - } - } - - ++destY; - } -} - -void ASurface::transBlitFrom(ASurface &src) { - blitFrom(src); -} - -void ASurface::blitFrom(const Graphics::Surface &src) { - assert(w >= src.w && h >= src.h); - for (int y = 0; y < src.h; ++y) { - const byte *srcP = (const byte *)src.getBasePtr(0, y); - byte *destP = (byte *)getBasePtr(0, y); - Common::copy(srcP, srcP + src.w, destP); - } -} - -void ASurface::copyBuffer(Graphics::Surface *src) { +void ASurface::copyBuffer(Graphics::ManagedSurface *src) { blitFrom(*src); } @@ -282,14 +157,11 @@ void ASurface::plotB(SpriteFrame *frame, const Common::Point &pt) { } void ASurface::sPlotF(SpriteFrame *frame, const Common::Rect &bounds) { - transBlitFrom(frame, bounds); + transBlitFrom(*frame, Common::Rect(0, 0, frame->w, frame->h), bounds, TRANSPARENCY, false); } void ASurface::sPlotB(SpriteFrame *frame, const Common::Rect &bounds) { - ASurface flippedFrame; - frame->flipHorizontal(flippedFrame); - - transBlitFrom(&flippedFrame, bounds); + transBlitFrom(*frame, Common::Rect(0, 0, frame->w, frame->h), bounds, TRANSPARENCY, true); } void ASurface::copyBlock(ASurface *src, const Common::Rect &bounds) { @@ -324,22 +196,22 @@ void ASurface::restoreBlock() { } void ASurface::drawRect() { - Graphics::Surface::fillRect(Common::Rect(_orgX1, _orgY1, _orgX2, _orgY2), _lColor); + Graphics::ManagedSurface::fillRect(Common::Rect(_orgX1, _orgY1, _orgX2, _orgY2), _lColor); } void ASurface::drawLine(int x1, int y1, int x2, int y2, int col) { - Graphics::Surface::drawLine(x1, y1, x2, y2, col); + Graphics::ManagedSurface::drawLine(x1, y1, x2, y2, col); } void ASurface::drawLine() { - Graphics::Surface::drawLine(_orgX1, _orgY1, _orgX2, _orgY1, _lColor); + Graphics::ManagedSurface::drawLine(_orgX1, _orgY1, _orgX2, _orgY1, _lColor); } void ASurface::drawBox() { - Graphics::Surface::drawLine(_orgX1, _orgY1, _orgX2, _orgY1, _lColor); - Graphics::Surface::drawLine(_orgX1, _orgY2, _orgX2, _orgY2, _lColor); - Graphics::Surface::drawLine(_orgX2, _orgY1, _orgX2, _orgY1, _lColor); - Graphics::Surface::drawLine(_orgX2, _orgY2, _orgX2, _orgY2, _lColor); + Graphics::ManagedSurface::drawLine(_orgX1, _orgY1, _orgX2, _orgY1, _lColor); + Graphics::ManagedSurface::drawLine(_orgX1, _orgY2, _orgX2, _orgY2, _lColor); + Graphics::ManagedSurface::drawLine(_orgX2, _orgY1, _orgX2, _orgY1, _lColor); + Graphics::ManagedSurface::drawLine(_orgX2, _orgY2, _orgX2, _orgY2, _lColor); } void ASurface::flipHorizontal(ASurface &dest) { @@ -373,4 +245,50 @@ void ASurface::moveBufferDown() { Common::copy_backward(p, p + (pitch * (h - TILE_HEIGHT)), p + (pitch * h)); } +bool ASurface::clip(Common::Rect &r) { + int skip; + _leftSkip = _rightSkip = 0; + _topSkip = _bottomSkip = 0; + + if (r.left > _clipWidth || r.left < 0) { + if (r.left >= 0) + return true; + + skip = -r.left; + r.setWidth(r.width() - skip); + _leftSkip = skip; + r.moveTo(0, r.top); + } + + int right = r.right - 1; + if (right < 0) + return true; + else if (right > _clipWidth) { + skip = right - _clipWidth; + r.setWidth(r.width() - skip); + _rightSkip = skip; + } + + if (r.top > _clipHeight || r.top < 0) { + if (r.top >= 0) + return true; + + skip = -r.top; + r.setHeight(r.height() - skip); + _topSkip = skip; + r.moveTo(r.left, 0); + } + + int bottom = r.bottom - 1; + if (bottom < 0) + return true; + else if (bottom > _clipHeight) { + skip = bottom - _clipHeight; + _bottomSkip = skip; + r.setHeight(r.height() - skip); + } + + return false; +} + } // End of namespace Access diff --git a/engines/access/asurface.h b/engines/access/asurface.h index dd05c8067b..ec18ec09c3 100644 --- a/engines/access/asurface.h +++ b/engines/access/asurface.h @@ -27,7 +27,7 @@ #include "common/array.h" #include "common/memstream.h" #include "common/rect.h" -#include "graphics/surface.h" +#include "graphics/managed_surface.h" #include "access/data.h" namespace Access { @@ -35,7 +35,7 @@ namespace Access { class SpriteResource; class SpriteFrame; -class ASurface : public Graphics::Surface { +class ASurface : virtual public Graphics::ManagedSurface { private: Graphics::Surface _savedBlock; @@ -61,14 +61,8 @@ public: virtual ~ASurface(); - void create(uint16 width, uint16 height); - - bool empty() const { return w == 0 || h == 0 || pixels == nullptr; } - void clearBuffer(); - bool clip(Common::Rect &r); - void plotImage(SpriteResource *sprite, int frameNum, const Common::Point &pt); /** @@ -102,18 +96,8 @@ public: virtual void drawLine(); virtual void drawBox(); - - virtual void transBlitFrom(ASurface *src, const Common::Point &destPos); - - virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds); - virtual void transBlitFrom(ASurface &src); - - virtual void blitFrom(const Graphics::Surface &src); - - virtual void copyBuffer(Graphics::Surface *src); - - virtual void addDirtyRect(const Common::Rect &r) {} + virtual void copyBuffer(Graphics::ManagedSurface *src); void copyTo(ASurface *dest); @@ -126,6 +110,8 @@ public: void moveBufferUp(); void moveBufferDown(); + + bool clip(Common::Rect &r); }; class SpriteFrame : public ASurface { diff --git a/engines/access/events.cpp b/engines/access/events.cpp index d62b05c33f..21ff0d0928 100644 --- a/engines/access/events.cpp +++ b/engines/access/events.cpp @@ -115,7 +115,7 @@ void EventsManager::setCursor(CursorType cursorId) { } } -void EventsManager::setCursorData(Graphics::Surface *src, const Common::Rect &r) { +void EventsManager::setCursorData(Graphics::ManagedSurface *src, const Common::Rect &r) { _invCursor.create(r.width(), r.height(), Graphics::PixelFormat::createFormatCLUT8()); _invCursor.copyRectToSurface(*src, 0, 0, r); } @@ -281,8 +281,7 @@ void EventsManager::nextFrame() { // Give time to the debugger _vm->_debugger->onFrame(); - // TODO: Refactor for dirty rects - _vm->_screen->updateScreen(); + _vm->_screen->update(); } void EventsManager::nextTimer() { diff --git a/engines/access/events.h b/engines/access/events.h index b8c5f0ee5e..5acbb71c9d 100644 --- a/engines/access/events.h +++ b/engines/access/events.h @@ -100,7 +100,7 @@ public: /** * Set the image for the inventory cursor */ - void setCursorData(Graphics::Surface *src, const Common::Rect &r); + void setCursorData(Graphics::ManagedSurface *src, const Common::Rect &r); /** * Return the current cursor Id diff --git a/engines/access/files.cpp b/engines/access/files.cpp index b9c0f7080d..48276ee477 100644 --- a/engines/access/files.cpp +++ b/engines/access/files.cpp @@ -130,13 +130,13 @@ void FileManager::openFile(Resource *res, const Common::String &filename) { error("Could not open file - %s", filename.c_str()); } -void FileManager::loadScreen(Graphics::Surface *dest, int fileNum, int subfile) { +void FileManager::loadScreen(Graphics::ManagedSurface *dest, int fileNum, int subfile) { Resource *res = loadFile(fileNum, subfile); handleScreen(dest, res); delete res; } -void FileManager::handleScreen(Graphics::Surface *dest, Resource *res) { +void FileManager::handleScreen(Graphics::ManagedSurface *dest, Resource *res) { _vm->_screen->loadRawPalette(res->_stream); if (_setPaletteFlag) _vm->_screen->setPalette(); @@ -147,20 +147,17 @@ void FileManager::handleScreen(Graphics::Surface *dest, Resource *res) { res->_size -= res->_stream->pos(); handleFile(res); - if (dest != _vm->_screen) - dest->w = _vm->_screen->w; + Graphics::Surface destSurface = dest->getSubArea(Common::Rect(0, 0, + _vm->_screen->w, _vm->_screen->h)); - if (dest->w == dest->pitch) { - res->_stream->read((byte *)dest->getPixels(), dest->w * dest->h); + if (destSurface.w == destSurface.pitch) { + res->_stream->read((byte *)destSurface.getPixels(), destSurface.w * destSurface.h); } else { - for (int y = 0; y < dest->h; ++y) { - byte *pDest = (byte *)dest->getBasePtr(0, y); - res->_stream->read(pDest, dest->w); + for (int y = 0; y < destSurface.h; ++y) { + byte *pDest = (byte *)destSurface.getBasePtr(0, y); + res->_stream->read(pDest, destSurface.w); } } - - if (dest == _vm->_screen) - _vm->_screen->addDirtyRect(Common::Rect(0, 0, dest->w, dest->h)); } void FileManager::loadScreen(int fileNum, int subfile) { diff --git a/engines/access/files.h b/engines/access/files.h index d081934e91..61fccc2431 100644 --- a/engines/access/files.h +++ b/engines/access/files.h @@ -26,7 +26,7 @@ #include "common/scummsys.h" #include "common/array.h" #include "common/file.h" -#include "graphics/surface.h" +#include "graphics/managed_surface.h" #include "access/decompress.h" namespace Access { @@ -81,7 +81,7 @@ private: /** * Handles loading a screen surface and palette with decoded resource */ - void handleScreen(Graphics::Surface *dest, Resource *res); + void handleScreen(Graphics::ManagedSurface *dest, Resource *res); /** * Open up a sub-file container file @@ -133,7 +133,7 @@ public: /** * Load a screen resource onto a designated surface */ - void loadScreen(Graphics::Surface *dest, int fileNum, int subfile); + void loadScreen(Graphics::ManagedSurface *dest, int fileNum, int subfile); }; } // End of namespace Access diff --git a/engines/access/font.cpp b/engines/access/font.cpp index 8af183f193..6ae65e43f0 100644 --- a/engines/access/font.cpp +++ b/engines/access/font.cpp @@ -151,13 +151,12 @@ void Font::drawString(ASurface *s, const Common::String &msg, const Common::Poin int Font::drawChar(ASurface *s, char c, Common::Point &pt) { Graphics::Surface &ch = _chars[c - ' ']; - - s->addDirtyRect(Common::Rect(pt.x, pt.y, pt.x + ch.w, pt.y + ch.h)); + Graphics::Surface dest = s->getSubArea(Common::Rect(pt.x, pt.y, pt.x + ch.w, pt.y + ch.h)); // Loop through the lines of the character for (int y = 0; y < ch.h; ++y) { byte *pSrc = (byte *)ch.getBasePtr(0, y); - byte *pDest = (byte *)s->getBasePtr(pt.x, pt.y + y); + byte *pDest = (byte *)dest.getBasePtr(0, y); // Loop through the horizontal pixels of the line for (int x = 0; x < ch.w; ++x, ++pSrc, ++pDest) { diff --git a/engines/access/screen.cpp b/engines/access/screen.cpp index aa15abd59a..9700640b71 100644 --- a/engines/access/screen.cpp +++ b/engines/access/screen.cpp @@ -69,8 +69,6 @@ void Screen::clearScreen() { clearBuffer(); if (_vesaMode) _vm->_clearSummaryFlag = true; - - addDirtyRect(Common::Rect(0, 0, this->w, this->h)); } void Screen::setDisplayScan() { @@ -89,28 +87,14 @@ void Screen::setPanel(int num) { _msVirtualOffset = _virtualOffsetsTable[num]; } -void Screen::updateScreen() { +void Screen::update() { if (_vm->_startup >= 0) { if (--_vm->_startup == -1) _fadeIn = true; return; } - - // Merge the dirty rects - mergeDirtyRects(); - - // Loop through copying dirty areas to the physical screen - Common::List<Common::Rect>::iterator i; - for (i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) { - const Common::Rect &r = *i; - const byte *srcP = (const byte *)getBasePtr(r.left, r.top); - g_system->copyRectToScreen(srcP, this->pitch, r.left, r.top, - r.width(), r.height()); - } - - // Signal the physical screen to update - g_system->updateScreen(); - _dirtyRects.clear(); + markAllDirty();//****DEBUG**** + Graphics::Screen::update(); } void Screen::setInitialPalettte() { @@ -153,7 +137,7 @@ void Screen::loadRawPalette(Common::SeekableReadStream *stream) { void Screen::updatePalette() { g_system->getPaletteManager()->setPalette(&_tempPalette[0], 0, PALETTE_COUNT); - updateScreen(); + update(); } void Screen::savePalette() { @@ -293,22 +277,7 @@ void Screen::drawBox() { ASurface::drawBox(); } -void Screen::transBlitFrom(ASurface *src, const Common::Point &destPos) { - addDirtyRect(Common::Rect(destPos.x, destPos.y, destPos.x + src->w, destPos.y + src->h)); - ASurface::transBlitFrom(src, destPos); -} - -void Screen::transBlitFrom(ASurface *src, const Common::Rect &bounds) { - addDirtyRect(bounds); - ASurface::transBlitFrom(src, bounds); -} - -void Screen::blitFrom(const Graphics::Surface &src) { - addDirtyRect(Common::Rect(0, 0, src.w, src.h)); - ASurface::blitFrom(src); -} - -void Screen::copyBuffer(Graphics::Surface *src) { +void Screen::copyBuffer(Graphics::ManagedSurface *src) { addDirtyRect(Common::Rect(0, 0, src->w, src->h)); ASurface::copyBuffer(src); } @@ -349,51 +318,7 @@ void Screen::cyclePaletteBackwards() { } void Screen::flashPalette(int count) { - warning("TODO: Implement flashPalette"); -} - -void Screen::addDirtyRect(const Common::Rect &r) { - _dirtyRects.push_back(r); - assert(r.isValidRect() && r.width() > 0 && r.height() > 0); -} - -void Screen::mergeDirtyRects() { - Common::List<Common::Rect>::iterator rOuter, rInner; - - // Ensure dirty rect list has at least two entries - rOuter = _dirtyRects.begin(); - for (int i = 0; i < 2; ++i, ++rOuter) { - if (rOuter == _dirtyRects.end()) - return; - } - - // Process the dirty rect list to find any rects to merge - for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) { - rInner = rOuter; - while (++rInner != _dirtyRects.end()) { - - if ((*rOuter).intersects(*rInner)) { - // these two rectangles overlap or - // are next to each other - merge them - - unionRectangle(*rOuter, *rOuter, *rInner); - - // remove the inner rect from the list - _dirtyRects.erase(rInner); - - // move back to beginning of list - rInner = rOuter; - } - } - } + // No implementation needed in ScummVM } -bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) { - destRect = src1; - destRect.extend(src2); - - return !destRect.isEmpty(); -} - - } // End of namespace Access diff --git a/engines/access/screen.h b/engines/access/screen.h index 6fa0fe3812..a022741f91 100644 --- a/engines/access/screen.h +++ b/engines/access/screen.h @@ -26,15 +26,13 @@ #include "common/scummsys.h" #include "common/rect.h" #include "common/stream.h" +#include "graphics/screen.h" #include "access/asurface.h" namespace Access { class AccessEngine; -#define PALETTE_COUNT 256 -#define PALETTE_SIZE (256 * 3) - struct ScreenSave { int _clipWidth; int _clipHeight; @@ -47,7 +45,7 @@ struct ScreenSave { int _screenYOff; }; -class Screen : public ASurface { +class Screen : public virtual ASurface, public virtual Graphics::Screen { private: AccessEngine *_vm; byte _tempPalette[PALETTE_SIZE]; @@ -66,10 +64,6 @@ private: Common::List<Common::Rect> _dirtyRects; void updatePalette(); - - void mergeDirtyRects(); - - bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); public: int _vesaMode; int _startColor, _numColors; @@ -87,6 +81,11 @@ public: bool _screenChangeFlag; bool _fadeIn; public: + /** + * Updates the screen + */ + virtual void update(); + virtual void copyBlock(ASurface *src, const Common::Rect &bounds); virtual void restoreBlock(); @@ -95,15 +94,7 @@ public: virtual void drawBox(); - virtual void transBlitFrom(ASurface *src, const Common::Point &destPos); - - virtual void transBlitFrom(ASurface *src, const Common::Rect &bounds); - - virtual void blitFrom(const Graphics::Surface &src); - - virtual void copyBuffer(Graphics::Surface *src); - - virtual void addDirtyRect(const Common::Rect &r); + virtual void copyBuffer(Graphics::ManagedSurface *src); public: Screen(AccessEngine *vm); @@ -114,11 +105,6 @@ public: void setPanel(int num); /** - * Update the underlying screen - */ - void updateScreen(); - - /** * Fade out screen */ void forceFadeOut(); diff --git a/engines/access/video.cpp b/engines/access/video.cpp index 5fc5f6762c..e3ff457c3b 100644 --- a/engines/access/video.cpp +++ b/engines/access/video.cpp @@ -157,7 +157,7 @@ void VideoPlayer::playVideo() { // If the video is playing on the screen surface, add a dirty rect if (_vidSurface == _vm->_screen) - _vm->_screen->addDirtyRect(_videoBounds); + _vm->_screen->markAllDirty(); getFrame(); if (++_videoFrame == _frameCount) { diff --git a/engines/access/video/movie_decoder.cpp b/engines/access/video/movie_decoder.cpp index 05ec25d54c..1406e549ad 100644 --- a/engines/access/video/movie_decoder.cpp +++ b/engines/access/video/movie_decoder.cpp @@ -719,7 +719,7 @@ bool AccessEngine::playMovie(const Common::String &filename, const Common::Point g_system->getPaletteManager()->setPalette(palette, 0, 256); } - _screen->updateScreen(); + _screen->update(); } } diff --git a/engines/bbvs/bbvs.cpp b/engines/bbvs/bbvs.cpp index d40d5e482f..6ae663479d 100644 --- a/engines/bbvs/bbvs.cpp +++ b/engines/bbvs/bbvs.cpp @@ -137,6 +137,21 @@ BbvsEngine::~BbvsEngine() { } void BbvsEngine::newGame() { + memset(_easterEggInput, 0, sizeof(_easterEggInput)); + _gameTicks = 0; + _playVideoNumber = 0; + memset(_inventoryItemStatus, 0, sizeof(_inventoryItemStatus)); + memset(_gameVars, 0, sizeof(_gameVars)); + memset(_sceneVisited, 0, sizeof(_sceneVisited)); + + _mouseX = 160; + _mouseY = 120; + _mouseButtons = 0; + + _currVerbNum = kVerbLook; + _currTalkObjectIndex = -1; + _currSceneNum = 0; + _currInventoryItem = -1; _newSceneNum = 32; } @@ -162,24 +177,10 @@ Common::Error BbvsEngine::run() { _sound = new SoundMan(); allocSnapshot(); - memset(_easterEggInput, 0, sizeof(_easterEggInput)); - _gameTicks = 0; - _playVideoNumber = 0; - _bootSaveSlot = -1; - - memset(_inventoryItemStatus, 0, sizeof(_inventoryItemStatus)); - memset(_gameVars, 0, sizeof(_gameVars)); - memset(_sceneVisited, 0, sizeof(_sceneVisited)); - - _mouseX = 160; - _mouseY = 120; - _mouseButtons = 0; + newGame(); - _currVerbNum = kVerbLook; - _currInventoryItem = -1; - _currTalkObjectIndex = -1; - _currSceneNum = 0; + _bootSaveSlot = -1; _newSceneNum = 31; if (ConfMan.hasKey("save_slot")) 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; diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp index cb42ac0aaa..ad940aaf8b 100644 --- a/engines/saga/interface.cpp +++ b/engines/saga/interface.cpp @@ -1862,8 +1862,10 @@ void Interface::drawStatusBar() { int stringWidth; int color; // The default colors in the Spanish version of IHNM are shifted by one - // Fixes bug #1848016 - "IHNM: Wrong Subtitles Color (Spanish)" - int offset = (_vm->getLanguage() == Common::ES_ESP) ? 1 : 0; + // Fixes bug #1848016 - "IHNM: Wrong Subtitles Color (Spanish)". This + // also applies to the German and French versions (bug #7064 - "IHNM: + // text mistake in german version"). + int offset = (_vm->getLanguage() == Common::ES_ESP || _vm->getLanguage() == Common::DE_DEU || _vm->getLanguage() == Common::FR_FRA) ? 1 : 0; // Disable the status text in IHNM when the chapter is 8 if (_vm->getGameId() == GID_IHNM && _vm->_scene->currentChapterNumber() == 8) diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp index 532b59d3c7..77a21e7f93 100644 --- a/engines/saga/saga.cpp +++ b/engines/saga/saga.cpp @@ -578,9 +578,11 @@ ColorId SagaEngine::KnownColor2ColorId(KnownColor knownColor) { } #ifdef ENABLE_IHNM } else if (getGameId() == GID_IHNM) { - // The default colors in the Spanish version of IHNM are shifted by one - // Fixes bug #1848016 - "IHNM: Wrong Subtitles Color (Spanish)" - int offset = (getLanguage() == Common::ES_ESP) ? 1 : 0; + // The default colors in the Spanish, version of IHNM are shifted by one + // Fixes bug #1848016 - "IHNM: Wrong Subtitles Color (Spanish)". This + // also applies to the German and French versions (bug #7064 - "IHNM: + // text mistake in german version"). + int offset = (getLanguage() == Common::ES_ESP || getLanguage() == Common::DE_DEU || getLanguage() == Common::FR_FRA) ? 1 : 0; switch (knownColor) { case(kKnownColorTransparent): diff --git a/engines/sci/detection_tables.h b/engines/sci/detection_tables.h index d84500cc60..76c819961e 100644 --- a/engines/sci/detection_tables.h +++ b/engines/sci/detection_tables.h @@ -1651,14 +1651,6 @@ static const struct ADGameDescription SciGameDescriptions[] = { #ifdef ENABLE_SCI32 - // King's Quest 7 - English Windows (from abevi) - // VERSION 1.65c - {"kq7", "", { - {"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195}, - {"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925}, - AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // King's Quest 7 - English Windows (from the King's Quest Collection) // Executable scanning reports "2.100.002", VERSION file reports "1.4" {"kq7", "", { @@ -1667,6 +1659,33 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + // King's Quest 7 - English Windows-interpreter-only (supplied by m_kiewitz) + // SCI interpreter version 2.100.002, VERSION file reports "1.51" + {"kq7", "", { + {"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, + {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, + {"resource.aud", 0, "c2a988a16053eb98c7b73a75139902a0", 217716879}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + + // King's Quest 7 - German Windows-interpreter-only (supplied by markcoolio in bug report #2727402) + // SCI interpreter version 2.100.002, VERSION file reports "1.51" + // same as English 1.51, only resource.aud/resource.sfx are different + {"kq7", "", { + {"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, + {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, + {"resource.aud", 0, "3f17bcaf8a9ff6a6c2d4de1a2078fdcc", 258119621}, + AD_LISTEND}, + Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + + // King's Quest 7 - English Windows (from abevi) + // VERSION 1.65c + {"kq7", "", { + {"resource.000", 0, "4948e4e1506f1e1c4e1d47abfa06b7f8", 204385195}, + {"resource.map", 0, "40ccafb2195301504eba2e4f4f2c7f3d", 18925}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + // King's Quest 7 - English DOS (from FRG) // SCI interpreter version 2.100.002, VERSION file reports "2.00b" {"kq7", "", { @@ -1683,14 +1702,6 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // King's Quest 7 - German Windows (supplied by markcoolio in bug report #2727402) - // SCI interpreter version 2.100.002 - {"kq7", "", { - {"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, - {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, - AD_LISTEND}, - Common::DE_DEU, Common::kPlatformDOS, ADGF_UNSTABLE | ADGF_CD, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // King's Quest 7 - Spanish DOS (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "2.00" {"kq7", "", { @@ -2635,6 +2646,28 @@ static const struct ADGameDescription SciGameDescriptions[] = { Common::EN_ANY, Common::kPlatformDOS, 0, GUIO4(GUIO_NOSPEECH, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, #ifdef ENABLE_SCI32 + // Phantasmagoria - English DOS/Windows (from csnover) + // Windows executable scanning reports "2.100.002" - "Aug 06 1995" + // DOS executable scanning reports "2.100.002" - "May 24 1995" + // VERSION file reports "1.000.000" + {"phantasmagoria", "", { + {"resmap.001", 0, "43c395f312a190e67b90b2c1e93a79e2", 11518}, + {"ressci.001", 0, "3aae6559aa1df273bc542d5ac6330d75", 65844612}, + {"resmap.002", 0, "94f142cfe8ec4107b6a42876cb603ed0", 12058}, + {"ressci.002", 0, "3aae6559aa1df273bc542d5ac6330d75", 71588691}, + {"resmap.003", 0, "39e9abd4501b5b6168dd07379c0be753", 12334}, + {"ressci.003", 0, "3aae6559aa1df273bc542d5ac6330d75", 73651084}, + {"resmap.004", 0, "434f9704658229fef322c863d2422a9a", 12556}, + {"ressci.004", 0, "3aae6559aa1df273bc542d5ac6330d75", 75811935}, + {"resmap.005", 0, "3ff9b4f7301800825c0ed008e091205e", 12604}, + {"ressci.005", 0, "3aae6559aa1df273bc542d5ac6330d75", 78814934}, + {"resmap.006", 0, "27ad413313e2a3ec3c53250e7ff5b2d1", 12532}, + {"ressci.006", 0, "3aae6559aa1df273bc542d5ac6330d75", 77901360}, + {"resmap.007", 0, "aa8175cfc93242af6f5e65bdceaafc0d", 7972}, + //{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformDOS, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + // Phantasmagoria - English DOS (from jvprat) // Executable scanning reports "2.100.002", VERSION file reports "1.100.000UK" {"phantasmagoria", "", { @@ -2733,7 +2766,12 @@ static const struct ADGameDescription SciGameDescriptions[] = { Common::EN_ANY, Common::kPlatformMacintosh, ADGF_MACRESFORK | ADGF_UNSTABLE, GUIO4(GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, #ifdef ENABLE_SCI3_GAMES - // Phantasmagoria 2 - English Windows (from jvprat) + // Some versions of Phantasmagoria 2 were heavily censored. + // Censored versions (data files are currently unknown to us): UK, Australia, first English release in Germany + + // Phantasmagoria 2 - English Windows (from jvprat) - US release + // Note: Fully uncensored + // // Executable scanning reports "3.000.000", VERSION file reports "001.0.06" {"phantasmagoria2", "", { {"resmap.001", 0, "0a961e135f4f7effb195158325856633", 1108}, @@ -2749,11 +2787,23 @@ static const struct ADGameDescription SciGameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - // Phantasmagoria 2 - German DOS/Windows + // Phantasmagoria 2 - English DOS (GOG version) (supplied by littleboy in patch #1360) + // Note: Fully uncensored, basically the US release, but ressci.* merged into ressci.000 + // + // Executable scanning reports "3.000.000" - "Dec 07 1996 09:29:03" + // VERSION file reports "001.0.06" + {"phantasmagoria2", "", { + {"ressci.000", 0, "c54f26d9f43f908151263254b6d97053", 108134481}, + {"resmap.000", 0, "de154a223a9ef4ea7358b76adc38ef5b", 2956}, + AD_LISTEND}, + Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, + + // Phantasmagoria 2 - German DOS/Windows (supplied by AReim1982) + // Note: Fully uncensored, but one scene is missing probably because of a mastering error (Curtis + Therese meeting near water cooler) + // // Windows executable scanning reports "unknown" - "Dec 07 1996 15:42:02" // DOS executable scanning reports "unknown" - "Dec 07 1996 08:35:12" // VERSION file reports "000.1.0vu" (HEX: 30 30 30 2E 31 00 2E 30 76 FA 0D 0A) - // Supplied by AReim1982 {"phantasmagoria2", "", { {"resmap.001", 0, "d62f48ff8bddb39503b97e33439482c9", 1114}, {"ressci.001", 0, "4ebc2b8455c74ad205ae592eec27313a", 24590716}, @@ -2767,16 +2817,6 @@ static const struct ADGameDescription SciGameDescriptions[] = { {"ressci.005", 0, "e94005890d22dd3b7f605a2a7c025803", 68232146}, AD_LISTEND}, Common::DE_DEU, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, - - // Phantasmagoria 2 - English DOS (GOG version) - ressci.* merged in ressci.000 - // Executable scanning reports "3.000.000" - "Dec 07 1996 09:29:03" - // VERSION file reports "001.0.06" - // Supplied by littleboy in patch #3112884 - {"phantasmagoria2", "", { - {"ressci.000", 0, "c54f26d9f43f908151263254b6d97053", 108134481}, - {"resmap.000", 0, "de154a223a9ef4ea7358b76adc38ef5b", 2956}, - AD_LISTEND}, - Common::EN_ANY, Common::kPlatformWindows, ADGF_UNSTABLE, GUIO5(GUIO_NOSPEECH, GUIO_NOASPECT, GAMEOPTION_PREFER_DIGITAL_SFX, GAMEOPTION_ORIGINAL_SAVELOAD, GAMEOPTION_FB01_MIDI) }, #endif // ENABLE_SCI3_GAMES #endif // ENABLE_SCI32 diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 8321b8da82..62566a74b2 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -491,6 +491,8 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv); reg_t kSetPalStyleRange(EngineState *s, int argc, reg_t *argv); reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv); reg_t kFrameOut(EngineState *s, int argc, reg_t *argv); +reg_t kCelHigh32(EngineState *s, int argc, reg_t *argv); +reg_t kCelWide32(EngineState *s, int argc, reg_t *argv); reg_t kIsOnMe(EngineState *s, int argc, reg_t *argv); // kOnMe for SCI2, kIsOnMe for SCI2.1 reg_t kInPolygon(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index a61eb5afa4..3463d05e77 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -461,8 +461,12 @@ static SciKernelMapEntry s_kernelMap[] = { #ifdef ENABLE_SCI32 { MAP_CALL(CantBeHere), SIG_SCI32, SIGFOR_ALL, "ol", NULL, NULL }, #endif - { MAP_CALL(CelHigh), SIG_EVERYWHERE, "ii(i)", NULL, kCelHigh_workarounds }, - { MAP_CALL(CelWide), SIG_EVERYWHERE, "ii(i)", NULL, kCelWide_workarounds }, + { MAP_CALL(CelHigh), SIG_SCI16, SIGFOR_ALL, "ii(i)", NULL, kCelHigh_workarounds }, + { MAP_CALL(CelWide), SIG_SCI16, SIGFOR_ALL, "ii(i)", NULL, kCelWide_workarounds }, +#ifdef ENABLE_SCI32 + { "CelHigh", kCelHigh32, SIG_SCI32, SIGFOR_ALL, "iii", NULL, NULL }, + { "CelWide", kCelWide32, SIG_SCI32, SIGFOR_ALL, "iii", NULL, NULL }, +#endif { MAP_CALL(CheckFreeSpace), SIG_SCI32, SIGFOR_ALL, "r.*", NULL, NULL }, { MAP_CALL(CheckFreeSpace), SIG_SCI11, SIGFOR_ALL, "r(i)", NULL, NULL }, { MAP_CALL(CheckFreeSpace), SIG_EVERYWHERE, "r", NULL, NULL }, @@ -726,8 +730,8 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(WinHelp), SIG_EVERYWHERE, "(.*)", NULL, NULL }, { MAP_CALL(GetConfig), SIG_EVERYWHERE, "ro", NULL, NULL }, { MAP_CALL(GetSierraProfileInt), SIG_EVERYWHERE, "rri", NULL, NULL }, - { MAP_CALL(CelInfo), SIG_EVERYWHERE, "iiiiii", NULL, NULL }, - { MAP_CALL(SetLanguage), SIG_EVERYWHERE, "r", NULL, NULL }, + { MAP_CALL(CelInfo), SIG_SINCE_SCI21MID, SIGFOR_ALL, "iiiiii", NULL, NULL }, + { MAP_CALL(SetLanguage), SIG_SINCE_SCI21MID, SIGFOR_ALL, "r", NULL, NULL }, { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "i(.*)", kScrollWindow_subops, NULL }, { MAP_CALL(SetFontRes), SIG_SCI21EARLY, SIGFOR_ALL, "ii", NULL, NULL }, { MAP_CALL(Font), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kFont_subops, NULL }, diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index b64aff704c..7850a10006 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -74,19 +74,19 @@ reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv) { reg_t kAddScreenItem(EngineState *s, int argc, reg_t *argv) { debugC(6, kDebugLevelGraphics, "kAddScreenItem %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0])); g_sci->_gfxFrameout->kernelAddScreenItem(argv[0]); - return NULL_REG; + return s->r_acc; } reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv) { debugC(7, kDebugLevelGraphics, "kUpdateScreenItem %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0])); g_sci->_gfxFrameout->kernelUpdateScreenItem(argv[0]); - return NULL_REG; + return s->r_acc; } reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv) { debugC(6, kDebugLevelGraphics, "kDeleteScreenItem %x:%x (%s)", PRINT_REG(argv[0]), s->_segMan->getObjectName(argv[0])); g_sci->_gfxFrameout->kernelDeleteScreenItem(argv[0]); - return NULL_REG; + return s->r_acc; } reg_t kAddPlane(EngineState *s, int argc, reg_t *argv) { @@ -114,7 +114,7 @@ reg_t kMovePlaneItems(EngineState *s, int argc, reg_t *argv) { const bool scrollPics = argc > 3 ? argv[3].toUint16() : false; g_sci->_gfxFrameout->kernelMovePlaneItems(plane, deltaX, deltaY, scrollPics); - return NULL_REG; + return s->r_acc; } reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) { @@ -125,7 +125,7 @@ reg_t kAddPicAt(EngineState *s, int argc, reg_t *argv) { bool mirrorX = argc > 4 ? argv[4].toSint16() : false; g_sci->_gfxFrameout->kernelAddPicAt(planeObj, pictureId, x, y, mirrorX); - return NULL_REG; + return s->r_acc; } reg_t kGetHighPlanePri(EngineState *s, int argc, reg_t *argv) { @@ -137,12 +137,12 @@ reg_t kFrameOut(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxFrameout->kernelFrameOut(showBits); s->speedThrottler(16); s->_throttleTrigger = true; - return NULL_REG; + return s->r_acc; } reg_t kSetPalStyleRange(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxFrameout->kernelSetPalStyleRange(argv[0].toUint16(), argv[1].toUint16()); - return NULL_REG; + return s->r_acc; } reg_t kObjectIntersect(EngineState *s, int argc, reg_t *argv) { @@ -228,7 +228,7 @@ reg_t kTextSize32(EngineState *s, int argc, reg_t *argv) { rect[1] = make_reg(0, textRect.top); rect[2] = make_reg(0, textRect.right - 1); rect[3] = make_reg(0, textRect.bottom - 1); - return NULL_REG; + return s->r_acc; } reg_t kTextWidth(EngineState *s, int argc, reg_t *argv) { @@ -307,31 +307,50 @@ reg_t kSetShowStyle(EngineState *s, int argc, reg_t *argv) { // on the KernelMgr g_sci->_gfxFrameout->kernelSetShowStyle(argc, planeObj, type, seconds, back, priority, animate, refFrame, pFadeArray, divisions, blackScreen); - return NULL_REG; + return s->r_acc; +} + +reg_t kCelHigh32(EngineState *s, int argc, reg_t *argv) { + GuiResourceId resourceId = argv[0].toUint16(); + int16 loopNo = argv[1].toSint16(); + int16 celNo = argv[2].toSint16(); + CelObjView celObj(resourceId, loopNo, celNo); + return make_reg(0, mulru(celObj._height, Ratio(g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight, celObj._scaledHeight))); +} + +reg_t kCelWide32(EngineState *s, int argc, reg_t *argv) { + GuiResourceId resourceId = argv[0].toUint16(); + int16 loopNo = argv[1].toSint16(); + int16 celNo = argv[2].toSint16(); + CelObjView celObj(resourceId, loopNo, celNo); + return make_reg(0, mulru(celObj._width, Ratio(g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth, celObj._scaledWidth))); } reg_t kCelInfo(EngineState *s, int argc, reg_t *argv) { // Used by Shivers 1, room 23601 to determine what blocks on the red door puzzle board // are occupied by pieces already - switch (argv[0].toUint16()) { // subops 0 - 4 - // 0 - return the view - // 1 - return the loop - // 2, 3 - nop - case 4: { - GuiResourceId viewId = argv[1].toSint16(); - int16 loopNo = argv[2].toSint16(); - int16 celNo = argv[3].toSint16(); - int16 x = argv[4].toUint16(); - int16 y = argv[5].toUint16(); - byte color = g_sci->_gfxCache->kernelViewGetColorAtCoordinate(viewId, loopNo, celNo, x, y); - return make_reg(0, color); - } - default: { - kStub(s, argc, argv); - return s->r_acc; - } + CelObjView view(argv[1].toUint16(), argv[2].toSint16(), argv[3].toSint16()); + + int16 result = 0; + + switch (argv[0].toUint16()) { + case 0: + result = view._displace.x; + break; + case 1: + result = view._displace.y; + break; + case 2: + case 3: + // null operation + break; + case 4: + result = view.readPixel(argv[4].toSint16(), argv[5].toSint16(), view._mirrorX); + break; } + + return make_reg(0, result); } reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv) { @@ -488,13 +507,13 @@ reg_t kSetFontHeight(EngineState *s, int argc, reg_t *argv) { // which case we could just get the font directly ourselves. g_sci->_gfxText32->setFont(argv[0].toUint16()); g_sci->_gfxText32->_scaledHeight = (g_sci->_gfxText32->_font->getHeight() * g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight + g_sci->_gfxText32->_scaledHeight - 1) / g_sci->_gfxText32->_scaledHeight; - return NULL_REG; + return make_reg(0, g_sci->_gfxText32->_scaledHeight); } reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxText32->_scaledWidth = argv[0].toUint16(); g_sci->_gfxText32->_scaledHeight = argv[1].toUint16(); - return NULL_REG; + return s->r_acc; } reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { @@ -519,7 +538,7 @@ reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) { reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) { s->_segMan->freeHunkEntry(argv[0]); - return NULL_REG; + return s->r_acc; } reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv) { @@ -573,7 +592,6 @@ reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) { reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) { // called e.g. from TextButton::createBitmap() in Torin's Passage, script 64894 - // bitmap, text, textLeft, textTop, textRight, textBottom, foreColor, backColor, skipColor, fontNo, alignment, borderColor, dimmed BitmapResource bitmap(argv[0]); Common::String text = s->_segMan->getString(argv[1]); Common::Rect textRect( @@ -604,36 +622,23 @@ reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) { textCel.draw(bitmapBuffer, textRect, Common::Point(textRect.left, textRect.top), false); s->_segMan->freeHunkEntry(textBitmapObject); - return NULL_REG; + return s->r_acc; } reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv) { - // bitmap, left, top, right, bottom, color - // called e.g. from TextView::init() and TextView::draw() in Torin's Passage, script 64890 - return kStubNull(s, argc + 1, argv - 1); -#if 0 - reg_t hunkId = argv[1]; // obtained from kBitmap(0) - uint16 x = argv[2].toUint16(); - uint16 y = argv[3].toUint16(); - uint16 fillWidth = argv[4].toUint16(); // width - 1 - uint16 fillHeight = argv[5].toUint16(); // height - 1 - uint16 back = argv[6].toUint16(); - byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); - // Get totalWidth, totalHeight - uint16 totalWidth = READ_LE_UINT16(memoryPtr); - uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); - uint16 width = MIN<uint16>(totalWidth - x, fillWidth); - uint16 height = MIN<uint16>(totalHeight - y, fillHeight); - byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + BitmapResource bitmap(argv[0]); + Common::Rect fillRect( + argv[1].toSint16(), + argv[2].toSint16(), + argv[3].toSint16() + 1, + argv[4].toSint16() + 1 + ); - for (uint16 curY = 0; curY < height; curY++) { - for (uint16 curX = 0; curX < width; curX++) { - bitmap[(curY + y) * totalWidth + (curX + x)] = back; - } - } -#endif + Buffer buffer(bitmap.getWidth(), bitmap.getHeight(), bitmap.getPixels()); + buffer.fillRect(fillRect, argv[5].toSint16()); + return s->r_acc; } reg_t kBitmapDrawBitmap(EngineState *s, int argc, reg_t *argv) { @@ -649,9 +654,9 @@ reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv) { } reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv) { - // bitmap, x, y - - return kStubNull(s, argc + 1, argv - 1); + BitmapResource bitmap(argv[0]); + bitmap.setDisplace(Common::Point(argv[1].toSint16(), argv[2].toSint16())); + return s->r_acc; } reg_t kBitmapCreateFromView(EngineState *s, int argc, reg_t *argv) { @@ -701,12 +706,12 @@ reg_t kAddLine(EngineState *s, int argc, reg_t *argv) { reg_t plane = argv[0]; Common::Point startPoint(argv[1].toUint16(), argv[2].toUint16()); Common::Point endPoint(argv[3].toUint16(), argv[4].toUint16()); - // argv[5] is unknown (a number, usually 200) + byte priority = (byte)argv[5].toUint16(); byte color = (byte)argv[6].toUint16(); - byte priority = (byte)argv[7].toUint16(); - byte control = (byte)argv[8].toUint16(); - // argv[9] is unknown (usually a small number, 1 or 2). Thickness, perhaps? -// return g_sci->_gfxFrameout->addPlaneLine(plane, startPoint, endPoint, color, priority, control); + byte style = (byte)argv[7].toUint16(); // 0: solid, 1: dashed, 2: pattern + byte pattern = (byte)argv[8].toUint16(); + byte thickness = (byte)argv[9].toUint16(); +// return g_sci->_gfxFrameout->addPlaneLine(plane, startPoint, endPoint, color, priority, 0); return s->r_acc; #endif } @@ -765,7 +770,7 @@ reg_t kSetScroll(EngineState *s, int argc, reg_t *argv) { // Used by SQ6, script 900, the datacorder reprogramming puzzle (from room 270) reg_t kMorphOn(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxFrameout->_palMorphIsOn = true; - return NULL_REG; + return s->r_acc; } reg_t kPaletteSetFade(EngineState *s, int argc, reg_t *argv) { @@ -773,7 +778,7 @@ reg_t kPaletteSetFade(EngineState *s, int argc, reg_t *argv) { uint16 toColor = argv[1].toUint16(); uint16 percent = argv[2].toUint16(); g_sci->_gfxPalette32->setFade(percent, fromColor, toColor); - return NULL_REG; + return s->r_acc; } reg_t kPalVarySetVary(EngineState *s, int argc, reg_t *argv) { @@ -791,18 +796,14 @@ reg_t kPalVarySetVary(EngineState *s, int argc, reg_t *argv) { } g_sci->_gfxPalette32->kernelPalVarySet(paletteId, percent, time, fromColor, toColor); - return NULL_REG; + return s->r_acc; } reg_t kPalVarySetPercent(EngineState *s, int argc, reg_t *argv) { int time = argc > 0 ? argv[0].toSint16() * 60 : 0; int16 percent = argc > 1 ? argv[1].toSint16() : 0; - - // TODO: GK1 adds a third optional parameter here, at the end of chapter 1 - // (during the sunset/sunrise sequence, the parameter is 1) - g_sci->_gfxPalette32->setVaryPercent(percent, time, -1, -1); - return NULL_REG; + return s->r_acc; } reg_t kPalVaryGetPercent(EngineState *s, int argc, reg_t *argv) { @@ -811,7 +812,7 @@ reg_t kPalVaryGetPercent(EngineState *s, int argc, reg_t *argv) { reg_t kPalVaryOff(EngineState *s, int argc, reg_t *argv) { g_sci->_gfxPalette32->varyOff(); - return NULL_REG; + return s->r_acc; } reg_t kPalVaryMergeTarget(EngineState *s, int argc, reg_t *argv) { @@ -823,7 +824,7 @@ reg_t kPalVaryMergeTarget(EngineState *s, int argc, reg_t *argv) { reg_t kPalVarySetTime(EngineState *s, int argc, reg_t *argv) { int time = argv[0].toSint16() * 60; g_sci->_gfxPalette32->setVaryTime(time); - return NULL_REG; + return s->r_acc; } reg_t kPalVarySetTarget(EngineState *s, int argc, reg_t *argv) { diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index f598cf7457..1c08bf597c 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -765,11 +765,14 @@ reg_t kStringCopy(EngineState *s, int argc, reg_t *argv) { } // The original engine ignores bad copies too - if (index2 > string2Size) + if (index2 >= string2Size) return NULL_REG; // A count of -1 means fill the rest of the array - uint32 count = argv[4].toSint16() == -1 ? string2Size - index2 + 1 : argv[4].toUint16(); + uint32 count = string2Size - index2; + if (argv[4].toSint16() != -1) { + count = MIN(count, (uint32)argv[4].toUint16()); + } // reg_t strAddress = argv[0]; SciString *string1 = s->_segMan->lookupString(argv[0]); diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index ae7ab431f8..fcb65157d8 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -1012,6 +1012,26 @@ void gamestate_afterRestoreFixUp(EngineState *s, int savegameId) { g_sci->_gfxMenu->kernelSetAttribute(1025 >> 8, 1025 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Statistics g_sci->_gfxMenu->kernelSetAttribute(1026 >> 8, 1026 & 0xFF, SCI_MENU_ATTRIBUTE_ENABLED, TRUE_REG); // Status -> Goals break; + case GID_KQ6: + if (g_sci->isCD()) { + // WORKAROUND: + // For the CD version of King's Quest 6, set global depending on current hires/lowres state + // The game sets a global at the start depending on it and some things check that global + // instead of checking platform like for example the game action menu. + // This never happened in the original interpreter, because the original DOS interpreter + // was only capable of lowres graphics and the original Windows 3.11 interpreter was only capable + // of hires graphics. Saved games were not compatible between those two. + // Which means saving during lowres mode, then going into hires mode and restoring that saved game, + // will result in some graphics being incorrect (lowres). + // That's why we are setting the global after restoring a saved game depending on hires/lowres state. + // The CD demo of KQ6 does the same and uses the exact same global. + if ((g_sci->getPlatform() == Common::kPlatformWindows) || (g_sci->forceHiresGraphics())) { + s->variables[VAR_GLOBAL][0xA9].setOffset(1); + } else { + s->variables[VAR_GLOBAL][0xA9].setOffset(0); + } + } + break; case GID_PQ2: // HACK: Same as above - enable the save game menu option when loading in PQ2 (bug #6875). // It gets disabled in the game's death screen. diff --git a/engines/sci/engine/workarounds.cpp b/engines/sci/engine/workarounds.cpp index a4e19dc8b9..3832f4cf04 100644 --- a/engines/sci/engine/workarounds.cpp +++ b/engines/sci/engine/workarounds.cpp @@ -378,6 +378,7 @@ const SciWorkaroundEntry uninitializedReadWorkarounds[] = { { GID_SQ6, -1, 64950, -1, "Feature", "handleEvent", NULL, 0, { WORKAROUND_FAKE, 0 } }, // called when pressing "Start game" in the main menu, when entering the Orion's Belt bar (room 300), and perhaps other places { GID_SQ6, -1, 64964, 0, "DPath", "init", NULL, 1, { WORKAROUND_FAKE, 0 } }, // during the game { GID_TORIN, -1, 64017, 0, "oFlags", "clear", NULL, 0, { WORKAROUND_FAKE, 0 } }, // entering Torin's home in the French version + { GID_TORIN, 10000, 64029, 0, "oMessager", "nextMsg", NULL, 3, { WORKAROUND_FAKE, 0 } }, // start of chapter one SCI_WORKAROUNDENTRY_TERMINATOR }; diff --git a/engines/sci/graphics/cache.cpp b/engines/sci/graphics/cache.cpp index 59af8334eb..fb1f557ad6 100644 --- a/engines/sci/graphics/cache.cpp +++ b/engines/sci/graphics/cache.cpp @@ -102,8 +102,4 @@ int16 GfxCache::kernelViewGetCelCount(GuiResourceId viewId, int16 loopNo) { return getView(viewId)->getCelCount(loopNo); } -byte GfxCache::kernelViewGetColorAtCoordinate(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y) { - return getView(viewId)->getColorAtCoordinate(loopNo, celNo, x, y); -} - } // End of namespace Sci diff --git a/engines/sci/graphics/cache.h b/engines/sci/graphics/cache.h index 33fa4fe399..61952718a9 100644 --- a/engines/sci/graphics/cache.h +++ b/engines/sci/graphics/cache.h @@ -49,8 +49,6 @@ public: int16 kernelViewGetLoopCount(GuiResourceId viewId); int16 kernelViewGetCelCount(GuiResourceId viewId, int16 loopNo); - byte kernelViewGetColorAtCoordinate(GuiResourceId viewId, int16 loopNo, int16 celNo, int16 x, int16 y); - private: void purgeFontCache(); void purgeViewCache(); diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp index acf499308a..693bc5f196 100644 --- a/engines/sci/graphics/celobj32.cpp +++ b/engines/sci/graphics/celobj32.cpp @@ -27,6 +27,7 @@ #include "sci/graphics/frameout.h" #include "sci/graphics/palette32.h" #include "sci/graphics/picture.h" +#include "sci/graphics/remap.h" #include "sci/graphics/text32.h" #include "sci/graphics/view.h" @@ -109,25 +110,42 @@ void CelObj::deinit() { template<bool FLIP, typename READER> struct SCALER_NoScale { +#ifndef NDEBUG + const byte *_rowEdge; +#endif const byte *_row; READER _reader; const int16 _lastIndex; + const int16 _sourceX; + const int16 _sourceY; - SCALER_NoScale(const CelObj &celObj, const int16 maxWidth) : + SCALER_NoScale(const CelObj &celObj, const int16 maxWidth, const Common::Point &scaledPosition) : _reader(celObj, FLIP ? celObj._width : maxWidth), - _lastIndex(celObj._width - 1) {} + _lastIndex(celObj._width - 1), + _sourceX(scaledPosition.x), + _sourceY(scaledPosition.y) {} - inline void setSource(const int16 x, const int16 targetY, const int16 scaledPosY) { - _row = _reader.getRow(targetY - scaledPosY); + inline void setTarget(const int16 x, const int16 y) { + _row = _reader.getRow(y - _sourceY); if (FLIP) { - _row += _lastIndex - x; +#ifndef NDEBUG + _rowEdge = _row - 1; +#endif + _row += _lastIndex - (x - _sourceX); + assert(_row > _rowEdge); } else { - _row += x; +#ifndef NDEBUG + _rowEdge = _row + _lastIndex + 1; +#endif + _row += x - _sourceX; + assert(_row < _rowEdge); } } inline byte read() { + assert(_row != _rowEdge); + if (FLIP) { return *_row--; } else { @@ -138,58 +156,96 @@ struct SCALER_NoScale { template<bool FLIP, typename READER> struct SCALER_Scale { +#ifndef NDEBUG + int16 _maxX; +#endif const byte *_row; READER _reader; - const CelScalerTable *_table; int16 _x; - const uint16 _lastIndex; + static int16 _valuesX[1024]; + static int16 _valuesY[1024]; - SCALER_Scale(const CelObj &celObj, const int16 maxWidth, const Ratio scaleX, const Ratio scaleY) : + SCALER_Scale(const CelObj &celObj, const Common::Rect &targetRect, const Common::Point &scaledPosition, const Ratio scaleX, const Ratio scaleY) : +#ifndef NDEBUG + _maxX(targetRect.right - 1), +#endif // The maximum width of the scaled object may not be as // wide as the source data it requires if downscaling, // so just always make the reader decompress an entire // line of source data when scaling - _reader(celObj, celObj._width), - _table(CelObj::_scaler->getScalerTable(scaleX, scaleY)), - _lastIndex(maxWidth - 1) {} - - inline void setSource(const int16 x, const int16 targetY, const int16 scaledPosY) { - // look up both targetY + scaledPosY in here, only subtract afterwards - // otherwise y won't be correct all the time when uneven scaling is used (for example 5:12) - int16 y = _table->valuesY[targetY] - _table->valuesY[scaledPosY]; - _row = _reader.getRow(y); + _reader(celObj, celObj._width) { + // In order for scaling ratios to apply equally across objects that + // start at different positions on the screen, the pixels that are + // read from the source bitmap must all use the same pattern of + // division. In other words, cels must follow the same scaling pattern + // as if they were drawn starting at an even multiple of the scaling + // ratio, even if they were not. + // + // To get the correct source pixel when reading out through the scaler, + // the engine creates a lookup table for each axis that translates + // directly from target positions to the indexes of source pixels using + // the global cadence for the given scaling ratio. + + const CelScalerTable *table = CelObj::_scaler->getScalerTable(scaleX, scaleY); + + const int16 unscaledX = (scaledPosition.x / scaleX).toInt(); if (FLIP) { - _x = _lastIndex - x; + int lastIndex = celObj._width - 1; + for (int16 x = targetRect.left; x < targetRect.right; ++x) { + _valuesX[x] = lastIndex - (table->valuesX[x] - unscaledX); + } } else { - _x = x; + for (int16 x = targetRect.left; x < targetRect.right; ++x) { + _valuesX[x] = table->valuesX[x] - unscaledX; + } + } + + const int16 unscaledY = (scaledPosition.y / scaleY).toInt(); + for (int16 y = targetRect.top; y < targetRect.bottom; ++y) { + _valuesY[y] = table->valuesY[y] - unscaledY; } } + inline void setTarget(const int16 x, const int16 y) { + _row = _reader.getRow(_valuesY[y]); + _x = x; + assert(_x >= 0 && _x <= _maxX); + } + inline byte read() { - if (FLIP) { - return _row[_table->valuesX[_x--]]; - } else { - return _row[_table->valuesX[_x++]]; - } + assert(_x >= 0 && _x <= _maxX); + return _row[_valuesX[_x++]]; } }; +template<bool FLIP, typename READER> +int16 SCALER_Scale<FLIP, READER>::_valuesX[1024]; +template<bool FLIP, typename READER> +int16 SCALER_Scale<FLIP, READER>::_valuesY[1024]; + #pragma mark - #pragma mark CelObj - Resource readers struct READER_Uncompressed { private: +#ifndef NDEBUG + const int16 _sourceHeight; +#endif byte *_pixels; const int16 _sourceWidth; public: READER_Uncompressed(const CelObj &celObj, const int16) : +#ifndef NDEBUG + _sourceHeight(celObj._height), +#endif _sourceWidth(celObj._width) { byte *resource = celObj.getResPointer(); _pixels = resource + READ_SCI11ENDIAN_UINT32(resource + celObj._celHeaderOffset + 24); } inline const byte *getRow(const int16 y) const { + assert(y >= 0 && y < _sourceHeight); return _pixels + y * _sourceWidth; } }; @@ -213,7 +269,7 @@ public: _sourceHeight(celObj._height), _transparentColor(celObj._transparentColor), _maxWidth(maxWidth) { - assert(_maxWidth <= celObj._width); + assert(maxWidth <= celObj._width); byte *celHeader = _resource + celObj._celHeaderOffset; _dataOffset = READ_SCI11ENDIAN_UINT32(celHeader + 24); @@ -222,6 +278,7 @@ public: } inline const byte *getRow(const int16 y) { + assert(y >= 0 && y < _sourceHeight); if (y != _y) { // compressed data segment for row byte *row = _resource + _dataOffset + READ_SCI11ENDIAN_UINT32(_resource + _controlOffset + y * 4); @@ -230,7 +287,7 @@ public: byte *literal = _resource + _uncompressedDataOffset + READ_SCI11ENDIAN_UINT32(_resource + _controlOffset + _sourceHeight * 4 + y * 4); uint8 length; - for (int i = 0; i < _maxWidth; i += length) { + for (int16 i = 0; i < _maxWidth; i += length) { byte controlByte = *row++; length = controlByte; @@ -277,153 +334,101 @@ struct MAPPER_NoMDNoSkip { } }; +struct MAPPER_Map { + inline void draw(byte *target, const byte pixel, const uint8 skipColor) const { + if (pixel != skipColor) { + if (pixel < g_sci->_gfxRemap32->getStartColor()) { + *target = pixel; + } else { + if (g_sci->_gfxRemap32->remapEnabled(pixel)) + *target = g_sci->_gfxRemap32->remapColor(pixel, *target); + } + } + } +}; + void CelObj::draw(Buffer &target, const ScreenItem &screenItem, const Common::Rect &targetRect) const { - const Buffer &priorityMap = g_sci->_gfxFrameout->getPriorityMap(); const Common::Point &scaledPosition = screenItem._scaledPosition; const Ratio &scaleX = screenItem._ratioX; const Ratio &scaleY = screenItem._ratioY; if (_remap) { - if (g_sci->_gfxFrameout->_hasRemappedScreenItem) { - const uint8 priority = MAX((int16)0, MIN((int16)255, screenItem._priority)); - - // NOTE: In the original engine code, there was a second branch for - // _remap here that would then call the following functions if _remap was false: - // - // drawHzFlip(Buffer &, Buffer &, Common::Rect &, Common::Point &, uint8) - // drawNoFlip(Buffer &, Buffer &, Common::Rect &, Common::Point &, uint8) - // drawUncompHzFlip(Buffer &, Buffer &, Common::Rect &, Common::Point &, uint8) - // drawUncompNoFlip(Buffer &, Buffer &, Common::Rect &, Common::Point &, uint8) - // scaleDraw(Buffer &, Buffer &, Ratio &, Ratio &, Common::Rect &, Common::Point &, uint8) - // scaleDrawUncomp(Buffer &, Buffer &, Ratio &, Ratio &, Common::Rect &, Common::Point &, uint8) - // - // However, obviously, _remap cannot be false here. This dead code branch existed in - // at least SCI2/GK1 and SCI2.1/SQ6. - + // NOTE: In the original code this check was `g_Remap_numActiveRemaps && _remap`, + // but since we are already in a `_remap` branch, there is no reason to check it + // again + if (g_sci->_gfxRemap32->getRemapCount()) { if (scaleX.isOne() && scaleY.isOne()) { if (_compressionType == kCelCompressionNone) { if (_drawMirrored) { - drawUncompHzFlipMap(target, priorityMap, targetRect, scaledPosition, priority); + drawUncompHzFlipMap(target, targetRect, scaledPosition); } else { - drawUncompNoFlipMap(target, priorityMap, targetRect, scaledPosition, priority); + drawUncompNoFlipMap(target, targetRect, scaledPosition); } } else { if (_drawMirrored) { - drawHzFlipMap(target, priorityMap, targetRect, scaledPosition, priority); + drawHzFlipMap(target, targetRect, scaledPosition); } else { - drawNoFlipMap(target, priorityMap, targetRect, scaledPosition, priority); + drawNoFlipMap(target, targetRect, scaledPosition); } } } else { if (_compressionType == kCelCompressionNone) { - scaleDrawUncompMap(target, priorityMap, scaleX, scaleY, targetRect, scaledPosition, priority); + scaleDrawUncompMap(target, scaleX, scaleY, targetRect, scaledPosition); } else { - scaleDrawMap(target, priorityMap, scaleX, scaleY, targetRect, scaledPosition, priority); + scaleDrawMap(target, scaleX, scaleY, targetRect, scaledPosition); } } } else { - // NOTE: In the original code this check was `g_Remap_numActiveRemaps && _remap`, - // but since we are already in a `_remap` branch, there is no reason to check it - // again - if (/* TODO: g_Remap_numActiveRemaps */ false) { - if (scaleX.isOne() && scaleY.isOne()) { - if (_compressionType == kCelCompressionNone) { - if (_drawMirrored) { - drawUncompHzFlipMap(target, targetRect, scaledPosition); - } else { - drawUncompNoFlipMap(target, targetRect, scaledPosition); - } + if (scaleX.isOne() && scaleY.isOne()) { + if (_compressionType == kCelCompressionNone) { + if (_drawMirrored) { + drawUncompHzFlip(target, targetRect, scaledPosition); } else { - if (_drawMirrored) { - drawHzFlipMap(target, targetRect, scaledPosition); - } else { - drawNoFlipMap(target, targetRect, scaledPosition); - } + drawUncompNoFlip(target, targetRect, scaledPosition); } } else { - if (_compressionType == kCelCompressionNone) { - scaleDrawUncompMap(target, scaleX, scaleY, targetRect, scaledPosition); + if (_drawMirrored) { + drawHzFlip(target, targetRect, scaledPosition); } else { - scaleDrawMap(target, scaleX, scaleY, targetRect, scaledPosition); + drawNoFlip(target, targetRect, scaledPosition); } } } else { - if (scaleX.isOne() && scaleY.isOne()) { - if (_compressionType == kCelCompressionNone) { - if (_drawMirrored) { - drawUncompHzFlip(target, targetRect, scaledPosition); - } else { - drawUncompNoFlip(target, targetRect, scaledPosition); - } - } else { - if (_drawMirrored) { - drawHzFlip(target, targetRect, scaledPosition); - } else { - drawNoFlip(target, targetRect, scaledPosition); - } - } + if (_compressionType == kCelCompressionNone) { + scaleDrawUncomp(target, scaleX, scaleY, targetRect, scaledPosition); } else { - if (_compressionType == kCelCompressionNone) { - scaleDrawUncomp(target, scaleX, scaleY, targetRect, scaledPosition); - } else { - scaleDraw(target, scaleX, scaleY, targetRect, scaledPosition); - } + scaleDraw(target, scaleX, scaleY, targetRect, scaledPosition); } } } } else { - if (g_sci->_gfxFrameout->_hasRemappedScreenItem) { - const uint8 priority = MAX((int16)0, MIN((int16)255, screenItem._priority)); - if (scaleX.isOne() && scaleY.isOne()) { - if (_compressionType == kCelCompressionNone) { + if (scaleX.isOne() && scaleY.isOne()) { + if (_compressionType == kCelCompressionNone) { + if (_transparent) { if (_drawMirrored) { - drawUncompHzFlipNoMD(target, priorityMap, targetRect, scaledPosition, priority); + drawUncompHzFlipNoMD(target, targetRect, scaledPosition); } else { - drawUncompNoFlipNoMD(target, priorityMap, targetRect, scaledPosition, priority); + drawUncompNoFlipNoMD(target, targetRect, scaledPosition); } } else { if (_drawMirrored) { - drawHzFlipNoMD(target, priorityMap, targetRect, scaledPosition, priority); + drawUncompHzFlipNoMDNoSkip(target, targetRect, scaledPosition); } else { - drawNoFlipNoMD(target, priorityMap, targetRect, scaledPosition, priority); + drawUncompNoFlipNoMDNoSkip(target, targetRect, scaledPosition); } } } else { - if (_compressionType == kCelCompressionNone) { - scaleDrawUncompNoMD(target, priorityMap, scaleX, scaleY, targetRect, scaledPosition, priority); + if (_drawMirrored) { + drawHzFlipNoMD(target, targetRect, scaledPosition); } else { - scaleDrawNoMD(target, priorityMap, scaleX, scaleY, targetRect, scaledPosition, priority); + drawNoFlipNoMD(target, targetRect, scaledPosition); } } } else { - if (scaleX.isOne() && scaleY.isOne()) { - if (_compressionType == kCelCompressionNone) { - if (_transparent) { - if (_drawMirrored) { - drawUncompHzFlipNoMD(target, targetRect, scaledPosition); - } else { - drawUncompNoFlipNoMD(target, targetRect, scaledPosition); - } - } else { - if (_drawMirrored) { - drawUncompHzFlipNoMDNoSkip(target, targetRect, scaledPosition); - } else { - drawUncompNoFlipNoMDNoSkip(target, targetRect, scaledPosition); - } - } - } else { - if (_drawMirrored) { - drawHzFlipNoMD(target, targetRect, scaledPosition); - } else { - drawNoFlipNoMD(target, targetRect, scaledPosition); - } - } + if (_compressionType == kCelCompressionNone) { + scaleDrawUncompNoMD(target, scaleX, scaleY, targetRect, scaledPosition); } else { - if (_compressionType == kCelCompressionNone) { - scaleDrawUncompNoMD(target, scaleX, scaleY, targetRect, scaledPosition); - } else { - scaleDrawNoMD(target, scaleX, scaleY, targetRect, scaledPosition); - } + scaleDrawNoMD(target, scaleX, scaleY, targetRect, scaledPosition); } } } @@ -577,18 +582,15 @@ struct RENDERER { _skipColor(skipColor) {} inline void draw(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - const int16 sourceX = targetRect.left - scaledPosition.x; - //const int16 sourceY = targetRect.top - scaledPosition.y; - byte *targetPixel = (byte *)target.getPixels() + target.screenWidth * targetRect.top + targetRect.left; const int16 skipStride = target.screenWidth - targetRect.width(); const int16 targetWidth = targetRect.width(); const int16 targetHeight = targetRect.height(); - for (int y = 0; y < targetHeight; ++y) { - _scaler.setSource(sourceX, targetRect.top + y, scaledPosition.y); + for (int16 y = 0; y < targetHeight; ++y) { + _scaler.setTarget(targetRect.left, targetRect.top + y); - for (int x = 0; x < targetWidth; ++x) { + for (int16 x = 0; x < targetWidth; ++x) { _mapper.draw(targetPixel++, _scaler.read(), _skipColor); } @@ -601,7 +603,7 @@ template<typename MAPPER, typename SCALER> void CelObj::render(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { MAPPER mapper; - SCALER scaler(*this, targetRect.left - scaledPosition.x + targetRect.width()); + SCALER scaler(*this, targetRect.left - scaledPosition.x + targetRect.width(), scaledPosition); RENDERER<MAPPER, SCALER> renderer(mapper, scaler, _transparentColor); renderer.draw(target, targetRect, scaledPosition); } @@ -610,7 +612,7 @@ template<typename MAPPER, typename SCALER> void CelObj::render(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition, const Ratio &scaleX, const Ratio &scaleY) const { MAPPER mapper; - SCALER scaler(*this, targetRect.left - scaledPosition.x + targetRect.width(), scaleX, scaleY); + SCALER scaler(*this, targetRect, scaledPosition, scaleX, scaleY); RENDERER<MAPPER, SCALER> renderer(mapper, scaler, _transparentColor); renderer.draw(target, targetRect, scaledPosition); } @@ -623,49 +625,60 @@ void CelObj::drawHzFlip(Buffer &target, const Common::Rect &targetRect, const Co debug("drawHzFlip"); dummyFill(target, targetRect); } + void CelObj::drawNoFlip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { debug("drawNoFlip"); dummyFill(target, targetRect); } + void CelObj::drawUncompNoFlip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { debug("drawUncompNoFlip"); dummyFill(target, targetRect); } + void CelObj::drawUncompHzFlip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { debug("drawUncompHzFlip"); dummyFill(target, targetRect); } + void CelObj::scaleDraw(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { debug("scaleDraw"); dummyFill(target, targetRect); } + void CelObj::scaleDrawUncomp(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { debug("scaleDrawUncomp"); dummyFill(target, targetRect); } + void CelObj::drawHzFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - debug("drawHzFlipMap"); - dummyFill(target, targetRect); + render<MAPPER_Map, SCALER_NoScale<true, READER_Compressed> >(target, targetRect, scaledPosition); } + void CelObj::drawNoFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - debug("drawNoFlipMap"); - dummyFill(target, targetRect); + render<MAPPER_Map, SCALER_NoScale<false, READER_Compressed> >(target, targetRect, scaledPosition); } + void CelObj::drawUncompNoFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - debug("drawUncompNoFlipMap"); - dummyFill(target, targetRect); + render<MAPPER_Map, SCALER_NoScale<false, READER_Uncompressed> >(target, targetRect, scaledPosition); } + void CelObj::drawUncompHzFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - debug("drawUncompHzFlipMap"); - dummyFill(target, targetRect); + render<MAPPER_Map, SCALER_NoScale<true, READER_Uncompressed> >(target, targetRect, scaledPosition); } + void CelObj::scaleDrawMap(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - debug("scaleDrawMap"); - dummyFill(target, targetRect); + if (_drawMirrored) + render<MAPPER_Map, SCALER_Scale<true, READER_Compressed> >(target, targetRect, scaledPosition, scaleX, scaleY); + else + render<MAPPER_Map, SCALER_Scale<false, READER_Compressed> >(target, targetRect, scaledPosition, scaleX, scaleY); } + void CelObj::scaleDrawUncompMap(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - debug("scaleDrawUncompMap"); - dummyFill(target, targetRect); + if (_drawMirrored) + render<MAPPER_Map, SCALER_Scale<true, READER_Uncompressed> >(target, targetRect, scaledPosition, scaleX, scaleY); + else + render<MAPPER_Map, SCALER_Scale<false, READER_Uncompressed> >(target, targetRect, scaledPosition, scaleX, scaleY); } void CelObj::drawNoFlipNoMD(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { @@ -683,43 +696,29 @@ void CelObj::drawUncompNoFlipNoMD(Buffer &target, const Common::Rect &targetRect void CelObj::drawUncompNoFlipNoMDNoSkip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { render<MAPPER_NoMDNoSkip, SCALER_NoScale<false, READER_Uncompressed> >(target, targetRect, scaledPosition); } + void CelObj::drawUncompHzFlipNoMD(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { render<MAPPER_NoMD, SCALER_NoScale<true, READER_Uncompressed> >(target, targetRect, scaledPosition); } + void CelObj::drawUncompHzFlipNoMDNoSkip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { render<MAPPER_NoMDNoSkip, SCALER_NoScale<true, READER_Uncompressed> >(target, targetRect, scaledPosition); } void CelObj::scaleDrawNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - if (_drawMirrored) { + if (_drawMirrored) render<MAPPER_NoMD, SCALER_Scale<true, READER_Compressed> >(target, targetRect, scaledPosition, scaleX, scaleY); - } else { + else render<MAPPER_NoMD, SCALER_Scale<false, READER_Compressed> >(target, targetRect, scaledPosition, scaleX, scaleY); - } } void CelObj::scaleDrawUncompNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const { - if (_drawMirrored) { + if (_drawMirrored) render<MAPPER_NoMD, SCALER_Scale<true, READER_Uncompressed> >(target, targetRect, scaledPosition, scaleX, scaleY); - } else { + else render<MAPPER_NoMD, SCALER_Scale<false, READER_Uncompressed> >(target, targetRect, scaledPosition, scaleX, scaleY); - } } -// TODO: These functions may all be vestigial. -void CelObj::drawHzFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::drawNoFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::drawUncompNoFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::drawUncompHzFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::scaleDrawMap(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::scaleDrawUncompMap(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::drawHzFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::drawNoFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::drawUncompNoFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::drawUncompHzFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::scaleDrawNoMD(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} -void CelObj::scaleDrawUncompNoMD(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const {} - #pragma mark - #pragma mark CelObjView CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int16 celNo) { @@ -835,8 +834,8 @@ CelObjView::CelObjView(const GuiResourceId viewId, const int16 loopNo, const int bool CelObjView::analyzeUncompressedForRemap() const { byte *pixels = getResPointer() + READ_SCI11ENDIAN_UINT32(getResPointer() + _celHeaderOffset + 24); for (int i = 0; i < _width * _height; ++i) { - uint8 pixel = pixels[i]; - if (/* TODO: pixel >= Remap::minRemapColor && pixel <= Remap::maxRemapColor */ false && pixel != _transparentColor) { + byte pixel = pixels[i]; + if (pixel >= g_sci->_gfxRemap32->getStartColor() && pixel <= g_sci->_gfxRemap32->getEndColor() && pixel != _transparentColor) { return true; } } @@ -844,7 +843,16 @@ bool CelObjView::analyzeUncompressedForRemap() const { } bool CelObjView::analyzeForRemap() const { - // TODO: Implement decompression and analysis + READER_Compressed reader(*this, _width); + for (int y = 0; y < _height; y++) { + const byte *curRow = reader.getRow(y); + for (int x = 0; x < _width; x++) { + byte pixel = curRow[x]; + if (pixel >= g_sci->_gfxRemap32->getStartColor() && pixel <= g_sci->_gfxRemap32->getEndColor() && pixel != _transparentColor) { + return true; + } + } + } return false; } diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h index 8d030cfd4a..0bb4b03ae2 100644 --- a/engines/sci/graphics/celobj32.h +++ b/engines/sci/graphics/celobj32.h @@ -104,6 +104,10 @@ struct CelInfo32 { bitmap == other.bitmap ); } + + inline bool operator!=(const CelInfo32 &other) { + return !(*this == other); + } }; class CelObj; @@ -180,13 +184,16 @@ public: CelScaler() : _scaleTables(), _activeIndex(0) { - CelScalerTable &table = _scaleTables[_activeIndex]; + CelScalerTable &table = _scaleTables[0]; table.scaleX = Ratio(); table.scaleY = Ratio(); for (int i = 0; i < ARRAYSIZE(table.valuesX); ++i) { table.valuesX[i] = i; table.valuesY[i] = i; } + for (int i = 1; i < ARRAYSIZE(_scaleTables); ++i) { + _scaleTables[i] = _scaleTables[0]; + } } /** @@ -391,18 +398,15 @@ private: void drawUncompHzFlip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void scaleDraw(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void scaleDrawUncomp(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; + void drawHzFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void drawNoFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void drawUncompNoFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void drawUncompHzFlipMap(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void scaleDrawMap(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void scaleDrawUncompMap(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; - void drawHzFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void drawNoFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void drawUncompNoFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void drawUncompHzFlipMap(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void scaleDrawMap(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void scaleDrawUncompMap(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; + // NOTE: The original includes versions of the above functions with priority parameters, which were not actually used in SCI32 + void drawHzFlipNoMD(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void drawNoFlipNoMD(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void drawUncompNoFlipNoMD(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; @@ -411,12 +415,7 @@ private: void drawUncompHzFlipNoMDNoSkip(Buffer &target, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void scaleDrawNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; void scaleDrawUncompNoMD(Buffer &target, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition) const; - void drawHzFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void drawNoFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void drawUncompNoFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void drawUncompHzFlipNoMD(Buffer &target, const Buffer &priorityMap, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void scaleDrawNoMD(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; - void scaleDrawUncompNoMD(Buffer &target, const Buffer &priorityMap, const Ratio &scaleX, const Ratio &scaleY, const Common::Rect &targetRect, const Common::Point &scaledPosition, const uint8 priority) const; + // NOTE: The original includes versions of the above functions with priority parameters, which were not actually used in SCI32 #pragma mark - #pragma mark CelObj - Caching diff --git a/engines/sci/graphics/compare.cpp b/engines/sci/graphics/compare.cpp index 8b2d5e247a..729eeeaf81 100644 --- a/engines/sci/graphics/compare.cpp +++ b/engines/sci/graphics/compare.cpp @@ -158,6 +158,10 @@ reg_t GfxCompare::kernelCanBeHere(reg_t curObject, reg_t listReference) { } reg_t GfxCompare::kernelCantBeHere32(const reg_t curObject, const reg_t listReference) const { + // Most of SCI32 graphics code converts rects from the VM to exclusive + // rects before operating on them, but this call leverages SCI16 engine + // code that operates on inclusive rects, so the rect's bottom-right + // point is not modified like in other SCI32 kernel calls Common::Rect checkRect( readSelectorValue(_segMan, curObject, SELECTOR(brLeft)), readSelectorValue(_segMan, curObject, SELECTOR(brTop)), diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index b124573ba1..6454a1eb32 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -56,8 +56,6 @@ namespace Sci { -// TODO/FIXME: This is partially guesswork - static int dissolveSequences[2][20] = { /* SCI2.1early- */ { 3, 6, 12, 20, 48, 96, 184, 272, 576, 1280, 3232, 6912, 13568, 24576, 46080 }, /* SCI2.1mid+ */ { 0, 0, 3, 6, 12, 20, 48, 96, 184, 272, 576, 1280, 3232, 6912, 13568, 24576, 46080, 73728, 132096, 466944 } @@ -82,7 +80,6 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd _showStyles(nullptr), // TODO: Stop using _gfxScreen _currentBuffer(screen->getDisplayWidth(), screen->getDisplayHeight(), nullptr), - _priorityMap(screen->getDisplayWidth(), screen->getDisplayHeight(), nullptr), _remapOccurred(false), _frameNowVisible(false), _screenRect(screen->getDisplayWidth(), screen->getDisplayHeight()), @@ -118,6 +115,22 @@ GfxFrameout::GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAd _defaultUnknownC = unknownCDefaults[1]; } + switch (g_sci->getGameId()) { + case GID_GK2: + case GID_LIGHTHOUSE: + case GID_LSL7: + case GID_PHANTASMAGORIA2: + case GID_PQSWAT: + case GID_TORIN: + case GID_RAMA: + _currentBuffer.scriptWidth = 640; + _currentBuffer.scriptHeight = 480; + break; + default: + // default script width for other games is 320x200 + break; + } + // TODO: Nothing in the renderer really uses this. Currently, // the cursor renderer does, and kLocalToGlobal/kGlobalToLocal // do, but in the real engine (1) the cursor is handled in @@ -448,8 +461,7 @@ void GfxFrameout::frameOut(const bool shouldShowBits, const Common::Rect &rect) eraseLists.resize(_planes.size()); if (g_sci->_gfxRemap32->getRemapCount() > 0 && _remapOccurred) { - // TODO - // remapMarkRedraw(); + remapMarkRedraw(); } calcLists(screenItemLists, eraseLists, rect); @@ -773,16 +785,6 @@ void GfxFrameout::drawEraseList(const RectList &eraseList, const Plane &plane) { } void GfxFrameout::drawScreenItemList(const DrawList &screenItemList) { - _hasRemappedScreenItem = false; - if (/* TODO: g_Remap_UnknownCounter2 */ false && !_priorityMap.isNull()) { - for (DrawList::const_iterator it = screenItemList.begin(); it != screenItemList.end(); ++it) { - if ((*it)->screenItem->getCelObj()._remap) { - _hasRemappedScreenItem = true; - break; - } - } - } - for (DrawList::const_iterator it = screenItemList.begin(); it != screenItemList.end(); ++it) { DrawItem &drawItem = **it; mergeToShowList(drawItem.rect, _showList, _overdrawThreshold); @@ -827,9 +829,7 @@ void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry Palette sourcePalette(*_palette->getNextPalette()); alterVmap(sourcePalette, sourcePalette, -1, styleRanges); - // TODO: unsure if this is what this variable actually - // represents, but it is the correct variable number - int16 lastRoom = g_sci->getEngineState()->variables[VAR_GLOBAL][12].toSint16(); + int16 prevRoom = g_sci->getEngineState()->variables[VAR_GLOBAL][12].toSint16(); Common::Rect rect(_screen->getDisplayWidth(), _screen->getDisplayHeight()); _showList.add(rect); @@ -846,8 +846,7 @@ void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry eraseLists.resize(_planes.size()); if (g_sci->_gfxRemap32->getRemapCount() > 0 && _remapOccurred) { - // TODO - //_screen->remapMarkRedraw(); + remapMarkRedraw(); } calcLists(screenItemLists, eraseLists, calcRect); @@ -871,7 +870,7 @@ void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry Palette nextPalette(*_palette->getNextPalette()); - if (lastRoom < 1000) { + if (prevRoom < 1000) { for (int i = 0; i < ARRAYSIZE(sourcePalette.colors); ++i) { if (styleRanges[i] == -1 || styleRanges[i] == 0) { sourcePalette.colors[i] = nextPalette.colors[i]; @@ -895,7 +894,7 @@ void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry if (showStyle && showStyle->type != kShowStyleUnknown) { // TODO: SCI2.1mid transition effects // processEffects(); - warning("Transition not implemented!"); + warning("Transition %d not implemented!", showStyle->type); } else { showBits(); } @@ -903,13 +902,11 @@ void GfxFrameout::palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry _frameNowVisible = true; for (PlaneList::iterator plane = _planes.begin(); plane != _planes.end(); ++plane) { -// TODO: -// plane->updateRedrawAllCount(); + (*plane)->_redrawAllCount = getScreenCount(); } if (g_sci->_gfxRemap32->getRemapCount() > 0 && _remapOccurred) { - // TODO - //_screen->remapMarkRedraw(); + remapMarkRedraw(); } calcLists(screenItemLists, eraseLists, calcRect); @@ -1036,7 +1033,10 @@ void GfxFrameout::alterVmap(const Palette &palette1, const Palette &palette2, co int8 styleRangeValue = styleRanges[currentValue]; if (styleRangeValue == -1 && styleRangeValue == style) { currentValue = pixels[pixelIndex] = clut[currentValue]; - styleRangeValue = styleRanges[clut[currentValue]]; + // NOTE: In original engine this assignment happens outside of the + // condition, but if the branch is not followed the value is just + // going to be the same as it was before + styleRangeValue = styleRanges[currentValue]; } if ( @@ -1087,44 +1087,7 @@ inline ShowStyleEntry *GfxFrameout::deleteShowStyleInternal(ShowStyleEntry *cons lastEntry->next = showStyle->next; } - // NOTE: Differences from SCI2/2.1early engine: - // 1. Memory of ShowStyle-owned objects was freed before ShowStyle was - // removed from the linked list, but since this operation is position - // independent, it has been moved after removal from the list for - // consistency with SCI2.1mid+ - // 2. In SCI2, `screenItems` was a pointer to an array of pointers, so - // extra deletes were performed here; we use an owned container object - // instead, which is automatically freed when ShowStyle is freed -#if 0 - if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { - uint8 type = showStyle->type; - - if (type >= 1 && type <= 10) { - ScreenItemList &styleItems = showStyle->screenItems; - for (ScreenItemList::iterator it = styleItems.begin(); it != styleItems.end(); ++it) { - if (active) { - // TODO: _screen->deleteScreenItem(showStyle->plane, *it->id); - _screenItems.remove(*it); - } - delete *it; - } - } else if (type == 11 || type == 12) { - if (!showStyle->bitmapMemId.isNull()) { - _segMan->freeHunkEntry(showStyle->bitmapMemId); - } - if (showStyle->bitmapScreenItem != nullptr) { - // TODO: _screen->deleteScreenItem(showStyle->plane, showStyle->bitmapScreenItem->id); - _screenItems.remove(showStyle->bitmapScreenItem); - delete showStyle->bitmapScreenItem; - } - } - } else { -#endif - delete[] showStyle->fadeColorRanges; -#if 0 - } -#endif - + delete[] showStyle->fadeColorRanges; delete showStyle; // TODO: Verify that this is the correct entry to return @@ -1136,11 +1099,20 @@ inline ShowStyleEntry *GfxFrameout::deleteShowStyleInternal(ShowStyleEntry *cons // and need to be fixed in future // TODO: SQ6 does not use 'priority' (exists since SCI2) or 'blackScreen' (exists since SCI3); // check to see if other versions use or if they are just always ignored -void GfxFrameout::kernelSetShowStyle(const uint16 argc, const reg_t &planeObj, const ShowStyleType type, const int16 seconds, const int16 back, const int16 priority, const int16 animate, const int16 frameOutNow, const reg_t &pFadeArray, const int16 divisions, const int16 blackScreen) { +void GfxFrameout::kernelSetShowStyle(const uint16 argc, const reg_t planeObj, const ShowStyleType type, const int16 seconds, const int16 back, const int16 priority, const int16 animate, const int16 frameOutNow, reg_t pFadeArray, int16 divisions, const int16 blackScreen) { bool hasDivisions = false; bool hasFadeArray = false; - if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { + + // KQ7 2.0b uses a mismatched version of the Styler script (SCI2.1early script + // for SCI2.1mid engine), so the calls it makes to kSetShowStyle are wrong and + // put `divisions` where `pFadeArray` is supposed to be + if (getSciVersion() == SCI_VERSION_2_1_MIDDLE && g_sci->getGameId() == GID_KQ7) { + hasDivisions = argc > 7; + hasFadeArray = false; + divisions = argc > 7 ? pFadeArray.toSint16() : -1; + pFadeArray = NULL_REG; + } else if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { hasDivisions = argc > 7; hasFadeArray = false; } else if (getSciVersion() < SCI_VERSION_3) { @@ -1170,20 +1142,12 @@ void GfxFrameout::kernelSetShowStyle(const uint16 argc, const reg_t &planeObj, c error("Plane %04x:%04x is not present in active planes list", PRINT_REG(planeObj)); } - // TODO: This is Plane.gameRect in SCI engine, not planeRect. Engine uses - // Plane::ConvGameRectToPlaneRect to convert from gameRect to planeRect. - // Also this never gets used by SQ6 so it is not clear what it does yet - // Common::Rect gameRect = plane.planeRect; - bool createNewEntry = true; ShowStyleEntry *entry = findShowStyleForPlane(planeObj); if (entry != nullptr) { + // TODO: SCI2.1early has different criteria for show style reuse bool useExisting = true; - if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { - useExisting = plane->_planeRect.width() == entry->width && plane->_planeRect.height() == entry->height; - } - if (useExisting) { useExisting = entry->divisions == (hasDivisions ? divisions : _defaultDivisions[type]) && entry->unknownC == _defaultUnknownC[type]; } @@ -1212,39 +1176,28 @@ void GfxFrameout::kernelSetShowStyle(const uint16 argc, const reg_t &planeObj, c entry->divisions = hasDivisions ? divisions : _defaultDivisions[type]; entry->plane = planeObj; -#if 0 - if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { - entry->bitmapMemId = NULL_REG; - entry->screenItems.empty(); - entry->width = plane->_planeRect.width(); - entry->height = plane->_planeRect.height(); - } else { -#endif - entry->fadeColorRanges = nullptr; - if (hasFadeArray) { - // NOTE: SCI2.1mid engine does no check to verify that an array is - // successfully retrieved, and SegMan will cause a fatal error - // if we try to use a memory segment that is not an array - SciArray<reg_t> *table = _segMan->lookupArray(pFadeArray); - - uint32 rangeCount = table->getSize(); - entry->fadeColorRangesCount = rangeCount; - - // NOTE: SCI engine code always allocates memory even if the range - // table has no entries, but this does not really make sense, so - // we avoid the allocation call in this case - if (rangeCount > 0) { - entry->fadeColorRanges = new uint16[rangeCount]; - for (size_t i = 0; i < rangeCount; ++i) { - entry->fadeColorRanges[i] = table->getValue(i).toUint16(); - } + entry->fadeColorRanges = nullptr; + if (hasFadeArray) { + // NOTE: SCI2.1mid engine does no check to verify that an array is + // successfully retrieved, and SegMan will cause a fatal error + // if we try to use a memory segment that is not an array + SciArray<reg_t> *table = _segMan->lookupArray(pFadeArray); + + uint32 rangeCount = table->getSize(); + entry->fadeColorRangesCount = rangeCount; + + // NOTE: SCI engine code always allocates memory even if the range + // table has no entries, but this does not really make sense, so + // we avoid the allocation call in this case + if (rangeCount > 0) { + entry->fadeColorRanges = new uint16[rangeCount]; + for (size_t i = 0; i < rangeCount; ++i) { + entry->fadeColorRanges[i] = table->getValue(i).toUint16(); } - } else { - entry->fadeColorRangesCount = 0; } -#if 0 + } else { + entry->fadeColorRangesCount = 0; } -#endif } // NOTE: The original engine had no nullptr check and would just crash @@ -1261,9 +1214,6 @@ void GfxFrameout::kernelSetShowStyle(const uint16 argc, const reg_t &planeObj, c entry->delay = (seconds * 60 + entry->divisions - 1) / entry->divisions; if (entry->delay == 0) { -#if 0 - if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE && entry->fadeColorRanges != nullptr) { -#endif if (entry->fadeColorRanges != nullptr) { delete[] entry->fadeColorRanges; } @@ -1277,235 +1227,13 @@ void GfxFrameout::kernelSetShowStyle(const uint16 argc, const reg_t &planeObj, c } if (createNewEntry) { - // TODO: Implement SCI3, which may or may not actually have - // the same transitions as SCI2/SCI2.1early, but implemented - // differently -#if 0 - if (getSciVersion() < SCI_VERSION_2_1_MIDDLE) { - switch (entry->type) { - case kShowStyleHShutterIn: - case kShowStyleHShutterOut: - prepareShowStyleWipe(entry, priority, 2, true); - break; - - case kShowStyleVShutterIn: - case kShowStyleVShutterOut: - prepareShowStyleWipe(entry, priority, 2, false); - break; - - case kShowStyleHWipe1: - case kShowStyleHWipe2: - prepareShowStyleWipe(entry, priority, 1, true); - break; - - case kShowStyleVWipe1: - case kShowStyleVWipe2: - prepareShowStyleWipe(entry, priority, 1, false); - break; - - case kShowStyleIrisIn: - case kShowStyleIrisOut: - prepareShowStyleIris(entry, priority); - break; - - case kShowStyle11: - case kShowStyle12: - prepareShowStylePixels(entry, priority, plane->planeRect); - break; - - default: - break; - } - } -#endif - + // TODO: Implement SCI2.1early and SCI3 entry->next = _showStyles; _showStyles = entry; } } } -#if 0 -void addFrameoutEntryInternal(ShowStyleEntry *const showStyle, const int16 priority, const CelInfo32 &celInfo, const Common::Rect &rect) { - ScreenItem *screenItem = new ScreenItem; - screenItem->plane = showStyle->plane; - screenItem->celInfo = celInfo; - screenItem->celRect = rect; - screenItem->isInList = true; - screenItem->priority = priority; - screenItem->visible = true; - showStyle->screenItems.push_back(screenItem); -} - -void GfxFrameout::prepareShowStyleWipe(ShowStyleEntry *const showStyle, const int16 priority, const int16 edgeCount, const bool horizontal) { - assert(edgeCount == 1 || edgeCount == 2); - - const int numScreenItems = showStyle->divisions * edgeCount; - const int extra = edgeCount > 1 ? 1 : 0; - - showStyle->edgeCount = edgeCount; - showStyle->screenItems.reserve(numScreenItems); - - CelInfo32 celInfo; - celInfo.bitmap = NULL_REG; - celInfo.type = kCelObjTypeView; - celInfo.color = showStyle->color; - - for (int i = 0; i < numScreenItems; ++i) { - Common::Rect rect; - - if (horizontal) { - rect.top = 0; - rect.bottom = showStyle->height - 1; - rect.left = (showStyle->width * i) / (showStyle->divisions * edgeCount); - rect.right = ((i + 1) * (showStyle->width + extra)) / (showStyle->divisions * edgeCount) - 1; - } else { - rect.left = 0; - rect.right = showStyle->width - 1; - rect.top = (showStyle->height * i) / (showStyle->divisions * edgeCount); - rect.bottom = ((i + 1) * (showStyle->height + extra)) / (showStyle->divisions * edgeCount) - 1; - } - - addFrameoutEntryInternal(showStyle, priority, celInfo, rect); - - if (edgeCount == 2) { - if (horizontal) { - int temp = rect.left; - rect.left = showStyle->width - rect.right - 1; - rect.right = showStyle->width - temp - 1; - } else { - int temp = rect.top; - rect.top = showStyle->height - rect.bottom - 1; - rect.bottom = showStyle->height - temp - 1; - } - - addFrameoutEntryInternal(showStyle, priority, celInfo, rect); - } - } -} - -void GfxFrameout::prepareShowStyleIris(ShowStyleEntry *const showStyle, const int16 priority) { - const int edgeCount = 4; - const int numScreenItems = showStyle->divisions * edgeCount; - - showStyle->edgeCount = edgeCount; - showStyle->screenItems.reserve(numScreenItems); - - CelInfo32 celInfo; - celInfo.bitmap = NULL_REG; - celInfo.type = kCelObjTypeView; - celInfo.color = showStyle->color; - - for (int i = 0; i < numScreenItems; ++i) { - Common::Rect rect; - - rect.right = showStyle->width - ((showStyle->width * i) / (showStyle->divisions * 2)) - 1; - rect.left = (showStyle->width * i) / (showStyle->divisions * 2); - rect.top = (showStyle->height * i) / (showStyle->divisions * 2); - rect.bottom = ((i + 1) * (showStyle->height + 1)) / (showStyle->divisions * 2) - 1; - - addFrameoutEntryInternal(showStyle, priority, celInfo, rect); - - { - int temp = rect.top; - rect.top = showStyle->height - rect.bottom - 1; - rect.bottom = showStyle->height - temp - 1; - } - - addFrameoutEntryInternal(showStyle, priority, celInfo, rect); - - rect.top = ((i + 1) * (showStyle->height + 1)) / (showStyle->divisions * 2); - rect.right = ((i + 1) * (showStyle->width + 1)) / (showStyle->divisions * 2) - 1; - rect.bottom = ((i + 1) * (showStyle->height + 1)) / (showStyle->divisions * 2) - 1; - - addFrameoutEntryInternal(showStyle, priority, celInfo, rect); - - { - int temp = rect.left; - rect.left = showStyle->width - rect.right - 1; - rect.right = showStyle->width - temp - 1; - } - - addFrameoutEntryInternal(showStyle, priority, celInfo, rect); - } -} - -void GfxFrameout::prepareShowStylePixels(ShowStyleEntry *const showStyle, const int16 priority, const Common::Rect planeGameRect) { - const int bitmapSize = showStyle->width * showStyle->height; - - // TODO: Verify that memory type 0x200 (what GK1 engine uses) - // is Hunk type - reg_t bitmapMemId = _segMan->allocateHunkEntry("ShowStylePixels()", bitmapSize + sizeof(GfxBitmapHeader)); - showStyle->bitmapMemId = bitmapMemId; - - // TODO: SCI2 GK1 uses a Bitmap constructor function to - // do this work - byte *bitmap = _segMan->getHunkPointer(bitmapMemId); - GfxBitmapHeader *header = (GfxBitmapHeader *)bitmap; - byte *bitmapData = bitmap + sizeof(GfxBitmapHeader); - - // TODO: These are defaults from the Bitmap constructor in - // GK1, not specific values set by this function. - // TODO: This probably should not even be using a struct at - // all since this information is machine endian dependent - // and will be reversed for Mac versions or when running - // ScummVM on big-endian systems. GK1 used packed structs - // everywhere so this probably worked better there too. - header->field_18 = 36; - header->field_1c = 36; - memset(header, 0, sizeof(GfxBitmapHeader)); - - header->width = showStyle->width; - header->height = showStyle->height; - header->field_8 = 250; - header->size = bitmapSize; - - // TODO: Scaled dimensions in bitmap headers was not added - // until SCI2.1mid. It is not clear what the right thing to - // do here is. - if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { - header->scaledWidth = _currentBuffer.scriptWidth; - header->scaledHeight = _currentBuffer.scriptHeight; - } - - Common::Rect copyRect; - // TODO: planeGameRect is supposedly in script coordinates, - // which are usually 320x200. If bitsSaveDisplayScreen is - // in native resolution then seemingly this function will - // not work properly since we will be not copy enough bits, - // or from the correct location. - copyRect.left = planeGameRect.left; - copyRect.top = planeGameRect.top; - copyRect.right = planeGameRect.left + showStyle->width; - copyRect.bottom = planeGameRect.top + showStyle->height; - _screen->bitsSaveDisplayScreen(copyRect, bitmapData); - - CelInfo32 celInfo; - celInfo.bitmap = bitmapMemId; - celInfo.type = kCelObjTypeMem; - - ScreenItem *screenItem = new ScreenItem; - - screenItem->position.x = 0; - screenItem->position.y = 0; - - showStyle->bitmapScreenItem = screenItem; - screenItem->priority = priority; - - // TODO: Have not seen/identified this particular flag yet in - // SCI2.1mid (SQ6) engine; maybe (1) a duplicate of `created`, - // or (2) does not exist any more, or (3) one of the other - // still-unidentified fields. Probably need to look at the - // GK1 source for its use in drawing algorithms to determine - // if/how this correlates to ScreenItem members in the - // SCI2.1mid engine. -// screenItem->isInList = true; - - Plane *plane = _planes.findByObject(showStyle.plane); - plane->_screenItemList.add(screenItem); -} -#endif - // NOTE: Different version of SCI engine support different show styles // SCI2 implements 0, 1/3/5/7/9, 2/4/6/8/10, 11, 12, 13, 14 // SCI2.1 implements 0, 1/2/3/4/5/6/7/8/9/10/11/12/15, 13, 14 @@ -1547,53 +1275,15 @@ void GfxFrameout::processShowStyles() { case kShowStyleWipeLeft: case kShowStyleWipeUp: case kShowStyleIrisOut: -#if 0 - if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { -#endif - retval = processShowStyleMorph(showStyle); -#if 0 - } else { - retval = processShowStyleWipe(-1, showStyle); - } -#endif - break; case kShowStyleHShutterIn: case kShowStyleVShutterIn: case kShowStyleWipeRight: case kShowStyleWipeDown: case kShowStyleIrisIn: -#if 0 - if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { -#endif - retval = processShowStyleMorph(showStyle); -#if 0 - } else { - retval = processShowStyleWipe(1, showStyle); - } -#endif - break; case kShowStyle11: -#if 0 - if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { -#endif - retval = processShowStyleMorph(showStyle); -#if 0 - } else { - retval = processShowStyle11(showStyle); - } -#endif - break; case kShowStyle12: case kShowStyleUnknown: { -#if 0 - if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { -#endif - retval = processShowStyleMorph(showStyle); -#if 0 - } else { - retval = processShowStyle12(showStyle); - } -#endif + retval = processShowStyleMorph(showStyle); break; } case kShowStyleFadeOut: { @@ -1687,285 +1377,6 @@ bool GfxFrameout::processShowStyleFade(const int direction, ShowStyleEntry *cons return false; } -// TODO: Rect sizes are wrong, rects in SCI are inclusive of bottom/right but -// in ScummVM are exclusive so extra ±1 operations here are wrong -#if 0 -bool GfxFrameout::processShowStyleWipe(const ShowStyleEntry *const style) { - const int16 divisions = style->divisions; - Common::Rect rect(divisions, divisions); - - const Plane *const plane = _visibleScreen->planeList->findByObject(style->plane); - - const int16 planeLeft = plane->field_4C.left; - const int16 planeTop = plane->field_4C.top; - const int16 planeRight = plane->field_4C.right; - const int16 planeBottom = plane->field_4C.bottom; - const int16 planeWidth = planeRight - planeLeft + 1; - const int16 planeHeight = planeBottom - planeTop + 1; - - const int16 divisionWidth = planeWidth / divisions - 1; - int16 shutterDivisionWidth = planeWidth / (2 * divisions); - if (shutterDivisionWidth >= 0) { - const int16 heightPerDivision = planeHeight / divisions; - int16 shutterMiddleX = divisions * shutterDivisionWidth; - for (int16 x = divisionWidth - shutterDivisionWidth; x <= divisionWidth; ++x) { - int16 divisionTop = 0; - for (int16 y = 0; y < heightPerDivision; ++y, divisionTop += divisions) { - rect.top = planeTop + divisionTop; - rect.bottom = rect.top + divisions - 1; - rect.left = planeLeft + shutterMiddleX; - rect.right = rect.left + divisions - 1; - // _screen->rectList.clear(); - // _screen->rectList.add(rect); - // showBits(); - } - // number of divisions does not divide evenly into plane height, - // draw the remainder - if (planeHeight % divisions) { - rect.top = planeTop + divisionTop; - rect.bottom = rect.top + planeHeight % divisions - 1; - rect.left = planeLeft + shutterMiddleX; - rect.right = rect.left + divisions - 1; - // _screen->rectList.clear(); - // _screen->rectList.add(rect); - // showBits(); - } - - divisionTop = 0; - for (int16 y = 0; y < heightPerDivision; ++y, divisionTop += divisions) { - rect.top = planeTop + divisionTop; - rect.bottom = rect.top + divisions - 1; - rect.left = planeLeft + divisions * x; - rect.right = rect.left + divisions - 1; - // _screen->rectList.clear(); - // _screen->rectList.add(rect); - // showBits(); - } - if (planeHeight % divisions) { - rect.top = planeTop + divisionTop; - rect.bottom = rect.top + planeHeight % divisions - 1; - rect.left = planeLeft + divisions * x; - rect.right = rect.left + divisions - 1; - // _screen->rectList.clear(); - // _screen->rectList.add(rect); - // showBits(); - } - - shutterMiddleX -= divisions; - --shutterDivisionWidth; - } - } - - if (planeWidth % divisions) { - const int16 roundedPlaneWidth = divisions * divisionWidth; - int16 divisionTop = 0; - for (int16 y = 0; y < planeHeight / divisions; ++y, divisionTop += divisions) { - rect.top = planeTop + divisionTop; - rect.bottom = rect.top + divisions - 1; - rect.left = planeLeft + roundedPlaneWidth; - rect.right = rect.left + planeWidth % divisions + divisions - 1; - // _screen->rectList.clear(); - // _screen->rectList.add(rect); - // showBits(); - } - if (planeHeight % divisions) { - rect.top = planeTop + divisionTop; - rect.bottom = rect.top + planeHeight % divisions - 1; - rect.left = planeLeft + roundedPlaneWidth; - rect.right = rect.left + planeWidth % divisions + divisions - 1; - // _screen->rectList.clear(); - // _screen->rectList.add(rect); - // showBits(); - } - } - - rect.right = planeRight; - rect.left = planeLeft; - rect.top = planeTop; - rect.bottom = planeBottom; - // _screen->rectList.clear(); - // _screen->rectList.add(rect); - // showBits(); -} -#endif -#if 0 -bool GfxFrameout::processShowStyleWipe(const int direction, ShowStyleEntry *const showStyle) { - if (showStyle->currentStep < showStyle->divisions) { - int index; - if (direction <= 0) { - index = showStyle->divisions - showStyle->currentStep - 1; - } else { - index = showStyle->currentStep; - } - - index *= showStyle->edgeCount; - - if (showStyle->edgeCount > 0) { - for (int i = 0; i < showStyle->edgeCount; ++i) { - if (showStyle->fadeUp) { - ScreenItem *screenItem = showStyle->screenItems[index + i]; - if (screenItem != nullptr) { - // TODO: _screen->deleteScreenItem(screenItem); - _screenItems.remove(screenItem); - - delete screenItem; - showStyle->screenItems[index + i] = nullptr; - } - } else { - ScreenItem *screenItem = showStyle->screenItems[index + i]; - // TODO: _screen->addScreenItem(screenItem); - _screenItems.push_back(screenItem); - } - } - - ++showStyle->currentStep; - showStyle->nextTick += showStyle->delay; - } - } - - if (showStyle->currentStep >= showStyle->divisions) { - if (showStyle->fadeUp) { - showStyle->processed = true; - } - - return true; - } - - return false; -} - -void fillRect(byte *data, const Common::Rect &rect, const int16 color, const int16 stride) { - -} - -bool GfxFrameout::processShowStyle11(ShowStyleEntry *const showStyle) { - int divisions = showStyle->divisions * showStyle->divisions; - - byte *bitmapData = _segMan->getHunkPointer(showStyle->bitmapMemId) + sizeof(GfxBitmapHeader); - - int ebx; - - if (showStyle->currentStep == 0) { - int ctr = 0; - int bloot = divisions; - do { - bloot >>= 1; - ++ctr; - } while (bloot != 1); - - showStyle->dissolveSeed = _dissolveSequenceSeeds[ctr]; - ebx = 800; - showStyle->unknown3A = 800; - showStyle->dissolveInitial = 800; - } else { - int ebx = showStyle->unknown3A; - do { - int eax = ebx >> 1; - if (ebx & 1) { - ebx = showStyle->dissolveSeed ^ eax; - } else { - ebx = eax; - } - } while (ebx >= divisions); - - if (ebx == showStyle->dissolveInitial) { - ebx = 0; - } - } - - Common::Rect rect; - - rect.left = (showStyle->width + showStyle->divisions - 1) / showStyle->divisions; - rect.top = (showStyle->height + showStyle->divisions - 1) / showStyle->divisions; - - if (showStyle->currentStep <= showStyle->divisions) { - int ebp = 0; - do { - int ecx = ebx % showStyle->divisions; - - Common::Rect drawRect; - drawRect.left = rect.left * ecx; - drawRect.right = drawRect.left + rect.left - 1; - drawRect.top = rect.top * ebx; - drawRect.bottom = rect.top * ebx + rect.top - 1; - - bool doit; - if (drawRect.right >= 0 && drawRect.bottom >= 0 && drawRect.left <= rect.right && drawRect.top <= rect.bottom) { - doit = true; - } else { - doit = false; - } - - if (doit) { - if (drawRect.left < 0) { - drawRect.left = 0; - } - - if (drawRect.top < 0) { - drawRect.top = 0; - } - - if (drawRect.right > rect.right) { - drawRect.right = rect.right; - } - - if (drawRect.bottom > rect.bottom) { - drawRect.bottom = rect.bottom; - } - } else { - drawRect.right = 0; - drawRect.bottom = 0; - drawRect.left = 0; - drawRect.top = 0; - } - - fillRect(bitmapData, drawRect, showStyle->color, showStyle->width); - - int eax = ebx; - do { - eax >>= 1; - if (ebx & 1) { - ebx = showStyle->dissolveSeed; - ebx ^= eax; - } else { - ebx = eax; - } - } while (ebx >= divisions); - - if (showStyle->currentStep != showStyle->divisions) { - ebp++; - } else { - drawRect.left = 0; - drawRect.top = 0; - drawRect.right = showStyle->width - 1; - drawRect.bottom = showStyle->height - 1; - fillRect(bitmapData, drawRect, showStyle->color, showStyle->width); - } - - } while (ebp <= showStyle->divisions); - - showStyle->unknown3A = ebx; - ++showStyle->currentStep; - showStyle->nextTick += showStyle->delay; - // _screen->updateScreenItem(showStyle->bitmapScreenItem); - } - - if (showStyle->currentStep >= showStyle->divisions) { - if (showStyle->fadeUp) { - showStyle->processed = true; - } - - return true; - } - - return false; -} - -bool GfxFrameout::processShowStyle12(ShowStyleEntry *const showStyle) { - return true; -} -#endif - void GfxFrameout::kernelFrameOut(const bool shouldShowBits) { if (_showStyles != nullptr) { processShowStyles(); @@ -1974,8 +1385,8 @@ void GfxFrameout::kernelFrameOut(const bool shouldShowBits) { _palMorphIsOn = false; } else { // TODO: Window scroll -// if (g_ScrollWindow) { -// doScroll(); +// if (g_PlaneScroll) { +// processScrolls(); // } frameOut(shouldShowBits); @@ -1986,7 +1397,7 @@ void GfxFrameout::kernelFrameOut(const bool shouldShowBits) { #pragma mark Mouse cursor reg_t GfxFrameout::kernelIsOnMe(const reg_t object, const Common::Point &position, bool checkPixel) const { - reg_t planeObject = readSelector(_segMan, object, SELECTOR(plane)); + const reg_t planeObject = readSelector(_segMan, object, SELECTOR(plane)); Plane *plane = _visiblePlanes.findByObject(planeObject); if (plane == nullptr) { return make_reg(0, 0); @@ -1997,6 +1408,13 @@ reg_t GfxFrameout::kernelIsOnMe(const reg_t object, const Common::Point &positio return make_reg(0, 0); } + // NOTE: The original engine passed a copy of the ScreenItem into isOnMe + // as a hack around the fact that the screen items in `_visiblePlanes` + // did not have their `_celObj` pointers cleared when their CelInfo was + // updated by `Plane::decrementScreenItemArrayCounts`. We handle this + // this more intelligently by clearing `_celObj` in the copy assignment + // operator, which is only ever called by `decrementScreenItemArrayCounts` + // anyway. return make_reg(0, isOnMe(*screenItem, *plane, position, checkPixel)); } @@ -2053,6 +1471,13 @@ void GfxFrameout::kernelSetNowSeen(const reg_t screenItemObject) const { writeSelectorValue(_segMan, screenItemObject, SELECTOR(nsBottom), result.bottom - 1); } +void GfxFrameout::remapMarkRedraw() { + for (PlaneList::const_iterator it = _planes.begin(); it != _planes.end(); ++it) { + Plane *p = *it; + p->remapMarkRedraw(); + } +} + #pragma mark - #pragma mark Debugging diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index 22c0e14829..8ed95a00de 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -130,64 +130,6 @@ struct ShowStyleEntry { bool processed; // - // Engine-specific properties for SCI2 through 2.1early - // - - // TODO: Could union this stuff to save literally - // several bytes of memory. - - /** - * The width of the plane. Used to determine the correct - * size of screen items for wipes. - */ - int width; - - /** - * The height of the plane. Used to determine the correct - * size of screen items for wipes. - */ - int height; - - /** - * The number of edges that a transition operates on. - * Slide wipe: 1 edge - * Reveal wipe: 2 edges - * Iris wipe: 4 edges - */ - // TODO: I have no idea why SCI engine stores this instead - // of a screenItems count - int edgeCount; - - /** - * Used by transition types 1 through 10. - * One screen item per division per edge. - */ - ScreenItemList screenItems; - - /** - * Used by transition types 11 and 12. A copy of the - * visible frame buffer. - */ - // TODO: This is a reg_t in SCI engine; not sure if - // we can avoid allocation through SegMan or not. - reg_t bitmapMemId; - - /** - * Used by transition types 11 and 12. A screen item - * used to display the associated bitmap data. - */ - ScreenItem *bitmapScreenItem; - - /** - * A number used to pick pixels to dissolve by types - * 11 and 12. - */ - int dissolveSeed; - int unknown3A; - // max? - int dissolveInitial; - - // // Engine specific properties for SCI2.1mid through SCI3 // @@ -240,6 +182,7 @@ public: #pragma mark Screen items private: void deleteScreenItem(ScreenItem *screenItem, const reg_t plane); + void remapMarkRedraw(); public: void kernelAddScreenItem(const reg_t object); @@ -325,14 +268,11 @@ private: bool processShowStyleNone(ShowStyleEntry *showStyle); bool processShowStyleMorph(ShowStyleEntry *showStyle); bool processShowStyleFade(const int direction, ShowStyleEntry *showStyle); -#if 0 - bool processShowStyleWipe(const int direction, ShowStyleEntry *const showStyle); -#endif public: // NOTE: This signature is taken from SCI3 Phantasmagoria 2 // and is valid for all implementations of SCI32 - void kernelSetShowStyle(const uint16 argc, const reg_t &planeObj, const ShowStyleType type, const int16 seconds, const int16 direction, const int16 priority, const int16 animate, const int16 frameOutNow, const reg_t &pFadeArray, const int16 divisions, const int16 blackScreen); + void kernelSetShowStyle(const uint16 argc, const reg_t planeObj, const ShowStyleType type, const int16 seconds, const int16 direction, const int16 priority, const int16 animate, const int16 frameOutNow, reg_t pFadeArray, int16 divisions, const int16 blackScreen); #pragma mark - #pragma mark Rendering @@ -351,13 +291,6 @@ private: */ Buffer _currentBuffer; - // TODO: In SCI2.1/SQ6, priority map pixels are not allocated - // by default. In SCI2/GK1, pixels are allocated, but not used - // anywhere except within CelObj::Draw in seemingly the same - // way they are used in SCI2.1/SQ6: that is, never read, only - // written. - Buffer _priorityMap; - /** * TODO: Documentation */ @@ -456,12 +389,6 @@ private: public: /** - * TODO: Document - * This is used by CelObj::Draw. - */ - bool _hasRemappedScreenItem; - - /** * Whether palMorphFrameOut should be used instead of * frameOut for rendering. Used by kMorphOn to * explicitly enable palMorphFrameOut for one frame. @@ -487,11 +414,6 @@ public: */ void alterVmap(const Palette &palette1, const Palette &palette2, const int8 style, const int8 *const styleRanges); - // TODO: SCI2 engine never uses priority map? - inline Buffer &getPriorityMap() { - return _priorityMap; - } - // NOTE: This function is used within ScreenItem subsystem and assigned // to various booleanish fields that seem to represent the state of the // screen item (created, updated, deleted). In GK1/DOS, Phant1/m68k, diff --git a/engines/sci/graphics/plane32.cpp b/engines/sci/graphics/plane32.cpp index 099d4dd8c4..d05e4f79e1 100644 --- a/engines/sci/graphics/plane32.cpp +++ b/engines/sci/graphics/plane32.cpp @@ -27,6 +27,7 @@ #include "sci/graphics/frameout.h" #include "sci/graphics/lists32.h" #include "sci/graphics/plane32.h" +#include "sci/graphics/remap.h" #include "sci/graphics/screen.h" #include "sci/graphics/screen_item32.h" @@ -317,7 +318,7 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList vitem != nullptr && !vitem->_screenRect.isEmpty() ) { - if (/* TODO: g_Remap_numActiveRemaps */ false) { // active remaps? + if (g_sci->_gfxRemap32->getRemapCount()) { mergeToRectList(vitem->_screenRect, eraseList); } else { eraseList.add(vitem->_screenRect); @@ -328,7 +329,7 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList item->calcRects(*this); if(!item->_screenRect.isEmpty()) { - if (/* TODO: g_Remap_numActiveRemaps */ false) { // active remaps? + if (g_sci->_gfxRemap32->getRemapCount()) { drawList.add(item, item->_screenRect); mergeToRectList(item->_screenRect, eraseList); } else { @@ -338,7 +339,7 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList } else if (item->_updated) { // add old rect to erase list, new item to draw list item->calcRects(*this); - if (/* TODO: g_Remap_numActiveRemaps */ false) { // active remaps + if (g_sci->_gfxRemap32->getRemapCount()) { // if item and vitem don't overlap, ... if (item->_screenRect.isEmpty() || i >= visiblePlaneItemCount || @@ -395,7 +396,6 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList // over the currently inserted entries later. DrawList::size_type drawListSizePrimary = drawList.size(); - // NOTE: Setting this to true fixes the menu bars in GK1 if (/* TODO: dword_C6288 */ false) { // "high resolution pictures"???? _screenItemList.sort(); bool encounteredPic = false; @@ -453,7 +453,7 @@ void Plane::calcLists(Plane &visiblePlane, const PlaneList &planeList, DrawList } } - if (/* TODO: g_Remap_numActiveRemaps == 0 */ true) { // no remaps active? + if (g_sci->_gfxRemap32->getRemapCount() == 0) { // no remaps active? // Add all items that overlap with items in the drawlist and have higher // priority. @@ -812,6 +812,17 @@ void Plane::scrollScreenItems(const int16 deltaX, const int16 deltaY, const bool } } +void Plane::remapMarkRedraw() { + for (ScreenItemList::const_iterator screenItemPtr = _screenItemList.begin(); screenItemPtr != _screenItemList.end(); ++screenItemPtr) { + if (*screenItemPtr != nullptr) { + ScreenItem &screenItem = **screenItemPtr; + if (screenItem.getCelObj()._remap && !screenItem._deleted && !screenItem._created) { + screenItem._updated = g_sci->_gfxFrameout->getScreenCount(); + } + } + } +} + #pragma mark - #pragma mark PlaneList void PlaneList::add(Plane *plane) { diff --git a/engines/sci/graphics/plane32.h b/engines/sci/graphics/plane32.h index 51d93b78a5..770a6fa445 100644 --- a/engines/sci/graphics/plane32.h +++ b/engines/sci/graphics/plane32.h @@ -166,7 +166,7 @@ public: * another plane and cleared when draw list calculation * occurs. */ - int _priorityChanged; // ? + int _priorityChanged; /** * A handle to the VM object corresponding to this @@ -182,7 +182,12 @@ public: int16 _priority; /** - * TODO: Document + * Whether or not all screen items in this plane should + * be redrawn on the next frameout, instead of just + * the screen items marked as updated. This is set when + * visual changes to the plane itself are made that + * affect the rendering of the entire plane, and cleared + * once those changes are rendered by `redrawAll`. */ int _redrawAllCount; @@ -430,6 +435,8 @@ public: * and adds them to the given draw and erase lists. */ void redrawAll(Plane *visiblePlane, const PlaneList &planeList, DrawList &drawList, RectList &eraseList); + + void remapMarkRedraw(); }; #pragma mark - diff --git a/engines/sci/graphics/remap.cpp b/engines/sci/graphics/remap.cpp index 999cfc7753..e331eaf971 100644 --- a/engines/sci/graphics/remap.cpp +++ b/engines/sci/graphics/remap.cpp @@ -32,8 +32,8 @@ namespace Sci { #pragma mark - #pragma mark SCI16 remapping (QFG4 demo) -GfxRemap::GfxRemap(GfxScreen *screen, GfxPalette *palette) - : _screen(screen), _palette(palette) { +GfxRemap::GfxRemap(GfxPalette *palette) + : _palette(palette) { _remapOn = false; resetRemapping(); } @@ -174,6 +174,21 @@ void GfxRemap32::setNoMatchRange(byte from, byte count) { _noMapCount = count; } +bool GfxRemap32::remapEnabled(byte color) const { + assert(_remapEndColor - color >= 0 && _remapEndColor - color < REMAP_COLOR_COUNT); + const byte index = _remapEndColor - color; + return (_remaps[index].type != kRemappingNone); +} + +byte GfxRemap32::remapColor(byte color, byte target) { + assert(_remapEndColor - color >= 0 && _remapEndColor - color < REMAP_COLOR_COUNT); + const byte index = _remapEndColor - color; + if (_remaps[index].type != kRemappingNone) + return _remaps[index].remap[target]; + else + return target; +} + void GfxRemap32::initColorArrays(byte index) { Palette *curPalette = &_palette->_sysPalette; RemapParams *curRemap = &_remaps[index]; diff --git a/engines/sci/graphics/remap.h b/engines/sci/graphics/remap.h index cce48ec533..d012568f7f 100644 --- a/engines/sci/graphics/remap.h +++ b/engines/sci/graphics/remap.h @@ -46,7 +46,7 @@ enum ColorRemappingType { */ class GfxRemap { public: - GfxRemap(GfxScreen *screen, GfxPalette *_palette); + GfxRemap(GfxPalette *_palette); ~GfxRemap(); void resetRemapping(); @@ -128,9 +128,12 @@ public: void setRemappingToGray(byte color, byte gray); void setRemappingToPercentGray(byte color, byte gray, byte percent); void setNoMatchRange(byte from, byte count); + bool remapEnabled(byte color) const; + byte remapColor(byte color, byte target); bool remapAllTables(bool palChanged); int getRemapCount() const { return _remapCount; } - + int getStartColor() const { return _remapEndColor - REMAP_COLOR_COUNT + 1; } + int getEndColor() const { return _remapEndColor; } private: GfxPalette32 *_palette; RemapParams _remaps[REMAP_COLOR_COUNT]; diff --git a/engines/sci/graphics/screen_item32.cpp b/engines/sci/graphics/screen_item32.cpp index 41771c802c..c3fdbb6845 100644 --- a/engines/sci/graphics/screen_item32.cpp +++ b/engines/sci/graphics/screen_item32.cpp @@ -115,7 +115,17 @@ _screenRect(other._screenRect) { } void ScreenItem::operator=(const ScreenItem &other) { - _celInfo = other._celInfo; + // NOTE: The original engine did not check for differences in `_celInfo` + // to clear `_celObj` here; instead, it unconditionally set `_celInfo`, + // didn't clear `_celObj`, and did hacky stuff in `kIsOnMe` to avoid + // testing a mismatched `_celObj`. See `GfxFrameout::kernelIsOnMe` for + // more detail. + if (_celInfo != other._celInfo) { + _celInfo = other._celInfo; + delete _celObj; + _celObj = nullptr; + } + _screenRect = other._screenRect; _mirrorX = other._mirrorX; _useInsetRect = other._useInsetRect; @@ -241,28 +251,33 @@ void ScreenItem::calcRects(const Plane &plane) { _insetRect = celRect; } - Ratio newRatioX; - Ratio newRatioY; + Ratio scaleX, scaleY; if (_scale.signal & kScaleSignalDoScaling32) { if (_scale.signal & kScaleSignalUseVanishingPoint) { int num = _scale.max * (_position.y - plane._vanishingPoint.y) / (scriptWidth - plane._vanishingPoint.y); - newRatioX = Ratio(num, 128); - newRatioY = Ratio(num, 128); + scaleX = Ratio(num, 128); + scaleY = Ratio(num, 128); } else { - newRatioX = Ratio(_scale.x, 128); - newRatioY = Ratio(_scale.y, 128); + scaleX = Ratio(_scale.x, 128); + scaleY = Ratio(_scale.y, 128); } } - if (newRatioX.getNumerator() && newRatioY.getNumerator()) { + if (scaleX.getNumerator() && scaleY.getNumerator()) { _screenItemRect = _insetRect; + const Ratio celToScreenX(screenWidth, celObj._scaledWidth); + const Ratio celToScreenY(screenHeight, celObj._scaledHeight); + + // Cel may use a coordinate system that is not the same size as the + // script coordinate system (usually this means high-resolution + // pictures with low-resolution scripts) if (celObj._scaledWidth != scriptWidth || celObj._scaledHeight != scriptHeight) { if (_useInsetRect) { - Ratio celScriptXRatio(celObj._scaledWidth, scriptWidth); - Ratio celScriptYRatio(celObj._scaledHeight, scriptHeight); - mulru(_screenItemRect, celScriptXRatio, celScriptYRatio, 0); + const Ratio scriptToCelX(celObj._scaledWidth, scriptWidth); + const Ratio scriptToCelY(celObj._scaledHeight, scriptHeight); + mulru(_screenItemRect, scriptToCelX, scriptToCelY, 0); if (_screenItemRect.intersects(celRect)) { _screenItemRect.clip(celRect); @@ -278,26 +293,25 @@ void ScreenItem::calcRects(const Plane &plane) { displaceX = celObj._width - celObj._displace.x - 1; } - if (!newRatioX.isOne() || !newRatioY.isOne()) { - mulinc(_screenItemRect, newRatioX, newRatioY); - displaceX = (displaceX * newRatioX).toInt(); - displaceY = (displaceY * newRatioY).toInt(); + if (!scaleX.isOne() || !scaleY.isOne()) { + mulinc(_screenItemRect, scaleX, scaleY); + displaceX = (displaceX * scaleX).toInt(); + displaceY = (displaceY * scaleY).toInt(); } - Ratio celXRatio(screenWidth, celObj._scaledWidth); - Ratio celYRatio(screenHeight, celObj._scaledHeight); - - displaceX = (displaceX * celXRatio).toInt(); - displaceY = (displaceY * celYRatio).toInt(); + mulinc(_screenItemRect, celToScreenX, celToScreenY); + displaceX = (displaceX * celToScreenX).toInt(); + displaceY = (displaceY * celToScreenY).toInt(); - mulinc(_screenItemRect, celXRatio, celYRatio); + const Ratio scriptToScreenX = Ratio(screenWidth, scriptWidth); + const Ratio scriptToScreenY = Ratio(screenHeight, scriptHeight); if (/* TODO: dword_C6288 */ false && _celInfo.type == kCelTypePic) { _scaledPosition.x = _position.x; _scaledPosition.y = _position.y; } else { - _scaledPosition.x = (_position.x * screenWidth / scriptWidth) - displaceX; - _scaledPosition.y = (_position.y * screenHeight / scriptHeight) - displaceY; + _scaledPosition.x = (_position.x * scriptToScreenX).toInt() - displaceX; + _scaledPosition.y = (_position.y * scriptToScreenY).toInt() - displaceY; } _screenItemRect.translate(_scaledPosition.x, _scaledPosition.y); @@ -305,14 +319,14 @@ void ScreenItem::calcRects(const Plane &plane) { if (_mirrorX != celObj._mirrorX && _celInfo.type == kCelTypePic) { Common::Rect temp(_insetRect); - if (!newRatioX.isOne()) { - mulinc(temp, newRatioX, Ratio()); + if (!scaleX.isOne()) { + mulinc(temp, scaleX, Ratio()); } - mulinc(temp, celXRatio, Ratio()); + mulinc(temp, celToScreenX, Ratio()); CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj); - temp.translate(celObjPic->_relativePosition.x * screenWidth / scriptWidth - displaceX, 0); + temp.translate((celObjPic->_relativePosition.x * scriptToScreenX).toInt() - displaceX, 0); // TODO: This is weird. int deltaX = plane._planeRect.width() - temp.right - 1 - temp.left; @@ -325,16 +339,16 @@ void ScreenItem::calcRects(const Plane &plane) { _scaledPosition.y += plane._planeRect.top; _screenItemRect.translate(plane._planeRect.left, plane._planeRect.top); - _ratioX = newRatioX * Ratio(screenWidth, celObj._scaledWidth); - _ratioY = newRatioY * Ratio(screenHeight, celObj._scaledHeight); + _ratioX = scaleX * celToScreenX; + _ratioY = scaleY * celToScreenY; } else { int displaceX = celObj._displace.x; if (_mirrorX != celObj._mirrorX && _celInfo.type != kCelTypePic) { displaceX = celObj._width - celObj._displace.x - 1; } - if (!newRatioX.isOne() || !newRatioY.isOne()) { - mulinc(_screenItemRect, newRatioX, newRatioY); + if (!scaleX.isOne() || !scaleY.isOne()) { + mulinc(_screenItemRect, scaleX, scaleY); // TODO: This was in the original code, baked into the // multiplication though it is not immediately clear // why this is the only one that reduces the BR corner @@ -342,20 +356,20 @@ void ScreenItem::calcRects(const Plane &plane) { _screenItemRect.bottom -= 1; } - _scaledPosition.x = _position.x - (displaceX * newRatioX).toInt(); - _scaledPosition.y = _position.y - (celObj._displace.y * newRatioY).toInt(); + _scaledPosition.x = _position.x - (displaceX * scaleX).toInt(); + _scaledPosition.y = _position.y - (celObj._displace.y * scaleY).toInt(); _screenItemRect.translate(_scaledPosition.x, _scaledPosition.y); if (_mirrorX != celObj._mirrorX && _celInfo.type == kCelTypePic) { Common::Rect temp(_insetRect); - if (!newRatioX.isOne()) { - mulinc(temp, newRatioX, Ratio()); + if (!scaleX.isOne()) { + mulinc(temp, scaleX, Ratio()); temp.right -= 1; } CelObjPic *celObjPic = dynamic_cast<CelObjPic *>(_celObj); - temp.translate(celObjPic->_relativePosition.x - (displaceX * newRatioX).toInt(), celObjPic->_relativePosition.y - (celObj._displace.y * newRatioY).toInt()); + temp.translate(celObjPic->_relativePosition.x - (displaceX * scaleX).toInt(), celObjPic->_relativePosition.y - (celObj._displace.y * scaleY).toInt()); // TODO: This is weird. int deltaX = plane._gameRect.width() - temp.right - 1 - temp.left; @@ -368,15 +382,13 @@ void ScreenItem::calcRects(const Plane &plane) { _scaledPosition.y += plane._gameRect.top; _screenItemRect.translate(plane._gameRect.left, plane._gameRect.top); - if (screenWidth != celObj._scaledWidth || celObj._scaledHeight != screenHeight) { - Ratio celXRatio(screenWidth, celObj._scaledWidth); - Ratio celYRatio(screenHeight, celObj._scaledHeight); - mulru(_scaledPosition, celXRatio, celYRatio); - mulru(_screenItemRect, celXRatio, celYRatio, 1); + if (celObj._scaledWidth != screenWidth || celObj._scaledHeight != screenHeight) { + mulru(_scaledPosition, celToScreenX, celToScreenY); + mulru(_screenItemRect, celToScreenX, celToScreenY, 1); } - _ratioX = newRatioX * Ratio(screenWidth, celObj._scaledWidth); - _ratioY = newRatioY * Ratio(screenHeight, celObj._scaledHeight); + _ratioX = scaleX * celToScreenX; + _ratioY = scaleY * celToScreenY; } _screenRect = _screenItemRect; @@ -547,9 +559,9 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const { if (celObj._scaledWidth != scriptWidth || celObj._scaledHeight != scriptHeight) { if (_useInsetRect) { - Ratio scriptToScaledX(celObj._scaledWidth, scriptWidth); - Ratio scriptToScaledY(celObj._scaledHeight, scriptHeight); - mulru(nsRect, scriptToScaledX, scriptToScaledY, 0); + Ratio scriptToCelX(celObj._scaledWidth, scriptWidth); + Ratio scriptToCelY(celObj._scaledHeight, scriptHeight); + mulru(nsRect, scriptToCelX, scriptToCelY, 0); // TODO: This is weird. Checking to see if the inset rect is // fully inside the bounds of the celObjRect, and then @@ -570,13 +582,13 @@ Common::Rect ScreenItem::getNowSeenRect(const Plane &plane) const { nsRect.bottom -= 1; } - Ratio scaledToScriptX(scriptWidth, celObj._scaledWidth); - Ratio scaledToScriptY(scriptHeight, celObj._scaledHeight); + Ratio celToScriptX(scriptWidth, celObj._scaledWidth); + Ratio celToScriptY(scriptHeight, celObj._scaledHeight); - displaceX = (displaceX * scaleX * scaledToScriptX).toInt(); - displaceY = (displaceY * scaleY * scaledToScriptY).toInt(); + displaceX = (displaceX * scaleX * celToScriptX).toInt(); + displaceY = (displaceY * scaleY * celToScriptY).toInt(); - mulinc(nsRect, scaledToScriptX, scaledToScriptY); + mulinc(nsRect, celToScriptX, celToScriptY); nsRect.translate(_position.x - displaceX, _position.y - displaceY); } else { if (!scaleX.isOne() || !scaleY.isOne()) { diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp index ff3fc70619..1939e66179 100644 --- a/engines/sci/graphics/view.cpp +++ b/engines/sci/graphics/view.cpp @@ -975,13 +975,4 @@ void GfxView::adjustBackUpscaledCoordinates(int16 &y, int16 &x) { _screen->adjustBackUpscaledCoordinates(y, x, _sci2ScaleRes); } -byte GfxView::getColorAtCoordinate(int16 loopNo, int16 celNo, int16 x, int16 y) { - const CelInfo *celInfo = getCelInfo(loopNo, celNo); - const byte *bitmap = getBitmap(loopNo, celNo); - const int16 celWidth = celInfo->width; - - bitmap += (celWidth * y); - return bitmap[x]; -} - } // End of namespace Sci diff --git a/engines/sci/graphics/view.h b/engines/sci/graphics/view.h index d8803db208..91590208c1 100644 --- a/engines/sci/graphics/view.h +++ b/engines/sci/graphics/view.h @@ -85,8 +85,6 @@ public: void adjustToUpscaledCoordinates(int16 &y, int16 &x); void adjustBackUpscaledCoordinates(int16 &y, int16 &x); - byte getColorAtCoordinate(int16 loopNo, int16 celNo, int16 x, int16 y); - private: void initData(GuiResourceId resourceId); void unpackCel(int16 loopNo, int16 celNo, byte *outPtr, uint32 pixelCount); diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index f5ad048dba..e14d12b918 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -689,7 +689,7 @@ void SciEngine::initGraphics() { #endif _gfxPalette16 = new GfxPalette(_resMan, _gfxScreen); if (getGameId() == GID_QFG4DEMO) - _gfxRemap16 = new GfxRemap(_gfxScreen, _gfxPalette16); + _gfxRemap16 = new GfxRemap(_gfxPalette16); #ifdef ENABLE_SCI32 } #endif diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 2474db81d9..7df3d38163 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -206,8 +206,8 @@ enum SciVersion { SCI_VERSION_1_LATE, // Dr. Brain 1, EcoQuest 1, Longbow, PQ3, SQ1, LSL5, KQ5 CD SCI_VERSION_1_1, // Dr. Brain 2, EcoQuest 1 CD, EcoQuest 2, KQ6, QFG3, SQ4CD, XMAS 1992 and many more SCI_VERSION_2, // GK1, PQ4 floppy, QFG4 floppy - SCI_VERSION_2_1_EARLY, // GK2 demo, KQ7, LSL6 hires, PQ4, QFG4 floppy - SCI_VERSION_2_1_MIDDLE, // GK2, KQ7, MUMG Deluxe, Phantasmagoria 1, PQ4CD, PQ:SWAT, QFG4CD, Shivers 1, SQ6, Torin + SCI_VERSION_2_1_EARLY, // GK2 demo, KQ7 1.4/1.51, LSL6 hires, PQ4CD, QFG4 floppy + SCI_VERSION_2_1_MIDDLE, // GK2, KQ7 2.00b, MUMG Deluxe, Phantasmagoria 1, PQ:SWAT, QFG4CD, Shivers 1, SQ6, Torin SCI_VERSION_2_1_LATE, // demos of LSL7, Lighthouse, RAMA SCI_VERSION_3 // LSL7, Lighthouse, RAMA, Phantasmagoria 2 }; diff --git a/engines/scumm/players/player_ad.cpp b/engines/scumm/players/player_ad.cpp index 4d4be2c3c2..55bbeeef98 100644 --- a/engines/scumm/players/player_ad.cpp +++ b/engines/scumm/players/player_ad.cpp @@ -50,7 +50,7 @@ Player_AD::Player_AD(ScummEngine *scumm) writeReg(0x01, 0x20); _engineMusicTimer = 0; - _soundPlaying = -1; + _musicResource = -1; _curOffset = 0; @@ -104,8 +104,8 @@ void Player_AD::startSound(int sound) { stopMusic(); // Lock the new music resource - _soundPlaying = sound; - _vm->_res->lock(rtSound, _soundPlaying); + _musicResource = sound; + _vm->_res->lock(rtSound, _musicResource); // Start the new music resource _musicData = res; @@ -150,7 +150,7 @@ void Player_AD::startSound(int sound) { void Player_AD::stopSound(int sound) { Common::StackLock lock(_mutex); - if (sound == _soundPlaying) { + if (sound == _musicResource) { stopMusic(); } else { for (int i = 0; i < ARRAYSIZE(_sfx); ++i) { @@ -178,7 +178,17 @@ int Player_AD::getMusicTimer() { } int Player_AD::getSoundStatus(int sound) const { - return (sound == _soundPlaying); + if (sound == _musicResource) { + return true; + } + + for (int i = 0; i < ARRAYSIZE(_sfx); ++i) { + if (_sfx[i].resource == sound) { + return true; + } + } + + return false; } void Player_AD::saveLoadWithSerializer(Serializer *ser) { @@ -193,7 +203,7 @@ void Player_AD::saveLoadWithSerializer(Serializer *ser) { if (ser->getVersion() >= VER(96)) { int32 res[4] = { - _soundPlaying, _sfx[0].resource, _sfx[1].resource, _sfx[2].resource + _musicResource, _sfx[0].resource, _sfx[1].resource, _sfx[2].resource }; // The first thing we save is a list of sound resources being played @@ -461,13 +471,13 @@ void Player_AD::startMusic() { } void Player_AD::stopMusic() { - if (_soundPlaying == -1) { + if (_musicResource == -1) { return; } // Unlock the music resource if present - _vm->_res->unlock(rtSound, _soundPlaying); - _soundPlaying = -1; + _vm->_res->unlock(rtSound, _musicResource); + _musicResource = -1; // Stop the music playback _curOffset = 0; @@ -510,7 +520,7 @@ void Player_AD::updateMusic() { // important to note that we need to parse a command directly // at the new position, i.e. there is no time value we need to // parse. - if (_soundPlaying == -1) { + if (_musicResource == -1) { return; } else { continue; diff --git a/engines/scumm/players/player_ad.h b/engines/scumm/players/player_ad.h index 63fda3cc7c..9cd1a06261 100644 --- a/engines/scumm/players/player_ad.h +++ b/engines/scumm/players/player_ad.h @@ -68,7 +68,7 @@ private: OPL::OPL *_opl2; - int _soundPlaying; + int _musicResource; int32 _engineMusicTimer; struct SfxSlot; diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 681e71d0f6..4442c1da85 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -23,6 +23,8 @@ #include "sherlock/animation.h" #include "sherlock/sherlock.h" #include "sherlock/scalpel/scalpel_screen.h" +#include "sherlock/scalpel/3do/scalpel_3do_screen.h" + #include "common/algorithm.h" namespace Sherlock { @@ -89,7 +91,7 @@ bool Animation::play(const Common::String &filename, bool intro, int minDelay, i // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame, // since we don't want the offsets in the image file to be used, just the explicit position we specify - screen.transBlitFrom(images[imageFrame]._frame, pt); + screen.SHtransBlitFrom(images[imageFrame]._frame, pt); } else { // At this point, either the sprites for the frame has been complete, or there weren't any sprites // at all to draw for the frame @@ -201,7 +203,7 @@ bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame, // since we don't want the offsets in the image file to be used, just the explicit position we specify - screen._backBuffer1.transBlitFrom(images[imageFrame]._frame, pt); + screen._backBuffer1.SHtransBlitFrom(images[imageFrame]._frame, pt); if (!fadeActive) screen.slamArea(pt.x, pt.y, images[imageFrame]._frame.w, images[imageFrame]._frame.h); } else { diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index 4b0b7dfb3f..6cfee5d822 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -143,7 +143,7 @@ void Events::setCursor(CursorId cursorId, const Common::Point &cursorPos, const // Form a single surface containing both frames Surface s(r.width(), r.height()); - s.fill(TRANSPARENCY); + s.clear(TRANSPARENCY); // Draw the passed image Common::Point drawPos; @@ -151,11 +151,11 @@ void Events::setCursor(CursorId cursorId, const Common::Point &cursorPos, const drawPos.x = -cursorPt.x; if (cursorPt.y < 0) drawPos.y = -cursorPt.y; - s.blitFrom(surface, Common::Point(drawPos.x, drawPos.y)); + s.SHblitFrom(surface, Common::Point(drawPos.x, drawPos.y)); // Draw the cursor image drawPos = Common::Point(MAX(cursorPt.x, (int16)0), MAX(cursorPt.y, (int16)0)); - s.transBlitFrom(cursorImg, Common::Point(drawPos.x, drawPos.y)); + s.SHtransBlitFrom(cursorImg, Common::Point(drawPos.x, drawPos.y)); // Set up hotspot position for cursor, adjusting for cursor image's position within the surface Common::Point hotspot; @@ -163,7 +163,7 @@ void Events::setCursor(CursorId cursorId, const Common::Point &cursorPos, const hotspot = Common::Point(8, 8); hotspot += drawPos; // Set the cursor - setCursor(s.getRawSurface(), hotspot.x, hotspot.y); + setCursor(s, hotspot.x, hotspot.y); } void Events::animateCursorIfNeeded() { diff --git a/engines/sherlock/fonts.cpp b/engines/sherlock/fonts.cpp index 8e36c3908a..5a14881f1c 100644 --- a/engines/sherlock/fonts.cpp +++ b/engines/sherlock/fonts.cpp @@ -43,7 +43,7 @@ void Fonts::setVm(SherlockEngine *vm) { _charCount = 0; } -void Fonts::free() { +void Fonts::freeFont() { delete _font; } @@ -213,7 +213,7 @@ void Fonts::writeString(Surface *surface, const Common::String &str, if (curChar < _charCount) { ImageFrame &frame = (*_font)[curChar]; - surface->transBlitFrom(frame, Common::Point(charPos.x, charPos.y + _yOffsets[curChar]), false, overrideColor); + surface->SHtransBlitFrom(frame, Common::Point(charPos.x, charPos.y + _yOffsets[curChar]), false, overrideColor); charPos.x += frame._frame.w + 1; } else { warning("Invalid character encountered - %d", (int)curChar); diff --git a/engines/sherlock/fonts.h b/engines/sherlock/fonts.h index a527cc73c0..3594d466c2 100644 --- a/engines/sherlock/fonts.h +++ b/engines/sherlock/fonts.h @@ -57,7 +57,7 @@ public: /** * Frees the font manager */ - static void free(); + static void freeFont(); /** * Set the font to use for writing text on the screen diff --git a/engines/sherlock/image_file.h b/engines/sherlock/image_file.h index da260ab30b..778332b726 100644 --- a/engines/sherlock/image_file.h +++ b/engines/sherlock/image_file.h @@ -46,6 +46,11 @@ struct ImageFrame { Graphics::Surface _frame; /** + * Converts an ImageFrame record to a surface for convenience in passing to drawing methods + */ + operator const Graphics::Surface &() { return _frame; } + + /** * Decompress a single frame for the sprite */ void decompressFrame(const byte *src, bool isRoseTattoo); diff --git a/engines/sherlock/module.mk b/engines/sherlock/module.mk index 7fa7896691..0d17d0b249 100644 --- a/engines/sherlock/module.mk +++ b/engines/sherlock/module.mk @@ -3,6 +3,7 @@ MODULE := engines/sherlock MODULE_OBJS = \ scalpel/scalpel.o \ scalpel/3do/movie_decoder.o \ + scalpel/3do/scalpel_3do_screen.o \ scalpel/drivers/adlib.o \ scalpel/drivers/mt32.o \ scalpel/tsage/logo.o \ @@ -30,6 +31,7 @@ MODULE_OBJS = \ tattoo/tattoo_people.o \ tattoo/tattoo_resources.o \ tattoo/tattoo_scene.o \ + tattoo/tattoo_screen.o \ tattoo/tattoo_talk.o \ tattoo/tattoo_user_interface.o \ tattoo/widget_base.o \ diff --git a/engines/sherlock/objects.cpp b/engines/sherlock/objects.cpp index a89b8dce86..644c0c74c9 100644 --- a/engines/sherlock/objects.cpp +++ b/engines/sherlock/objects.cpp @@ -365,8 +365,8 @@ bool BaseObject::checkEndOfSequence() { if (seq == 99) { --_frameNumber; - screen._backBuffer1.transBlitFrom(*_imageFrame, _position); - screen._backBuffer2.transBlitFrom(*_imageFrame, _position); + screen._backBuffer1.SHtransBlitFrom(*_imageFrame, _position); + screen._backBuffer2.SHtransBlitFrom(*_imageFrame, _position); _type = INVALID; } else if (IS_ROSE_TATTOO && _talkSeq && seq == 0) { setObjTalkSequence(_talkSeq); diff --git a/engines/sherlock/scalpel/3do/scalpel_3do_screen.cpp b/engines/sherlock/scalpel/3do/scalpel_3do_screen.cpp new file mode 100644 index 0000000000..f848394864 --- /dev/null +++ b/engines/sherlock/scalpel/3do/scalpel_3do_screen.cpp @@ -0,0 +1,286 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "sherlock/scalpel/scalpel_screen.h" +#include "sherlock/scalpel/scalpel.h" +#include "sherlock/scalpel/3do/scalpel_3do_screen.h" + +namespace Sherlock { + +namespace Scalpel { + +Scalpel3DOScreen::Scalpel3DOScreen(SherlockEngine *vm): ScalpelScreen(vm) { +} + +void Scalpel3DOScreen::SHblitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { + if (!_vm->_isScreenDoubled) { + ScalpelScreen::SHblitFrom(src, pt, srcBounds); + return; + } + + Common::Rect srcRect = srcBounds; + Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); + + if (!srcRect.isValidRect() || !clip(srcRect, destRect)) + return; + + // Add dirty area remapped to the 640x200 surface + addDirtyRect(Common::Rect(destRect.left * 2, destRect.top * 2, destRect.right * 2, destRect.bottom * 2)); + + // Transfer the area, doubling each pixel + for (int yp = 0; yp < srcRect.height(); ++yp) { + const uint16 *srcP = (const uint16 *)src.getBasePtr(srcRect.left, srcRect.top + yp); + uint16 *destP = (uint16 *)getBasePtr(destRect.left * 2, (destRect.top + yp) * 2); + + for (int xp = srcRect.left; xp < srcRect.right; ++xp, ++srcP, destP += 2) { + *destP = *srcP; + *(destP + 1) = *srcP; + *(destP + 640) = *srcP; + *(destP + 640 + 1) = *srcP; + } + } +} + +void Scalpel3DOScreen::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, + bool flipped, int overrideColor) { + error("TODO: Refactor"); +#if 0 + if (!_vm->_isScreenDoubled) { + ScalpelScreen::transBlitFromUnscaled(src, pt, flipped, overrideColor); + return; + } + + Common::Rect drawRect(0, 0, src.w, src.h); + Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); + + // Clip the display area to on-screen + if (!clip(drawRect, destRect)) + // It's completely off-screen + return; + + if (flipped) + drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, + src.w - drawRect.left, src.h - drawRect.top); + + Common::Point destPt(destRect.left, destRect.top); + addDirtyRect(Common::Rect(destPt.x * 2, destPt.y * 2, (destPt.x + drawRect.width()) * 2, + (destPt.y + drawRect.height()) * 2)); + + assert(src.format.bytesPerPixel == 2 && _surface.format.bytesPerPixel == 2); + + for (int yp = 0; yp < drawRect.height(); ++yp) { + const uint16 *srcP = (const uint16 *)src.getBasePtr( + flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); + uint16 *destP = (uint16 *)getBasePtr(destPt.x * 2, (destPt.y + yp) * 2); + + for (int xp = 0; xp < drawRect.width(); ++xp, destP += 2) { + // RGB 0, 0, 0 -> transparent on 3DO + if (*srcP) { + *destP = *srcP; + *(destP + 1) = *srcP; + *(destP + 640) = *srcP; + *(destP + 640 + 1) = *srcP; + } + + srcP = flipped ? srcP - 1 : srcP + 1; + } + } +#endif +} + +void Scalpel3DOScreen::fillRect(const Common::Rect &r, uint color) { + if (_vm->_isScreenDoubled) + ScalpelScreen::fillRect(Common::Rect(r.left * 2, r.top * 2, r.right * 2, r.bottom * 2), color); + else + ScalpelScreen::fillRect(r, color); +} + +void Scalpel3DOScreen::fadeIntoScreen3DO(int speed) { + Events &events = *_vm->_events; + uint16 *currentScreenBasePtr = (uint16 *)getPixels(); + uint16 *targetScreenBasePtr = (uint16 *)_backBuffer->getPixels(); + uint16 currentScreenPixel = 0; + uint16 targetScreenPixel = 0; + + uint16 currentScreenPixelRed = 0; + uint16 currentScreenPixelGreen = 0; + uint16 currentScreenPixelBlue = 0; + + uint16 targetScreenPixelRed = 0; + uint16 targetScreenPixelGreen = 0; + uint16 targetScreenPixelBlue = 0; + + uint16 screenWidth = SHERLOCK_SCREEN_WIDTH; + uint16 screenHeight = SHERLOCK_SCREEN_HEIGHT; + uint16 screenX = 0; + uint16 screenY = 0; + uint16 pixelsChanged = 0; + + clearDirtyRects(); + + do { + pixelsChanged = 0; + uint16 *currentScreenPtr = currentScreenBasePtr; + uint16 *targetScreenPtr = targetScreenBasePtr; + + for (screenY = 0; screenY < screenHeight; screenY++) { + for (screenX = 0; screenX < screenWidth; screenX++) { + currentScreenPixel = *currentScreenPtr; + targetScreenPixel = *targetScreenPtr; + + if (currentScreenPixel != targetScreenPixel) { + // pixel doesn't match, adjust accordingly + currentScreenPixelRed = currentScreenPixel & 0xF800; + currentScreenPixelGreen = currentScreenPixel & 0x07E0; + currentScreenPixelBlue = currentScreenPixel & 0x001F; + targetScreenPixelRed = targetScreenPixel & 0xF800; + targetScreenPixelGreen = targetScreenPixel & 0x07E0; + targetScreenPixelBlue = targetScreenPixel & 0x001F; + + if (currentScreenPixelRed != targetScreenPixelRed) { + if (currentScreenPixelRed < targetScreenPixelRed) { + currentScreenPixelRed += 0x0800; + } else { + currentScreenPixelRed -= 0x0800; + } + } + if (currentScreenPixelGreen != targetScreenPixelGreen) { + // Adjust +2/-2 because we are running RGB555 at RGB565 + if (currentScreenPixelGreen < targetScreenPixelGreen) { + currentScreenPixelGreen += 0x0040; + } else { + currentScreenPixelGreen -= 0x0040; + } + } + if (currentScreenPixelBlue != targetScreenPixelBlue) { + if (currentScreenPixelBlue < targetScreenPixelBlue) { + currentScreenPixelBlue += 0x0001; + } else { + currentScreenPixelBlue -= 0x0001; + } + } + + uint16 v = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; + *currentScreenPtr = v; + if (_vm->_isScreenDoubled) { + *(currentScreenPtr + 1) = v; + *(currentScreenPtr + 640) = v; + *(currentScreenPtr + 640 + 1) = v; + } + + pixelsChanged++; + } + + currentScreenPtr += _vm->_isScreenDoubled ? 2 : 1; + targetScreenPtr++; + } + + if (_vm->_isScreenDoubled) + currentScreenPtr += 640; + } + + // Too much considered dirty at the moment + if (_vm->_isScreenDoubled) + addDirtyRect(Common::Rect(0, 0, screenWidth * 2, screenHeight * 2)); + else + addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); + + events.pollEvents(); + events.delay(10 * speed); + } while ((pixelsChanged) && (!_vm->shouldQuit())); +} + +void Scalpel3DOScreen::blitFrom3DOcolorLimit(uint16 limitColor) { + uint16 *currentScreenPtr = (uint16 *)getPixels(); + uint16 *targetScreenPtr = (uint16 *)_backBuffer->getPixels(); + uint16 currentScreenPixel = 0; + + uint16 screenWidth = SHERLOCK_SCREEN_WIDTH; + uint16 screenHeight = SHERLOCK_SCREEN_HEIGHT; + uint16 screenX = 0; + uint16 screenY = 0; + + uint16 currentScreenPixelRed = 0; + uint16 currentScreenPixelGreen = 0; + uint16 currentScreenPixelBlue = 0; + + uint16 limitPixelRed = limitColor & 0xF800; + uint16 limitPixelGreen = limitColor & 0x07E0; + uint16 limitPixelBlue = limitColor & 0x001F; + + for (screenY = 0; screenY < screenHeight; screenY++) { + for (screenX = 0; screenX < screenWidth; screenX++) { + currentScreenPixel = *targetScreenPtr; + + currentScreenPixelRed = currentScreenPixel & 0xF800; + currentScreenPixelGreen = currentScreenPixel & 0x07E0; + currentScreenPixelBlue = currentScreenPixel & 0x001F; + + if (currentScreenPixelRed < limitPixelRed) + currentScreenPixelRed = limitPixelRed; + if (currentScreenPixelGreen < limitPixelGreen) + currentScreenPixelGreen = limitPixelGreen; + if (currentScreenPixelBlue < limitPixelBlue) + currentScreenPixelBlue = limitPixelBlue; + + uint16 v = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; + *currentScreenPtr = v; + if (_vm->_isScreenDoubled) { + *(currentScreenPtr + 1) = v; + *(currentScreenPtr + 640) = v; + *(currentScreenPtr + 640 + 1) = v; + } + + currentScreenPtr += _vm->_isScreenDoubled ? 2 : 1; + targetScreenPtr++; + } + + if (_vm->_isScreenDoubled) + currentScreenPtr += 640; + } + + // Too much considered dirty at the moment + if (_vm->_isScreenDoubled) + addDirtyRect(Common::Rect(0, 0, screenWidth * 2, screenHeight * 2)); + else + addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); +} + +uint16 Scalpel3DOScreen::width() const { + return _vm->_isScreenDoubled ? this->w / 2 : this->w; +} + +uint16 Scalpel3DOScreen::height() const { + return _vm->_isScreenDoubled ? this->h / 2 : this->h; +} + +void Scalpel3DOScreen::rawBlitFrom(const Graphics::Surface &src, const Common::Point &pt) { + Common::Rect srcRect(0, 0, src.w, src.h); + Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); + + addDirtyRect(destRect); + copyRectToSurface(src, destRect.left, destRect.top, srcRect); +} + +} // End of namespace Scalpel + +} // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/3do/scalpel_3do_screen.h b/engines/sherlock/scalpel/3do/scalpel_3do_screen.h new file mode 100644 index 0000000000..422f588b17 --- /dev/null +++ b/engines/sherlock/scalpel/3do/scalpel_3do_screen.h @@ -0,0 +1,76 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SHERLOCK_SCALPEL_3DO_SCREEN_H +#define SHERLOCK_SCALPEL_3DO_SCREEN_H + +#include "sherlock/scalpel/scalpel_screen.h" + +namespace Sherlock { + +class SherlockEngine; + +namespace Scalpel { + +class Scalpel3DOScreen : public ScalpelScreen { +protected: + /** + * Draws a sub-section of a surface at a given position within this surface + * Overriden for the 3DO to automatically double the size of everything to the underlying 640x400 surface + */ + virtual void SHblitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + + /** + * Draws a surface at a given position within this surface with transparency + */ + virtual void transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, + int overrideColor); +public: + Scalpel3DOScreen(SherlockEngine *vm); + virtual ~Scalpel3DOScreen() {} + + /** + * Draws a sub-section of a surface at a given position within this surface + */ + void rawBlitFrom(const Graphics::Surface &src, const Common::Point &pt); + + /** + * Fade backbuffer 1 into screen (3DO RGB!) + */ + void fadeIntoScreen3DO(int speed); + + void blitFrom3DOcolorLimit(uint16 color); + + /** + * Fill a given area of the surface with a given color + */ + virtual void fillRect(const Common::Rect &r, uint color); + + virtual uint16 width() const; + virtual uint16 height() const; +}; + +} // End of namespace Scalpel + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index b17f38b218..cbb202095f 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -29,6 +29,7 @@ #include "sherlock/scalpel/scalpel_people.h" #include "sherlock/scalpel/scalpel_scene.h" #include "sherlock/scalpel/scalpel_screen.h" +#include "sherlock/scalpel/3do/scalpel_3do_screen.h" #include "sherlock/scalpel/tsage/logo.h" #include "sherlock/sherlock.h" #include "sherlock/music.h" @@ -371,8 +372,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages_LondonNovember("title2.vgs", true); - _screen->_backBuffer1.blitFrom(*_screen); - _screen->_backBuffer2.blitFrom(*_screen); + _screen->_backBuffer1.SHblitFrom(*_screen); + _screen->_backBuffer2.SHblitFrom(*_screen); Common::Point londonPosition; @@ -386,19 +387,19 @@ bool ScalpelEngine::showCityCutscene() { } // London, England - _screen->_backBuffer1.transBlitFrom(titleImages_LondonNovember[0], londonPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_LondonNovember[0], londonPosition); _screen->randomTransition(); finished = _events->delay(1000, true); // November, 1888 if (finished) { - _screen->_backBuffer1.transBlitFrom(titleImages_LondonNovember[1], Common::Point(100, 100)); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_LondonNovember[1], Common::Point(100, 100)); _screen->randomTransition(); finished = _events->delay(5000, true); } // Transition out the title - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2); + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2); _screen->randomTransition(); } @@ -407,8 +408,8 @@ bool ScalpelEngine::showCityCutscene() { if (finished) { ImageFile titleImages_SherlockHolmesTitle("title.vgs", true); - _screen->_backBuffer1.blitFrom(*_screen); - _screen->_backBuffer2.blitFrom(*_screen); + _screen->_backBuffer1.SHblitFrom(*_screen); + _screen->_backBuffer2.SHblitFrom(*_screen); Common::Point lostFilesPosition; Common::Point sherlockHolmesPosition; @@ -427,17 +428,17 @@ bool ScalpelEngine::showCityCutscene() { } // The Lost Files of - _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[0], lostFilesPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_SherlockHolmesTitle[0], lostFilesPosition); // Sherlock Holmes - _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[1], sherlockHolmesPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_SherlockHolmesTitle[1], sherlockHolmesPosition); // copyright - _screen->_backBuffer1.transBlitFrom(titleImages_SherlockHolmesTitle[2], copyrightPosition); + _screen->_backBuffer1.SHtransBlitFrom(titleImages_SherlockHolmesTitle[2], copyrightPosition); _screen->verticalTransition(); finished = _events->delay(4000, true); if (finished) { - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2); + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2); _screen->randomTransition(); finished = _events->delay(2000); } @@ -461,7 +462,7 @@ bool ScalpelEngine::showCityCutscene() { // English, width 175, height 38 alleyPosition = Common::Point(72, 51); } - _screen->transBlitFrom(titleImages_SherlockHolmesTitle[3], alleyPosition); + _screen->SHtransBlitFrom(titleImages_SherlockHolmesTitle[3], alleyPosition); _screen->fadeIn(palette, 3); // Wait until the track got looped and the first few notes were played @@ -537,7 +538,7 @@ bool ScalpelEngine::showAlleyCutscene() { earlyTheFollowingMorningPosition = Common::Point(35, 52); } - _screen->transBlitFrom(titleImages_EarlyTheFollowingMorning[0], earlyTheFollowingMorningPosition); + _screen->SHtransBlitFrom(titleImages_EarlyTheFollowingMorning[0], earlyTheFollowingMorningPosition); // fast fade-in _screen->fadeIn(palette, 1); @@ -641,23 +642,23 @@ bool ScalpelEngine::scrollCredits() { delete stream; // Save a copy of the screen background for use in drawing each credit frame - _screen->_backBuffer1.blitFrom(*_screen); + _screen->_backBuffer1.SHblitFrom(*_screen); // Loop for showing the credits for(int idx = 0; idx < 600 && !_events->kbHit() && !shouldQuit(); ++idx) { // Copy the entire screen background before writing text - _screen->blitFrom(_screen->_backBuffer1); + _screen->SHblitFrom(_screen->_backBuffer1); // Write the text appropriate for the next frame if (idx < 400) - _screen->transBlitFrom(creditsImages[0], Common::Point(10, 200 - idx), false, 0); + _screen->SHtransBlitFrom(creditsImages[0], Common::Point(10, 200 - idx), false, 0); if (idx > 200) - _screen->transBlitFrom(creditsImages[1], Common::Point(10, 400 - idx), false, 0); + _screen->SHtransBlitFrom(creditsImages[1], Common::Point(10, 400 - idx), false, 0); // Don't show credit text on the top and bottom ten rows of the screen - _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, _screen->w(), 10)); - _screen->blitFrom(_screen->_backBuffer1, Common::Point(0, _screen->h() - 10), - Common::Rect(0, _screen->h() - 10, _screen->w(), _screen->h())); + _screen->SHblitFrom(_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, _screen->width(), 10)); + _screen->SHblitFrom(_screen->_backBuffer1, Common::Point(0, _screen->height() - 10), + Common::Rect(0, _screen->height() - 10, _screen->width(), _screen->height())); _events->delay(100); } @@ -670,7 +671,7 @@ bool ScalpelEngine::show3DOSplash() { // 3DO EA Splash screen ImageFile3DO titleImage_3DOSplash("3DOSplash.cel", kImageFile3DOType_Cel); - _screen->transBlitFrom(titleImage_3DOSplash[0]._frame, Common::Point(0, -20)); + _screen->SHtransBlitFrom(titleImage_3DOSplash[0]._frame, Common::Point(0, -20)); bool finished = _events->delay(3000, true); if (finished) { @@ -706,7 +707,7 @@ bool ScalpelEngine::showCityCutscene3DO() { _sound->playAiff("prologue/sounds/rain.aiff", 15, true); // Fade screen to grey - screen._backBuffer1.fill(0xCE59); // RGB565: 25, 50, 25 (grey) + screen._backBuffer1.clear(0xCE59); // RGB565: 25, 50, 25 (grey) screen.fadeIntoScreen3DO(2); } @@ -715,16 +716,16 @@ bool ScalpelEngine::showCityCutscene3DO() { } if (finished) { - screen._backBuffer1.fill(0); // fill backbuffer with black to avoid issues during fade from white + screen._backBuffer1.clear(0); // fill backbuffer with black to avoid issues during fade from white finished = _animation->play3DO("26open1", true, 1, true, 2); } if (finished) { - screen._backBuffer2.blitFrom(screen._backBuffer1); + screen._backBuffer2.SHblitFrom(screen._backBuffer1); // "London, England" ImageFile3DO titleImage_London("title2a.cel", kImageFile3DOType_Cel); - screen._backBuffer1.transBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50)); + screen._backBuffer1.SHtransBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50)); screen.fadeIntoScreen3DO(1); finished = _events->delay(1500, true); @@ -732,7 +733,7 @@ bool ScalpelEngine::showCityCutscene3DO() { if (finished) { // "November, 1888" ImageFile3DO titleImage_November("title2b.cel", kImageFile3DOType_Cel); - screen._backBuffer1.transBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100)); + screen._backBuffer1.SHtransBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100)); screen.fadeIntoScreen3DO(1); finished = _music->waitUntilMSec(14700, 0, 0, 5000); @@ -740,8 +741,8 @@ bool ScalpelEngine::showCityCutscene3DO() { if (finished) { // Restore screen - _screen->_backBuffer1.blitFrom(screen._backBuffer2); - _screen->blitFrom(screen._backBuffer1); + _screen->_backBuffer1.SHblitFrom(screen._backBuffer2); + _screen->SHblitFrom(screen._backBuffer1); } } @@ -751,7 +752,7 @@ bool ScalpelEngine::showCityCutscene3DO() { if (finished) { // "Sherlock Holmes" (title) ImageFile3DO titleImage_SherlockHolmesTitle("title1ab.cel", kImageFile3DOType_Cel); - screen._backBuffer1.transBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5)); + screen._backBuffer1.SHtransBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5)); // Blend in screen.fadeIntoScreen3DO(2); @@ -761,7 +762,7 @@ bool ScalpelEngine::showCityCutscene3DO() { if (finished) { ImageFile3DO titleImage_Copyright("title1c.cel", kImageFile3DOType_Cel); - screen.transBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190)); + screen.SHtransBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190)); finished = _events->delay(3500, true); } } @@ -780,7 +781,7 @@ bool ScalpelEngine::showCityCutscene3DO() { if (finished) { // "In the alley behind the Regency Theatre..." ImageFile3DO titleImage_InTheAlley("title1d.cel", kImageFile3DOType_Cel); - screen._backBuffer1.transBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51)); + screen._backBuffer1.SHtransBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51)); // Fade in screen.fadeIntoScreen3DO(4); @@ -819,7 +820,7 @@ bool ScalpelEngine::showAlleyCutscene3DO() { ImageFile3DO titleImage_ScreamingVictim("scream.cel", kImageFile3DOType_Cel); screen.clear(); - screen.transBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0)); + screen.SHtransBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0)); // Play "scream.aiff" if (_sound->_voices) @@ -848,7 +849,7 @@ bool ScalpelEngine::showAlleyCutscene3DO() { if (finished) { // "Early the following morning on Baker Street..." ImageFile3DO titleImage_EarlyTheFollowingMorning("title3.cel", kImageFile3DOType_Cel); - screen._backBuffer1.transBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51)); + screen._backBuffer1.SHtransBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51)); // Fade in screen.fadeIntoScreen3DO(4); @@ -908,7 +909,7 @@ bool ScalpelEngine::showOfficeCutscene3DO() { ImageFile3DO titleImage_CoffeeNote("note.cel", kImageFile3DOType_Cel); _screen->clear(); - _screen->transBlitFrom(titleImage_CoffeeNote[0]._frame, Common::Point(0, 0)); + _screen->SHtransBlitFrom(titleImage_CoffeeNote[0]._frame, Common::Point(0, 0)); if (_sound->_voices) { finished = _sound->playSound("prologue/sounds/note.aiff", WAIT_KBD_OR_FINISH); @@ -937,7 +938,7 @@ bool ScalpelEngine::showOfficeCutscene3DO() { // TODO: Brighten the image, possibly by doing a partial fade // to white. - _screen->_backBuffer2.blitFrom(_screen->_backBuffer1); + _screen->_backBuffer2.SHblitFrom(_screen->_backBuffer1); for (int nr = 1; finished && nr <= 4; nr++) { char filename[15]; @@ -945,8 +946,8 @@ bool ScalpelEngine::showOfficeCutscene3DO() { ImageFile3DO *creditsImage = new ImageFile3DO(filename, kImageFile3DOType_Cel); ImageFrame *creditsFrame = &(*creditsImage)[0]; for (int i = 0; finished && i < 200 + creditsFrame->_height; i++) { - _screen->blitFrom(_screen->_backBuffer2); - _screen->transBlitFrom(creditsFrame->_frame, Common::Point((320 - creditsFrame->_width) / 2, 200 - i)); + _screen->SHblitFrom(_screen->_backBuffer2); + _screen->SHtransBlitFrom(creditsFrame->_frame, Common::Point((320 - creditsFrame->_width) / 2, 200 - i)); if (!_events->delay(70, true)) finished = false; } @@ -998,7 +999,7 @@ void ScalpelEngine::showLBV(const Common::String &filename) { delete stream; _screen->setPalette(images._palette); - _screen->_backBuffer1.blitFrom(images[0]); + _screen->_backBuffer1.SHblitFrom(images[0]); _screen->verticalTransition(); } @@ -1156,7 +1157,7 @@ void ScalpelEngine::eraseBrumwellMirror() { // If player is in range of the mirror, then restore background from the secondary back buffer if (Common::Rect(70, 100, 200, 200).contains(pt)) { - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 18), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(137, 18), Common::Rect(137, 18, 184, 74)); } } @@ -1218,20 +1219,20 @@ void ScalpelEngine::doBrumwellMirror() { bool flipped = people[HOLMES]._sequenceNumber == WALK_LEFT || people[HOLMES]._sequenceNumber == STOP_LEFT || people[HOLMES]._sequenceNumber == WALK_UPRIGHT || people[HOLMES]._sequenceNumber == STOP_UPRIGHT || people[HOLMES]._sequenceNumber == WALK_DOWNLEFT || people[HOLMES]._sequenceNumber == STOP_DOWNLEFT; - _screen->_backBuffer1.transBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped); + _screen->_backBuffer1.SHtransBlitFrom(imageFrame, pt + Common::Point(38, -imageFrame._frame.h - 25), flipped); // Redraw the mirror borders to prevent the drawn image of Holmes from appearing outside of the mirror - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(114, 18), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(114, 18), Common::Rect(114, 18, 137, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(137, 70), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(137, 70), Common::Rect(137, 70, 142, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(142, 71), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(142, 71), Common::Rect(142, 71, 159, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(159, 72), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(159, 72), Common::Rect(159, 72, 170, 116)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(170, 73), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(170, 73), Common::Rect(170, 73, 184, 114)); - _screen->_backBuffer1.blitFrom(_screen->_backBuffer2, Common::Point(184, 18), + _screen->_backBuffer1.SHblitFrom(_screen->_backBuffer2, Common::Point(184, 18), Common::Rect(184, 18, 212, 114)); } } @@ -1272,7 +1273,7 @@ void ScalpelEngine::showScummVMRestoreDialog() { bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::Point &pos, bool isPortrait) { Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; Scalpel3DOMovieDecoder *videoDecoder = new Scalpel3DOMovieDecoder(); - Graphics::Surface tempSurface; + Graphics::ManagedSurface tempSurface; Common::Point framePos(pos.x, pos.y); ImageFile3DO *frameImageFile = nullptr; @@ -1307,7 +1308,7 @@ bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::P // If we're to show the movie at half-size, we'll need a temporary intermediate surface if (halfSize) - tempSurface.create(width / 2, height / 2, _screen->getPixelFormat()); + tempSurface.create(width / 2, height / 2); while (!shouldQuit() && !videoDecoder->endOfVideo() && !skipVideo) { if (videoDecoder->needsUpdate()) { @@ -1371,19 +1372,19 @@ bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::P } // Point the drawing frame to the temporary surface - frame = &tempSurface; + frame = &tempSurface.rawSurface(); } if (isPortrait && !frameShown) { // Draw the frame (not the frame of the video, but a frame around the video) itself - _screen->transBlitFrom(frameImage->_frame, framePos); + _screen->SHtransBlitFrom(frameImage->_frame, framePos); frameShown = true; } if (isPortrait && !halfSize) { screen.rawBlitFrom(*frame, Common::Point(pos.x * 2, pos.y * 2)); } else { - _screen->blitFrom(*frame, pos); + _screen->SHblitFrom(*frame, pos); } _screen->update(); @@ -1413,9 +1414,9 @@ bool ScalpelEngine::play3doMovie(const Common::String &filename, const Common::P } // Restore scene - screen._backBuffer1.blitFrom(screen._backBuffer2); + screen._backBuffer1.SHblitFrom(screen._backBuffer2); _scene->updateBackground(); - screen.slamArea(0, 0, screen.w(), CONTROLS_Y); + screen.slamArea(0, 0, screen.width(), CONTROLS_Y); return !skipVideo; } diff --git a/engines/sherlock/scalpel/scalpel_darts.cpp b/engines/sherlock/scalpel/scalpel_darts.cpp index 87f4566837..c5ba8032f3 100644 --- a/engines/sherlock/scalpel/scalpel_darts.cpp +++ b/engines/sherlock/scalpel/scalpel_darts.cpp @@ -102,7 +102,7 @@ void Darts::playDarts() { score -= lastDart; _roundScore += lastDart; - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.print(Common::Point(DART_INFO_X, DART_INFO_Y), DART_COL_FORE, "Dart # %d", idx + 1); screen.print(Common::Point(DART_INFO_X, DART_INFO_Y + 10), DART_COL_FORE, "Scored %d points", lastDart); @@ -154,7 +154,7 @@ void Darts::playDarts() { events.wait(20); } - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -166,8 +166,8 @@ void Darts::playDarts() { done |= _vm->shouldQuit(); if (!done) { - screen._backBuffer2.blitFrom((*_dartImages)[0], Common::Point(0, 0)); - screen._backBuffer1.blitFrom(screen._backBuffer2); + screen._backBuffer2.SHblitFrom((*_dartImages)[0], Common::Point(0, 0)); + screen._backBuffer1.SHblitFrom(screen._backBuffer2); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } } while (!done); @@ -185,7 +185,7 @@ void Darts::loadDarts() { _dartImages = new ImageFile("darts.vgs"); screen.setPalette(_dartImages->_palette); - screen._backBuffer1.blitFrom((*_dartImages)[0], Common::Point(0, 0)); + screen._backBuffer1.SHblitFrom((*_dartImages)[0], Common::Point(0, 0)); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -245,7 +245,7 @@ void Darts::showNames(int playerNum) { screen.slamArea(STATUS_INFO_X + 50, STATUS_INFO_Y + 10, 81, 12); // Make a copy of the back buffer to the secondary one - screen._backBuffer2.blitFrom(screen._backBuffer1); + screen._backBuffer2.SHblitFrom(screen._backBuffer1); } void Darts::showStatus(int playerNum) { @@ -253,7 +253,7 @@ void Darts::showStatus(int playerNum) { byte color; // Copy scoring screen from secondary back buffer. This will erase any previously displayed status/score info - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, SHERLOCK_SCREEN_WIDTH, STATUS_INFO_Y + 48)); color = (playerNum == 0) ? PLAYER_COLOR : DART_COL_FORE; @@ -292,7 +292,7 @@ int Darts::throwDart(int dartNum, int computer) { if (_vm->shouldQuit()) return 0; - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(DART_INFO_X, DART_INFO_Y - 1), Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamRect(Common::Rect(DART_INFO_X, DART_INFO_Y - 1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); @@ -309,9 +309,9 @@ int Darts::throwDart(int dartNum, int computer) { // Copy the bars to the secondary back buffer so that they remain fixed at their selected values // whilst the dart is being animated at being thrown at the board - screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARHX - 1, DARTHORIZY - 1), + screen._backBuffer2.SHblitFrom(screen._backBuffer1, Common::Point(DARTBARHX - 1, DARTHORIZY - 1), Common::Rect(DARTBARHX - 1, DARTHORIZY - 1, DARTBARHX + DARTBARSIZE + 3, DARTHORIZY + 10)); - screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1), + screen._backBuffer2.SHblitFrom(screen._backBuffer1, Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1), Common::Rect(DARTBARVX - 1, DARTHEIGHTY - 1, DARTBARVX + 11, DARTHEIGHTY + DARTBARSIZE + 3)); // Convert height and width to relative range of -50 to 50, where 0,0 is the exact centre of the board @@ -344,7 +344,7 @@ void Darts::drawDartThrow(const Common::Point &pt) { // Draw the dart Common::Point drawPos(pos.x - frame._width / 2, pos.y - frame._height); - screen._backBuffer1.transBlitFrom(frame, drawPos); + screen._backBuffer1.SHtransBlitFrom(frame, drawPos); screen.slamArea(drawPos.x, drawPos.y, frame._width, frame._height); // Handle erasing old dart frame area @@ -352,14 +352,14 @@ void Darts::drawDartThrow(const Common::Point &pt) { screen.slamRect(oldDrawBounds); oldDrawBounds = Common::Rect(drawPos.x, drawPos.y, drawPos.x + frame._width, drawPos.y + frame._height); - screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, oldDrawBounds); + screen._backBuffer1.SHblitFrom(screen._backBuffer2, drawPos, oldDrawBounds); events.wait(2); } // Draw dart in final "stuck to board" form - screen._backBuffer1.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); - screen._backBuffer2.transBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen._backBuffer1.SHtransBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); + screen._backBuffer2.SHtransBlitFrom((*_dartImages)[22], Common::Point(oldDrawBounds.left, oldDrawBounds.top)); screen.slamRect(oldDrawBounds); } @@ -368,8 +368,8 @@ void Darts::erasePowerBars() { screen._backBuffer1.fillRect(Common::Rect(DARTBARHX, DARTHORIZY, DARTBARHX + DARTBARSIZE, DARTHORIZY + 10), BLACK); screen._backBuffer1.fillRect(Common::Rect(DARTBARVX, DARTHEIGHTY, DARTBARVX + 10, DARTHEIGHTY + DARTBARSIZE), BLACK); - screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(DARTBARHX - 1, DARTHORIZY - 1)); - screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1)); + screen._backBuffer1.SHtransBlitFrom((*_dartImages)[2], Common::Point(DARTBARHX - 1, DARTHORIZY - 1)); + screen._backBuffer1.SHtransBlitFrom((*_dartImages)[3], Common::Point(DARTBARVX - 1, DARTHEIGHTY - 1)); screen.slamArea(DARTBARHX - 1, DARTHORIZY - 1, DARTBARSIZE + 3, 11); screen.slamArea(DARTBARVX - 1, DARTHEIGHTY - 1, 11, DARTBARSIZE + 3); } @@ -398,11 +398,11 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, bool i if (isVertical) { screen._backBuffer1.hLine(pt.x, pt.y + DARTBARSIZE - 1 - idx, pt.x + 8, color); - screen._backBuffer1.transBlitFrom((*_dartImages)[3], Common::Point(pt.x - 1, pt.y - 1)); + screen._backBuffer1.SHtransBlitFrom((*_dartImages)[3], Common::Point(pt.x - 1, pt.y - 1)); screen.slamArea(pt.x, pt.y + DARTBARSIZE - 1 - idx, 8, 2); } else { screen._backBuffer1.vLine(pt.x + idx, pt.y, pt.y + 8, color); - screen._backBuffer1.transBlitFrom((*_dartImages)[2], Common::Point(pt.x - 1, pt.y - 1)); + screen._backBuffer1.SHtransBlitFrom((*_dartImages)[2], Common::Point(pt.x - 1, pt.y - 1)); screen.slamArea(pt.x + idx, pt.y, 1, 8); } diff --git a/engines/sherlock/scalpel/scalpel_inventory.cpp b/engines/sherlock/scalpel/scalpel_inventory.cpp index c3e20295fd..e8d4d3b934 100644 --- a/engines/sherlock/scalpel/scalpel_inventory.cpp +++ b/engines/sherlock/scalpel/scalpel_inventory.cpp @@ -201,7 +201,7 @@ void ScalpelInventory::highlight(int index, byte color) { ImageFrame &frame = (*_invShapes[slot])[0]; bb.fillRect(Common::Rect(8 + slot * 52, 165, (slot + 1) * 52, 194), color); - bb.transBlitFrom(frame, Common::Point(6 + slot * 52 + ((47 - frame._width) / 2), + bb.SHtransBlitFrom(frame, Common::Point(6 + slot * 52 + ((47 - frame._width) / 2), 163 + ((33 - frame._height) / 2))); screen.slamArea(8 + slot * 52, 165, 44, 30); } @@ -217,12 +217,12 @@ void ScalpelInventory::refreshInv() { ui._infoFlag = true; ui.clearInfo(); - screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(0, CONTROLS_Y), + screen._backBuffer2.SHblitFrom(screen._backBuffer1, Common::Point(0, CONTROLS_Y), Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); ui.examine(); if (!talk._talkToAbort) { - screen._backBuffer2.blitFrom((*ui._controlPanel)[0], Common::Point(0, CONTROLS_Y)); + screen._backBuffer2.SHblitFrom((*ui._controlPanel)[0], Common::Point(0, CONTROLS_Y)); loadInv(); } } @@ -264,7 +264,7 @@ void ScalpelInventory::putInv(InvSlamMode slamIt) { // Draw the item image ImageFrame &frame = (*_invShapes[itemNum])[0]; - bb.transBlitFrom(frame, Common::Point(6 + itemNum * 52 + ((47 - frame._width) / 2), + bb.SHtransBlitFrom(frame, Common::Point(6 + itemNum * 52 + ((47 - frame._width) / 2), 163 + ((33 - frame._height) / 2))); } diff --git a/engines/sherlock/scalpel/scalpel_map.cpp b/engines/sherlock/scalpel/scalpel_map.cpp index 0924581e38..ba14b5b300 100644 --- a/engines/sherlock/scalpel/scalpel_map.cpp +++ b/engines/sherlock/scalpel/scalpel_map.cpp @@ -167,13 +167,13 @@ int ScalpelMap::show() { setupSprites(); if (!IS_3DO) { - screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); - screen._backBuffer1.blitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); } else { - screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); - screen.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); + screen.SHblitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); } _drawMap = true; @@ -238,12 +238,12 @@ int ScalpelMap::show() { changed = false; if (!IS_3DO) { - screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); - screen._backBuffer1.blitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); - screen._backBuffer1.blitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y)); } else { - screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); + screen._backBuffer1.SHblitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y)); } showPlaces(); @@ -359,7 +359,6 @@ void ScalpelMap::freeSprites() { delete _mapCursors; delete _shapes; delete _iconShapes; - _iconSave.free(); } void ScalpelMap::showPlaces() { @@ -376,7 +375,7 @@ void ScalpelMap::showPlaces() { if (pt.x >= _bigPos.x && (pt.x - _bigPos.x) < SHERLOCK_SCREEN_WIDTH && pt.y >= _bigPos.y && (pt.y - _bigPos.y) < SHERLOCK_SCREEN_HEIGHT) { if (_vm->readFlags(idx)) { - screen._backBuffer1.transBlitFrom((*_iconShapes)[pt._translate], + screen._backBuffer1.SHtransBlitFrom((*_iconShapes)[pt._translate], Common::Point(pt.x - _bigPos.x - 6, pt.y - _bigPos.y - 12)); } } @@ -388,13 +387,13 @@ void ScalpelMap::showPlaces() { } void ScalpelMap::saveTopLine() { - _topLine.blitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12)); + _topLine.SHblitFrom(_vm->_screen->_backBuffer1, Common::Point(0, 0), Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, 12)); } void ScalpelMap::eraseTopLine() { Screen &screen = *_vm->_screen; - screen._backBuffer1.blitFrom(_topLine, Common::Point(0, 0)); - screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.h()); + screen._backBuffer1.SHblitFrom(_topLine, Common::Point(0, 0)); + screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, _topLine.height()); } void ScalpelMap::showPlaceName(int idx, bool highlighted) { @@ -409,7 +408,7 @@ void ScalpelMap::showPlaceName(int idx, bool highlighted) { bool flipped = people[HOLMES]._sequenceNumber == MAP_DOWNLEFT || people[HOLMES]._sequenceNumber == MAP_LEFT || people[HOLMES]._sequenceNumber == MAP_UPLEFT; - screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, _lDrawnPos, flipped); + screen._backBuffer1.SHtransBlitFrom(*people[HOLMES]._imageFrame, _lDrawnPos, flipped); } if (highlighted) { @@ -451,9 +450,9 @@ void ScalpelMap::updateMap(bool flushScreen) { saveIcon(people[HOLMES]._imageFrame, hPos); if (people[HOLMES]._sequenceNumber == MAP_DOWNLEFT || people[HOLMES]._sequenceNumber == MAP_LEFT || people[HOLMES]._sequenceNumber == MAP_UPLEFT) - screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, hPos, true); + screen._backBuffer1.SHtransBlitFrom(*people[HOLMES]._imageFrame, hPos, true); else - screen._backBuffer1.transBlitFrom(*people[HOLMES]._imageFrame, hPos, false); + screen._backBuffer1.SHtransBlitFrom(*people[HOLMES]._imageFrame, hPos, false); if (flushScreen) { screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -553,8 +552,8 @@ void ScalpelMap::saveIcon(ImageFrame *src, const Common::Point &pt) { return; } - assert(size.x <= _iconSave.w() && size.y <= _iconSave.h()); - _iconSave.blitFrom(screen._backBuffer1, Common::Point(0, 0), + assert(size.x <= _iconSave.width() && size.y <= _iconSave.height()); + _iconSave.SHblitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y)); _savedPos = pos; _savedSize = size; @@ -565,7 +564,7 @@ void ScalpelMap::restoreIcon() { if (_savedPos.x >= 0 && _savedPos.y >= 0 && _savedPos.x <= SHERLOCK_SCREEN_WIDTH && _savedPos.y < SHERLOCK_SCREEN_HEIGHT) - screen._backBuffer1.blitFrom(_iconSave, _savedPos, Common::Rect(0, 0, _savedSize.x, _savedSize.y)); + screen._backBuffer1.SHblitFrom(_iconSave, _savedPos, Common::Rect(0, 0, _savedSize.x, _savedSize.y)); } void ScalpelMap::highlightIcon(const Common::Point &pt) { diff --git a/engines/sherlock/scalpel/scalpel_scene.cpp b/engines/sherlock/scalpel/scalpel_scene.cpp index b62703e0fb..83e49bb3fa 100644 --- a/engines/sherlock/scalpel/scalpel_scene.cpp +++ b/engines/sherlock/scalpel/scalpel_scene.cpp @@ -71,26 +71,26 @@ void ScalpelScene::drawAllShapes() { // Draw all active shapes which are behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == BEHIND) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]->_type == ACTIVE_BG_SHAPE && _canimShapes[idx]->_misc == BEHIND) - screen._backBuffer->transBlitFrom(*_canimShapes[idx]->_imageFrame, + screen._backBuffer->SHtransBlitFrom(*_canimShapes[idx]->_imageFrame, _canimShapes[idx]->_position, _canimShapes[idx]->_flags & OBJ_FLIPPED); } // Draw all active shapes which are normal and behind the person for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if (_bgShapes[idx]._type == ACTIVE_BG_SHAPE && _bgShapes[idx]._misc == NORMAL_BEHIND) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } // Draw all canimations which are normal and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if (_canimShapes[idx]->_type == ACTIVE_BG_SHAPE && _canimShapes[idx]->_misc == NORMAL_BEHIND) - screen._backBuffer->transBlitFrom(*_canimShapes[idx]->_imageFrame, _canimShapes[idx]->_position, + screen._backBuffer->SHtransBlitFrom(*_canimShapes[idx]->_imageFrame, _canimShapes[idx]->_position, _canimShapes[idx]->_flags & OBJ_FLIPPED); } @@ -103,7 +103,7 @@ void ScalpelScene::drawAllShapes() { p._sequenceNumber == WALK_UPLEFT || p._sequenceNumber == STOP_UPLEFT || p._sequenceNumber == WALK_DOWNRIGHT || p._sequenceNumber == STOP_DOWNRIGHT); - screen._backBuffer->transBlitFrom(*p._imageFrame, Common::Point(p._position.x / FIXED_INT_MULTIPLIER, + screen._backBuffer->SHtransBlitFrom(*p._imageFrame, Common::Point(p._position.x / FIXED_INT_MULTIPLIER, p._position.y / FIXED_INT_MULTIPLIER - p.frameHeight()), flipped); } } @@ -112,7 +112,7 @@ void ScalpelScene::drawAllShapes() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == NORMAL_FORWARD) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, + screen._backBuffer->SHtransBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } @@ -120,7 +120,7 @@ void ScalpelScene::drawAllShapes() { for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]->_type == ACTIVE_BG_SHAPE || _canimShapes[idx]->_type == STATIC_BG_SHAPE) && _canimShapes[idx]->_misc == NORMAL_FORWARD) - screen._backBuffer->transBlitFrom(*_canimShapes[idx]->_imageFrame, _canimShapes[idx]->_position, + screen._backBuffer->SHtransBlitFrom(*_canimShapes[idx]->_imageFrame, _canimShapes[idx]->_position, _canimShapes[idx]->_flags & OBJ_FLIPPED); } @@ -132,7 +132,7 @@ void ScalpelScene::drawAllShapes() { if ((_bgShapes[idx]._type == ACTIVE_BG_SHAPE || _bgShapes[idx]._type == STATIC_BG_SHAPE) && _bgShapes[idx]._misc == FORWARD) - screen._backBuffer->transBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, + screen._backBuffer->SHtransBlitFrom(*_bgShapes[idx]._imageFrame, _bgShapes[idx]._position, _bgShapes[idx]._flags & OBJ_FLIPPED); } @@ -140,7 +140,7 @@ void ScalpelScene::drawAllShapes() { for (uint idx = 0; idx < _canimShapes.size(); ++idx) { if ((_canimShapes[idx]->_type == ACTIVE_BG_SHAPE || _canimShapes[idx]->_type == STATIC_BG_SHAPE) && _canimShapes[idx]->_misc == FORWARD) - screen._backBuffer->transBlitFrom(*_canimShapes[idx]->_imageFrame, _canimShapes[idx]->_position, + screen._backBuffer->SHtransBlitFrom(*_canimShapes[idx]->_imageFrame, _canimShapes[idx]->_position, _canimShapes[idx]->_flags & OBJ_FLIPPED); } @@ -242,7 +242,7 @@ void ScalpelScene::doBgAnim() { if (people[HOLMES]._type == CHARACTER) screen.restoreBackground(bounds); else if (people[HOLMES]._type == REMOVE) - screen._backBuffer->blitFrom(screen._backBuffer2, pt, bounds); + screen._backBuffer->SHblitFrom(screen._backBuffer2, pt, bounds); for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; @@ -261,7 +261,7 @@ void ScalpelScene::doBgAnim() { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && ((o._flags & OBJ_BEHIND) == 0)) { // Restore screen area - screen._backBuffer->blitFrom(screen._backBuffer2, o._position, + screen._backBuffer->SHblitFrom(screen._backBuffer2, o._position, Common::Rect(o._position.x, o._position.y, o._position.x + o._noShapeSize.x, o._position.y + o._noShapeSize.y)); @@ -309,14 +309,14 @@ void ScalpelScene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw all canimations which are behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = *_canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == BEHIND) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } @@ -324,14 +324,14 @@ void ScalpelScene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw all canimations which are NORMAL and behind the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = *_canimShapes[idx]; if (o._type == ACTIVE_BG_SHAPE && o._misc == NORMAL_BEHIND) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } @@ -344,7 +344,7 @@ void ScalpelScene::doBgAnim() { bool flipped = people[HOLMES]._sequenceNumber == WALK_LEFT || people[HOLMES]._sequenceNumber == STOP_LEFT || people[HOLMES]._sequenceNumber == WALK_UPLEFT || people[HOLMES]._sequenceNumber == STOP_UPLEFT || people[HOLMES]._sequenceNumber == WALK_DOWNRIGHT || people[HOLMES]._sequenceNumber == STOP_DOWNRIGHT; - screen._backBuffer->transBlitFrom(*people[HOLMES]._imageFrame, + screen._backBuffer->SHtransBlitFrom(*people[HOLMES]._imageFrame, Common::Point(tempX, people[HOLMES]._position.y / FIXED_INT_MULTIPLIER - people[HOLMES]._imageFrame->_frame.h), flipped); } @@ -352,14 +352,14 @@ void ScalpelScene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw all static and active canimations that are NORMAL and are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = *_canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == NORMAL_FORWARD) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } @@ -367,19 +367,19 @@ void ScalpelScene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Draw any active portrait if (people._portraitLoaded && people._portrait._type == ACTIVE_BG_SHAPE) - screen._backBuffer->transBlitFrom(*people._portrait._imageFrame, + screen._backBuffer->SHtransBlitFrom(*people._portrait._imageFrame, people._portrait._position, people._portrait._flags & OBJ_FLIPPED); // Draw all static and active canimations that are in front of the person for (uint idx = 0; idx < _canimShapes.size(); ++idx) { Object &o = *_canimShapes[idx]; if ((o._type == ACTIVE_BG_SHAPE || o._type == STATIC_BG_SHAPE) && o._misc == FORWARD) { - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } } @@ -387,7 +387,7 @@ void ScalpelScene::doBgAnim() { for (uint idx = 0; idx < _bgShapes.size(); ++idx) { Object &o = _bgShapes[idx]; if (o._type == NO_SHAPE && (o._flags & OBJ_BEHIND) == 0) - screen._backBuffer->transBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); + screen._backBuffer->SHtransBlitFrom(*o._imageFrame, o._position, o._flags & OBJ_FLIPPED); } // Bring the newly built picture to the screen diff --git a/engines/sherlock/scalpel/scalpel_screen.cpp b/engines/sherlock/scalpel/scalpel_screen.cpp index 197a2a2634..37e5294c02 100644 --- a/engines/sherlock/scalpel/scalpel_screen.cpp +++ b/engines/sherlock/scalpel/scalpel_screen.cpp @@ -28,6 +28,8 @@ namespace Sherlock { namespace Scalpel { ScalpelScreen::ScalpelScreen(SherlockEngine *vm) : Screen(vm) { + _backBuffer1.create(320, 200); + _backBuffer2.create(320, 200); } void ScalpelScreen::makeButton(const Common::Rect &bounds, int textX, @@ -123,255 +125,6 @@ void ScalpelScreen::makeField(const Common::Rect &r) { _backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP); } -/*----------------------------------------------------------------*/ - -void Scalpel3DOScreen::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { - if (!_vm->_isScreenDoubled) { - ScalpelScreen::blitFrom(src, pt, srcBounds); - return; - } - - Common::Rect srcRect = srcBounds; - Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); - - if (!srcRect.isValidRect() || !clip(srcRect, destRect)) - return; - - // Add dirty area remapped to the 640x200 surface - addDirtyRect(Common::Rect(destRect.left * 2, destRect.top * 2, destRect.right * 2, destRect.bottom * 2)); - - // Transfer the area, doubling each pixel - for (int yp = 0; yp < srcRect.height(); ++yp) { - const uint16 *srcP = (const uint16 *)src.getBasePtr(srcRect.left, srcRect.top + yp); - uint16 *destP = (uint16 *)getBasePtr(destRect.left * 2, (destRect.top + yp) * 2); - - for (int xp = srcRect.left; xp < srcRect.right; ++xp, ++srcP, destP += 2) { - *destP = *srcP; - *(destP + 1) = *srcP; - *(destP + 640) = *srcP; - *(destP + 640 + 1) = *srcP; - } - } -} - -void Scalpel3DOScreen::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, - bool flipped, int overrideColor) { - if (!_vm->_isScreenDoubled) { - ScalpelScreen::transBlitFromUnscaled(src, pt, flipped, overrideColor); - return; - } - - Common::Rect drawRect(0, 0, src.w, src.h); - Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); - - // Clip the display area to on-screen - if (!clip(drawRect, destRect)) - // It's completely off-screen - return; - - if (flipped) - drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, - src.w - drawRect.left, src.h - drawRect.top); - - Common::Point destPt(destRect.left, destRect.top); - addDirtyRect(Common::Rect(destPt.x * 2, destPt.y * 2, (destPt.x + drawRect.width()) * 2, - (destPt.y + drawRect.height()) * 2)); - - assert(src.format.bytesPerPixel == 2 && _surface.format.bytesPerPixel == 2); - - for (int yp = 0; yp < drawRect.height(); ++yp) { - const uint16 *srcP = (const uint16 *)src.getBasePtr( - flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); - uint16 *destP = (uint16 *)getBasePtr(destPt.x * 2, (destPt.y + yp) * 2); - - for (int xp = 0; xp < drawRect.width(); ++xp, destP += 2) { - // RGB 0, 0, 0 -> transparent on 3DO - if (*srcP) { - *destP = *srcP; - *(destP + 1) = *srcP; - *(destP + 640) = *srcP; - *(destP + 640 + 1) = *srcP; - } - - srcP = flipped ? srcP - 1 : srcP + 1; - } - } -} - -void Scalpel3DOScreen::fillRect(const Common::Rect &r, uint color) { - if (_vm->_isScreenDoubled) - ScalpelScreen::fillRect(Common::Rect(r.left * 2, r.top * 2, r.right * 2, r.bottom * 2), color); - else - ScalpelScreen::fillRect(r, color); -} - -void Scalpel3DOScreen::fadeIntoScreen3DO(int speed) { - Events &events = *_vm->_events; - uint16 *currentScreenBasePtr = (uint16 *)getPixels(); - uint16 *targetScreenBasePtr = (uint16 *)_backBuffer->getPixels(); - uint16 currentScreenPixel = 0; - uint16 targetScreenPixel = 0; - - uint16 currentScreenPixelRed = 0; - uint16 currentScreenPixelGreen = 0; - uint16 currentScreenPixelBlue = 0; - - uint16 targetScreenPixelRed = 0; - uint16 targetScreenPixelGreen = 0; - uint16 targetScreenPixelBlue = 0; - - uint16 screenWidth = SHERLOCK_SCREEN_WIDTH; - uint16 screenHeight = SHERLOCK_SCREEN_HEIGHT; - uint16 screenX = 0; - uint16 screenY = 0; - uint16 pixelsChanged = 0; - - clearDirtyRects(); - - do { - pixelsChanged = 0; - uint16 *currentScreenPtr = currentScreenBasePtr; - uint16 *targetScreenPtr = targetScreenBasePtr; - - for (screenY = 0; screenY < screenHeight; screenY++) { - for (screenX = 0; screenX < screenWidth; screenX++) { - currentScreenPixel = *currentScreenPtr; - targetScreenPixel = *targetScreenPtr; - - if (currentScreenPixel != targetScreenPixel) { - // pixel doesn't match, adjust accordingly - currentScreenPixelRed = currentScreenPixel & 0xF800; - currentScreenPixelGreen = currentScreenPixel & 0x07E0; - currentScreenPixelBlue = currentScreenPixel & 0x001F; - targetScreenPixelRed = targetScreenPixel & 0xF800; - targetScreenPixelGreen = targetScreenPixel & 0x07E0; - targetScreenPixelBlue = targetScreenPixel & 0x001F; - - if (currentScreenPixelRed != targetScreenPixelRed) { - if (currentScreenPixelRed < targetScreenPixelRed) { - currentScreenPixelRed += 0x0800; - } else { - currentScreenPixelRed -= 0x0800; - } - } - if (currentScreenPixelGreen != targetScreenPixelGreen) { - // Adjust +2/-2 because we are running RGB555 at RGB565 - if (currentScreenPixelGreen < targetScreenPixelGreen) { - currentScreenPixelGreen += 0x0040; - } else { - currentScreenPixelGreen -= 0x0040; - } - } - if (currentScreenPixelBlue != targetScreenPixelBlue) { - if (currentScreenPixelBlue < targetScreenPixelBlue) { - currentScreenPixelBlue += 0x0001; - } else { - currentScreenPixelBlue -= 0x0001; - } - } - - uint16 v = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; - *currentScreenPtr = v; - if (_vm->_isScreenDoubled) { - *(currentScreenPtr + 1) = v; - *(currentScreenPtr + 640) = v; - *(currentScreenPtr + 640 + 1) = v; - } - - pixelsChanged++; - } - - currentScreenPtr += _vm->_isScreenDoubled ? 2 : 1; - targetScreenPtr++; - } - - if (_vm->_isScreenDoubled) - currentScreenPtr += 640; - } - - // Too much considered dirty at the moment - if (_vm->_isScreenDoubled) - addDirtyRect(Common::Rect(0, 0, screenWidth * 2, screenHeight * 2)); - else - addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); - - events.pollEvents(); - events.delay(10 * speed); - } while ((pixelsChanged) && (!_vm->shouldQuit())); -} - -void Scalpel3DOScreen::blitFrom3DOcolorLimit(uint16 limitColor) { - uint16 *currentScreenPtr = (uint16 *)getPixels(); - uint16 *targetScreenPtr = (uint16 *)_backBuffer->getPixels(); - uint16 currentScreenPixel = 0; - - uint16 screenWidth = SHERLOCK_SCREEN_WIDTH; - uint16 screenHeight = SHERLOCK_SCREEN_HEIGHT; - uint16 screenX = 0; - uint16 screenY = 0; - - uint16 currentScreenPixelRed = 0; - uint16 currentScreenPixelGreen = 0; - uint16 currentScreenPixelBlue = 0; - - uint16 limitPixelRed = limitColor & 0xF800; - uint16 limitPixelGreen = limitColor & 0x07E0; - uint16 limitPixelBlue = limitColor & 0x001F; - - for (screenY = 0; screenY < screenHeight; screenY++) { - for (screenX = 0; screenX < screenWidth; screenX++) { - currentScreenPixel = *targetScreenPtr; - - currentScreenPixelRed = currentScreenPixel & 0xF800; - currentScreenPixelGreen = currentScreenPixel & 0x07E0; - currentScreenPixelBlue = currentScreenPixel & 0x001F; - - if (currentScreenPixelRed < limitPixelRed) - currentScreenPixelRed = limitPixelRed; - if (currentScreenPixelGreen < limitPixelGreen) - currentScreenPixelGreen = limitPixelGreen; - if (currentScreenPixelBlue < limitPixelBlue) - currentScreenPixelBlue = limitPixelBlue; - - uint16 v = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; - *currentScreenPtr = v; - if (_vm->_isScreenDoubled) { - *(currentScreenPtr + 1) = v; - *(currentScreenPtr + 640) = v; - *(currentScreenPtr + 640 + 1) = v; - } - - currentScreenPtr += _vm->_isScreenDoubled ? 2 : 1; - targetScreenPtr++; - } - - if (_vm->_isScreenDoubled) - currentScreenPtr += 640; - } - - // Too much considered dirty at the moment - if (_vm->_isScreenDoubled) - addDirtyRect(Common::Rect(0, 0, screenWidth * 2, screenHeight * 2)); - else - addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); -} - -uint16 Scalpel3DOScreen::w() const { - return _vm->_isScreenDoubled ? _surface.w / 2 : _surface.w; -} - -uint16 Scalpel3DOScreen::h() const { - return _vm->_isScreenDoubled ? _surface.h / 2 : _surface.h; -} - -void Scalpel3DOScreen::rawBlitFrom(const Graphics::Surface &src, const Common::Point &pt) { - Common::Rect srcRect(0, 0, src.w, src.h); - Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); - - addDirtyRect(destRect); - _surface.copyRectToSurface(src, destRect.left, destRect.top, srcRect); -} - } // End of namespace Scalpel } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_screen.h b/engines/sherlock/scalpel/scalpel_screen.h index cee33b8c6c..d9be29c8b2 100644 --- a/engines/sherlock/scalpel/scalpel_screen.h +++ b/engines/sherlock/scalpel/scalpel_screen.h @@ -61,44 +61,6 @@ public: void makeField(const Common::Rect &r); }; -class Scalpel3DOScreen : public ScalpelScreen { -protected: - /** - * Draws a sub-section of a surface at a given position within this surface - * Overriden for the 3DO to automatically double the size of everything to the underlying 640x400 surface - */ - virtual void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); - - /** - * Draws a surface at a given position within this surface with transparency - */ - virtual void transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, - int overrideColor); -public: - Scalpel3DOScreen(SherlockEngine *vm) : ScalpelScreen(vm) {} - virtual ~Scalpel3DOScreen() {} - - /** - * Draws a sub-section of a surface at a given position within this surface - */ - void rawBlitFrom(const Graphics::Surface &src, const Common::Point &pt); - - /** - * Fade backbuffer 1 into screen (3DO RGB!) - */ - void fadeIntoScreen3DO(int speed); - - void blitFrom3DOcolorLimit(uint16 color); - - /** - * Fill a given area of the surface with a given color - */ - virtual void fillRect(const Common::Rect &r, uint color); - - virtual uint16 w() const; - virtual uint16 h() const; -}; - } // End of namespace Scalpel } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_user_interface.cpp b/engines/sherlock/scalpel/scalpel_user_interface.cpp index 7ac8d0d5cf..6534f61a87 100644 --- a/engines/sherlock/scalpel/scalpel_user_interface.cpp +++ b/engines/sherlock/scalpel/scalpel_user_interface.cpp @@ -148,23 +148,24 @@ void ScalpelUserInterface::reset() { void ScalpelUserInterface::drawInterface(int bufferNum) { Screen &screen = *_vm->_screen; - const ImageFrame &src = (*_controlPanel)[0]; + const Graphics::Surface &src = (*_controlPanel)[0]._frame; int16 x = (!IS_3DO) ? 0 : UI_OFFSET_3DO; if (bufferNum & 1) { if (IS_3DO) screen._backBuffer1.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BLACK); - screen._backBuffer1.transBlitFrom(src, Common::Point(x, CONTROLS_Y)); + screen._backBuffer1.SHtransBlitFrom(src, Common::Point(x, CONTROLS_Y)); } if (bufferNum & 2) { if (IS_3DO) screen._backBuffer2.fillRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT), BLACK); - screen._backBuffer2.transBlitFrom(src, Common::Point(x, CONTROLS_Y)); + screen._backBuffer2.SHtransBlitFrom(src, Common::Point(x, CONTROLS_Y)); } if (bufferNum == 3) - screen._backBuffer2.fillRect(0, INFO_LINE, SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10, INFO_BLACK); + screen._backBuffer2.SHfillRect(Common::Rect(0, INFO_LINE, + SHERLOCK_SCREEN_WIDTH, INFO_LINE + 10), INFO_BLACK); } void ScalpelUserInterface::handleInput() { @@ -426,7 +427,7 @@ void ScalpelUserInterface::depressButton(int num) { offsetButton3DO(pt, num); ImageFrame &frame = (*_controls)[num]; - screen._backBuffer1.transBlitFrom(frame, pt); + screen._backBuffer1.SHtransBlitFrom(frame, pt); screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height); } @@ -442,7 +443,7 @@ void ScalpelUserInterface::restoreButton(int num) { events.setCursor(ARROW); // Restore the UI on the back buffer - screen._backBuffer1.blitFrom(screen._backBuffer2, pt, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, pt, Common::Rect(pt.x, pt.y, pt.x + 90, pt.y + 19)); screen.slamArea(pt.x, pt.y, pt.x + frame.w, pt.y + frame.h); @@ -489,7 +490,7 @@ void ScalpelUserInterface::toggleButton(uint16 num) { ImageFrame &frame = (*_controls)[num]; Common::Point pt(MENU_POINTS[num][0], MENU_POINTS[num][1]); offsetButton3DO(pt, num); - screen._backBuffer1.transBlitFrom(frame, pt); + screen._backBuffer1.SHtransBlitFrom(frame, pt); screen.slamArea(pt.x, pt.y, pt.x + frame._width, pt.y + frame._height); } } else { @@ -1272,7 +1273,7 @@ void ScalpelUserInterface::doLookControl() { // Need to close the window and depress the Look button Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); offsetButton3DO(pt, 0); - screen._backBuffer2.blitFrom((*_controls)[0], pt); + screen._backBuffer2.SHblitFrom((*_controls)[0], pt); banishWindow(true); _windowBounds.top = CONTROLS_Y1; @@ -1296,14 +1297,14 @@ void ScalpelUserInterface::doLookControl() { // Looking at an inventory object // Backup the user interface Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1); - tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), + tempSurface.SHblitFrom(screen._backBuffer2, Common::Point(0, 0), Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); inv.drawInventory(INVENTORY_DONT_DISPLAY); banishWindow(true); // Restore the ui - screen._backBuffer2.blitFrom(tempSurface, Common::Point(0, CONTROLS_Y1)); + screen._backBuffer2.SHblitFrom(tempSurface, Common::Point(0, CONTROLS_Y1)); _windowBounds.top = CONTROLS_Y1; _key = _oldKey = _hotkeyLook; @@ -1887,7 +1888,7 @@ void ScalpelUserInterface::journalControl() { // Reset the palette screen.setPalette(screen._cMap); - screen._backBuffer1.blitFrom(screen._backBuffer2); + screen._backBuffer1.SHblitFrom(screen._backBuffer2); scene.updateBackground(); screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -1921,9 +1922,9 @@ void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool first Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]); offsetButton3DO(pt, 0); - tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0), - Common::Rect(pt.x, pt.y, pt.x + tempSurface.w(), pt.y + tempSurface.h())); - screen._backBuffer2.transBlitFrom((*_controls)[0], pt); + tempSurface.SHblitFrom(screen._backBuffer2, Common::Point(0, 0), + Common::Rect(pt.x, pt.y, pt.x + tempSurface.width(), pt.y + tempSurface.height())); + screen._backBuffer2.SHtransBlitFrom((*_controls)[0], pt); banishWindow(1); events.setCursor(MAGNIFY); @@ -1933,7 +1934,7 @@ void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool first _menuMode = LOOK_MODE; events.clearEvents(); - screen._backBuffer2.blitFrom(tempSurface, pt); + screen._backBuffer2.SHblitFrom(tempSurface, pt); } else { events.setCursor(ARROW); banishWindow(true); @@ -2071,9 +2072,9 @@ void ScalpelUserInterface::summonWindow(const Surface &bgSurface, bool slideUp) if (slideUp) { // Gradually slide up the display of the window - for (int idx = 1; idx <= bgSurface.h(); idx += 2) { - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), - Common::Rect(0, 0, bgSurface.w(), idx)); + for (int idx = 1; idx <= bgSurface.height(); idx += 2) { + screen._backBuffer->SHblitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - idx), + Common::Rect(0, 0, bgSurface.width(), idx)); screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - idx, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); @@ -2081,21 +2082,21 @@ void ScalpelUserInterface::summonWindow(const Surface &bgSurface, bool slideUp) } } else { // Gradually slide down the display of the window - for (int idx = 1; idx <= bgSurface.h(); idx += 2) { - screen._backBuffer->blitFrom(bgSurface, - Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()), - Common::Rect(0, bgSurface.h() - idx, bgSurface.w(), bgSurface.h())); - screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(), - SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - bgSurface.h() + idx)); + for (int idx = 1; idx <= bgSurface.height(); idx += 2) { + screen._backBuffer->SHblitFrom(bgSurface, + Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.height()), + Common::Rect(0, bgSurface.height() - idx, bgSurface.width(), bgSurface.height())); + screen.slamRect(Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.height(), + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - bgSurface.height() + idx)); events.delay(10); } } // Final display of the entire window - screen._backBuffer->blitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h()), - Common::Rect(0, 0, bgSurface.w(), bgSurface.h())); - screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.h(), bgSurface.w(), bgSurface.h()); + screen._backBuffer->SHblitFrom(bgSurface, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.height()), + Common::Rect(0, 0, bgSurface.width(), bgSurface.height())); + screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - bgSurface.height(), bgSurface.width(), bgSurface.height()); _windowOpen = true; } @@ -2106,10 +2107,10 @@ void ScalpelUserInterface::summonWindow(bool slideUp, int height) { // Extract the window that's been drawn on the back buffer Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - height); Common::Rect r(0, height, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); - tempSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), r); + tempSurface.SHblitFrom(screen._backBuffer1, Common::Point(0, 0), r); // Remove drawn window with original user interface - screen._backBuffer1.blitFrom(screen._backBuffer2, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(0, height), r); // Display the window gradually on-screen @@ -2133,7 +2134,7 @@ void ScalpelUserInterface::banishWindow(bool slideUp) { Common::copy_backward(pSrc, pSrcEnd, pDest); // Restore lines from the ui in the secondary back buffer - screen._backBuffer1.blitFrom(screen._backBuffer2, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, CONTROLS_Y + idx)); @@ -2143,14 +2144,14 @@ void ScalpelUserInterface::banishWindow(bool slideUp) { } // Restore final two old lines - screen._backBuffer1.blitFrom(screen._backBuffer2, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(0, SHERLOCK_SCREEN_HEIGHT - 2), Common::Rect(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamArea(0, SHERLOCK_SCREEN_HEIGHT - 2, SHERLOCK_SCREEN_WIDTH, 2); } else { // Restore old area to completely erase window - screen._backBuffer1.blitFrom(screen._backBuffer2, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y), Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamRect(Common::Rect(0, CONTROLS_Y, SHERLOCK_SCREEN_WIDTH, @@ -2170,7 +2171,7 @@ void ScalpelUserInterface::banishWindow(bool slideUp) { } // Show entire final area - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y1), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(0, CONTROLS_Y1), Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); screen.slamRect(Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); } diff --git a/engines/sherlock/scalpel/tsage/logo.cpp b/engines/sherlock/scalpel/tsage/logo.cpp index 273d26df74..a885057f35 100644 --- a/engines/sherlock/scalpel/tsage/logo.cpp +++ b/engines/sherlock/scalpel/tsage/logo.cpp @@ -217,7 +217,7 @@ void Object::erase() { Screen &screen = *_vm->_screen; if (_visage.isLoaded() && !_oldBounds.isEmpty()) - screen.blitFrom(screen._backBuffer1, Common::Point(_oldBounds.left, _oldBounds.top), _oldBounds); + screen.SHblitFrom(screen._backBuffer1, Common::Point(_oldBounds.left, _oldBounds.top), _oldBounds); } void Object::update() { @@ -246,9 +246,9 @@ void Object::update() { _visage.getFrame(s, _frame); // Display the frame - _oldBounds = Common::Rect(_position.x, _position.y, _position.x + s.w(), _position.y + s.h()); + _oldBounds = Common::Rect(_position.x, _position.y, _position.x + s.width(), _position.y + s.height()); _oldBounds.translate(-s._centroid.x, -s._centroid.y); - screen.transBlitFrom(s, Common::Point(_oldBounds.left, _oldBounds.top)); + screen.SHtransBlitFrom(s, Common::Point(_oldBounds.left, _oldBounds.top)); } } @@ -652,7 +652,7 @@ void Logo::loadBackground() { screen.setPalette(palette); // Copy the surface to the screen - screen.blitFrom(screen._backBuffer1); + screen.SHblitFrom(screen._backBuffer1); } void Logo::fade(const byte palette[PALETTE_SIZE], int step) { diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 6f9ef179a3..78d0cd862c 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -27,6 +27,7 @@ #include "sherlock/scalpel/scalpel_people.h" #include "sherlock/scalpel/scalpel_scene.h" #include "sherlock/scalpel/scalpel_screen.h" +#include "sherlock/scalpel/3do/scalpel_3do_screen.h" #include "sherlock/tattoo/tattoo.h" #include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_user_interface.h" @@ -356,7 +357,7 @@ bool Scene::loadScene(const Common::String &filename) { if (IS_ROSE_TATTOO) { // Resize the screen if necessary int fullWidth = SHERLOCK_SCREEN_WIDTH + bgHeader._scrollSize; - if (screen._backBuffer1.w() != fullWidth) { + if (screen._backBuffer1.width() != fullWidth) { screen._backBuffer1.create(fullWidth, SHERLOCK_SCREEN_HEIGHT); screen._backBuffer2.create(fullWidth, SHERLOCK_SCREEN_HEIGHT); } @@ -649,7 +650,7 @@ bool Scene::loadScene(const Common::String &filename) { } // Backup the image and set the palette - screen._backBuffer2.blitFrom(screen._backBuffer1); + screen._backBuffer2.SHblitFrom(screen._backBuffer1); screen.setPalette(screen._cMap); delete rrmStream; @@ -996,12 +997,12 @@ bool Scene::loadScene(const Common::String &filename) { #if 0 // code to show the background - screen.blitFrom(screen._backBuffer1); + screen.SHblitFrom(screen._backBuffer1); _vm->_events->wait(10000); #endif // Backup the image - screen._backBuffer2.blitFrom(screen._backBuffer1); + screen._backBuffer2.SHblitFrom(screen._backBuffer1); } // Handle drawing any on-screen interface @@ -1236,7 +1237,7 @@ void Scene::transitionToScene() { // If the scene is capable of scrolling, set the current scroll so that whoever has control // of the scroll code is in the middle of the screen - if (screen._backBuffer1.w() > SHERLOCK_SCREEN_WIDTH) + if (screen._backBuffer1.width() > SHERLOCK_SCREEN_WIDTH) people[people._walkControl].centerScreenOnPerson(); for (uint objIdx = 0; objIdx < _bgShapes.size(); ++objIdx) { diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index 74da2a80ea..33e12530ed 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -23,6 +23,8 @@ #include "sherlock/screen.h" #include "sherlock/sherlock.h" #include "sherlock/scalpel/scalpel_screen.h" +#include "sherlock/scalpel/3do/scalpel_3do_screen.h" +#include "sherlock/tattoo/tattoo_screen.h" #include "common/system.h" #include "common/util.h" #include "graphics/palette.h" @@ -31,17 +33,14 @@ namespace Sherlock { Screen *Screen::init(SherlockEngine *vm) { if (vm->getGameID() == GType_RoseTattoo) - return new Screen(vm); + return new Tattoo::TattooScreen(vm); else if (vm->getPlatform() == Common::kPlatform3DO) return new Scalpel::Scalpel3DOScreen(vm); else return new Scalpel::ScalpelScreen(vm); } -Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->getHeight()), _vm(vm), - _backBuffer1(vm->getGameID() == GType_RoseTattoo ? 640 : 320, vm->getGameID() == GType_RoseTattoo ? 480 : 200), - _backBuffer2(vm->getGameID() == GType_RoseTattoo ? 640 : 320, vm->getGameID() == GType_RoseTattoo ? 480 : 200), - _backBuffer(&_backBuffer1) { +Screen::Screen(SherlockEngine *vm) : Graphics::Screen(), _vm(vm), _backBuffer(&_backBuffer1) { _transitionSeed = 1; _fadeStyle = false; Common::fill(&_cMap[0], &_cMap[PALETTE_SIZE], 0); @@ -58,37 +57,7 @@ Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->get } Screen::~Screen() { - Fonts::free(); -} - -void Screen::update() { - // Merge the dirty rects - mergeDirtyRects(); - - // Loop through copying dirty areas to the physical screen - Common::List<Common::Rect>::iterator i; - for (i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) { - const Common::Rect &r = *i; - const byte *srcP = (const byte *)getBasePtr(r.left, r.top); - g_system->copyRectToScreen(srcP, _surface.pitch, r.left, r.top, - r.width(), r.height()); - } - - // Signal the physical screen to update - g_system->updateScreen(); - _dirtyRects.clear(); -} - -void Screen::makeAllDirty() { - addDirtyRect(Common::Rect(0, 0, this->w(), this->h())); -} - -void Screen::getPalette(byte palette[PALETTE_SIZE]) { - g_system->getPaletteManager()->grabPalette(palette, 0, PALETTE_COUNT); -} - -void Screen::setPalette(const byte palette[PALETTE_SIZE]) { - g_system->getPaletteManager()->setPalette(palette, 0, PALETTE_COUNT); + Fonts::freeFont(); } int Screen::equalizePalette(const byte palette[PALETTE_SIZE]) { @@ -124,7 +93,7 @@ void Screen::fadeToBlack(int speed) { } setPalette(tempPalette); - fillRect(Common::Rect(0, 0, _surface.w, _surface.h), 0); + fillRect(Common::Rect(0, 0, this->w, this->h), 0); } void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { @@ -136,59 +105,23 @@ void Screen::fadeIn(const byte palette[PALETTE_SIZE], int speed) { setPalette(palette); } -void Screen::addDirtyRect(const Common::Rect &r) { - _dirtyRects.push_back(r); - assert(r.width() > 0 && r.height() > 0); -} - -void Screen::mergeDirtyRects() { - Common::List<Common::Rect>::iterator rOuter, rInner; - - // Process the dirty rect list to find any rects to merge - for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) { - rInner = rOuter; - while (++rInner != _dirtyRects.end()) { - - if ((*rOuter).intersects(*rInner)) { - // these two rectangles overlap or - // are next to each other - merge them - - unionRectangle(*rOuter, *rOuter, *rInner); - - // remove the inner rect from the list - _dirtyRects.erase(rInner); - - // move back to beginning of list - rInner = rOuter; - } - } - } -} - -bool Screen::unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2) { - destRect = src1; - destRect.extend(src2); - - return !destRect.isEmpty(); -} - void Screen::randomTransition() { Events &events = *_vm->_events; const int TRANSITION_MULTIPLIER = 0x15a4e35; - _dirtyRects.clear(); + clearDirtyRects(); assert(IS_SERRATED_SCALPEL); for (int idx = 0; idx <= 65535 && !_vm->shouldQuit(); ++idx) { _transitionSeed = _transitionSeed * TRANSITION_MULTIPLIER + 1; int offset = _transitionSeed & 0xFFFF; - if (offset < (this->w() * this->h())) + if (offset < (this->width() * this->height())) *((byte *)getPixels() + offset) = *((const byte *)_backBuffer->getPixels() + offset); if (idx != 0 && (idx % 300) == 0) { // Ensure there's a full screen dirty rect for the next frame update - if (_dirtyRects.empty()) - addDirtyRect(Common::Rect(0, 0, _surface.w, _surface.h)); + if (!isDirty()) + addDirtyRect(Common::Rect(0, 0, this->w, this->h)); events.pollEvents(); events.delay(1); @@ -196,7 +129,7 @@ void Screen::randomTransition() { } // Make sure everything has been transferred - blitFrom(*_backBuffer); + SHblitFrom(*_backBuffer); } void Screen::verticalTransition() { @@ -205,13 +138,13 @@ void Screen::verticalTransition() { byte table[640]; Common::fill(&table[0], &table[640], 0); - for (int yp = 0; yp < this->h(); ++yp) { - for (int xp = 0; xp < this->w(); ++xp) { - int temp = (table[xp] >= (this->h() - 3)) ? this->h() - table[xp] : + for (int yp = 0; yp < this->height(); ++yp) { + for (int xp = 0; xp < this->width(); ++xp) { + int temp = (table[xp] >= (this->height() - 3)) ? this->height() - table[xp] : _vm->getRandomNumber(3) + 1; if (temp) { - blitFrom(_backBuffer1, Common::Point(xp, table[xp]), + SHblitFrom(_backBuffer1, Common::Point(xp, table[xp]), Common::Rect(xp, table[xp], xp + 1, table[xp] + temp)); table[xp] += temp; } @@ -223,7 +156,7 @@ void Screen::verticalTransition() { void Screen::restoreBackground(const Common::Rect &r) { if (r.width() > 0 && r.height() > 0) - _backBuffer->blitFrom(_backBuffer2, Common::Point(r.left, r.top), r); + _backBuffer->SHblitFrom(_backBuffer2, Common::Point(r.left, r.top), r); } void Screen::slamArea(int16 xp, int16 yp, int16 width, int16 height) { @@ -254,11 +187,10 @@ void Screen::slamRect(const Common::Rect &r) { } if (srcRect.isValidRect()) - blitFrom(*_backBuffer, Common::Point(destRect.left, destRect.top), srcRect); + SHblitFrom(*_backBuffer, Common::Point(destRect.left, destRect.top), srcRect); } } - void Screen::flushImage(ImageFrame *frame, const Common::Point &pt, int16 *xp, int16 *yp, int16 *width, int16 *height) { Common::Point imgPos = pt + frame->_offset; @@ -335,7 +267,7 @@ void Screen::blockMove(const Common::Rect &r) { } void Screen::blockMove() { - blockMove(Common::Rect(0, 0, w(), h())); + blockMove(Common::Rect(0, 0, width(), height())); } void Screen::print(const Common::Point &pt, uint color, const char *formatStr, ...) { @@ -351,13 +283,13 @@ void Screen::print(const Common::Point &pt, uint color, const char *formatStr, . pos.y--; // Font is always drawing one line higher if (!pos.x) // Center text horizontally - pos.x = (this->w() - width) / 2; + pos.x = (this->width() - width) / 2; Common::Rect textBounds(pos.x, pos.y, pos.x + width, pos.y + _fontHeight); - if (textBounds.right > this->w()) - textBounds.moveTo(this->w() - width, textBounds.top); - if (textBounds.bottom > this->h()) - textBounds.moveTo(textBounds.left, this->h() - _fontHeight); + if (textBounds.right > this->width()) + textBounds.moveTo(this->width() - width, textBounds.top); + if (textBounds.bottom > this->height()) + textBounds.moveTo(textBounds.left, this->height() - _fontHeight); // Write out the string at the given position writeString(str, Common::Point(textBounds.left, textBounds.top), color); @@ -387,7 +319,8 @@ void Screen::vgaBar(const Common::Rect &r, int color) { } void Screen::setDisplayBounds(const Common::Rect &r) { - _sceneSurface.setPixels(_backBuffer1.getBasePtr(r.left, r.top), r.width(), r.height(), _backBuffer1.getPixelFormat()); + _sceneSurface.setPixelsData((byte *)_backBuffer1.getBasePtr(r.left, r.top), + r.width(), r.height(), _backBuffer1.format); _backBuffer = &_sceneSurface; } @@ -397,8 +330,8 @@ void Screen::resetDisplayBounds() { } Common::Rect Screen::getDisplayBounds() { - return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.w(), _sceneSurface.h()) : - Common::Rect(0, 0, this->w(), this->h()); + return (_backBuffer == &_sceneSurface) ? Common::Rect(0, 0, _sceneSurface.width(), _sceneSurface.height()) : + Common::Rect(0, 0, this->width(), this->height()); } void Screen::synchronize(Serializer &s) { diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 04a0c1e505..ceeb1297a3 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -25,52 +25,30 @@ #include "common/list.h" #include "common/rect.h" +#include "graphics/screen.h" +#include "sherlock/image_file.h" #include "sherlock/surface.h" #include "sherlock/resources.h" #include "sherlock/saveload.h" namespace Sherlock { -#define PALETTE_SIZE 768 -#define PALETTE_COUNT 256 #define VGA_COLOR_TRANS(x) ((x) * 255 / 63) #define BG_GREYSCALE_RANGE_END 229 #define BLACK 0 class SherlockEngine; -class Screen : public Surface { +class Screen : virtual public Graphics::Screen, virtual public Surface { private: - Common::List<Common::Rect> _dirtyRects; uint32 _transitionSeed; Surface _sceneSurface; // Rose Tattoo fields int _fadeBytesRead, _fadeBytesToRead; int _oldFadePercent; -private: - /** - * Merges together overlapping dirty areas of the screen - */ - void mergeDirtyRects(); - - /** - * Returns the union of two dirty area rectangles - */ - bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2); protected: SherlockEngine *_vm; - - /** - * Clear the current dirty rects list - */ - void clearDirtyRects() { _dirtyRects.clear(); } - - /** - * Adds a rectangle to the list of modified areas of the screen during the - * current frame - */ - virtual void addDirtyRect(const Common::Rect &r); public: Surface _backBuffer1, _backBuffer2; Surface *_backBuffer; @@ -86,26 +64,6 @@ public: virtual ~Screen(); /** - * Handles updating any dirty areas of the screen Surface object to the physical screen - */ - void update(); - - /** - * Makes the whole screen dirty - */ - void makeAllDirty(); - - /** - * Return the currently active palette - */ - void getPalette(byte palette[PALETTE_SIZE]); - - /** - * Set the palette - */ - void setPalette(const byte palette[PALETTE_SIZE]); - - /** * Fades from the currently active palette to the passed palette */ int equalizePalette(const byte palette[PALETTE_SIZE]); diff --git a/engines/sherlock/sherlock.h b/engines/sherlock/sherlock.h index b85321c385..d3b2d0cac8 100644 --- a/engines/sherlock/sherlock.h +++ b/engines/sherlock/sherlock.h @@ -63,9 +63,9 @@ enum GameType { GType_RoseTattoo = 1 }; -#define SHERLOCK_SCREEN_WIDTH _vm->_screen->w() -#define SHERLOCK_SCREEN_HEIGHT _vm->_screen->h() -#define SHERLOCK_SCENE_WIDTH _vm->_screen->_backBuffer1.w() +#define SHERLOCK_SCREEN_WIDTH _vm->_screen->width() +#define SHERLOCK_SCREEN_HEIGHT _vm->_screen->height() +#define SHERLOCK_SCENE_WIDTH _vm->_screen->_backBuffer1.width() #define SHERLOCK_SCENE_HEIGHT (IS_SERRATED_SCALPEL ? 138 : 480) #define SCENES_COUNT (IS_SERRATED_SCALPEL ? 63 : 101) #define MAX_BGSHAPES (IS_SERRATED_SCALPEL ? 64 : 150) diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index b7fc76325c..b9df33a309 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -21,245 +21,24 @@ */ #include "sherlock/surface.h" -#include "sherlock/sherlock.h" -#include "sherlock/resources.h" -#include "common/system.h" -#include "graphics/palette.h" +#include "sherlock/fonts.h" namespace Sherlock { -Surface::Surface(uint16 width, uint16 height) : Fonts(), _freePixels(true) { - create(width, height); -} - -Surface::Surface() : Fonts(), _freePixels(false) { -} - -Surface::~Surface() { - if (_freePixels) - _surface.free(); -} - -void Surface::create(uint16 width, uint16 height) { - if (_freePixels) - _surface.free(); - - if (_vm->getPlatform() == Common::kPlatform3DO) { - _surface.create(width, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); - } else { - _surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - } - _freePixels = true; -} - -Graphics::PixelFormat Surface::getPixelFormat() { - return _surface.format; -} - -void Surface::blitFrom(const Surface &src) { - blitFrom(src, Common::Point(0, 0)); -} - -void Surface::blitFrom(const ImageFrame &src) { - blitFrom(src._frame, Common::Point(0, 0)); -} - -void Surface::blitFrom(const Graphics::Surface &src) { - blitFrom(src, Common::Point(0, 0)); -} - -void Surface::blitFrom(const Surface &src, const Common::Point &pt) { - blitFrom(src, pt, Common::Rect(0, 0, src._surface.w, src._surface.h)); -} - -void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt) { - blitFrom(src._frame, pt, Common::Rect(0, 0, src._frame.w, src._frame.h)); -} - -void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt) { - blitFrom(src, pt, Common::Rect(0, 0, src.w, src.h)); -} - -void Surface::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { - Common::Rect srcRect = srcBounds; - Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); - - if (srcRect.isValidRect() && clip(srcRect, destRect)) { - // Surface is at least partially or completely on-screen - addDirtyRect(destRect); - _surface.copyRectToSurface(src, destRect.left, destRect.top, srcRect); - } -} - -void Surface::blitFrom(const ImageFrame &src, const Common::Point &pt, const Common::Rect &srcBounds) { - blitFrom(src._frame, pt, srcBounds); -} - -void Surface::blitFrom(const Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { - blitFrom(src._surface, pt, srcBounds); -} - -void Surface::transBlitFrom(const ImageFrame &src, const Common::Point &pt, - bool flipped, int overrideColor, int scaleVal) { - Common::Point drawPt(pt.x + src.sDrawXOffset(scaleVal), pt.y + src.sDrawYOffset(scaleVal)); - transBlitFrom(src._frame, drawPt, flipped, overrideColor, scaleVal); -} - -void Surface::transBlitFrom(const Surface &src, const Common::Point &pt, - bool flipped, int overrideColor, int scaleVal) { - const Graphics::Surface &s = src._surface; - transBlitFrom(s, pt, flipped, overrideColor, scaleVal); -} - -void Surface::transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, - bool flipped, int overrideColor, int scaleVal) { - if (scaleVal == SCALE_THRESHOLD) { - transBlitFromUnscaled(src, pt, flipped, overrideColor); - return; - } - - int destWidth = src.w * SCALE_THRESHOLD / scaleVal; - int destHeight = src.h * SCALE_THRESHOLD / scaleVal; - - // Loop through drawing output lines - for (int destY = pt.y, scaleYCtr = 0; destY < (pt.y + destHeight); ++destY, scaleYCtr += scaleVal) { - if (destY < 0 || destY >= this->h()) - continue; - const byte *srcLine = (const byte *)src.getBasePtr(0, scaleYCtr / SCALE_THRESHOLD); - byte *destLine = (byte *)getBasePtr(pt.x, destY); - - // Loop through drawing individual rows - for (int xCtr = 0, scaleXCtr = 0; xCtr < destWidth; ++xCtr, scaleXCtr += scaleVal) { - int destX = pt.x + xCtr; - if (destX < 0 || destX >= this->w()) - continue; - - byte srcVal = srcLine[flipped ? src.w - scaleXCtr / SCALE_THRESHOLD - 1 : scaleXCtr / SCALE_THRESHOLD]; - if (srcVal != TRANSPARENCY) - destLine[xCtr] = srcVal; - } - } - - // Mark the affected area - addDirtyRect(Common::Rect(pt.x, pt.y, pt.x + destWidth, pt.y + destHeight)); -} - -void Surface::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, - bool flipped, int overrideColor) { - Common::Rect drawRect(0, 0, src.w, src.h); - Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); - - // Clip the display area to on-screen - if (!clip(drawRect, destRect)) - // It's completely off-screen - return; - - if (flipped) - drawRect = Common::Rect(src.w - drawRect.right, drawRect.top, - src.w - drawRect.left, drawRect.bottom); - - Common::Point destPt(destRect.left, destRect.top); - addDirtyRect(Common::Rect(destPt.x, destPt.y, destPt.x + drawRect.width(), - destPt.y + drawRect.height())); - - switch (src.format.bytesPerPixel) { - case 1: - // 8-bit palettized: Draw loop - assert(_surface.format.bytesPerPixel == 1); // Security check - for (int yp = 0; yp < drawRect.height(); ++yp) { - const byte *srcP = (const byte *)src.getBasePtr( - flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); - byte *destP = (byte *)getBasePtr(destPt.x, destPt.y + yp); - - for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { - if (*srcP != TRANSPARENCY) - *destP = overrideColor ? overrideColor : *srcP; - - srcP = flipped ? srcP - 1 : srcP + 1; - } - } - break; - case 2: - // 3DO 15-bit RGB565: Draw loop - assert(_surface.format.bytesPerPixel == 2); // Security check - for (int yp = 0; yp < drawRect.height(); ++yp) { - const uint16 *srcP = (const uint16 *)src.getBasePtr( - flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); - uint16 *destP = (uint16 *)getBasePtr(destPt.x, destPt.y + yp); - - for (int xp = 0; xp < drawRect.width(); ++xp, ++destP) { - if (*srcP) // RGB 0, 0, 0 -> transparent on 3DO - *destP = *srcP; // overrideColor ? overrideColor : *srcP; - - srcP = flipped ? srcP - 1 : srcP + 1; - } - } - break; - default: - error("Surface: unsupported bytesperpixel"); - break; - } +Surface::Surface() : Graphics::ManagedSurface(), Fonts() { } -void Surface::fillRect(int x1, int y1, int x2, int y2, uint color) { - fillRect(Common::Rect(x1, y1, x2, y2), color); -} - -void Surface::fillRect(const Common::Rect &r, uint color) { - _surface.fillRect(r, color); - addDirtyRect(r); -} - -void Surface::fill(uint color) { - fillRect(Common::Rect(_surface.w, _surface.h), color); -} - -bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { - if (destBounds.left >= w() || destBounds.top >= h() || - destBounds.right <= 0 || destBounds.bottom <= 0) - return false; - - // Clip the bounds if necessary to fit on-screen - if (destBounds.right > w()) { - srcBounds.right -= destBounds.right - w(); - destBounds.right = w(); - } - - if (destBounds.bottom > h()) { - srcBounds.bottom -= destBounds.bottom - h(); - destBounds.bottom = h(); - } - - if (destBounds.top < 0) { - srcBounds.top += -destBounds.top; - destBounds.top = 0; - } - - if (destBounds.left < 0) { - srcBounds.left += -destBounds.left; - destBounds.left = 0; - } - - return true; -} - -void Surface::clear() { - fillRect(Common::Rect(0, 0, w(), h()), 0); -} - -void Surface::free() { - if (_freePixels) { - _surface.free(); - _freePixels = false; - } +Surface::Surface(int width, int height) : Graphics::ManagedSurface(width, height), + Fonts() { + create(width, height); } -void Surface::setPixels(byte *pixels, int width, int height, Graphics::PixelFormat pixelFormat) { - _surface.format = pixelFormat; - _surface.w = width; - _surface.h = height; - _surface.pitch = width * pixelFormat.bytesPerPixel; - _surface.setPixels(pixels); +void Surface::setPixelsData(byte *pixelsPtr, int sizeX, int sizeY, const Graphics::PixelFormat &pixFormat) { + Graphics::ManagedSurface::setPixels(pixelsPtr); + this->format = pixFormat; + this->w = sizeX; + this->h = sizeY; + this->pitch = sizeX * pixFormat.bytesPerPixel; } void Surface::writeString(const Common::String &str, const Common::Point &pt, uint overrideColor) { @@ -278,4 +57,21 @@ void Surface::writeFancyString(const Common::String &str, const Common::Point &p writeString(str, Common::Point(pt.x + 1, pt.y + 1), overrideColor2); } +void Surface::SHtransBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped, int overrideColor, int scaleVal) { + Common::Point drawPt(pt.x + src.sDrawXOffset(scaleVal), pt.y + src.sDrawYOffset(scaleVal)); + SHtransBlitFrom(src._frame, drawPt, flipped, overrideColor, scaleVal); +} + +void Surface::SHtransBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped, int overrideColor, int scaleVal) { + Common::Rect srcRect(0, 0, src.w, src.h); + Common::Rect destRect(pt.x, pt.y, pt.x + src.w * SCALE_THRESHOLD / scaleVal, + pt.y + src.h * SCALE_THRESHOLD / scaleVal); + + Graphics::ManagedSurface::transBlitFrom(src, srcRect, destRect, TRANSPARENCY, + flipped, overrideColor); +} + + } // End of namespace Sherlock diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index 378c9be9cd..856d0edc9b 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -20,165 +20,101 @@ * */ -#ifndef SHERLOCK_GRAPHICS_H -#define SHERLOCK_GRAPHICS_H +#ifndef SHERLOCK_SURFACE_H +#define SHERLOCK_SURFACE_H #include "common/rect.h" #include "common/platform.h" -#include "graphics/surface.h" +#include "graphics/managed_surface.h" #include "sherlock/fonts.h" +#include "sherlock/image_file.h" namespace Sherlock { #define SCALE_THRESHOLD 0x100 #define TRANSPARENCY 255 -struct ImageFrame; - -class Surface: public Fonts { -private: - bool _freePixels; - - /** - * Copy a surface into this one - */ - void blitFrom(const Graphics::Surface &src); -protected: - Graphics::Surface _surface; - - /** - * Clips the given source bounds so the passed destBounds will be entirely on-screen - */ - bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); - - /** - * Base method stub for signalling dirty rect areas - */ - virtual void addDirtyRect(const Common::Rect &r) {} - - /** - * Draws a sub-section of a surface at a given position within this surface - */ - virtual void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); - +/** + * Implements a descendent surface that combines both a managed surface and the font + * drawing code. It also introduces a series of drawing method stubs that the 3DO + * Serrated Scalpel screen overrides to implement sprite doubling + */ +class Surface: virtual public Graphics::ManagedSurface, public Fonts { +public: /** - * Draws a surface at a given position within this surface with transparency + * Constructor */ - virtual void transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, - int overrideColor); -public: - Surface(uint16 width, uint16 height); Surface(); - virtual ~Surface(); - + /** - * Sets up an internal surface with the specified dimensions that will be automatically freed - * when the surface object is destroyed + * Constructor */ - void create(uint16 width, uint16 height); - - Graphics::PixelFormat getPixelFormat(); + Surface(int width, int height); /** - * Copy a surface into this one + * Set the surface details */ - void blitFrom(const Surface &src); + void setPixelsData(byte *pixelsPtr, int sizeX, int sizeY, const Graphics::PixelFormat &pixFormat); /** - * Copy an image frame into this surface + * Draws a surface on this surface */ - void blitFrom(const ImageFrame &src); + virtual void SHblitFrom(const Graphics::Surface &src) { + Graphics::ManagedSurface::blitFrom(src); + } /** * Draws a surface at a given position within this surface */ - void blitFrom(const Surface &src, const Common::Point &pt); - - /** - * Copy an image frame onto this surface at a given position - */ - void blitFrom(const ImageFrame &src, const Common::Point &pt); + virtual void SHblitFrom(const Graphics::Surface &src, const Common::Point &destPos) { + Graphics::ManagedSurface::blitFrom(src, destPos); + } /** * Draws a sub-section of a surface at a given position within this surface */ - void blitFrom(const Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); - - /** - * Copy a sub-area of a source image frame into this surface at a given position - */ - void blitFrom(const ImageFrame &src, const Common::Point &pt, const Common::Rect &srcBounds); - - /** - * Draws a surface at a given position within this surface - */ - void blitFrom(const Graphics::Surface &src, const Common::Point &pt); + virtual void SHblitFrom(const Graphics::Surface &src, const Common::Point &destPos, const Common::Rect &srcBounds) { + Graphics::ManagedSurface::blitFrom(src, srcBounds, destPos); + } /** * Draws an image frame at a given position within this surface with transparency */ - void transBlitFrom(const ImageFrame &src, const Common::Point &pt, - bool flipped = false, int overrideColor = 0, int scaleVal = 256); - - /** - * Draws a surface at a given position within this surface with transparency - */ - void transBlitFrom(const Surface &src, const Common::Point &pt, - bool flipped = false, int overrideColor = 0, int scaleVal = 256); + void SHtransBlitFrom(const ImageFrame &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0, int scaleVal = SCALE_THRESHOLD); /** - * Draws a surface at a given position within this surface with transparency + * Draws an image frame at a given position within this surface with transparency */ - void transBlitFrom(const Graphics::Surface &src, const Common::Point &pt, - bool flipped = false, int overrideColor = 0, int scaleVal = 256); + void SHtransBlitFrom(const Graphics::Surface &src, const Common::Point &pt, + bool flipped = false, int overrideColor = 0, int scaleVal = SCALE_THRESHOLD); /** * Fill a given area of the surface with a given color */ - void fillRect(int x1, int y1, int x2, int y2, uint color); - - /** - * Fill a given area of the surface with a given color - */ - virtual void fillRect(const Common::Rect &r, uint color); - - void fill(uint color); - - /** - * Clear the surface - */ - void clear(); + virtual void SHfillRect(const Common::Rect &r, uint color) { + Graphics::ManagedSurface::fillRect(r, color); + } /** - * Free the underlying surface + * Return the width of the surface */ - void free(); - + virtual uint16 width() const { return this->w; } + /** - * Returns true if the surface is empty + * Return the height of the surface */ - bool empty() const { return _surface.getPixels() == nullptr; } + virtual uint16 height() const { return this->h; } /** - * Set the pixels for the surface to an existing data block + * Draws the given string into the back buffer using the images stored in _font */ - void setPixels(byte *pixels, int width, int height, Graphics::PixelFormat format); - + void writeString(const Common::String &str, const Common::Point &pt, uint overrideColor); + /** - * Draws the given string into the back buffer using the images stored in _font + * Draws a fancy version of the given string at the given position */ - virtual void writeString(const Common::String &str, const Common::Point &pt, uint overrideColor); void writeFancyString(const Common::String &str, const Common::Point &pt, uint overrideColor1, uint overrideColor2); - - inline virtual uint16 w() const { return _surface.w; } - inline virtual uint16 h() const { return _surface.h; } - inline const byte *getPixels() const { return (const byte *)_surface.getPixels(); } - inline byte *getPixels() { return (byte *)_surface.getPixels(); } - inline byte *getBasePtr(int x, int y) { return (byte *)_surface.getBasePtr(x, y); } - inline const byte *getBasePtr(int x, int y) const { return (const byte *)_surface.getBasePtr(x, y); } - inline Graphics::Surface &getRawSurface() { return _surface; } - inline void hLine(int x, int y, int x2, uint color) { _surface.hLine(x, y, x2, color); } - inline void vLine(int x, int y, int y2, uint color) { _surface.vLine(x, y, y2, color); } }; } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_darts.cpp b/engines/sherlock/tattoo/tattoo_darts.cpp index 0a815af39e..cbc3ea1fe8 100644 --- a/engines/sherlock/tattoo/tattoo_darts.cpp +++ b/engines/sherlock/tattoo/tattoo_darts.cpp @@ -163,7 +163,7 @@ void Darts::playDarts(GameType gameType) { // Show scores showStatus(playerNum); - screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1), + screen._backBuffer2.SHblitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1), Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1)); screen.print(Common::Point(_dartInfo.left, _dartInfo.top), 0, FIXED(DartsCurrentDart), idx + 1); @@ -267,10 +267,11 @@ void Darts::playDarts(GameType gameType) { } else { events.wait(40); } + // Clears the status part of the board - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_dartInfo.left, _dartInfo.top - 1), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(_dartInfo.left, _dartInfo.top - 1), Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1)); - screen.blitFrom(screen._backBuffer1); + screen.SHblitFrom(screen._backBuffer1); } playerNum ^= 1; @@ -278,9 +279,9 @@ void Darts::playDarts(GameType gameType) { ++_roundNum; if (!done) { - screen._backBuffer2.blitFrom((*_dartBoard)[0], Common::Point(0, 0)); - screen._backBuffer1.blitFrom(screen._backBuffer2); - screen.blitFrom(screen._backBuffer2); + screen._backBuffer2.SHblitFrom((*_dartBoard)[0], Common::Point(0, 0)); + screen._backBuffer1.SHblitFrom(screen._backBuffer2); + screen.SHblitFrom(screen._backBuffer2); } } @@ -367,9 +368,9 @@ void Darts::loadDarts() { delete stream; // Load the initial background - screen._backBuffer1.blitFrom((*_dartBoard)[0], Common::Point(0, 0)); - screen._backBuffer2.blitFrom(screen._backBuffer1); - screen.blitFrom(screen._backBuffer1); + screen._backBuffer1.SHblitFrom((*_dartBoard)[0], Common::Point(0, 0)); + screen._backBuffer2.SHblitFrom(screen._backBuffer1); + screen.SHblitFrom(screen._backBuffer1); } void Darts::closeDarts() { @@ -399,14 +400,14 @@ void Darts::showNames(int playerNum) { screen.fillRect(Common::Rect(STATUS2_INFO_X, STATUS_INFO_Y + _spacing + 1, STATUS2_INFO_X + 50, STATUS_INFO_Y + _spacing + 3), color); - screen._backBuffer2.blitFrom(screen._backBuffer1); + screen._backBuffer2.SHblitFrom(screen._backBuffer1); } void Darts::showStatus(int playerNum) { Screen &screen = *_vm->_screen; const char *const CRICKET_SCORE_NAME[7] = { "20", "19", "18", "17", "16", "15", FIXED(DartsBull) }; - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, STATUS_INFO_X + STATUS_INFO_WIDTH, STATUS_INFO_Y + STATUS_INFO_HEIGHT - 10)); screen.print(Common::Point(STATUS_INFO_X + 30, STATUS_INFO_Y + _spacing + 4), 0, "%d", _score1); @@ -447,7 +448,7 @@ void Darts::showStatus(int playerNum) { } } - screen.blitFrom(screen._backBuffer1, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), + screen.SHblitFrom(screen._backBuffer1, Common::Point(STATUS_INFO_X, STATUS_INFO_Y + 10), Common::Rect(STATUS_INFO_X, STATUS_INFO_Y + 10, STATUS_INFO_X + STATUS_INFO_WIDTH, STATUS_INFO_Y + STATUS_INFO_HEIGHT - 10)); } @@ -457,7 +458,7 @@ void Darts::erasePowerBars() { // Erase the old power bars and replace them with empty ones screen._backBuffer1.fillRect(Common::Rect(DART_BAR_VX, DART_HEIGHT_Y, DART_BAR_VX + 9, DART_HEIGHT_Y + DART_BAR_SIZE), 0); - screen._backBuffer1.transBlitFrom((*_dartGraphics)[0], Common::Point(DART_BAR_VX - 1, DART_HEIGHT_Y - 1)); + screen._backBuffer1.SHtransBlitFrom((*_dartGraphics)[0], Common::Point(DART_BAR_VX - 1, DART_HEIGHT_Y - 1)); screen.slamArea(DART_BAR_VX - 1, DART_HEIGHT_Y - 1, 10, DART_BAR_SIZE + 2); } @@ -497,7 +498,7 @@ int Darts::doPowerBar(const Common::Point &pt, byte color, int goToPower, int or } screen._backBuffer1.hLine(pt.x, pt.y + DART_BAR_SIZE- 1 - idx, pt.x + 8, color); - screen._backBuffer1.transBlitFrom((*_dartGraphics)[0], Common::Point(pt.x - 1, pt.y - 1)); + screen._backBuffer1.SHtransBlitFrom((*_dartGraphics)[0], Common::Point(pt.x - 1, pt.y - 1)); screen.slamArea(pt.x, pt.y + DART_BAR_SIZE - 1 - idx, 8, 2); if (!(idx % 8)) @@ -544,7 +545,7 @@ int Darts::drawHand(int goToPower, int computer) { break; } - screen._backBuffer1.transBlitFrom((*hands)[0], pt); + screen._backBuffer1.SHtransBlitFrom((*hands)[0], pt); screen.slamArea(pt.x - 1, pt.y, _handSize.x + 1, _handSize.y); screen.restoreBackground(Common::Rect(pt.x, pt.y, pt.x + _handSize.x, pt.y + _handSize.y)); @@ -631,7 +632,7 @@ void Darts::drawDartThrow(const Common::Point &dartPos, int computer) { _handSize.y = hands[idx]._offset.y + hands[idx]._height; int handCy = SHERLOCK_SCREEN_HEIGHT - _handSize.y; - screen._backBuffer1.transBlitFrom(hands[idx], Common::Point(_handX, handCy)); + screen._backBuffer1.SHtransBlitFrom(hands[idx], Common::Point(_handX, handCy)); screen.slamArea(_handX, handCy, _handSize.x + 1, _handSize.y); screen.slamArea(handOCx, handOCy, handOldxSize, handOldySize); screen.restoreBackground(Common::Rect(_handX, handCy, _handX + _handSize.x, handCy + _handSize.y)); @@ -653,7 +654,7 @@ void Darts::drawDartThrow(const Common::Point &dartPos, int computer) { ocy = drawPos.y = cy - (*_dartGraphics)[dartNum]._height; // Draw dart - screen._backBuffer1.transBlitFrom((*_dartGraphics)[dartNum], drawPos); + screen._backBuffer1.SHtransBlitFrom((*_dartGraphics)[dartNum], drawPos); if (drawPos.x < 0) { xSize += drawPos.x; @@ -675,7 +676,7 @@ void Darts::drawDartThrow(const Common::Point &dartPos, int computer) { // Flush the erased dart area screen.slamArea(oldDrawPos.x, oldDrawPos.y, oldxSize, oldySize); - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(drawPos.x, drawPos.y), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(drawPos.x, drawPos.y), Common::Rect(drawPos.x, drawPos.y, drawPos.x + xSize, drawPos.y + ySize)); oldDrawPos.x = drawPos.x; @@ -696,7 +697,7 @@ void Darts::drawDartThrow(const Common::Point &dartPos, int computer) { if (oldDrawPos.x != -1) screen.slamArea(oldDrawPos.x, oldDrawPos.y, oldxSize, oldySize); - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(drawPos.x, drawPos.y), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(drawPos.x, drawPos.y), Common::Rect(drawPos.x, drawPos.y, drawPos.x + xSize, drawPos.y + ySize)); cx = dartPos.x; @@ -722,7 +723,7 @@ void Darts::drawDartThrow(const Common::Point &dartPos, int computer) { ocx = drawPos.x = cx - (*_dartGraphics)[dartNum]._width / 2; ocy = drawPos.y = cy - (*_dartGraphics)[dartNum]._height; - screen._backBuffer1.transBlitFrom((*_dartGraphics)[dartNum], Common::Point(drawPos.x, drawPos.y)); + screen._backBuffer1.SHtransBlitFrom((*_dartGraphics)[dartNum], Common::Point(drawPos.x, drawPos.y)); if (drawPos.x < 0) { xSize += drawPos.x; @@ -744,7 +745,7 @@ void Darts::drawDartThrow(const Common::Point &dartPos, int computer) { screen.slamArea(oldDrawPos.x, oldDrawPos.y, oldxSize, oldySize); if (idx != 23) - screen._backBuffer1.blitFrom(screen._backBuffer2, drawPos, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, drawPos, Common::Rect(drawPos.x, drawPos.y, drawPos.x + xSize, drawPos.y + ySize)); // erase dart events.wait(1); @@ -761,8 +762,8 @@ void Darts::drawDartThrow(const Common::Point &dartPos, int computer) { ySize = (*_dartGraphics)[dartNum]._height; // Draw final dart on the board - screen._backBuffer1.transBlitFrom((*_dartGraphics)[dartNum], Common::Point(ocx, ocy)); - screen._backBuffer2.transBlitFrom((*_dartGraphics)[dartNum], Common::Point(ocx, ocy)); + screen._backBuffer1.SHtransBlitFrom((*_dartGraphics)[dartNum], Common::Point(ocx, ocy)); + screen._backBuffer2.SHtransBlitFrom((*_dartGraphics)[dartNum], Common::Point(ocx, ocy)); screen.slamArea(ocx, ocy, xSize, ySize); } @@ -955,9 +956,9 @@ int Darts::throwDart(int dartNum, int computer) { } drawDartsLeft(dartNum + 1, computer); - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_dartInfo.left, _dartInfo.top - 1), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(_dartInfo.left, _dartInfo.top - 1), Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1)); - screen.blitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1), + screen.SHblitFrom(screen._backBuffer1, Common::Point(_dartInfo.left, _dartInfo.top - 1), Common::Rect(_dartInfo.left, _dartInfo.top - 1, _dartInfo.right, _dartInfo.bottom - 1)); if (computer) { @@ -979,7 +980,7 @@ int Darts::throwDart(int dartNum, int computer) { height = 101 - height; // Copy power bars to the secondary back buffer - screen._backBuffer2.blitFrom(screen._backBuffer1, Common::Point(DART_BAR_VX - 1, DART_HEIGHT_Y - 1), + screen._backBuffer2.SHblitFrom(screen._backBuffer1, Common::Point(DART_BAR_VX - 1, DART_HEIGHT_Y - 1), Common::Rect(DART_BAR_VX - 1, DART_HEIGHT_Y - 1, DART_BAR_VX - 1 + 10, DART_HEIGHT_Y - 1 + DART_BAR_SIZE + 2)); @@ -1023,14 +1024,14 @@ void Darts::drawDartsLeft(int dartNum, int computer) { const int DART_X2[3] = { 393, 441, 502 }; const int DART_Y2[3] = { 373, 373, 373 }; - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(DART_X1[0], DART_Y1[0]), + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(DART_X1[0], DART_Y1[0]), Common::Rect(DART_X1[0], DART_Y1[0], SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); for (int idx = 2; idx >= dartNum - 1; --idx) { if (computer) - screen._backBuffer1.transBlitFrom((*_dartsLeft)[idx + 3], Common::Point(DART_X2[idx], DART_Y2[idx])); + screen._backBuffer1.SHtransBlitFrom((*_dartsLeft)[idx + 3], Common::Point(DART_X2[idx], DART_Y2[idx])); else - screen._backBuffer1.transBlitFrom((*_dartsLeft)[idx], Common::Point(DART_X1[idx], DART_Y1[idx])); + screen._backBuffer1.SHtransBlitFrom((*_dartsLeft)[idx], Common::Point(DART_X1[idx], DART_Y1[idx])); } screen.slamArea(DART_X1[0], DART_Y1[0], SHERLOCK_SCREEN_WIDTH - DART_X1[0], SHERLOCK_SCREEN_HEIGHT - DART_Y1[0]); diff --git a/engines/sherlock/tattoo/tattoo_journal.cpp b/engines/sherlock/tattoo/tattoo_journal.cpp index dac0760ad2..918887f320 100644 --- a/engines/sherlock/tattoo/tattoo_journal.cpp +++ b/engines/sherlock/tattoo/tattoo_journal.cpp @@ -65,7 +65,7 @@ void TattooJournal::show() { delete stream; // Set screen to black, and set background - screen._backBuffer1.blitFrom((*_journalImages)[0], Common::Point(0, 0)); + screen._backBuffer1.SHblitFrom((*_journalImages)[0], Common::Point(0, 0)); screen.empty(); screen.setPalette(palette); @@ -461,7 +461,7 @@ void TattooJournal::loadLocations() { void TattooJournal::drawFrame() { Screen &screen = *_vm->_screen; - screen._backBuffer1.blitFrom((*_journalImages)[0], Common::Point(0, 0)); + screen._backBuffer1.SHblitFrom((*_journalImages)[0], Common::Point(0, 0)); drawControls(0); } @@ -486,10 +486,10 @@ void TattooJournal::drawControls(int mode) { screen._backBuffer1.fillRect(inner, MENU_BACKGROUND); // Draw the four corners of the info box - screen._backBuffer1.transBlitFrom(images[0], Common::Point(r.left, r.top)); - screen._backBuffer1.transBlitFrom(images[1], Common::Point(r.right - images[1]._width, r.top)); - screen._backBuffer1.transBlitFrom(images[1], Common::Point(r.left, r.bottom - images[1]._height)); - screen._backBuffer1.transBlitFrom(images[1], Common::Point(r.right - images[1]._width, r.bottom - images[1]._height)); + screen._backBuffer1.SHtransBlitFrom(images[0], Common::Point(r.left, r.top)); + screen._backBuffer1.SHtransBlitFrom(images[1], Common::Point(r.right - images[1]._width, r.top)); + screen._backBuffer1.SHtransBlitFrom(images[1], Common::Point(r.left, r.bottom - images[1]._height)); + screen._backBuffer1.SHtransBlitFrom(images[1], Common::Point(r.right - images[1]._width, r.bottom - images[1]._height)); // Draw the top of the info box screen._backBuffer1.hLine(r.left + images[0]._width, r.top, r.right - images[0]._height, INFO_TOP); @@ -513,8 +513,8 @@ void TattooJournal::drawControls(int mode) { // Draw the sides of the separator bar above the scroll bar int yp = r.top + screen.fontHeight() + 7; - screen._backBuffer1.transBlitFrom(images[4], Common::Point(r.left, yp - 1)); - screen._backBuffer1.transBlitFrom(images[5], Common::Point(r.right - images[5]._width, yp - 1)); + screen._backBuffer1.SHtransBlitFrom(images[4], Common::Point(r.left, yp - 1)); + screen._backBuffer1.SHtransBlitFrom(images[5], Common::Point(r.right - images[5]._width, yp - 1)); // Draw the bar above the scroll bar screen._backBuffer1.hLine(r.left + images[4]._width, yp, r.right - images[5]._width, INFO_TOP); @@ -525,8 +525,8 @@ void TattooJournal::drawControls(int mode) { // Draw the Bars separating the Journal Commands int xp = r.right / 3; for (int idx = 0; idx < 2; ++idx) { - screen._backBuffer1.transBlitFrom(images[6], Common::Point(xp - 2, r.top + 1)); - screen._backBuffer1.transBlitFrom(images[7], Common::Point(xp - 2, yp - 1)); + screen._backBuffer1.SHtransBlitFrom(images[6], Common::Point(xp - 2, r.top + 1)); + screen._backBuffer1.SHtransBlitFrom(images[7], Common::Point(xp - 2, yp - 1)); screen._backBuffer1.hLine(xp - 1, r.top + 4, yp - 2, INFO_TOP); screen._backBuffer1.hLine(xp, r.top + 4, yp - 2, INFO_MIDDLE); @@ -779,7 +779,7 @@ int TattooJournal::getFindName(bool printError) { // Backup the area under the text entry Surface bgSurface(r.width() - 6, screen.fontHeight()); - bgSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(r.left + 3, cursorY, + bgSurface.SHblitFrom(screen._backBuffer1, Common::Point(0, 0), Common::Rect(r.left + 3, cursorY, r.right - 3, cursorY + screen.fontHeight())); if (printError) { @@ -810,7 +810,7 @@ int TattooJournal::getFindName(bool printError) { events.clearEvents(); // Restore the text background - screen._backBuffer1.blitFrom(bgSurface, Common::Point(r.left, cursorY)); + screen._backBuffer1.SHblitFrom(bgSurface, Common::Point(r.left, cursorY)); // If there was a name already entered, copy it to name and display it if (!_find.empty()) { @@ -846,7 +846,7 @@ int TattooJournal::getFindName(bool printError) { } else { // Erase cursor by restoring background and writing current text - screen._backBuffer1.blitFrom(bgSurface, Common::Point(r.left + 3, cursorY)); + screen._backBuffer1.SHblitFrom(bgSurface, Common::Point(r.left + 3, cursorY)); screen.gPrint(Common::Point(r.left + screen.widestChar() + 3, cursorY), COMMAND_HIGHLIGHTED, "%s", name.c_str()); screen.slamArea(r.left + 3, cursorY, r.width() - 3, screen.fontHeight()); } @@ -912,7 +912,7 @@ int TattooJournal::getFindName(bool printError) { } // Redraw the text - screen._backBuffer1.blitFrom(bgSurface, Common::Point(r.left + 3, cursorY)); + screen._backBuffer1.SHblitFrom(bgSurface, Common::Point(r.left + 3, cursorY)); screen.gPrint(Common::Point(r.left + screen.widestChar() + 3, cursorY), COMMAND_HIGHLIGHTED, "%s", name.c_str()); screen.slamArea(r.left + 3, cursorY, r.right - 3, screen.fontHeight()); diff --git a/engines/sherlock/tattoo/tattoo_map.cpp b/engines/sherlock/tattoo/tattoo_map.cpp index 4c7e8c8fef..0839e46260 100644 --- a/engines/sherlock/tattoo/tattoo_map.cpp +++ b/engines/sherlock/tattoo/tattoo_map.cpp @@ -105,7 +105,7 @@ int TattooMap::show() { // Load the map image and draw it to the back buffer ImageFile *map = new ImageFile("map.vgs"); screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2); - screen._backBuffer1.blitFrom((*map)[0], Common::Point(0, 0)); + screen._backBuffer1.SHblitFrom((*map)[0], Common::Point(0, 0)); delete map; screen.clear(); @@ -114,7 +114,7 @@ int TattooMap::show() { // Copy the map drawn in the back buffer to the secondary back buffer screen._backBuffer2.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2); - screen._backBuffer2.blitFrom(screen._backBuffer1); + screen._backBuffer2.SHblitFrom(screen._backBuffer1); // Display the built map to the screen screen.slamArea(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); @@ -148,12 +148,12 @@ int TattooMap::show() { if (_targetScroll.x < 0) _targetScroll.x = 0; - if ((_targetScroll.x + SHERLOCK_SCREEN_WIDTH) > screen._backBuffer1.w()) - _targetScroll.x = screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH; + if ((_targetScroll.x + SHERLOCK_SCREEN_WIDTH) > screen._backBuffer1.width()) + _targetScroll.x = screen._backBuffer1.width() - SHERLOCK_SCREEN_WIDTH; if (_targetScroll.y < 0) _targetScroll.y = 0; - if ((_targetScroll.y + SHERLOCK_SCREEN_HEIGHT) > screen._backBuffer1.h()) - _targetScroll.y = screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT; + if ((_targetScroll.y + SHERLOCK_SCREEN_HEIGHT) > screen._backBuffer1.height()) + _targetScroll.y = screen._backBuffer1.height() - SHERLOCK_SCREEN_HEIGHT; // Check the keyboard if (events.kbHit()) { @@ -166,8 +166,8 @@ int TattooMap::show() { break; case Common::KEYCODE_END: - _targetScroll.x = screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH; - _targetScroll.y = screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT; + _targetScroll.x = screen._backBuffer1.width() - SHERLOCK_SCREEN_WIDTH; + _targetScroll.y = screen._backBuffer1.height() - SHERLOCK_SCREEN_HEIGHT; break; case Common::KEYCODE_PAGEUP: @@ -178,8 +178,8 @@ int TattooMap::show() { case Common::KEYCODE_PAGEDOWN: _targetScroll.y += SHERLOCK_SCREEN_HEIGHT; - if (_targetScroll.y > (screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT)) - _targetScroll.y = screen._backBuffer1.h() - SHERLOCK_SCREEN_HEIGHT; + if (_targetScroll.y > (screen._backBuffer1.height() - SHERLOCK_SCREEN_HEIGHT)) + _targetScroll.y = screen._backBuffer1.height() - SHERLOCK_SCREEN_HEIGHT; break; case Common::KEYCODE_SPACE: @@ -304,7 +304,7 @@ void TattooMap::drawMapIcons() { if (_data[idx]._iconNum != -1 && _vm->readFlags(idx + 1)) { MapEntry &mapEntry = _data[idx]; ImageFrame &img = (*_iconImages)[mapEntry._iconNum]; - screen._backBuffer1.transBlitFrom(img._frame, Common::Point(mapEntry.x - img._width / 2, + screen._backBuffer1.SHtransBlitFrom(img._frame, Common::Point(mapEntry.x - img._width / 2, mapEntry.y - img._height / 2)); } } @@ -355,10 +355,10 @@ void TattooMap::restoreArea(const Common::Rect &bounds) { Screen &screen = *_vm->_screen; Common::Rect r = bounds; - r.clip(Common::Rect(0, 0, screen._backBuffer1.w(), screen._backBuffer1.h())); + r.clip(Common::Rect(0, 0, screen._backBuffer1.width(), screen._backBuffer1.height())); if (!r.isEmpty()) - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(r.left, r.top), r); + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(r.left, r.top), r); } void TattooMap::showCloseUp(int closeUpNum) { @@ -407,7 +407,7 @@ void TattooMap::showCloseUp(int closeUpNum) { screen._currentScroll.y + closeUp.y / 100 - picSize.y / 2); restoreArea(oldBounds); - screen._backBuffer1.transBlitFrom(pic[0], pt, false, 0, scaleVal); + screen._backBuffer1.SHtransBlitFrom(pic[0], pt, false, 0, scaleVal); screen.slamRect(oldBounds); screen.slamArea(pt.x, pt.y, picSize.x, picSize.y); @@ -426,7 +426,7 @@ void TattooMap::showCloseUp(int closeUpNum) { screen._currentScroll.y + SHERLOCK_SCREEN_HEIGHT / 2 - pic[0]._height / 2 + pic[0]._height); restoreArea(oldBounds); - screen._backBuffer1.transBlitFrom(pic[0], Common::Point(r.left, r.top)); + screen._backBuffer1.SHtransBlitFrom(pic[0], Common::Point(r.left, r.top)); screen.slamRect(oldBounds); screen.slamRect(r); diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index b83a977a77..65cc283b66 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -1042,7 +1042,7 @@ void TattooPerson::walkHolmesToNPC() { holmes._walkDest.x = MAX(_position.x / FIXED_INT_MULTIPLIER - imgFrame.sDrawXSize(scaleVal), 0); } else { holmes._walkDest.x = MIN(_position.x / FIXED_INT_MULTIPLIER + imgFrame.sDrawXSize(scaleVal) * 2, - screen._backBuffer1.w() - 1); + screen._backBuffer1.width() - 1); } // See where Holmes is with respect to the NPC (y coords) @@ -1168,7 +1168,7 @@ void TattooPerson::centerScreenOnPerson() { TattooUserInterface &ui = *(TattooUserInterface *)_vm->_ui; ui._targetScroll.x = CLIP(_position.x / FIXED_INT_MULTIPLIER - SHERLOCK_SCREEN_WIDTH / 2, - 0, screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH); + 0, screen._backBuffer1.width() - SHERLOCK_SCREEN_WIDTH); screen._currentScroll = ui._targetScroll; // Reset the default look position to the center of the screen @@ -1478,7 +1478,7 @@ const Common::Point TattooPeople::restrictToZone(int zoneId, const Common::Point Screen &screen = *_vm->_screen; Common::Rect &r = scene._zones[zoneId]; - if (destPos.x < 0 || destPos.x > screen._backBuffer1.w()) + if (destPos.x < 0 || destPos.x > screen._backBuffer1.width()) return destPos; else if (destPos.y < r.top && r.left < destPos.x && destPos.x < r.right) return Common::Point(destPos.x, r.top); diff --git a/engines/sherlock/tattoo/tattoo_scene.cpp b/engines/sherlock/tattoo/tattoo_scene.cpp index 27f37665dc..00015cb189 100644 --- a/engines/sherlock/tattoo/tattoo_scene.cpp +++ b/engines/sherlock/tattoo/tattoo_scene.cpp @@ -141,15 +141,15 @@ void TattooScene::drawAllShapes() { if (obj._type == ACTIVE_BG_SHAPE && obj._misc == BEHIND) { if (obj._quickDraw && obj._scaleVal == SCALE_THRESHOLD) - screen._backBuffer1.blitFrom(*obj._imageFrame, obj._position); + screen._backBuffer1.SHblitFrom(*obj._imageFrame, obj._position); else - screen._backBuffer1.transBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal); + screen._backBuffer1.SHtransBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal); } } // Draw the animation if it is behind the person if (_activeCAnim.active() && _activeCAnim._zPlacement == BEHIND) - screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, + screen._backBuffer1.SHtransBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal); screen.resetDisplayBounds(); @@ -194,13 +194,13 @@ void TattooScene::drawAllShapes() { if (se._shape) { // it's a bg shape if (se._shape->_quickDraw && se._shape->_scaleVal == SCALE_THRESHOLD) - screen._backBuffer1.blitFrom(*se._shape->_imageFrame, se._shape->_position); + screen._backBuffer1.SHblitFrom(*se._shape->_imageFrame, se._shape->_position); else - screen._backBuffer1.transBlitFrom(*se._shape->_imageFrame, se._shape->_position, + screen._backBuffer1.SHtransBlitFrom(*se._shape->_imageFrame, se._shape->_position, se._shape->_flags & OBJ_FLIPPED, 0, se._shape->_scaleVal); } else if (se._isAnimation) { // It's an active animation - screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, + screen._backBuffer1.SHtransBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal); } else { // Drawing person @@ -212,7 +212,7 @@ void TattooScene::drawAllShapes() { if (p._tempScaleVal == SCALE_THRESHOLD) { p._tempX += adjust.x; - screen._backBuffer1.transBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER + screen._backBuffer1.SHtransBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER - p.frameHeight() - adjust.y), p._walkSequences[p._sequenceNumber]._horizFlip, 0, p._tempScaleVal); } else { if (adjust.x) { @@ -242,7 +242,7 @@ void TattooScene::drawAllShapes() { ++adjust.y; } - screen._backBuffer1.transBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER + screen._backBuffer1.SHtransBlitFrom(*p._imageFrame, Common::Point(p._tempX, p._position.y / FIXED_INT_MULTIPLIER - p._imageFrame->sDrawYSize(p._tempScaleVal) - adjust.y), p._walkSequences[p._sequenceNumber]._horizFlip, 0, p._tempScaleVal); } } @@ -255,15 +255,15 @@ void TattooScene::drawAllShapes() { if (obj._type == ACTIVE_BG_SHAPE && obj._misc == FORWARD) { if (obj._quickDraw && obj._scaleVal == SCALE_THRESHOLD) - screen._backBuffer1.blitFrom(*obj._imageFrame, obj._position); + screen._backBuffer1.SHblitFrom(*obj._imageFrame, obj._position); else - screen._backBuffer1.transBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal); + screen._backBuffer1.SHtransBlitFrom(*obj._imageFrame, obj._position, obj._flags & OBJ_FLIPPED, 0, obj._scaleVal); } } // Draw the canimation if it is set as FORWARD if (_activeCAnim.active() && _activeCAnim._zPlacement == FORWARD) - screen._backBuffer1.transBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal); + screen._backBuffer1.SHtransBlitFrom(_activeCAnim._imageFrame, _activeCAnim._position, (_activeCAnim._flags & 4) >> 1, 0, _activeCAnim._scaleVal); // Draw all NO_SHAPE shapes which have their flag bits clear for (uint idx = 0; idx < _bgShapes.size(); ++idx) { diff --git a/engines/sherlock/tattoo/tattoo_screen.cpp b/engines/sherlock/tattoo/tattoo_screen.cpp new file mode 100644 index 0000000000..c98ae2679d --- /dev/null +++ b/engines/sherlock/tattoo/tattoo_screen.cpp @@ -0,0 +1,37 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "sherlock/tattoo/tattoo_screen.h" +#include "sherlock/tattoo/tattoo.h" + +namespace Sherlock { + +namespace Tattoo { + +TattooScreen::TattooScreen(SherlockEngine *vm) : Screen(vm) { + _backBuffer1.create(640, 480); + _backBuffer2.create(640, 480); +} + +} // End of namespace Tattoo + +} // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_screen.h b/engines/sherlock/tattoo/tattoo_screen.h new file mode 100644 index 0000000000..b55e9bb0dd --- /dev/null +++ b/engines/sherlock/tattoo/tattoo_screen.h @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SHERLOCK_TATTOO_SCREEN_H +#define SHERLOCK_TATTOO_SCREEN_H + +#include "sherlock/screen.h" + +namespace Sherlock { + +class SherlockEngine; + +namespace Tattoo { + +class TattooScreen : public Screen { +public: + TattooScreen(SherlockEngine *vm); + virtual ~TattooScreen() {} +}; + +} // End of namespace Tattoo + +} // End of namespace Sherlock + +#endif diff --git a/engines/sherlock/tattoo/tattoo_user_interface.cpp b/engines/sherlock/tattoo/tattoo_user_interface.cpp index ee028f89c2..677a662535 100644 --- a/engines/sherlock/tattoo/tattoo_user_interface.cpp +++ b/engines/sherlock/tattoo/tattoo_user_interface.cpp @@ -72,7 +72,7 @@ TattooUserInterface::~TattooUserInterface() { void TattooUserInterface::initScrollVars() { Screen &screen = *_vm->_screen; - _scrollSize = screen._backBuffer1.w() - SHERLOCK_SCREEN_WIDTH; + _scrollSize = screen._backBuffer1.width() - SHERLOCK_SCREEN_WIDTH; _targetScroll = Common::Point(0, 0); screen._currentScroll = Common::Point(0, 0); } @@ -233,7 +233,7 @@ void TattooUserInterface::doJournal() { Common::copy(&lookupTable1[0], &lookupTable1[PALETTE_COUNT], &_lookupTable1[0]); // Restore the scene - screen._backBuffer1.blitFrom(screen._backBuffer2); + screen._backBuffer1.SHblitFrom(screen._backBuffer2); scene.updateBackground(); screen.slamArea(screen._currentScroll.x, screen._currentScroll.y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); } @@ -727,7 +727,7 @@ void TattooUserInterface::doBgAnimEraseBackground() { if (_mask != nullptr) { // Since a mask is active, restore the screen from the secondary back buffer prior to applying the mask - screen._backBuffer1.blitFrom(screen._backBuffer2, screen._currentScroll, Common::Rect(screen._currentScroll.x, 0, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, screen._currentScroll, Common::Rect(screen._currentScroll.x, 0, screen._currentScroll.x + SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT)); switch (scene._currentScene) { @@ -757,7 +757,7 @@ void TattooUserInterface::doBgAnimEraseBackground() { case 53: if (++_maskCounter == 2) { _maskCounter = 0; - if (++_maskOffset.x == screen._backBuffer1.w()) + if (++_maskOffset.x == screen._backBuffer1.width()) _maskOffset.x = 0; } break; @@ -779,7 +779,7 @@ void TattooUserInterface::doBgAnimEraseBackground() { if ((obj._type == ACTIVE_BG_SHAPE && (obj._maxFrames > 1 || obj._delta.x != 0 || obj._delta.y != 0)) || obj._type == HIDE_SHAPE || obj._type == REMOVE) - screen._backBuffer1.blitFrom(screen._backBuffer2, obj._oldPosition, + screen._backBuffer1.SHblitFrom(screen._backBuffer2, obj._oldPosition, Common::Rect(obj._oldPosition.x, obj._oldPosition.y, obj._oldPosition.x + obj._oldSize.x, obj._oldPosition.y + obj._oldSize.y)); } @@ -793,7 +793,7 @@ void TattooUserInterface::doBgAnimEraseBackground() { Object &obj = scene._bgShapes[idx]; if (obj._type == NO_SHAPE && (obj._flags & 1) == 0) { - screen._backBuffer1.blitFrom(screen._backBuffer2, obj._position, obj.getNoShapeBounds()); + screen._backBuffer1.SHblitFrom(screen._backBuffer2, obj._position, obj.getNoShapeBounds()); obj._oldPosition = obj._position; obj._oldSize = obj._noShapeSize; @@ -870,7 +870,7 @@ void TattooUserInterface::maskArea(Common::SeekableReadStream &mask, const Commo int pixel, len, xp, yp; for (yp = 0; yp < ySize; ++yp) { - byte *ptr = bb1.getBasePtr(pt.x, pt.y + yp); + byte *ptr = (byte *)bb1.getBasePtr(pt.x, pt.y + yp); for (xp = 0; xp < xSize;) { // The mask data consists of pairs of pixel/lengths, where all non-zero pixels means that the @@ -893,7 +893,7 @@ void TattooUserInterface::makeBGArea(const Common::Rect &r) { Screen &screen = *_vm->_screen; for (int yp = r.top; yp < r.bottom; ++yp) { - byte *ptr = screen._backBuffer1.getBasePtr(r.left, yp); + byte *ptr = (byte *)screen._backBuffer1.getBasePtr(r.left, yp); for (int xp = r.left; xp < r.right; ++xp, ++ptr) *ptr = _lookupTable[*ptr]; diff --git a/engines/sherlock/tattoo/widget_base.cpp b/engines/sherlock/tattoo/widget_base.cpp index 8f0649130a..a35f4e5d74 100644 --- a/engines/sherlock/tattoo/widget_base.cpp +++ b/engines/sherlock/tattoo/widget_base.cpp @@ -88,7 +88,7 @@ void WidgetBase::erase() { if (_oldBounds.width() > 0) { // Restore the affected area from the secondary back buffer into the first one, and then copy to screen - screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldBounds.left, _oldBounds.top), _oldBounds); + screen._backBuffer1.SHblitFrom(screen._backBuffer2, Common::Point(_oldBounds.left, _oldBounds.top), _oldBounds); screen.slamRect(_oldBounds); // Reset the old bounds so it won't be erased again @@ -111,7 +111,7 @@ void WidgetBase::draw() { drawBackground(); // Draw the widget onto the back buffer and then slam it to the screen - screen._backBuffer1.transBlitFrom(_surface, Common::Point(_bounds.left, _bounds.top)); + screen._backBuffer1.SHtransBlitFrom(_surface, Common::Point(_bounds.left, _bounds.top)); screen.slamRect(_bounds); // Store a copy of the drawn area for later erasing @@ -183,8 +183,8 @@ void WidgetBase::restrictToScreen() { _bounds.moveTo(_bounds.left, 0); if (_bounds.right > (screen._currentScroll.x + SHERLOCK_SCREEN_WIDTH)) _bounds.moveTo(screen._currentScroll.x + SHERLOCK_SCREEN_WIDTH - _bounds.width(), _bounds.top); - if (_bounds.bottom > screen._backBuffer1.h()) - _bounds.moveTo(_bounds.left, screen._backBuffer1.h() - _bounds.height()); + if (_bounds.bottom > screen._backBuffer1.height()) + _bounds.moveTo(_bounds.left, screen._backBuffer1.height() - _bounds.height()); } void WidgetBase::makeInfoArea(Surface &s) { @@ -192,30 +192,30 @@ void WidgetBase::makeInfoArea(Surface &s) { ImageFile &images = *ui._interfaceImages; // Draw the four corners of the Info Box - s.transBlitFrom(images[0], Common::Point(0, 0)); - s.transBlitFrom(images[1], Common::Point(s.w() - images[1]._width, 0)); - s.transBlitFrom(images[2], Common::Point(0, s.h() - images[2]._height)); - s.transBlitFrom(images[3], Common::Point(s.w() - images[3]._width, s.h())); + s.SHtransBlitFrom(images[0], Common::Point(0, 0)); + s.SHtransBlitFrom(images[1], Common::Point(s.width() - images[1]._width, 0)); + s.SHtransBlitFrom(images[2], Common::Point(0, s.height() - images[2]._height)); + s.SHtransBlitFrom(images[3], Common::Point(s.width() - images[3]._width, s.height())); // Draw the top of the Info Box - s.hLine(images[0]._width, 0, s.w() - images[1]._width, INFO_TOP); - s.hLine(images[0]._width, 1, s.w() - images[1]._width, INFO_MIDDLE); - s.hLine(images[0]._width, 2, s.w() - images[1]._width, INFO_BOTTOM); + s.hLine(images[0]._width, 0, s.width() - images[1]._width, INFO_TOP); + s.hLine(images[0]._width, 1, s.width() - images[1]._width, INFO_MIDDLE); + s.hLine(images[0]._width, 2, s.width() - images[1]._width, INFO_BOTTOM); // Draw the bottom of the Info Box - s.hLine(images[0]._width, s.h()- 3, s.w() - images[1]._width, INFO_TOP); - s.hLine(images[0]._width, s.h()- 2, s.w() - images[1]._width, INFO_MIDDLE); - s.hLine(images[0]._width, s.h()- 1, s.w() - images[1]._width, INFO_BOTTOM); + s.hLine(images[0]._width, s.height()- 3, s.width() - images[1]._width, INFO_TOP); + s.hLine(images[0]._width, s.height()- 2, s.width() - images[1]._width, INFO_MIDDLE); + s.hLine(images[0]._width, s.height()- 1, s.width() - images[1]._width, INFO_BOTTOM); // Draw the left Side of the Info Box - s.vLine(0, images[0]._height, s.h()- images[2]._height, INFO_TOP); - s.vLine(1, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE); - s.vLine(2, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM); + s.vLine(0, images[0]._height, s.height()- images[2]._height, INFO_TOP); + s.vLine(1, images[0]._height, s.height()- images[2]._height, INFO_MIDDLE); + s.vLine(2, images[0]._height, s.height()- images[2]._height, INFO_BOTTOM); // Draw the right Side of the Info Box - s.vLine(s.w() - 3, images[0]._height, s.h()- images[2]._height, INFO_TOP); - s.vLine(s.w() - 2, images[0]._height, s.h()- images[2]._height, INFO_MIDDLE); - s.vLine(s.w() - 1, images[0]._height, s.h()- images[2]._height, INFO_BOTTOM); + s.vLine(s.width() - 3, images[0]._height, s.height()- images[2]._height, INFO_TOP); + s.vLine(s.width() - 2, images[0]._height, s.height()- images[2]._height, INFO_MIDDLE); + s.vLine(s.width() - 1, images[0]._height, s.height()- images[2]._height, INFO_BOTTOM); } void WidgetBase::makeInfoArea() { diff --git a/engines/sherlock/tattoo/widget_credits.cpp b/engines/sherlock/tattoo/widget_credits.cpp index 2b37dd304b..1c878daaf6 100644 --- a/engines/sherlock/tattoo/widget_credits.cpp +++ b/engines/sherlock/tattoo/widget_credits.cpp @@ -37,7 +37,7 @@ void WidgetCredits::initCredits() { Screen &screen = *_vm->_screen; Common::SeekableReadStream *stream = res.load("credits.txt"); int spacing = screen.fontHeight() * 2; - int yp = screen.h(); + int yp = screen.height(); _creditsActive = true; _creditLines.clear(); @@ -60,7 +60,7 @@ void WidgetCredits::initCredits() { } else { int width = screen.stringWidth(line) + 2; - _creditLines.push_back(CreditLine(line, Common::Point((screen.w() - width) / 2 + 1, yp), width)); + _creditLines.push_back(CreditLine(line, Common::Point((screen.width() - width) / 2 + 1, yp), width)); yp += spacing; } } @@ -120,10 +120,10 @@ void WidgetCredits::close() { void WidgetCredits::drawCredits() { Screen &screen = *_vm->_screen; - Common::Rect screenRect(0, 0, screen.w(), screen.h()); + Common::Rect screenRect(0, 0, screen.width(), screen.height()); Surface &bb1 = screen._backBuffer1; - for (uint idx = 0; idx < _creditLines.size() && _creditLines[idx]._position.y < screen.h(); ++idx) { + for (uint idx = 0; idx < _creditLines.size() && _creditLines[idx]._position.y < screen.height(); ++idx) { if (screenRect.contains(_creditLines[idx]._position)) { if (!_creditLines[idx]._line2.empty()) { int x1 = _creditLines[idx]._position.x; @@ -176,7 +176,7 @@ void WidgetCredits::drawCredits() { void WidgetCredits::blitCredits() { Screen &screen = *_vm->_screen; - Common::Rect screenRect(0, -_creditSpeed, screen.w(), screen.h() + _creditSpeed); + Common::Rect screenRect(0, -_creditSpeed, screen.width(), screen.height() + _creditSpeed); for (uint idx = 0; idx < _creditLines.size(); ++idx) { if (screenRect.contains(_creditLines[idx]._position)) { @@ -190,7 +190,7 @@ void WidgetCredits::blitCredits() { void WidgetCredits::eraseCredits() { Screen &screen = *_vm->_screen; - Common::Rect screenRect(0, -_creditSpeed, screen.w(), screen.h() + _creditSpeed); + Common::Rect screenRect(0, -_creditSpeed, screen.width(), screen.height() + _creditSpeed); for (uint idx = 0; idx < _creditLines.size(); ++idx) { if (screenRect.contains(_creditLines[idx]._position)) { diff --git a/engines/sherlock/tattoo/widget_files.cpp b/engines/sherlock/tattoo/widget_files.cpp index ff8cb83dca..7666e81480 100644 --- a/engines/sherlock/tattoo/widget_files.cpp +++ b/engines/sherlock/tattoo/widget_files.cpp @@ -107,36 +107,36 @@ void WidgetFiles::render(FilesRenderMode mode) { byte color; if (mode == RENDER_ALL) { - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); makeInfoArea(); switch (_fileMode) { case SAVEMODE_LOAD: _surface.writeString(FIXED(LoadGame), - Common::Point((_surface.w() - _surface.stringWidth(FIXED(LoadGame))) / 2, 5), INFO_TOP); + Common::Point((_surface.width() - _surface.stringWidth(FIXED(LoadGame))) / 2, 5), INFO_TOP); break; case SAVEMODE_SAVE: _surface.writeString(FIXED(SaveGame), - Common::Point((_surface.w() - _surface.stringWidth(FIXED(SaveGame))) / 2, 5), INFO_TOP); + Common::Point((_surface.width() - _surface.stringWidth(FIXED(SaveGame))) / 2, 5), INFO_TOP); break; default: break; } - _surface.hLine(3, _surface.fontHeight() + 7, _surface.w() - 4, INFO_TOP); - _surface.hLine(3, _surface.fontHeight() + 8, _surface.w() - 4, INFO_MIDDLE); - _surface.hLine(3, _surface.fontHeight() + 9, _surface.w() - 4, INFO_BOTTOM); - _surface.transBlitFrom(images[4], Common::Point(0, _surface.fontHeight() + 6)); - _surface.transBlitFrom(images[5], Common::Point(_surface.w() - images[5]._width, _surface.fontHeight() + 6)); + _surface.hLine(3, _surface.fontHeight() + 7, _surface.width() - 4, INFO_TOP); + _surface.hLine(3, _surface.fontHeight() + 8, _surface.width() - 4, INFO_MIDDLE); + _surface.hLine(3, _surface.fontHeight() + 9, _surface.width() - 4, INFO_BOTTOM); + _surface.SHtransBlitFrom(images[4], Common::Point(0, _surface.fontHeight() + 6)); + _surface.SHtransBlitFrom(images[5], Common::Point(_surface.width() - images[5]._width, _surface.fontHeight() + 6)); - int xp = _surface.w() - BUTTON_SIZE - 6; + int xp = _surface.width() - BUTTON_SIZE - 6; _surface.vLine(xp, _surface.fontHeight() + 10, _bounds.height() - 4, INFO_TOP); _surface.vLine(xp + 1, _surface.fontHeight() + 10, _bounds.height() - 4, INFO_MIDDLE); _surface.vLine(xp + 2, _surface.fontHeight() + 10, _bounds.height() - 4, INFO_BOTTOM); - _surface.transBlitFrom(images[6], Common::Point(xp - 1, _surface.fontHeight() + 8)); - _surface.transBlitFrom(images[7], Common::Point(xp - 1, _bounds.height() - 4)); + _surface.SHtransBlitFrom(images[6], Common::Point(xp - 1, _surface.fontHeight() + 8)); + _surface.SHtransBlitFrom(images[7], Common::Point(xp - 1, _bounds.height() - 4)); } int xp = _surface.stringWidth("00.") + _surface.widestChar() + 5; @@ -149,7 +149,7 @@ void WidgetFiles::render(FilesRenderMode mode) { color = INFO_TOP; if (mode == RENDER_NAMES_AND_SCROLLBAR) - _surface.fillRect(Common::Rect(4, yp, _surface.w() - BUTTON_SIZE - 9, yp + _surface.fontHeight()), TRANSPARENCY); + _surface.fillRect(Common::Rect(4, yp, _surface.width() - BUTTON_SIZE - 9, yp + _surface.fontHeight()), TRANSPARENCY); Common::String numStr = Common::String::format("%d.", idx + 1); _surface.writeString(numStr, Common::Point(_surface.widestChar(), yp), color); @@ -324,7 +324,7 @@ bool WidgetFiles::getFilename() { filename.setChar(' ', index); } - _surface.fillRect(Common::Rect(pt.x, pt.y, _surface.w() - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY); + _surface.fillRect(Common::Rect(pt.x, pt.y, _surface.width() - BUTTON_SIZE - 9, pt.y + _surface.fontHeight() - 1), TRANSPARENCY); _surface.writeString(filename.c_str() + index, pt, COMMAND_HIGHLIGHTED); } else if ((keyState.keycode == Common::KEYCODE_LEFT && index > 0) @@ -387,7 +387,7 @@ bool WidgetFiles::getFilename() { } if ((keyState.ascii >= ' ') && (keyState.ascii <= 'z') && (index < 50)) { - if (pt.x + _surface.charWidth(keyState.ascii) < _surface.w() - BUTTON_SIZE - 20) { + if (pt.x + _surface.charWidth(keyState.ascii) < _surface.w - BUTTON_SIZE - 20) { if (insert) filename.insertChar(keyState.ascii, index); else diff --git a/engines/sherlock/tattoo/widget_foolscap.cpp b/engines/sherlock/tattoo/widget_foolscap.cpp index c8df71e873..8225946838 100644 --- a/engines/sherlock/tattoo/widget_foolscap.cpp +++ b/engines/sherlock/tattoo/widget_foolscap.cpp @@ -103,7 +103,7 @@ void WidgetFoolscap::show() { // Set up the window background _surface.create(_bounds.width(), _bounds.height()); - _surface.blitFrom(paperFrame, Common::Point(0, 0)); + _surface.SHblitFrom(paperFrame, Common::Point(0, 0)); // If they have already solved the puzzle, put the answer on the graphic if (_vm->readFlags(299)) { @@ -265,7 +265,7 @@ void WidgetFoolscap::handleKeyboardEvents() { void WidgetFoolscap::restoreChar() { Screen &screen = *_vm->_screen; ImageFrame &bgFrame = (*_images)[0]; - _surface.blitFrom(bgFrame, _cursorPos, Common::Rect(_cursorPos.x, _cursorPos.y, + _surface.SHblitFrom(bgFrame, _cursorPos, Common::Rect(_cursorPos.x, _cursorPos.y, _cursorPos.x + screen.widestChar(), _cursorPos.y + screen.fontHeight())); } diff --git a/engines/sherlock/tattoo/widget_inventory.cpp b/engines/sherlock/tattoo/widget_inventory.cpp index b49e30b30d..34331f0eae 100644 --- a/engines/sherlock/tattoo/widget_inventory.cpp +++ b/engines/sherlock/tattoo/widget_inventory.cpp @@ -94,7 +94,7 @@ void WidgetInventoryTooltip::setText(const Common::String &str) { // Allocate a fresh surface for the new string _bounds = Common::Rect(width, height); _surface.create(width, height); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); if (line2.empty()) { _surface.writeFancyString(str, Common::Point(0, 0), BLACK, INFO_TOP); @@ -338,7 +338,7 @@ void WidgetInventoryVerbs::load() { // Create the surface _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); makeInfoArea(); // Draw the Verb commands and the lines separating them @@ -352,8 +352,8 @@ void WidgetInventoryVerbs::load() { _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 1, _bounds.right - 4, INFO_MIDDLE); _surface.vLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 2, _bounds.right - 4, INFO_BOTTOM); - _surface.transBlitFrom(images[4], Common::Point(0, (_surface.fontHeight() + 7) * (idx + 1))); - _surface.transBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width, + _surface.SHtransBlitFrom(images[4], Common::Point(0, (_surface.fontHeight() + 7) * (idx + 1))); + _surface.SHtransBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width, (_surface.fontHeight() + 7) * (idx + 1) - 1)); } } @@ -515,7 +515,7 @@ void WidgetInventory::load(int mode) { // Redraw the inventory menu on the widget surface _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); // Draw the window background and then the inventory on top of it makeInfoArea(_surface); @@ -531,7 +531,7 @@ void WidgetInventory::drawBars() { _surface.hLine(3, INVENTORY_YSIZE + 3, _bounds.width() - 4, INFO_TOP); _surface.hLine(3, INVENTORY_YSIZE + 4, _bounds.width() - 4, INFO_MIDDLE); _surface.hLine(3, INVENTORY_YSIZE + 5, _bounds.width() - 4, INFO_BOTTOM); - _surface.transBlitFrom(images[4], Common::Point(0, INVENTORY_YSIZE + 2)); + _surface.SHtransBlitFrom(images[4], Common::Point(0, INVENTORY_YSIZE + 2)); for (int idx = 1; idx <= NUM_INVENTORY_SHOWN / 2; ++idx) { x = idx * (INVENTORY_XSIZE + 3); @@ -540,10 +540,10 @@ void WidgetInventory::drawBars() { _surface.vLine(x + 1, 3, _bounds.height() - 4, INFO_MIDDLE); _surface.vLine(x + 2, 3, _bounds.height() - 4, INFO_BOTTOM); - _surface.transBlitFrom(images[6], Common::Point(x - 1, 1)); - _surface.transBlitFrom(images[7], Common::Point(x - 1, _bounds.height() - 4)); - _surface.transBlitFrom(images[6], Common::Point(x - 1, INVENTORY_YSIZE + 5)); - _surface.transBlitFrom(images[7], Common::Point(x - 1, INVENTORY_YSIZE + 2)); + _surface.SHtransBlitFrom(images[6], Common::Point(x - 1, 1)); + _surface.SHtransBlitFrom(images[7], Common::Point(x - 1, _bounds.height() - 4)); + _surface.SHtransBlitFrom(images[6], Common::Point(x - 1, INVENTORY_YSIZE + 5)); + _surface.SHtransBlitFrom(images[7], Common::Point(x - 1, INVENTORY_YSIZE + 2)); } _surface.hLine(x + 2, INVENTORY_YSIZE + 2, INVENTORY_YSIZE + 8, INFO_BOTTOM); @@ -566,7 +566,7 @@ void WidgetInventory::drawInventory() { // Draw the item if (itemId < inv._holdings) { ImageFrame &img = (*inv._invShapes[idx])[0]; - _surface.transBlitFrom(img, Common::Point(pt.x + (INVENTORY_XSIZE - img._width) / 2, + _surface.SHtransBlitFrom(img, Common::Point(pt.x + (INVENTORY_XSIZE - img._width) / 2, pt.y + (INVENTORY_YSIZE - img._height) / 2)); } } diff --git a/engines/sherlock/tattoo/widget_options.cpp b/engines/sherlock/tattoo/widget_options.cpp index 92bd10bbf6..81f50f3bc5 100644 --- a/engines/sherlock/tattoo/widget_options.cpp +++ b/engines/sherlock/tattoo/widget_options.cpp @@ -257,17 +257,17 @@ void WidgetOptions::render(OptionRenderMode mode) { // Setup the dialog _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); makeInfoArea(); // Draw the lines separating options in the dialog int yp = _surface.fontHeight() + 7; for (int idx = 0; idx < 7; ++idx) { - _surface.transBlitFrom(images[4], Common::Point(0, yp - 1)); - _surface.transBlitFrom(images[5], Common::Point(_surface.w() - images[5]._width, yp - 1)); - _surface.hLine(3, yp, _surface.w() - 4, INFO_TOP); - _surface.hLine(3, yp + 1, _surface.w() - 4, INFO_MIDDLE); - _surface.hLine(3, yp + 2, _surface.w() - 4, INFO_BOTTOM); + _surface.SHtransBlitFrom(images[4], Common::Point(0, yp - 1)); + _surface.SHtransBlitFrom(images[5], Common::Point(_surface.width() - images[5]._width, yp - 1)); + _surface.hLine(3, yp, _surface.width() - 4, INFO_TOP); + _surface.hLine(3, yp + 1, _surface.width() - 4, INFO_MIDDLE); + _surface.hLine(3, yp + 2, _surface.width() - 4, INFO_BOTTOM); yp += _surface.fontHeight() + 7; if (idx == 1) @@ -281,7 +281,7 @@ void WidgetOptions::render(OptionRenderMode mode) { for (int idx = 0, yp = 5; idx < 11; ++idx, yp += _surface.fontHeight() + 7) { if (mode == OP_ALL || idx == _selector || idx == _oldSelector) { if (mode == OP_NAMES) - _surface.fillRect(Common::Rect(4, yp, _surface.w() - 5, yp + _surface.fontHeight() - 1), TRANSPARENCY); + _surface.fillRect(Common::Rect(4, yp, _surface.width() - 5, yp + _surface.fontHeight() - 1), TRANSPARENCY); byte color = (idx == _selector) ? COMMAND_HIGHLIGHTED : INFO_TOP; Common::String str; @@ -302,11 +302,11 @@ void WidgetOptions::render(OptionRenderMode mode) { int num = (_surface.fontHeight() + 4) & 0xfe; int sliderY = yp + num / 2 - 8; - _surface.fillRect(Common::Rect(4, sliderY - (num - 6) / 2, _surface.w() - 5, + _surface.fillRect(Common::Rect(4, sliderY - (num - 6) / 2, _surface.width() - 5, sliderY - (num - 6) / 2 + num - 1), TRANSPARENCY); _surface.fillRect(Common::Rect(_surface.widestChar(), sliderY + 2, - _surface.w() - _surface.widestChar() - 1, sliderY + 3), INFO_MIDDLE); - drawDialogRect(Common::Rect(_surface.widestChar(), sliderY, _surface.w() - _surface.widestChar(), sliderY + 6)); + _surface.width() - _surface.widestChar() - 1, sliderY + 3), INFO_MIDDLE); + drawDialogRect(Common::Rect(_surface.widestChar(), sliderY, _surface.width() - _surface.widestChar(), sliderY + 6)); _surface.fillRect(Common::Rect(_midiSliderX - 1, sliderY - (num - 6) / 2 + 2, _midiSliderX + 1, sliderY - (num - 6) / 2 + num - 3), INFO_MIDDLE); @@ -315,7 +315,7 @@ void WidgetOptions::render(OptionRenderMode mode) { if (_midiSliderX - 4 > _surface.widestChar()) _surface.fillRect(Common::Rect(_midiSliderX - 4, sliderY, _midiSliderX - 4, sliderY + 4), INFO_BOTTOM); - if (_midiSliderX + 4 < _surface.w() - _surface.widestChar()) + if (_midiSliderX + 4 < _surface.width() - _surface.widestChar()) _surface.fillRect(Common::Rect(_midiSliderX + 4, sliderY, _midiSliderX + 4, sliderY + 4), INFO_BOTTOM); break; } @@ -332,18 +332,18 @@ void WidgetOptions::render(OptionRenderMode mode) { int num = (_surface.fontHeight() + 4) & 0xfe; int sliderY = yp + num / 2 - 8; - _surface.fillRect(Common::Rect(4, sliderY - (num - 6) / 2, _surface.w() - 5, + _surface.fillRect(Common::Rect(4, sliderY - (num - 6) / 2, _surface.width() - 5, sliderY - (num - 6) / 2 + num - 1), TRANSPARENCY); - _surface.fillRect(Common::Rect(_surface.widestChar(), sliderY + 2, _surface.w() - _surface.widestChar() - 1, + _surface.fillRect(Common::Rect(_surface.widestChar(), sliderY + 2, _surface.width() - _surface.widestChar() - 1, sliderY + 3), INFO_MIDDLE); - drawDialogRect(Common::Rect(_surface.widestChar(), sliderY, _surface.w() - _surface.widestChar(), sliderY + 6)); + drawDialogRect(Common::Rect(_surface.widestChar(), sliderY, _surface.width() - _surface.widestChar(), sliderY + 6)); _surface.fillRect(Common::Rect(_digiSliderX - 1, sliderY - (num - 6) / 2 + 2, _digiSliderX + 1, sliderY - (num - 6) / 2 + num - 3), INFO_MIDDLE); drawDialogRect(Common::Rect(_digiSliderX - 3, sliderY - (num - 6) / 2, _digiSliderX + 4, sliderY - (num - 6) / 2 + num)); if (_digiSliderX - 4 > _surface.widestChar()) _surface.fillRect(Common::Rect(_digiSliderX - 4, sliderY, _digiSliderX - 4, sliderY + 4), INFO_BOTTOM); - if (_digiSliderX + 4 < _surface.w() - _surface.widestChar()) + if (_digiSliderX + 4 < _surface.width() - _surface.widestChar()) _surface.fillRect(Common::Rect(_digiSliderX + 4, sliderY, _digiSliderX + 4, sliderY + 4), INFO_BOTTOM); break; } @@ -375,7 +375,7 @@ void WidgetOptions::render(OptionRenderMode mode) { // Unless we're doing one of the Slider Controls, print the text for the line if (idx != 3 && idx != 6) { - int xp = (_surface.w() - _surface.stringWidth(str)) / 2; + int xp = (_surface.width() - _surface.stringWidth(str)) / 2; _surface.writeString(str, Common::Point(xp, yp), color); } } diff --git a/engines/sherlock/tattoo/widget_password.cpp b/engines/sherlock/tattoo/widget_password.cpp index 57a5e02653..2a2921026d 100644 --- a/engines/sherlock/tattoo/widget_password.cpp +++ b/engines/sherlock/tattoo/widget_password.cpp @@ -47,7 +47,7 @@ void WidgetPassword::show() { // Create the surface _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); makeInfoArea(); // Draw the header area @@ -55,8 +55,8 @@ void WidgetPassword::show() { _surface.hLine(3, _surface.fontHeight() + 7, _bounds.width() - 4, INFO_TOP); _surface.hLine(3, _surface.fontHeight() + 8, _bounds.width() - 4, INFO_MIDDLE); _surface.hLine(3, _surface.fontHeight() + 9, _bounds.width() - 4, INFO_BOTTOM); - _surface.transBlitFrom(images[4], Common::Point(0, _surface.fontHeight() + 7 - 1)); - _surface.transBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width, _surface.fontHeight() + 7 - 1)); + _surface.SHtransBlitFrom(images[4], Common::Point(0, _surface.fontHeight() + 7 - 1)); + _surface.SHtransBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width, _surface.fontHeight() + 7 - 1)); // Set the password entry data _cursorPos = Common::Point(_surface.widestChar(), _surface.fontHeight() + 12); diff --git a/engines/sherlock/tattoo/widget_quit.cpp b/engines/sherlock/tattoo/widget_quit.cpp index f853e7f47f..ea8f2e080c 100644 --- a/engines/sherlock/tattoo/widget_quit.cpp +++ b/engines/sherlock/tattoo/widget_quit.cpp @@ -48,22 +48,22 @@ void WidgetQuit::show() { // Create the surface _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); makeInfoArea(); // Draw the message text - _surface.writeString(FIXED(AreYouSureYou), Common::Point((_surface.w() - _surface.stringWidth(FIXED(AreYouSureYou))) / 2, 5), INFO_TOP); - _surface.writeString(FIXED(WishToQuit), Common::Point((_surface.w() - _surface.stringWidth(FIXED(WishToQuit))) / 2, + _surface.writeString(FIXED(AreYouSureYou), Common::Point((_surface.width() - _surface.stringWidth(FIXED(AreYouSureYou))) / 2, 5), INFO_TOP); + _surface.writeString(FIXED(WishToQuit), Common::Point((_surface.width() - _surface.stringWidth(FIXED(WishToQuit))) / 2, _surface.fontHeight() + 9), INFO_TOP); // Draw the horizontal bars seperating the commands and the message int yp = (_surface.fontHeight() + 4) * 2 + 3; for (int idx = 0; idx < 2; ++idx) { - _surface.transBlitFrom(images[4], Common::Point(0, yp - 1)); - _surface.transBlitFrom(images[5], Common::Point(_surface.w() - images[5]._width, yp - 1)); - _surface.hLine(3, yp, _surface.w() - 4, INFO_TOP); - _surface.hLine(3, yp + 1, _surface.w() - 4, INFO_MIDDLE); - _surface.hLine(3, yp + 2, _surface.w() - 4, INFO_BOTTOM); + _surface.SHtransBlitFrom(images[4], Common::Point(0, yp - 1)); + _surface.SHtransBlitFrom(images[5], Common::Point(_surface.width() - images[5]._width, yp - 1)); + _surface.hLine(3, yp, _surface.width() - 4, INFO_TOP); + _surface.hLine(3, yp + 1, _surface.width() - 4, INFO_MIDDLE); + _surface.hLine(3, yp + 2, _surface.width() - 4, INFO_BOTTOM); const char *btn = (idx == 0) ? YES : NO; _surface.writeString(btn, Common::Point((_bounds.width() - _surface.stringWidth(btn)) / 2, yp + 5), INFO_TOP); @@ -129,11 +129,11 @@ void WidgetQuit::handleEvents() { if (_select != _oldSelect) { byte color = (_select == 1) ? COMMAND_HIGHLIGHTED : INFO_TOP; int yp = (_surface.fontHeight() + 4) * 2 + 8; - _surface.writeString(FIXED(Yes), Common::Point((_surface.w() - _surface.stringWidth(FIXED(Yes))) / 2, yp), color); + _surface.writeString(FIXED(Yes), Common::Point((_surface.width() - _surface.stringWidth(FIXED(Yes))) / 2, yp), color); color = (_select == 0) ? COMMAND_HIGHLIGHTED : INFO_TOP; yp += (_surface.fontHeight() + 7); - _surface.writeString(FIXED(No), Common::Point((_surface.w() - _surface.stringWidth(FIXED(No))) / 2, yp), color); + _surface.writeString(FIXED(No), Common::Point((_surface.width() - _surface.stringWidth(FIXED(No))) / 2, yp), color); } _oldSelect = _select; diff --git a/engines/sherlock/tattoo/widget_talk.cpp b/engines/sherlock/tattoo/widget_talk.cpp index 6e7bde292f..b673f32d31 100644 --- a/engines/sherlock/tattoo/widget_talk.cpp +++ b/engines/sherlock/tattoo/widget_talk.cpp @@ -100,7 +100,7 @@ void WidgetTalk::load() { // Set up the surface _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); // Form the background for the new window makeInfoArea(); @@ -389,7 +389,7 @@ void WidgetTalk::render(Highlight highlightMode) { if (highlightMode == HL_NO_HIGHLIGHTING || _statementLines[idx]._num == _selector || _statementLines[idx]._num == _oldSelector) { // Erase the line contents - _surface.fillRect(Common::Rect(3, yp, _surface.w() - BUTTON_SIZE - 3, yp + _surface.fontHeight()), TRANSPARENCY); + _surface.fillRect(Common::Rect(3, yp, _surface.width() - BUTTON_SIZE - 3, yp + _surface.fontHeight()), TRANSPARENCY); // Different coloring based on whether the option has been previously chosen or not byte color = (!talk._talkHistory[talk._converseNum][_statementLines[idx]._num]) ? diff --git a/engines/sherlock/tattoo/widget_text.cpp b/engines/sherlock/tattoo/widget_text.cpp index d8d229d277..a29cd2700f 100644 --- a/engines/sherlock/tattoo/widget_text.cpp +++ b/engines/sherlock/tattoo/widget_text.cpp @@ -166,7 +166,7 @@ void WidgetText::render(const Common::String &str) { // Allocate a surface for the window _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); // Form the background for the new window makeInfoArea(); @@ -195,7 +195,7 @@ void WidgetMessage::load(const Common::String &str, int time) { // Allocate a surface for the window _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); // Form the background for the new window and write the line of text makeInfoArea(); diff --git a/engines/sherlock/tattoo/widget_tooltip.cpp b/engines/sherlock/tattoo/widget_tooltip.cpp index b29f45f531..1560cb9a80 100644 --- a/engines/sherlock/tattoo/widget_tooltip.cpp +++ b/engines/sherlock/tattoo/widget_tooltip.cpp @@ -47,7 +47,7 @@ void WidgetTooltipBase::draw() { // Draw the widget directly onto the screen. Unlike other widgets, we don't draw to the back buffer, // since nothing should be drawing on top of tooltips, so there's no need to store in the back buffer - screen.transBlitFrom(_surface, Common::Point(_bounds.left - screen._currentScroll.x, + screen.SHtransBlitFrom(_surface, Common::Point(_bounds.left - screen._currentScroll.x, _bounds.top - screen._currentScroll.y)); // Store a copy of the drawn area for later erasing @@ -126,7 +126,7 @@ void WidgetTooltip::setText(const Common::String &str) { // Reallocate the text surface with the new size _surface.create(width, height); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); if (line2.empty()) { // Only a single line diff --git a/engines/sherlock/tattoo/widget_verbs.cpp b/engines/sherlock/tattoo/widget_verbs.cpp index 499afb2e79..5041888ffb 100644 --- a/engines/sherlock/tattoo/widget_verbs.cpp +++ b/engines/sherlock/tattoo/widget_verbs.cpp @@ -127,7 +127,7 @@ void WidgetVerbs::render() { // Create the drawing surface _surface.create(_bounds.width(), _bounds.height()); - _surface.fill(TRANSPARENCY); + _surface.clear(TRANSPARENCY); // Draw basic background makeInfoArea(); @@ -142,8 +142,8 @@ void WidgetVerbs::render() { _surface.hLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 1, _bounds.width() - 4, INFO_MIDDLE); _surface.hLine(3, (_surface.fontHeight() + 7) * (idx + 1) + 2, _bounds.width() - 4, INFO_BOTTOM); - _surface.transBlitFrom(images[4], Common::Point(0, (_surface.fontHeight() + 7) * (idx + 1) - 1)); - _surface.transBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width, + _surface.SHtransBlitFrom(images[4], Common::Point(0, (_surface.fontHeight() + 7) * (idx + 1) - 1)); + _surface.SHtransBlitFrom(images[5], Common::Point(_bounds.width() - images[5]._width, (_surface.fontHeight() + 7) * (idx + 1) - 1)); } } diff --git a/engines/sword25/fmv/movieplayer.cpp b/engines/sword25/fmv/movieplayer.cpp index eb0f0390dc..62a897a332 100644 --- a/engines/sword25/fmv/movieplayer.cpp +++ b/engines/sword25/fmv/movieplayer.cpp @@ -58,6 +58,8 @@ MoviePlayer::~MoviePlayer() { } bool MoviePlayer::loadMovie(const Common::String &filename, uint z) { + if (isMovieLoaded()) + unloadMovie(); // Get the file and load it into the decoder Common::SeekableReadStream *in = Kernel::getInstance()->getPackage()->getStream(filename); _decoder.loadStream(in); diff --git a/engines/tsage/blue_force/blueforce_dialogs.cpp b/engines/tsage/blue_force/blueforce_dialogs.cpp index 5be27c9ae7..3697ca700e 100644 --- a/engines/tsage/blue_force/blueforce_dialogs.cpp +++ b/engines/tsage/blue_force/blueforce_dialogs.cpp @@ -161,7 +161,7 @@ void RightClickDialog::execute() { } g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } // Deactivate the graphics manager used for the dialog @@ -242,7 +242,7 @@ void AmmoBeltDialog::execute() { } g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } _gfxManager.deactivate(); diff --git a/engines/tsage/blue_force/blueforce_logic.cpp b/engines/tsage/blue_force/blueforce_logic.cpp index e6e71399dc..2c5f9bd738 100644 --- a/engines/tsage/blue_force/blueforce_logic.cpp +++ b/engines/tsage/blue_force/blueforce_logic.cpp @@ -859,7 +859,7 @@ void SceneExt::endStrip() { } void SceneExt::clearScreen() { - BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0); + BF_GLOBALS._screen.clear(); } /*--------------------------------------------------------------------------*/ @@ -1411,7 +1411,7 @@ void SceneMessage::process(Event &event) { void SceneMessage::draw() { - GfxSurface &surface = BF_GLOBALS._screenSurface; + GfxSurface &surface = BF_GLOBALS._screen; // Clear the game area surface.fillRect(Rect(0, 0, SCREEN_WIDTH, UI_INTERFACE_Y), 0); diff --git a/engines/tsage/blue_force/blueforce_scenes6.cpp b/engines/tsage/blue_force/blueforce_scenes6.cpp index 92534d3095..0d6b5c2487 100644 --- a/engines/tsage/blue_force/blueforce_scenes6.cpp +++ b/engines/tsage/blue_force/blueforce_scenes6.cpp @@ -78,7 +78,7 @@ void Scene600::Action1::signal() { pObj->animate(ANIM_MODE_NONE, NULL); } - BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0); + BF_GLOBALS._screen.fillRect(BF_GLOBALS._screen.getBounds(), 0); scene->loadScene(999); setDelay(5); break; @@ -275,7 +275,7 @@ void Scene666::postInit(SceneObjectList *OwnerList) { SceneExt::postInit(); BF_GLOBALS._interfaceY = SCREEN_HEIGHT; loadScene(999); - BF_GLOBALS._screenSurface.fillRect(BF_GLOBALS._screenSurface.getBounds(), 0); + BF_GLOBALS._screen.fillRect(BF_GLOBALS._screen.getBounds(), 0); if (BF_GLOBALS._dayNumber == 0) { BF_GLOBALS._dayNumber = 1; diff --git a/engines/tsage/converse.cpp b/engines/tsage/converse.cpp index d1faca5dac..7240c91720 100644 --- a/engines/tsage/converse.cpp +++ b/engines/tsage/converse.cpp @@ -469,7 +469,7 @@ int ConversationChoiceDialog::execute(const Common::StringArray &choiceList) { while (!g_globals->_events.getEvent(event, EVENT_KEYPRESS | EVENT_BUTTON_DOWN | EVENT_MOUSE_MOVE) && !g_vm->shouldQuit()) { g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } if (g_vm->shouldQuit()) break; diff --git a/engines/tsage/core.cpp b/engines/tsage/core.cpp index d4068c25c9..985d16b031 100644 --- a/engines/tsage/core.cpp +++ b/engines/tsage/core.cpp @@ -1467,7 +1467,7 @@ void ScenePalette::fade(const byte *adjustData, bool fullAdjust, int percent) { // Set the altered palette g_system->getPaletteManager()->setPalette((const byte *)&tempPalette[0], 0, 256); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } PaletteRotation *ScenePalette::addRotation(int start, int end, int rotationMode, int duration, Action *action) { @@ -1524,11 +1524,11 @@ void ScenePalette::changeBackground(const Rect &bounds, FadeMode fadeMode) { if (g_vm->getGameID() != GType_Ringworld && g_vm->getGameID() != GType_Sherlock1) tempRect.setHeight(T2_GLOBALS._interfaceY); - g_globals->_screenSurface.copyFrom(g_globals->_sceneManager._scene->_backSurface, + g_globals->_screen.copyFrom(g_globals->_sceneManager._scene->_backSurface, tempRect, Rect(0, 0, tempRect.width(), tempRect.height()), NULL); if (g_vm->getGameID() == GType_Ringworld2 && !GLOBALS._player._uiEnabled && T2_GLOBALS._interfaceY == UI_INTERFACE_Y) { - g_globals->_screenSurface.fillRect(Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT - 1), 0); + g_globals->_screen.fillRect(Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT - 1), 0); } for (SynchronizedList<PaletteModifier *>::iterator i = tempPalette._listeners.begin(); i != tempPalette._listeners.end(); ++i) @@ -1796,7 +1796,7 @@ void SceneItem::display(int resNum, int lineNum, ...) { // Keep event on-screen until a mouse or keypress while (!g_vm->shouldQuit() && !g_globals->_events.getEvent(event, EVENT_BUTTON_DOWN | EVENT_KEYPRESS)) { - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); if ((g_vm->getGameID() == GType_Ringworld2) && (R2_GLOBALS._speechSubtitles & SPEECH_VOICE)) { @@ -2816,7 +2816,7 @@ void SceneObject::updateScreen() { destRect.translate(-sceneBounds.left, -sceneBounds.top); srcRect.translate(-g_globals->_sceneOffset.x, -g_globals->_sceneOffset.y); - g_globals->_screenSurface.copyFrom(g_globals->_sceneManager._scene->_backSurface, srcRect, destRect); + g_globals->_screen.copyFrom(g_globals->_sceneManager._scene->_backSurface, srcRect, destRect); } } diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp index 0491c043a4..1fa17022de 100644 --- a/engines/tsage/events.cpp +++ b/engines/tsage/events.cpp @@ -50,7 +50,7 @@ bool EventsClass::pollEvent() { ++_frameNumber; // Update screen - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } if (!g_system->getEventManager()->pollEvent(_event)) return false; @@ -400,7 +400,7 @@ void EventsClass::delay(int numFrames) { _priorFrameTime = g_system->getMillis(); } - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); _prevDelayFrame = _frameNumber; _priorFrameTime = g_system->getMillis(); } diff --git a/engines/tsage/globals.cpp b/engines/tsage/globals.cpp index b880f35007..b95bea3b23 100644 --- a/engines/tsage/globals.cpp +++ b/engines/tsage/globals.cpp @@ -59,7 +59,7 @@ static SavedObject *classFactoryProc(const Common::String &className) { /*--------------------------------------------------------------------------*/ -Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface), +Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screen), _randomSource("tsage"), _color1(0), _color2(255), _color3(255) { reset(); _stripNum = 0; @@ -119,7 +119,7 @@ Globals::Globals() : _dialogCenter(160, 140), _gfxManagerInstance(_screenSurface _color3 = 4; _dialogCenter.y = 100; } - _screenSurface.setScreenSurface(); + _gfxManagers.push_back(&_gfxManagerInstance); _sceneObjects = &_sceneObjectsInstance; diff --git a/engines/tsage/globals.h b/engines/tsage/globals.h index 1194fe8b9c..e1ebe261dc 100644 --- a/engines/tsage/globals.h +++ b/engines/tsage/globals.h @@ -30,6 +30,7 @@ #include "tsage/events.h" #include "tsage/sound.h" #include "tsage/saveload.h" +#include "tsage/screen.h" #include "tsage/user_interface.h" namespace TsAGE { @@ -38,7 +39,7 @@ class Globals : public SavedObject { private: static void dispatchSound(ASound *obj); public: - GfxSurface _screenSurface; + Screen _screen; GfxManager _gfxManagerInstance; Common::List<GfxManager *> _gfxManagers; SceneHandler *_sceneHandler; diff --git a/engines/tsage/graphics.cpp b/engines/tsage/graphics.cpp index 156503fb51..58fa5b8094 100644 --- a/engines/tsage/graphics.cpp +++ b/engines/tsage/graphics.cpp @@ -229,123 +229,43 @@ void Rect::synchronize(Serializer &s) { /*--------------------------------------------------------------------------*/ -GfxSurface::GfxSurface() : _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) { +GfxSurface::GfxSurface() : Graphics::ManagedSurface(), _bounds(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) { _disableUpdates = false; _lockSurfaceCtr = 0; - _customSurface = NULL; _transColor = -1; - _trackDirtyRects = false; _flags = 0; } -GfxSurface::GfxSurface(const GfxSurface &s) { +GfxSurface::GfxSurface(const GfxSurface &s): Graphics::ManagedSurface() { _lockSurfaceCtr = 0; - _customSurface = NULL; - _trackDirtyRects = false; - *this = s; + + operator=(s); } GfxSurface::~GfxSurface() { - clear(); + // Sanity check.. GfxSurface should always be just referencing _rawSurface, + // and not directly managing it's own surface + assert(disposeAfterUse() == DisposeAfterUse::NO); } -void GfxSurface::clear() { - if (_customSurface) { - _customSurface->free(); - delete _customSurface; - _customSurface = NULL; - } -} - -/** - * Specifies that the surface will encapsulate the ScummVM screen surface - */ -void GfxSurface::setScreenSurface() { - _trackDirtyRects = true; - create(SCREEN_WIDTH, SCREEN_HEIGHT); -} - -/** - * Updates the physical screen with the screen surface buffer - */ -void GfxSurface::updateScreen() { - assert(_trackDirtyRects); - - // Merge any overlapping dirty rects - mergeDirtyRects(); - - // Loop through the dirty rect list to copy the affected areas to the sc - for (Common::List<Rect>::iterator i = _dirtyRects.begin(); i != _dirtyRects.end(); ++i) { - Rect r = *i; - - // Make sure that there is something to update. If not, skip this - // rectangle. An example case is the speedbike closeup at the beginning - // of Ringworld (third screen). - if (r.isEmpty()) - continue; - - const byte *srcP = (const byte *)_customSurface->getBasePtr(r.left, r.top); - g_system->copyRectToScreen(srcP, _customSurface->pitch, r.left, r.top, - r.width(), r.height()); - } - - // Update the physical screen - g_system->updateScreen(); - - // Now that the dirty rects have been copied, clear the dirty rect list - _dirtyRects.clear(); -} +void GfxSurface::create(uint16 width, uint16 height) { + free(); -/** - * Adds a rect to the dirty rect list - */ -void GfxSurface::addDirtyRect(const Rect &r) { - if (_trackDirtyRects) { - // Get the bounds and adjust to allow for sub-screen areas - Rect r2 = r; - r2.translate(_bounds.left, _bounds.top); - - // Add to the dirty rect list - r2.right = MIN(r2.right + 1, SCREEN_WIDTH); - r2.bottom = MIN(r2.bottom + 1, SCREEN_HEIGHT); - - if (r2.isValidRect()) - _dirtyRects.push_back(r2); - } + _rawSurface.create(width, height); + setBounds(Rect(0, 0, width, height)); } - - -/** - * Specifies that the surface should maintain it's own internal surface - */ -void GfxSurface::create(int width, int height) { - assert((width >= 0) && (height >= 0)); - - if (_customSurface) { - _customSurface->free(); - delete _customSurface; - } - _customSurface = new Graphics::Surface(); - _customSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8()); - Common::fill((byte *)_customSurface->getPixels(), (byte *)_customSurface->getBasePtr(0, height), 0); - _bounds = Rect(0, 0, width, height); +void GfxSurface::setBounds(const Rect &bounds) { + _bounds = bounds; + Graphics::ManagedSurface::create(_rawSurface, bounds); } /** * Locks the surface for access, and returns a raw ScummVM surface to manipulate it */ -Graphics::Surface GfxSurface::lockSurface() { +Graphics::ManagedSurface &GfxSurface::lockSurface() { ++_lockSurfaceCtr; - - Graphics::Surface *src = _customSurface; - assert(src); - - // Setup the returned surface either as one pointing to the same pixels as the source, or - // as a subset of the source one based on the currently set bounds - Graphics::Surface result; - result.init(_bounds.width(), _bounds.height(), src->pitch, src->getBasePtr(_bounds.left, _bounds.top), src->format); - return result; + return *this; } /** @@ -367,69 +287,43 @@ void GfxSurface::synchronize(Serializer &s) { if (s.isSaving()) { // Save contents of the surface - if (_customSurface) { - s.syncAsSint16LE(_customSurface->w); - s.syncAsSint16LE(_customSurface->h); - s.syncBytes((byte *)_customSurface->getPixels(), _customSurface->w * _customSurface->h); + if (disposeAfterUse() == DisposeAfterUse::YES) { + s.syncAsSint16LE(this->w); + s.syncAsSint16LE(this->h); + s.syncBytes((byte *)getPixels(), this->w * this->h); } else { int zero = 0; s.syncAsSint16LE(zero); s.syncAsSint16LE(zero); } } else { - int w = 0, h = 0; - s.syncAsSint16LE(w); - s.syncAsSint16LE(h); - - if ((w == 0) || (h == 0)) { - if (_customSurface) - delete _customSurface; - _customSurface = NULL; + int xSize = 0, ySize = 0; + s.syncAsSint16LE(xSize); + s.syncAsSint16LE(ySize); + + if (xSize == 0 || ySize == 0) { + free(); } else { - create(w, h); - s.syncBytes((byte *)_customSurface->getPixels(), w * h); + create(xSize, ySize); + s.syncBytes((byte *)getPixels(), xSize * ySize); } } } -/** - * Fills a specified rectangle on the surface with the specified color - * - * @bounds Area to fill - * @color Color to use - */ -void GfxSurface::fillRect(const Rect &bounds, int color) { - Graphics::Surface surface = lockSurface(); - surface.fillRect(bounds, color); - unlockSurface(); - addDirtyRect(bounds); -} - GfxSurface &GfxSurface::operator=(const GfxSurface &s) { assert(_lockSurfaceCtr == 0); assert(s._lockSurfaceCtr == 0); - if (_customSurface) { - _customSurface->free(); - delete _customSurface; - } - - _customSurface = s._customSurface; _disableUpdates = s._disableUpdates; _bounds = s._bounds; _centroid = s._centroid; _transColor = s._transColor; _flags = s._flags; - if (_customSurface) { - // Surface owns the internal data, so replicate it so new surface owns it's own - _customSurface = new Graphics::Surface(); - _customSurface->create(s._customSurface->w, s._customSurface->h, Graphics::PixelFormat::createFormatCLUT8()); - const byte *srcP = (const byte *)s._customSurface->getPixels(); - byte *destP = (byte *)_customSurface->getPixels(); - - Common::copy(srcP, srcP + (_bounds.width() * _bounds.height()), destP); - } + // Copy the source's surface + create(s.w, s.h); + blitFrom(s); + setBounds(s.getBounds()); return *this; } @@ -474,7 +368,7 @@ bool GfxSurface::displayText(const Common::String &msg, const Common::Point &pt) /** * Loads a quarter of a screen from a resource */ -void GfxSurface::loadScreenSection(Graphics::Surface &dest, int xHalf, int yHalf, int xSection, int ySection) { +void GfxSurface::loadScreenSection(Graphics::ManagedSurface &dest, int xHalf, int yHalf, int xSection, int ySection) { int screenNum = g_globals->_sceneManager._scene->_activeScreenNumber; Rect updateRect(0, 0, 160, 100); updateRect.translate(xHalf * 160, yHalf * 100); @@ -682,50 +576,6 @@ void GfxSurface::draw(const Common::Point &pt, Rect *rect) { } } -/** - * Merges any clipping rectangles that overlap to try and reduce - * the total number of clip rectangles. - */ -void GfxSurface::mergeDirtyRects() { - if (_dirtyRects.size() <= 1) - return; - - Common::List<Rect>::iterator rOuter, rInner; - - for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) { - rInner = rOuter; - while (++rInner != _dirtyRects.end()) { - - if ((*rOuter).intersects(*rInner)) { - // these two rectangles overlap or - // are next to each other - merge them - - unionRectangle(*rOuter, *rOuter, *rInner); - - // remove the inner rect from the list - _dirtyRects.erase(rInner); - - // move back to beginning of list - rInner = rOuter; - } - } - } -} - -/** - * Creates the union of two rectangles. - * Returns True if there is a union. - * @param pDest destination rectangle that is to receive the new union - * @param pSrc1 a source rectangle - * @param pSrc2 a source rectangle - */ -bool GfxSurface::unionRectangle(Common::Rect &destRect, const Rect &src1, const Rect &src2) { - destRect = src1; - destRect.extend(src2); - - return !destRect.isEmpty(); -} - /*--------------------------------------------------------------------------*/ GfxElement::GfxElement() { @@ -762,17 +612,16 @@ void GfxElement::highlight() { Rect tempRect(_bounds); tempRect.collapse(g_globals->_gfxEdgeAdjust - 1, g_globals->_gfxEdgeAdjust - 1); - for (int yp = tempRect.top; yp < tempRect.bottom; ++yp) { - byte *lineP = (byte *)surface.getBasePtr(tempRect.left, yp); - for (int xp = tempRect.left; xp < tempRect.right; ++xp, ++lineP) { + Graphics::Surface dest = surface.getSubArea(tempRect); + + for (int yp = 0; yp < dest.h; ++yp) { + byte *lineP = (byte *)dest.getBasePtr(0, yp); + for (int xp = 0; xp < tempRect.right; ++xp, ++lineP) { if (*lineP == _colors.background) *lineP = _colors.foreground; else if (*lineP == _colors.foreground) *lineP = _colors.background; } } - // Mark the affected area as dirty - gfxManager.getSurface().addDirtyRect(tempRect); - // Release the surface gfxManager.unlockSurface(); } @@ -816,10 +665,11 @@ void GfxElement::drawFrame() { // Loop through the surface area to replace each pixel // with its proper shaded replacement - Graphics::Surface surface = gfxManager.lockSurface(); - for (int y = tempRect.top; y < tempRect.bottom; ++y) { - byte *lineP = (byte *)surface.getBasePtr(tempRect.left, y); - for (int x = 0; x < tempRect.width(); ++x) { + Graphics::Surface dest = gfxManager.getSurface().getSubArea(tempRect); + + for (int y = 0; y < dest.h; ++y) { + byte *lineP = (byte *)dest.getBasePtr(0, y); + for (int x = 0; x < dest.w; ++x) { *lineP = transList[*lineP]; lineP++; } @@ -827,27 +677,24 @@ void GfxElement::drawFrame() { // Draw the edge frame // Outer frame border - surface.hLine(tempRect.left + 2, tempRect.top, tempRect.right - 2, 0); - surface.hLine(tempRect.left + 2, tempRect.bottom, tempRect.right - 2, 0); - surface.vLine(tempRect.left, tempRect.top + 2, tempRect.bottom - 2, 0); - surface.vLine(tempRect.right, tempRect.top + 2, tempRect.bottom - 2, 0); - *((byte *)surface.getBasePtr(tempRect.left + 1, tempRect.top + 1)) = 0; - *((byte *)surface.getBasePtr(tempRect.right - 1, tempRect.top + 1)) = 0; - *((byte *)surface.getBasePtr(tempRect.left + 1, tempRect.bottom - 1)) = 0; - *((byte *)surface.getBasePtr(tempRect.right - 1, tempRect.bottom - 1)) = 0; + dest.hLine(2, 0, dest.w - 2, 0); + dest.hLine(2, dest.h - 1, dest.w - 2, 0); + dest.vLine(0, 2, dest.h - 2, 0); + dest.vLine(tempRect.right, 2, dest.h - 2, 0); + *((byte *)dest.getBasePtr(1, 1)) = 0; + *((byte *)dest.getBasePtr(dest.w - 1, 1)) = 0; + *((byte *)dest.getBasePtr(1, dest.h - 1)) = 0; + *((byte *)dest.getBasePtr(dest.w - 1, dest.h - 1)) = 0; // Inner frame border - surface.hLine(tempRect.left + 2, tempRect.top + 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor); - surface.hLine(tempRect.left + 2, tempRect.bottom - 1, tempRect.right - 2, R2_GLOBALS._frameEdgeColor); - surface.vLine(tempRect.left + 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor); - surface.vLine(tempRect.right - 1, tempRect.top + 2, tempRect.bottom - 2, R2_GLOBALS._frameEdgeColor); - *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor; - *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.top + 2)) = R2_GLOBALS._frameEdgeColor; - *((byte *)surface.getBasePtr(tempRect.left + 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor; - *((byte *)surface.getBasePtr(tempRect.right - 2, tempRect.bottom - 2)) = R2_GLOBALS._frameEdgeColor; - - gfxManager.unlockSurface(); - gfxManager.getSurface().addDirtyRect(tempRect); + dest.hLine(2, 1, dest.w - 2, R2_GLOBALS._frameEdgeColor); + dest.hLine(2, dest.h - 1, dest.w - 2, R2_GLOBALS._frameEdgeColor); + dest.vLine(1, 2, dest.h - 2, R2_GLOBALS._frameEdgeColor); + dest.vLine(dest.w - 1, 2, dest.h - 2, R2_GLOBALS._frameEdgeColor); + *((byte *)dest.getBasePtr(2, 2)) = R2_GLOBALS._frameEdgeColor; + *((byte *)dest.getBasePtr(dest.w - 2, 2)) = R2_GLOBALS._frameEdgeColor; + *((byte *)dest.getBasePtr(2, dest.h - 2)) = R2_GLOBALS._frameEdgeColor; + *((byte *)dest.getBasePtr(dest.w - 2, dest.h - 2)) = R2_GLOBALS._frameEdgeColor; } else { // Fill dialog content with specified background color @@ -1236,7 +1083,7 @@ GfxButton *GfxDialog::execute(GfxButton *defaultButton) { } g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } _gfxManager.deactivate(); @@ -1269,7 +1116,7 @@ void GfxDialog::setPalette() { /*--------------------------------------------------------------------------*/ -GfxManager::GfxManager() : _surface(g_globals->_screenSurface), _oldManager(NULL) { +GfxManager::GfxManager() : _surface(g_globals->_screen), _oldManager(NULL) { _font.setOwner(this); _font._fillFlag = false; _bounds = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); @@ -1563,23 +1410,24 @@ int GfxFont::writeChar(const char ch) { int yOffset = (_fontData[charOffset + 1] >> 3) & 0x1f; const uint8 *dataP = &_fontData[charOffset + 2]; - // Lock the surface for access - Graphics::Surface surfacePtr = _gfxManager->lockSurface(); - Rect charRect; charRect.set(0, 0, charWidth, _fontSize.y); charRect.translate(_topLeft.x + _position.x, _topLeft.y + _position.y + yOffset); + // Get the sub-section of the screen to update + Graphics::Surface dest = _gfxManager->getSurface().getSubArea(charRect); + if (_fillFlag) - surfacePtr.fillRect(charRect, _colors.background); + dest.fillRect(charRect, _colors.background); charRect.bottom = charRect.top + charHeight; + assert(charRect.height() <= dest.h); // Display the character int bitCtr = 0; uint8 v = 0; - for (int yp = charRect.top; yp < charRect.bottom; ++yp) { - byte *destP = (byte *)surfacePtr.getBasePtr(charRect.left, yp); + for (int yp = 0; yp < charHeight; ++yp) { + byte *destP = (byte *)dest.getBasePtr(0, yp); for (int xs = 0; xs < charRect.width(); ++xs, ++destP) { // Get the next color index to use @@ -1599,13 +1447,9 @@ int GfxFont::writeChar(const char ch) { } } - // Mark the affected area as dirty - _gfxManager->getSurface().addDirtyRect(charRect); - // Move the text writing position _position.x += charWidth; - _gfxManager->unlockSurface(); return charWidth; } diff --git a/engines/tsage/graphics.h b/engines/tsage/graphics.h index 25f7aea8cd..3b395b7625 100644 --- a/engines/tsage/graphics.h +++ b/engines/tsage/graphics.h @@ -28,7 +28,7 @@ #include "common/list.h" #include "common/rect.h" #include "common/system.h" -#include "graphics/surface.h" +#include "graphics/managed_surface.h" namespace TsAGE { @@ -73,20 +73,13 @@ public: enum FrameFlag { FRAME_FLIP_CENTROID_X = 4, FRAME_FLIP_CENTROID_Y = 8 }; -class GfxSurface { +class GfxSurface: virtual public Graphics::ManagedSurface { private: - Graphics::Surface *_customSurface; int _lockSurfaceCtr; + Graphics::ManagedSurface _rawSurface; bool _disableUpdates; Rect _bounds; - - bool _trackDirtyRects; - Common::List<Rect> _dirtyRects; - - void mergeDirtyRects(); - bool unionRectangle(Common::Rect &destRect, const Rect &src1, const Rect &src2); - public: Common::Point _centroid; int _transColor; @@ -95,17 +88,13 @@ public: public: GfxSurface(); GfxSurface(const GfxSurface &s); - ~GfxSurface(); + virtual ~GfxSurface(); - void setScreenSurface(); - void updateScreen(); - void addDirtyRect(const Rect &r); - Graphics::Surface lockSurface(); + Graphics::ManagedSurface &lockSurface(); void unlockSurface(); void synchronize(Serializer &s); - void create(int width, int height); - void clear(); - void setBounds(const Rect &bounds) { _bounds = bounds; } + virtual void create(uint16 width, uint16 height); + void setBounds(const Rect &bounds); const Rect &getBounds() const { return _bounds; } void copyFrom(GfxSurface &src, Rect srcBounds, Rect destBounds, @@ -119,10 +108,9 @@ public: copyFrom(src, tempRect, priorityRegion); } void draw(const Common::Point &pt, Rect *rect = NULL); - void fillRect(const Rect &bounds, int color); GfxSurface &operator=(const GfxSurface &s); - static void loadScreenSection(Graphics::Surface &dest, int xHalf, int yHalf, int xSection, int ySection); + static void loadScreenSection(Graphics::ManagedSurface &dest, int xHalf, int yHalf, int xSection, int ySection); static bool displayText(const Common::String &msg, const Common::Point &pt = Common::Point(160, 100)); }; @@ -281,7 +269,7 @@ public: void getStringBounds(const char *s, Rect &bounds, int maxWidth); void setDialogPalette(); - Graphics::Surface lockSurface() { + Graphics::ManagedSurface lockSurface() { _surface.setBounds(_bounds); return _surface.lockSurface(); } diff --git a/engines/tsage/module.mk b/engines/tsage/module.mk index e23b157a95..b58c748567 100644 --- a/engines/tsage/module.mk +++ b/engines/tsage/module.mk @@ -47,6 +47,7 @@ MODULE_OBJS := \ ringworld2/ringworld2_vampire.o \ saveload.o \ scenes.o \ + screen.o \ sherlock/sherlock_logo.o \ sound.o \ staticres.o \ diff --git a/engines/tsage/ringworld/ringworld_dialogs.cpp b/engines/tsage/ringworld/ringworld_dialogs.cpp index 1dd3bc158b..9fa17f3920 100644 --- a/engines/tsage/ringworld/ringworld_dialogs.cpp +++ b/engines/tsage/ringworld/ringworld_dialogs.cpp @@ -181,7 +181,7 @@ void RightClickDialog::execute() { } g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } _gfxManager.deactivate(); @@ -391,7 +391,7 @@ void InventoryDialog::execute() { Event event; while (!g_globals->_events.getEvent(event) && !g_vm->shouldQuit()) { g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } if (g_vm->shouldQuit()) break; @@ -439,7 +439,7 @@ void InventoryDialog::execute() { // Inventory item selected InvObject *invObject = static_cast<GfxInvImage *>(hiliteObj)->_invObject; if (lookFlag) { - g_globals->_screenSurface.displayText(invObject->_description); + g_globals->_screen.displayText(invObject->_description); } else { RING_INVENTORY._selectedItem = invObject; invObject->setCursor(); diff --git a/engines/tsage/ringworld/ringworld_logic.cpp b/engines/tsage/ringworld/ringworld_logic.cpp index 1d8293cffd..354c86abfc 100644 --- a/engines/tsage/ringworld/ringworld_logic.cpp +++ b/engines/tsage/ringworld/ringworld_logic.cpp @@ -320,7 +320,7 @@ void SceneArea::wait() { // Wait until a mouse or keypress Event event; while (!g_vm->shouldQuit() && !g_globals->_events.getEvent(event)) { - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); } diff --git a/engines/tsage/ringworld/ringworld_scenes3.cpp b/engines/tsage/ringworld/ringworld_scenes3.cpp index a515224964..a9ed7af870 100644 --- a/engines/tsage/ringworld/ringworld_scenes3.cpp +++ b/engines/tsage/ringworld/ringworld_scenes3.cpp @@ -532,7 +532,7 @@ void Scene2100::Action1::signal() { // Wait for an event Event event; if (!g_globals->_events.getEvent(event)) { - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); continue; } @@ -2265,7 +2265,7 @@ void Scene2150::Action1::signal() { // Wait for an event Event event; if (!g_globals->_events.getEvent(event)) { - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); continue; } @@ -5119,7 +5119,7 @@ void Scene2320::Action3::signal() { // Wait for an event Event event; if (!g_globals->_events.getEvent(event)) { - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); continue; } diff --git a/engines/tsage/ringworld/ringworld_scenes5.cpp b/engines/tsage/ringworld/ringworld_scenes5.cpp index cb8a89de80..98859f32ee 100644 --- a/engines/tsage/ringworld/ringworld_scenes5.cpp +++ b/engines/tsage/ringworld/ringworld_scenes5.cpp @@ -2813,7 +2813,7 @@ void Scene4150::Action1::signal() { case 4: { for (int idx = 100; idx >= 0; idx -= 5) { g_globals->_scenePalette.fade(adjustData, false, idx); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); } @@ -2841,7 +2841,7 @@ void Scene4150::Action1::signal() { case 7: for (int idx = 100; idx >= 0; idx -= 5) { g_globals->_scenePalette.fade(adjustData, false, idx); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); } diff --git a/engines/tsage/ringworld2/ringworld2_dialogs.cpp b/engines/tsage/ringworld2/ringworld2_dialogs.cpp index 99f88a1687..027fb558db 100644 --- a/engines/tsage/ringworld2/ringworld2_dialogs.cpp +++ b/engines/tsage/ringworld2/ringworld2_dialogs.cpp @@ -154,7 +154,7 @@ int RightClickDialog::execute() { } g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } // Execute the specified action diff --git a/engines/tsage/ringworld2/ringworld2_logic.cpp b/engines/tsage/ringworld2/ringworld2_logic.cpp index d24541932f..ecaa671bd7 100644 --- a/engines/tsage/ringworld2/ringworld2_logic.cpp +++ b/engines/tsage/ringworld2/ringworld2_logic.cpp @@ -351,7 +351,7 @@ SceneExt::SceneExt(): Scene() { _preventSaving = false; // Reset screen clipping area - R2_GLOBALS._screenSurface._clipRect = Rect(); + R2_GLOBALS._screen._clipRect = Rect(); // WORKAROUND: In the original, playing animations don't reset the global _animationCtr // counter as scene changes unless the playing animation explicitly finishes. For now, @@ -513,7 +513,7 @@ void SceneExt::endStrip() { } void SceneExt::clearScreen() { - R2_GLOBALS._screenSurface.fillRect(R2_GLOBALS._screenSurface.getBounds(), 0); + R2_GLOBALS._screen.fillRect(R2_GLOBALS._screen.getBounds(), 0); } void SceneExt::refreshBackground(int xAmount, int yAmount) { @@ -543,15 +543,12 @@ void SceneExt::refreshBackground(int xAmount, int yAmount) { int screenSize = g_vm->_memoryManager.getSize(dataP); // Lock the background for update - Graphics::Surface s = _backSurface.lockSurface(); - assert(screenSize == (s.w * s.h)); + assert(screenSize == (_backSurface.w * _backSurface.h)); + Graphics::Surface s = _backSurface.getSubArea(Common::Rect(0, 0, _backSurface.w, _backSurface.h)); - // Copy the data + // Copy the data into the surface byte *destP = (byte *)s.getPixels(); Common::copy(dataP, dataP + (s.w * s.h), destP); - _backSurface.unlockSurface(); - - R2_GLOBALS._screenSurface.addDirtyRect(_backSurface.getBounds()); // Free the resource data DEALLOCATE(dataP); @@ -601,7 +598,7 @@ void SceneExt::loadBlankScene() { _backSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT * 3 / 2); _backSurface.fillRect(_backSurface.getBounds(), 0); - R2_GLOBALS._screenSurface.fillRect(R2_GLOBALS._screenSurface.getBounds(), 0); + R2_GLOBALS._screen.fillRect(R2_GLOBALS._screen.getBounds(), 0); } /*--------------------------------------------------------------------------*/ @@ -1966,10 +1963,9 @@ void AnimationPlayer::drawFrame(int sliceIndex) { byte *sliceData1 = sliceDataStart; Rect playerBounds = _screenBounds; - int y = _screenBounds.top; - R2_GLOBALS._screenSurface.addDirtyRect(playerBounds); - Graphics::Surface surface = R2_GLOBALS._screenSurface.lockSurface(); + Graphics::Surface dest = R2_GLOBALS._screen.getSubArea(playerBounds); + int y = 0; // Handle different drawing modes switch (slice._drawMode) { @@ -1980,7 +1976,7 @@ void AnimationPlayer::drawFrame(int sliceIndex) { // TODO: Check of _subData._drawType was done for two different kinds of // line slice drawing in original const byte *pSrc = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2); - byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++); + byte *pDest = (byte *)dest.getBasePtr(0, y++); Common::copy(pSrc, pSrc + _subData._sliceSize, pDest); } @@ -1997,7 +1993,7 @@ void AnimationPlayer::drawFrame(int sliceIndex) { if (offset) { const byte *pSrc = (const byte *)sliceDataStart + offset; - byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, playerBounds.top); + byte *pDest = (byte *)dest.getBasePtr(0, 0); //Common::copy(pSrc, pSrc + playerBounds.width(), pDest); rleDecode(pSrc, pDest, playerBounds.width()); @@ -2012,7 +2008,7 @@ void AnimationPlayer::drawFrame(int sliceIndex) { // TODO: Check of _subData._drawType was done for two different kinds of // line slice drawing in original const byte *pSrc = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2); - byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, playerBounds.top); + byte *pDest = (byte *)dest.getBasePtr(0, 0); rleDecode(pSrc, pDest, _subData._sliceSize); } @@ -2027,7 +2023,7 @@ void AnimationPlayer::drawFrame(int sliceIndex) { for (int yIndex = 0; yIndex < _sliceHeight; ++yIndex) { const byte *pSrc1 = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData2 + sliceNum * 2); const byte *pSrc2 = (const byte *)sliceDataStart + READ_LE_UINT16(sliceData1 + sliceNum * 2); - byte *pDest = (byte *)surface.getBasePtr(playerBounds.left, y++); + byte *pDest = (byte *)dest.getBasePtr(0, y++); if (slice2._drawMode == 0) { // Uncompressed background, foreground compressed @@ -2047,17 +2043,14 @@ void AnimationPlayer::drawFrame(int sliceIndex) { break; } - // Unlock the screen surface - R2_GLOBALS._screenSurface.unlockSurface(); - if (_objectMode == ANIMOBJMODE_42) { _screenBounds.expandPanes(); // Copy the drawn frame to the back surface - Rect srcRect = R2_GLOBALS._screenSurface.getBounds(); + Rect srcRect = R2_GLOBALS._screen.getBounds(); Rect destRect = srcRect; destRect.translate(-g_globals->_sceneOffset.x, -g_globals->_sceneOffset.y); - R2_GLOBALS._sceneManager._scene->_backSurface.copyFrom(R2_GLOBALS._screenSurface, + R2_GLOBALS._sceneManager._scene->_backSurface.copyFrom(R2_GLOBALS._screen, srcRect, destRect); // Draw any objects into the scene diff --git a/engines/tsage/ringworld2/ringworld2_outpost.cpp b/engines/tsage/ringworld2/ringworld2_outpost.cpp index cad21b4623..8c64970bda 100644 --- a/engines/tsage/ringworld2/ringworld2_outpost.cpp +++ b/engines/tsage/ringworld2/ringworld2_outpost.cpp @@ -4689,7 +4689,7 @@ GfxButton *Scene1337::OptionsDialog::execute(GfxButton *defaultButton) { } g_system->delayMillis(10); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); } _gfxManager.deactivate(); diff --git a/engines/tsage/ringworld2/ringworld2_scenes0.cpp b/engines/tsage/ringworld2/ringworld2_scenes0.cpp index 573cbbb29a..63879b0366 100644 --- a/engines/tsage/ringworld2/ringworld2_scenes0.cpp +++ b/engines/tsage/ringworld2/ringworld2_scenes0.cpp @@ -1613,7 +1613,7 @@ void Scene180::signal() { case 43: case 47: _helpEnabled = false; - R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); + R2_GLOBALS._screen.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); _palette.loadPalette(0); _palette.loadPalette(9998); R2_GLOBALS._scenePalette.addFader(_palette._palette, 256, 8, this); @@ -1815,7 +1815,7 @@ void Scene180::signal() { _shipDisplay.remove(); _backSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); - R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); + R2_GLOBALS._screen.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); R2_GLOBALS._sound2.fadeOut2(NULL); R2_GLOBALS._sound1.fadeOut2(this); break; @@ -1880,7 +1880,7 @@ void Scene180::signal() { R2_GLOBALS._paneRefreshFlag[0] = 3; _backSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); - R2_GLOBALS._screenSurface.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); + R2_GLOBALS._screen.fillRect(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); setSceneDelay(1); break; diff --git a/engines/tsage/saveload.cpp b/engines/tsage/saveload.cpp index 9954b929b2..3cb8e52692 100644 --- a/engines/tsage/saveload.cpp +++ b/engines/tsage/saveload.cpp @@ -289,10 +289,10 @@ void Saver::writeSavegameHeader(Common::OutSaveFile *out, tSageSavegameHeader &h // Create a thumbnail and save it Graphics::Surface *thumb = new Graphics::Surface(); - Graphics::Surface s = g_globals->_screenSurface.lockSurface(); + Graphics::Surface s = g_globals->_screen.lockSurface(); ::createThumbnail(thumb, (const byte *)s.getPixels(), SCREEN_WIDTH, SCREEN_HEIGHT, thumbPalette); Graphics::saveThumbnail(*out, *thumb); - g_globals->_screenSurface.unlockSurface(); + g_globals->_screen.unlockSurface(); thumb->free(); delete thumb; diff --git a/engines/tsage/scenes.cpp b/engines/tsage/scenes.cpp index 80ce1e3ecc..095c0d7ab5 100644 --- a/engines/tsage/scenes.cpp +++ b/engines/tsage/scenes.cpp @@ -139,7 +139,7 @@ void SceneManager::fadeInIfNecessary() { percent = 100; g_globals->_scenePalette.fade((const byte *)&adjustData, false, percent); - GLOBALS._screenSurface.updateScreen(); + GLOBALS._screen.update(); g_system->delayMillis(10); } @@ -175,7 +175,7 @@ void SceneManager::changeScene(int newSceneNumber) { } // Blank out the screen - g_globals->_screenSurface.fillRect(g_globals->_screenSurface.getBounds(), 0); + g_globals->_screen.fillRect(g_globals->_screen.getBounds(), 0); // If there are any fading sounds, wait until fading is complete while (g_globals->_soundManager.isFading()) { @@ -463,7 +463,7 @@ void Scene::refreshBackground(int xAmount, int yAmount) { // Check if the section is already loaded if ((_enabledSections[xp * 16 + yp] == 0xffff) || ((xAmount == 0) && (yAmount == 0))) { // Chunk isn't loaded, so load it in - Graphics::Surface s = _backSurface.lockSurface(); + Graphics::ManagedSurface s = _backSurface.lockSurface(); GfxSurface::loadScreenSection(s, xp - xHalfOffset, yp - yHalfOffset, xp, yp); _backSurface.unlockSurface(); changedFlag = true; diff --git a/engines/tsage/screen.cpp b/engines/tsage/screen.cpp new file mode 100644 index 0000000000..f11c384797 --- /dev/null +++ b/engines/tsage/screen.cpp @@ -0,0 +1,46 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/scummsys.h" +#include "tsage/screen.h" + +namespace TsAGE { + +Screen::Screen(): GfxSurface(), Graphics::Screen() { + create(SCREEN_WIDTH, SCREEN_HEIGHT); +} + +void Screen::update() { + // When dialogs are active, the screen surface may be remapped to + // sub-sections of the screen. But for drawing we'll need to temporarily + // remove any such remappings and use the entirety of the screen + Rect clipBounds = getBounds(); + setBounds(Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)); + + // Update the screen + Graphics::Screen::update(); + + // Reset the clipping + setBounds(clipBounds); +} + +} // End of namespace TsAGE diff --git a/engines/tsage/screen.h b/engines/tsage/screen.h new file mode 100644 index 0000000000..bf5057e4d6 --- /dev/null +++ b/engines/tsage/screen.h @@ -0,0 +1,59 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TSAGE_SCREEN_H +#define TSAGE_SCREEN_H + +#include "common/scummsys.h" +#include "common/array.h" +#include "graphics/screen.h" +#include "tsage/graphics.h" + +namespace TsAGE { + +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 200 +#define SCREEN_CENTER_X 160 +#define SCREEN_CENTER_Y 100 +#define UI_INTERFACE_Y 168 + +class Screen : virtual public Graphics::Screen, virtual public GfxSurface { +public: + /** + * Constructor + */ + Screen(); + + /** + * Destructor + */ + virtual ~Screen() {} + + /** + * Update the screen + */ + virtual void update(); +}; + +} // End of namespace TsAGE + +#endif /* MADS_SCREEN_H */ diff --git a/engines/tsage/tsage.h b/engines/tsage/tsage.h index 667a8daa59..1a29700a10 100644 --- a/engines/tsage/tsage.h +++ b/engines/tsage/tsage.h @@ -62,12 +62,6 @@ enum { struct tSageGameDescription; -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 200 -#define SCREEN_CENTER_X 160 -#define SCREEN_CENTER_Y 100 -#define UI_INTERFACE_Y 168 - class TSageEngine : public Engine { private: const tSageGameDescription *_gameDescription; diff --git a/engines/tsage/user_interface.cpp b/engines/tsage/user_interface.cpp index 3ee585d5ef..fffc0dc16c 100644 --- a/engines/tsage/user_interface.cpp +++ b/engines/tsage/user_interface.cpp @@ -253,7 +253,7 @@ void UICollection::show() { void UICollection::erase() { if (_clearScreen) { Rect tempRect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT); - GLOBALS._screenSurface.fillRect(tempRect, 0); + GLOBALS._screen.fillRect(tempRect, 0); GLOBALS._sceneManager._scene->_backSurface.fillRect(tempRect, 0); _clearScreen = false; } @@ -274,7 +274,7 @@ void UICollection::draw() { _objList[idx]->draw(); // Draw the resulting UI onto the screen - GLOBALS._screenSurface.copyFrom(GLOBALS._sceneManager._scene->_backSurface, + GLOBALS._screen.copyFrom(GLOBALS._sceneManager._scene->_backSurface, Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT), Rect(0, UI_INTERFACE_Y, SCREEN_WIDTH, SCREEN_HEIGHT)); @@ -293,12 +293,12 @@ void UICollection::r2rDrawFrame() { GfxSurface vertLineRight = visage.getFrame(3); GfxSurface horizLine = visage.getFrame(2); - GLOBALS._screenSurface.copyFrom(horizLine, 0, 0); - GLOBALS._screenSurface.copyFrom(vertLineLeft, 0, 3); - GLOBALS._screenSurface.copyFrom(vertLineRight, SCREEN_WIDTH - 4, 3); + GLOBALS._screen.copyFrom(horizLine, 0, 0); + GLOBALS._screen.copyFrom(vertLineLeft, 0, 3); + GLOBALS._screen.copyFrom(vertLineRight, SCREEN_WIDTH - 4, 3); // Restrict drawing area to exclude the borders at the edge of the screen - R2_GLOBALS._screenSurface._clipRect = Rect(4, 3, SCREEN_WIDTH - 4, + R2_GLOBALS._screen._clipRect = Rect(4, 3, SCREEN_WIDTH - 4, SCREEN_HEIGHT - 3); } diff --git a/engines/voyeur/animation.cpp b/engines/voyeur/animation.cpp index 62b37346da..d5d58a2fd3 100644 --- a/engines/voyeur/animation.cpp +++ b/engines/voyeur/animation.cpp @@ -470,7 +470,7 @@ void RL2Decoder::play(VoyeurEngine *vm, int resourceOffset, if (hasDirtyPalette()) { const byte *palette = getPalette(); - vm->_graphicsManager->setPalette128(palette, paletteStart, paletteCount); + vm->_screen->setPalette128(palette, paletteStart, paletteCount); } if (needsUpdate()) { @@ -482,15 +482,14 @@ void RL2Decoder::play(VoyeurEngine *vm, int resourceOffset, Common::Point pt(READ_LE_UINT16(imgPos + 4 * picCtr) - 32, READ_LE_UINT16(imgPos + 4 * picCtr + 2) - 20); - vm->_graphicsManager->sDrawPic(newPic, &videoFrame, pt); + vm->_screen->sDrawPic(newPic, &videoFrame, pt); ++picCtr; } } // Decode the next frame and display const Graphics::Surface *frame = decodeNextFrame(); - Common::copy((const byte *)frame->getPixels(), (const byte *)frame->getPixels() + 320 * 200, - (byte *)vm->_graphicsManager->_screenSurface.getPixels()); + vm->_screen->blitFrom(*frame); } vm->_eventsManager->getMouseInfo(); diff --git a/engines/voyeur/data.cpp b/engines/voyeur/data.cpp index b8c987f18b..4d6e32436d 100644 --- a/engines/voyeur/data.cpp +++ b/engines/voyeur/data.cpp @@ -240,10 +240,10 @@ void SVoy::reviewAnEvidEvent(int eventIndex) { int frameOff = e._computerOff; if (_vm->_bVoy->getBoltGroup(_vm->_playStampGroupId)) { - _vm->_graphicsManager->_backColors = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + 1)._cMapResource; - _vm->_graphicsManager->_backgroundPage = _vm->_bVoy->boltEntry(_vm->_playStampGroupId)._picResource; - _vm->_graphicsManager->_vPort->setupViewPort(_vm->_graphicsManager->_backgroundPage); - _vm->_graphicsManager->_backColors->startFade(); + _vm->_screen->_backColors = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + 1)._cMapResource; + _vm->_screen->_backgroundPage = _vm->_bVoy->boltEntry(_vm->_playStampGroupId)._picResource; + _vm->_screen->_vPort->setupViewPort(_vm->_screen->_backgroundPage); + _vm->_screen->_backColors->startFade(); _vm->doEvidDisplay(frameOff, e._dead); _vm->_bVoy->freeBoltGroup(_vm->_playStampGroupId); @@ -262,10 +262,10 @@ void SVoy::reviewComputerEvent(int eventIndex) { _computerTextId = e._computerOn; if (_vm->_bVoy->getBoltGroup(_vm->_playStampGroupId)) { - _vm->_graphicsManager->_backColors = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + 1)._cMapResource; - _vm->_graphicsManager->_backgroundPage = _vm->_bVoy->boltEntry(_vm->_playStampGroupId)._picResource; - _vm->_graphicsManager->_vPort->setupViewPort(_vm->_graphicsManager->_backgroundPage); - _vm->_graphicsManager->_backColors->startFade(); + _vm->_screen->_backColors = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + 1)._cMapResource; + _vm->_screen->_backgroundPage = _vm->_bVoy->boltEntry(_vm->_playStampGroupId)._picResource; + _vm->_screen->_vPort->setupViewPort(_vm->_screen->_backgroundPage); + _vm->_screen->_backColors->startFade(); _vm->flipPageAndWaitForFade(); _vm->getComputerBrush(); diff --git a/engines/voyeur/debugger.cpp b/engines/voyeur/debugger.cpp index e9a12180da..ebfa123eb6 100644 --- a/engines/voyeur/debugger.cpp +++ b/engines/voyeur/debugger.cpp @@ -21,7 +21,7 @@ */ #include "voyeur/debugger.h" -#include "voyeur/graphics.h" +#include "voyeur/screen.h" #include "voyeur/voyeur.h" #include "voyeur/staticres.h" diff --git a/engines/voyeur/events.cpp b/engines/voyeur/events.cpp index 34ef507ad3..020fe4b692 100644 --- a/engines/voyeur/events.cpp +++ b/engines/voyeur/events.cpp @@ -111,18 +111,18 @@ void EventsManager::mainVoyeurIntFunc() { } void EventsManager::sWaitFlip() { - Common::Array<ViewPortResource *> &viewPorts = _vm->_graphicsManager->_viewPortListPtr->_entries; + Common::Array<ViewPortResource *> &viewPorts = _vm->_screen->_viewPortListPtr->_entries; for (uint idx = 0; idx < viewPorts.size(); ++idx) { ViewPortResource &viewPort = *viewPorts[idx]; - if (_vm->_graphicsManager->_saveBack && (viewPort._flags & DISPFLAG_40)) { - Common::Rect *clipPtr = _vm->_graphicsManager->_clipPtr; - _vm->_graphicsManager->_clipPtr = &viewPort._clipRect; + if (_vm->_screen->_saveBack && (viewPort._flags & DISPFLAG_40)) { + Common::Rect *clipPtr = _vm->_screen->_clipPtr; + _vm->_screen->_clipPtr = &viewPort._clipRect; if (viewPort._restoreFn) - (_vm->_graphicsManager->*viewPort._restoreFn)(&viewPort); + (_vm->_screen->*viewPort._restoreFn)(&viewPort); - _vm->_graphicsManager->_clipPtr = clipPtr; + _vm->_screen->_clipPtr = clipPtr; viewPort._rectListCount[viewPort._pageIndex] = 0; viewPort._rectListPtr[viewPort._pageIndex]->clear(); viewPort._flags &= ~DISPFLAG_40; @@ -158,9 +158,7 @@ void EventsManager::checkForNextFrameCounter() { showMousePosition(); // Display the frame - g_system->copyRectToScreen((byte *)_vm->_graphicsManager->_screenSurface.getPixels(), - SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); - g_system->updateScreen(); + _vm->_screen->update(); // Signal the ScummVM debugger _vm->_debugger->onFrame(); @@ -178,10 +176,8 @@ void EventsManager::showMousePosition() { mousePos += Common::String::format(" - (%d,%d)", pt.x, pt.y); } - _vm->_graphicsManager->_screenSurface.fillRect( - Common::Rect(0, 0, 110, font.getFontHeight()), 0); - font.drawString(&_vm->_graphicsManager->_screenSurface, mousePos, - 0, 0, 110, 63); + _vm->_screen->fillRect(Common::Rect(0, 0, 110, font.getFontHeight()), 0); + font.drawString(_vm->_screen, mousePos, 0, 0, 110, 63); } void EventsManager::voyeurTimer() { @@ -299,11 +295,11 @@ void EventsManager::startFade(CMapResource *cMap) { if (cMap->_steps > 0) { _fadeStatus = cMap->_fadeStatus | 1; - byte *vgaP = &_vm->_graphicsManager->_VGAColors[_fadeFirstCol * 3]; + byte *vgaP = &_vm->_screen->_VGAColors[_fadeFirstCol * 3]; int mapIndex = 0; for (int idx = _fadeFirstCol; idx <= _fadeLastCol; ++idx, vgaP += 3) { - ViewPortPalEntry &palEntry = _vm->_graphicsManager->_viewPortListPtr->_palette[idx]; + ViewPortPalEntry &palEntry = _vm->_screen->_viewPortListPtr->_palette[idx]; palEntry._rEntry = vgaP[0] << 8; int rDiff = (cMap->_entries[mapIndex * 3] << 8) - palEntry._rEntry; palEntry._rChange = rDiff / cMap->_steps; @@ -325,7 +321,7 @@ void EventsManager::startFade(CMapResource *cMap) { _intPtr._skipFading = true; _fadeIntNode._flags &= ~1; } else { - byte *vgaP = &_vm->_graphicsManager->_VGAColors[_fadeFirstCol * 3]; + byte *vgaP = &_vm->_screen->_VGAColors[_fadeFirstCol * 3]; int mapIndex = 0; for (int idx = _fadeFirstCol; idx <= _fadeLastCol; ++idx, vgaP += 3) { @@ -371,8 +367,8 @@ void EventsManager::vDoFadeInt() { } for (int i = _fadeFirstCol; i <= _fadeLastCol; ++i) { - ViewPortPalEntry &palEntry = _vm->_graphicsManager->_viewPortListPtr->_palette[i]; - byte *vgaP = &_vm->_graphicsManager->_VGAColors[palEntry._palIndex * 3]; + ViewPortPalEntry &palEntry = _vm->_screen->_viewPortListPtr->_palette[i]; + byte *vgaP = &_vm->_screen->_VGAColors[palEntry._palIndex * 3]; palEntry._rEntry += palEntry._rChange; palEntry._gEntry += palEntry._gChange; @@ -395,7 +391,7 @@ void EventsManager::vDoCycleInt() { for (int idx = 3; idx >= 0; --idx) { if (_cyclePtr->_type[idx] && --_cycleTime[idx] <= 0) { byte *pSrc = _cycleNext[idx]; - byte *pPal = _vm->_graphicsManager->_VGAColors; + byte *pPal = _vm->_screen->_VGAColors; if (_cyclePtr->_type[idx] != 1) { // New palette data being specified - loop to set entries @@ -521,7 +517,7 @@ void EventsManager::setCursor(PictureResource *pic) { cursor._bounds = pic->_bounds; cursor._flags = DISPFLAG_CURSOR; - _vm->_graphicsManager->sDrawPic(pic, &cursor, Common::Point()); + _vm->_screen->sDrawPic(pic, &cursor, Common::Point()); } void EventsManager::setCursor(byte *cursorData, int width, int height, int keyColor) { @@ -531,16 +527,16 @@ void EventsManager::setCursor(byte *cursorData, int width, int height, int keyCo void EventsManager::setCursorColor(int idx, int mode) { switch (mode) { case 0: - _vm->_graphicsManager->setColor(idx, 90, 90, 232); + _vm->_screen->setColor(idx, 90, 90, 232); break; case 1: - _vm->_graphicsManager->setColor(idx, 232, 90, 90); + _vm->_screen->setColor(idx, 232, 90, 90); break; case 2: - _vm->_graphicsManager->setColor(idx, 90, 232, 90); + _vm->_screen->setColor(idx, 90, 232, 90); break; case 3: - _vm->_graphicsManager->setColor(idx, 90, 232, 232); + _vm->_screen->setColor(idx, 90, 232, 232); break; default: break; @@ -564,12 +560,12 @@ void EventsManager::getMouseInfo() { if (_cursorBlinked) { _cursorBlinked = false; - _vm->_graphicsManager->setOneColor(128, 220, 20, 20); - _vm->_graphicsManager->setColor(128, 220, 20, 20); + _vm->_screen->setOneColor(128, 220, 20, 20); + _vm->_screen->setColor(128, 220, 20, 20); } else { _cursorBlinked = true; - _vm->_graphicsManager->setOneColor(128, 220, 220, 220); - _vm->_graphicsManager->setColor(128, 220, 220, 220); + _vm->_screen->setOneColor(128, 220, 220, 220); + _vm->_screen->setColor(128, 220, 220, 220); } } } @@ -585,11 +581,11 @@ void EventsManager::getMouseInfo() { void EventsManager::startCursorBlink() { if (_vm->_voy->_eventFlags & EVTFLAG_RECORDING) { - _vm->_graphicsManager->setOneColor(128, 55, 5, 5); - _vm->_graphicsManager->setColor(128, 220, 20, 20); + _vm->_screen->setOneColor(128, 55, 5, 5); + _vm->_screen->setColor(128, 220, 20, 20); _intPtr._hasPalette = true; - _vm->_graphicsManager->drawDot(); + _vm->_screen->drawDot(); //copySection(); } } diff --git a/engines/voyeur/files.cpp b/engines/voyeur/files.cpp index 300e086f75..46b195ecaf 100644 --- a/engines/voyeur/files.cpp +++ b/engines/voyeur/files.cpp @@ -21,7 +21,7 @@ */ #include "voyeur/files.h" -#include "voyeur/graphics.h" +#include "voyeur/screen.h" #include "voyeur/voyeur.h" #include "voyeur/staticres.h" @@ -359,7 +359,7 @@ void BoltFile::resolveIt(uint32 id, byte **p) { } } -void BoltFile::resolveFunction(uint32 id, GraphicMethodPtr *fn) { +void BoltFile::resolveFunction(uint32 id, ScreenMethodPtr *fn) { if ((int32)id == -1) *fn = NULL; else @@ -485,8 +485,8 @@ void BVoyBoltFile::initViewPortList() { _state._curMemberPtr->_viewPortListResource = res = new ViewPortListResource( _state, _state._curMemberPtr->_data); - _state._vm->_graphicsManager->_viewPortListPtr = res; - _state._vm->_graphicsManager->_vPort = res->_entries[0]; + _state._vm->_screen->_viewPortListPtr = res; + _state._vm->_screen->_vPort = res->_entries[0]; } void BVoyBoltFile::initFontInfo() { @@ -752,24 +752,24 @@ DisplayResource::DisplayResource(VoyeurEngine *vm) { void DisplayResource::sFillBox(int width, int height) { assert(_vm); - bool saveBack = _vm->_graphicsManager->_saveBack; - _vm->_graphicsManager->_saveBack = false; + bool saveBack = _vm->_screen->_saveBack; + _vm->_screen->_saveBack = false; PictureResource pr; pr._flags = DISPFLAG_1; pr._select = 0xff; pr._pick = 0; - pr._onOff = _vm->_graphicsManager->_drawPtr->_penColor; + pr._onOff = _vm->_screen->_drawPtr->_penColor; pr._bounds = Common::Rect(0, 0, width, height); - _vm->_graphicsManager->sDrawPic(&pr, this, _vm->_graphicsManager->_drawPtr->_pos); - _vm->_graphicsManager->_saveBack = saveBack; + _vm->_screen->sDrawPic(&pr, this, _vm->_screen->_drawPtr->_pos); + _vm->_screen->_saveBack = saveBack; } bool DisplayResource::clipRect(Common::Rect &rect) { Common::Rect clippingRect; - if (_vm->_graphicsManager->_clipPtr) { - clippingRect = *_vm->_graphicsManager->_clipPtr; + if (_vm->_screen->_clipPtr) { + clippingRect = *_vm->_screen->_clipPtr; } else if (_flags & DISPFLAG_VIEWPORT) { clippingRect = ((ViewPortResource *)this)->_clipRect; } else { @@ -804,18 +804,18 @@ bool DisplayResource::clipRect(Common::Rect &rect) { } int DisplayResource::drawText(const Common::String &msg) { - GraphicsManager &gfxManager = *_vm->_graphicsManager; - assert(gfxManager._fontPtr); - assert(gfxManager._fontPtr->_curFont); - FontInfoResource &fontInfo = *gfxManager._fontPtr; - PictureResource &fontChar = *_vm->_graphicsManager->_fontChar; + Screen &screen = *_vm->_screen; + assert(screen._fontPtr); + assert(screen._fontPtr->_curFont); + FontInfoResource &fontInfo = *screen._fontPtr; + PictureResource &fontChar = *_vm->_screen->_fontChar; FontResource &fontData = *fontInfo._curFont; int xShadows[9] = { 0, 1, 1, 1, 0, -1, -1, -1, 0 }; int yShadows[9] = { 0, 1, 0, -1, -1, -1, 0, 1, 1 }; - Common::Rect *clipPtr = gfxManager._clipPtr; + Common::Rect *clipPtr = screen._clipPtr; if (!(fontInfo._picFlags & DISPFLAG_1)) - gfxManager._clipPtr = NULL; + screen._clipPtr = NULL; int minChar = fontData._minChar; int padding = fontData._padding; @@ -834,7 +834,7 @@ int DisplayResource::drawText(const Common::String &msg) { (ViewPortResource *)this; if ((fontInfo._fontFlags & DISPFLAG_1) || fontInfo._justify || - (gfxManager._saveBack && fontInfo._fontSaveBack && (_flags & DISPFLAG_VIEWPORT))) { + (screen._saveBack && fontInfo._fontSaveBack && (_flags & DISPFLAG_VIEWPORT))) { msgWidth = viewPort->textWidth(msg); yp = pos.y; xp = pos.x; @@ -898,18 +898,18 @@ int DisplayResource::drawText(const Common::String &msg) { } } - if (gfxManager._saveBack && fontInfo._fontSaveBack && (_flags & DISPFLAG_VIEWPORT)) { + if (screen._saveBack && fontInfo._fontSaveBack && (_flags & DISPFLAG_VIEWPORT)) { viewPort->addSaveRect(viewPort->_pageIndex, viewPort->_fontRect); } if (fontInfo._fontFlags & DISPFLAG_1) { - gfxManager._drawPtr->_pos = Common::Point(viewPort->_fontRect.left, viewPort->_fontRect.top); - gfxManager._drawPtr->_penColor = fontInfo._backColor; + screen._drawPtr->_pos = Common::Point(viewPort->_fontRect.left, viewPort->_fontRect.top); + screen._drawPtr->_penColor = fontInfo._backColor; sFillBox(viewPort->_fontRect.width(), viewPort->_fontRect.height()); } - bool saveBack = gfxManager._saveBack; - gfxManager._saveBack = false; + bool saveBack = screen._saveBack; + screen._saveBack = false; int count = 0; if (fontInfo._fontFlags & DISPFLAG_4) @@ -970,7 +970,7 @@ int DisplayResource::drawText(const Common::String &msg) { uint16 offset = READ_LE_UINT16(fontData._charOffsets + charValue * 2); fontChar._imgData = fontData._charImages + offset * 2; - gfxManager.sDrawPic(&fontChar, this, Common::Point(xp, yp)); + screen.sDrawPic(&fontChar, this, Common::Point(xp, yp)); fontChar._imgData = NULL; xp += charWidth + padding; @@ -982,8 +982,8 @@ int DisplayResource::drawText(const Common::String &msg) { if (fontInfo._justify == ALIGN_LEFT) fontInfo._pos.x = xp; - gfxManager._saveBack = saveBack; - gfxManager._clipPtr = clipPtr; + screen._saveBack = saveBack; + screen._clipPtr = clipPtr; return msgWidth; } @@ -993,7 +993,7 @@ int DisplayResource::textWidth(const Common::String &msg) { return 0; const char *msgP = msg.c_str(); - FontResource &fontData = *_vm->_graphicsManager->_fontPtr->_curFont; + FontResource &fontData = *_vm->_screen->_fontPtr->_curFont; int minChar = fontData._minChar; int maxChar = fontData._maxChar; int padding = fontData._padding; @@ -1085,9 +1085,9 @@ PictureResource::PictureResource(BoltFilesState &state, const byte *src): mode = 226; } - if (mode != state._vm->_graphicsManager->_SVGAMode) { - state._vm->_graphicsManager->_SVGAMode = mode; - state._vm->_graphicsManager->clearPalette(); + if (mode != state._vm->_screen->_SVGAMode) { + state._vm->_screen->_SVGAMode = mode; + state._vm->_screen->clearPalette(); } int screenOffset = READ_LE_UINT32(&src[18]) & 0xffff; @@ -1096,13 +1096,14 @@ PictureResource::PictureResource(BoltFilesState &state, const byte *src): if (_flags & PICFLAG_CLEAR_SCREEN) { // Clear screen picture. That's right. This game actually has a picture // resource flag to clear the screen! Bizarre. - Graphics::Surface &s = state._vm->_graphicsManager->_screenSurface; - s.fillRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), 0); + state._vm->_screen->clear(); } else { // Direct screen loading picture. In this case, the raw data of the resource // is directly decompressed into the screen surface. Again, bizarre. - byte *pDest = (byte *)state._vm->_graphicsManager->_screenSurface.getPixels(); + Screen &screen = *state._vm->_screen; + byte *pDest = (byte *)screen.getPixels(); state.decompress(pDest, SCREEN_WIDTH * SCREEN_HEIGHT, state._curMemberPtr->_mode); + screen.markAllDirty(); } } else { if (_flags & PICFLAG_CLEAR_SCREEN00) { @@ -1249,13 +1250,13 @@ ViewPortResource::ViewPortResource(BoltFilesState &state, const byte *src): ys + READ_LE_UINT16(src + 0x4C)); state._curLibPtr->resolveIt(READ_LE_UINT32(src + 0x7A), &dummy); - state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x7E), (GraphicMethodPtr *)&_fn1); - state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x82), (GraphicMethodPtr *)&_setupFn); - state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x86), (GraphicMethodPtr *)&_addFn); - state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x8A), (GraphicMethodPtr *)&_restoreFn); + state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x7E), (ScreenMethodPtr *)&_fn1); + state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x82), (ScreenMethodPtr *)&_setupFn); + state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x86), (ScreenMethodPtr *)&_addFn); + state._curLibPtr->resolveFunction(READ_LE_UINT32(src + 0x8A), (ScreenMethodPtr *)&_restoreFn); if (!_restoreFn && _addFn) - _addFn = &GraphicsManager::addRectNoSaveBack; + _addFn = &Screen::addRectNoSaveBack; } ViewPortResource::~ViewPortResource() { @@ -1327,19 +1328,19 @@ void ViewPortResource::setupViewPort(PictureResource *page, Common::Rect *clippi _restoreFn = restoreFn; if (setupFn) - (_state._vm->_graphicsManager->*setupFn)(this); + (_state._vm->_screen->*setupFn)(this); } void ViewPortResource::setupViewPort() { - setupViewPort(_state._vm->_graphicsManager->_backgroundPage, NULL, - &GraphicsManager::setupMCGASaveRect, &GraphicsManager::addRectOptSaveRect, - &GraphicsManager::restoreMCGASaveRect); + setupViewPort(_state._vm->_screen->_backgroundPage, NULL, + &Screen::setupMCGASaveRect, &Screen::addRectOptSaveRect, + &Screen::restoreMCGASaveRect); } void ViewPortResource::setupViewPort(PictureResource *pic, Common::Rect *clippingRect) { setupViewPort(pic, clippingRect, - &GraphicsManager::setupMCGASaveRect, &GraphicsManager::addRectOptSaveRect, - &GraphicsManager::restoreMCGASaveRect); + &Screen::setupMCGASaveRect, &Screen::addRectOptSaveRect, + &Screen::restoreMCGASaveRect); } void ViewPortResource::addSaveRect(int pageIndex, const Common::Rect &r) { @@ -1347,7 +1348,7 @@ void ViewPortResource::addSaveRect(int pageIndex, const Common::Rect &r) { if (clipRect(rect)) { if (_addFn) { - (_state._vm->_graphicsManager->*_addFn)(this, pageIndex, rect); + (_state._vm->_screen->*_addFn)(this, pageIndex, rect); } else if (_rectListCount[pageIndex] != -1) { _rectListPtr[pageIndex]->push_back(rect); } @@ -1355,26 +1356,26 @@ void ViewPortResource::addSaveRect(int pageIndex, const Common::Rect &r) { } void ViewPortResource::fillPic(byte onOff) { - _state._vm->_graphicsManager->fillPic(this, onOff); + _state._vm->_screen->fillPic(this, onOff); } void ViewPortResource::drawIfaceTime() { // Hour display - _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort, + _state._vm->_screen->drawANumber(_state._vm->_screen->_vPort, (_state._vm->_gameHour / 10) == 0 ? 10 : _state._vm->_gameHour / 10, Common::Point(161, 25)); - _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort, + _state._vm->_screen->drawANumber(_state._vm->_screen->_vPort, _state._vm->_gameHour % 10, Common::Point(172, 25)); // Minute display - _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort, + _state._vm->_screen->drawANumber(_state._vm->_screen->_vPort, _state._vm->_gameMinute / 10, Common::Point(190, 25)); - _state._vm->_graphicsManager->drawANumber(_state._vm->_graphicsManager->_vPort, + _state._vm->_screen->drawANumber(_state._vm->_screen->_vPort, _state._vm->_gameMinute % 10, Common::Point(201, 25)); // AM/PM indicator PictureResource *pic = _state._vm->_bVoy->boltEntry(_state._vm->_voy->_isAM ? 272 : 273)._picResource; - _state._vm->_graphicsManager->sDrawPic(pic, _state._vm->_graphicsManager->_vPort, + _state._vm->_screen->sDrawPic(pic, _state._vm->_screen->_vPort, Common::Point(215, 27)); } @@ -1382,9 +1383,9 @@ void ViewPortResource::drawPicPerm(PictureResource *pic, const Common::Point &pt Common::Rect bounds = pic->_bounds; bounds.translate(pt.x, pt.y); - bool saveBack = _state._vm->_graphicsManager->_saveBack; - _state._vm->_graphicsManager->_saveBack = false; - _state._vm->_graphicsManager->sDrawPic(pic, this, pt); + bool saveBack = _state._vm->_screen->_saveBack; + _state._vm->_screen->_saveBack = false; + _state._vm->_screen->sDrawPic(pic, this, pt); clipRect(bounds); for (int pageIndex = 0; pageIndex < _pageCount; ++pageIndex) { @@ -1393,7 +1394,7 @@ void ViewPortResource::drawPicPerm(PictureResource *pic, const Common::Point &pt } } - _state._vm->_graphicsManager->_saveBack = saveBack; + _state._vm->_screen->_saveBack = saveBack; } /*------------------------------------------------------------------------*/ @@ -1526,7 +1527,7 @@ CMapResource::CMapResource(BoltFilesState &state, const byte *src): _vm(state._v _entries = new byte[count * 3]; Common::copy(src + 6, src + 6 + 3 * count, _entries); - int palIndex = state._vm->_graphicsManager->_viewPortListPtr->_palIndex; + int palIndex = state._vm->_screen->_viewPortListPtr->_palIndex; if (_end > palIndex) _end = palIndex; if (_start > palIndex) diff --git a/engines/voyeur/files.h b/engines/voyeur/files.h index eef5df497c..8726b38ddf 100644 --- a/engines/voyeur/files.h +++ b/engines/voyeur/files.h @@ -27,7 +27,7 @@ #include "common/file.h" #include "common/rect.h" #include "common/str.h" -#include "voyeur/graphics.h" +#include "voyeur/screen.h" namespace Voyeur { @@ -112,7 +112,7 @@ public: byte *memberAddr(uint32 id); byte *memberAddrOffset(uint32 id); void resolveIt(uint32 id, byte **p); - void resolveFunction(uint32 id, GraphicMethodPtr *fn); + void resolveFunction(uint32 id, ScreenMethodPtr *fn); BoltEntry &boltEntry(uint16 id); BoltEntry &getBoltEntryFromLong(uint32 id); @@ -340,7 +340,7 @@ public: int _rectListCount[3]; Common::Rect _clipRect; - GraphicMethodPtr _fn1; + ScreenMethodPtr _fn1; ViewPortSetupPtr _setupFn; ViewPortAddPtr _addFn; ViewPortRestorePtr _restoreFn; diff --git a/engines/voyeur/files_threads.cpp b/engines/voyeur/files_threads.cpp index 9908324043..bbd3dfe4e9 100644 --- a/engines/voyeur/files_threads.cpp +++ b/engines/voyeur/files_threads.cpp @@ -21,7 +21,7 @@ */ #include "voyeur/files.h" -#include "voyeur/graphics.h" +#include "voyeur/screen.h" #include "voyeur/voyeur.h" #include "voyeur/staticres.h" @@ -461,7 +461,7 @@ void ThreadResource::parsePlayCommands() { pic = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + i * 2)._picResource; pal = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + i * 2 + 1)._cMapResource; - _vm->_graphicsManager->_vPort->setupViewPort(pic); + _vm->_screen->_vPort->setupViewPort(pic); pal->startFade(); _vm->flipPageAndWaitForFade(); @@ -980,10 +980,10 @@ int ThreadResource::doApt() { _vm->_soundManager->startVOCPlay(_vm->_soundManager->getVOCFileName(_vm->_currentVocId)); _vm->_currentVocId = 151; - _vm->_graphicsManager->setColor(129, 82, 82, 82); - _vm->_graphicsManager->setColor(130, 112, 112, 112); - _vm->_graphicsManager->setColor(131, 215, 215, 215); - _vm->_graphicsManager->setColor(132, 235, 235, 235); + _vm->_screen->setColor(129, 82, 82, 82); + _vm->_screen->setColor(130, 112, 112, 112); + _vm->_screen->setColor(131, 215, 215, 215); + _vm->_screen->setColor(132, 235, 235, 235); _vm->_eventsManager->_intPtr._hasPalette = true; @@ -1044,7 +1044,7 @@ int ThreadResource::doApt() { // Draw the text description for the highlighted hotspot pic = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + hotspotId + 6)._picResource; - _vm->_graphicsManager->sDrawPic(pic, _vm->_graphicsManager->_vPort, + _vm->_screen->sDrawPic(pic, _vm->_screen->_vPort, Common::Point(106, 200)); } @@ -1112,10 +1112,10 @@ void ThreadResource::doRoom() { if (!vm._bVoy->getBoltGroup(vm._playStampGroupId)) return; - vm._graphicsManager->_backColors = vm._bVoy->boltEntry(vm._playStampGroupId + 1)._cMapResource; - vm._graphicsManager->_backgroundPage = vm._bVoy->boltEntry(vm._playStampGroupId)._picResource; - vm._graphicsManager->_vPort->setupViewPort(vm._graphicsManager->_backgroundPage); - vm._graphicsManager->_backColors->startFade(); + vm._screen->_backColors = vm._bVoy->boltEntry(vm._playStampGroupId + 1)._cMapResource; + vm._screen->_backgroundPage = vm._bVoy->boltEntry(vm._playStampGroupId)._picResource; + vm._screen->_vPort->setupViewPort(vm._screen->_backgroundPage); + vm._screen->_backColors->startFade(); voy._fadingStep1 = 2; voy._fadingStep2 = 0; @@ -1144,7 +1144,7 @@ void ThreadResource::doRoom() { bool breakFlag = false; while (!vm.shouldQuit() && !breakFlag) { _vm->_voyeurArea = AREA_ROOM; - vm._graphicsManager->setColor(128, 0, 255, 0); + vm._screen->setColor(128, 0, 255, 0); vm._eventsManager->_intPtr._hasPalette = true; do { @@ -1186,7 +1186,7 @@ void ThreadResource::doRoom() { } vm._eventsManager->_intPtr._hasPalette = true; - vm._graphicsManager->flipPage(); + vm._screen->flipPage(); vm._eventsManager->sWaitFlip(); } while (!vm.shouldQuit() && !vm._eventsManager->_mouseClicked); @@ -1234,13 +1234,13 @@ void ThreadResource::doRoom() { // WORKAROUND: Skipped code from the original, that freed the group, // reloaded it, and reloaded the cursors - vm._graphicsManager->_backColors = vm._bVoy->boltEntry( + vm._screen->_backColors = vm._bVoy->boltEntry( vm._playStampGroupId + 1)._cMapResource; - vm._graphicsManager->_backgroundPage = vm._bVoy->boltEntry( + vm._screen->_backgroundPage = vm._bVoy->boltEntry( vm._playStampGroupId)._picResource; - vm._graphicsManager->_vPort->setupViewPort(); - vm._graphicsManager->_backColors->startFade(); + vm._screen->_vPort->setupViewPort(); + vm._screen->_backColors->startFade(); _vm->flipPageAndWait(); while (!vm.shouldQuit() && (vm._eventsManager->_fadeStatus & 1)) @@ -1265,7 +1265,7 @@ void ThreadResource::doRoom() { _vm->flipPageAndWait(); - vm._graphicsManager->fadeUpICF1(); + vm._screen->fadeUpICF1(); voy._eventFlags &= EVTFLAG_RECORDING; vm._eventsManager->showCursor(); } @@ -1350,7 +1350,7 @@ int ThreadResource::doInterface() { _vm->_soundManager->startVOCPlay(fname); _vm->_eventsManager->getMouseInfo(); - _vm->_graphicsManager->setColor(240, 220, 220, 220); + _vm->_screen->setColor(240, 220, 220, 220); _vm->_eventsManager->_intPtr._hasPalette = true; _vm->_voy->_eventFlags &= ~EVTFLAG_TIME_DISABLED; @@ -1424,20 +1424,20 @@ int ThreadResource::doInterface() { // Regularly update the time display if (_vm->_voy->_RTANum & 2) { - _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort, + _vm->_screen->drawANumber(_vm->_screen->_vPort, _vm->_gameMinute / 10, Common::Point(190, 25)); - _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort, + _vm->_screen->drawANumber(_vm->_screen->_vPort, _vm->_gameMinute % 10, Common::Point(201, 25)); if (_vm->_voy->_RTANum & 4) { int v = _vm->_gameHour / 10; - _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort, + _vm->_screen->drawANumber(_vm->_screen->_vPort, v == 0 ? 10 : v, Common::Point(161, 25)); - _vm->_graphicsManager->drawANumber(_vm->_graphicsManager->_vPort, + _vm->_screen->drawANumber(_vm->_screen->_vPort, _vm->_gameHour % 10, Common::Point(172, 25)); pic = _vm->_bVoy->boltEntry(_vm->_voy->_isAM ? 272 : 273)._picResource; - _vm->_graphicsManager->sDrawPic(pic, _vm->_graphicsManager->_vPort, + _vm->_screen->sDrawPic(pic, _vm->_screen->_vPort, Common::Point(215, 27)); } } @@ -1605,16 +1605,16 @@ void ThreadResource::loadTheApt() { _vm->_bVoy->getBoltGroup(_vm->_playStampGroupId); _vm->_voy->_aptLoadMode = -1; - _vm->_graphicsManager->_backgroundPage = _vm->_bVoy->boltEntry( + _vm->_screen->_backgroundPage = _vm->_bVoy->boltEntry( _vm->_playStampGroupId + 5)._picResource; - _vm->_graphicsManager->_vPort->setupViewPort( - _vm->_graphicsManager->_backgroundPage); + _vm->_screen->_vPort->setupViewPort( + _vm->_screen->_backgroundPage); } else { _vm->_bVoy->getBoltGroup(_vm->_playStampGroupId); - _vm->_graphicsManager->_backgroundPage = _vm->_bVoy->boltEntry( + _vm->_screen->_backgroundPage = _vm->_bVoy->boltEntry( _vm->_playStampGroupId + 5)._picResource; - _vm->_graphicsManager->_vPort->setupViewPort( - _vm->_graphicsManager->_backgroundPage); + _vm->_screen->_vPort->setupViewPort( + _vm->_screen->_backgroundPage); } CMapResource *pal = _vm->_bVoy->boltEntry(_vm->_playStampGroupId + 4)._cMapResource; @@ -1624,10 +1624,10 @@ void ThreadResource::loadTheApt() { } void ThreadResource::freeTheApt() { - _vm->_graphicsManager->fadeDownICF1(5); + _vm->_screen->fadeDownICF1(5); _vm->flipPageAndWaitForFade(); - _vm->_graphicsManager->fadeUpICF1(); + _vm->_screen->fadeUpICF1(); if (_vm->_currentVocId != -1) { _vm->_soundManager->stopVOCPlay(); @@ -1635,17 +1635,17 @@ void ThreadResource::freeTheApt() { } if (_vm->_voy->_aptLoadMode == -1) { - _vm->_graphicsManager->fadeDownICF(6); + _vm->_screen->fadeDownICF(6); } else { doAptAnim(2); } if (_vm->_voy->_aptLoadMode == 140) { - _vm->_graphicsManager->screenReset(); - _vm->_graphicsManager->resetPalette(); + _vm->_screen->screenReset(); + _vm->_screen->resetPalette(); } - _vm->_graphicsManager->_vPort->setupViewPort(nullptr); + _vm->_screen->_vPort->setupViewPort(nullptr); _vm->_bVoy->freeBoltGroup(_vm->_playStampGroupId); _vm->_playStampGroupId = -1; _vm->_voy->_viewBounds = nullptr; @@ -1705,7 +1705,7 @@ void ThreadResource::doAptAnim(int mode) { for (int idx = 0; (idx < 6) && !_vm->shouldQuit(); ++idx) { PictureResource *pic = _vm->_bVoy->boltEntry(id + idx + 1)._picResource; - _vm->_graphicsManager->_vPort->setupViewPort(pic); + _vm->_screen->_vPort->setupViewPort(pic); pal->startFade(); _vm->flipPageAndWait(); diff --git a/engines/voyeur/module.mk b/engines/voyeur/module.mk index aab254cf36..a38bdd9ab2 100644 --- a/engines/voyeur/module.mk +++ b/engines/voyeur/module.mk @@ -8,7 +8,7 @@ MODULE_OBJS := \ events.o \ files.o \ files_threads.o \ - graphics.o \ + screen.o \ sound.o \ staticres.o \ voyeur.o \ diff --git a/engines/voyeur/graphics.cpp b/engines/voyeur/screen.cpp index a20e9f6006..62f609c5c7 100644 --- a/engines/voyeur/graphics.cpp +++ b/engines/voyeur/screen.cpp @@ -20,7 +20,7 @@ * */ -#include "voyeur/graphics.h" +#include "voyeur/screen.h" #include "voyeur/voyeur.h" #include "voyeur/staticres.h" #include "engines/util.h" @@ -38,7 +38,8 @@ DrawInfo::DrawInfo(int penColor, const Common::Point &pos) { /*------------------------------------------------------------------------*/ -GraphicsManager::GraphicsManager(VoyeurEngine *vm) : _defaultDrawInfo(1, Common::Point()), _drawPtr(&_defaultDrawInfo), _vm(vm) { +Screen::Screen(VoyeurEngine *vm) : Graphics::Screen(), _vm(vm), _drawPtr(&_defaultDrawInfo), + _defaultDrawInfo(1, Common::Point()) { _SVGAMode = 0; _planeSelect = 0; _saveBack = true; @@ -52,18 +53,17 @@ GraphicsManager::GraphicsManager(VoyeurEngine *vm) : _defaultDrawInfo(1, Common: _backColors = nullptr; } -void GraphicsManager::sInitGraphics() { +void Screen::sInitGraphics() { initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, false); - _screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8()); + create(SCREEN_WIDTH, SCREEN_HEIGHT); clearPalette(); } -GraphicsManager::~GraphicsManager() { - _screenSurface.free(); +Screen::~Screen() { delete _fontChar; } -void GraphicsManager::setupMCGASaveRect(ViewPortResource *viewPort) { +void Screen::setupMCGASaveRect(ViewPortResource *viewPort) { if (viewPort->_activePage) { viewPort->_activePage->_flags |= DISPFLAG_1; Common::Rect *clipRect = _clipPtr; @@ -77,7 +77,7 @@ void GraphicsManager::setupMCGASaveRect(ViewPortResource *viewPort) { viewPort->_rectListCount[1] = -1; } -void GraphicsManager::addRectOptSaveRect(ViewPortResource *viewPort, int idx, const Common::Rect &bounds) { +void Screen::addRectOptSaveRect(ViewPortResource *viewPort, int idx, const Common::Rect &bounds) { if (viewPort->_rectListCount[idx] == -1) return; @@ -86,7 +86,7 @@ void GraphicsManager::addRectOptSaveRect(ViewPortResource *viewPort, int idx, co ++viewPort->_rectListCount[idx]; } -void GraphicsManager::restoreMCGASaveRect(ViewPortResource *viewPort) { +void Screen::restoreMCGASaveRect(ViewPortResource *viewPort) { if (viewPort->_rectListCount[0] != -1) { for (int i = 0; i < viewPort->_rectListCount[0]; ++i) { addRectOptSaveRect(viewPort, 1, (*viewPort->_rectListPtr[0])[i]); @@ -106,11 +106,11 @@ void GraphicsManager::restoreMCGASaveRect(ViewPortResource *viewPort) { viewPort->_rectListCount[1] = count; } -void GraphicsManager::addRectNoSaveBack(ViewPortResource *viewPort, int idx, const Common::Rect &bounds) { +void Screen::addRectNoSaveBack(ViewPortResource *viewPort, int idx, const Common::Rect &bounds) { // Stubbed/dummy method in the original. } -void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *destDisplay, +void Screen::sDrawPic(DisplayResource *srcDisplay, DisplayResource *destDisplay, const Common::Point &initialOffset) { int width1, width2; int widthDiff, widthDiff2; @@ -128,7 +128,8 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des int runLength; byte *srcImgData, *destImgData; - byte *srcP, *destP; + const byte *srcP; + byte *destP; byte byteVal, byteVal2; PictureResource *srcPic; @@ -292,7 +293,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des // loc_2566F if (srcFlags & DISPFLAG_2) { // loc_256FA - srcP = (byte *)_screenSurface.getPixels() + srcOffset; + srcP = (const byte *)getPixels() + srcOffset; for (int yp = 0; yp < height1; ++yp) { for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) { @@ -325,13 +326,16 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des } } else { // loc_25829 - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { Common::copy(srcP, srcP + width2, destP); srcP += width2 + widthDiff; destP += width2 + widthDiff2; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } } } else { @@ -341,13 +345,16 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des error("TODO: sDrawPic variation"); } else { // loc_2606D - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { Common::copy(srcP, srcP + width2, destP); destP += width2 + widthDiff2; srcP += width2 + widthDiff; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } } } else { @@ -530,11 +537,14 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des // loc_27477 if (destFlags & DISPFLAG_8) { // loc_27481 - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { Common::fill(destP, destP + width2, onOff); destP += width2 + widthDiff2; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } else { // loc_2753C destP = destImgData + screenOffset; @@ -561,7 +571,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des if (srcFlags & PICFLAG_100) { if (isClipped) { // loc_266E3 - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0; int xMax = tmpWidth + width2; tmpHeight = (tmpHeight < 0) ? -tmpHeight : 0; @@ -592,9 +602,12 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des if (yp >= tmpHeight) destP += widthDiff2; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } else { // loc_26815 - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { for (int xi = 0; xi < width2; ++xi, ++destP) { @@ -618,10 +631,13 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des destP += widthDiff2; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } } else { // Direct screen write - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) { @@ -631,6 +647,9 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des destP += widthDiff2; srcP += widthDiff; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } } else if (srcFlags & PICFLAG_100) { srcP = srcImgData; @@ -663,7 +682,7 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des } } else { // loc_26BD5 - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { byteVal2 = 0; @@ -684,10 +703,13 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des destP += widthDiff2; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } } else { // loc_26C9A - destP = (byte *)_screenSurface.getPixels() + screenOffset; + destP = (byte *)getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) { @@ -696,6 +718,9 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des destP += widthDiff2; srcP += widthDiff; } + + addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2, + offset.y + height1)); } } else { // loc_26D2F @@ -850,12 +875,12 @@ void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *des } } -void GraphicsManager::drawANumber(DisplayResource *display, int num, const Common::Point &pt) { +void Screen::drawANumber(DisplayResource *display, int num, const Common::Point &pt) { PictureResource *pic = _vm->_bVoy->boltEntry(num + 261)._picResource; sDrawPic(pic, display, pt); } -void GraphicsManager::fillPic(DisplayResource *display, byte onOff) { +void Screen::fillPic(DisplayResource *display, byte onOff) { PictureResource *pic; if (display->_flags & DISPFLAG_VIEWPORT) { pic = ((ViewPortResource *)display)->_currentPic; @@ -876,11 +901,11 @@ void GraphicsManager::fillPic(DisplayResource *display, byte onOff) { /** * Queues the given picture for display */ -void GraphicsManager::sDisplayPic(PictureResource *pic) { +void Screen::sDisplayPic(PictureResource *pic) { _vm->_eventsManager->_intPtr._flipWait = true; } -void GraphicsManager::flipPage() { +void Screen::flipPage() { Common::Array<ViewPortResource *> &viewPorts = _viewPortListPtr->_entries; bool flipFlag = false; @@ -907,7 +932,7 @@ void GraphicsManager::flipPage() { } } -void GraphicsManager::restoreBack(Common::Array<Common::Rect> &rectList, int rectListCount, +void Screen::restoreBack(Common::Array<Common::Rect> &rectList, int rectListCount, PictureResource *srcPic, PictureResource *destPic) { // WORKAROUND: Since _backgroundPage can point to a resource freed at the end of display methods, // I'm now explicitly resetting it to null in screenReset(), so at this point it can be null @@ -929,33 +954,26 @@ void GraphicsManager::restoreBack(Common::Array<Common::Rect> &rectList, int rec _saveBack = saveBack; } -void GraphicsManager::clearPalette() { - byte palette[768]; - Common::fill(&palette[0], &palette[768], 0); - g_system->getPaletteManager()->setPalette(&palette[0], 0, 256); -} - -void GraphicsManager::setPalette(const byte *palette, int start, int count) { - g_system->getPaletteManager()->setPalette(palette, start, count); +void Screen::setPalette(const byte *palette, int start, int count) { + Graphics::Screen::setPalette(palette, start, count); _vm->_eventsManager->_gameData._hasPalette = false; } -void GraphicsManager::setPalette128(const byte *palette, int start, int count) { +void Screen::setPalette128(const byte *palette, int start, int count) { byte rgb[3]; - g_system->getPaletteManager()->grabPalette(&rgb[0], 128, 1); - g_system->getPaletteManager()->setPalette(palette, start, count); - g_system->getPaletteManager()->setPalette(&rgb[0], 128, 1); + getPalette(&rgb[0], 128, 1); + Graphics::Screen::setPalette(palette, start, count); + Graphics::Screen::setPalette(&rgb[0], 128, 1); } - -void GraphicsManager::resetPalette() { +void Screen::resetPalette() { for (int i = 0; i < 256; ++i) setColor(i, 0, 0, 0); _vm->_eventsManager->_intPtr._hasPalette = true; } -void GraphicsManager::setColor(int idx, byte r, byte g, byte b) { +void Screen::setColor(int idx, byte r, byte g, byte b) { byte *vgaP = &_VGAColors[idx * 3]; vgaP[0] = r; vgaP[1] = g; @@ -965,7 +983,7 @@ void GraphicsManager::setColor(int idx, byte r, byte g, byte b) { _vm->_eventsManager->_intPtr._palEndIndex = MAX(_vm->_eventsManager->_intPtr._palEndIndex, idx); } -void GraphicsManager::setOneColor(int idx, byte r, byte g, byte b) { +void Screen::setOneColor(int idx, byte r, byte g, byte b) { byte palEntry[3]; palEntry[0] = r; palEntry[1] = g; @@ -973,7 +991,7 @@ void GraphicsManager::setOneColor(int idx, byte r, byte g, byte b) { g_system->getPaletteManager()->setPalette(&palEntry[0], idx, 1); } -void GraphicsManager::setColors(int start, int count, const byte *pal) { +void Screen::setColors(int start, int count, const byte *pal) { for (int i = 0; i < count; ++i) { if ((i + start) != 128) { const byte *rgb = pal + i * 3; @@ -984,7 +1002,7 @@ void GraphicsManager::setColors(int start, int count, const byte *pal) { _vm->_eventsManager->_intPtr._hasPalette = true; } -void GraphicsManager::screenReset() { +void Screen::screenReset() { resetPalette(); _backgroundPage = NULL; @@ -994,7 +1012,7 @@ void GraphicsManager::screenReset() { _vm->flipPageAndWait(); } -void GraphicsManager::fadeDownICF1(int steps) { +void Screen::fadeDownICF1(int steps) { if (steps > 0) { int stepAmount = _vm->_voy->_fadingAmount2 / steps; @@ -1007,7 +1025,7 @@ void GraphicsManager::fadeDownICF1(int steps) { _vm->_voy->_fadingAmount2 = 0; } -void GraphicsManager::fadeUpICF1(int steps) { +void Screen::fadeUpICF1(int steps) { if (steps > 0) { int stepAmount = (63 - _vm->_voy->_fadingAmount2) / steps; @@ -1020,7 +1038,7 @@ void GraphicsManager::fadeUpICF1(int steps) { _vm->_voy->_fadingAmount2 = 63; } -void GraphicsManager::fadeDownICF(int steps) { +void Screen::fadeDownICF(int steps) { if (steps > 0) { _vm->_eventsManager->hideCursor(); int stepAmount1 = _vm->_voy->_fadingAmount1 / steps; @@ -1037,14 +1055,19 @@ void GraphicsManager::fadeDownICF(int steps) { _vm->_voy->_fadingAmount2 = 0; } -void GraphicsManager::drawDot() { - for (int y = 0; y < 9; ++y) { - byte *pDest = (byte *)_screenSurface.getPixels() + DOT_LINE_START[y] + DOT_LINE_OFFSET[y]; - Common::fill(pDest, pDest + DOT_LINE_LENGTH[y], 0x80); +void Screen::drawDot() { + for (int idx = 0; idx < 9; ++idx) { + uint offset = DOT_LINE_START[idx] + DOT_LINE_OFFSET[idx]; + int xp = offset % SCREEN_WIDTH; + int yp = offset / SCREEN_WIDTH; + + byte *pDest = (byte *)getPixels() + offset; + Common::fill(pDest, pDest + DOT_LINE_LENGTH[idx], 0x80); + addDirtyRect(Common::Rect(xp, yp, xp + DOT_LINE_LENGTH[idx], yp + 1)); } } -void GraphicsManager::synchronize(Common::Serializer &s) { +void Screen::synchronize(Common::Serializer &s) { s.syncBytes(&_VGAColors[0], PALETTE_SIZE); } diff --git a/engines/voyeur/graphics.h b/engines/voyeur/screen.h index e4d0b38650..aaf61747a4 100644 --- a/engines/voyeur/graphics.h +++ b/engines/voyeur/screen.h @@ -27,17 +27,15 @@ #include "common/array.h" #include "common/rect.h" #include "common/serializer.h" -#include "graphics/surface.h" +#include "graphics/screen.h" namespace Voyeur { #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 200 -#define PALETTE_COUNT 256 -#define PALETTE_SIZE (256 * 3) class VoyeurEngine; -class GraphicsManager; +class Screen; class DisplayResource; class PictureResource; class ViewPortResource; @@ -54,12 +52,12 @@ public: DrawInfo(int penColor, const Common::Point &pos); }; -typedef void (GraphicsManager::*GraphicMethodPtr)(); -typedef void (GraphicsManager::*ViewPortSetupPtr)(ViewPortResource *); -typedef void (GraphicsManager::*ViewPortAddPtr)(ViewPortResource *, int idx, const Common::Rect &bounds); -typedef void (GraphicsManager::*ViewPortRestorePtr)(ViewPortResource *); +typedef void (Screen::*ScreenMethodPtr)(); +typedef void (Screen::*ViewPortSetupPtr)(ViewPortResource *); +typedef void (Screen::*ViewPortAddPtr)(ViewPortResource *, int idx, const Common::Rect &bounds); +typedef void (Screen::*ViewPortRestorePtr)(ViewPortResource *); -class GraphicsManager { +class Screen: public Graphics::Screen { public: byte _VGAColors[PALETTE_SIZE]; PictureResource *_backgroundPage; @@ -69,7 +67,6 @@ public: bool _saveBack; Common::Rect *_clipPtr; uint _planeSelect; - Graphics::Surface _screenSurface; CMapResource *_backColors; FontInfoResource *_fontPtr; PictureResource *_fontChar; @@ -81,8 +78,8 @@ private: void restoreBack(Common::Array<Common::Rect> &rectList, int rectListCount, PictureResource *srcPic, PictureResource *destPic); public: - GraphicsManager(VoyeurEngine *vm); - ~GraphicsManager(); + Screen(VoyeurEngine *vm); + virtual ~Screen(); void sInitGraphics(); @@ -96,7 +93,6 @@ public: void sDisplayPic(PictureResource *pic); void drawANumber(DisplayResource *display, int num, const Common::Point &pt); void flipPage(); - void clearPalette(); void setPalette(const byte *palette, int start, int count); void setPalette128(const byte *palette, int start, int count); void resetPalette(); diff --git a/engines/voyeur/voyeur.cpp b/engines/voyeur/voyeur.cpp index cbb6846340..01b76a72d1 100644 --- a/engines/voyeur/voyeur.cpp +++ b/engines/voyeur/voyeur.cpp @@ -22,7 +22,7 @@ #include "voyeur/voyeur.h" #include "voyeur/animation.h" -#include "voyeur/graphics.h" +#include "voyeur/screen.h" #include "voyeur/staticres.h" #include "common/scummsys.h" #include "common/config-manager.h" @@ -40,7 +40,7 @@ VoyeurEngine::VoyeurEngine(OSystem *syst, const VoyeurGameDescription *gameDesc) _debugger = nullptr; _eventsManager = nullptr; _filesManager = nullptr; - _graphicsManager = nullptr; + _screen = nullptr; _soundManager = nullptr; _voy = nullptr; _bVoy = NULL; @@ -65,13 +65,6 @@ VoyeurEngine::VoyeurEngine(OSystem *syst, const VoyeurGameDescription *gameDesc) DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts"); - _debugger = new Debugger(this); - _eventsManager = new EventsManager(this); - _filesManager = new FilesManager(this); - _graphicsManager = new GraphicsManager(this); - _soundManager = new SoundManager(_mixer); - _voy = new SVoy(this); - _stampLibPtr = nullptr; _controlGroupPtr = nullptr; _stampData = nullptr; @@ -88,7 +81,7 @@ VoyeurEngine::~VoyeurEngine() { delete _bVoy; delete _voy; delete _soundManager; - delete _graphicsManager; + delete _screen; delete _filesManager; delete _eventsManager; delete _debugger; @@ -126,15 +119,22 @@ void VoyeurEngine::ESP_Init() { } void VoyeurEngine::globalInitBolt() { + _debugger = new Debugger(this); + _eventsManager = new EventsManager(this); + _filesManager = new FilesManager(this); + _screen = new Screen(this); + _soundManager = new SoundManager(_mixer); + _voy = new SVoy(this); + initBolt(); _filesManager->openBoltLib("bvoy.blt", _bVoy); _bVoy->getBoltGroup(0x000); _bVoy->getBoltGroup(0x100); - _graphicsManager->_fontPtr = &_defaultFontInfo; - _graphicsManager->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; - assert(_graphicsManager->_fontPtr->_curFont); + _screen->_fontPtr = &_defaultFontInfo; + _screen->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; + assert(_screen->_fontPtr->_curFont); // Setup default flags _voy->_viewBounds = nullptr; @@ -144,13 +144,13 @@ void VoyeurEngine::globalInitBolt() { void VoyeurEngine::initBolt() { vInitInterrupts(); - _graphicsManager->sInitGraphics(); + _screen->sInitGraphics(); _eventsManager->vInitColor(); initInput(); } void VoyeurEngine::vInitInterrupts() { - _eventsManager->_intPtr._palette = &_graphicsManager->_VGAColors[0]; + _eventsManager->_intPtr._palette = &_screen->_VGAColors[0]; } void VoyeurEngine::initInput() { @@ -213,8 +213,8 @@ bool VoyeurEngine::doHeadTitle() { } void VoyeurEngine::showConversionScreen() { - _graphicsManager->_backgroundPage = _bVoy->boltEntry(0x502)._picResource; - _graphicsManager->_vPort->setupViewPort(); + _screen->_backgroundPage = _bVoy->boltEntry(0x502)._picResource; + _screen->_vPort->setupViewPort(); flipPageAndWait(); // Immediate palette load to show the initial screen @@ -237,7 +237,7 @@ void VoyeurEngine::showConversionScreen() { flipPageAndWaitForFade(); - _graphicsManager->screenReset(); + _screen->screenReset(); } bool VoyeurEngine::doLock() { @@ -249,28 +249,28 @@ bool VoyeurEngine::doLock() { if (_bVoy->getBoltGroup(0x700)) { Common::String password = "3333"; - _graphicsManager->_backgroundPage = _bVoy->getPictureResource(0x700); - _graphicsManager->_backColors = _bVoy->getCMapResource(0x701); + _screen->_backgroundPage = _bVoy->getPictureResource(0x700); + _screen->_backColors = _bVoy->getCMapResource(0x701); PictureResource *cursorPic = _bVoy->getPictureResource(0x702); _voy->_viewBounds = _bVoy->boltEntry(0x704)._rectResource; Common::Array<RectEntry> &hotspots = _bVoy->boltEntry(0x705)._rectResource->_entries; assert(cursorPic); - _graphicsManager->_vPort->setupViewPort(); + _screen->_vPort->setupViewPort(); - _graphicsManager->_backColors->startFade(); - _graphicsManager->_vPort->_parent->_flags |= DISPFLAG_8; - _graphicsManager->flipPage(); + _screen->_backColors->startFade(); + _screen->_vPort->_parent->_flags |= DISPFLAG_8; + _screen->flipPage(); _eventsManager->sWaitFlip(); while (!shouldQuit() && (_eventsManager->_fadeStatus & 1)) _eventsManager->delay(1); _eventsManager->setCursorColor(127, 0); - _graphicsManager->setColor(1, 64, 64, 64); - _graphicsManager->setColor(2, 96, 96, 96); - _graphicsManager->setColor(3, 160, 160, 160); - _graphicsManager->setColor(4, 224, 224, 224); + _screen->setColor(1, 64, 64, 64); + _screen->setColor(2, 96, 96, 96); + _screen->setColor(3, 160, 160, 160); + _screen->setColor(4, 224, 224, 224); // Set up the cursor _eventsManager->setCursor(cursorPic); @@ -278,9 +278,9 @@ bool VoyeurEngine::doLock() { _eventsManager->_intPtr._hasPalette = true; - _graphicsManager->_fontPtr->_curFont = _bVoy->boltEntry(0x708)._fontResource; - _graphicsManager->_fontPtr->_fontSaveBack = 0; - _graphicsManager->_fontPtr->_fontFlags = DISPFLAG_NONE; + _screen->_fontPtr->_curFont = _bVoy->boltEntry(0x708)._fontResource; + _screen->_fontPtr->_fontSaveBack = 0; + _screen->_fontPtr->_fontFlags = DISPFLAG_NONE; Common::String dateString = "ScummVM"; Common::String displayString = Common::String::format("Last Play %s", dateString.c_str()); @@ -288,16 +288,16 @@ bool VoyeurEngine::doLock() { bool firstLoop = true; bool breakFlag = false; while (!breakFlag && !shouldQuit()) { - _graphicsManager->_vPort->setupViewPort(); + _screen->_vPort->setupViewPort(); flipPageAndWait(); // Display the last play time - _graphicsManager->_fontPtr->_pos = Common::Point(0, 97); - _graphicsManager->_fontPtr->_justify = ALIGN_CENTER; - _graphicsManager->_fontPtr->_justifyWidth = 384; - _graphicsManager->_fontPtr->_justifyHeight = 97; + _screen->_fontPtr->_pos = Common::Point(0, 97); + _screen->_fontPtr->_justify = ALIGN_CENTER; + _screen->_fontPtr->_justifyWidth = 384; + _screen->_fontPtr->_justifyHeight = 97; - _graphicsManager->_vPort->drawText(displayString); + _screen->_vPort->drawText(displayString); flipPageAndWait(); if (firstLoop) { @@ -356,7 +356,7 @@ bool VoyeurEngine::doLock() { } else if (key == 11) { // New code if ((password.empty() && displayString.empty()) || (password != displayString)) { - _graphicsManager->_vPort->setupViewPort(); + _screen->_vPort->setupViewPort(); password = displayString; displayString = ""; continue; @@ -373,9 +373,9 @@ bool VoyeurEngine::doLock() { _soundManager->playVOCMap(wrongVoc, wrongVocSize); } - _graphicsManager->fillPic(_graphicsManager->_vPort, 0); + _screen->fillPic(_screen->_vPort, 0); flipPageAndWait(); - _graphicsManager->resetPalette(); + _screen->resetPalette(); _voy->_viewBounds = nullptr; _bVoy->freeBoltGroup(0x700); @@ -393,9 +393,9 @@ void VoyeurEngine::showTitleScreen() { if (!_bVoy->getBoltGroup(0x500)) return; - _graphicsManager->_backgroundPage = _bVoy->getPictureResource(0x500); + _screen->_backgroundPage = _bVoy->getPictureResource(0x500); - _graphicsManager->_vPort->setupViewPort(); + _screen->_vPort->setupViewPort(); flipPageAndWait(); // Immediate palette load to show the initial screen @@ -422,18 +422,18 @@ void VoyeurEngine::showTitleScreen() { return; } - _graphicsManager->screenReset(); + _screen->screenReset(); _eventsManager->delayClick(200); // Voyeur title playRL2Video("a1100100.rl2"); - _graphicsManager->screenReset(); + _screen->screenReset(); _bVoy->freeBoltGroup(0x500); } void VoyeurEngine::doOpening() { - _graphicsManager->screenReset(); + _screen->screenReset(); if (!_bVoy->getBoltGroup(0x200)) return; @@ -459,10 +459,10 @@ void VoyeurEngine::doOpening() { _voy->_eventFlags &= ~EVTFLAG_TIME_DISABLED; for (int i = 0; i < 256; ++i) - _graphicsManager->setColor(i, 8, 8, 8); + _screen->setColor(i, 8, 8, 8); _eventsManager->_intPtr._hasPalette = true; - _graphicsManager->_vPort->setupViewPort(); + _screen->_vPort->setupViewPort(); flipPageAndWait(); RL2Decoder decoder; @@ -472,14 +472,12 @@ void VoyeurEngine::doOpening() { while (!shouldQuit() && !decoder.endOfVideo() && !_eventsManager->_mouseClicked) { if (decoder.hasDirtyPalette()) { const byte *palette = decoder.getPalette(); - _graphicsManager->setPalette(palette, 0, 256); + _screen->setPalette(palette, 0, 256); } if (decoder.needsUpdate()) { const Graphics::Surface *frame = decoder.decodeNextFrame(); - - Common::copy((const byte *)frame->getPixels(), (const byte *)frame->getPixels() + 320 * 200, - (byte *)_graphicsManager->_screenSurface.getPixels()); + _screen->blitFrom(*frame); if (decoder.getCurFrame() >= (int32)READ_LE_UINT32(frameTable + frameIndex * 4)) { if (creditShow) { @@ -499,7 +497,7 @@ void VoyeurEngine::doOpening() { } if (textPic) { - _graphicsManager->sDrawPic(textPic, _graphicsManager->_vPort, textPos); + _screen->sDrawPic(textPic, _screen->_vPort, textPos); } flipPageAndWait(); @@ -527,14 +525,12 @@ void VoyeurEngine::playRL2Video(const Common::String &filename) { while (!shouldQuit() && !decoder.endOfVideo() && !_eventsManager->_mouseClicked) { if (decoder.hasDirtyPalette()) { const byte *palette = decoder.getPalette(); - _graphicsManager->setPalette(palette, 0, 256); + _screen->setPalette(palette, 0, 256); } if (decoder.needsUpdate()) { const Graphics::Surface *frame = decoder.decodeNextFrame(); - - Common::copy((const byte *)frame->getPixels(), (const byte *)frame->getPixels() + 320 * 200, - (byte *)_graphicsManager->_screenSurface.getPixels()); + _screen->blitFrom(*frame); } _eventsManager->getMouseInfo(); @@ -573,17 +569,16 @@ void VoyeurEngine::playAVideoDuration(int videoId, int duration) { (decoder.getCurFrame() < endFrame)) { if (decoder.needsUpdate()) { const Graphics::Surface *frame = decoder.decodeNextFrame(); + _screen->blitFrom(*frame); - Common::copy((const byte *)frame->getPixels(), (const byte *)frame->getPixels() + 320 * 200, - (byte *)_graphicsManager->_screenSurface.getPixels()); if (_voy->_eventFlags & EVTFLAG_RECORDING) - _graphicsManager->drawDot(); + _screen->drawDot(); } if (decoder.hasDirtyPalette()) { const byte *palette = decoder.getPalette(); - _graphicsManager->setPalette(palette, 0, decoder.getPaletteCount()); - _graphicsManager->setOneColor(128, 220, 20, 20); + _screen->setPalette(palette, 0, decoder.getPaletteCount()); + _screen->setOneColor(128, 220, 20, 20); } _eventsManager->getMouseInfo(); @@ -591,13 +586,13 @@ void VoyeurEngine::playAVideoDuration(int videoId, int duration) { } // RL2 finished - _graphicsManager->screenReset(); + _screen->screenReset(); _voy->_eventFlags &= ~EVTFLAG_RECORDING; if (_voy->_eventFlags & EVTFLAG_8) { assert(pic); - byte *imgData = _graphicsManager->_vPort->_currentPic->_imgData; - _graphicsManager->_vPort->_currentPic->_imgData = pic->_imgData; + byte *imgData = _screen->_vPort->_currentPic->_imgData; + _screen->_vPort->_currentPic->_imgData = pic->_imgData; pic->_imgData = imgData; _voy->_eventFlags &= ~EVTFLAG_8; } @@ -608,13 +603,13 @@ void VoyeurEngine::playAVideoDuration(int videoId, int duration) { void VoyeurEngine::playAudio(int audioId) { _bVoy->getBoltGroup(0x7F00); - _graphicsManager->_backgroundPage = _bVoy->boltEntry(0x7F00 + + _screen->_backgroundPage = _bVoy->boltEntry(0x7F00 + BLIND_TABLE[audioId] * 2)._picResource; - _graphicsManager->_backColors = _bVoy->boltEntry(0x7F01 + + _screen->_backColors = _bVoy->boltEntry(0x7F01 + BLIND_TABLE[audioId] * 2)._cMapResource; - _graphicsManager->_vPort->setupViewPort(); - _graphicsManager->_backColors->startFade(); + _screen->_vPort->setupViewPort(); + _screen->_backColors->startFade(); flipPageAndWaitForFade(); _voy->_eventFlags &= ~EVTFLAG_TIME_DISABLED; @@ -633,26 +628,26 @@ void VoyeurEngine::playAudio(int audioId) { _soundManager->stopVOCPlay(); _bVoy->freeBoltGroup(0x7F00); - _graphicsManager->_vPort->setupViewPort(NULL); + _screen->_vPort->setupViewPort(NULL); _voy->_eventFlags &= ~EVTFLAG_RECORDING; _voy->_playStampMode = 129; } void VoyeurEngine::doTransitionCard(const Common::String &time, const Common::String &location) { - _graphicsManager->setColor(128, 16, 16, 16); - _graphicsManager->setColor(224, 220, 220, 220); + _screen->setColor(128, 16, 16, 16); + _screen->setColor(224, 220, 220, 220); _eventsManager->_intPtr._hasPalette = true; - _graphicsManager->_vPort->setupViewPort(NULL); - _graphicsManager->_vPort->fillPic(0x80); - _graphicsManager->flipPage(); + _screen->_vPort->setupViewPort(NULL); + _screen->_vPort->fillPic(0x80); + _screen->flipPage(); _eventsManager->sWaitFlip(); flipPageAndWait(); - _graphicsManager->_vPort->fillPic(0x80); + _screen->_vPort->fillPic(0x80); - FontInfoResource &fi = *_graphicsManager->_fontPtr; + FontInfoResource &fi = *_screen->_fontPtr; fi._curFont = _bVoy->boltEntry(257)._fontResource; fi._foreColor = 224; fi._fontSaveBack = 0; @@ -661,7 +656,7 @@ void VoyeurEngine::doTransitionCard(const Common::String &time, const Common::St fi._justifyWidth = 384; fi._justifyHeight = 120; - _graphicsManager->_vPort->drawText(time); + _screen->_vPort->drawText(time); if (!location.empty()) { fi._pos = Common::Point(0, 138); @@ -669,7 +664,7 @@ void VoyeurEngine::doTransitionCard(const Common::String &time, const Common::St fi._justifyWidth = 384; fi._justifyHeight = 140; - _graphicsManager->_vPort->drawText(location); + _screen->_vPort->drawText(location); } flipPageAndWait(); @@ -680,8 +675,8 @@ void VoyeurEngine::saveLastInplay() { } void VoyeurEngine::flipPageAndWait() { - _graphicsManager->_vPort->_flags |= DISPFLAG_8; - _graphicsManager->flipPage(); + _screen->_vPort->_flags |= DISPFLAG_8; + _screen->flipPage(); _eventsManager->sWaitFlip(); } @@ -702,7 +697,7 @@ void VoyeurEngine::showEndingNews() { PictureResource *pic = _bVoy->boltEntry(_playStampGroupId)._picResource; CMapResource *pal = _bVoy->boltEntry(_playStampGroupId + 1)._cMapResource; - _graphicsManager->_vPort->setupViewPort(pic); + _screen->_vPort->setupViewPort(pic); pal->startFade(); flipPageAndWaitForFade(); @@ -717,7 +712,7 @@ void VoyeurEngine::showEndingNews() { pal = _bVoy->boltEntry(_playStampGroupId + idx * 2 + 1)._cMapResource; } - _graphicsManager->_vPort->setupViewPort(pic); + _screen->_vPort->setupViewPort(pic); pal->startFade(); flipPageAndWaitForFade(); @@ -852,7 +847,7 @@ void VoyeurEngine::synchronize(Common::Serializer &s) { // Sub-systems _voy->synchronize(s); - _graphicsManager->synchronize(s); + _screen->synchronize(s); _mainThread->synchronize(s); _controlPtr->_state->synchronize(s); } @@ -906,8 +901,8 @@ void VoyeurSavegameHeader::write(Common::OutSaveFile *f, VoyeurEngine *vm, const // Create a thumbnail and save it Graphics::Surface *thumb = new Graphics::Surface(); - ::createThumbnail(thumb, (byte *)vm->_graphicsManager->_screenSurface.getPixels(), - SCREEN_WIDTH, SCREEN_HEIGHT, vm->_graphicsManager->_VGAColors); + ::createThumbnail(thumb, (const byte *)vm->_screen->getPixels(), + SCREEN_WIDTH, SCREEN_HEIGHT, vm->_screen->_VGAColors); Graphics::saveThumbnail(*f, *thumb); thumb->free(); delete thumb; diff --git a/engines/voyeur/voyeur.h b/engines/voyeur/voyeur.h index e0bb734fa8..9cda85fd51 100644 --- a/engines/voyeur/voyeur.h +++ b/engines/voyeur/voyeur.h @@ -27,7 +27,7 @@ #include "voyeur/data.h" #include "voyeur/events.h" #include "voyeur/files.h" -#include "voyeur/graphics.h" +#include "voyeur/screen.h" #include "voyeur/sound.h" #include "common/scummsys.h" #include "common/system.h" @@ -164,7 +164,7 @@ public: Debugger *_debugger; EventsManager *_eventsManager; FilesManager *_filesManager; - GraphicsManager *_graphicsManager; + Screen *_screen; SoundManager *_soundManager; SVoy *_voy; diff --git a/engines/voyeur/voyeur_game.cpp b/engines/voyeur/voyeur_game.cpp index 13ef31839a..e9591955fc 100644 --- a/engines/voyeur/voyeur_game.cpp +++ b/engines/voyeur/voyeur_game.cpp @@ -149,8 +149,8 @@ void VoyeurEngine::playStamp() { case 130: { // user selected to send the tape if (_bVoy->getBoltGroup(_playStampGroupId)) { - _graphicsManager->_backgroundPage = _bVoy->boltEntry(_playStampGroupId)._picResource; - _graphicsManager->_backColors = _bVoy->boltEntry(_playStampGroupId + 1)._cMapResource; + _screen->_backgroundPage = _bVoy->boltEntry(_playStampGroupId)._picResource; + _screen->_backColors = _bVoy->boltEntry(_playStampGroupId + 1)._cMapResource; buttonId = getChooseButton(); if (_eventsManager->_rightClick) @@ -158,7 +158,7 @@ void VoyeurEngine::playStamp() { buttonId = 4; _bVoy->freeBoltGroup(_playStampGroupId); - _graphicsManager->screenReset(); + _screen->screenReset(); _playStampGroupId = -1; flag = true; @@ -232,8 +232,8 @@ void VoyeurEngine::closeStamp() { } void VoyeurEngine::doTailTitle() { - _graphicsManager->_vPort->setupViewPort(NULL); - _graphicsManager->screenReset(); + _screen->_vPort->setupViewPort(NULL); + _screen->screenReset(); if (_bVoy->getBoltGroup(0x600)) { RL2Decoder decoder; @@ -245,12 +245,12 @@ void VoyeurEngine::doTailTitle() { doClosingCredits(); if (!shouldQuit() && !_eventsManager->_mouseClicked) { - _graphicsManager->screenReset(); + _screen->screenReset(); PictureResource *pic = _bVoy->boltEntry(0x602)._picResource; CMapResource *pal = _bVoy->boltEntry(0x603)._cMapResource; - _graphicsManager->_vPort->setupViewPort(pic); + _screen->_vPort->setupViewPort(pic); pal->startFade(); flipPageAndWaitForFade(); _eventsManager->delayClick(300); @@ -258,7 +258,7 @@ void VoyeurEngine::doTailTitle() { pic = _bVoy->boltEntry(0x604)._picResource; pal = _bVoy->boltEntry(0x605)._cMapResource; - _graphicsManager->_vPort->setupViewPort(pic); + _screen->_vPort->setupViewPort(pic); pal->startFade(); flipPageAndWaitForFade(); _eventsManager->delayClick(120); @@ -283,26 +283,26 @@ void VoyeurEngine::doClosingCredits() { const char *msg = (const char *)_bVoy->memberAddr(0x404); const byte *creditList = (const byte *)_bVoy->memberAddr(0x405); - _graphicsManager->_vPort->setupViewPort(NULL); - _graphicsManager->setColor(1, 180, 180, 180); - _graphicsManager->setColor(2, 200, 200, 200); + _screen->_vPort->setupViewPort(NULL); + _screen->setColor(1, 180, 180, 180); + _screen->setColor(2, 200, 200, 200); _eventsManager->_intPtr._hasPalette = true; - _graphicsManager->_fontPtr->_curFont = _bVoy->boltEntry(0x402)._fontResource; - _graphicsManager->_fontPtr->_foreColor = 2; - _graphicsManager->_fontPtr->_backColor = 2; - _graphicsManager->_fontPtr->_fontSaveBack = false; - _graphicsManager->_fontPtr->_fontFlags = DISPFLAG_NONE; + _screen->_fontPtr->_curFont = _bVoy->boltEntry(0x402)._fontResource; + _screen->_fontPtr->_foreColor = 2; + _screen->_fontPtr->_backColor = 2; + _screen->_fontPtr->_fontSaveBack = false; + _screen->_fontPtr->_fontFlags = DISPFLAG_NONE; _soundManager->startVOCPlay(152); - FontInfoResource &fi = *_graphicsManager->_fontPtr; + FontInfoResource &fi = *_screen->_fontPtr; for (int idx = 0; idx < 78; ++idx) { const byte *entry = creditList + idx * 6; int flags = READ_LE_UINT16(entry + 4); if (flags & 0x10) - _graphicsManager->_vPort->fillPic(0); + _screen->_vPort->fillPic(0); if (flags & 1) { fi._foreColor = 1; @@ -312,7 +312,7 @@ void VoyeurEngine::doClosingCredits() { fi._justifyHeight = 240; fi._pos = Common::Point(0, READ_LE_UINT16(entry)); - _graphicsManager->_vPort->drawText(msg); + _screen->_vPort->drawText(msg); msg += strlen(msg) + 1; } @@ -324,7 +324,7 @@ void VoyeurEngine::doClosingCredits() { fi._justifyHeight = 240; fi._pos = Common::Point(0, READ_LE_UINT16(entry)); - _graphicsManager->_vPort->drawText(msg); + _screen->_vPort->drawText(msg); msg += strlen(msg) + 1; } @@ -336,7 +336,7 @@ void VoyeurEngine::doClosingCredits() { fi._justifyHeight = 240; fi._pos = Common::Point(38, READ_LE_UINT16(entry)); - _graphicsManager->_vPort->drawText(msg); + _screen->_vPort->drawText(msg); msg += strlen(msg) + 1; fi._foreColor = 2; @@ -345,7 +345,7 @@ void VoyeurEngine::doClosingCredits() { fi._justifyHeight = 240; fi._pos = Common::Point(198, READ_LE_UINT16(entry)); - _graphicsManager->_vPort->drawText(msg); + _screen->_vPort->drawText(msg); msg += strlen(msg) + 1; } @@ -357,7 +357,7 @@ void VoyeurEngine::doClosingCredits() { fi._justifyHeight = 240; fi._pos = Common::Point(0, READ_LE_UINT16(entry)); - _graphicsManager->_vPort->drawText(msg); + _screen->_vPort->drawText(msg); msg += strlen(msg) + 1; fi._foreColor = 2; @@ -367,7 +367,7 @@ void VoyeurEngine::doClosingCredits() { fi._justifyHeight = 240; fi._pos = Common::Point(0, READ_LE_UINT16(entry) + 13); - _graphicsManager->_vPort->drawText(msg); + _screen->_vPort->drawText(msg); msg += strlen(msg) + 1; } @@ -381,19 +381,19 @@ void VoyeurEngine::doClosingCredits() { } _soundManager->stopVOCPlay(); - _graphicsManager->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; + _screen->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; _bVoy->freeBoltGroup(0x400); } void VoyeurEngine::doPiracy() { - _graphicsManager->screenReset(); - _graphicsManager->setColor(1, 0, 0, 0); - _graphicsManager->setColor(2, 255, 255, 255); + _screen->screenReset(); + _screen->setColor(1, 0, 0, 0); + _screen->setColor(2, 255, 255, 255); _eventsManager->_intPtr._hasPalette = true; - _graphicsManager->_vPort->setupViewPort(NULL); - _graphicsManager->_vPort->fillPic(1); + _screen->_vPort->setupViewPort(NULL); + _screen->_vPort->fillPic(1); - FontInfoResource &fi = *_graphicsManager->_fontPtr; + FontInfoResource &fi = *_screen->_fontPtr; fi._curFont = _bVoy->boltEntry(0x101)._fontResource; fi._foreColor = 2; fi._backColor = 2; @@ -406,7 +406,7 @@ void VoyeurEngine::doPiracy() { // Loop through the piracy message array to draw each line for (int idx = 0, yp = 33; idx < 10; ++idx) { fi._pos = Common::Point(0, yp); - _graphicsManager->_vPort->drawText(PIRACY_MESSAGE[idx]); + _screen->_vPort->drawText(PIRACY_MESSAGE[idx]); yp += fi._curFont->_fontHeight + 4; } @@ -439,27 +439,27 @@ void VoyeurEngine::reviewTape() { _voy->_viewBounds = _bVoy->boltEntry(0x907)._rectResource; Common::Array<RectEntry> &hotspots = _bVoy->boltEntry(0x906)._rectResource->_entries; - _graphicsManager->_backColors = _bVoy->boltEntry(0x902)._cMapResource; - _graphicsManager->_backgroundPage = _bVoy->boltEntry(0x901)._picResource; - _graphicsManager->_vPort->setupViewPort(_graphicsManager->_backgroundPage); - _graphicsManager->_backColors->startFade(); + _screen->_backColors = _bVoy->boltEntry(0x902)._cMapResource; + _screen->_backgroundPage = _bVoy->boltEntry(0x901)._picResource; + _screen->_vPort->setupViewPort(_screen->_backgroundPage); + _screen->_backColors->startFade(); flipPageAndWaitForFade(); - _graphicsManager->setColor(1, 32, 32, 32); - _graphicsManager->setColor(2, 96, 96, 96); - _graphicsManager->setColor(3, 160, 160, 160); - _graphicsManager->setColor(4, 224, 224, 224); - _graphicsManager->setColor(9, 24, 64, 24); - _graphicsManager->setColor(10, 64, 132, 64); - _graphicsManager->setColor(11, 100, 192, 100); - _graphicsManager->setColor(12, 120, 248, 120); + _screen->setColor(1, 32, 32, 32); + _screen->setColor(2, 96, 96, 96); + _screen->setColor(3, 160, 160, 160); + _screen->setColor(4, 224, 224, 224); + _screen->setColor(9, 24, 64, 24); + _screen->setColor(10, 64, 132, 64); + _screen->setColor(11, 100, 192, 100); + _screen->setColor(12, 120, 248, 120); _eventsManager->setCursorColor(128, 1); _eventsManager->_intPtr._hasPalette = true; - _graphicsManager->_fontPtr->_curFont = _bVoy->boltEntry(0x909)._fontResource; - _graphicsManager->_fontPtr->_fontSaveBack = false; - _graphicsManager->_fontPtr->_fontFlags = DISPFLAG_NONE; + _screen->_fontPtr->_curFont = _bVoy->boltEntry(0x909)._fontResource; + _screen->_fontPtr->_fontSaveBack = false; + _screen->_fontPtr->_fontFlags = DISPFLAG_NONE; _eventsManager->getMouseInfo(); if (newX == -1) { @@ -481,37 +481,37 @@ void VoyeurEngine::reviewTape() { needRedraw = false; flipPageAndWait(); - _graphicsManager->_drawPtr->_penColor = 0; - _graphicsManager->_drawPtr->_pos = Common::Point(tempRect.left, tempRect.top); - _graphicsManager->_backgroundPage->sFillBox(tempRect.width(), tempRect.height()); + _screen->_drawPtr->_penColor = 0; + _screen->_drawPtr->_pos = Common::Point(tempRect.left, tempRect.top); + _screen->_backgroundPage->sFillBox(tempRect.width(), tempRect.height()); int yp = 45; int eventNum = eventStart; for (int lineNum = 0; lineNum < 8 && eventNum < _voy->_eventCount; ++lineNum, ++eventNum) { - _graphicsManager->_fontPtr->_picFlags = DISPFLAG_NONE; - _graphicsManager->_fontPtr->_picSelect = 0xff; - _graphicsManager->_fontPtr->_picPick = 7; - _graphicsManager->_fontPtr->_picOnOff = (lineNum == eventLine) ? 8 : 0; - _graphicsManager->_fontPtr->_pos = Common::Point(68, yp); - _graphicsManager->_fontPtr->_justify = ALIGN_LEFT; - _graphicsManager->_fontPtr->_justifyWidth = 0; - _graphicsManager->_fontPtr->_justifyHeight = 0; + _screen->_fontPtr->_picFlags = DISPFLAG_NONE; + _screen->_fontPtr->_picSelect = 0xff; + _screen->_fontPtr->_picPick = 7; + _screen->_fontPtr->_picOnOff = (lineNum == eventLine) ? 8 : 0; + _screen->_fontPtr->_pos = Common::Point(68, yp); + _screen->_fontPtr->_justify = ALIGN_LEFT; + _screen->_fontPtr->_justifyWidth = 0; + _screen->_fontPtr->_justifyHeight = 0; Common::String msg = _eventsManager->getEvidString(eventNum); - _graphicsManager->_backgroundPage->drawText(msg); + _screen->_backgroundPage->drawText(msg); yp += 15; } - _graphicsManager->_vPort->addSaveRect( - _graphicsManager->_vPort->_lastPage, tempRect); + _screen->_vPort->addSaveRect( + _screen->_vPort->_lastPage, tempRect); flipPageAndWait(); - _graphicsManager->_vPort->addSaveRect( - _graphicsManager->_vPort->_lastPage, tempRect); + _screen->_vPort->addSaveRect( + _screen->_vPort->_lastPage, tempRect); } - _graphicsManager->sDrawPic(cursor, _graphicsManager->_vPort, + _screen->sDrawPic(cursor, _screen->_vPort, _eventsManager->getMousePos()); flipPageAndWait(); @@ -543,34 +543,34 @@ void VoyeurEngine::reviewTape() { flipPageAndWait(); - _graphicsManager->_drawPtr->_penColor = 0; - _graphicsManager->_drawPtr->_pos = Common::Point(tempRect.left, tempRect.top); - _graphicsManager->_backgroundPage->sFillBox(tempRect.width(), tempRect.height()); + _screen->_drawPtr->_penColor = 0; + _screen->_drawPtr->_pos = Common::Point(tempRect.left, tempRect.top); + _screen->_backgroundPage->sFillBox(tempRect.width(), tempRect.height()); int yp = 45; int eventNum = eventStart; for (int idx = 0; idx < 8 && eventNum < _voy->_eventCount; ++idx, ++eventNum) { - _graphicsManager->_fontPtr->_picFlags = DISPFLAG_NONE; - _graphicsManager->_fontPtr->_picSelect = 0xff; - _graphicsManager->_fontPtr->_picPick = 7; - _graphicsManager->_fontPtr->_picOnOff = (idx == eventLine) ? 8 : 0; - _graphicsManager->_fontPtr->_pos = Common::Point(68, yp); - _graphicsManager->_fontPtr->_justify = ALIGN_LEFT; - _graphicsManager->_fontPtr->_justifyWidth = 0; - _graphicsManager->_fontPtr->_justifyHeight = 0; + _screen->_fontPtr->_picFlags = DISPFLAG_NONE; + _screen->_fontPtr->_picSelect = 0xff; + _screen->_fontPtr->_picPick = 7; + _screen->_fontPtr->_picOnOff = (idx == eventLine) ? 8 : 0; + _screen->_fontPtr->_pos = Common::Point(68, yp); + _screen->_fontPtr->_justify = ALIGN_LEFT; + _screen->_fontPtr->_justifyWidth = 0; + _screen->_fontPtr->_justifyHeight = 0; Common::String msg = _eventsManager->getEvidString(eventNum); - _graphicsManager->_backgroundPage->drawText(msg); + _screen->_backgroundPage->drawText(msg); yp += 15; } - _graphicsManager->_vPort->addSaveRect( - _graphicsManager->_vPort->_lastPage, tempRect); + _screen->_vPort->addSaveRect( + _screen->_vPort->_lastPage, tempRect); flipPageAndWait(); - _graphicsManager->_vPort->addSaveRect( - _graphicsManager->_vPort->_lastPage, tempRect); + _screen->_vPort->addSaveRect( + _screen->_vPort->_lastPage, tempRect); flipPageAndWait(); _eventsManager->getMouseInfo(); @@ -650,7 +650,7 @@ void VoyeurEngine::reviewTape() { newY = _eventsManager->getMousePos().y; _voy->_fadingType = 0; _voy->_viewBounds = nullptr; - _graphicsManager->_vPort->setupViewPort(NULL); + _screen->_vPort->setupViewPort(NULL); if (_currentVocId != -1) { _voy->_vocSecondsOffset = _voy->_RTVNum - _voy->_musicStartTime; @@ -673,13 +673,13 @@ void VoyeurEngine::reviewTape() { _voy->_vocSecondsOffset = e._computerOn; _bVoy->getBoltGroup(0x7F00); - _graphicsManager->_backgroundPage = _bVoy->boltEntry(0x7F00 + + _screen->_backgroundPage = _bVoy->boltEntry(0x7F00 + BLIND_TABLE[_audioVideoId])._picResource; - _graphicsManager->_backColors = _bVoy->boltEntry(0x7F01 + + _screen->_backColors = _bVoy->boltEntry(0x7F01 + BLIND_TABLE[_audioVideoId])._cMapResource; - _graphicsManager->_vPort->setupViewPort(_graphicsManager->_backgroundPage); - _graphicsManager->_backColors->startFade(); + _screen->_vPort->setupViewPort(_screen->_backgroundPage); + _screen->_backColors->startFade(); flipPageAndWaitForFade(); _eventsManager->_intPtr._flashStep = 1; @@ -725,16 +725,16 @@ void VoyeurEngine::reviewTape() { } } - _graphicsManager->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; + _screen->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; - _graphicsManager->_vPort->fillPic(0); + _screen->_vPort->fillPic(0); flipPageAndWait(); _bVoy->freeBoltGroup(0x900); } void VoyeurEngine::doGossip() { - _graphicsManager->resetPalette(); - _graphicsManager->screenReset(); + _screen->resetPalette(); + _screen->screenReset(); if (!_bVoy->getBoltGroup(0x300)) return; @@ -752,7 +752,7 @@ void VoyeurEngine::doGossip() { // Transfer initial background to video decoder PictureResource videoFrame(decoder.getRL2VideoTrack()->getBackSurface()); bgPic->_bounds.moveTo(0, 0); - _graphicsManager->sDrawPic(bgPic, &videoFrame, Common::Point(0, 0)); + _screen->sDrawPic(bgPic, &videoFrame, Common::Point(0, 0)); byte *frameNumsP = _bVoy->memberAddr(0x309); byte *posP = _bVoy->boltEntry(0x30A)._data; @@ -762,8 +762,8 @@ void VoyeurEngine::doGossip() { decoder.close(); // Reset the palette and clear the screen - _graphicsManager->resetPalette(); - _graphicsManager->screenReset(); + _screen->resetPalette(); + _screen->screenReset(); // Play interview video RL2Decoder decoder2; @@ -775,7 +775,7 @@ void VoyeurEngine::doGossip() { decoder2.close(); _bVoy->freeBoltGroup(0x300); - _graphicsManager->screenReset(); + _screen->screenReset(); } void VoyeurEngine::doTapePlaying() { @@ -783,14 +783,14 @@ void VoyeurEngine::doTapePlaying() { return; _eventsManager->getMouseInfo(); - _graphicsManager->_backColors = _bVoy->boltEntry(0xA01)._cMapResource; - _graphicsManager->_backgroundPage = _bVoy->boltEntry(0xA00)._picResource; + _screen->_backColors = _bVoy->boltEntry(0xA01)._cMapResource; + _screen->_backgroundPage = _bVoy->boltEntry(0xA00)._picResource; PictureResource *pic = _bVoy->boltEntry(0xA02)._picResource; VInitCycleResource *cycle = _bVoy->boltEntry(0xA05)._vInitCycleResource; - _graphicsManager->_vPort->setupViewPort(_graphicsManager->_backgroundPage); - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, Common::Point(57, 30)); - _graphicsManager->_backColors->startFade(); + _screen->_vPort->setupViewPort(_screen->_backgroundPage); + _screen->sDrawPic(pic, _screen->_vPort, Common::Point(57, 30)); + _screen->_backColors->startFade(); flipPageAndWaitForFade(); cycle->vStartCycle(); @@ -932,9 +932,9 @@ int VoyeurEngine::getChooseButton() { + 6)._rectResource->_entries; int selectedIndex = -1; - _graphicsManager->_vPort->setupViewPort(_graphicsManager->_backgroundPage); - _graphicsManager->_backColors->_steps = 0; - _graphicsManager->_backColors->startFade(); + _screen->_vPort->setupViewPort(_screen->_backgroundPage); + _screen->_backColors->_steps = 0; + _screen->_backColors->startFade(); flipPageAndWait(); _voy->_viewBounds = _bVoy->boltEntry(_playStampGroupId + 7)._rectResource; @@ -955,7 +955,7 @@ int VoyeurEngine::getChooseButton() { selectedIndex = idx; if (selectedIndex != prevIndex) { PictureResource *btnPic = _bVoy->boltEntry(_playStampGroupId + 8 + idx)._picResource; - _graphicsManager->sDrawPic(btnPic, _graphicsManager->_vPort, + _screen->sDrawPic(btnPic, _screen->_vPort, Common::Point(106, 200)); cursorPic = _bVoy->boltEntry(_playStampGroupId + 4)._picResource; @@ -967,11 +967,11 @@ int VoyeurEngine::getChooseButton() { if (selectedIndex == -1) { cursorPic = _bVoy->boltEntry(_playStampGroupId + 2)._picResource; PictureResource *btnPic = _bVoy->boltEntry(_playStampGroupId + 12)._picResource; - _graphicsManager->sDrawPic(btnPic, _graphicsManager->_vPort, + _screen->sDrawPic(btnPic, _screen->_vPort, Common::Point(106, 200)); } - _graphicsManager->sDrawPic(cursorPic, _graphicsManager->_vPort, + _screen->sDrawPic(cursorPic, _screen->_vPort, Common::Point(pt.x + 13, pt.y - 12)); flipPageAndWait(); @@ -982,9 +982,9 @@ int VoyeurEngine::getChooseButton() { } void VoyeurEngine::makeViewFinder() { - _graphicsManager->_backgroundPage = _bVoy->boltEntry(0x103)._picResource; - _graphicsManager->sDrawPic(_graphicsManager->_backgroundPage, - _graphicsManager->_vPort, Common::Point(0, 0)); + _screen->_backgroundPage = _bVoy->boltEntry(0x103)._picResource; + _screen->sDrawPic(_screen->_backgroundPage, + _screen->_vPort, Common::Point(0, 0)); CMapResource *pal = _bVoy->boltEntry(0x104)._cMapResource; int palOffset = 0; @@ -1016,22 +1016,22 @@ void VoyeurEngine::makeViewFinder() { break; } - _graphicsManager->_vPort->drawIfaceTime(); + _screen->_vPort->drawIfaceTime(); doTimeBar(); pal->startFade(); flipPageAndWaitForFade(); - _graphicsManager->setColor(241, 105, 105, 105); - _graphicsManager->setColor(242, 105, 105, 105); - _graphicsManager->setColor(243, 105, 105, 105); - _graphicsManager->setColor(palOffset + 241, 219, 235, 235); + _screen->setColor(241, 105, 105, 105); + _screen->setColor(242, 105, 105, 105); + _screen->setColor(243, 105, 105, 105); + _screen->setColor(palOffset + 241, 219, 235, 235); _eventsManager->_intPtr._hasPalette = true; } void VoyeurEngine::makeViewFinderP() { - _graphicsManager->screenReset(); + _screen->screenReset(); } void VoyeurEngine::initIFace() { @@ -1077,7 +1077,7 @@ void VoyeurEngine::initIFace() { void VoyeurEngine::doScroll(const Common::Point &pt) { Common::Rect clipRect(72, 47, 72 + 240, 47 + 148); - _graphicsManager->_vPort->setupViewPort(NULL, &clipRect); + _screen->_vPort->setupViewPort(NULL, &clipRect); int base = 0; switch (_voy->_transitionId) { @@ -1101,18 +1101,18 @@ void VoyeurEngine::doScroll(const Common::Point &pt) { if (base) { PictureResource *pic = _bVoy->boltEntry(base + 3)._picResource; - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y - 104)); + _screen->sDrawPic(pic, _screen->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y - 104)); pic = _bVoy->boltEntry(base + 4)._picResource; - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y - 44)); + _screen->sDrawPic(pic, _screen->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y - 44)); pic = _bVoy->boltEntry(base + 5)._picResource; - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y + 16)); + _screen->sDrawPic(pic, _screen->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y + 16)); pic = _bVoy->boltEntry(base + 6)._picResource; - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y + 76)); + _screen->sDrawPic(pic, _screen->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y + 76)); pic = _bVoy->boltEntry(base + 7)._picResource; - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y + 136)); + _screen->sDrawPic(pic, _screen->_vPort, Common::Point(784 - pt.x - 712, 150 - pt.y + 136)); } - _graphicsManager->_vPort->setupViewPort(NULL); + _screen->_vPort->setupViewPort(NULL); } void VoyeurEngine::checkTransition() { @@ -1124,7 +1124,7 @@ void VoyeurEngine::checkTransition() { // Only proceed if a valid day string was returned if (!day.empty()) { - _graphicsManager->fadeDownICF(6); + _screen->fadeDownICF(6); // Get the time of day string time = getTimeOfDay(); @@ -1163,7 +1163,7 @@ Common::String VoyeurEngine::getTimeOfDay() { } int VoyeurEngine::doComputerText(int maxLen) { - FontInfoResource &font = *_graphicsManager->_fontPtr; + FontInfoResource &font = *_screen->_fontPtr; int totalChars = 0; font._curFont = _bVoy->boltEntry(0x4910)._fontResource; @@ -1180,7 +1180,7 @@ int VoyeurEngine::doComputerText(int maxLen) { font._justifyWidth = 384; font._justifyHeight = 100; font._pos = Common::Point(128, 100); - _graphicsManager->_vPort->drawText(END_OF_MESSAGE); + _screen->_vPort->drawText(END_OF_MESSAGE); } else if (_voy->_RTVNum < _voy->_computerTimeMin && maxLen == 9999) { if (_currentVocId != -1) _soundManager->startVOCPlay(_currentVocId); @@ -1188,7 +1188,7 @@ int VoyeurEngine::doComputerText(int maxLen) { font._justifyWidth = 384; font._justifyHeight = 100; font._pos = Common::Point(120, 100); - _graphicsManager->_vPort->drawText(START_OF_MESSAGE); + _screen->_vPort->drawText(START_OF_MESSAGE); } else { char *msg = (char *)_bVoy->memberAddr(0x4900 + _voy->_computerTextId); font._pos = Common::Point(96, 60); @@ -1206,14 +1206,14 @@ int VoyeurEngine::doComputerText(int maxLen) { if (c == '\0') { if (showEnd) { _eventsManager->delay(90); - _graphicsManager->_drawPtr->_pos = Common::Point(96, 54); - _graphicsManager->_drawPtr->_penColor = 254; - _graphicsManager->_vPort->sFillBox(196, 124); - _graphicsManager->_fontPtr->_justify = ALIGN_LEFT; - _graphicsManager->_fontPtr->_justifyWidth = 384; - _graphicsManager->_fontPtr->_justifyHeight = 100; - _graphicsManager->_fontPtr->_pos = Common::Point(128, 100); - _graphicsManager->_vPort->drawText(END_OF_MESSAGE); + _screen->_drawPtr->_pos = Common::Point(96, 54); + _screen->_drawPtr->_penColor = 254; + _screen->_vPort->sFillBox(196, 124); + _screen->_fontPtr->_justify = ALIGN_LEFT; + _screen->_fontPtr->_justifyWidth = 384; + _screen->_fontPtr->_justifyHeight = 100; + _screen->_fontPtr->_pos = Common::Point(128, 100); + _screen->_vPort->drawText(END_OF_MESSAGE); } break; } @@ -1223,20 +1223,20 @@ int VoyeurEngine::doComputerText(int maxLen) { yp += 10; } else { _eventsManager->delay(90); - _graphicsManager->_drawPtr->_pos = Common::Point(96, 54); - _graphicsManager->_drawPtr->_penColor = 255; - _graphicsManager->_vPort->sFillBox(196, 124); + _screen->_drawPtr->_pos = Common::Point(96, 54); + _screen->_drawPtr->_penColor = 255; + _screen->_vPort->sFillBox(196, 124); yp = 60; } - _graphicsManager->_fontPtr->_pos = Common::Point(96, yp); + _screen->_fontPtr->_pos = Common::Point(96, yp); } else if (c == '_') { showEnd = false; } else { - _graphicsManager->_fontPtr->_justify = ALIGN_LEFT; - _graphicsManager->_fontPtr->_justifyWidth = 0; - _graphicsManager->_fontPtr->_justifyHeight = 0; - _graphicsManager->_vPort->drawText(Common::String(c)); + _screen->_fontPtr->_justify = ALIGN_LEFT; + _screen->_fontPtr->_justifyWidth = 0; + _screen->_fontPtr->_justifyHeight = 0; + _screen->_vPort->drawText(Common::String(c)); _eventsManager->delay(4); } @@ -1251,7 +1251,7 @@ int VoyeurEngine::doComputerText(int maxLen) { flipPageAndWait(); - _graphicsManager->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; + _screen->_fontPtr->_curFont = _bVoy->boltEntry(0x101)._fontResource; return totalChars; } @@ -1263,7 +1263,7 @@ void VoyeurEngine::getComputerBrush() { int xp = (384 - pic->_bounds.width()) / 2; int yp = (240 - pic->_bounds.height()) / 2 - 4; - _graphicsManager->_vPort->drawPicPerm(pic, Common::Point(xp, yp)); + _screen->_vPort->drawPicPerm(pic, Common::Point(xp, yp)); CMapResource *pal = _bVoy->boltEntry(0x490F)._cMapResource; pal->startFade(); @@ -1280,17 +1280,17 @@ void VoyeurEngine::doTimeBar() { int height = ((_voy->_RTVLimit - _voy->_RTVNum) * 59) / _voy->_RTVLimit; int fullHeight = MAX(151 - height, 93); - _graphicsManager->_drawPtr->_penColor = 134; - _graphicsManager->_drawPtr->_pos = Common::Point(39, 92); + _screen->_drawPtr->_penColor = 134; + _screen->_drawPtr->_pos = Common::Point(39, 92); - _graphicsManager->_vPort->sFillBox(6, fullHeight - 92); + _screen->_vPort->sFillBox(6, fullHeight - 92); if (height > 0) { - _graphicsManager->setColor(215, 238, 238, 238); + _screen->setColor(215, 238, 238, 238); _eventsManager->_intPtr._hasPalette = true; - _graphicsManager->_drawPtr->_penColor = 215; - _graphicsManager->_drawPtr->_pos = Common::Point(39, fullHeight); - _graphicsManager->_vPort->sFillBox(6, height); + _screen->_drawPtr->_penColor = 215; + _screen->_drawPtr->_pos = Common::Point(39, fullHeight); + _screen->_vPort->sFillBox(6, height); } } } @@ -1303,9 +1303,9 @@ void VoyeurEngine::flashTimeBar() { _flashTimeVal = _eventsManager->_intPtr._flashTimer; if (_flashTimeFlag) - _graphicsManager->setColor(240, 220, 20, 20); + _screen->setColor(240, 220, 20, 20); else - _graphicsManager->setColor(240, 220, 220, 220); + _screen->setColor(240, 220, 220, 220); _eventsManager->_intPtr._hasPalette = true; _flashTimeFlag = !_flashTimeFlag; @@ -1343,7 +1343,7 @@ void VoyeurEngine::doEvidDisplay(int evidId, int eventId) { _bVoy->getBoltGroup(_voy->_boltGroupId2); PictureResource *pic = _bVoy->boltEntry(_voy->_boltGroupId2 + evidId * 2)._picResource; - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, Common::Point( + _screen->sDrawPic(pic, _screen->_vPort, Common::Point( (384 - pic->_bounds.width()) / 2, (240 - pic->_bounds.height()) / 2)); _bVoy->freeBoltMember(_voy->_boltGroupId2 + evidId * 2); @@ -1394,7 +1394,7 @@ void VoyeurEngine::doEvidDisplay(int evidId, int eventId) { continue; pic = _voy->_evPicPtrs[arrIndex]; - _graphicsManager->sDrawPic(pic, _graphicsManager->_vPort, + _screen->sDrawPic(pic, _screen->_vPort, Common::Point((384 - pic->_bounds.width()) / 2, (240 - pic->_bounds.height()) / 2)); _voy->_evCmPtrs[arrIndex]->startFade(); diff --git a/engines/wage/debugger.cpp b/engines/wage/debugger.cpp new file mode 100644 index 0000000000..7d01b0b85e --- /dev/null +++ b/engines/wage/debugger.cpp @@ -0,0 +1,97 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/file.h" +#include "wage/wage.h" +#include "wage/debugger.h" +#include "wage/entities.h" +#include "wage/script.h" +#include "wage/world.h" + +namespace Wage { + +Debugger::Debugger(WageEngine *engine) : GUI::Debugger(), _engine(engine) { + registerCmd("continue", WRAP_METHOD(Debugger, cmdExit)); + registerCmd("scenes", WRAP_METHOD(Debugger, Cmd_ListScenes)); + registerCmd("script", WRAP_METHOD(Debugger, Cmd_Script)); +} + +Debugger::~Debugger() { +} + +static int strToInt(const char *s) { + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; +} + +bool Debugger::Cmd_ListScenes(int argc, const char **argv) { + int currentScene; + + for (uint i = 1; i < _engine->_world->_orderedScenes.size(); i++) { // #0 is STORAGE@ + if (_engine->_world->_player->_currentScene == _engine->_world->_orderedScenes[i]) + currentScene = i; + + debugPrintf("%d: %s\n", i, _engine->_world->_orderedScenes[i]->_name.c_str()); + } + + debugPrintf("\nCurrent scene is #%d: %s\n", currentScene, _engine->_world->_orderedScenes[currentScene]->_name.c_str()); + + return true; +} + +bool Debugger::Cmd_Script(int argc, const char **argv) { + Script *script = _engine->_world->_player->_currentScene->_script; + + if (argc >= 2) { + int scriptNum = strToInt(argv[1]); + + if (scriptNum) + script = _engine->_world->_orderedScenes[scriptNum]->_script; + else + script = _engine->_world->_globalScript; + } + + if (script == NULL) { + debugPrintf("There is no script for current scene\n"); + return true; + } + + for (uint i = 0; i < script->_scriptText.size(); i++) { + debugPrintf("%d [%04x]: %s\n", i, script->_scriptText[i]->offset, script->_scriptText[i]->line.c_str()); + } + + return true; +} + +} // End of namespace Wage diff --git a/engines/wage/debugger.h b/engines/wage/debugger.h new file mode 100644 index 0000000000..90687760cb --- /dev/null +++ b/engines/wage/debugger.h @@ -0,0 +1,47 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef WAGE_DEBUGGER_H +#define WAGE_DEBUGGER_H + +#include "common/scummsys.h" +#include "gui/debugger.h" + +namespace Wage { + +class WageEngine; + +class Debugger : public GUI::Debugger { +protected: + WageEngine *_engine; + + bool Cmd_ListScenes(int argc, const char **argv); + bool Cmd_Script(int argc, const char **argv); + +public: + Debugger(WageEngine *engine); + virtual ~Debugger(); +}; + +} // End of namespace Wage + +#endif diff --git a/engines/wage/design.cpp b/engines/wage/design.cpp index 220acae05a..907a1ec435 100644 --- a/engines/wage/design.cpp +++ b/engines/wage/design.cpp @@ -87,16 +87,14 @@ void Design::paint(Graphics::Surface *surface, Patterns &patterns, int x, int y) bool needRender = false; if (_surface == NULL) { - //_boundsCalculationMode = true; + _boundsCalculationMode = true; _bounds->debugPrint(4, "Internal bounds:"); - //_bounds->left = _bounds->top = 10000; - //_bounds->right =_bounds->bottom = -10000; - //render(patterns); + render(patterns); _boundsCalculationMode = false; if (_bounds->right == -10000) { _bounds->left = _bounds->top = _bounds->right = _bounds->bottom = 0; } - //_bounds->debugPrint(4, "Calculated bounds:"); + _bounds->debugPrint(4, "Calculated bounds:"); _surface = new Graphics::Surface; _surface->create(_bounds->width(), _bounds->height(), Graphics::PixelFormat::createFormatCLUT8()); @@ -201,9 +199,7 @@ bool Design::isPointOpaque(int x, int y) { } void Design::adjustBounds(int16 x, int16 y) { - _bounds->left = MIN(x, _bounds->left); _bounds->right = MAX(x, _bounds->right); - _bounds->top = MIN(y, _bounds->top); _bounds->bottom = MAX(y, _bounds->bottom); } diff --git a/engines/wage/detection.cpp b/engines/wage/detection.cpp index fcecb8d2b0..512d432e54 100644 --- a/engines/wage/detection.cpp +++ b/engines/wage/detection.cpp @@ -41,6 +41,7 @@ static const PlainGameDescriptor wageGames[] = { {"afm", "Another Fine Mess"}, {"amot", "A Mess O' Trouble"}, {"cantitoe", "Camp Cantitoe"}, + {"drakmythcastle", "Drakmyth Castle"}, {"raysmaze", "Ray's Maze"}, {"scepters", "Enchanted Scepters"}, {"twisted", "Twisted!"}, diff --git a/engines/wage/detection_tables.h b/engines/wage/detection_tables.h index 18ba8970ed..e164ea70cd 100644 --- a/engines/wage/detection_tables.h +++ b/engines/wage/detection_tables.h @@ -23,10 +23,12 @@ namespace Wage { #define ADGF_DEFAULT (ADGF_DROPLANGUAGE|ADGF_DROPPLATFORM|ADGF_MACRESFORK) -#define ADGF_GENERIC (ADGF_DROPLANGUAGE|ADGF_DROPPLATFORM|ADGF_USEEXTRAASTITLE|ADGF_AUTOGENTARGET|ADGF_MACRESFORK) +#define ADGF_GENERIC (ADGF_DEFAULT|ADGF_USEEXTRAASTITLE|ADGF_AUTOGENTARGET) +#define ADGF_DEMO (ADGF_GENERIC|ADGF_DEMO) #define FANGAME(n,m,s) { "wage",n,AD_ENTRY1s(n,m,s),Common::EN_ANY,Common::kPlatformMacintosh,ADGF_GENERIC,GUIO0()} #define FANGAMEN(n,f,m,s) { "wage",n,AD_ENTRY1s(f,m,s),Common::EN_ANY,Common::kPlatformMacintosh,ADGF_GENERIC,GUIO0()} +#define FANGAMEND(n,f,m,s) { "wage",n,AD_ENTRY1s(f,m,s),Common::EN_ANY,Common::kPlatformMacintosh,ADGF_DEMO,GUIO0()} #define BIGGAME(t,v,f,m,s) { t,v,AD_ENTRY1s(f,m,s),Common::EN_ANY,Common::kPlatformMacintosh,ADGF_DEFAULT,GUIO0()} static const ADGameDescription gameDescriptions[] = { @@ -37,11 +39,17 @@ static const ADGameDescription gameDescriptions[] = { BIGGAME("cantitoe", "", "Camp Cantitoe", "913812a1ac7a6b0e48dadd1afa1c7763", 616985), // Problems with letter rendering FANGAME("Canal District", "a56aa3cd4a6e070e15ce1d5815c7be0a", 641470), + FANGAME("Carbon Copy", "913812a1ac7a6b0e48dadd1afa1c7763", 519445), // Invalid rect in scene "FINALE" FANGAME("Castle of Ert", "327610eb2298a9427a566288312df040", 198955), FANGAME("Deep Angst", "b130b3c811cd89024dd5fdd2b71f70b8", 329550), + FANGAME("Deep Ennui", "913812a1ac7a6b0e48dadd1afa1c7763", 86075), // Polygons with ignored byte 1 FANGAME("Double Trouble", "1652e36857a04c01dc560234c4818619", 542371), + BIGGAME("drakmythcastle", "disk I", "Drakmyth Castle disk I of II", "94a9c4f8b3dabd1846d76215a49bd221", 793784), + BIGGAME("drakmythcastle", "disk II", "Drakmyth Castle II", "cc978cc9a5256724702463cb5aaaffa0", 1685659), + // Crash at start in GUI rendering + FANGAME("Dune Eternity", "94a9c4f8b3dabd1846d76215a49bd221", 290201), // Original file name is "***DUNE ETERNITY*** " FANGAMEN("Dungeon World II", "DungeonWorld2", "0154ea11d3cbb536c13b4ae9e6902d48", 230199), FANGAME("Eidisi I", "595117cbed33e8de1ab3714b33880205", 172552), // Problems(?) with text on the first screen @@ -51,15 +59,24 @@ static const ADGameDescription gameDescriptions[] = { // Crash in console rendering on the first scene FANGAME("Fantasy Quest", "4b0e1a1fbaaa4930accd0f9f0e1519c7", 762754), FANGAME("Find the Heart", "595117cbed33e8de1ab3714b33880205", 106235), // From Joshua's Worlds 1.0 + // Problems with window overlay + FANGAMEN("Jumble", "LSJUMBLE", "e12ec4d76d48bdc86567c5e63750547e", 647339), // Original file name is "LSJUMBLE† " FANGAME("Karth of the Jungle", "595117cbed33e8de1ab3714b33880205", 96711), FANGAME("Karth of the Jungle", "595117cbed33e8de1ab3714b33880205", 96960), // Alternative version FANGAME("Karth of the Jungle II", "c106835ab4436de054e03aec3ce904ce", 201053), FANGAMEN("Little Pythagoras", "Little Pythagoras 1.1.1", "94a9c4f8b3dabd1846d76215a49bd221", 628821), FANGAME("Lost Crystal", "8174c81ea1858d0079ae040dae2cefd3", 771072), FANGAME("Magic Rings", "913812a1ac7a6b0e48dadd1afa1c7763", 109044), + // No way to click on the house + FANGAME("Messy House", "913812a1ac7a6b0e48dadd1afa1c7763", 177120), FANGAME("Midnight Snack", "913812a1ac7a6b0e48dadd1afa1c7763", 67952), + FANGAME("Midnight Snack", "913812a1ac7a6b0e48dadd1afa1c7763", 67966), // Alt version FANGAME("Minitorian", "913812a1ac7a6b0e48dadd1afa1c7763", 586464), + // No way to pass through the first screen + FANGAME("Nightcrawler Ned", "94a9c4f8b3dabd1846d76215a49bd221", 366542), FANGAME("Pavilion", "4d991d7d1534d48d90598d86ea6d5d97", 231687), + // Polygons with byte 1 + FANGAME("Periapt", "913812a1ac7a6b0e48dadd1afa1c7763", 406006), FANGAME("Puzzle Piece Search", "595117cbed33e8de1ab3714b33880205", 247693), // From Joshua's Worlds 1.0 // Empty(?) first scene FANGAME("Pyramid of No Return", "77a55a45f794b4d4a56703d3acce871e", 385145), @@ -67,27 +84,36 @@ static const ADGameDescription gameDescriptions[] = { FANGAME("Quest for T-Rex", "913812a1ac7a6b0e48dadd1afa1c7763", 592584), // Crash in console rendering on the initial scene FANGAME("Quest for the Dark Sword", "b35dd0c078da9f35fc25a455f56bb129", 572576), + FANGAME("Radical Castle", "677bfee4afeca2f7152eb8b76c85ca8d", 355601), FANGAME("Radical Castle 1.0", "677bfee4afeca2f7152eb8b76c85ca8d", 347278), BIGGAME("raysmaze", "v1.5", "Ray's Maze1.5", "064b16d8c20724f8debbbdc3aafde538", 1408516), BIGGAME("raysmaze", "v1.5/alt", "Ray's Maze1.5", "92cca777800c3d31a77b5ed7f6ee49ad", 1408516), BIGGAME("scepters", "", "Scepters", "3311deef8bf82f0b4b1cfa15a3b3289d", 346595), // ??? problems with dog bitmap? FANGAMEN("Space Adventure", "SpaceAdventure", "f9f3f1c419f56955f7966355b34ea5c8", 155356), + FANGAMEN("Spear of Destiny", "SpearOfDestiny", "913812a1ac7a6b0e48dadd1afa1c7763", 333665), // Original file name "SpearOfDestiny†" FANGAME("Star Trek", "44aaef4806578700429de5aaf95c266e", 53320), - // Crash in bitmap drawing on the first scene FANGAME("Strange Disappearance", "d81f2d03a1e863f04fb1e3a5495b720e", 772282), + // Code 0x03 in text + FANGAME("Swamp Witch", "913812a1ac7a6b0e48dadd1afa1c7763", 739781), // Original file name "Swamp Witch†" + FANGAME("Sweetspace Now!", "e12ec4d76d48bdc86567c5e63750547e", 123813), // Comes with Jumble FANGAME("Time Bomb", "4b0e1a1fbaaa4930accd0f9f0e1519c7", 64564), + FANGAME("Time Bomb", "4b0e1a1fbaaa4930accd0f9f0e1519c7", 64578), // Alt version + FANGAMEND("The Ashland Revolution", "The Ashland Revolution Demo", "913812a1ac7a6b0e48dadd1afa1c7763", 145023), // Original file name "The Ashland Revolution Demo†" FANGAMEN("The Hotel Caper", "The Hotel Caper V1.0", "595117cbed33e8de1ab3714b33880205", 231969), // Invalid rect in scene "Access Tube 1" FANGAMEN("The Phoenix v1.2", "The Phoenix", "4b0e1a1fbaaa4930accd0f9f0e1519c7", 431640), FANGAME("The Sultan's Palace", "358799d446ee4fc12f793febd6c94b95", 456855), // Admission for on 3rd screen is messed up FANGAME("The Tower", "435f420b9dff895ae1ddf1338040c51d", 556539), + // Polygons with ignored byte 1 and 2 on second scene + FANGAME("The Village", "913812a1ac7a6b0e48dadd1afa1c7763", 314828), // Doesn't go past first scene BIGGAME("twisted", "", "Twisted! 1.6", "26207bdf0bb539464f136f0669af885f", 960954), FANGAME("Wishing Well", "913812a1ac7a6b0e48dadd1afa1c7763", 103688), FANGAME("Wizard's Warehouse", "913812a1ac7a6b0e48dadd1afa1c7763", 159748), FANGAME("ZikTuria", "418e74ca71029a1e9db80d0eb30c0843", 52972), + FANGAME("Zoony", "539a64151426edc92da5eedadf39f23c", 154990), // original filename "Zoony™" AD_TABLE_END_MARKER }; diff --git a/engines/wage/gui.cpp b/engines/wage/gui.cpp index 387731cc18..9dd1a24b3c 100644 --- a/engines/wage/gui.cpp +++ b/engines/wage/gui.cpp @@ -294,10 +294,10 @@ void Gui::drawBox(Graphics::Surface *g, int x, int y, int w, int h) { g->frameRect(r, kColorBlack); } -void Gui::fillRect(Graphics::Surface *g, int x, int y, int w, int h) { +void Gui::fillRect(Graphics::Surface *g, int x, int y, int w, int h, int color) { Common::Rect r(x, y, x + w, y + h); - g->fillRect(r, kColorBlack); + g->fillRect(r, color); } #define ARROW_W 12 @@ -310,8 +310,8 @@ const int arrowPixels[ARROW_H][ARROW_W] = { {0,1,1,1,1,1,1,1,1,1,1,0}, {1,1,1,1,1,1,1,1,1,1,1,1}}; -void Gui::paintBorder(Graphics::Surface *g, Common::Rect &r, WindowType windowType) { - bool active = false, scrollable = false, closeable = false, closeBoxPressed = false, drawTitle = false; +void Gui::paintBorder(Graphics::Surface *g, Common::Rect &r, WindowType windowType, int highlightedPart) { + bool active = false, scrollable = false, closeable = false, drawTitle = false; const int size = kBorderWidth; int x = r.left - size; int y = r.top - size; @@ -323,14 +323,12 @@ void Gui::paintBorder(Graphics::Surface *g, Common::Rect &r, WindowType windowTy active = _sceneIsActive; scrollable = false; closeable = _sceneIsActive; - closeBoxPressed = false; drawTitle = true; break; case kWindowConsole: active = !_sceneIsActive; scrollable = true; closeable = !_sceneIsActive; - closeBoxPressed = false; drawTitle = false; break; } @@ -353,29 +351,43 @@ void Gui::paintBorder(Graphics::Surface *g, Common::Rect &r, WindowType windowTy } else { int x1 = x + width - 15; int y1 = y + size + 1; + int color1 = kColorBlack; + int color2 = kColorWhite; + if (highlightedPart == kBorderScrollUp) { + SWAP(color1, color2); + fillRect(g, x + width - kBorderWidth + 2, y + size, size - 4, r.height() / 2); + } for (int yy = 0; yy < ARROW_H; yy++) { for (int xx = 0; xx < ARROW_W; xx++) { if (arrowPixels[yy][xx] != 0) { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorBlack); + g->hLine(x1 + xx, y1 + yy, x1 + xx, color1); } else { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorWhite); + g->hLine(x1 + xx, y1 + yy, x1 + xx, color2); } } } - fillRect(g, x + width - 13, y + size + ARROW_H, 8, height - 2 * size - 1 - ARROW_H * 2); + fillRect(g, x + width - 13, y + size + ARROW_H, 8, r.height() / 2 - ARROW_H, color1); + + color1 = kColorBlack; + color2 = kColorWhite; + if (highlightedPart == kBorderScrollDown) { + SWAP(color1, color2); + fillRect(g, x + width - kBorderWidth + 2, y + size + r.height() / 2, size - 4, r.height() / 2); + } + fillRect(g, x + width - 13, y + size + r.height() / 2, 8, r.height() / 2 - ARROW_H, color1); y1 += height - 2 * size - ARROW_H - 2; for (int yy = 0; yy < ARROW_H; yy++) { for (int xx = 0; xx < ARROW_W; xx++) { if (arrowPixels[ARROW_H - yy - 1][xx] != 0) { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorBlack); + g->hLine(x1 + xx, y1 + yy, x1 + xx, color1); } else { - g->hLine(x1 + xx, y1 + yy, x1 + xx, kColorWhite); + g->hLine(x1 + xx, y1 + yy, x1 + xx, color2); } } } } if (closeable) { - if (closeBoxPressed) { + if (highlightedPart == kBorderCloseButton) { fillRect(g, x + 6, y + 6, 6, 6); } else { drawBox(g, x + 5, y + 5, 7, 7); @@ -499,6 +511,26 @@ void Gui::popCursor() { CursorMan.popCursor(); } +static int isInBorder(Common::Rect &rect, int x, int y) { + if (x >= rect.left - kBorderWidth && x < rect.left && y >= rect.top - kBorderWidth && y < rect.top) + return kBorderCloseButton; + + if (x >= rect.right && x < rect.right + kBorderWidth) { + if (y < rect.top - kBorderWidth) + return kBorderNone; + + if (y >= rect.bottom + kBorderWidth) + return kBorderNone; + + if (y >= rect.top + rect.height() / 2) + return kBorderScrollDown; + + return kBorderScrollUp; + } + + return kBorderNone; +} + Designed *Gui::mouseUp(int x, int y) { if (_menu->_menuActivated) { if (_menu->mouseRelease(x, y)) { @@ -532,6 +564,8 @@ Designed *Gui::mouseUp(int x, int y) { } } + int borderClick; + if (_sceneArea.contains(x, y)) { if (!_sceneIsActive) { _sceneIsActive = true; @@ -552,16 +586,40 @@ Designed *Gui::mouseUp(int x, int y) { _sceneIsActive = false; _bordersDirty = true; } + } else if ((borderClick = isInBorder(_consoleTextArea, x, y)) != kBorderNone) { + _bordersDirty = true; + int _oldScrollPos = _scrollPos; + + switch (borderClick) { + case kBorderScrollUp: + _scrollPos = MAX<int>(0, _scrollPos - _consoleLineHeight); + undrawCursor(); + _cursorY -= (_scrollPos - _oldScrollPos); + _consoleDirty = true; + _consoleFullRedraw = true; + break; + case kBorderScrollDown: + _scrollPos = MIN<int>((_lines.size() - 2) * _consoleLineHeight, _scrollPos + _consoleLineHeight); + undrawCursor(); + _cursorY -= (_scrollPos - _oldScrollPos); + _consoleDirty = true; + _consoleFullRedraw = true; + break; + } } return NULL; } void Gui::mouseDown(int x, int y) { + int borderClick; + if (_menu->mouseClick(x, y)) { _menuDirty = true; } else if (_consoleTextArea.contains(x, y)) { startMarking(x, y); + } else if ((borderClick = isInBorder(_consoleTextArea, x, y)) != kBorderNone) { + paintBorder(&_screen, _consoleTextArea, kWindowConsole, borderClick); } } diff --git a/engines/wage/gui.h b/engines/wage/gui.h index 61f8c31a07..73814d39b4 100644 --- a/engines/wage/gui.h +++ b/engines/wage/gui.h @@ -84,6 +84,13 @@ enum { kPatternCheckers2 = 4 }; +enum { + kBorderNone = 0, + kBorderScrollUp, + kBorderScrollDown, + kBorderCloseButton +}; + class Gui { public: Gui(WageEngine *engine); @@ -116,10 +123,10 @@ public: private: void undrawCursor(); void drawDesktop(); - void paintBorder(Graphics::Surface *g, Common::Rect &r, WindowType windowType); + void paintBorder(Graphics::Surface *g, Common::Rect &r, WindowType windowType, int highlightedPart = kBorderNone); void renderConsole(Graphics::Surface *g, Common::Rect &r); void drawBox(Graphics::Surface *g, int x, int y, int w, int h); - void fillRect(Graphics::Surface *g, int x, int y, int w, int h); + void fillRect(Graphics::Surface *g, int x, int y, int w, int h, int color = kColorBlack); void loadFonts(); void flowText(Common::String &str); const Graphics::Font *getConsoleFont(); diff --git a/engines/wage/menu.cpp b/engines/wage/menu.cpp index 48f16421b5..12ef8c2219 100644 --- a/engines/wage/menu.cpp +++ b/engines/wage/menu.cpp @@ -206,10 +206,10 @@ void Menu::createCommandsMenu(MenuItem *menu) { char shortcut = 0; const char *shortPtr = strrchr(item.c_str(), '/'); if (shortPtr != NULL) { - if (strlen(shortPtr) == 2) { + if (strlen(shortPtr) >= 2) { shortcut = shortPtr[1]; - item.deleteLastChar(); - item.deleteLastChar(); + item.deleteChar(shortPtr - item.c_str()); + item.deleteChar(shortPtr - item.c_str()); } else { error("Unexpected shortcut: '%s', item '%s' in menu '%s'", shortPtr, item.c_str(), string.c_str()); } diff --git a/engines/wage/module.mk b/engines/wage/module.mk index 548e440c28..21316bbf83 100644 --- a/engines/wage/module.mk +++ b/engines/wage/module.mk @@ -2,6 +2,7 @@ MODULE := engines/wage MODULE_OBJS := \ combat.o \ + debugger.o \ design.o \ detection.o \ dialog.o \ diff --git a/engines/wage/script.cpp b/engines/wage/script.cpp index bd99fa1d86..294c08ed82 100644 --- a/engines/wage/script.cpp +++ b/engines/wage/script.cpp @@ -1124,7 +1124,7 @@ void Script::convertToText() { if (c < 0x80) { if (c < 0x20) - error("Unknown code 0x%02x at %d", c, _data->pos()); + error("convertToText: Unknown code 0x%02x at %d", c, _data->pos()); do { scr->line += c; diff --git a/engines/wage/script.h b/engines/wage/script.h index 325733add7..de9476228c 100644 --- a/engines/wage/script.h +++ b/engines/wage/script.h @@ -150,8 +150,10 @@ private: void assign(byte operandType, int uservar, uint16 value); - Common::Array<ScriptText *> _scriptText; void convertToText(); + +public: + Common::Array<ScriptText *> _scriptText; }; } // End of namespace Wage diff --git a/engines/wage/wage.cpp b/engines/wage/wage.cpp index b708cff134..e0299c8da2 100644 --- a/engines/wage/wage.cpp +++ b/engines/wage/wage.cpp @@ -102,12 +102,14 @@ WageEngine::~WageEngine() { } Common::Error WageEngine::run() { + debug("WageEngine::init"); + initGraphics(512, 342, true); // Create debugger console. It requires GFX to be initialized _console = new Console(this); - debug("WageEngine::init"); + _debugger = new Debugger(this); // Your main event loop should be (invoked from) here. _resManager = new Common::MacResManager(); @@ -130,6 +132,8 @@ Common::Error WageEngine::run() { _shouldQuit = false; while (!_shouldQuit) { + _debugger->onFrame(); + processEvents(); _gui->draw(); @@ -180,6 +184,11 @@ void WageEngine::processEvents() { break; default: + if (event.kbd.ascii == '~') { + _debugger->attach(); + break; + } + if (event.kbd.flags & (Common::KBD_ALT | Common::KBD_CTRL | Common::KBD_META)) { if (event.kbd.ascii >= 0x20 && event.kbd.ascii <= 0x7f) { _gui->processMenuShortCut(event.kbd.flags, event.kbd.ascii); diff --git a/engines/wage/wage.h b/engines/wage/wage.h index 6905fdc530..8ca306aea3 100644 --- a/engines/wage/wage.h +++ b/engines/wage/wage.h @@ -50,12 +50,13 @@ #include "engines/engine.h" #include "common/debug.h" -#include "gui/debugger.h" #include "common/endian.h" #include "common/rect.h" #include "common/macresman.h" #include "common/random.h" +#include "wage/debugger.h" + struct ADGameDescription; namespace Wage { @@ -181,6 +182,8 @@ public: public: Common::RandomSource *_rnd; + Debugger *_debugger; + Gui *_gui; World *_world; @@ -212,6 +215,8 @@ public: void redrawScene(); void saveGame(); + virtual GUI::Debugger *getDebugger() { return _debugger; } + private: Console *_console; |