[Scummvm-git-logs] scummvm master -> 13c3d6cddcf08dd0f2e3e4d41711ff1e26ba3acd

criezy noreply at scummvm.org
Wed Jun 15 21:13:11 UTC 2022


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

Summary:
98bb288bbe AGS: Fixed BufferedStream may overwrite dest with clear buffer
74416f547f AGS: Removed redundant arrays keeping copies of obj script names
5d9ae41cd6 AGS: Store room objects in std::vector
13c3d6cddc AGS: Increased Room Objects limit to 256


Commit: 98bb288bbe117cf2cedb28c04551c9183aac1f07
    https://github.com/scummvm/scummvm/commit/98bb288bbe117cf2cedb28c04551c9183aac1f07
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-15T22:13:02+01:00

Commit Message:
AGS: Fixed BufferedStream may overwrite dest with clear buffer

>From upstream 39c8f628575eeabff1ed583b43bd6c58530c6b24

Changed paths:
    engines/ags/shared/util/buffered_stream.cpp


diff --git a/engines/ags/shared/util/buffered_stream.cpp b/engines/ags/shared/util/buffered_stream.cpp
index 398302d3309..95c8cb8a29b 100644
--- a/engines/ags/shared/util/buffered_stream.cpp
+++ b/engines/ags/shared/util/buffered_stream.cpp
@@ -133,7 +133,10 @@ int32_t BufferedStream::ReadByte() {
 size_t BufferedStream::Write(const void *buffer, size_t size) {
 	const uint8_t *from = static_cast<const uint8_t*>(buffer);
 	while (size > 0) {
-		if (_position < _bufferPosition || _position >= _bufferPosition + BufferSize) {
+		if (_position < _bufferPosition || // seeked before buffer pos
+			_position > _bufferPosition + _buffer.size() || // seeked beyond buffer pos
+			_position >= _bufferPosition + BufferSize) // seeked, or exceeded buffer limit
+		{
 			FlushBuffer(_position);
 		}
 		size_t pos_in_buff = static_cast<size_t>(_position - _bufferPosition);


Commit: 74416f547f517828561354cf2b02bdcbf962d450
    https://github.com/scummvm/scummvm/commit/74416f547f517828561354cf2b02bdcbf962d450
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-15T22:13:02+01:00

Commit Message:
AGS: Removed redundant arrays keeping copies of obj script names

>From upstream f0887ba798b9df7aa70125b432efd5d62c64a622

Changed paths:
    engines/ags/engine/ac/game.cpp
    engines/ags/engine/ac/room.cpp
    engines/ags/engine/game/game_init.cpp
    engines/ags/globals.cpp
    engines/ags/globals.h


diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index dc8202979e6..1c6ecbdfef6 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -361,7 +361,6 @@ void unload_game_file() {
 
 	_GP(play).FreeViewportsAndCameras();
 
-	_GP(characterScriptObjNames).clear();
 	_GP(charextra).clear();
 	_GP(mls).clear();
 
@@ -426,7 +425,6 @@ void unload_game_file() {
 	delete[] _G(scrDialog);
 	_G(scrDialog) = nullptr;
 
-	_GP(guiScriptObjNames).clear();
 	_GP(guis).clear();
 	free(_G(scrGui));
 
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index cb4be1cc741..8dd038c14e5 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -279,10 +279,10 @@ void unload_old_room() {
 
 	for (ff = 0; ff < _G(croom)->numobj; ff++) {
 		// un-export the object's script object
-		if (_G(objectScriptObjNames)[ff].IsEmpty())
+		if (_GP(thisroom).Objects[ff].ScriptName.IsEmpty())
 			continue;
 
-		ccRemoveExternalSymbol(_G(objectScriptObjNames)[ff]);
+		ccRemoveExternalSymbol(_GP(thisroom).Objects[ff].ScriptName);
 	}
 
 	for (ff = 0; ff < MAX_ROOM_HOTSPOTS; ff++) {
@@ -622,16 +622,11 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 
 	_G(objs) = &_G(croom)->obj[0];
 
-	for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++) {
-		_G(objectScriptObjNames)[cc].Free();
-	}
-
 	for (cc = 0; cc < _G(croom)->numobj; cc++) {
 		// export the object's script object
 		if (_GP(thisroom).Objects[cc].ScriptName.IsEmpty())
 			continue;
-		_G(objectScriptObjNames)[cc] = _GP(thisroom).Objects[cc].ScriptName;
-		ccAddExternalDynamicObject(_G(objectScriptObjNames)[cc], &_G(scrObj)[cc], &_GP(ccDynamicObject));
+		ccAddExternalDynamicObject(_GP(thisroom).Objects[cc].ScriptName, &_G(scrObj)[cc], &_GP(ccDynamicObject));
 	}
 
 	for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++) {
diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp
index e7f12572ad0..313fe477ae8 100644
--- a/engines/ags/engine/game/game_init.cpp
+++ b/engines/ags/engine/game/game_init.cpp
@@ -106,7 +106,6 @@ void InitAndRegisterAudioObjects(GameSetupStruct &game) {
 
 // Initializes characters and registers them in the script system
 void InitAndRegisterCharacters(GameSetupStruct &game) {
-	_GP(characterScriptObjNames).resize(game.numcharacters);
 	for (int i = 0; i < game.numcharacters; ++i) {
 		game.chars[i].walking = 0;
 		game.chars[i].animating = 0;
@@ -124,8 +123,7 @@ void InitAndRegisterCharacters(GameSetupStruct &game) {
 		ccRegisterManagedObject(&game.chars[i], &_GP(ccDynamicCharacter));
 
 		// export the character's script object
-		_GP(characterScriptObjNames)[i] = game.chars[i].scrname;
-		ccAddExternalDynamicObject(_GP(characterScriptObjNames)[i], &game.chars[i], &_GP(ccDynamicCharacter));
+		ccAddExternalDynamicObject(game.chars[i].scrname, &game.chars[i], &_GP(ccDynamicCharacter));
 	}
 }
 
@@ -159,7 +157,6 @@ HError InitAndRegisterGUI(GameSetupStruct &game) {
 		_G(scrGui)[i].id = -1;
 	}
 
-	_GP(guiScriptObjNames).resize(game.numgui);
 	for (int i = 0; i < game.numgui; ++i) {
 		// link controls to their parent guis
 		HError err = _GP(guis)[i].RebuildArray();
@@ -167,11 +164,8 @@ HError InitAndRegisterGUI(GameSetupStruct &game) {
 			return err;
 		// export all the GUI's controls
 		export_gui_controls(i);
-		// copy the script name to its own memory location
-		// because ccAddExtSymbol only keeps a reference
-		_GP(guiScriptObjNames)[i] = _GP(guis)[i].Name;
 		_G(scrGui)[i].id = i;
-		ccAddExternalDynamicObject(_GP(guiScriptObjNames)[i], &_G(scrGui)[i], &_GP(ccDynamicGUI));
+		ccAddExternalDynamicObject(_GP(guis)[i].Name, &_G(scrGui)[i], &_GP(ccDynamicGUI));
 		ccRegisterManagedObject(&_G(scrGui)[i], &_GP(ccDynamicGUI));
 	}
 	return HError::None();
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 1aec36ddcf1..7917dd43ded 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -356,9 +356,6 @@ Globals::Globals() {
 	_moduleInst = new std::vector<ccInstance *>();
 	_moduleInstFork = new std::vector<ccInstance *>();
 	_moduleRepExecAddr = new std::vector<RuntimeScriptValue>();
-	_characterScriptObjNames = new std::vector<String>();
-	_objectScriptObjNames = new String[MAX_ROOM_OBJECTS];
-	_guiScriptObjNames = new std::vector<String>();
 
 	// script_runtime.cpp globals
 	Common::fill(_loadedInstances, _loadedInstances + MAX_LOADED_INSTANCES,
@@ -606,9 +603,6 @@ Globals::~Globals() {
 	delete _moduleInst;
 	delete _moduleInstFork;
 	delete _moduleRepExecAddr;
-	delete _characterScriptObjNames;
-	delete[] _objectScriptObjNames;
-	delete _guiScriptObjNames;
 
 	// system_imports.cpp globals
 	delete _simp;
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 82b3e80d9aa..71a0a20b6b9 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1267,12 +1267,6 @@ public:
 	std::vector<RuntimeScriptValue> *_moduleRepExecAddr;
 	size_t _numScriptModules = 0;
 
-	// TODO: find out if these extra arrays are really necessary. This may be remains from the
-	// time when the symbol import table was holding raw pointers to char array.
-	std::vector<String> *_characterScriptObjNames;
-	String *_objectScriptObjNames;
-	std::vector<String> *_guiScriptObjNames;
-
 	/**@}*/
 
 	/**


Commit: 5d9ae41cd6569f046ec2113e7d3bd213a90e5cce
    https://github.com/scummvm/scummvm/commit/5d9ae41cd6569f046ec2113e7d3bd213a90e5cce
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-15T22:13:02+01:00

Commit Message:
AGS: Store room objects in std::vector

>From upstream 5f3b8eb509c9535c75b401f9b7257f7c7acd0e6d

Changed paths:
    engines/ags/engine/ac/dynobj/script_object.h
    engines/ags/engine/ac/room.cpp
    engines/ags/engine/ac/room_status.cpp
    engines/ags/engine/ac/room_status.h
    engines/ags/engine/game/savegame.cpp
    engines/ags/engine/game/savegame_components.cpp
    engines/ags/shared/game/room_file.cpp
    engines/ags/shared/game/room_struct.cpp
    engines/ags/shared/game/room_struct.h


diff --git a/engines/ags/engine/ac/dynobj/script_object.h b/engines/ags/engine/ac/dynobj/script_object.h
index c9583fadd00..761e474257a 100644
--- a/engines/ags/engine/ac/dynobj/script_object.h
+++ b/engines/ags/engine/ac/dynobj/script_object.h
@@ -26,10 +26,9 @@
 
 namespace AGS3 {
 
-// 64 bit: Struct size must be 8 byte for scripts to work
+// WARNING: struct size must be 8 byte for old scripts to work
 struct ScriptObject {
-	int id = 0;
-	//RoomObject *obj;
+	int id = -1;
 	int __padding = 0;
 };
 
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index 8dd038c14e5..f4c088e4ed1 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -314,11 +314,11 @@ void convert_room_coordinates_to_data_res(RoomStruct *rstruc) {
 		return;
 
 	const int mul = _GP(game).GetDataUpscaleMult();
-	for (size_t i = 0; i < rstruc->ObjectCount; ++i) {
-		rstruc->Objects[i].X /= mul;
-		rstruc->Objects[i].Y /= mul;
-		if (rstruc->Objects[i].Baseline > 0) {
-			rstruc->Objects[i].Baseline /= mul;
+	for (auto &obj : rstruc->Objects) {
+		obj.X /= mul;
+		obj.Y /= mul;
+		if (obj.Baseline > 0) {
+			obj.Baseline /= mul;
 		}
 	}
 
@@ -405,8 +405,6 @@ HError LoadRoomScript(RoomStruct *room, int newnum) {
 }
 
 static void reset_temp_room() {
-	_GP(troom).FreeScriptData();
-	_GP(troom).FreeProperties();
 	_GP(troom) = RoomStatus();
 }
 
@@ -537,7 +535,7 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 			_GP(thisroom).Interaction->CopyTimesRun(_G(croom)->intrRoom);
 			for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
 				_GP(thisroom).Hotspots[cc].Interaction->CopyTimesRun(_G(croom)->intrHotspot[cc]);
-			for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++)
+			for (cc = 0; cc < _GP(thisroom).Objects.size(); cc++)
 				_GP(thisroom).Objects[cc].Interaction->CopyTimesRun(_G(croom)->intrObject[cc]);
 			for (cc = 0; cc < MAX_ROOM_REGIONS; cc++)
 				_GP(thisroom).Regions[cc].Interaction->CopyTimesRun(_G(croom)->intrRegion[cc]);
@@ -547,39 +545,44 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 
 		// Always copy object and hotspot names for < 3.6.0 games, because they were not settable
 		if (_G(loaded_game_file_version) < kGameVersion_360_16) {
-			for (cc = 0; cc < _G(croom)->numobj; ++cc)
+			for (cc = 0; cc < _GP(thisroom).Objects.size(); ++cc)
 				_G(croom)->obj[cc].name = _GP(thisroom).Objects[cc].Name;
 			for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
 				_G(croom)->hotspot[cc].Name = _GP(thisroom).Hotspots[cc].Name;
 		}
 	} else {
 		// If we have not been in this room before, then copy necessary fields from _GP(thisroom)
-		_G(croom)->numobj = _GP(thisroom).ObjectCount;
+		_G(croom)->numobj = _GP(thisroom).Objects.size();
 		_G(croom)->tsdatasize = 0;
+		_G(croom)->obj.resize(_G(croom)->numobj);
+		_G(croom)->objProps.resize(_G(croom)->numobj);
+		_G(croom)->intrObject.resize(_G(croom)->numobj);
 		for (cc = 0; cc < _G(croom)->numobj; cc++) {
-			_G(croom)->obj[cc].x = _GP(thisroom).Objects[cc].X;
-			_G(croom)->obj[cc].y = _GP(thisroom).Objects[cc].Y;
-			_G(croom)->obj[cc].num = Math::InRangeOrDef<uint16_t>(_GP(thisroom).Objects[cc].Sprite, 0);
-			_G(croom)->obj[cc].on = _GP(thisroom).Objects[cc].IsOn;
-			_G(croom)->obj[cc].view = RoomObject::NoView;
-			_G(croom)->obj[cc].loop = 0;
-			_G(croom)->obj[cc].frame = 0;
-			_G(croom)->obj[cc].wait = 0;
-			_G(croom)->obj[cc].transparent = 0;
-			_G(croom)->obj[cc].moving = -1;
-			_G(croom)->obj[cc].flags = _GP(thisroom).Objects[cc].Flags;
-			_G(croom)->obj[cc].baseline = -1;
-			_G(croom)->obj[cc].zoom = 100;
-			_G(croom)->obj[cc].last_width = 0;
-			_G(croom)->obj[cc].last_height = 0;
-			_G(croom)->obj[cc].blocking_width = 0;
-			_G(croom)->obj[cc].blocking_height = 0;
-			_G(croom)->obj[cc].name = _GP(thisroom).Objects[cc].Name;
-			if (_GP(thisroom).Objects[cc].Baseline >= 0)
-				_G(croom)->obj[cc].baseline = _GP(thisroom).Objects[cc].Baseline;
-			if (_GP(thisroom).Objects[cc].Sprite > UINT16_MAX)
+			const auto &trobj = _GP(thisroom).Objects[cc];
+			auto &crobj = _G(croom)->obj[cc];
+			crobj.x = trobj.X;
+			crobj.y = trobj.Y;
+			crobj.num = Math::InRangeOrDef<uint16_t>(trobj.Sprite, 0);
+			crobj.on = trobj.IsOn;
+			crobj.view = RoomObject::NoView;
+			crobj.loop = 0;
+			crobj.frame = 0;
+			crobj.wait = 0;
+			crobj.transparent = 0;
+			crobj.moving = -1;
+			crobj.flags = trobj.Flags;
+			crobj.baseline = -1;
+			crobj.zoom = 100;
+			crobj.last_width = 0;
+			crobj.last_height = 0;
+			crobj.blocking_width = 0;
+			crobj.blocking_height = 0;
+			crobj.name = trobj.Name;
+			if (trobj.Baseline >= 0)
+				crobj.baseline = trobj.Baseline;
+			if (trobj.Sprite > UINT16_MAX)
 				debug_script_warn("Warning: object's (id %d) sprite %d outside of internal range (%d), reset to 0",
-				                  cc, _GP(thisroom).Objects[cc].Sprite, UINT16_MAX);
+				                  cc, trobj.Sprite, UINT16_MAX);
 		}
 		for (size_t i = 0; i < (size_t)MAX_WALK_BEHINDS; ++i)
 			_G(croom)->walkbehind_base[i] = _GP(thisroom).WalkBehinds[i].Baseline;
@@ -614,13 +617,13 @@ void load_new_room(int newnum, CharacterInfo *forchar) {
 		_G(croom)->intrRoom = *_GP(thisroom).Interaction;
 		for (cc = 0; cc < MAX_ROOM_HOTSPOTS; cc++)
 			_G(croom)->intrHotspot[cc] = *_GP(thisroom).Hotspots[cc].Interaction;
-		for (cc = 0; cc < MAX_ROOM_OBJECTS; cc++)
+		for (cc = 0; cc < _GP(thisroom).Objects.size(); cc++)
 			_G(croom)->intrObject[cc] = *_GP(thisroom).Objects[cc].Interaction;
 		for (cc = 0; cc < MAX_ROOM_REGIONS; cc++)
 			_G(croom)->intrRegion[cc] = *_GP(thisroom).Regions[cc].Interaction;
 	}
 
-	_G(objs) = &_G(croom)->obj[0];
+	_G(objs) = _G(croom)->obj.size() > 0 ? &_G(croom)->obj[0] : nullptr;
 
 	for (cc = 0; cc < _G(croom)->numobj; cc++) {
 		// export the object's script object
diff --git a/engines/ags/engine/ac/room_status.cpp b/engines/ags/engine/ac/room_status.cpp
index b1625f0bae9..c424544a983 100644
--- a/engines/ags/engine/ac/room_status.cpp
+++ b/engines/ags/engine/ac/room_status.cpp
@@ -73,23 +73,28 @@ void RoomStatus::FreeProperties() {
 	for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) {
 		hsProps[i].clear();
 	}
-	for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
-		objProps[i].clear();
-	}
+	objProps.clear();
 }
 
 void RoomStatus::ReadFromFile_v321(Stream *in) {
+	FreeScriptData();
+	FreeProperties();
+
 	beenhere = in->ReadInt32();
 	numobj = in->ReadInt32();
+	obj.resize(numobj);
+	objProps.resize(numobj);
+	intrObject.resize(numobj);
 	ReadRoomObjects_Aligned(in);
+
 	in->Seek(MAX_LEGACY_ROOM_FLAGS * sizeof(int16_t)); // flagstates (OBSOLETE)
 	tsdatasize = in->ReadInt32();
 	in->ReadInt32(); // tsdata
 	for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) {
 		intrHotspot[i].ReadFromSavedgame_v321(in);
 	}
-	for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
-		intrObject[i].ReadFromSavedgame_v321(in);
+	for (auto &intr : intrObject) {
+		intr.ReadFromSavedgame_v321(in);
 	}
 	for (int i = 0; i < MAX_ROOM_REGIONS; ++i) {
 		intrRegion[i].ReadFromSavedgame_v321(in);
@@ -106,16 +111,16 @@ void RoomStatus::ReadFromFile_v321(Stream *in) {
 		for (int i = 0; i < MAX_ROOM_HOTSPOTS; ++i) {
 			Properties::ReadValues(hsProps[i], in);
 		}
-		for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
-			Properties::ReadValues(objProps[i], in);
+		for (auto &props : objProps) {
+			Properties::ReadValues(props, in);
 		}
 	}
 }
 
 void RoomStatus::ReadRoomObjects_Aligned(Shared::Stream *in) {
 	AlignedStream align_s(in, Shared::kAligned_Read);
-	for (int i = 0; i < MAX_ROOM_OBJECTS; ++i) {
-		obj[i].ReadFromSavegame(&align_s, 0);
+	for (auto &o : obj) {
+		o.ReadFromSavegame(&align_s, 0);
 		align_s.Reset();
 	}
 }
@@ -126,7 +131,10 @@ void RoomStatus::ReadFromSavegame(Stream *in, int save_ver) {
 
 	beenhere = in->ReadInt8();
 	numobj = in->ReadInt32();
-	for (int i = 0; i < numobj; ++i) {
+	obj.resize(numobj);
+	objProps.resize(numobj);
+	intrObject.resize(numobj);
+	for (size_t i = 0; i < numobj; ++i) {
 		obj[i].ReadFromSavegame(in, save_ver);
 		Properties::ReadValues(objProps[i], in);
 		if (_G(loaded_game_file_version) <= kGameVersion_272)
@@ -163,7 +171,7 @@ void RoomStatus::ReadFromSavegame(Stream *in, int save_ver) {
 void RoomStatus::WriteToSavegame(Stream *out) const {
 	out->WriteInt8(beenhere);
 	out->WriteInt32(numobj);
-	for (int i = 0; i < numobj; ++i) {
+	for (size_t i = 0; i < numobj; ++i) {
 		obj[i].WriteToSavegame(out);
 		Properties::WriteValues(objProps[i], out);
 		if (_G(loaded_game_file_version) <= kGameVersion_272)
diff --git a/engines/ags/engine/ac/room_status.h b/engines/ags/engine/ac/room_status.h
index ee8d2e79f14..bf17316e336 100644
--- a/engines/ags/engine/ac/room_status.h
+++ b/engines/ags/engine/ac/room_status.h
@@ -52,17 +52,17 @@ struct HotspotState {
 struct RoomStatus {
 	int   beenhere = 0;
 	int   numobj = 0;
-	RoomObject obj[MAX_ROOM_OBJECTS];
+	std::vector<RoomObject> obj;
 	int   tsdatasize = 0;
 	char *tsdata = nullptr;
 	Interaction intrHotspot[MAX_ROOM_HOTSPOTS];
-	Interaction intrObject[MAX_ROOM_OBJECTS];
+	std::vector<Interaction> intrObject;
 	Interaction intrRegion[MAX_ROOM_REGIONS];
 	Interaction intrRoom;
 
 	Shared::StringIMap roomProps;
 	Shared::StringIMap hsProps[MAX_ROOM_HOTSPOTS];
-	Shared::StringIMap objProps[MAX_ROOM_OBJECTS];
+	std::vector<Shared::StringIMap> objProps;
 	HotspotState hotspot[MAX_ROOM_HOTSPOTS];
 	int8  region_enabled[MAX_ROOM_REGIONS];
 	short walkbehind_base[MAX_WALK_BEHINDS];
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index 3f2c81cc643..63c69626c34 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -374,8 +374,7 @@ void DoBeforeRestore(PreservedParams &pp) {
 	_G(dialogScriptsInst) = nullptr;
 
 	resetRoomStatuses();
-	_GP(troom).FreeScriptData();
-	_GP(troom).FreeProperties();
+	_GP(troom) = RoomStatus(); // reset temp room state
 	free_do_once_tokens();
 
 	// unregister gui controls from API exports
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 4bc8a5ae073..277cf1adf3c 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -917,8 +917,9 @@ HSaveError WriteThisRoom(Stream *out) {
 	}
 
 	// room object movement paths cache
-	out->WriteInt32(_GP(thisroom).ObjectCount + 1);
-	for (size_t i = 0; i < _GP(thisroom).ObjectCount + 1; ++i) {
+	// CHECKME: not sure why it saves (object count + 1) move lists
+	out->WriteInt32(_GP(thisroom).Objects.size() + 1);
+	for (size_t i = 0; i < _GP(thisroom).Objects.size() + 1; ++i) {
 		_GP(mls)[i].WriteToFile(out);
 	}
 
diff --git a/engines/ags/shared/game/room_file.cpp b/engines/ags/shared/game/room_file.cpp
index 0db9e4bd203..de5529dfae7 100644
--- a/engines/ags/shared/game/room_file.cpp
+++ b/engines/ags/shared/game/room_file.cpp
@@ -149,12 +149,13 @@ HError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) {
 	room->Edges.Right = in->ReadInt16();
 
 	// Room objects
-	room->ObjectCount = in->ReadInt16();
-	if (room->ObjectCount > MAX_ROOM_OBJECTS)
-		return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many objects (in room: %d, max: %d).", room->ObjectCount, MAX_ROOM_OBJECTS));
+	uint16_t obj_count = in->ReadInt16();
+	if (obj_count > MAX_ROOM_OBJECTS)
+		return new RoomFileError(kRoomFileErr_IncompatibleEngine, String::FromFormat("Too many objects (in room: %d, max: %d).", obj_count, MAX_ROOM_OBJECTS));
 
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		ReadRoomObject(room->Objects[i], in);
+	room->Objects.resize(obj_count);
+	for (auto &obj : room->Objects)
+		ReadRoomObject(obj, in);
 
 	// Legacy interactions
 	if (data_ver >= kRoomVersion_253) {
@@ -169,8 +170,8 @@ HError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) {
 	if (data_ver >= kRoomVersion_241 && data_ver < kRoomVersion_300a) {
 		for (size_t i = 0; i < room->HotspotCount; ++i)
 			room->Hotspots[i].Interaction.reset(Interaction::CreateFromStream(in));
-		for (size_t i = 0; i < room->ObjectCount; ++i)
-			room->Objects[i].Interaction.reset(Interaction::CreateFromStream(in));
+		for (auto &obj : room->Objects)
+			obj.Interaction.reset(Interaction::CreateFromStream(in));
 		room->Interaction.reset(Interaction::CreateFromStream(in));
 	}
 
@@ -190,22 +191,22 @@ HError ReadMainBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) {
 		room->EventHandlers.reset(InteractionScripts::CreateFromStream(in));
 		for (size_t i = 0; i < room->HotspotCount; ++i)
 			room->Hotspots[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in));
-		for (size_t i = 0; i < room->ObjectCount; ++i)
-			room->Objects[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in));
+		for (auto &obj : room->Objects)
+			obj.EventHandlers.reset(InteractionScripts::CreateFromStream(in));
 		for (size_t i = 0; i < room->RegionCount; ++i)
 			room->Regions[i].EventHandlers.reset(InteractionScripts::CreateFromStream(in));
 	}
 
 	if (data_ver >= kRoomVersion_200_alpha) {
-		for (size_t i = 0; i < room->ObjectCount; ++i)
-			room->Objects[i].Baseline = in->ReadInt32();
+		for (auto &obj : room->Objects)
+			obj.Baseline = in->ReadInt32();
 		room->Width = in->ReadInt16();
 		room->Height = in->ReadInt16();
 	}
 
 	if (data_ver >= kRoomVersion_262)
-		for (size_t i = 0; i < room->ObjectCount; ++i)
-			room->Objects[i].Flags = in->ReadInt16();
+		for (auto &obj : room->Objects)
+			obj.Flags = in->ReadInt16();
 
 	if (data_ver >= kRoomVersion_200_final)
 		room->MaskResolution = in->ReadInt16();
@@ -339,15 +340,15 @@ HError ReadCompSc3Block(RoomStruct *room, Stream *in, RoomFileVersion /*data_ver
 // Room object names
 HError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) {
 	size_t name_count = static_cast<uint8_t>(in->ReadInt8());
-	if (name_count != room->ObjectCount)
+	if (name_count != room->Objects.size())
 		return new RoomFileError(kRoomFileErr_InconsistentData,
-			String::FromFormat("In the object names block, expected name count: %zu, got %zu", room->ObjectCount, name_count));
+			String::FromFormat("In the object names block, expected name count: %zu, got %zu", room->Objects.size(), name_count));
 
-	for (size_t i = 0; i < room->ObjectCount; ++i) {
+	for (auto &obj : room->Objects) {
 		if (data_ver >= kRoomVersion_3415)
-			room->Objects[i].Name = StrUtil::ReadString(in);
+			obj.Name = StrUtil::ReadString(in);
 		else
-			room->Objects[i].Name.ReadCount(in, LEGACY_MAXOBJNAMELEN);
+			obj.Name.ReadCount(in, LEGACY_MAXOBJNAMELEN);
 	}
 	return HError::None();
 }
@@ -355,15 +356,15 @@ HError ReadObjNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver)
 // Room object script names
 HError ReadObjScNamesBlock(RoomStruct *room, Stream *in, RoomFileVersion data_ver) {
 	size_t name_count = static_cast<uint8_t>(in->ReadInt8());
-	if (name_count != room->ObjectCount)
+	if (name_count != room->Objects.size())
 		return new RoomFileError(kRoomFileErr_InconsistentData,
-			String::FromFormat("In the object script names block, expected name count: %zu, got %zu", room->ObjectCount, name_count));
+			String::FromFormat("In the object script names block, expected name count: %zu, got %zu", room->Objects.size(), name_count));
 
-	for (size_t i = 0; i < room->ObjectCount; ++i) {
+	for (auto &obj : room->Objects) {
 		if (data_ver >= kRoomVersion_3415)
-			room->Objects[i].ScriptName = StrUtil::ReadString(in);
+			obj.ScriptName = StrUtil::ReadString(in);
 		else
-			room->Objects[i].ScriptName.ReadCount(in, MAX_SCRIPT_NAME_LEN);
+			obj.ScriptName.ReadCount(in, MAX_SCRIPT_NAME_LEN);
 	}
 	return HError::None();
 }
@@ -398,8 +399,8 @@ HError ReadPropertiesBlock(RoomStruct *room, Stream *in, RoomFileVersion /*data_
 	errors += Properties::ReadValues(room->Properties, in);
 	for (size_t i = 0; i < room->HotspotCount; ++i)
 		errors += Properties::ReadValues(room->Hotspots[i].Properties, in);
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		errors += Properties::ReadValues(room->Objects[i].Properties, in);
+	for (auto &obj : room->Objects)
+		errors += Properties::ReadValues(obj.Properties, in);
 
 	if (errors > 0)
 		return new RoomFileError(kRoomFileErr_InvalidPropertyValues);
@@ -525,9 +526,9 @@ HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool g
 		for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i)
 			if (!room->Hotspots[i].Interaction)
 				room->Hotspots[i].Interaction.reset(new Interaction());
-		for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i)
-			if (!room->Objects[i].Interaction)
-				room->Objects[i].Interaction.reset(new Interaction());
+		for (auto &obj : room->Objects)
+			if (!obj.Interaction)
+				obj.Interaction.reset(new Interaction());
 		for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i)
 			if (!room->Regions[i].Interaction)
 				room->Regions[i].Interaction.reset(new Interaction());
@@ -535,14 +536,14 @@ HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool g
 
 	// Upgade room object script names
 	if (data_ver < kRoomVersion_300a) {
-		for (size_t i = 0; i < room->ObjectCount; ++i) {
-			if (room->Objects[i].ScriptName.GetLength() > 0) {
+		for (auto &obj : room->Objects) {
+			if (obj.ScriptName.GetLength() > 0) {
 				String jibbledScriptName;
-				jibbledScriptName.Format("o%s", room->Objects[i].ScriptName.GetCStr());
+				jibbledScriptName.Format("o%s", obj.ScriptName.GetCStr());
 				jibbledScriptName.MakeLower();
 				if (jibbledScriptName.GetLength() >= 2)
 					jibbledScriptName.SetAt(1, toupper(jibbledScriptName[1u]));
-				room->Objects[i].ScriptName = jibbledScriptName;
+				obj.ScriptName = jibbledScriptName;
 			}
 		}
 	}
@@ -553,11 +554,11 @@ HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool g
 	// function in the engine
 	if (data_ver < kRoomVersion_303b && game_is_hires) {
 		const int mul = HIRES_COORD_MULTIPLIER;
-		for (size_t i = 0; i < room->ObjectCount; ++i) {
-			room->Objects[i].X *= mul;
-			room->Objects[i].Y *= mul;
-			if (room->Objects[i].Baseline > 0) {
-				room->Objects[i].Baseline *= mul;
+		for (auto &obj : room->Objects) {
+			obj.X *= mul;
+			obj.Y *= mul;
+			if (obj.Baseline > 0) {
+				obj.Baseline *= mul;
 			}
 		}
 
@@ -582,8 +583,8 @@ HRoomFileError UpdateRoomData(RoomStruct *room, RoomFileVersion data_ver, bool g
 	// NOTE: this is impossible to do without game sprite information loaded beforehand
 	// NOTE: this should be done after coordinate conversion above for simplicity
 	if (data_ver < kRoomVersion_300a) {
-		for (size_t i = 0; i < room->ObjectCount; ++i)
-			room->Objects[i].Y += sprinfos[room->Objects[i].Sprite].Height;
+		for (auto &obj : room->Objects)
+			obj.Y += sprinfos[obj.Sprite].Height;
 	}
 
 	if (data_ver >= kRoomVersion_251) {
@@ -681,9 +682,9 @@ void WriteMainBlock(const RoomStruct *room, Stream *out) {
 	out->WriteInt16(room->Edges.Left);
 	out->WriteInt16(room->Edges.Right);
 
-	out->WriteInt16((int16_t)room->ObjectCount);
-	for (size_t i = 0; i < room->ObjectCount; ++i) {
-		WriteRoomObject(room->Objects[i], out);
+	out->WriteInt16((int16_t)room->Objects.size());
+	for (const auto &obj : room->Objects) {
+		WriteRoomObject(obj, out);
 	}
 
 	out->WriteInt32(0); // legacy interaction vars
@@ -692,17 +693,17 @@ void WriteMainBlock(const RoomStruct *room, Stream *out) {
 	WriteInteractionScripts(room->EventHandlers.get(), out);
 	for (size_t i = 0; i < room->HotspotCount; ++i)
 		WriteInteractionScripts(room->Hotspots[i].EventHandlers.get(), out);
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		WriteInteractionScripts(room->Objects[i].EventHandlers.get(), out);
+	for (const auto &obj : room->Objects)
+		WriteInteractionScripts(obj.EventHandlers.get(), out);
 	for (size_t i = 0; i < room->RegionCount; ++i)
 		WriteInteractionScripts(room->Regions[i].EventHandlers.get(), out);
 
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		out->WriteInt32(room->Objects[i].Baseline);
+	for (const auto &obj : room->Objects)
+		out->WriteInt32(obj.Baseline);
 	out->WriteInt16(room->Width);
 	out->WriteInt16(room->Height);
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		out->WriteInt16(room->Objects[i].Flags);
+	for (const auto &obj : room->Objects)
+		out->WriteInt16(obj.Flags);
 	out->WriteInt16(room->MaskResolution);
 
 	out->WriteInt32(MAX_WALK_AREAS + 1);
@@ -755,15 +756,15 @@ void WriteCompSc3Block(const RoomStruct *room, Stream *out) {
 }
 
 void WriteObjNamesBlock(const RoomStruct *room, Stream *out) {
-	out->WriteByte((int8_t)room->ObjectCount);
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		Shared::StrUtil::WriteString(room->Objects[i].Name, out);
+	out->WriteByte((uint8_t)room->Objects.size());
+	for (const auto &obj : room->Objects)
+		Shared::StrUtil::WriteString(obj.Name, out);
 }
 
 void WriteObjScNamesBlock(const RoomStruct *room, Stream *out) {
-	out->WriteByte((int8_t)room->ObjectCount);
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		Shared::StrUtil::WriteString(room->Objects[i].ScriptName, out);
+	out->WriteByte((uint8_t)room->Objects.size());
+	for (const auto &obj : room->Objects)
+		Shared::StrUtil::WriteString(obj.ScriptName, out);
 }
 
 void WriteAnimBgBlock(const RoomStruct *room, Stream *out) {
@@ -781,8 +782,8 @@ void WritePropertiesBlock(const RoomStruct *room, Stream *out) {
 	Properties::WriteValues(room->Properties, out);
 	for (size_t i = 0; i < room->HotspotCount; ++i)
 		Properties::WriteValues(room->Hotspots[i].Properties, out);
-	for (size_t i = 0; i < room->ObjectCount; ++i)
-		Properties::WriteValues(room->Objects[i].Properties, out);
+	for (const auto &obj : room->Objects)
+		Properties::WriteValues(obj.Properties, out);
 }
 
 void WriteStrOptions(const RoomStruct *room, Stream *out) {
@@ -801,7 +802,7 @@ HRoomFileError WriteRoomData(const RoomStruct *room, Stream *out, RoomFileVersio
 	if (room->CompiledScript)
 		WriteRoomBlock(room, kRoomFblk_CompScript3, WriteCompSc3Block, out);
 	// Object names
-	if (room->ObjectCount > 0) {
+	if (room->Objects.size() > 0) {
 		WriteRoomBlock(room, kRoomFblk_ObjectNames, WriteObjNamesBlock, out);
 		WriteRoomBlock(room, kRoomFblk_ObjectScNames, WriteObjScNamesBlock, out);
 	}
diff --git a/engines/ags/shared/game/room_struct.cpp b/engines/ags/shared/game/room_struct.cpp
index a2f76d3f8c5..e5cd1915e1f 100644
--- a/engines/ags/shared/game/room_struct.cpp
+++ b/engines/ags/shared/game/room_struct.cpp
@@ -112,10 +112,7 @@ void RoomStruct::Free() {
 		Hotspots[i].Interaction.reset();
 		Hotspots[i].Properties.clear();
 	}
-	for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i) {
-		Objects[i].Interaction.reset();
-		Objects[i].Properties.clear();
-	}
+	Objects.clear();
 	for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i) {
 		Regions[i].Interaction.reset();
 		Regions[i].Properties.clear();
@@ -139,8 +136,8 @@ void RoomStruct::FreeScripts() {
 	EventHandlers.reset();
 	for (size_t i = 0; i < HotspotCount; ++i)
 		Hotspots[i].EventHandlers.reset();
-	for (size_t i = 0; i < ObjectCount; ++i)
-		Objects[i].EventHandlers.reset();
+	for (auto &obj : Objects)
+		obj.EventHandlers.reset();
 	for (size_t i = 0; i < RegionCount; ++i)
 		Regions[i].EventHandlers.reset();
 }
@@ -159,7 +156,6 @@ void RoomStruct::InitDefaults() {
 
 	BgFrameCount = 1;
 	HotspotCount = 0;
-	ObjectCount = 0;
 	RegionCount = 0;
 	WalkAreaCount = 0;
 	WalkBehindCount = 0;
@@ -167,8 +163,6 @@ void RoomStruct::InitDefaults() {
 
 	for (size_t i = 0; i < (size_t)MAX_ROOM_HOTSPOTS; ++i)
 		Hotspots[i] = RoomHotspot();
-	for (size_t i = 0; i < (size_t)MAX_ROOM_OBJECTS; ++i)
-		Objects[i] = RoomObjectInfo();
 	for (size_t i = 0; i < (size_t)MAX_ROOM_REGIONS; ++i)
 		Regions[i] = RoomRegion();
 	for (size_t i = 0; i <= (size_t)MAX_WALK_AREAS; ++i)
diff --git a/engines/ags/shared/game/room_struct.h b/engines/ags/shared/game/room_struct.h
index 89b1a182b50..e54322f4e0b 100644
--- a/engines/ags/shared/game/room_struct.h
+++ b/engines/ags/shared/game/room_struct.h
@@ -349,8 +349,7 @@ public:
 	// Room entities
 	size_t                  HotspotCount;
 	RoomHotspot             Hotspots[MAX_ROOM_HOTSPOTS];
-	size_t                  ObjectCount;
-	RoomObjectInfo          Objects[MAX_ROOM_OBJECTS];
+	std::vector<RoomObjectInfo> Objects;
 	size_t                  RegionCount;
 	RoomRegion              Regions[MAX_ROOM_REGIONS];
 	size_t                  WalkAreaCount;


Commit: 13c3d6cddcf08dd0f2e3e4d41711ff1e26ba3acd
    https://github.com/scummvm/scummvm/commit/13c3d6cddcf08dd0f2e3e4d41711ff1e26ba3acd
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-15T22:13:02+01:00

Commit Message:
AGS: Increased Room Objects limit to 256

>From upstream b71f820c992d70ffef8f40b783ee4b53df634254

Changed paths:
    engines/ags/engine/ac/draw.cpp
    engines/ags/engine/ac/runtime_defines.h
    engines/ags/engine/game/savegame_components.cpp
    engines/ags/engine/game/savegame_v321.cpp
    engines/ags/globals.h
    engines/ags/shared/game/room_struct.h


diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 830e6e22675..22106aacce6 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1141,7 +1141,6 @@ static bool scale_and_flip_sprite(int useindx, int sppic, int newwidth, int newh
 // returns 1 if nothing at all has changed and actsps is still
 // intact from last time; 0 otherwise
 int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysUseSoftware) {
-	int useindx = aa;
 	bool hardwareAccelerated = !alwaysUseSoftware && _G(gfxDriver)->HasAcceleratedTransform();
 
 	if (_GP(spriteset)[_G(objs)[aa].num] == nullptr)
@@ -1215,6 +1214,7 @@ int construct_object_gfx(int aa, int *drawnWidth, int *drawnHeight, bool alwaysU
 		isMirrored = true;
 	}
 
+	const int useindx = aa; // actsps array index
 	auto &actsp = _GP(actsps)[useindx];
 	actsp.SpriteID = _G(objs)[aa].num; // for texture sharing
 	if ((hardwareAccelerated) &&
@@ -1322,10 +1322,10 @@ void prepare_objects_for_drawing() {
 		if ((_G(objs)[aa].x >= _GP(thisroom).Width) || (_G(objs)[aa].y < 1))
 			continue;
 
-		const int useindx = aa;
 		int tehHeight;
 		int actspsIntact = construct_object_gfx(aa, nullptr, &tehHeight, false);
 
+		const int useindx = aa; // actsps array index
 		auto &actsp = _GP(actsps)[useindx];
 
 		// update the cache for next time
@@ -1437,7 +1437,6 @@ void prepare_characters_for_drawing() {
 		if (_GP(game).chars[aa].on == 0) continue;
 		if (_GP(game).chars[aa].room != _G(displayed_room)) continue;
 		_G(eip_guinum) = aa;
-		const int useindx = aa + MAX_ROOM_OBJECTS;
 
 		CharacterInfo *chin = &_GP(game).chars[aa];
 		_G(our_eip) = 330;
@@ -1512,6 +1511,7 @@ void prepare_characters_for_drawing() {
 
 		_G(our_eip) = 3331;
 
+		const int useindx = aa + ACTSP_OBJSOFF; // actsps array index
 		auto &actsp = _GP(actsps)[useindx];
 		actsp.SpriteID = sppic; // for texture sharing
 
@@ -1666,7 +1666,7 @@ void prepare_characters_for_drawing() {
 }
 
 Bitmap *get_cached_character_image(int charid) {
-	return _GP(actsps)[charid + MAX_ROOM_OBJECTS].Bmp.get();
+	return _GP(actsps)[charid + ACTSP_OBJSOFF].Bmp.get();
 }
 
 Bitmap *get_cached_object_image(int objid) {
diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h
index 3899dfb4881..6bfcf23e9e7 100644
--- a/engines/ags/engine/ac/runtime_defines.h
+++ b/engines/ags/engine/ac/runtime_defines.h
@@ -125,7 +125,10 @@ const int LegacyRoomVolumeFactor = 30;
 #define FOR_ANIMATION 1
 #define FOR_SCRIPT    2
 #define FOR_EXITLOOP  3
-#define CHMLSOFFS (MAX_ROOM_OBJECTS+1)    // reserve this many movelists for objects & stuff
+// an actsps index offset for characters
+#define ACTSP_OBJSOFF (MAX_ROOM_OBJECTS)
+// a 1-based movelist index offset for characters
+#define CHMLSOFFS (1 + MAX_ROOM_OBJECTS)
 #define MAX_SCRIPT_AT_ONCE 10
 #define EVENT_NONE       0
 #define EVENT_INPROGRESS 1
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 277cf1adf3c..90df78e729b 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -967,7 +967,7 @@ HSaveError ReadThisRoom(Stream *in, int32_t cmp_ver, const PreservedParams & /*p
 	if (!AssertCompatLimit(err, objmls_count, CHMLSOFFS, "room object move lists"))
 		return err;
 	for (int i = 0; i < objmls_count; ++i) {
-		err = _GP(mls)[i].ReadFromFile(in, cmp_ver > 0 ? 1 : 0); // FIXME!!
+		err = _GP(mls)[i].ReadFromFile(in, cmp_ver > 0 ? 1 : 0); // FIXME cmp_ver, ugly
 		if (!err)
 			return err;
 	}
diff --git a/engines/ags/engine/game/savegame_v321.cpp b/engines/ags/engine/game/savegame_v321.cpp
index 4cfb35d240a..5236b595a9e 100644
--- a/engines/ags/engine/game/savegame_v321.cpp
+++ b/engines/ags/engine/game/savegame_v321.cpp
@@ -175,7 +175,6 @@ static void ReadMoveList_Aligned(Stream *in) {
 	AlignedStream align_s(in, Shared::kAligned_Read);
 	for (int i = 0; i < _GP(game).numcharacters + MAX_ROOM_OBJECTS + 1; ++i) {
 		_GP(mls)[i].ReadFromFile_Legacy(&align_s);
-
 		align_s.Reset();
 	}
 }
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 71a0a20b6b9..982f4dbc695 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -575,8 +575,9 @@ public:
 	AGS::Engine::IDriverDependantBitmap *_blankSidebarImage = nullptr;
 	AGS::Engine::IDriverDependantBitmap *_debugConsole = nullptr;
 
-	// actsps is used for temporary storage of the bitamp image
-	// of the latest version of the sprite
+	// actsps is used for temporary storage of the bitamp and texture
+	// of the latest version of the sprite (room objects and characters);
+	// objects sprites begin with index 0, characters are after MAX_ROOM_OBJECTS
 	std::vector<ObjTexture> *_actsps;
 	// Walk-behind textures (3D renderers only)
 	std::vector<ObjTexture> *_walkbehindobj;
@@ -758,6 +759,8 @@ public:
 	ObjectCache *_objcache;
 	std::vector<Point> *_screenovercache;
 	std::vector<CharacterExtras> *_charextra;
+	// MoveLists for characters and room objects; NOTE: 1-based array!
+	// object sprites begin with index 1, characters are after MAX_ROOM_OBJECTS + 1
 	std::vector<MoveList> *_mls;
 
 	GameSetup *_usetup;
diff --git a/engines/ags/shared/game/room_struct.h b/engines/ags/shared/game/room_struct.h
index e54322f4e0b..7852e895cea 100644
--- a/engines/ags/shared/game/room_struct.h
+++ b/engines/ags/shared/game/room_struct.h
@@ -101,8 +101,8 @@ enum RoomFlags {
 
 #define MAX_ROOM_BGFRAMES  5   // max number of frames in animating bg scene
 
-#define MAX_ROOM_HOTSPOTS  50  // v2.62 increased from 20 to 30; v2.8 to 50
-#define MAX_ROOM_OBJECTS   40
+#define MAX_ROOM_HOTSPOTS  50  // v2.62: 20 -> 30; v2.8: -> 50
+#define MAX_ROOM_OBJECTS   256 // v3.6.0: 40 -> 256 (now limited by room format)
 #define MAX_ROOM_REGIONS   16
 // TODO: this is remains of the older code, MAX_WALK_AREAS = real number - 1, where
 // -1 is for the solid wall. When fixing this you need to be careful, because some




More information about the Scummvm-git-logs mailing list