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
This commit is contained in:
Paul Gilbert 2010-06-30 10:13:20 +00:00
parent 915b9fa318
commit 0c283ed197
5 changed files with 47 additions and 21 deletions

View File

@ -74,7 +74,8 @@ M4Surface::~M4Surface() {
_madsVm->_palette->deleteRange(_rgbList);
delete _rgbList;
}
free();
if (_ownsData)
free();
}
void M4Surface::loadCodesM4(Common::SeekableReadStream *source) {

View File

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

View File

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

View File

@ -133,7 +133,7 @@ bool sortHelper(const DepthEntry &entry1, const DepthEntry &entry2) {
typedef Common::List<DepthEntry> 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

View File

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