aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scumm/boxes.cpp278
-rw-r--r--scumm/scumm.h5
-rw-r--r--scumm/scummvm.cpp6
3 files changed, 122 insertions, 167 deletions
diff --git a/scumm/boxes.cpp b/scumm/boxes.cpp
index 6b0e65a06f..ae320bebc8 100644
--- a/scumm/boxes.cpp
+++ b/scumm/boxes.cpp
@@ -88,7 +88,6 @@ struct PathVertex { /* Linked list of walkpath nodes */
static bool compareSlope(int X1, int Y1, int X2, int Y2, int X3, int Y3);
static ScummVM::Point closestPtOnLine(int ulx, int uly, int llx, int lly, int x, int y);
-static PathVertex *unkMatrixProc1(PathVertex *vtx, PathNode *node);
byte Scumm::getMaskFromBox(int box) {
@@ -751,41 +750,109 @@ bool Actor::findPathTowards(byte box1nr, byte box2nr, byte box3nr, int16 &foundP
return false;
}
-#define BOX_DEBUG 0
-#if BOX_DEBUG
-static void printMatrix(byte *boxm, int num) {
- int i;
- for (i = 0; i < num; i++) {
- printf("%d: ", i);
- while (*boxm != 0xFF) {
- printf("%d, ", *boxm);
- boxm++;
- }
- boxm++;
- printf("\n");
+class BoxHeap {
+ int heapSize, heapCurrentIndex;
+ byte *heapCurrent, *heapStart;
+
+ void *getHeapBlock(int size) {
+ byte *ptr = heapCurrent;
+
+ heapCurrent += size;
+ heapCurrentIndex += size;
+
+ if (heapCurrentIndex >= heapSize)
+ error("Box path vertex heap overflow");
+
+ return ptr;
+ }
+
+public:
+ BoxHeap() {
+ heapSize = 1000;
+ heapStart = heapCurrent = (byte *)calloc(heapSize, 1);
+ heapCurrentIndex = 0;
+ }
+
+ ~BoxHeap() {
+ free(heapStart);
}
-}
-static void printMatrix2(byte *matrix, int num) {
- int i, j;
- printf(" ");
- for (i = 0; i < num; i++)
- printf("%2d ", i);
- printf("\n");
- for (i = 0; i < num; i++) {
- printf("%2d: ", i);
- for (j = 0; j < num; j++) {
- int val = matrix[i * 64 + j];
- if (val == 250)
- printf(" ? ");
- else
- printf("%2d ", val);
+ PathNode *unkMatrixProc2(PathVertex *vtx, int i) {
+ PathNode *node;
+
+ if (vtx == NULL)
+ return NULL;
+
+ node = (PathNode *)getHeapBlock(sizeof(PathNode));
+ node->index = i;
+ node->left = 0;
+ node->right = 0;
+
+ if (!vtx->right) {
+ vtx->left = node;
+ } else {
+ vtx->right->left = node;
+ node->right = vtx->right;
}
- printf("\n");
+
+ vtx->right = node;
+
+ return vtx->right;
+ }
+
+
+ PathVertex *newPathVertex() {
+ // Reset the heap
+ heapCurrent = heapStart;
+ heapCurrentIndex = 0;
+
+ // Add a single new PathVertex to the heap
+ return (PathVertex *)getHeapBlock(sizeof(PathVertex));
+ }
+
+};
+
+class BoxMatrix {
+ int matrixSize;
+ byte *matrixPtr;
+
+public:
+ BoxMatrix(byte *matrix) {
+ assert(matrix);
+ matrixSize = 0;
+ matrixPtr = matrix;
}
+
+ void add(byte b) {
+ if (++matrixSize > BOX_MATRIX_SIZE)
+ error("Box matrix overflow");
+ *matrixPtr++ = b;
+ }
+};
+
+
+PathVertex *unkMatrixProc1(PathVertex *vtx, PathNode *node) {
+ if (node == NULL || vtx == NULL)
+ return NULL;
+
+ if (!node->right) {
+ vtx->left = node->left;
+ } else {
+ node->right->left = node->left;
+ }
+
+ if (!node->left) {
+ vtx->right = node->right;
+ } else {
+ node->left->right = node->right;
+ }
+
+ if (vtx->left)
+ return vtx;
+
+ return NULL;
}
-#endif
void Scumm::createBoxMatrix() {
int num, i, j;
@@ -793,75 +860,51 @@ void Scumm::createBoxMatrix() {
int table_1[66], table_2[66];
int counter, val;
int code;
+ byte *distanceMatrix;
// A heap (an optiimsation to avoid calling malloc/free extremly often)
- _maxBoxVertexHeap = 1000;
- createResource(rtMatrix, 4, _maxBoxVertexHeap);
- _boxPathVertexHeap = getResourceAddress(rtMatrix, 4);
- _boxPathVertexHeapIndex = _boxMatrixItem = 0;
+ BoxHeap heap;
// Temporary 64*65 distance matrix
- createResource(rtMatrix, 3, 65 * 64);
- _boxMatrixPtr3 = getResourceAddress(rtMatrix, 3);
+ distanceMatrix = (byte *)calloc(65, 64);
// The result "matrix" in the special format used by Scumm.
- createResource(rtMatrix, 1, BOX_MATRIX_SIZE);
- _boxMatrixPtr1 = getResourceAddress(rtMatrix, 1);
+ BoxMatrix boxMatrix(createResource(rtMatrix, 1, BOX_MATRIX_SIZE));
num = getNumBoxes();
-#if BOX_DEBUG
-printf("Creating box matrix...\n");
- for (i = 0; i < num; i++) {
- BoxCoords coords;
- flags = getBoxFlags(i);
- getBoxCoordinates(i, &coords);
-
- printf("%d: [%d x %d] [%d x %d] [%d x %d] [%d x %d], flags=0x%02x\n",
- i,
- coords.ul.x, coords.ul.y, coords.ll.x, coords.ll.y,
- coords.ur.x, coords.ur.y, coords.lr.x, coords.lr.y,
- flags);
- }
-#endif
-
// Initialise the distance matrix: each box has distance 0 to itself,
// and distance 1 to its direct neighbors. Initially, it has distance
// 250 (= infinity) to all other boxes.
for (i = 0; i < num; i++) {
for (j = 0; j < num; j++) {
if (i == j) {
- _boxMatrixPtr3[i * 64 + j] = 0;
+ distanceMatrix[i * 64 + j] = 0;
} else if (areBoxesNeighbours(i, j)) {
- _boxMatrixPtr3[i * 64 + j] = 1;
+ distanceMatrix[i * 64 + j] = 1;
} else {
- _boxMatrixPtr3[i * 64 + j] = 250;
+ distanceMatrix[i * 64 + j] = 250;
}
}
}
-#if BOX_DEBUG
- printf("Initial matrix:\n");
- printMatrix2(_boxMatrixPtr3, num);
-#endif
-
// Iterate over all boxes
for (j = 0; j < num; j++) {
flags = getBoxFlags(j);
if (flags & kBoxInvisible) {
// Locked/invisible boxes are only reachable from themselves.
- addToBoxMatrix(0xFF);
- addToBoxMatrix(j);
- addToBoxMatrix(j);
- addToBoxMatrix(j);
+ boxMatrix.add(0xFF);
+ boxMatrix.add(j);
+ boxMatrix.add(j);
+ boxMatrix.add(j);
} else {
PathNode *node, *node2 = NULL;
- PathVertex *vtx = addPathVertex();
+ PathVertex *vtx = heap.newPathVertex();
for (i = 0; i < num; i++) {
flags = getBoxFlags(j);
if (!(flags & kBoxInvisible)) {
- node = unkMatrixProc2(vtx, i);
+ node = heap.unkMatrixProc2(vtx, i);
if (i == j)
node2 = node;
}
@@ -873,7 +916,7 @@ printf("Creating box matrix...\n");
counter = 250;
while (node) {
- val = _boxMatrixPtr3[j * 64 + node->index];
+ val = distanceMatrix[j * 64 + node->index];
table_1[node->index] = val;
if (val < counter)
counter = val;
@@ -900,7 +943,7 @@ printf("Creating box matrix...\n");
vtx = unkMatrixProc1(vtx, node2);
node = vtx ? vtx->left : NULL;
while (node) {
- code = _boxMatrixPtr3[node2->index * 64 + node->index];
+ code = distanceMatrix[node2->index * 64 + node->index];
code += table_1[node2->index];
if (code < table_1[node->index]) {
table_1[node->index] = code;
@@ -910,85 +953,33 @@ printf("Creating box matrix...\n");
}
}
- addToBoxMatrix(0xFF);
+ boxMatrix.add(0xFF);
for (i = 1; i < num; i++) {
if (table_2[i - 1] != -1) {
- addToBoxMatrix(i - 1); /* lo */
+ boxMatrix.add(i - 1); /* lo */
while (table_2[i - 1] == table_2[i]) {
++i;
if (i == num)
break;
}
- addToBoxMatrix(i - 1); /* hi */
- addToBoxMatrix(table_2[i - 1]); /* dst */
+ boxMatrix.add(i - 1); /* hi */
+ boxMatrix.add(table_2[i - 1]); /* dst */
}
}
if (i == num && table_2[i - 1] != -1) {
- addToBoxMatrix(i - 1); /* lo */
- addToBoxMatrix(i - 1); /* hi */
- addToBoxMatrix(table_2[i - 1]); /* dest */
+ boxMatrix.add(i - 1); /* lo */
+ boxMatrix.add(i - 1); /* hi */
+ boxMatrix.add(table_2[i - 1]); /* dest */
}
}
}
- addToBoxMatrix(0xFF);
- nukeResource(rtMatrix, 4);
- nukeResource(rtMatrix, 3);
+ boxMatrix.add(0xFF);
-#if BOX_DEBUG
- printf("End result:\n");
- printMatrix2(_boxMatrixPtr3, num);
- printMatrix(getBoxMatrixBaseAddr(), num);
-#endif
-}
-
-PathVertex *unkMatrixProc1(PathVertex *vtx, PathNode *node) {
- if (node == NULL || vtx == NULL)
- return NULL;
-
- if (!node->right) {
- vtx->left = node->left;
- } else {
- node->right->left = node->left;
- }
-
- if (!node->left) {
- vtx->right = node->right;
- } else {
- node->left->right = node->right;
- }
-
- if (vtx->left)
- return vtx;
-
- return NULL;
+ free(distanceMatrix);
}
-PathNode *Scumm::unkMatrixProc2(PathVertex *vtx, int i) {
- PathNode *node;
-
- if (vtx == NULL)
- return NULL;
-
- node = (PathNode *)addToBoxVertexHeap(sizeof(PathNode));
- node->index = i;
- node->left = 0;
- node->right = 0;
-
- if (!vtx->right) {
- vtx->left = node;
- } else {
- vtx->right->left = node;
- node->right = vtx->right;
- }
-
- vtx->right = node;
-
- return vtx->right;
-}
-
-
-/* Check if two boxes are neighbours */
+/** Check if two boxes are neighbours. */
bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
int j, k, m, n;
int tmp_x, tmp_y;
@@ -1098,31 +1089,6 @@ bool Scumm::areBoxesNeighbours(int box1nr, int box2nr) {
return result;
}
-void Scumm::addToBoxMatrix(byte b) {
- if (++_boxMatrixItem > BOX_MATRIX_SIZE)
- error("Box matrix overflow");
- *_boxMatrixPtr1++ = b;
-}
-
-void *Scumm::addToBoxVertexHeap(int size) {
- byte *ptr = _boxPathVertexHeap;
-
- _boxPathVertexHeap += size;
- _boxPathVertexHeapIndex += size;
-
- if (_boxPathVertexHeapIndex >= _maxBoxVertexHeap)
- error("Box path vertex heap overflow");
-
- return ptr;
-}
-
-PathVertex *Scumm::addPathVertex() {
- _boxPathVertexHeap = getResourceAddress(rtMatrix, 4);
- _boxPathVertexHeapIndex = 0;
-
- return (PathVertex *)addToBoxVertexHeap(sizeof(PathVertex));
-}
-
void Actor::findPathTowardsOld(byte trap1, byte trap2, byte final_trap, ScummVM::Point gateLoc[5]) {
ScummVM::Point pt;
ScummVM::Point gateA[2];
diff --git a/scumm/scumm.h b/scumm/scumm.h
index a3b1c728d9..49d4275261 100644
--- a/scumm/scumm.h
+++ b/scumm/scumm.h
@@ -979,11 +979,6 @@ public:
bool _silentDigitalImuse, _noDigitalSamples;
int current_cd_sound; // Used in class Sound
-protected:
- /* Walkbox / Navigation class */
- int _maxBoxVertexHeap, _boxPathVertexHeapIndex, _boxMatrixItem;
- byte *_boxPathVertexHeap, *_boxMatrixPtr1, *_boxMatrixPtr3;
-
public:
uint16 _extraBoxFlags[65];
diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp
index e4b952050d..f50987284b 100644
--- a/scumm/scummvm.cpp
+++ b/scumm/scummvm.cpp
@@ -397,12 +397,6 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst)
_noDigitalSamples = 0;
_saveSound = 1;
current_cd_sound = 0;
- _maxBoxVertexHeap = 0;
- _boxPathVertexHeapIndex = 0;
- _boxMatrixItem = 0;
- _boxPathVertexHeap = NULL;
- _boxMatrixPtr1 = NULL;
- _boxMatrixPtr3 = NULL;
memset(_extraBoxFlags,0,sizeof(_extraBoxFlags));
memset(_scaleSlots,0,sizeof(_scaleSlots));
_charset = NULL;