diff options
author | Nicola Mettifogo | 2009-01-07 07:35:11 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2009-01-07 07:35:11 +0000 |
commit | 21fae9d029e1c902c47f59143c1a8f938c694318 (patch) | |
tree | 66cd7707f39f40b0a1bb1d5931a9aa33182a3655 /engines/parallaction | |
parent | ef05ed7a985062edf978472b76b97ead0946b92b (diff) | |
download | scummvm-rg350-21fae9d029e1c902c47f59143c1a8f938c694318.tar.gz scummvm-rg350-21fae9d029e1c902c47f59143c1a8f938c694318.tar.bz2 scummvm-rg350-21fae9d029e1c902c47f59143c1a8f938c694318.zip |
* moved more mask management to BackgroundInfo
* simplified mask management for client code
* reduced the clutter into graphics.h by moving the implementations of BackgroundInfo, MaskBuffer and PathBuffer to graphics.cpp
* preparation for the full implementation of BRA's PathBuffer
svn-id: r35765
Diffstat (limited to 'engines/parallaction')
-rw-r--r-- | engines/parallaction/callables_ns.cpp | 20 | ||||
-rw-r--r-- | engines/parallaction/disk_br.cpp | 5 | ||||
-rw-r--r-- | engines/parallaction/disk_ns.cpp | 21 | ||||
-rw-r--r-- | engines/parallaction/gfxbase.cpp | 25 | ||||
-rw-r--r-- | engines/parallaction/graphics.cpp | 210 | ||||
-rw-r--r-- | engines/parallaction/graphics.h | 269 | ||||
-rw-r--r-- | engines/parallaction/parallaction.cpp | 4 | ||||
-rw-r--r-- | engines/parallaction/parser_br.cpp | 7 | ||||
-rw-r--r-- | engines/parallaction/walk.cpp | 21 |
9 files changed, 337 insertions, 245 deletions
diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index b45a30c317..d40f028941 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -288,7 +288,10 @@ void Parallaction_ns::_c_onMouse(void *parm) { void Parallaction_ns::_c_setMask(void *parm) { - memset(_gfx->_backgroundInfo->mask.data + 3600, 0, 3600); + if (!_gfx->_backgroundInfo->hasMask()) + return; + + memset(_gfx->_backgroundInfo->_mask->data + 3600, 0, 3600); _gfx->_backgroundInfo->layers[1] = 500; return; @@ -446,10 +449,13 @@ void Parallaction_ns::_c_moveSheet(void *parm) { void zeroMask(int x, int y, int color, void *data) { //_vm->_gfx->zeroMaskValue(x, y, color); - BackgroundInfo* info = (BackgroundInfo*)data; + if (!_vm->_gfx->_backgroundInfo->hasMask()) + return; + +// BackgroundInfo* info = (BackgroundInfo*)data; - uint16 _ax = x + y * info->width; - info->mask.data[_ax >> 2] &= ~(3 << ((_ax & 3) << 1)); + uint16 _ax = x + y * _vm->_gfx->_backgroundInfo->_mask->w; + _vm->_gfx->_backgroundInfo->_mask->data[_ax >> 2] &= ~(3 << ((_ax & 3) << 1)); } @@ -498,11 +504,11 @@ void Parallaction_ns::_c_shade(void *parm) { _rightHandAnim->getY() ); - uint16 _di = r.left/4 + r.top * _gfx->_backgroundInfo->mask.internalWidth; + uint16 _di = r.left/4 + r.top * _vm->_gfx->_backgroundInfo->_mask->internalWidth; for (uint16 _si = r.top; _si < r.bottom; _si++) { - memset(_gfx->_backgroundInfo->mask.data + _di, 0, r.width()/4+1); - _di += _gfx->_backgroundInfo->mask.internalWidth; + memset(_vm->_gfx->_backgroundInfo->_mask->data + _di, 0, r.width()/4+1); + _di += _vm->_gfx->_backgroundInfo->_mask->internalWidth; } return; diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp index 45ef34e046..5f2ddcd1b7 100644 --- a/engines/parallaction/disk_br.cpp +++ b/engines/parallaction/disk_br.cpp @@ -339,8 +339,9 @@ void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char } if (mask) { - info.mask.create(info.width, info.height); - loadMask(mask, info.mask); + info._mask = new MaskBuffer; + info._mask->create(info.width, info.height); + loadMask(mask, *info._mask); } if (path) { diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp index eedfaf92b7..c24eaf7007 100644 --- a/engines/parallaction/disk_ns.cpp +++ b/engines/parallaction/disk_ns.cpp @@ -457,12 +457,13 @@ void DosDisk_ns::loadBackground(BackgroundInfo& info, const char *filename) { parseBackground(info, *stream); info.bg.create(info.width, info.height, 1); - info.mask.create(info.width, info.height); - info.mask.bigEndian = true; + info._mask = new MaskBuffer; + info._mask->create(info.width, info.height); + info._mask->bigEndian = true; info.path.create(info.width, info.height); Graphics::PackBitsReadStream pbstream(*stream); - unpackBackground(&pbstream, (byte*)info.bg.pixels, info.mask.data, info.path.data); + unpackBackground(&pbstream, (byte*)info.bg.pixels, info._mask->data, info.path.data); delete stream; } @@ -480,9 +481,10 @@ void DosDisk_ns::loadMaskAndPath(BackgroundInfo& info, const char *name) { parseDepths(info, *stream); info.path.create(info.width, info.height); stream->read(info.path.data, info.path.size); - info.mask.create(info.width, info.height); - info.mask.bigEndian = true; - stream->read(info.mask.data, info.mask.size); + info._mask = new MaskBuffer; + info._mask->create(info.width, info.height); + info._mask->bigEndian = true; + stream->read(info._mask->data, info._mask->size); delete stream; } @@ -1049,9 +1051,10 @@ void AmigaDisk_ns::loadMask(BackgroundInfo& info, const char *name) { s->seek(0x126, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic Graphics::PackBitsReadStream stream(*s); - info.mask.create(info.width, info.height); - stream.read(info.mask.data, info.mask.size); - buildMask(info.mask.data); + info._mask = new MaskBuffer; + info._mask->create(info.width, info.height); + stream.read(info._mask->data, info._mask->size); + buildMask(info._mask->data); delete s; diff --git a/engines/parallaction/gfxbase.cpp b/engines/parallaction/gfxbase.cpp index 2e7794a1f1..a585caa713 100644 --- a/engines/parallaction/gfxbase.cpp +++ b/engines/parallaction/gfxbase.cpp @@ -46,7 +46,6 @@ GfxObj::GfxObj(uint objType, Frames *frames, const char* name) : GfxObj::~GfxObj() { delete _frames; free(_name); - _mask.free(); } void GfxObj::release() { @@ -157,12 +156,15 @@ void Gfx::freeCharacterObjects() { clearGfxObjects(kGfxObjCharacter); } - void Gfx::loadGfxObjMask(const char *name, GfxObj *obj) { Common::Rect rect; obj->getRect(0, rect); - obj->_mask.create(rect.width(), rect.height()); - _vm->_disk->loadMask(name, obj->_mask); + + MaskBuffer *buf = new MaskBuffer; + buf->create(rect.width(), rect.height()); + _vm->_disk->loadMask(name, *buf); + + obj->_maskId = _backgroundInfo->addMaskPatch(buf); obj->_hasMask = true; } @@ -177,12 +179,9 @@ void Gfx::showGfxObj(GfxObj* obj, bool visible) { obj->clearFlags(kGfxObjVisible); } - if (obj->_hasMask && _backgroundInfo->hasMask) { - if (visible) { - _backgroundInfo->mask.bltOr(obj->x, obj->y, obj->_mask, 0, 0, obj->_mask.w, obj->_mask.h); - } else { - _backgroundInfo->mask.bltCopy(obj->x, obj->y, _backgroundInfo->maskBackup, obj->x, obj->y, obj->_mask.w, obj->_mask.h); - } + //TODO: move handling of mask existence inside MaskManager + if (obj->_hasMask) { + _backgroundInfo->toggleMaskPatch(obj->_maskId, obj->x, obj->y, visible); } } @@ -334,7 +333,7 @@ void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *sur } if (*s != transparentColor) { - byte v = _backgroundInfo->mask.getValue(dp.x + col, dp.y + line); + byte v = _backgroundInfo->_mask->getValue(dp.x + col, dp.y + line); if (z >= v) *d2 = *s; } @@ -351,7 +350,7 @@ void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *sur } void Gfx::bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor) { - if (!_backgroundInfo->mask.data || (z == LAYER_FOREGROUND)) { + if (!_backgroundInfo->hasMask() || (z == LAYER_FOREGROUND)) { // use optimized path bltNoMaskNoScale(r, data, surf, transparentColor); return; @@ -380,7 +379,7 @@ void Gfx::bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *s for (uint16 j = 0; j < q.width(); j++) { if (*s != transparentColor) { - byte v = _backgroundInfo->mask.getValue(dp.x + j, dp.y + i); + byte v = _backgroundInfo->_mask->getValue(dp.x + j, dp.y + i); if (z >= v) *d = *s; } diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index d3ca4934d0..1a233bb990 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -464,7 +464,7 @@ void Gfx::patchBackground(Graphics::Surface &surf, int16 x, int16 y, bool mask) Common::Rect r(surf.w, surf.h); r.moveTo(x, y); - uint16 z = (mask) ? _backgroundInfo->getLayer(y) : LAYER_FOREGROUND; + uint16 z = (mask) ? _backgroundInfo->getMaskLayer(y) : LAYER_FOREGROUND; blt(r, (byte*)surf.pixels, &_backgroundInfo->bg, z, 100, 0); } @@ -687,7 +687,7 @@ void Gfx::grabBackground(const Common::Rect& r, Graphics::Surface &dst) { Gfx::Gfx(Parallaction* vm) : - _vm(vm), _disk(vm->_disk), _scrollPos(0), _minScroll(0), _maxScroll(0) { + _vm(vm), _disk(vm->_disk), _backgroundInfo(0), _scrollPos(0), _minScroll(0), _maxScroll(0) { _gameType = _vm->getGameType(); _doubleBuffering = _gameType != GType_Nippon; @@ -778,6 +778,11 @@ void Gfx::freeDialogueObjects() { } void Gfx::setBackground(uint type, BackgroundInfo *info) { + if (!info) { + warning("Gfx::setBackground() called with an null BackgroundInfo"); + return; + } + delete _backgroundInfo; _backgroundInfo = info; @@ -801,9 +806,7 @@ void Gfx::setBackground(uint type, BackgroundInfo *info) { setPalette(_backgroundInfo->palette); } - if (_backgroundInfo->hasMask) { - _backgroundInfo->maskBackup.clone(_backgroundInfo->mask); - } + _backgroundInfo->finalizeMask(); if (_gameType == GType_BRA) { int width = CLIP(info->width, (int)_vm->_screenWidth, info->width); @@ -818,4 +821,201 @@ void Gfx::setBackground(uint type, BackgroundInfo *info) { _maxScroll = MAX<int>(0, _backgroundInfo->width - _vm->_screenWidth); } + +BackgroundInfo::BackgroundInfo() : x(0), y(0), width(0), height(0), _mask(0) { + layers[0] = layers[1] = layers[2] = layers[3] = 0; + memset(ranges, 0, sizeof(ranges)); +} + +BackgroundInfo::~BackgroundInfo() { + bg.free(); + clearMaskData(); + path.free(); +} + +bool BackgroundInfo::hasMask() { + return _mask != 0; +} + +void BackgroundInfo::clearMaskData() { + // free mask data + MaskPatchMap::iterator it = _maskPatches.begin(); + for ( ; it != _maskPatches.end(); it++) { + delete (*it)._value; + } + _maskPatches.clear(); + delete _mask; + _mask = 0; + _maskBackup.free(); +} + +void BackgroundInfo::finalizeMask() { + if (_mask) { + _maskBackup.clone(*_mask); + } else { + clearMaskData(); + } +} + +int BackgroundInfo::addMaskPatch(MaskBuffer *patch) { + int id = _maskPatches.size(); + _maskPatches.setVal(id, patch); + return id; +} + +void BackgroundInfo::toggleMaskPatch(int id, int x, int y, bool apply) { + if (!hasMask()) { + return; + } + if (!_maskPatches.contains(id)) { + return; + } + MaskBuffer *patch = _maskPatches.getVal(id); + if (apply) { + _mask->bltOr(x, y, *patch, 0, 0, patch->w, patch->h); + } else { + _mask->bltCopy(x, y, _maskBackup, x, y, patch->w, patch->h); + } +} + +uint16 BackgroundInfo::getMaskLayer(uint16 z) const { + for (uint16 i = 0; i < 3; i++) { + if (layers[i+1] > z) return i; + } + return LAYER_FOREGROUND; +} + +void BackgroundInfo::setPaletteRange(int index, const PaletteFxRange& range) { + assert(index < 6); + memcpy(&ranges[index], &range, sizeof(PaletteFxRange)); +} + +MaskBuffer::MaskBuffer() : w(0), internalWidth(0), h(0), size(0), data(0), bigEndian(true) { +} + +MaskBuffer::~MaskBuffer() { + free(); +} + +byte* MaskBuffer::getPtr(uint16 x, uint16 y) const { + return data + (x >> 2) + y * internalWidth; +} + +void MaskBuffer::clone(const MaskBuffer &buf) { + if (!buf.data) + return; + + create(buf.w, buf.h); + bigEndian = buf.bigEndian; + memcpy(data, buf.data, size); +} + +void MaskBuffer::create(uint16 width, uint16 height) { + free(); + + w = width; + internalWidth = w >> 2; + h = height; + size = (internalWidth * h); + data = (byte*)calloc(size, 1); +} + +void MaskBuffer::free() { + ::free(data); + data = 0; + w = 0; + h = 0; + internalWidth = 0; + size = 0; +} + +byte MaskBuffer::getValue(uint16 x, uint16 y) const { + byte m = data[(x >> 2) + y * internalWidth]; + uint n; + if (bigEndian) { + n = (x & 3) << 1; + } else { + n = (3 - (x & 3)) << 1; + } + return (m >> n) & 3; +} + +void MaskBuffer::bltOr(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { + assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); + + byte *s = src.getPtr(sx, sy); + byte *d = getPtr(dx, dy); + + // this code assumes buffers are aligned on 4-pixels boundaries, as the original does + uint16 linewidth = width >> 2; + for (uint16 i = 0; i < height; i++) { + for (uint16 j = 0; j < linewidth; j++) { + *d++ |= *s++; + } + d += internalWidth - linewidth; + s += src.internalWidth - linewidth; + } +} + +void MaskBuffer::bltCopy(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { + assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); + + byte *s = src.getPtr(sx, sy); + byte *d = getPtr(dx, dy); + + // this code assumes buffers are aligned on 4-pixels boundaries, as the original does + for (uint16 i = 0; i < height; i++) { + memcpy(d, s, (width >> 2)); + d += internalWidth; + s += src.internalWidth; + } +} + + + +PathBuffer::PathBuffer() : w(0), internalWidth(0), h(0), size(0), data(0) { +} + +PathBuffer::~PathBuffer() { + free(); +} + +void PathBuffer::create(uint16 width, uint16 height) { + free(); + + w = width; + internalWidth = w >> 3; + h = height; + size = (internalWidth * h); + data = (byte*)calloc(size, 1); +} + +void PathBuffer::free() { + ::free(data); + data = 0; + w = 0; + h = 0; + internalWidth = 0; + size = 0; +} + +byte PathBuffer::getValue(uint16 x, uint16 y) const { + byte m = data[(x >> 3) + y * internalWidth]; + uint bit = 0; + switch (_vm->getGameType()) { + case GType_Nippon: + bit = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7)); + break; + + case GType_BRA: + // Amiga and PC versions pack the path bits the same way in BRA + bit = 7 - (x & 7); + break; + + default: + error("path mask not yet implemented for this game type"); + } + return ((1 << bit) & m) >> bit; +} + } // namespace Parallaction diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index f409ab7745..db80586a70 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -28,6 +28,7 @@ #include "common/list.h" #include "common/rect.h" +#include "common/hashmap.h" #include "common/hash-str.h" #include "common/stream.h" @@ -124,97 +125,85 @@ public: }; - - -struct MaskBuffer { - // handles a 2-bit depth buffer used for z-buffering - - uint16 w; - uint16 internalWidth; - uint16 h; - uint size; - byte *data; - bool bigEndian; +struct Cnv : public Frames { + uint16 _count; // # of frames + uint16 _width; // + uint16 _height; // + byte** field_8; // unused + byte* _data; + bool _freeData; public: - MaskBuffer() : w(0), internalWidth(0), h(0), size(0), data(0), bigEndian(true) { + Cnv() { + _width = _height = _count = 0; + _data = NULL; } - void clone(const MaskBuffer &buf) { - if (!buf.data) - return; + Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data, bool freeData = false) + : _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData) { - create(buf.w, buf.h); - bigEndian = buf.bigEndian; - memcpy(data, buf.data, size); } - void create(uint16 width, uint16 height) { - free(); - - w = width; - internalWidth = w >> 2; - h = height; - size = (internalWidth * h); - data = (byte*)calloc(size, 1); + ~Cnv() { + if (_freeData) + delete []_data; } - void free() { - ::free(data); - data = 0; - w = 0; - h = 0; - internalWidth = 0; - size = 0; + byte* getFramePtr(uint16 index) { + if (index >= _count) + return NULL; + return &_data[index * _width * _height]; } - inline byte getValue(uint16 x, uint16 y) { - byte m = data[(x >> 2) + y * internalWidth]; - uint n; - if (bigEndian) { - n = (x & 3) << 1; - } else { - n = (3 - (x & 3)) << 1; - } - return (m >> n) & 3; + uint16 getNum() { + return _count; } - inline byte* getPtr(uint16 x, uint16 y) const { - return data + (x >> 2) + y * internalWidth; + byte *getData(uint16 index) { + return getFramePtr(index); } - void bltOr(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { - assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); - - byte *s = src.getPtr(sx, sy); - byte *d = getPtr(dx, dy); - - // this code assumes buffers are aligned on 4-pixels boundaries, as the original does - uint16 linewidth = width >> 2; - for (uint16 i = 0; i < height; i++) { - for (uint16 j = 0; j < linewidth; j++) { - *d++ |= *s++; - } - d += internalWidth - linewidth; - s += src.internalWidth - linewidth; - } + void getRect(uint16 index, Common::Rect &r) { + r.left = 0; + r.top = 0; + r.setWidth(_width); + r.setHeight(_height); + } + uint getRawSize(uint16 index) { + assert(index < _count); + return getSize(index); + } + uint getSize(uint16 index) { + assert(index < _count); + return _width * _height; } - void bltCopy(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { - assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); +}; - byte *s = src.getPtr(sx, sy); - byte *d = getPtr(dx, dy); - // this code assumes buffers are aligned on 4-pixels boundaries, as the original does - for (uint16 i = 0; i < height; i++) { - memcpy(d, s, (width >> 2)); - d += internalWidth; - s += src.internalWidth; - } - } +struct MaskBuffer { + // handles a 2-bit depth buffer used for z-buffering + uint16 w; + uint16 internalWidth; + uint16 h; + uint size; + byte *data; + bool bigEndian; + + byte* getPtr(uint16 x, uint16 y) const; + +public: + MaskBuffer(); + ~MaskBuffer(); + void clone(const MaskBuffer &buf); + void create(uint16 width, uint16 height); + void free(); + + byte getValue(uint16 x, uint16 y) const; + void bltOr(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height); + void bltCopy(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height); }; @@ -228,29 +217,12 @@ struct PathBuffer { byte *data; public: - PathBuffer() : w(0), internalWidth(0), h(0), size(0), data(0) { - } - - void create(uint16 width, uint16 height) { - free(); - - w = width; - internalWidth = w >> 3; - h = height; - size = (internalWidth * h); - data = (byte*)calloc(size, 1); - } - - void free() { - ::free(data); - data = 0; - w = 0; - h = 0; - internalWidth = 0; - size = 0; - } + PathBuffer(); + ~PathBuffer(); - inline byte getValue(uint16 x, uint16 y); + void create(uint16 width, uint16 height); + void free(); + byte getValue(uint16 x, uint16 y) const; }; @@ -279,62 +251,6 @@ public: }; -struct Cnv : public Frames { - uint16 _count; // # of frames - uint16 _width; // - uint16 _height; // - byte** field_8; // unused - byte* _data; - bool _freeData; - -public: - Cnv() { - _width = _height = _count = 0; - _data = NULL; - } - - Cnv(uint16 numFrames, uint16 width, uint16 height, byte* data, bool freeData = false) - : _count(numFrames), _width(width), _height(height), _data(data), _freeData(freeData) { - - } - - ~Cnv() { - if (_freeData) - delete []_data; - } - - byte* getFramePtr(uint16 index) { - if (index >= _count) - return NULL; - return &_data[index * _width * _height]; - } - - uint16 getNum() { - return _count; - } - - byte *getData(uint16 index) { - return getFramePtr(index); - } - - void getRect(uint16 index, Common::Rect &r) { - r.left = 0; - r.top = 0; - r.setWidth(_width); - r.setHeight(_height); - } - uint getRawSize(uint16 index) { - assert(index < _count); - return getSize(index); - } - uint getSize(uint16 index) { - assert(index < _count); - return _width * _height; - } - -}; - - #define CENTER_LABEL_HORIZONTAL -1 #define CENTER_LABEL_VERTICAL -1 @@ -387,7 +303,7 @@ public: uint transparentKey; uint scale; - MaskBuffer _mask; + int _maskId; bool _hasMask; @@ -420,13 +336,20 @@ public: being the most common options. */ struct BackgroundInfo { +protected: + typedef Common::HashMap<int, MaskBuffer*> MaskPatchMap; + MaskPatchMap _maskPatches; + MaskBuffer _maskBackup; + + void clearMaskData(); + +public: int x, y; // used to display bitmaps smaller than the screen int width; int height; Graphics::Surface bg; - MaskBuffer mask; - MaskBuffer maskBackup; + MaskBuffer *_mask; PathBuffer path; Palette palette; @@ -434,39 +357,28 @@ struct BackgroundInfo { int layers[4]; PaletteFxRange ranges[6]; - bool hasMask; - BackgroundInfo() : x(0), y(0), width(0), height(0), hasMask(false) { - layers[0] = layers[1] = layers[2] = layers[3] = 0; - memset(ranges, 0, sizeof(ranges)); - } + BackgroundInfo(); + ~BackgroundInfo(); - void setPaletteRange(int index, const PaletteFxRange& range) { - assert(index < 6); - memcpy(&ranges[index], &range, sizeof(PaletteFxRange)); - } + void setPaletteRange(int index, const PaletteFxRange& range); - uint16 getLayer(uint16 z) { - for (uint16 i = 0; i < 3; i++) { - if (layers[i+1] > z) return i; - } - return LAYER_FOREGROUND; - } - - ~BackgroundInfo() { - bg.free(); - mask.free(); - maskBackup.free(); - path.free(); - x = 0; - y = 0; - width = 0; - height = 0; - } + // mask management + bool hasMask(); + int addMaskPatch(MaskBuffer *patch); + void toggleMaskPatch(int id, int x, int y, bool apply); + uint16 getMaskLayer(uint16 z) const; + void finalizeMask(); + // path management + bool hasPath(); + int addPathPatch(PathBuffer *patch); + void togglePathPatch(int id, int x, int y, bool apply); }; + + enum { kBackgroundLocation = 1, kBackgroundSlide = 2 @@ -611,9 +523,6 @@ protected: void bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor); void bltMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, byte transparentColor); void bltNoMaskNoScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, byte transparentColor); - -public: - }; diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index e1f26874e8..426cb7afde 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -456,12 +456,12 @@ void Parallaction::drawAnimations() { } else { if (getGameType() == GType_Nippon) { // Layer in NS depends on where the animation is on the screen, for each animation. - layer = _gfx->_backgroundInfo->getLayer(anim->getBottom()); + layer = _gfx->_backgroundInfo->getMaskLayer(anim->getBottom()); } else { // Layer in BRA is calculated from Z value. For characters it is the same as NS, // but other animations can have Z set from scripts independently from their // position on the screen. - layer = _gfx->_backgroundInfo->getLayer(anim->getZ()); + layer = _gfx->_backgroundInfo->getMaskLayer(anim->getZ()); } } diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index b48db587db..3b5efd2c3f 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -472,7 +472,6 @@ DECLARE_LOCATION_PARSER(mask) { ctxt.info->layers[3] = atoi(_tokens[4]); _vm->_disk->loadScenery(*ctxt.info, 0, _tokens[1], 0); - ctxt.info->hasMask = true; } @@ -789,11 +788,7 @@ void LocationParser_br::parseGetData(ZonePtr z) { } if (!scumm_stricmp(_tokens[0], "mask")) { - if (ctxt.info->hasMask) { - _vm->_gfx->loadGfxObjMask(_tokens[1], data->gfxobj); - } else { - warning("Mask for zone '%s' ignored, since background doesn't have one", z->_name); - } + _vm->_gfx->loadGfxObjMask(_tokens[1], data->gfxobj); } if (!scumm_stricmp(_tokens[0], "path")) { diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index acd5daa8d5..5a646caa9f 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -27,29 +27,8 @@ namespace Parallaction { - - #define IS_PATH_CLEAR(x,y) _vm->_gfx->_backgroundInfo->path.getValue((x), (y)) -inline byte PathBuffer::getValue(uint16 x, uint16 y) { - byte m = data[(x >> 3) + y * internalWidth]; - uint bit = 0; - switch (_vm->getGameType()) { - case GType_Nippon: - bit = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7)); - break; - - case GType_BRA: - // Amiga and PC versions pack the path bits the same way in BRA - bit = 7 - (x & 7); - break; - - default: - error("path mask not yet implemented for this game type"); - } - return ((1 << bit) & m) >> bit; -} - // adjusts position towards nearest walkable point // void PathBuilder_NS::correctPathPoint(Common::Point &to) { |