[Scummvm-git-logs] scummvm master -> b8ed2f32520261f08765cc55de7c719b5515f931

AndywinXp noreply at scummvm.org
Sat Oct 4 13:42:51 UTC 2025


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

Summary:
b8ed2f3252 SCUMM: HE: Implement Array down caching mechanism


Commit: b8ed2f32520261f08765cc55de7c719b5515f931
    https://github.com/scummvm/scummvm/commit/b8ed2f32520261f08765cc55de7c719b5515f931
Author: AndywinXp (andywinxp at gmail.com)
Date: 2025-10-04T15:42:46+02:00

Commit Message:
SCUMM: HE: Implement Array down caching mechanism

This is found on HE95 onwards

Changed paths:
    engines/scumm/he/intern_he.h
    engines/scumm/he/script_v72he.cpp


diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index e613b2d5eac..7ee477837a4 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -396,6 +396,8 @@ protected:
 		int32 acrossMax;
 		int32 downMin;
 		int32 downMax;
+		int32 lastDown;
+		int32 lastDownOffset;
 		byte data[1];
 	} PACKED_STRUCT;
 
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index bca1f631ec6..d9f74479f40 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -144,11 +144,16 @@ byte *ScummEngine_v72he::defineArray(int array, int type, int downMin, int downM
 	ah->downMin = TO_LE_32(downMin);
 	ah->downMax = TO_LE_32(downMax);
 
+	if (_game.heversion >= 95) {
+		ah->lastDown = -1;
+		ah->lastDownOffset = -1;
+	}
+
 	return ah->data;
 }
 
-int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
-	debug(9, "readArray (array %d, down %d, aMin %d)", readVar(array), idx2, idx1);
+int ScummEngine_v72he::readArray(int array, int down, int across) {
+	debug(9, "readArray (array %d, down %d, aMin %d)", readVar(array), down, across);
 
 	if (readVar(array) == 0)
 		error("readArray: Reference to zeroed array pointer");
@@ -158,10 +163,10 @@ 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->downMin) || idx2 > (int)FROM_LE_32(ah->downMax) ||
-		idx1 < (int)FROM_LE_32(ah->acrossMin) || idx1 > (int)FROM_LE_32(ah->acrossMax)) {
+	if (down < (int)FROM_LE_32(ah->downMin) || down > (int)FROM_LE_32(ah->downMax) ||
+		across < (int)FROM_LE_32(ah->acrossMin) || across > (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->acrossMin), FROM_LE_32(ah->acrossMax),
+			  array, across, down, FROM_LE_32(ah->acrossMin), FROM_LE_32(ah->acrossMax),
 			  FROM_LE_32(ah->downMin), FROM_LE_32(ah->downMax));
 	}
 
@@ -178,7 +183,7 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
 			readVar(ROOM_VAL(11)) == 1 &&  // The ball is a pop-up
 			readVar(291) < 2 &&  // Less than two outs
 			// This is the array of baserunner status info, and the value in position 8 specifies whether the runner is forced
-			array == 295 && idx1 == 8) {
+			array == 295 && across == 8) {
 				int runnerIdx = readVar(342);
 				if (readArray(array, runnerIdx, 6) == 1 && readArray(array, runnerIdx, 7) == 1) {
 					// Bugfix: if runner is going forward to 1st base, return 1 so they can't turn around
@@ -190,19 +195,32 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
 	}
 #endif
 
-	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));
+	int index;
+
+	if (_game.heversion >= 95) { // Caches the down offset
+		if (down == ah->lastDown) {
+			index = ah->lastDownOffset + across;
+		} else {
+			ah->lastDown = down;
+			ah->lastDownOffset = ((down - FROM_LE_32(ah->downMin)) *
+								 (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1)) - FROM_LE_32(ah->acrossMin);
+			index = ah->lastDownOffset + across;
+		}
+	} else {
+		index = (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+				 (down - FROM_LE_32(ah->downMin)) + (across - FROM_LE_32(ah->acrossMin));
+	}
 
 	switch (FROM_LE_32(ah->type)) {
 	case kByteArray:
 	case kStringArray:
-		return ah->data[offset];
+		return ah->data[index];
 
 	case kIntArray:
-		return (int16)READ_LE_UINT16(ah->data + offset * 2);
+		return (int16)READ_LE_UINT16(ah->data + index * 2);
 
 	case kDwordArray:
-		return (int32)READ_LE_UINT32(ah->data + offset * 4);
+		return (int32)READ_LE_UINT32(ah->data + index * 4);
 
 	default:
 		break;
@@ -211,8 +229,8 @@ int ScummEngine_v72he::readArray(int array, int idx2, int idx1) {
 	return 0;
 }
 
-void ScummEngine_v72he::writeArray(int array, int idx2, int idx1, int value) {
-	debug(9, "writeArray (array %d, down %d, aMin %d, value %d)", readVar(array), idx2, idx1, value);
+void ScummEngine_v72he::writeArray(int array, int down, int across, int value) {
+	debug(9, "writeArray (array %d, down %d, aMin %d, value %d)", readVar(array), down, across, value);
 
 	if (readVar(array) == 0)
 		error("writeArray: Reference to zeroed array pointer");
@@ -222,28 +240,43 @@ 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->downMin) || idx2 > (int)FROM_LE_32(ah->downMax) ||
-		idx1 < (int)FROM_LE_32(ah->acrossMin) || idx1 > (int)FROM_LE_32(ah->acrossMax)) {
+	if (down < (int)FROM_LE_32(ah->downMin) || down > (int)FROM_LE_32(ah->downMax) ||
+		across < (int)FROM_LE_32(ah->acrossMin) || across > (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->acrossMin), FROM_LE_32(ah->acrossMax),
+			  array, across, down, 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->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
-		(idx2 - FROM_LE_32(ah->downMin)) - FROM_LE_32(ah->acrossMin) + idx1;
+	int index;
+
+	if (_game.heversion >= 95) { // Caches the down offset
+		if (down == ah->lastDown) {
+			index = ah->lastDownOffset + across;
+		} else {
+			ah->lastDown = down;
+			ah->lastDownOffset = ((down - FROM_LE_32(ah->downMin)) *
+								  (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1)) -
+								 FROM_LE_32(ah->acrossMin);
+			index = ah->lastDownOffset + across;
+		}
+	} else {
+		index = (FROM_LE_32(ah->acrossMax) - FROM_LE_32(ah->acrossMin) + 1) *
+					(down - FROM_LE_32(ah->downMin)) +
+				(across - FROM_LE_32(ah->acrossMin));
+	}
 
 	switch (FROM_LE_32(ah->type)) {
 	case kByteArray:
 	case kStringArray:
-		ah->data[offset] = value;
+		ah->data[index] = value;
 		break;
 
 	case kIntArray:
-		WRITE_LE_UINT16(ah->data + offset * 2, value);
+		WRITE_LE_UINT16(ah->data + index * 2, value);
 		break;
 
 	case kDwordArray:
-		WRITE_LE_UINT32(ah->data + offset * 4, value);
+		WRITE_LE_UINT32(ah->data + index * 4, value);
 		break;
 
 	default:
@@ -1996,6 +2029,11 @@ void ScummEngine_v72he::redimArray(int arrayId, int newDim2start, int newDim2end
 	ah->acrossMax = TO_LE_32(newDim1end);
 	ah->downMin = TO_LE_32(newDim2start);
 	ah->downMax = TO_LE_32(newDim2end);
+
+	if (_game.heversion >= 95) {
+		ah->lastDown = -1;
+		ah->lastDownOffset = -1;
+	}
 }
 
 void ScummEngine_v72he::checkArrayLimits(int array, int downMin, int downMax, int acrossMin, int acrossMax) {




More information about the Scummvm-git-logs mailing list