Ticket #9074: mm64-walkbox.patch
File mm64-walkbox.patch, 6.5 KB (added by , 15 years ago) |
---|
-
engines/scumm/boxes.cpp
26 26 #include "scumm/scumm.h" 27 27 #include "scumm/actor.h" 28 28 #include "scumm/boxes.h" 29 #include "scumm/scumm_v0.h" 29 30 #include "scumm/scumm_v6.h" 30 31 #include "scumm/util.h" 31 32 … … 712 713 boxm = getBoxMatrixBaseAddr(); 713 714 714 715 if (_game.version == 0) { 715 // Skip up to the matrix data for box 'from' 716 for (i = 0; i < from; i++) { 717 while (*boxm != 0xFF) 718 boxm++; 719 boxm++; 720 } 716 // calculate shortest paths 717 byte *itineraryMatrix = (byte *)malloc(numOfBoxes * numOfBoxes); 718 calcItineraryMatrix(itineraryMatrix, numOfBoxes); 721 719 722 // Now search for the entry for box 'to' 723 while (boxm[0] != 0xFF) { 724 if (boxm[0] == to) 725 dest = (int8)boxm[0]; 726 boxm++; 727 } 720 dest = to; 721 do { 722 dest = itineraryMatrix[numOfBoxes * from + dest]; 723 } while (dest != Actor::kInvalidBox && !areBoxesNeighbours(from, dest)); 728 724 725 if (dest == Actor::kInvalidBox) 726 dest = -1; 727 728 free(itineraryMatrix); 729 729 return dest; 730 730 } else if (_game.version <= 2) { 731 731 // The v2 box matrix is a real matrix with numOfBoxes rows and columns. … … 932 932 for (i = 0; i < num; i++) { 933 933 printf("%2d: ", i); 934 934 for (j = 0; j < num; j++) { 935 int val = matrix[i * 64+ j];935 int val = matrix[i * num + j]; 936 936 if (val == Actor::kInvalidBox) 937 937 printf(" ? "); 938 938 else … … 943 943 } 944 944 #endif 945 945 946 void ScummEngine::createBoxMatrix() { 947 int num, i, j, k; 948 byte *adjacentMatrix, *itineraryMatrix; 946 /** 947 * Computes shortest paths and stores them in the itinerary matrix. 948 * Parameter "num" holds the number of rows (= number of columns). 949 */ 950 void ScummEngine::calcItineraryMatrix(byte *itineraryMatrix, int num) { 951 int i, j, k; 952 byte *adjacentMatrix; 949 953 950 // The total number of boxes951 num = getNumBoxes();952 assert(num <= 64);953 954 954 // Allocate the adjacent & itinerary matrices 955 adjacentMatrix = (byte *)malloc(64 * 64); 956 itineraryMatrix = (byte *)malloc(64 * 64); 955 adjacentMatrix = (byte *)malloc(num * num); 957 956 958 957 // Initialise the adjacent matrix: each box has distance 0 to itself, 959 958 // and distance 1 to its direct neighbors. Initially, it has distance … … 961 960 for (i = 0; i < num; i++) { 962 961 for (j = 0; j < num; j++) { 963 962 if (i == j) { 964 adjacentMatrix[i * 64+ j] = 0;965 itineraryMatrix[i * 64+ j] = j;963 adjacentMatrix[i * num + j] = 0; 964 itineraryMatrix[i * num + j] = j; 966 965 } else if (areBoxesNeighbours(i, j)) { 967 adjacentMatrix[i * 64+ j] = 1;968 itineraryMatrix[i * 64+ j] = j;966 adjacentMatrix[i * num + j] = 1; 967 itineraryMatrix[i * num + j] = j; 969 968 } else { 970 adjacentMatrix[i * 64+ j] = 255;971 itineraryMatrix[i * 64+ j] = Actor::kInvalidBox;969 adjacentMatrix[i * num + j] = 255; 970 itineraryMatrix[i * num + j] = Actor::kInvalidBox; 972 971 } 973 972 } 974 973 } … … 984 983 for (j = 0; j < num; j++) { 985 984 if (i == j) 986 985 continue; 987 byte distIK = adjacentMatrix[ 64* i + k];988 byte distKJ = adjacentMatrix[ 64* k + j];989 if (adjacentMatrix[ 64* i + j] > distIK + distKJ) {990 adjacentMatrix[ 64* i + j] = distIK + distKJ;991 itineraryMatrix[ 64 * i + j] = itineraryMatrix[64* i + k];986 byte distIK = adjacentMatrix[num * i + k]; 987 byte distKJ = adjacentMatrix[num * k + j]; 988 if (adjacentMatrix[num * i + j] > distIK + distKJ) { 989 adjacentMatrix[num * i + j] = distIK + distKJ; 990 itineraryMatrix[num * i + j] = itineraryMatrix[num * i + k]; 992 991 } 993 992 } 994 993 } 995 994 996 995 } 997 996 997 free(adjacentMatrix); 998 } 999 1000 void ScummEngine::createBoxMatrix() { 1001 int num, i, j; 1002 1003 // The total number of boxes 1004 num = getNumBoxes(); 1005 1006 // calculate shortest paths 1007 byte *itineraryMatrix = (byte *)malloc(num * num); 1008 calcItineraryMatrix(itineraryMatrix, num); 1009 998 1010 // "Compress" the distance matrix into the box matrix format used 999 1011 // by the engine. The format is like this: 1000 1012 // For each box (from 0 to num) there is first a byte with value 0xFF, … … 1015 1027 for (i = 0; i < num; i++) { 1016 1028 addToMatrix(0xFF); 1017 1029 for (j = 0; j < num; j++) { 1018 byte itinerary = itineraryMatrix[ 64* i + j];1030 byte itinerary = itineraryMatrix[num * i + j]; 1019 1031 if (itinerary != Actor::kInvalidBox) { 1020 1032 addToMatrix(j); 1021 while (j < num - 1 && itinerary == itineraryMatrix[ 64* i + (j + 1)])1033 while (j < num - 1 && itinerary == itineraryMatrix[num * i + (j + 1)]) 1022 1034 j++; 1023 1035 addToMatrix(j); 1024 1036 addToMatrix(itinerary); … … 1035 1047 printMatrix(getBoxMatrixBaseAddr(), num); 1036 1048 #endif 1037 1049 1038 free(adjacentMatrix);1039 1050 free(itineraryMatrix); 1040 1051 } 1041 1052 … … 1137 1148 return false; 1138 1149 } 1139 1150 1151 bool ScummEngine_v0::areBoxesNeighbours(int box1nr, int box2nr) { 1152 int i; 1153 const int numOfBoxes = getNumBoxes(); 1154 const byte *boxm; 1155 1156 assert(box1nr < numOfBoxes); 1157 assert(box2nr < numOfBoxes); 1158 1159 boxm = getBoxMatrixBaseAddr(); 1160 // TODO: what are the first bytes for (mostly 0)? 1161 boxm += 4; 1162 1163 // For each box, the matrix contains an arbitrary number 1164 // of box indices that are linked with the box (neighbors). 1165 // Each list is separated by 0xFF (|). 1166 // E.g. "1 | 0 3 | 3 | 1 2" means: 1167 // 0 -> 1, 1 -> 0/3, 2 -> 3, 3 -> 1/2 1168 1169 // Skip up to the matrix data for box 'box1nr' 1170 for (i = 0; i < box1nr; i++) { 1171 while (*boxm != 0xFF) 1172 boxm++; 1173 boxm++; 1174 } 1175 1176 // Now search for the entry for box 'box2nr' 1177 while (boxm[0] != 0xFF) { 1178 if (boxm[0] == box2nr) 1179 return true; 1180 boxm++; 1181 } 1182 1183 return false; 1184 } 1185 1140 1186 void Actor_v3::findPathTowardsOld(byte box1, byte box2, byte finalBox, Common::Point &p2, Common::Point &p3) { 1141 1187 Common::Point pt; 1142 1188 Common::Point gateA[2]; -
engines/scumm/scumm.h
1178 1178 void setBoxScaleSlot(int box, int slot); 1179 1179 void convertScaleTableToScaleSlot(int slot); 1180 1180 1181 void calcItineraryMatrix(byte *itineraryMatrix, int num); 1181 1182 void createBoxMatrix(); 1182 bool areBoxesNeighbours(int i, int j);1183 virtual bool areBoxesNeighbours(int i, int j); 1183 1184 1184 1185 /* String class */ 1185 1186 public: -
engines/scumm/scumm_v0.h
96 96 97 97 virtual void resetSentence(bool walking = false); 98 98 99 virtual bool areBoxesNeighbours(int box1nr, int box2nr); 100 99 101 /* Version C64 script opcodes */ 100 102 void o_stopCurrentScript(); 101 103 void o_loadSound();