[Scummvm-git-logs] scummvm master -> 4353765c3289b62d2fdc19e53945a0c34fea3418

AndywinXp noreply at scummvm.org
Sat Jul 6 19:12:15 UTC 2024


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4353765c32 SCUMM: HE: Relabel and clean-up arrays subsystem


Commit: 4353765c3289b62d2fdc19e53945a0c34fea3418
    https://github.com/scummvm/scummvm/commit/4353765c3289b62d2fdc19e53945a0c34fea3418
Author: AndywinXp (andywinxp at gmail.com)
Date: 2024-07-06T21:12:04+02:00

Commit Message:
SCUMM: HE: Relabel and clean-up arrays subsystem

I wanted to do this for a very long time. This is helping me
debugging some very hard to understand remaining bugs
on some SCUMM HE games.

I tested this for several hours with several games,
including Moonbase and some Backyard games
ensuring there were no obvious regressions.

Changed paths:
    engines/scumm/he/intern_he.h
    engines/scumm/he/logic/football.cpp
    engines/scumm/he/net/net_lobby.cpp
    engines/scumm/he/net/net_main.cpp
    engines/scumm/he/script_v100he.cpp
    engines/scumm/he/script_v60he.cpp
    engines/scumm/he/script_v72he.cpp
    engines/scumm/he/script_v80he.cpp
    engines/scumm/he/script_v90he.cpp
    engines/scumm/resource.cpp
    engines/scumm/script_v6.cpp


diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index e798e971bbe..0dddfd84cb1 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -35,6 +35,8 @@ class SeekableWriteStream;
 
 namespace Scumm {
 
+#define MAGIC_ARRAY_NUMBER 0x33539000
+
 class ActorHE;
 class ResExtractor;
 #ifdef ENABLE_HE
@@ -383,12 +385,12 @@ protected:
 #include "common/pack-start.h"	// START STRUCT PACKING
 
 	struct ArrayHeader {
-		int32 type;      //0
-		int32 dim1start; //4
-		int32 dim1end;   //8
-		int32 dim2start; //0C
-		int32 dim2end;   //10
-		byte data[1];    //14
+		int32 type;
+		int32 acrossMin;
+		int32 acrossMax;
+		int32 downMin;
+		int32 downMax;
+		byte data[1];
 	} PACKED_STRUCT;
 
 #include "common/pack-end.h"	// END STRUCT PACKING
@@ -421,17 +423,22 @@ protected:
 	void redrawBGAreas() override;
 	void checkExecVerbs() override;
 
-	byte *defineArray(int array, int type, int dim2start, int dim2end, int dim1start, int dim1end, bool newArray = false, int *newid = NULL);
+	byte *defineArray(int array, int type, int downMin, int downMax, int acrossMin, int acrossMax, bool newArray = false, int *newid = NULL);
 	int readArray(int array, int idx2, int idx1) override;
 	void writeArray(int array, int idx2, int idx1, int value) override;
 	void redimArray(int arrayId, int newDim2start, int newDim2end,
 					int newDim1start, int newDim1end, int type);
-	void checkArrayLimits(int array, int dim2start, int dim2end, int dim1start, int dim1end);
+	void checkArrayLimits(int array, int downMin, int downMax, int acrossMin, int acrossMax);
 	void copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end,
 					int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end);
-	void copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num);
+	void getArrayDataPtrAndDataSize(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num);
 	int readFileToArray(int slot, int32 size);
 	void writeFileFromArray(int slot, int32 resID);
+	void arrayBlockOperation(
+		int dstVariable, int dstDownMin, int dstDownMax, int dstAcrossMin, int dstAcrossMax,
+		int a2Variable, int a2DownMin, int a2DownMax, int a2AcrossMin, int a2AcrossMax,
+		int a1Variable, int a1DownMin, int a1DownMax, int a1AcrossMin, int a1AcrossMax,
+		int (*op)(int a2, int a1));
 
 	void decodeParseString(int a, int b) override;
 	void decodeScriptString(byte *dst, bool scriptString = false);
@@ -709,8 +716,8 @@ protected:
 	bool heAuxProcessFileRelativeBlock(HEAnimAuxData *auxInfoPtr, const byte *dataBlockPtr);
 	bool heAuxProcessDisplacedBlock(HEAnimAuxData *auxInfoPtr, const byte *displacedBlockPtr);
 
-	void getArrayDim(int array, int *dim2start, int *dim2end, int *dim1start, int *dim1end);
-	void sortArray(int array, int dim2start, int dim2end, int dim1start, int dim1end, int sortOrder);
+	void getArrayDim(int array, int *downMin, int *downMax, int *acrossMin, int *acrossMax);
+	void sortArray(int array, int downMin, int downMax, int acrossMin, int acrossMax, int sortOrder);
 
 public:
 	int getGroupSpriteArray(int spriteGroupId);
diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp
index b5c897efcf9..0b31d4a4220 100644
--- a/engines/scumm/he/logic/football.cpp
+++ b/engines/scumm/he/logic/football.cpp
@@ -623,7 +623,7 @@ int LogicHEfootball2002::getPlaybookFiles(int32 *args) {
 	// Get the pattern and then skip over the directory prefix ("*\" or "*:")
 	// Also prepend the target name
 	Common::String targetName = _vm->getTargetName();
-	Common::String basePattern = ((const char *)_vm->getStringAddress(args[0] & ~0x33539000) + 2);
+	Common::String basePattern = ((const char *)_vm->getStringAddress(args[0] & ~MAGIC_ARRAY_NUMBER) + 2);
 	Common::String pattern = targetName + '-' + basePattern;
 
 	// Prepare a buffer to hold the file names
diff --git a/engines/scumm/he/net/net_lobby.cpp b/engines/scumm/he/net/net_lobby.cpp
index 0782274fd02..dd79a1a98af 100644
--- a/engines/scumm/he/net/net_lobby.cpp
+++ b/engines/scumm/he/net/net_lobby.cpp
@@ -608,9 +608,9 @@ void Lobby::sendGameResults(int userId, int arrayIndex, int lastFlag) {
 	setProfileRequest.setVal("cmd", new Common::JSONValue("game_results"));
 	setProfileRequest.setVal("user", new Common::JSONValue((long long int)userId));
 
-	ScummEngine_v90he::ArrayHeader *ah = (ScummEngine_v90he::ArrayHeader *)_vm->getResourceAddress(rtString, arrayIndex & ~0x33539000);
-	int32 size = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
-		(FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
+	ScummEngine_v90he::ArrayHeader *ah = (ScummEngine_v90he::ArrayHeader *)_vm->getResourceAddress(rtString, arrayIndex & ~MAGIC_ARRAY_NUMBER);
+	int32 size = (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+		(FROM_LE_32(ah->downMax) - FROM_LE_32(ah->downMin) + 1);
 
 	Common::JSONArray arrayData;
 	for (int i = 0; i < size; i++) {
diff --git a/engines/scumm/he/net/net_main.cpp b/engines/scumm/he/net/net_main.cpp
index 785efba95bc..23c68e388db 100644
--- a/engines/scumm/he/net/net_main.cpp
+++ b/engines/scumm/he/net/net_main.cpp
@@ -836,16 +836,16 @@ int Net::remoteSendData(int typeOfSend, int sendTypeParam, int type, Common::Str
 }
 
 void Net::remoteSendArray(int typeOfSend, int sendTypeParam, int priority, int arrayIndex) {
-	debugC(DEBUG_NETWORK, "Net::remoteSendArray(%d, %d, %d, %d)", typeOfSend, sendTypeParam, priority, arrayIndex & ~0x33539000); // PN_RemoteSendArrayCommand
+	debugC(DEBUG_NETWORK, "Net::remoteSendArray(%d, %d, %d, %d)", typeOfSend, sendTypeParam, priority, arrayIndex & ~MAGIC_ARRAY_NUMBER); // PN_RemoteSendArrayCommand
 
-	ScummEngine_v90he::ArrayHeader *ah = (ScummEngine_v90he::ArrayHeader *)_vm->getResourceAddress(rtString, arrayIndex & ~0x33539000);
+	ScummEngine_v90he::ArrayHeader *ah = (ScummEngine_v90he::ArrayHeader *)_vm->getResourceAddress(rtString, arrayIndex & ~MAGIC_ARRAY_NUMBER);
 
 	Common::String jsonData = Common::String::format(
 		"\"type\":%d,\"dim1start\":%d,\"dim1end\":%d,\"dim2start\":%d,\"dim2end\":%d,\"data\":[",
-		ah->type, ah->dim1start, ah->dim1end, ah->dim2start, ah->dim2end);
+		ah->type, ah->acrossMin, ah->acrossMax, ah->downMin, ah->downMax);
 
-	int32 size = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
-		(FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
+	int32 size = (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+		(FROM_LE_32(ah->downMax) - FROM_LE_32(ah->downMin) + 1);
 
 	for (int i = 0; i < size; i++) {
 		int32 data;
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 46705ad98fc..29e28bb40ed 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -551,7 +551,7 @@ void ScummEngine_v100he::o100_actorOps() {
 void ScummEngine_v100he::o100_arrayOps() {
 	byte *data;
 	byte string[1024];
-	int dim1end, dim1start, dim2end, dim2start;
+	int acrossMax, acrossMin, downMax, downMin;
 	int id, len, b, c, list[128];
 	int offs, tmp, tmp2;
 	uint tmp3, type;
@@ -597,26 +597,26 @@ void ScummEngine_v100he::o100_arrayOps() {
 		break;
 	case SO_COMPLEX_ARRAY_ASSIGNMENT:
 		len = getStackList(list, ARRAYSIZE(list));
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
+		acrossMax = pop();
+		acrossMin = pop();
+		downMax = pop();
+		downMin = pop();
 		id = readVar(array);
 		if (id == 0) {
-			defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
+			defineArray(array, kDwordArray, downMin, downMax, acrossMin, acrossMax);
 		}
-		checkArrayLimits(array, dim2start, dim2end, dim1start, dim1end);
+		checkArrayLimits(array, downMin, downMax, acrossMin, acrossMax);
 
 		tmp2 = 0;
-		while (dim2start <= dim2end) {
-			tmp = dim1start;
-			while (tmp <= dim1end) {
-				writeArray(array, dim2start, tmp, list[tmp2++]);
+		while (downMin <= downMax) {
+			tmp = acrossMin;
+			while (tmp <= acrossMax) {
+				writeArray(array, downMin, tmp, list[tmp2++]);
 				if (tmp2 == len)
 					tmp2 = 0;
 				tmp++;
 			}
-			dim2start++;
+			downMin++;
 		}
 		break;
 	case SO_COMPLEX_ARRAY_COPY_OPERATION:
@@ -650,10 +650,10 @@ void ScummEngine_v100he::o100_arrayOps() {
 			int a2_dim1start = pop();
 			int a2_dim2end = pop();
 			int a2_dim2start = pop();
-			dim1end = pop();
-			dim1start = pop();
-			dim2end = pop();
-			dim2start = pop();
+			acrossMax = pop();
+			acrossMin = pop();
+			downMax = pop();
+			downMin = pop();
 
 			debug(0, "Complex: %d = %d[%d to %d][%d to %d] %c %d[%d to %d][%d to %d]", array,
 				array1, a1_dim1start, a1_dim2end, a1_dim1start, a1_dim2end,
@@ -664,21 +664,21 @@ void ScummEngine_v100he::o100_arrayOps() {
 			int a11_num = a1_dim1end - a1_dim1start + 1;
 			int a22_num = a2_dim2end - a2_dim2start + 1;
 			int a21_num = a2_dim1end - a2_dim1start + 1;
-			int d12_num = dim2end - dim2start + 1;
-			int d11_num = dim1end - dim1start + 1;
+			int d12_num = downMax - downMin + 1;
+			int d11_num = acrossMax - acrossMin + 1;
 
 			id = readVar(array);
 			if (id == 0) {
-				defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
+				defineArray(array, kDwordArray, downMin, downMax, acrossMin, acrossMax);
 			}
 			if (a12_num != a22_num || a12_num != d12_num || a11_num != a21_num || a11_num != d11_num) {
 				error("Operation size mismatch (%d vs %d)(%d vs %d)", a12_num, a22_num, a11_num, a21_num);
 			}
 
-			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start, ++a2_dim2start, ++dim2start) {
+			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start, ++a2_dim2start, ++downMin) {
 				int a2dim1 = a2_dim1start;
 				int a1dim1 = a1_dim1start;
-				int dim1 = dim1start;
+				int dim1 = acrossMin;
 				for (; a1dim1 <= a1_dim1end; ++a1dim1, ++a2dim1, ++dim1) {
 					int val1 = readArray(array1, a1_dim2start, a1dim1);
 					int val2 = readArray(array2, a2_dim2start, a2dim1);
@@ -703,7 +703,7 @@ void ScummEngine_v100he::o100_arrayOps() {
 					default:
 						error("o100_arrayOps: case 132 unknown type %d)", type);
 					}
-					writeArray(array, dim2start, dim1, res);
+					writeArray(array, downMin, dim1, res);
 				}
 			}
 			break;
@@ -711,23 +711,23 @@ void ScummEngine_v100he::o100_arrayOps() {
 	case SO_RANGE_ARRAY_ASSIGNMENT:
 		b = pop();
 		c = pop();
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
+		acrossMax = pop();
+		acrossMin = pop();
+		downMax = pop();
+		downMin = pop();
 		id = readVar(array);
 		if (id == 0) {
-			defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
+			defineArray(array, kDwordArray, downMin, downMax, acrossMin, acrossMax);
 		}
-		checkArrayLimits(array, dim2start, dim2end, dim1start, dim1end);
+		checkArrayLimits(array, downMin, downMax, acrossMin, acrossMax);
 
 		offs = (b >= c) ? 1 : -1;
 		tmp2 = c;
 		tmp3 = ABS(c - b) + 1;
-		while (dim2start <= dim2end) {
-			tmp = dim1start;
-			while (tmp <= dim1end) {
-				writeArray(array, dim2start, tmp, tmp2);
+		while (downMin <= downMax) {
+			tmp = acrossMin;
+			while (tmp <= acrossMax) {
+				writeArray(array, downMin, tmp, tmp2);
 				if (--tmp3 == 0) {
 					tmp2 = c;
 					tmp3 = ABS(c - b) + 1;
@@ -736,7 +736,7 @@ void ScummEngine_v100he::o100_arrayOps() {
 				}
 				tmp++;
 			}
-			dim2start++;
+			downMin++;
 		}
 		break;
 	default:
@@ -777,7 +777,7 @@ void ScummEngine_v100he::o100_createSound() {
 }
 
 void ScummEngine_v100he::o100_dim2dimArray() {
-	int data, dim1end, dim2end;
+	int data, acrossMax, downMax;
 
 	byte subOp = fetchScriptByte();
 
@@ -804,9 +804,9 @@ void ScummEngine_v100he::o100_dim2dimArray() {
 		error("o100_dim2dimArray: default case %d", subOp);
 	}
 
-	dim1end = pop();
-	dim2end = pop();
-	defineArray(fetchScriptWord(), data, 0, dim2end, 0, dim1end);
+	acrossMax = pop();
+	downMax = pop();
+	defineArray(fetchScriptWord(), data, 0, downMax, 0, acrossMax);
 }
 
 void ScummEngine_v100he::o100_dimArray() {
@@ -1420,7 +1420,7 @@ void ScummEngine_v100he::o100_wizImageOps() {
 }
 
 void ScummEngine_v100he::o100_dim2dim2Array() {
-	int data, dim1start, dim1end, dim2start, dim2end;
+	int data, acrossMin, acrossMax, downMin, downMax;
 
 	byte subOp = fetchScriptByte();
 
@@ -1448,18 +1448,18 @@ void ScummEngine_v100he::o100_dim2dim2Array() {
 	}
 
 	if (pop() == 2) {
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
+		acrossMax = pop();
+		acrossMin = pop();
+		downMax = pop();
+		downMin = pop();
 	} else {
-		dim2end = pop();
-		dim2start = pop();
-		dim1end = pop();
-		dim1start = pop();
+		downMax = pop();
+		downMin = pop();
+		acrossMax = pop();
+		acrossMin = pop();
 	}
 
-	defineArray(fetchScriptWord(), data, dim2start, dim2end, dim1start, dim1end);
+	defineArray(fetchScriptWord(), data, downMin, downMax, acrossMin, acrossMax);
 }
 
 void ScummEngine_v100he::o100_redim2dimArray() {
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index 1b4bcc8065e..9a4541011e7 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -1035,7 +1035,7 @@ void ScummEngine_v60he::o60_soundOps() {
 
 void ScummEngine_v60he::localizeArray(int slot, byte scriptSlot) {
 	if (_game.heversion >= 80)
-		slot &= ~0x33539000;
+		slot &= ~MAGIC_ARRAY_NUMBER;
 
 	if (slot >= _numArray)
 		error("o60_localizeArrayToScript(%d): array slot out of range", slot);
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 59ef476d085..a443d568a27 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -101,14 +101,14 @@ void ScummEngine_v72he::setupOpcodes() {
 
 static const int arrayDataSizes[] = { 0, 1, 4, 8, 8, 16, 32 };
 
-byte *ScummEngine_v72he::defineArray(int array, int type, int dim2start, int dim2end,
-											int dim1start, int dim1end, bool newArray, int *newid) {
-	int id;
+byte *ScummEngine_v72he::defineArray(int array, int type, int downMin, int downMax,
+											int acrossMin, int acrossMax, bool newArray, int *newid) {
+	int arrayPtr;
 	int size;
 	ArrayHeader *ah;
 
-	assert(dim2start >= 0 && dim2start <= dim2end);
-	assert(dim1start >= 0 && dim1start <= dim1end);
+	assert(downMin >= 0 && downMin <= downMax);
+	assert(acrossMin >= 0 && acrossMin <= acrossMax);
 	assert(0 <= type && type <= 6);
 
 
@@ -118,45 +118,37 @@ byte *ScummEngine_v72he::defineArray(int array, int type, int dim2start, int dim
 	if (!newArray)
 		nukeArray(array);
 
-	id = findFreeArrayId();
+	arrayPtr = findFreeArrayId();
 
-	if (newid != NULL)
-		*newid = id;
+	if (newid)
+		*newid = arrayPtr;
 
-	debug(9, "defineArray (array %d, dim2start %d, dim2end %d dim1start %d dim1end %d", id, dim2start, dim2end, dim1start, dim1end);
+	debug(9, "defineArray (array %d, downMin %d, downMax %d acrossMin %d acrossMax %d", arrayPtr, downMin, downMax, acrossMin, acrossMax);
 
 	if (!newArray && (array & 0x80000000)) {
 		error("Can't define bit variable as array pointer");
 	}
 
-	size = arrayDataSizes[type];
-
-	if (_game.heversion >= 80)
-		id |= 0x33539000;
-
 	if (!newArray)
-		writeVar(array, id);
+		writeVar(array, (_game.heversion >= 80 ? (arrayPtr | MAGIC_ARRAY_NUMBER) : arrayPtr));
 
-	if (_game.heversion >= 80)
-		id &= ~0x33539000;
+	size = ((downMax - downMin + 1) * (acrossMax - acrossMin + 1) * arrayDataSizes[type]) / 8;
 
-	size *= dim2end - dim2start + 1;
-	size *= dim1end - dim1start + 1;
-	size >>= 3;
-
-	ah = (ArrayHeader *)_res->createResource(rtString, id, size + sizeof(ArrayHeader));
+	ah = (ArrayHeader *)_res->createResource(rtString,
+		(_game.heversion >= 80 ? (arrayPtr & ~MAGIC_ARRAY_NUMBER) : arrayPtr),
+		size + sizeof(ArrayHeader));
 
 	ah->type = TO_LE_32(type);
-	ah->dim1start = TO_LE_32(dim1start);
-	ah->dim1end = TO_LE_32(dim1end);
-	ah->dim2start = TO_LE_32(dim2start);
-	ah->dim2end = TO_LE_32(dim2end);
+	ah->acrossMin = TO_LE_32(acrossMin);
+	ah->acrossMax = TO_LE_32(acrossMax);
+	ah->downMin = TO_LE_32(downMin);
+	ah->downMax = TO_LE_32(downMax);
 
 	return ah->data;
 }
 
 int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
-	debug(9, "readArray (array %d, idx2 %d, idx1 %d)", readVar(array), idx2, idx1);
+	debug(9, "readArray (array %d, down %d, aMin %d)", readVar(array), idx2, idx1);
 
 	if (readVar(array) == 0)
 		error("readArray: Reference to zeroed array pointer");
@@ -166,11 +158,11 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
 	if (!ah)
 		error("readArray: invalid array %d (%d)", array, readVar(array));
 
-	if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
-		idx1 < (int)FROM_LE_32(ah->dim1start) || idx1 > (int)FROM_LE_32(ah->dim1end)) {
+	if (idx2 < (int)FROM_LE_32(ah->downMin) || idx2 > (int)FROM_LE_32(ah->downMax) ||
+		idx1 < (int)FROM_LE_32(ah->acrossMin) || idx1 > (int)FROM_LE_32(ah->acrossMax)) {
 		error("readArray: array %d out of bounds: [%d, %d] exceeds [%d..%d, %d..%d]",
-			  array, idx1, idx2, FROM_LE_32(ah->dim1start), FROM_LE_32(ah->dim1end),
-			  FROM_LE_32(ah->dim2start), FROM_LE_32(ah->dim2end));
+			  array, idx1, idx2, FROM_LE_32(ah->acrossMin), FROM_LE_32(ah->acrossMax),
+			  FROM_LE_32(ah->downMin), FROM_LE_32(ah->downMax));
 	}
 
 #if defined(USE_ENET) && defined(USE_LIBCURL)
@@ -198,8 +190,8 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
 	}
 #endif
 
-	const int offset = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
-		(idx2 - FROM_LE_32(ah->dim2start)) + (idx1 - FROM_LE_32(ah->dim1start));
+	const int offset = (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+		(idx2 - FROM_LE_32(ah->downMin)) + (idx1 - FROM_LE_32(ah->acrossMin));
 
 	switch (FROM_LE_32(ah->type)) {
 	case kByteArray:
@@ -220,7 +212,7 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
 }
 
 void ScummEngine_v72he::writeArray(int array, int idx2, int idx1, int value) {
-	debug(9, "writeArray (array %d, idx2 %d, idx1 %d, value %d)", readVar(array), idx2, idx1, value);
+	debug(9, "writeArray (array %d, down %d, aMin %d, value %d)", readVar(array), idx2, idx1, value);
 
 	if (readVar(array) == 0)
 		error("writeArray: Reference to zeroed array pointer");
@@ -230,15 +222,15 @@ void ScummEngine_v72he::writeArray(int array, int idx2, int idx1, int value) {
 	if (!ah)
 		error("writeArray: Invalid array (%d) reference", readVar(array));
 
-	if (idx2 < (int)FROM_LE_32(ah->dim2start) || idx2 > (int)FROM_LE_32(ah->dim2end) ||
-		idx1 < (int)FROM_LE_32(ah->dim1start) || idx1 > (int)FROM_LE_32(ah->dim1end)) {
+	if (idx2 < (int)FROM_LE_32(ah->downMin) || idx2 > (int)FROM_LE_32(ah->downMax) ||
+		idx1 < (int)FROM_LE_32(ah->acrossMin) || idx1 > (int)FROM_LE_32(ah->acrossMax)) {
 		error("writeArray: array %d out of bounds: [%d, %d] exceeds [%d..%d, %d..%d]",
-			  array, idx1, idx2, FROM_LE_32(ah->dim1start), FROM_LE_32(ah->dim1end),
-			  FROM_LE_32(ah->dim2start), FROM_LE_32(ah->dim2end));
+			  array, idx1, idx2, FROM_LE_32(ah->acrossMin), FROM_LE_32(ah->acrossMax),
+			  FROM_LE_32(ah->downMin), FROM_LE_32(ah->downMax));
 	}
 
-	const int offset = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
-		(idx2 - FROM_LE_32(ah->dim2start)) - FROM_LE_32(ah->dim1start) + idx1;
+	const int offset = (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+		(idx2 - FROM_LE_32(ah->downMin)) - FROM_LE_32(ah->acrossMin) + idx1;
 
 	switch (FROM_LE_32(ah->type)) {
 	case kByteArray:
@@ -299,6 +291,68 @@ void ScummEngine_v72he::readArrayFromIndexFile() {
 	}
 }
 
+void ScummEngine_v72he::arrayBlockOperation(
+	int dstVariable, int dstDownMin, int dstDownMax, int dstAcrossMin, int dstAcrossMax,
+	int a2Variable, int a2DownMin, int a2DownMax, int a2AcrossMin, int a2AcrossMax,
+	int a1Variable, int a1DownMin, int a1DownMax, int a1AcrossMin, int a1AcrossMax,
+	int (*op)(int a2, int a1)) {
+	int downCount, acrossCount;
+	int dstD, dstA, a1D, a1A, a2D, a2A;
+	int dstDIndex, dstAIndex;
+	int a1DIndex, a1AIndex;
+	int a2DIndex, a2AIndex;
+
+	checkArrayLimits(dstVariable, dstDownMin, dstDownMax, dstAcrossMin, dstAcrossMax);
+	checkArrayLimits(a2Variable, a2DownMin, a2DownMax, a2AcrossMin, a2AcrossMax);
+	checkArrayLimits(a1Variable, a1DownMin, a1DownMax, a1AcrossMin, a1AcrossMax);
+
+	dstD = ((dstDownMax - dstDownMin) + 1);
+	dstA = ((dstAcrossMax - dstAcrossMin) + 1);
+	a1D = ((a1DownMax - a1DownMin) + 1);
+	a1A = ((a1AcrossMax - a1AcrossMin) + 1);
+	a2D = ((a2DownMax - a2DownMin) + 1);
+	a2A = ((a2AcrossMax - a2AcrossMin) + 1);
+
+	if (((dstD != a1D) || (a1D != a2D)) || ((dstA != a1A) || (a1A != a2A))) {
+
+		debug("ScummEngine_v72he::arrayBlockOperation(): "
+			"{%8d}[ %4d to %4d ][ %4d to %4d ] = "
+			"({%8d}[ %4d to %4d ][ %4d to %4d ] <?> "
+			"{%8d}[ %4d to %4d ][ %4d to %4d ] <%d>)\n",
+			dstVariable, dstDownMin, dstDownMax, dstAcrossMin, dstAcrossMax,
+			a2Variable, a2DownMin, a2DownMax, a2AcrossMin, a2AcrossMax,
+			a1Variable, a1DownMin, a1DownMax, a1AcrossMin, a1AcrossMax);
+
+		error("Invalid ranges for array block math operation");
+	}
+
+	acrossCount = dstA;
+	downCount = dstD;
+
+	dstDIndex = dstDownMin;
+	a1DIndex = a1DownMin;
+	a2DIndex = a2DownMin;
+
+	for (int downCounter = 0; downCounter < downCount; downCounter++) {
+		dstAIndex = dstAcrossMin;
+		a1AIndex = a1AcrossMin;
+		a2AIndex = a2AcrossMin;
+
+		for (int acrossCounter = 0; acrossCounter < acrossCount; acrossCounter++) {
+			writeArray(dstVariable, dstDIndex, dstAIndex,
+				(*op)(readArray(a2Variable, a2DIndex, a2AIndex), readArray(a1Variable, a1DIndex, a1AIndex)));
+
+			dstAIndex++;
+			a1AIndex++;
+			a2AIndex++;
+		}
+
+		dstDIndex++;
+		a1DIndex++;
+		a2DIndex++;
+	}
+}
+
 void ScummEngine_v72he::copyScriptString(byte *dst, int dstSize) {
 	byte string[1024];
 	byte chr;
@@ -648,7 +702,7 @@ void ScummEngine_v72he::o72_printWizImage() {
 
 void ScummEngine_v72he::o72_getArrayDimSize() {
 	byte subOp = fetchScriptByte();
-	int32 val1, val2;
+	int32 maxValue, minValue;
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(fetchScriptWord()));
 	if (!ah) {
 		push(0);
@@ -658,26 +712,26 @@ void ScummEngine_v72he::o72_getArrayDimSize() {
 	switch (subOp) {
 	case SO_NONE:
 	case SO_NIBBLE:
-		val1 = FROM_LE_32(ah->dim1end);
-		val2 = FROM_LE_32(ah->dim1start);
-		push(val1 - val2 + 1);
+		maxValue = FROM_LE_32(ah->acrossMax);
+		minValue = FROM_LE_32(ah->acrossMin);
+		push(maxValue - minValue + 1);
 		break;
 	case SO_BIT:
-		val1 = FROM_LE_32(ah->dim2end);
-		val2 = FROM_LE_32(ah->dim2start);
-		push(val1 - val2 + 1);
+		maxValue = FROM_LE_32(ah->downMax);
+		minValue = FROM_LE_32(ah->downMin);
+		push(maxValue - minValue + 1);
 		break;
 	case SO_BYTE:
-		push(FROM_LE_32(ah->dim1start));
+		push(FROM_LE_32(ah->acrossMin));
 		break;
 	case SO_INT:
-		push(FROM_LE_32(ah->dim1end));
+		push(FROM_LE_32(ah->acrossMax));
 		break;
 	case SO_DWORD:
-		push(FROM_LE_32(ah->dim2start));
+		push(FROM_LE_32(ah->downMin));
 		break;
 	case SO_STRING:
-		push(FROM_LE_32(ah->dim2end));
+		push(FROM_LE_32(ah->downMax));
 		break;
 	default:
 		error("o72_getArrayDimSize: default case %d", subOp);
@@ -1142,13 +1196,31 @@ void ScummEngine_v72he::o72_findObject() {
 	push(r);
 }
 
+static int arrayBlockSubOp(int a2, int a1) {
+	return (a2 - a1);
+}
+
+static int arrayBlockAddOp(int a2, int a1) {
+	return (a2 + a1);
+}
+
+static int arrayBlockBANDOp(int a2, int a1) {
+	return (a2 & a1);
+}
+
+static int arrayBlockBOROp(int a2, int a1) {
+	return (a2 | a1);
+}
+
+static int arrayBlockBXOROp(int a2, int a1) {
+	return (a2 ^ a1);
+}
+
 void ScummEngine_v72he::o72_arrayOps() {
 	byte *data;
 	byte string[1024];
-	int dim1end, dim1start, dim2end, dim2start;
+	int acrossMax, acrossMin, downMax, downMin;
 	int id, len, b, c, list[128];
-	int offs, tmp, tmp2;
-	uint tmp3, type;
 
 	byte subOp = fetchScriptByte();
 	int array = fetchScriptWord();
@@ -1163,150 +1235,185 @@ void ScummEngine_v72he::o72_arrayOps() {
 		break;
 
 	case SO_COMPLEX_ARRAY_ASSIGNMENT:
-		len = getStackList(list, ARRAYSIZE(list));
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
-		id = readVar(array);
-		if (id == 0) {
-			defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
-		}
-		checkArrayLimits(array, dim2start, dim2end, dim1start, dim1end);
-
-		tmp2 = 0;
-		while (dim2start <= dim2end) {
-			tmp = dim1start;
-			while (tmp <= dim1end) {
-				writeArray(array, dim2start, tmp, list[tmp2++]);
-				if (tmp2 == len)
-					tmp2 = 0;
-				tmp++;
+		{
+			len = getStackList(list, ARRAYSIZE(list));
+			acrossMax = pop();
+			acrossMin = pop();
+			downMax = pop();
+			downMin = pop();
+			id = readVar(array);
+
+			if (id == 0) {
+				defineArray(array, kDwordArray, downMin, downMax, acrossMin, acrossMax);
+			}
+
+			checkArrayLimits(array, downMin, downMax, acrossMin, acrossMax);
+
+			int *currPtr = list;
+			int countDown = len;
+
+			for (int downCounter = downMin; downCounter <= downMax; downCounter++) {
+				for (int acrossCounter = acrossMin; acrossCounter <= acrossMax; acrossCounter++) {
+					writeArray(array, downCounter, acrossCounter, *currPtr++);
+
+					if (!--countDown) {
+						countDown = len;
+						currPtr = list;
+					}
+				}
 			}
-			dim2start++;
 		}
+
 		break;
 	case SO_COMPLEX_ARRAY_COPY_OPERATION:
 		{
-			int a2_dim1end = pop();
-			int a2_dim1start = pop();
-			int a2_dim2end = pop();
-			int a2_dim2start = pop();
-			int array2 = fetchScriptWord();
-			int a1_dim1end = pop();
-			int a1_dim1start = pop();
-			int a1_dim2end = pop();
-			int a1_dim2start = pop();
-			if (a1_dim1end - a1_dim1start != a2_dim1end - a2_dim1start || a2_dim2end - a2_dim2start != a1_dim2end - a1_dim2start) {
-				error("Source and dest ranges size are mismatched");
+			int srcAcrossMax = pop();
+			int srcAcrossMin = pop();
+			int srcDownMax = pop();
+			int srcDownMin = pop();
+			int srcVariable = fetchScriptWord();
+			int dstAcrossMax = pop();
+			int dstAcrossMin = pop();
+			int dstDownMax = pop();
+			int dstDownMin = pop();
+
+			if (dstAcrossMax - dstAcrossMin != srcAcrossMax - srcAcrossMin || srcDownMax - srcDownMin != dstDownMax - dstDownMin) {
+				error("Source and dest ranges dataOffsetPtr are mismatched");
 			}
-			copyArray(array, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end, array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
+
+			copyArray(array, dstDownMin, dstDownMax, dstAcrossMin, dstAcrossMax, srcVariable, srcDownMin, srcDownMax, srcAcrossMin, srcAcrossMax);
 		}
+
 		break;
 	case SO_RANGE_ARRAY_ASSIGNMENT:
-		b = pop();
-		c = pop();
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
-		id = readVar(array);
-		if (id == 0) {
-			defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
-		}
-		checkArrayLimits(array, dim2start, dim2end, dim1start, dim1end);
-
-		offs = (b >= c) ? 1 : -1;
-		tmp2 = c;
-		tmp3 = ABS(c - b) + 1;
-		while (dim2start <= dim2end) {
-			tmp = dim1start;
-			while (tmp <= dim1end) {
-				writeArray(array, dim2start, tmp, tmp2);
-				if (--tmp3 == 0) {
-					tmp2 = c;
-					tmp3 = ABS(c - b) + 1;
-				} else {
-					tmp2 += offs;
+		{
+			int rangeEnd = pop();
+			int rangeStart = pop();
+			acrossMax = pop();
+			acrossMin = pop();
+			downMax = pop();
+			downMin = pop();
+			id = readVar(array);
+
+			if (id == 0) {
+				defineArray(array, kDwordArray, downMin, downMax, acrossMin, acrossMax);
+			}
+
+			checkArrayLimits(array, downMin, downMax, acrossMin, acrossMax);
+
+			int value = rangeStart;
+			int count = ABS(rangeStart - rangeEnd) + 1;
+			int stepValue = (rangeStart <= rangeEnd) ? 1 : -1;
+			int countDown = count;
+
+			for (int downCounter = downMin; downCounter <= downMax; downCounter++) {
+				for (int acrossCounter = acrossMin; acrossCounter <= acrossMax; acrossCounter++) {
+					writeArray(array, downCounter, acrossCounter, value);
+
+					if (!--countDown) {
+						value = rangeStart;
+						countDown = count;
+					} else {
+						value += stepValue;
+					}
 				}
-				tmp++;
 			}
-			dim2start++;
 		}
+
 		break;
 	case SO_COMPLEX_ARRAY_MATH_OPERATION:
-			{
-				// Used by script 84 (Send end of play info) in Backyard Football during online play.
-				int array2 = fetchScriptWord();
-				int array1 = fetchScriptWord();
-				type = pop();
-				int a1_dim1end = pop();
-				int a1_dim1start = pop();
-				int a1_dim2end = pop();
-				int a1_dim2start = pop();
-				int a2_dim1end = pop();
-				int a2_dim1start = pop();
-				int a2_dim2end = pop();
-				int a2_dim2start = pop();
-				dim1end = pop();
-				dim1start = pop();
-				dim2end = pop();
-				dim2start = pop();
-
-				debug(0, "Complex: %d = %d[%d to %d][%d to %d] %c %d[%d to %d][%d to %d]", array,
-					array1, a1_dim1start, a1_dim2end, a1_dim1start, a1_dim2end,
-					" +-&|^"[type],
-					array2, a2_dim1start, a2_dim2end, a2_dim1start, a2_dim2end);
-
-				int a12_num = a1_dim2end - a1_dim2start + 1;
-				int a11_num = a1_dim1end - a1_dim1start + 1;
-				int a22_num = a2_dim2end - a2_dim2start + 1;
-				int a21_num = a2_dim1end - a2_dim1start + 1;
-				int d12_num = dim2end - dim2start + 1;
-				int d11_num = dim1end - dim1start + 1;
-
-				id = readVar(array);
-				if (id == 0) {
-					defineArray(array, kDwordArray, dim2start, dim2end, dim1start, dim1end);
-				}
-				if (a12_num != a22_num || a12_num != d12_num || a11_num != a21_num || a11_num != d11_num) {
-					error("Operation size mismatch (%d vs %d)(%d vs %d)", a12_num, a22_num, a11_num, a21_num);
-				}
+		{
+			// Used by script 84 (Send end of play info) in Backyard Football during online play.
+			int a2Variable = fetchScriptWord();
+			int a1Variable = fetchScriptWord();
+			int mathOperationType = pop();
+
+			int a1AcrossMax = pop();
+			int a1AcrossMin = pop();
+			int a1DownMax = pop();
+			int a1DownMin = pop();
+
+			int a2AcrossMax = pop();
+			int a2AcrossMin = pop();
+			int a2DownMax = pop();
+			int a2DownMin = pop();
+
+			acrossMax = pop();
+			acrossMin = pop();
+			downMax = pop();
+			downMin = pop();
+
+			debug(0, "Complex: %d = %d[%d to %d][%d to %d] %c %d[%d to %d][%d to %d]", array,
+				a1Variable, a1AcrossMin, a1DownMax, a1AcrossMin, a1DownMax,
+				" +-&|^"[mathOperationType],
+				a2Variable, a2AcrossMin, a2DownMax, a2AcrossMin, a2DownMax);
+
+			int dstD = downMax - downMin + 1;
+			int dstA = acrossMax - acrossMin + 1;
+
+			int a1D = a1DownMax - a1DownMin + 1;
+			int a1A = a1AcrossMax - a1AcrossMin + 1;
+			int a2D = a2DownMax - a2DownMin + 1;
+			int a2A = a2AcrossMax - a2AcrossMin + 1;
+
+			id = readVar(array);
+			if (id == 0) {
+				defineArray(array, kDwordArray, downMin, downMax, acrossMin, acrossMax);
+			}
 
-				for (; a1_dim2start <= a1_dim2end; ++a1_dim2start, ++a2_dim2start, ++dim2start) {
-					int a2dim1 = a2_dim1start;
-					int a1dim1 = a1_dim1start;
-					int dim1 = dim1start;
-					for (; a1dim1 <= a1_dim1end; ++a1dim1, ++a2dim1, ++dim1) {
-						int val1 = readArray(array1, a1_dim2start, a1dim1);
-						int val2 = readArray(array2, a2_dim2start, a2dim1);
-						int res;
-
-						switch (type) {
-						case 1: // Addition
-							res = val2 + val1;
-							break;
-						case 2: // Subtraction
-							res = val2 - val1;
-							break;
-						case 3: // Binary AND
-							res = val2 & val1;
-							break;
-						case 4: // Binary OR
-							res = val2 | val1;
-							break;
-						case 5: // Binary XOR
-							res = val2 ^ val1;
-							break;
-						default:
-							error("o72_arrayOps: case 138 unknown type %d)", type);
-						}
-						writeArray(array, dim2start, dim1, res);
-					}
-				}
+			if (a1D != a2D || a1D != dstD || a1A != a2A || a1A != dstA) {
+				error("Operation dataOffsetPtr mismatch (%d vs %d)(%d vs %d)", a1D, a2D, a1A, a2A);
+			}
+
+			switch (mathOperationType) {
+			case 1: // Addition
+				arrayBlockOperation(
+					array, downMin, downMax, acrossMin, acrossMax,
+					a2Variable, a2DownMin, a2DownMax, a2AcrossMin, a2AcrossMax,
+					a1Variable, a1DownMin, a1DownMax, a1AcrossMin, a1AcrossMax,
+					arrayBlockAddOp);
+				break;
+
+			case 2: // Subtraction
+				arrayBlockOperation(
+					array, downMin, downMax, acrossMin, acrossMax,
+					a2Variable, a2DownMin, a2DownMax, a2AcrossMin, a2AcrossMax,
+					a1Variable, a1DownMin, a1DownMax, a1AcrossMin, a1AcrossMax,
+					arrayBlockSubOp);
+				break;
+
+			case 3: // Binary AND
+				arrayBlockOperation(
+					array, downMin, downMax, acrossMin, acrossMax,
+					a2Variable, a2DownMin, a2DownMax, a2AcrossMin, a2AcrossMax,
+					a1Variable, a1DownMin, a1DownMax, a1AcrossMin, a1AcrossMax,
+					arrayBlockBANDOp);
+				break;
+
+			case 4: // Binary OR
+				arrayBlockOperation(
+					array, downMin, downMax, acrossMin, acrossMax,
+					a2Variable, a2DownMin, a2DownMax, a2AcrossMin, a2AcrossMax,
+					a1Variable, a1DownMin, a1DownMax, a1AcrossMin, a1AcrossMax,
+					arrayBlockBOROp);
+				break;
+
+			case 5: // Binary BXOR
+				arrayBlockOperation(
+					array, downMin, downMax, acrossMin, acrossMax,
+					a2Variable, a2DownMin, a2DownMax, a2AcrossMin, a2AcrossMax,
+					a1Variable, a1DownMin, a1DownMax, a1AcrossMin, a1AcrossMax,
+					arrayBlockBXOROp);
+				break;
+
+			default:
+				error("Invalid array math operation (%d)", mathOperationType);
 				break;
 			}
-	case SO_FORMATTED_STRING: // SO_FORMATTED_STRING
+
+			break;
+		}
+	case SO_FORMATTED_STRING:
 		decodeScriptString(string);
 		len = resStrLen(string);
 		data = defineArray(array, kStringArray, 0, 0, 0, len);
@@ -1440,7 +1547,7 @@ void ScummEngine_v72he::o72_dimArray() {
 
 
 void ScummEngine_v72he::o72_dim2dimArray() {
-	int data, dim1end, dim2end;
+	int data, acrossMax, downMax;
 
 	byte subOp = fetchScriptByte();
 
@@ -1467,9 +1574,9 @@ void ScummEngine_v72he::o72_dim2dimArray() {
 		error("o72_dim2dimArray: default case %d", subOp);
 	}
 
-	dim1end = pop();
-	dim2end = pop();
-	defineArray(fetchScriptWord(), data, 0, dim2end, 0, dim1end);
+	acrossMax = pop();
+	downMax = pop();
+	defineArray(fetchScriptWord(), data, 0, downMax, 0, acrossMax);
 }
 
 void ScummEngine_v72he::o72_traceStatus() {
@@ -1633,8 +1740,8 @@ void ScummEngine_v72he::o72_readFile() {
 
 void ScummEngine_v72he::writeFileFromArray(int slot, int32 resID) {
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, resID);
-	int32 size = (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
-		(FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
+	int32 size = (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+		(FROM_LE_32(ah->downMax) - FROM_LE_32(ah->downMin) + 1);
 
 	if (slot != -1) {
 		_hOutFileTable[slot]->write(ah->data, size);
@@ -1762,7 +1869,7 @@ void ScummEngine_v72he::o72_getPixel() {
 void ScummEngine_v72he::o72_pickVarRandom() {
 	int num;
 	int args[100];
-	int32 dim1end;
+	int32 acrossMax;
 
 	num = getStackList(args, ARRAYSIZE(args));
 	int value = fetchScriptWord();
@@ -1785,11 +1892,11 @@ void ScummEngine_v72he::o72_pickVarRandom() {
 	num = readArray(value, 0, 0);
 
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(value));
-	dim1end = FROM_LE_32(ah->dim1end);
+	acrossMax = FROM_LE_32(ah->acrossMax);
 
-	if (dim1end < num) {
+	if (acrossMax < num) {
 		int32 var_2 = readArray(value, 0, num - 1);
-		shuffleArray(value, 1, dim1end);
+		shuffleArray(value, 1, acrossMax);
 		if (readArray(value, 0, 1) == var_2) {
 			num = 2;
 		} else {
@@ -1826,134 +1933,170 @@ void ScummEngine_v72he::o72_redimArray() {
 void ScummEngine_v72he::redimArray(int arrayId, int newDim2start, int newDim2end,
 								   int newDim1start, int newDim1end, int type) {
 	int newSize, oldSize;
-
-	if (readVar(arrayId) == 0)
+	int rawArray = readVar(arrayId);
+	if (rawArray == 0)
 		error("redimArray: Reference to zeroed array pointer");
 
-	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(arrayId));
+	if (_game.heversion >= 80) {
+		if ((rawArray & MAGIC_ARRAY_NUMBER) != MAGIC_ARRAY_NUMBER) {
+			error("redimArray: Illegal array pointer not having magic number (%d,%d)", arrayId, rawArray);
+		}
+
+		rawArray &= ~MAGIC_ARRAY_NUMBER;
+	}
+
+	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, rawArray);
 
 	if (!ah)
-		error("redimArray: Invalid array (%d) reference", readVar(arrayId));
+		error("redimArray: Invalid array (%d) reference", rawArray);
 
-	newSize = arrayDataSizes[type];
-	oldSize = arrayDataSizes[FROM_LE_32(ah->type)];
+	newSize = arrayDataSizes[type] / 8;
+	oldSize = arrayDataSizes[FROM_LE_32(ah->type)] / 8;
 
 	newSize *= (newDim1end - newDim1start + 1) * (newDim2end - newDim2start + 1);
-	oldSize *= (FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1) *
-		(FROM_LE_32(ah->dim2end) - FROM_LE_32(ah->dim2start) + 1);
-
-	newSize >>= 3;
-	oldSize >>= 3;
+	oldSize *= (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+		(FROM_LE_32(ah->downMax) - FROM_LE_32(ah->downMin) + 1);
 
 	if (newSize != oldSize)
-		error("redimArray: array %d redim mismatch", readVar(arrayId));
+		error("redimArray: array %d redim mismatch", rawArray);
 
 	ah->type = TO_LE_32(type);
-	ah->dim1start = TO_LE_32(newDim1start);
-	ah->dim1end = TO_LE_32(newDim1end);
-	ah->dim2start = TO_LE_32(newDim2start);
-	ah->dim2end = TO_LE_32(newDim2end);
+	ah->acrossMin = TO_LE_32(newDim1start);
+	ah->acrossMax = TO_LE_32(newDim1end);
+	ah->downMin = TO_LE_32(newDim2start);
+	ah->downMax = TO_LE_32(newDim2end);
 }
 
-void ScummEngine_v72he::checkArrayLimits(int array, int dim2start, int dim2end, int dim1start, int dim1end) {
-	if (dim1end < dim1start) {
-		error("Across max %d smaller than min %d", dim1end, dim1start);
+void ScummEngine_v72he::checkArrayLimits(int array, int downMin, int downMax, int acrossMin, int acrossMax) {
+	if (acrossMax < acrossMin) {
+		error("Across max %d smaller than min %d", acrossMax, acrossMin);
 	}
-	if (dim2end < dim2start) {
-		error("Down max %d smaller than min %d", dim2end, dim2start);
+
+	if (downMax < downMin) {
+		error("Down max %d smaller than min %d", downMax, downMin);
 	}
+
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
 	assert(ah);
-	if ((int)FROM_LE_32(ah->dim2start) > dim2start || (int)FROM_LE_32(ah->dim2end) < dim2end || (int)FROM_LE_32(ah->dim1start) > dim1start || (int)FROM_LE_32(ah->dim1end) < dim1end) {
-		error("Invalid array access (%d,%d,%d,%d) limit (%d,%d,%d,%d)", dim2start, dim2end, dim1start, dim1end, FROM_LE_32(ah->dim2start), FROM_LE_32(ah->dim2end), FROM_LE_32(ah->dim1start), FROM_LE_32(ah->dim1end));
-	}
-}
-
-void ScummEngine_v72he::copyArray(int array1, int a1_dim2start, int a1_dim2end, int a1_dim1start, int a1_dim1end,
-				int array2, int a2_dim2start, int a2_dim2end, int a2_dim1start, int a2_dim1end)
-{
-	byte *dst, *src;
-	int dstPitch, srcPitch;
-	int rowSize;
-	checkArrayLimits(array1, a1_dim2start, a1_dim2end, a1_dim1start, a1_dim1end);
-	checkArrayLimits(array2, a2_dim2start, a2_dim2end, a2_dim1start, a2_dim1end);
-	int a12_num = a1_dim2end - a1_dim2start + 1;
-	int a11_num = a1_dim1end - a1_dim1start + 1;
-	int a22_num = a2_dim2end - a2_dim2start + 1;
-	int a21_num = a2_dim1end - a2_dim1start + 1;
-	if (a22_num != a12_num || a21_num != a11_num) {
-		error("Operation size mismatch (%d vs %d)(%d vs %d)", a12_num, a22_num, a11_num, a21_num);
-	}
-
-	if (array1 != array2) {
-		ArrayHeader *ah1 = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
-		assert(ah1);
-		ArrayHeader *ah2 = (ArrayHeader *)getResourceAddress(rtString, readVar(array2));
-		assert(ah2);
-		if (FROM_LE_32(ah1->type) == FROM_LE_32(ah2->type)) {
-			copyArrayHelper(ah1, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
-			copyArrayHelper(ah2, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
-			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
-				memcpy(dst, src, rowSize);
-				dst += dstPitch;
-				src += srcPitch;
+	if ((int)FROM_LE_32(ah->downMin) > downMin || (int)FROM_LE_32(ah->downMax) < downMax || (int)FROM_LE_32(ah->acrossMin) > acrossMin || (int)FROM_LE_32(ah->acrossMax) < acrossMax) {
+		error("Invalid array access (%d,%d,%d,%d) limit (%d,%d,%d,%d)", downMin, downMax, acrossMin, acrossMax, FROM_LE_32(ah->downMin), FROM_LE_32(ah->downMax), FROM_LE_32(ah->acrossMin), FROM_LE_32(ah->acrossMax));
+	}
+}
+
+void ScummEngine_v72he::copyArray(int dstVariable, int dstDownMin, int dstDownMax, int dstAcrossMin, int dstAcrossMax,
+				int srcVariable, int srcDownMin, int srcDownMax, int srcAcrossMin, int srcAcrossMax) {
+	byte *dstPtr, *srcPtr;
+	int dstOffset, srcOffset;
+	int dataSize;
+
+	checkArrayLimits(dstVariable, dstDownMin, dstDownMax, dstAcrossMin, dstAcrossMax);
+	checkArrayLimits(srcVariable, srcDownMin, srcDownMax, srcAcrossMin, srcAcrossMax);
+
+	int dstDownCount = dstDownMax - dstDownMin + 1;
+	int dstAcrossCount = dstAcrossMax - dstAcrossMin + 1;
+	int srcDownCount = srcDownMax - srcDownMin + 1;
+	int srcAcrossCount = srcAcrossMax - srcAcrossMin + 1;
+
+	if (srcDownCount != dstDownCount || srcAcrossCount != dstAcrossCount) {
+		error("Operation dataOffsetPtr mismatch (%d vs %d)(%d vs %d)", dstDownCount, srcDownCount, dstAcrossCount, srcAcrossCount);
+	}
+
+	if (dstVariable != srcVariable) {
+		ArrayHeader *dstArray = (ArrayHeader *)getResourceAddress(rtString, readVar(dstVariable));
+		assert(dstArray);
+		ArrayHeader *srcArray = (ArrayHeader *)getResourceAddress(rtString, readVar(srcVariable));
+		assert(srcArray);
+
+		if (FROM_LE_32(dstArray->type) == FROM_LE_32(srcArray->type)) {
+			getArrayDataPtrAndDataSize(dstArray, dstDownMin, dstAcrossMin, dstAcrossMax, &dstPtr, &dstOffset, &dataSize);
+			getArrayDataPtrAndDataSize(srcArray, srcDownMin, srcAcrossMin, srcAcrossMax, &srcPtr, &srcOffset, &dataSize);
+
+			for (int dstDownCounter = dstDownMin; dstDownCounter <= dstDownMax; dstDownCounter++) {
+				memcpy(dstPtr, srcPtr, dataSize);
+				dstPtr += dstOffset;
+				srcPtr += srcOffset;
 			}
 		} else {
-			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start, ++a2_dim2start) {
-				int a2dim1 = a2_dim1start;
-				int a1dim1 = a1_dim1start;
-				for (; a1dim1 <= a1_dim1end; ++a1dim1, ++a2dim1) {
-					int val = readArray(array2, a2_dim2start, a2dim1);
-					writeArray(array1, a1_dim2start, a1dim1, val);
+			int srcDownIndex = srcDownMin;
+
+			for (int dstDownCounter = dstDownMin; dstDownCounter <= dstDownMax; dstDownCounter++) {
+				int srcAcrossIndex = srcAcrossMin;
+
+				for (int dstAcrossCounter = dstAcrossMin; dstAcrossCounter <= dstAcrossMax; dstAcrossCounter++) {
+					writeArray(dstVariable, dstDownMin, dstAcrossCounter,
+						readArray(srcVariable, srcDownMin, srcAcrossIndex++));
 				}
+
+				srcDownIndex++;
 			}
 		}
 	} else {
-		if (a2_dim2start != a1_dim2start || a2_dim1start != a1_dim1start) {
-			ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array1));
-			assert(ah);
-			if (a2_dim2start > a1_dim2start) {
-				copyArrayHelper(ah, a1_dim2start, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
-				copyArrayHelper(ah, a2_dim2start, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
+		if (srcDownMin != dstDownMin || srcAcrossMin != dstAcrossMin) {
+			int dstArray = readVar(dstVariable);
+
+			ArrayHeader *dstArrayPtr = (ArrayHeader *)getResourceAddress(rtString, dstArray & ~MAGIC_ARRAY_NUMBER);
+			ArrayHeader *srcArrayPtr = dstArrayPtr;
+
+			if (!dstArrayPtr) {
+				error("Missing array (%d,%d,4) reference", (dstArray & ~MAGIC_ARRAY_NUMBER), dstArray);
+			}
+
+			bool useMemcpy = false;
+
+			// Calculate the check for overlap or flipped reads on src and dst pointers
+			// and setup the copy operation variables...
+			if ((dstDownMin < srcDownMin) || (_game.heversion > 99 || _isHE995)) {
+				useMemcpy = true;
+
+				getArrayDataPtrAndDataSize(dstArrayPtr, dstDownMin, dstAcrossMin, dstAcrossMax, &dstPtr, &dstOffset, &dataSize);
+				getArrayDataPtrAndDataSize(srcArrayPtr, srcDownMin, srcAcrossMin, srcAcrossMax, &srcPtr, &srcOffset, &dataSize);
 			} else {
-				// start at the end, so we copy backwards (in case the indices overlap)
-				copyArrayHelper(ah, a1_dim2end, a1_dim1start, a1_dim1end, &dst, &dstPitch, &rowSize);
-				copyArrayHelper(ah, a2_dim2end, a2_dim1start, a2_dim1end, &src, &srcPitch, &rowSize);
-				dstPitch = -dstPitch;
-				srcPitch = -srcPitch;
+				getArrayDataPtrAndDataSize(dstArrayPtr, dstDownMax, dstAcrossMin, dstAcrossMax, &dstPtr, &dstOffset, &dataSize);
+				getArrayDataPtrAndDataSize(srcArrayPtr, srcDownMax, srcAcrossMin, srcAcrossMax, &srcPtr, &srcOffset, &dataSize);
+
+				useMemcpy = (dstAcrossMin <= srcAcrossMin);
 			}
-			for (; a1_dim2start <= a1_dim2end; ++a1_dim2start) {
-				memcpy(dst, src, rowSize);
-				dst += dstPitch;
-				src += srcPitch;
+
+			if (useMemcpy) {
+				for (int dstDownCounter = dstDownMin; dstDownCounter <= dstDownMax; dstDownCounter++) {
+					memcpy(dstPtr, srcPtr, dataSize);
+					dstPtr += dstOffset;
+					srcPtr += srcOffset;
+				}
+			} else {
+				for (int dstDownCounter = dstDownMin; dstDownCounter <= dstDownMax; dstDownCounter++) {
+					memmove(dstPtr, srcPtr, dataSize);
+					dstPtr += dstOffset;
+					srcPtr += srcOffset;
+				}
 			}
 		}
 	}
 }
 
-void ScummEngine_v72he::copyArrayHelper(ArrayHeader *ah, int idx2, int idx1, int len1, byte **data, int *size, int *num) {
-	const int pitch = FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1;
-	const int offset = pitch * (idx2 - FROM_LE_32(ah->dim2start)) + idx1 - FROM_LE_32(ah->dim1start);
+void ScummEngine_v72he::getArrayDataPtrAndDataSize(ArrayHeader *headerPtr, int down, int aMin, int aMax, byte **ptrPtr, int *dataOffsetPtr, int *dataSizePtr) {
+	const int acrossCount = FROM_LE_32(headerPtr->acrossMax) - FROM_LE_32(headerPtr->acrossMin) + 1;
+	const int index = acrossCount * (down - FROM_LE_32(headerPtr->downMin)) + aMin - FROM_LE_32(headerPtr->acrossMin);
 
-	switch (FROM_LE_32(ah->type)) {
+	switch (FROM_LE_32(headerPtr->type)) {
 	case kByteArray:
 	case kStringArray:
-		*num = len1 - idx1 + 1;
-		*size = pitch;
-		*data = ah->data + offset;
+		*dataSizePtr = aMax - aMin + 1;
+		*dataOffsetPtr = acrossCount;
+		*ptrPtr = headerPtr->data + index;
 		break;
 	case kIntArray:
-		*num = (len1 - idx1) * 2 + 2;
-		*size = pitch * 2;
-		*data = ah->data + offset * 2;
+		*dataSizePtr = (aMax - aMin) * 2 + 2;
+		*dataOffsetPtr = acrossCount * 2;
+		*ptrPtr = headerPtr->data + index * 2;
 		break;
 	case kDwordArray:
-		*num = (len1 - idx1) * 4 + 4;
-		*size = pitch * 4;
-		*data = ah->data + offset * 4;
+		*dataSizePtr = (aMax - aMin) * 4 + 4;
+		*dataOffsetPtr = acrossCount * 4;
+		*ptrPtr = headerPtr->data + index * 4;
 		break;
 	default:
-		error("Invalid array type %d", FROM_LE_32(ah->type));
+		error("Invalid array type %d", FROM_LE_32(headerPtr->type));
 	}
 }
 
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index b10fac58e76..d4ca3db057e 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -500,7 +500,7 @@ void ScummEngine_v80he::o80_drawLine() {
 void ScummEngine_v80he::o80_pickVarRandom() {
 	int num;
 	int args[100];
-	int32 dim1end;
+	int32 acrossMax;
 
 	num = getStackList(args, ARRAYSIZE(args));
 	int value = fetchScriptWord();
@@ -528,13 +528,13 @@ void ScummEngine_v80he::o80_pickVarRandom() {
 	num = readArray(value, 0, 0);
 
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(value));
-	dim1end = FROM_LE_32(ah->dim1end);
+	acrossMax = FROM_LE_32(ah->acrossMax);
 
-	if (dim1end < num) {
+	if (acrossMax < num) {
 		int32 var_2 = readArray(value, 0, num - 1);
-		shuffleArray(value, 1, dim1end);
+		shuffleArray(value, 1, acrossMax);
 		num = 1;
-		if (readArray(value, 0, 1) == var_2 && dim1end >= 3) {
+		if (readArray(value, 0, 1) == var_2 && acrossMax >= 3) {
 			int32 tmp = readArray(value, 0, 2);
 			writeArray(value, 0, num, tmp);
 			writeArray(value, 0, 2, var_2);
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index aca2931ce6f..8cafde5677d 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -1826,7 +1826,7 @@ void ScummEngine_v90he::o90_cond() {
 }
 
 void ScummEngine_v90he::o90_dim2dim2Array() {
-	int data, dim1start, dim1end, dim2start, dim2end;
+	int data, acrossMin, acrossMax, downMin, downMax;
 
 	byte subOp = fetchScriptByte();
 
@@ -1854,18 +1854,18 @@ void ScummEngine_v90he::o90_dim2dim2Array() {
 	}
 
 	if (pop() == 2) {
-		dim1end = pop();
-		dim1start = pop();
-		dim2end = pop();
-		dim2start = pop();
+		acrossMax = pop();
+		acrossMin = pop();
+		downMax = pop();
+		downMin = pop();
 	} else {
-		dim2end = pop();
-		dim2start = pop();
-		dim1end = pop();
-		dim1start = pop();
+		downMax = pop();
+		downMin = pop();
+		acrossMax = pop();
+		acrossMin = pop();
 	}
 
-	defineArray(fetchScriptWord(), data, dim2start, dim2end, dim1start, dim1end);
+	defineArray(fetchScriptWord(), data, downMin, downMax, acrossMin, acrossMax);
 }
 
 void ScummEngine_v90he::o90_redim2dimArray() {
@@ -2032,20 +2032,20 @@ void ScummEngine_v90he::o90_getLinesIntersectionPoint() {
 	push(0);
 }
 
-void ScummEngine_v90he::getArrayDim(int array, int *dim2start, int *dim2end, int *dim1start, int *dim1end) {
+void ScummEngine_v90he::getArrayDim(int array, int *downMin, int *downMax, int *acrossMin, int *acrossMax) {
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
 	assert(ah);
-	if (dim2start && *dim2start == -1) {
-		*dim2start = FROM_LE_32(ah->dim2start);
+	if (downMin && *downMin == -1) {
+		*downMin = FROM_LE_32(ah->downMin);
 	}
-	if (dim2end && *dim2end == -1) {
-		*dim2end = FROM_LE_32(ah->dim2end);
+	if (downMax && *downMax == -1) {
+		*downMax = FROM_LE_32(ah->downMax);
 	}
-	if (dim1start && *dim1start == -1) {
-		*dim1start = FROM_LE_32(ah->dim1start);
+	if (acrossMin && *acrossMin == -1) {
+		*acrossMin = FROM_LE_32(ah->acrossMin);
 	}
-	if (dim1end && *dim1end == -1) {
-		*dim1end = FROM_LE_32(ah->dim1end);
+	if (acrossMax && *acrossMax == -1) {
+		*acrossMax = FROM_LE_32(ah->acrossMax);
 	}
 }
 
@@ -2091,21 +2091,21 @@ static int compareDwordArrayReverse(const void *a, const void *b) {
 /**
  * Sort a row range in a two-dimensional array by the value in a given column.
  *
- * We sort the data in the row range [dim2start..dim2end], according to the value
- * in column dim1start == dim1end.
+ * We sort the data in the row range [downMin..downMax], according to the value
+ * in column acrossMin == acrossMax.
  */
-void ScummEngine_v90he::sortArray(int array, int dim2start, int dim2end, int dim1start, int dim1end, int sortOrder) {
-	debug(9, "sortArray(%d, [%d,%d,%d,%d], %d)", array, dim2start, dim2end, dim1start, dim1end, sortOrder);
+void ScummEngine_v90he::sortArray(int array, int downMin, int downMax, int acrossMin, int acrossMax, int sortOrder) {
+	debug(9, "sortArray(%d, [%d,%d,%d,%d], %d)", array, downMin, downMax, acrossMin, acrossMax, sortOrder);
 
-	assert(dim1start == dim1end);
-	checkArrayLimits(array, dim2start, dim2end, dim1start, dim1end);
+	assert(acrossMin == acrossMax);
+	checkArrayLimits(array, downMin, downMax, acrossMin, acrossMax);
 	ArrayHeader *ah = (ArrayHeader *)getResourceAddress(rtString, readVar(array));
 	assert(ah);
 
-	const int num = dim2end - dim2start + 1;	// number of rows to sort
-	const int pitch = FROM_LE_32(ah->dim1end) - FROM_LE_32(ah->dim1start) + 1;	// length of a row = number of columns in it
-	const int offset = pitch * (dim2start - FROM_LE_32(ah->dim2start));	// memory offset to the first row to be sorted
-	sortArrayOffset = dim1start - FROM_LE_32(ah->dim1start);	// offset to the column by which we sort
+	const int num = downMax - downMin + 1;	// number of rows to sort
+	const int pitch = FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1;	// length of a row = number of columns in it
+	const int offset = pitch * (downMin - FROM_LE_32(ah->downMin));	// memory offset to the first row to be sorted
+	sortArrayOffset = acrossMin - FROM_LE_32(ah->acrossMin);	// offset to the column by which we sort
 
 	// Now we just have to invoke qsort on the appropriate row range. We
 	// need to pass sortArrayOffset as an implicit parameter to the
@@ -2154,12 +2154,12 @@ void ScummEngine_v90he::o90_sortArray() {
 		{
 			int array = fetchScriptWord();
 			int sortOrder = pop();
-			int dim1end = pop();
-			int dim1start = pop();
-			int dim2end = pop();
-			int dim2start = pop();
-			getArrayDim(array, &dim2start, &dim2end, &dim1start, &dim1end);
-			sortArray(array, dim2start, dim2end, dim1start, dim1end, sortOrder);
+			int acrossMax = pop();
+			int acrossMin = pop();
+			int downMax = pop();
+			int downMin = pop();
+			getArrayDim(array, &downMin, &downMax, &acrossMin, &acrossMax);
+			sortArray(array, downMin, downMax, acrossMin, acrossMax, sortOrder);
 		}
 		break;
 	default:
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index bfabde42494..b37902dedb1 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -763,7 +763,7 @@ byte *ScummEngine::getResourceAddress(ResType type, ResId idx) {
 	byte *ptr;
 
 	if (_game.heversion >= 80 && type == rtString)
-		idx &= ~0x33539000;
+		idx &= ~MAGIC_ARRAY_NUMBER;
 
 	if (!_res->validateResource("getResourceAddress", type, idx))
 		return nullptr;
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index b4918bd5259..778f00d276b 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -25,6 +25,7 @@
 #include "scumm/actor.h"
 #include "scumm/charset.h"
 #include "scumm/file.h"
+#include "scumm/he/intern_he.h"
 #include "scumm/imuse/imuse.h"
 #include "scumm/imuse_digi/dimuse_engine.h"
 #include "scumm/insane/insane.h"
@@ -345,7 +346,7 @@ void ScummEngine_v6::nukeArray(int a) {
 	data = readVar(a);
 
 	if (_game.heversion >= 80)
-		data &= ~0x33539000;
+		data &= ~MAGIC_ARRAY_NUMBER;
 
 	if (data)
 		_res->nukeResource(rtString, data);
@@ -3505,15 +3506,21 @@ void ScummEngine_v6::o6_findAllObjects() {
 	push(readVar(0));
 }
 
-void ScummEngine_v6::shuffleArray(int num, int minIdx, int maxIdx) {
+void ScummEngine_v6::shuffleArray(int num, int minIdx, int maxIdx) {	
+	int rand1, rand2;
 	int range = maxIdx - minIdx;
 	int count = range * 2;
-
+	
 	// Shuffle the array 'num'
 	while (count--) {
 		// Determine two random elements...
-		int rand1 = _rnd.getRandomNumber(range) + minIdx;
-		int rand2 = _rnd.getRandomNumber(range) + minIdx;
+		if (_game.heversion >= 72) {
+			rand1 = VAR(VAR_RANDOM_NR) = _rnd.getRandomNumberRng(minIdx, maxIdx);
+			rand2 = VAR(VAR_RANDOM_NR) = _rnd.getRandomNumberRng(minIdx, maxIdx);
+		} else {
+			rand1 = _rnd.getRandomNumber(range) + minIdx;
+			rand2 = _rnd.getRandomNumber(range) + minIdx;
+		}
 
 		// ...and swap them
 		int val1 = readArray(num, 0, rand1);




More information about the Scummvm-git-logs mailing list