From 797f114aacbd34195d8fd58cb989ac0f5daa655d Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Mon, 6 Aug 2007 22:03:17 +0000 Subject: - Renamed BitBuffer to MaskBuffer - Added PathBuffer to handle 1-bit buffers for walkable areas - Changed relevant walk code to use PathBuffer objects for querying screen dimensions. svn-id: r28478 --- engines/parallaction/disk_ns.cpp | 27 ++++++++------- engines/parallaction/graphics.cpp | 2 +- engines/parallaction/graphics.h | 14 ++++---- engines/parallaction/parallaction.cpp | 6 +++- engines/parallaction/parallaction.h | 4 +-- engines/parallaction/walk.cpp | 63 ++++++++++++++++------------------- engines/parallaction/walk.h | 33 ++++++++++++++++++ 7 files changed, 90 insertions(+), 59 deletions(-) (limited to 'engines/parallaction') diff --git a/engines/parallaction/disk_ns.cpp b/engines/parallaction/disk_ns.cpp index b79e845ad3..0dbabd4bc9 100644 --- a/engines/parallaction/disk_ns.cpp +++ b/engines/parallaction/disk_ns.cpp @@ -592,20 +592,19 @@ void DosDisk_ns::loadBackground(const char *filename) { Graphics::Surface *bg = new Graphics::Surface; bg->create(_vm->_screenWidth, _vm->_screenHeight, 1); - BitBuffer *mask = new BitBuffer; + MaskBuffer *mask = new MaskBuffer; mask->create(_vm->_screenWidth, _vm->_screenHeight); - byte *path = (byte*)calloc(1, _vm->_screenPathSize); + PathBuffer *path = new PathBuffer; + path->create(_vm->_screenWidth, _vm->_screenHeight); Graphics::PackBitsReadStream stream(_resArchive); - unpackBackground(&stream, (byte*)bg->pixels, mask->data, path); + unpackBackground(&stream, (byte*)bg->pixels, mask->data, path->data); _vm->_gfx->setBackground(bg); _vm->_gfx->setMask(mask); _vm->setPath(path); - free(path); - return; } @@ -622,13 +621,15 @@ void DosDisk_ns::loadMaskAndPath(const char *name) { if (!_resArchive.openArchivedFile(path)) errorFileNotFound(name); - BitBuffer *mask = new BitBuffer; + MaskBuffer *mask = new MaskBuffer; mask->create(_vm->_screenWidth, _vm->_screenHeight); - byte *pathBuf = (byte*)calloc(1, _vm->_screenPathSize); + + PathBuffer *pathBuf = new PathBuffer; + pathBuf->create(_vm->_screenWidth, _vm->_screenHeight); parseDepths(_resArchive); - _resArchive.read(pathBuf, _vm->_screenPathSize); + _resArchive.read(pathBuf->data, pathBuf->size); _resArchive.read(mask->data, mask->size); _vm->_gfx->setMask(mask); @@ -1238,7 +1239,7 @@ void AmigaDisk_ns::loadMask(const char *name) { s->seek(0x126, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic Graphics::PackBitsReadStream stream(*s); - BitBuffer *mask = new BitBuffer; + MaskBuffer *mask = new MaskBuffer; mask->create(_vm->_screenWidth, _vm->_screenHeight); stream.read(mask->data, mask->size); buildMask(mask->data); @@ -1262,10 +1263,12 @@ void AmigaDisk_ns::loadPath(const char *name) { s->seek(0x120, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic Graphics::PackBitsReadStream stream(*s); - byte *buf = (byte*)malloc(_vm->_screenPathSize); - stream.read(buf, _vm->_screenPathSize); + + PathBuffer *buf = new PathBuffer; + buf->create(_vm->_screenWidth, _vm->_screenHeight); + stream.read(buf->data, buf->size); _vm->setPath(buf); - free(buf); + delete s; return; diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index b13519ed2a..fe8d3722cc 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -760,7 +760,7 @@ void Gfx::setBackground(Graphics::Surface *surface) { copyScreen(kBit2, kBitBack); } -void Gfx::setMask(BitBuffer *buffer) { +void Gfx::setMask(MaskBuffer *buffer) { if (_depthMask) delete _depthMask; diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 66eb5b9f39..499b3a4834 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -146,12 +146,9 @@ enum Fonts { kFontMenu = 2 }; -struct BitBuffer { +struct MaskBuffer { // handles a 2-bit depth buffer used for z-buffering - // TODO: generalize to handle 1-bit buffers, so that - // path buffers can be handled as well (use templates?) - uint16 w; uint16 internalWidth; uint16 h; @@ -159,10 +156,10 @@ struct BitBuffer { byte *data; public: - BitBuffer() : w(0), internalWidth(0), h(0), data(0) { + MaskBuffer() : w(0), internalWidth(0), h(0), data(0) { } - ~BitBuffer() { + ~MaskBuffer() { free(); } @@ -220,7 +217,7 @@ public: // location void setBackground(Graphics::Surface *surf); - void setMask(BitBuffer *buffer); + void setMask(MaskBuffer *buffer); int16 queryMask(int16 v); void intGrottaHackMask(); void restoreBackground(const Common::Rect& r); @@ -274,7 +271,7 @@ public: protected: Parallaction* _vm; Graphics::Surface *_buffers[NUM_BUFFERS]; - BitBuffer *_depthMask; + MaskBuffer *_depthMask; static byte _mouseArrow[256]; StaticCnv *_mouseComposedArrow; Font *_font; @@ -295,3 +292,4 @@ protected: #endif + diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 0953bcd27f..a3dfd90a07 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -131,6 +131,9 @@ Parallaction::~Parallaction() { delete _zoneTypeNames; delete _zoneFlagNames; + if (_pathBuffer) + delete _pathBuffer; + _animations.remove(&_char._ani); freeLocation(); @@ -173,7 +176,8 @@ int Parallaction::init() { memset(_locationNames, 0, 120*32); - initWalk(); // needs to be pushed into subclass + _pathBuffer = 0; + initInventory(); // needs to be pushed into subclass _animations.push_front(&_char._ani); diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index c7eb30a746..417f57c119 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -315,7 +315,7 @@ public: void resumeJobs(); void runJobs(); - void setPath(byte *path); + void setPath(PathBuffer *buffer); void finalizeWalk(WalkNodeList *list); int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from); void clipMove(Common::Point& pos, const WalkNode* from); @@ -361,6 +361,7 @@ public: int32 _screenPathWidth; int32 _screenPathSize; + PathBuffer *_pathBuffer; SoundMan *_soundMan; @@ -451,7 +452,6 @@ protected: // members void displayItemComment(ExamineData *data); void parseWalkNodes(Script& script, WalkNodeList &list); - void initWalk(); uint16 checkDoor(); Animation * parseAnimation(Script &script, AnimationList &list, char *name); diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index d57e9d2532..9a306b4f4e 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -29,8 +29,6 @@ namespace Parallaction { -static byte *_buffer; - static uint16 _doorData1 = 1000; static Zone *_zoneTrap = NULL; @@ -38,32 +36,27 @@ static uint16 walkData1 = 0; static uint16 walkData2 = 0; // next walk frame -uint16 queryPath(uint16 x, uint16 y) { - - // NOTE: a better solution would have us mirror each byte in the mask in the loading routine - // AmigaDisk_ns::loadPath() instead of doing it here. - - byte _al = _buffer[y*40 + x/8]; - byte _dl = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7)); - - return _al & (1 << _dl); +inline byte PathBuffer::getValue(uint16 x, uint16 y) { + byte m = data[(x >> 3) + y * internalWidth]; + uint n = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7)); + return ((1 << n) & m) >> n; } // adjusts position towards nearest walkable point // void PathBuilder::correctPathPoint(Common::Point &to) { - if (queryPath(to.x, to.y)) return; + if (_vm->_pathBuffer->getValue(to.x, to.y)) return; int16 right = to.x; int16 left = to.x; do { right++; - } while ((queryPath(right, to.y) == 0) && (right < _vm->_screenWidth)); + } while ((_vm->_pathBuffer->getValue(right, to.y) == 0) && (right < _vm->_pathBuffer->w)); do { left--; - } while ((queryPath(left, to.y) == 0) && (left > 0)); - right = (right == _vm->_screenWidth) ? 1000 : right - to.x; + } while ((_vm->_pathBuffer->getValue(left, to.y) == 0) && (left > 0)); + right = (right == _vm->_pathBuffer->w) ? 1000 : right - to.x; left = (left == 0) ? 1000 : to.x - left; @@ -71,12 +64,12 @@ void PathBuilder::correctPathPoint(Common::Point &to) { int16 bottom = to.y; do { top--; - } while ((queryPath(to.x, top) == 0) && (top > 0)); + } while ((_vm->_pathBuffer->getValue(to.x, top) == 0) && (top > 0)); do { bottom++; - } while ((queryPath(to.x, bottom) == 0) && (bottom < _vm->_screenHeight)); + } while ((_vm->_pathBuffer->getValue(to.x, bottom) == 0) && (bottom < _vm->_pathBuffer->h)); top = (top == 0) ? 1000 : to.y - top; - bottom = (bottom == _vm->_screenHeight) ? 1000 : bottom - to.y; + bottom = (bottom == _vm->_pathBuffer->h) ? 1000 : bottom - to.y; int16 closeX = (right >= left) ? left : right; @@ -232,10 +225,10 @@ uint16 PathBuilder::walkFunc1(int16 x, int16 y, WalkNode *Node) { while (foot != arg) { - if (foot.x < x && queryPath(foot.x + 1, foot.y) != 0) foot.x++; - if (foot.x > x && queryPath(foot.x - 1, foot.y) != 0) foot.x--; - if (foot.y < y && queryPath(foot.x, foot.y + 1) != 0) foot.y++; - if (foot.y > y && queryPath(foot.x, foot.y - 1) != 0) foot.y--; + if (foot.x < x && _vm->_pathBuffer->getValue(foot.x + 1, foot.y) != 0) foot.x++; + if (foot.x > x && _vm->_pathBuffer->getValue(foot.x - 1, foot.y) != 0) foot.x--; + if (foot.y < y && _vm->_pathBuffer->getValue(foot.x, foot.y + 1) != 0) foot.y++; + if (foot.y > y && _vm->_pathBuffer->getValue(foot.x, foot.y - 1) != 0) foot.y--; if (foot == v8 && foot != arg) { @@ -245,10 +238,10 @@ uint16 PathBuilder::walkFunc1(int16 x, int16 y, WalkNode *Node) { while (foot != arg) { - if (foot.x < x && queryPath(foot.x + 1, foot.y) == 0) foot.x++; - if (foot.x > x && queryPath(foot.x - 1, foot.y) == 0) foot.x--; - if (foot.y < y && queryPath(foot.x, foot.y + 1) == 0) foot.y++; - if (foot.y > y && queryPath(foot.x, foot.y - 1) == 0) foot.y--; + if (foot.x < x && _vm->_pathBuffer->getValue(foot.x + 1, foot.y) == 0) foot.x++; + if (foot.x > x && _vm->_pathBuffer->getValue(foot.x - 1, foot.y) == 0) foot.x--; + if (foot.y < y && _vm->_pathBuffer->getValue(foot.x, foot.y + 1) == 0) foot.y++; + if (foot.y > y && _vm->_pathBuffer->getValue(foot.x, foot.y - 1) == 0) foot.y--; if (foot == v8 && foot != arg) return 0; @@ -272,19 +265,19 @@ uint16 PathBuilder::walkFunc1(int16 x, int16 y, WalkNode *Node) { void Parallaction::clipMove(Common::Point& pos, const WalkNode* from) { - if ((pos.x < from->_x) && (pos.x < _screenWidth) && (queryPath(_char._ani.width()/2 + pos.x + 2, _char._ani.height() + pos.y) != 0)) { + if ((pos.x < from->_x) && (pos.x < _vm->_pathBuffer->w) && (_pathBuffer->getValue(_char._ani.width()/2 + pos.x + 2, _char._ani.height() + pos.y) != 0)) { pos.x = (pos.x + 2 < from->_x) ? pos.x + 2 : from->_x; } - if ((pos.x > from->_x) && (pos.x > -20) && (queryPath(_char._ani.width()/2 + pos.x - 2, _char._ani.height() + pos.y) != 0)) { + if ((pos.x > from->_x) && (pos.x > -20) && (_pathBuffer->getValue(_char._ani.width()/2 + pos.x - 2, _char._ani.height() + pos.y) != 0)) { pos.x = (pos.x - 2 > from->_x) ? pos.x - 2 : from->_x; } - if ((pos.y < from->_y) && (pos.y < (_screenHeight - _char._ani.height())) && (queryPath(_char._ani.width()/2 + pos.x, _char._ani.height() + pos.y + 2) != 0)) { + if ((pos.y < from->_y) && (pos.y < (_vm->_pathBuffer->h - _char._ani.height())) && (_pathBuffer->getValue(_char._ani.width()/2 + pos.x, _char._ani.height() + pos.y + 2) != 0)) { pos.y = (pos.y + 2 <= from->_y) ? pos.y + 2 : from->_y; } - if ((pos.y > from->_y) && (pos.y > -20) && (queryPath(_char._ani.width()/2 + pos.x, _char._ani.height() + pos.y- 2) != 0)) { + if ((pos.y > from->_y) && (pos.y > -20) && (_pathBuffer->getValue(_char._ani.width()/2 + pos.x, _char._ani.height() + pos.y- 2) != 0)) { pos.y = (pos.y - 2 >= from->_y) ? pos.y - 2 :from->_y; } @@ -428,12 +421,11 @@ void jobWalk(void *parm, Job *j) { } -void Parallaction::setPath(byte *path) { - memcpy(_buffer, path, _screenPathSize); -} +void Parallaction::setPath(PathBuffer *buffer) { + if (_pathBuffer) + delete _pathBuffer; -void Parallaction::initWalk() { - _buffer = (byte*)malloc(_screenPathSize); + _pathBuffer = buffer; } @@ -459,3 +451,4 @@ PathBuilder::PathBuilder(Animation *anim) : _anim(anim), _list(0) { + diff --git a/engines/parallaction/walk.h b/engines/parallaction/walk.h index 476f5cc47a..77b359b03e 100644 --- a/engines/parallaction/walk.h +++ b/engines/parallaction/walk.h @@ -50,6 +50,39 @@ typedef ManagedList WalkNodeList; void jobWalk(void*, Job *j); +struct PathBuffer { + // handles a 1-bit depth buffer used for masking non-walkable areas + + uint16 w; + uint16 internalWidth; + uint16 h; + uint size; + byte *data; + +public: + PathBuffer() : w(0), internalWidth(0), h(0), data(0) { + } + + ~PathBuffer() { + free(); + } + + void create(uint16 width, uint16 height) { + w = width; + internalWidth = w >> 3; + h = height; + size = (internalWidth * h); + data = (byte*)calloc(size, 1); + } + + void free() { + if (data) + ::free(data); + } + + inline byte getValue(uint16 x, uint16 y); +}; + class PathBuilder { -- cgit v1.2.3