internal int GetNextBox(byte from, byte to)
{
byte i;
int numOfBoxes = GetNumBoxes();
int dest = -1;
if (from == to)
return to;
if (to == InvalidBox)
return -1;
if (from == InvalidBox)
return to;
if (from >= numOfBoxes)
throw new ArgumentOutOfRangeException("from");
if (to >= numOfBoxes)
throw new ArgumentOutOfRangeException("to");
var boxm = _boxMatrix;
if (Game.Version == 0)
{
// calculate shortest paths
var itineraryMatrix = CalcItineraryMatrix(numOfBoxes);
dest = to;
do
{
dest = itineraryMatrix[from, dest];
} while (dest != InvalidBox && !AreBoxesNeighbors(from, (byte)dest));
if (dest == InvalidBox)
dest = -1;
return dest;
}
else if (Game.Version <= 2)
{
// The v2 box matrix is a real matrix with numOfBoxes rows and columns.
// The first numOfBoxes bytes contain indices to the start of the corresponding
// row (although that seems unnecessary to me - the value is easily computable.
return (sbyte)boxm[numOfBoxes + boxm[from] + to];
}
// WORKAROUND #1: It seems that in some cases, the box matrix is corrupt
// (more precisely, is too short) in the datafiles already. In
// particular this seems to be the case in room 46 of Indy3 EGA (see
// also bug #770690). This didn't cause problems in the original
// engine, because there, the memory layout is different. After the
// walkbox would follow the rest of the room file, thus the program
// always behaved the same (and by chance, correct). Not so for us,
// since random data may follow after the resource in ScummVM.
//
// As a workaround, we add a check for the end of the box matrix
// resource, and abort the search once we reach the end.
int boxmIndex = _boxMatrix[0] == 0xFF ? 1 : 0;
// Skip up to the matrix data for box 'from'
for (i = 0; i < from && boxmIndex < boxm.Count; i++)
{
while (boxmIndex < boxm.Count && boxm[boxmIndex] != 0xFF)
boxmIndex += 3;
boxmIndex++;
}
// Now search for the entry for box 'to'
while (boxmIndex < boxm.Count && boxm[boxmIndex] != 0xFF)
{
if (boxm[boxmIndex] <= to && to <= boxm[boxmIndex + 1])
dest = (sbyte)boxm[boxmIndex + 2];
boxmIndex += 3;
}
//if (boxm >= boxm.Count)
// debug(0, "The box matrix apparently is truncated (room %d)", _roomResource);
return dest;
}