[Scummvm-cvs-logs] SF.net SVN: scummvm:[45437] scummvm/trunk/engines/scumm
Kirben at users.sourceforge.net
Kirben at users.sourceforge.net
Tue Oct 27 12:32:33 CET 2009
Revision: 45437
http://scummvm.svn.sourceforge.net/scummvm/?rev=45437&view=rev
Author: Kirben
Date: 2009-10-27 11:32:33 +0000 (Tue, 27 Oct 2009)
Log Message:
-----------
Add patch #2846425 - MM C64: walkbox fixed, with minor changes.
Modified Paths:
--------------
scummvm/trunk/engines/scumm/boxes.cpp
scummvm/trunk/engines/scumm/scumm.h
scummvm/trunk/engines/scumm/scumm_v0.h
Modified: scummvm/trunk/engines/scumm/boxes.cpp
===================================================================
--- scummvm/trunk/engines/scumm/boxes.cpp 2009-10-27 09:44:13 UTC (rev 45436)
+++ scummvm/trunk/engines/scumm/boxes.cpp 2009-10-27 11:32:33 UTC (rev 45437)
@@ -26,6 +26,7 @@
#include "scumm/scumm.h"
#include "scumm/actor.h"
#include "scumm/boxes.h"
+#include "scumm/scumm_v0.h"
#include "scumm/scumm_v6.h"
#include "scumm/util.h"
@@ -712,20 +713,19 @@
boxm = getBoxMatrixBaseAddr();
if (_game.version == 0) {
- // Skip up to the matrix data for box 'from'
- for (i = 0; i < from; i++) {
- while (*boxm != 0xFF)
- boxm++;
- boxm++;
- }
+ // calculate shortest paths
+ byte *itineraryMatrix = (byte *)malloc(numOfBoxes * numOfBoxes);
+ calcItineraryMatrix(itineraryMatrix, numOfBoxes);
- // Now search for the entry for box 'to'
- while (boxm[0] != 0xFF) {
- if (boxm[0] == to)
- dest = (int8)boxm[0];
- boxm++;
- }
+ dest = to;
+ do {
+ dest = itineraryMatrix[numOfBoxes * from + dest];
+ } while (dest != Actor::kInvalidBox && !areBoxesNeighbours(from, dest));
+ if (dest == Actor::kInvalidBox)
+ dest = -1;
+
+ free(itineraryMatrix);
return dest;
} else if (_game.version <= 2) {
// The v2 box matrix is a real matrix with numOfBoxes rows and columns.
@@ -932,7 +932,7 @@
for (i = 0; i < num; i++) {
printf("%2d: ", i);
for (j = 0; j < num; j++) {
- int val = matrix[i * 64 + j];
+ int val = matrix[i * num + j];
if (val == Actor::kInvalidBox)
printf(" ? ");
else
@@ -943,17 +943,18 @@
}
#endif
-void ScummEngine::createBoxMatrix() {
- int num, i, j, k;
- byte *adjacentMatrix, *itineraryMatrix;
+/**
+ * Computes shortest paths and stores them in the itinerary matrix.
+ * Parameter "num" holds the number of rows (= number of columns).
+ */
+void ScummEngine::calcItineraryMatrix(byte *itineraryMatrix, int num) {
+ int i, j, k;
+ byte *adjacentMatrix;
- // The total number of boxes
- num = getNumBoxes();
- assert(num <= 64);
+ const uint8 boxSize = (_game.version == 0) ? num : 64;
// Allocate the adjacent & itinerary matrices
- adjacentMatrix = (byte *)malloc(64 * 64);
- itineraryMatrix = (byte *)malloc(64 * 64);
+ adjacentMatrix = (byte *)malloc(boxSize * boxSize);
// Initialise the adjacent matrix: each box has distance 0 to itself,
// and distance 1 to its direct neighbors. Initially, it has distance
@@ -961,14 +962,14 @@
for (i = 0; i < num; i++) {
for (j = 0; j < num; j++) {
if (i == j) {
- adjacentMatrix[i * 64 + j] = 0;
- itineraryMatrix[i * 64 + j] = j;
+ adjacentMatrix[i * boxSize + j] = 0;
+ itineraryMatrix[i * boxSize + j] = j;
} else if (areBoxesNeighbours(i, j)) {
- adjacentMatrix[i * 64 + j] = 1;
- itineraryMatrix[i * 64 + j] = j;
+ adjacentMatrix[i * boxSize + j] = 1;
+ itineraryMatrix[i * boxSize + j] = j;
} else {
- adjacentMatrix[i * 64 + j] = 255;
- itineraryMatrix[i * 64 + j] = Actor::kInvalidBox;
+ adjacentMatrix[i * boxSize + j] = 255;
+ itineraryMatrix[i * boxSize + j] = Actor::kInvalidBox;
}
}
}
@@ -984,17 +985,32 @@
for (j = 0; j < num; j++) {
if (i == j)
continue;
- byte distIK = adjacentMatrix[64 * i + k];
- byte distKJ = adjacentMatrix[64 * k + j];
- if (adjacentMatrix[64 * i + j] > distIK + distKJ) {
- adjacentMatrix[64 * i + j] = distIK + distKJ;
- itineraryMatrix[64 * i + j] = itineraryMatrix[64 * i + k];
+ byte distIK = adjacentMatrix[boxSize * i + k];
+ byte distKJ = adjacentMatrix[boxSize * k + j];
+ if (adjacentMatrix[boxSize * i + j] > distIK + distKJ) {
+ adjacentMatrix[boxSize * i + j] = distIK + distKJ;
+ itineraryMatrix[boxSize * i + j] = itineraryMatrix[boxSize * i + k];
}
}
}
}
+ free(adjacentMatrix);
+}
+
+void ScummEngine::createBoxMatrix() {
+ int num, i, j;
+
+ // The total number of boxes
+ num = getNumBoxes();
+
+ const uint8 boxSize = (_game.version == 0) ? num : 64;
+
+ // calculate shortest paths
+ byte *itineraryMatrix = (byte *)malloc(boxSize * boxSize);
+ calcItineraryMatrix(itineraryMatrix, num);
+
// "Compress" the distance matrix into the box matrix format used
// by the engine. The format is like this:
// For each box (from 0 to num) there is first a byte with value 0xFF,
@@ -1015,10 +1031,10 @@
for (i = 0; i < num; i++) {
addToMatrix(0xFF);
for (j = 0; j < num; j++) {
- byte itinerary = itineraryMatrix[64 * i + j];
+ byte itinerary = itineraryMatrix[boxSize * i + j];
if (itinerary != Actor::kInvalidBox) {
addToMatrix(j);
- while (j < num - 1 && itinerary == itineraryMatrix[64 * i + (j + 1)])
+ while (j < num - 1 && itinerary == itineraryMatrix[boxSize * i + (j + 1)])
j++;
addToMatrix(j);
addToMatrix(itinerary);
@@ -1035,7 +1051,6 @@
printMatrix(getBoxMatrixBaseAddr(), num);
#endif
- free(adjacentMatrix);
free(itineraryMatrix);
}
@@ -1137,6 +1152,41 @@
return false;
}
+bool ScummEngine_v0::areBoxesNeighbours(int box1nr, int box2nr) {
+ int i;
+ const int numOfBoxes = getNumBoxes();
+ const byte *boxm;
+
+ assert(box1nr < numOfBoxes);
+ assert(box2nr < numOfBoxes);
+
+ boxm = getBoxMatrixBaseAddr();
+ // TODO: what are the first bytes for (mostly 0)?
+ boxm += 4;
+
+ // For each box, the matrix contains an arbitrary number
+ // of box indices that are linked with the box (neighbors).
+ // Each list is separated by 0xFF (|).
+ // E.g. "1 | 0 3 | 3 | 1 2" means:
+ // 0 -> 1, 1 -> 0/3, 2 -> 3, 3 -> 1/2
+
+ // Skip up to the matrix data for box 'box1nr'
+ for (i = 0; i < box1nr; i++) {
+ while (*boxm != 0xFF)
+ boxm++;
+ boxm++;
+ }
+
+ // Now search for the entry for box 'box2nr'
+ while (boxm[0] != 0xFF) {
+ if (boxm[0] == box2nr)
+ return true;
+ boxm++;
+ }
+
+ return false;
+}
+
void Actor_v3::findPathTowardsOld(byte box1, byte box2, byte finalBox, Common::Point &p2, Common::Point &p3) {
Common::Point gateA[2];
Common::Point gateB[2];
Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h 2009-10-27 09:44:13 UTC (rev 45436)
+++ scummvm/trunk/engines/scumm/scumm.h 2009-10-27 11:32:33 UTC (rev 45437)
@@ -1181,8 +1181,9 @@
void setBoxScaleSlot(int box, int slot);
void convertScaleTableToScaleSlot(int slot);
+ void calcItineraryMatrix(byte *itineraryMatrix, int num);
void createBoxMatrix();
- bool areBoxesNeighbours(int i, int j);
+ virtual bool areBoxesNeighbours(int i, int j);
/* String class */
public:
Modified: scummvm/trunk/engines/scumm/scumm_v0.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm_v0.h 2009-10-27 09:44:13 UTC (rev 45436)
+++ scummvm/trunk/engines/scumm/scumm_v0.h 2009-10-27 11:32:33 UTC (rev 45437)
@@ -96,6 +96,8 @@
virtual void resetSentence(bool walking = false);
+ virtual bool areBoxesNeighbours(int box1nr, int box2nr);
+
/* Version C64 script opcodes */
void o_stopCurrentScript();
void o_loadSound();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list