From 0c283ed197d839cb81e5957424833700ada1c4ae Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 30 Jun 2010 10:13:20 +0000 Subject: [PATCH] Replaced Y offset from various drawing routines in favour of a viewport sub-surface - this will make it easier to clip sprites to within the drawable area svn-id: r50523 --- engines/m4/graphics.cpp | 3 ++- engines/m4/graphics.h | 14 ++++++++++++++ engines/m4/mads_anim.cpp | 2 +- engines/m4/mads_views.cpp | 38 ++++++++++++++++++++++++-------------- engines/m4/mads_views.h | 11 ++++++----- 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/engines/m4/graphics.cpp b/engines/m4/graphics.cpp index 43df6e1b5f5..56c40a7402d 100644 --- a/engines/m4/graphics.cpp +++ b/engines/m4/graphics.cpp @@ -74,7 +74,8 @@ M4Surface::~M4Surface() { _madsVm->_palette->deleteRange(_rgbList); delete _rgbList; } - free(); + if (_ownsData) + free(); } void M4Surface::loadCodesM4(Common::SeekableReadStream *source) { diff --git a/engines/m4/graphics.h b/engines/m4/graphics.h index 96cd039e274..5e97d4f09b0 100644 --- a/engines/m4/graphics.h +++ b/engines/m4/graphics.h @@ -97,6 +97,7 @@ private: byte _color; bool _isScreen; RGBList *_rgbList; + bool _ownsData; void rexLoadBackground(Common::SeekableReadStream *source, RGBList **palData = NULL); void madsLoadBackground(int roomNumber, RGBList **palData = NULL); @@ -106,12 +107,24 @@ public: create(g_system->getWidth(), isScreen ? g_system->getHeight() : MADS_SURFACE_HEIGHT, 1); _isScreen = isScreen; _rgbList = NULL; + _ownsData = true; } M4Surface(int width_, int height_) { create(width_, height_, 1); _isScreen = false; _rgbList = NULL; + _ownsData = true; } + M4Surface(int width_, int height_, byte *srcPixels, int pitch_) { + bytesPerPixel = 1; + w = width_; + h = height_; + pitch = pitch_; + pixels = srcPixels; + _rgbList = NULL; + _ownsData = false; + } + virtual ~M4Surface(); // loads a .COD file into the M4Surface @@ -143,6 +156,7 @@ public: inline Common::Rect bounds() const { return Common::Rect(0, 0, width(), height()); } inline int width() const { return w; } inline int height() const { return h; } + inline int getPitch() const { return pitch; } void setSize(int sizeX, int sizeY) { create(sizeX, sizeY, 1); } inline byte *getBasePtr() { return (byte *)pixels; diff --git a/engines/m4/mads_anim.cpp b/engines/m4/mads_anim.cpp index ebc684bec44..ca53bdca75c 100644 --- a/engines/m4/mads_anim.cpp +++ b/engines/m4/mads_anim.cpp @@ -446,7 +446,7 @@ AnimviewView::AnimviewView(MadsM4Engine *vm): MadsView::_bgSurface = &_backgroundSurface; MadsView::_depthSurface = &_codeSurface; - MadsView::_yOffset = MADS_Y_OFFSET; + MadsView::setViewport(Common::Rect(0, MADS_Y_OFFSET, MADS_SURFACE_WIDTH, MADS_Y_OFFSET + MADS_SURFACE_HEIGHT)); _screenType = VIEWID_ANIMVIEW; _screenFlags.layer = LAYER_BACKGROUND; diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index 1766603dc8a..c9aacbad4e4 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -133,7 +133,7 @@ bool sortHelper(const DepthEntry &entry1, const DepthEntry &entry2) { typedef Common::List DepthList; -void MadsSpriteSlots::drawBackground(int yOffset) { +void MadsSpriteSlots::drawBackground() { // Draw all active sprites onto the background surface for (int i = 0; i < startIndex; ++i) { MadsSpriteSlot &slot = _entries[i]; @@ -173,7 +173,7 @@ void MadsSpriteSlots::drawBackground(int yOffset) { _owner._dirtyAreas[i].active = false; } -void MadsSpriteSlots::drawForeground(View *view, int yOffset) { +void MadsSpriteSlots::drawForeground(M4Surface *viewport) { DepthList depthList; // Get a list of sprite object depths for active objects @@ -199,7 +199,7 @@ void MadsSpriteSlots::drawForeground(View *view, int yOffset) { // Minimalised drawing assert(slot.spriteListIndex < (int)_sprites.size()); M4Sprite *spr = spriteSet.getFrame((slot.frameNumber & 0x7fff) - 1); - view->copyFrom(spr, slot.xp, slot.yp, Common::Point(0, yOffset), slot.depth, _owner._depthSurface, + viewport->copyFrom(spr, slot.xp, slot.yp, Common::Point(0, 0), slot.depth, _owner._depthSurface, slot.scale, spr->getTransparencyIndex()); } else { int xp, yp; @@ -215,11 +215,11 @@ void MadsSpriteSlots::drawForeground(View *view, int yOffset) { if (slot.depth > 1) { // Draw the frame with depth processing - view->copyFrom(spr, xp, yp, Common::Point(0, yOffset), slot.depth, _owner._depthSurface, 100, + viewport->copyFrom(spr, xp, yp, Common::Point(0, 0), slot.depth, _owner._depthSurface, 100, spr->getTransparencyIndex()); } else { // No depth, so simply draw the image - spr->copyTo(view, xp, yp + yOffset, spr->getTransparencyIndex()); + spr->copyTo(viewport, xp, yp, spr->getTransparencyIndex()); } } } @@ -332,12 +332,12 @@ void MadsTextDisplay::setDirtyAreas2() { } } -void MadsTextDisplay::draw(View *view, int yOffset) { +void MadsTextDisplay::draw(M4Surface *view) { for (uint idx = 0; idx < _entries.size(); ++idx) { if (_entries[idx].active && (_entries[idx].expire >= 0)) { _entries[idx].font->setColours(_entries[idx].colour1, _entries[idx].colour2, 0); _entries[idx].font->writeString(view, _entries[idx].msg, - _entries[idx].bounds.left, _entries[idx].bounds.top + yOffset, _entries[idx].bounds.width(), + _entries[idx].bounds.left, _entries[idx].bounds.top, _entries[idx].bounds.width(), _entries[idx].spacing); } } @@ -859,7 +859,7 @@ void MadsDirtyAreas::mergeAreas(int idx1, int idx2) { da1.textActive = true; } -void MadsDirtyAreas::copy(M4Surface *dest, M4Surface *src, int yOffset, const Common::Point &posAdjust) { +void MadsDirtyAreas::copy(M4Surface *dest, M4Surface *src, const Common::Point &posAdjust) { for (uint i = 0; i < _entries.size(); ++i) { const Common::Rect &srcBounds = _entries[i].bounds; @@ -867,7 +867,7 @@ void MadsDirtyAreas::copy(M4Surface *dest, M4Surface *src, int yOffset, const Co srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y); if (_entries[i].active && _entries[i].bounds.isValidRect()) - src->copyTo(dest, bounds, _entries[i].bounds.left, _entries[i].bounds.top + yOffset); + src->copyTo(dest, bounds, _entries[i].bounds.left, _entries[i].bounds.top); } } @@ -1195,20 +1195,24 @@ MadsView::MadsView(View *view): _view(view), _dynamicHotspots(*this), _sequenceL _abortTimersMode = ABORTMODE_0; _abortTimersMode2 = ABORTMODE_0; - _yOffset = 0; _depthSurface = NULL; _bgSurface = NULL; + _viewport = NULL; _sceneAnimation = new MadsAnimation(_vm, this); } MadsView::~MadsView() { delete _sceneAnimation; + delete _viewport; } void MadsView::refresh() { + if (!_viewport) + setViewport(_view->bounds()); + // Draw any sprites _dirtyAreas.clear(); - _spriteSlots.drawBackground(_yOffset); + _spriteSlots.drawBackground(); // Process dirty areas _textDisplay.setDirtyAreas(); @@ -1217,7 +1221,7 @@ void MadsView::refresh() { _dirtyAreas.merge(1, DIRTY_AREAS_SIZE); // Copy dirty areas to the main display surface - _dirtyAreas.copy(_view, _bgSurface, _yOffset, _posAdjust); + _dirtyAreas.copy(_viewport, _bgSurface, _posAdjust); // Handle dirty areas for foreground objects _spriteSlots.setDirtyAreas(); @@ -1225,10 +1229,10 @@ void MadsView::refresh() { _dirtyAreas.merge(1, DIRTY_AREAS_SIZE); // Draw foreground sprites - _spriteSlots.drawForeground(_view, _yOffset); + _spriteSlots.drawForeground(_viewport); // Draw text elements onto the view - _textDisplay.draw(_view, _yOffset); + _textDisplay.draw(_viewport); // Remove any sprite slots that are no longer needed _spriteSlots.cleanUp(); @@ -1248,4 +1252,10 @@ void MadsView::clearLists() { _spriteSlots.clear(); } +void MadsView::setViewport(const Common::Rect &bounds) { + delete _viewport; + _viewport = new M4Surface(bounds.width(), bounds.height(), _view->getBasePtr(bounds.left, bounds.top), + _view->getPitch()); +} + } // End of namespace M4 diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 8bc507f20b8..2fbe6a6dc73 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -97,8 +97,8 @@ public: void clear(); void deleteTimer(int seqIndex); - void drawBackground(int yOffset); - void drawForeground(View *view, int yOffset); + void drawBackground(); + void drawForeground(M4Surface *viewport); void setDirtyAreas(); void fullRefresh(); void cleanUp(); @@ -139,7 +139,7 @@ public: int add(int xp, int yp, uint fontColour, int charSpacing, const char *msg, Font *font); void clear(); - void draw(View *view, int yOffset); + void draw(M4Surface *view); void setDirtyAreas(); void setDirtyAreas2(); void cleanUp(); @@ -293,7 +293,7 @@ public: void merge(int startIndex, int count); bool intersects(int idx1, int idx2); void mergeAreas(int idx1, int idx2); - void copy(M4Surface *dest, M4Surface *src, int yOffset, const Common::Point &posAdjust); + void copy(M4Surface *dest, M4Surface *src, const Common::Point &posAdjust); void clear(); }; @@ -403,7 +403,7 @@ public: M4Surface *_depthSurface; M4Surface *_bgSurface; - int _yOffset; + M4Surface *_viewport; public: MadsView(View *view); ~MadsView(); @@ -411,6 +411,7 @@ public: void refresh(); void update(); void clearLists(); + void setViewport(const Common::Rect &bounds); }; }