aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
authorNicola Mettifogo2007-08-06 22:03:17 +0000
committerNicola Mettifogo2007-08-06 22:03:17 +0000
commit797f114aacbd34195d8fd58cb989ac0f5daa655d (patch)
treef5723e0afcf6892116e066e36378c56bdbb0755c /engines/parallaction
parentc60fc2202f463c5130361f663d4c8dc5ca77c5bf (diff)
downloadscummvm-rg350-797f114aacbd34195d8fd58cb989ac0f5daa655d.tar.gz
scummvm-rg350-797f114aacbd34195d8fd58cb989ac0f5daa655d.tar.bz2
scummvm-rg350-797f114aacbd34195d8fd58cb989ac0f5daa655d.zip
- 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
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/disk_ns.cpp27
-rw-r--r--engines/parallaction/graphics.cpp2
-rw-r--r--engines/parallaction/graphics.h14
-rw-r--r--engines/parallaction/parallaction.cpp6
-rw-r--r--engines/parallaction/parallaction.h4
-rw-r--r--engines/parallaction/walk.cpp63
-rw-r--r--engines/parallaction/walk.h33
7 files changed, 90 insertions, 59 deletions
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<WalkNode*> 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 {