[Scummvm-git-logs] scummvm master -> 28b91b2eef570ea241c810c4047d567d05fb385c

a-yyg 76591232+a-yyg at users.noreply.github.com
Mon Jul 12 04:10:11 UTC 2021


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

Summary:
a9f7ee09d7 SAGA2: Implement Sensor save/loading
52dce2abe4 SAGA2: Implement TempActorCount save/loading
09a416c4ff SAGA2: Implement Mission save/loading
5cc7b8803c SAGA2: Implement FactionTallies save/loading
cbf1177550 SAGA2: Implement TileModeState save/loading
1bcdc8eb36 SAGA2: Fix alloc-dealloc mismatch
a6a98833f7 SAGA2: Add Sensor debug output
db9ad228cd SAGA2: Implement SpellState save/loading
d2f96b708a SAGA2: Implement AutoMap save/loading
7f359b450f SAGA2: Implement UIState save/loading
3fa5f4b67f SAGA2: Implement Palette State save/loading
6d84b504bc SAGA2: Fix savePaletteState debug message
28b91b2eef SAGA2: Implement ContainerNodes save/loading


Commit: a9f7ee09d742a2f4ef9c4d1351cc29333b20e84f
    https://github.com/scummvm/scummvm/commit/a9f7ee09d742a2f4ef9c4d1351cc29333b20e84f
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement Sensor save/loading

Changed paths:
    engines/saga2/loadsave.cpp
    engines/saga2/sensor.cpp
    engines/saga2/sensor.h


diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index b22b1e54b2..4f927211a4 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -163,9 +163,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveSpeechTasks(out);
 	saveActiveRegions(out);
 	saveTimers(out);
+	saveSensors(out);
 
 #if 0
-	saveSensors(saveGame);
 	saveTempActorCount(saveGame);
 	saveMissions(saveGame);
 	saveFactionTallies(saveGame);
@@ -359,15 +359,15 @@ void loadSavedGameState(int16 saveNo) {
 			} else
 				error("Timers loaded prematurely");
 			break;
-#if 0
 
 		case MKTAG('S', 'E', 'N', 'S'):
 			if (loadFlags & loadActorsFlag) {
-				loadSensors(saveGame);
+				loadSensors(in);
 				loadFlags |= loadSensorsFlag;
 			} else
 				error("Sensors loaded prematurely");
 			break;
+#if 0
 
 		case MKTAG('A', 'C', 'N', 'T'):
 			loadTempActorCount(saveGame);
diff --git a/engines/saga2/sensor.cpp b/engines/saga2/sensor.cpp
index 8fa0ecbbf0..ab48ff3594 100644
--- a/engines/saga2/sensor.cpp
+++ b/engines/saga2/sensor.cpp
@@ -133,6 +133,52 @@ void *constructSensor(int16 ctr, void *buf) {
 	return buf;
 }
 
+void readSensor(int16 ctr, Common::InSaveFile *in) {
+	int16 type;
+	Sensor *sensor = nullptr;
+	SensorList *sl;
+
+	//  Get the sensor type
+	type = in->readSint16LE();
+	debugC(3, kDebugSaveload, "type = %d", type);
+
+	switch (type) {
+	case protaganistSensor:
+		sensor = new ProtaganistSensor(in, ctr);
+		break;
+
+	case specificObjectSensor:
+		sensor = new SpecificObjectSensor(in, ctr);
+		break;
+
+	case objectPropertySensor:
+		sensor = new ObjectPropertySensor(in, ctr);
+		break;
+
+	case specificActorSensor:
+		sensor = new SpecificActorSensor(in, ctr);
+		break;
+
+	case actorPropertySensor:
+		sensor = new ActorPropertySensor(in, ctr);
+		break;
+
+	case eventSensor:
+		sensor = new EventSensor(in, ctr);
+		break;
+	}
+
+	assert(sensor != nullptr);
+
+	//  Get the sensor list
+	sl = fetchSensorList(sensor->getObject());
+
+	assert(sl != nullptr);
+
+	//  Append this Sensor to the sensor list
+	sl->_list.push_back(sensor);
+}
+
 //----------------------------------------------------------------------
 //	Return the number of bytes needed to archive the specified Sensor in
 //	an archive buffer
@@ -160,6 +206,17 @@ void *archiveSensor(Sensor *sensor, void *buf) {
 	return buf;
 }
 
+void writeSensor(Sensor *sensor, Common::OutSaveFile *out) {
+	assert(sensor != NULL);
+
+	//  Store the sensor type
+	out->writeSint16LE(sensor->getType());
+	debugC(3, kDebugSaveload, "type = %d", sensor->getType());
+
+	//  Let the sensor store its data in the buffer
+	sensor->write(out);
+}
+
 //----------------------------------------------------------------------
 
 void checkSensors(void) {
@@ -293,6 +350,74 @@ void saveSensors(SaveFileConstructor &saveGame) {
 #endif
 }
 
+static int getSensorListID(SensorList *t) {
+	int i = 0;
+	for (Common::List<SensorList *>::iterator it = g_vm->_sensorListList.begin(); it != g_vm->_sensorListList.end(); it++, i++) {
+		if ((*it) == t)
+			return i;
+	}
+	return -1;
+}
+
+static int getSensorID(Sensor *t) {
+	int i = 0;
+	for (Common::List<Sensor *>::iterator it = g_vm->_sensorList.begin(); it != g_vm->_sensorList.end(); it++, i++) {
+		if ((*it) == t)
+			return i;
+	}
+	return -1;
+}
+
+
+void saveSensors(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving Sensors");
+
+	int16 sensorListCount = 0,
+	      sensorCount = 0;
+
+	int32 archiveBufSize = 0;
+
+	//  Add the sizes of the sensor list count an sensor count
+	archiveBufSize += sizeof(sensorListCount) + sizeof(sensorCount);
+
+	//  Tally the sensor lists
+	sensorListCount = g_vm->_sensorListList.size();
+
+	//  Add the total archive size of all of the sensor lists
+	archiveBufSize += sensorListCount * SensorList::archiveSize();
+
+	//  Tally the sensors and add the archive size of each
+	for (Common::List<Sensor *>::iterator it = g_vm->_sensorList.begin(); it != g_vm->_sensorList.end(); ++it) {
+		sensorCount++;
+		archiveBufSize += sizeof((*it)->checkCtr) + sensorArchiveSize(*it);
+	}
+
+	out->write("SENS", 4);
+	out->writeUint32LE(archiveBufSize);
+
+	//  Store the sensor list count and sensor count
+	out->writeSint16LE(sensorListCount);
+	out->writeSint16LE(sensorCount);
+
+	debugC(3, kDebugSaveload, "... sensorListCount = %d", sensorListCount);
+	debugC(3, kDebugSaveload, "... sensorCount = %d", sensorCount);
+
+	//  Archive all sensor lists
+	for (Common::List<SensorList *>::iterator it = g_vm->_sensorListList.begin(); it != g_vm->_sensorListList.end(); ++it) {
+		debugC(3, kDebugSaveload, "Saving SensorList %d", getSensorListID(*it));
+		(*it)->write(out);
+	}
+
+	//  Archive all sensors
+	for (Common::List<Sensor *>::iterator it = g_vm->_sensorList.begin(); it != g_vm->_sensorList.end(); ++it) {
+		debugC(3, kDebugSaveload, "Saving Sensor %d", getSensorID(*it));
+		out->writeSint16LE((*it)->checkCtr);
+		debugC(3, kDebugSaveload, "... ctr = %d", (*it)->checkCtr);
+
+		writeSensor(*it, out);
+	}
+}
+
 //----------------------------------------------------------------------
 //	Load sensors from a save file
 
@@ -341,6 +466,36 @@ void loadSensors(SaveFileReader &saveGame) {
 #endif
 }
 
+void loadSensors(Common::InSaveFile *in) {
+	debugC(2, kDebugSaveload, "Loading Sensors");
+
+	int16 sensorListCount,
+	      sensorCount;
+
+	//  Get the sensor list count and sensor count
+	sensorListCount = in->readSint16LE();
+	sensorCount = in->readSint16LE();
+	debugC(3, kDebugSaveload, "... sensorListCount = %d", sensorListCount);
+	debugC(3, kDebugSaveload, "... sensorCount = %d", sensorCount);
+
+	//  Restore all sensor lists
+	for (int i = 0; i < sensorListCount; i++) {
+		debugC(3, kDebugSaveload, "Loading SensorList %d", i);
+		new SensorList(in);
+	}
+
+	//  Restore all sensors
+	for (int i = 0; i < sensorCount; i++) {
+		int16 ctr;
+
+		debugC(3, kDebugSaveload, "Loading Sensor %d", i);
+		ctr = in->readSint16LE();
+		debugC(3, kDebugSaveload, "... ctr = %d", ctr);
+
+		readSensor(ctr, in);
+	}
+}
+
 //----------------------------------------------------------------------
 //	Cleanup the active sensors
 
@@ -391,6 +546,16 @@ SensorList::SensorList(void **buf) {
 	newSensorList(this);
 }
 
+SensorList::SensorList(Common::InSaveFile *in) {
+	ObjectID id = in->readUint16LE();
+
+	assert(isObject(id) || isActor(id));
+
+	obj = GameObject::objectAddress(id);
+
+	newSensorList(this);
+}
+
 //----------------------------------------------------------------------
 //	Archive this object in a buffer
 
@@ -401,6 +566,10 @@ void *SensorList::archive(void *buf) {
 	return buf;
 }
 
+void SensorList::write(Common::OutSaveFile *out) {
+	out->writeUint16LE(obj->thisID());
+}
+
 /* ===================================================================== *
    Sensor member functions
  * ===================================================================== */
@@ -431,6 +600,23 @@ Sensor::Sensor(void **buf, int16 ctr) {
 	newSensor(this, ctr);
 }
 
+Sensor::Sensor(Common::InSaveFile *in, int16 ctr) {
+	ObjectID objID = in->readUint16LE();
+
+	assert(isObject(objID) || isActor(objID));
+
+	//  Restore the object pointer
+	obj = GameObject::objectAddress(objID);
+
+	//  Restore the ID
+	id = in->readSint16LE();
+
+	//  Restore the range
+	range = in->readSint16LE();
+
+	newSensor(this, ctr);
+}
+
 //----------------------------------------------------------------------
 //	Return the number of bytes needed to archive this object in a buffer
 
@@ -459,6 +645,17 @@ void *Sensor::archive(void *buf) {
 	return buf;
 }
 
+void Sensor::write(Common::OutSaveFile *out) {
+	//  Store the object's ID
+	out->writeUint16LE(obj->thisID());
+
+	//  Store the sensor ID
+	out->writeSint16LE(id);
+
+	//  Store the range
+	out->writeSint16LE(range);
+}
+
 /* ===================================================================== *
    ProtaganistSensor member functions
  * ===================================================================== */
@@ -612,6 +809,14 @@ SpecificObjectSensor::SpecificObjectSensor(void **buf, int16 ctr) :
 	*buf = bufferPtr;
 }
 
+SpecificObjectSensor::SpecificObjectSensor(Common::InSaveFile *in, int16 ctr) :
+	ObjectSensor(in, ctr) {
+	debugC(3, kDebugSaveload, "Loading SpecificObjectSensor");
+
+	//  Restore the sought object's ID
+	soughtObjID = in->readUint16LE();
+}
+
 //----------------------------------------------------------------------
 //	Return the number of bytes needed to archive this object in a buffer
 
@@ -633,6 +838,16 @@ void *SpecificObjectSensor::archive(void *buf) {
 	return buf;
 }
 
+void SpecificObjectSensor::write(Common::OutSaveFile *out) {
+	debugC(3, kDebugSaveload, "Saving SpecificObjectSensor");
+
+	//  Let the base class archive its data
+	ObjectSensor::write(out);
+
+	//  Store the sought object's ID
+	out->writeUint16LE(soughtObjID);
+}
+
 //----------------------------------------------------------------------
 //	Return an integer representing the type of this sensor
 
@@ -706,6 +921,14 @@ ObjectPropertySensor::ObjectPropertySensor(void **buf, int16 ctr) :
 	*buf = bufferPtr;
 }
 
+ObjectPropertySensor::ObjectPropertySensor(Common::InSaveFile *in, int16 ctr) :
+	ObjectSensor(in, ctr) {
+	debugC(3, kDebugSaveload, "Loading ObjectPropertySensor");
+
+	//  Restore the object property ID
+	objectProperty = in->readSint16LE();;
+}
+
 //----------------------------------------------------------------------
 //	Return the number of bytes needed to archive this object in a buffer
 
@@ -727,6 +950,16 @@ void *ObjectPropertySensor::archive(void *buf) {
 	return buf;
 }
 
+void ObjectPropertySensor::write(Common::OutSaveFile *out) {
+	debugC(3, kDebugSaveload, "Saving ObjectPropertySensor");
+
+	//  Let the base class archive its data
+	ObjectSensor::write(out);
+
+	//  Store the object property's ID
+	out->writeSint16LE(objectProperty);
+}
+
 //----------------------------------------------------------------------
 //	Return an integer representing the type of this sensor
 
@@ -775,6 +1008,16 @@ SpecificActorSensor::SpecificActorSensor(void **buf, int16 ctr) : ActorSensor(bu
 	*buf = bufferPtr;
 }
 
+SpecificActorSensor::SpecificActorSensor(Common::InSaveFile *in, int16 ctr) : ActorSensor(in, ctr) {
+	debugC(3, kDebugSaveload, "Loading SpecificActorSensor");
+	ObjectID actorID = in->readUint16LE();
+
+	assert(isActor(actorID));
+
+	//  Restore the sought actor pointer
+	soughtActor = (Actor *)GameObject::objectAddress(actorID);
+}
+
 //----------------------------------------------------------------------
 //	Return the number of bytes needed to archive this object in a buffer
 
@@ -796,6 +1039,16 @@ void *SpecificActorSensor::archive(void *buf) {
 	return buf;
 }
 
+void SpecificActorSensor::write(Common::OutSaveFile *out) {
+	debugC(3, kDebugSaveload, "Saving SpecificActorSensor");
+
+	//  Let the base class archive its data
+	ActorSensor::write(out);
+
+	//  Store the sought actor's ID
+	out->writeUint16LE(soughtActor->thisID());
+}
+
 //----------------------------------------------------------------------
 //	Return an integer representing the type of this sensor
 
@@ -859,6 +1112,12 @@ ActorPropertySensor::ActorPropertySensor(void **buf, int16 ctr) : ActorSensor(bu
 	*buf = bufferPtr;
 }
 
+ActorPropertySensor::ActorPropertySensor(Common::InSaveFile *in, int16 ctr) : ActorSensor(in, ctr) {
+	debugC(3, kDebugSaveload, "Loading ActorPropertySensor");
+	//  Restore the actor property's ID
+	actorProperty = in->readSint16LE();
+}
+
 //----------------------------------------------------------------------
 //	Return the number of bytes needed to archive this object in a buffer
 
@@ -880,6 +1139,16 @@ void *ActorPropertySensor::archive(void *buf) {
 	return buf;
 }
 
+void ActorPropertySensor::write(Common::OutSaveFile *out) {
+	debugC(3, kDebugSaveload, "Saving ActorPropertySensor");
+
+	//  Let the base class archive its data
+	ActorSensor::write(out);
+
+	//  Store the actor property's ID
+	out->writeSint16LE(actorProperty);
+}
+
 //----------------------------------------------------------------------
 //	Return an integer representing the type of this sensor
 
@@ -922,6 +1191,12 @@ EventSensor::EventSensor(void **buf, int16 ctr) : Sensor(buf, ctr) {
 	*buf = bufferPtr;
 }
 
+EventSensor::EventSensor(Common::InSaveFile *in, int16 ctr) : Sensor(in, ctr) {
+	debugC(3, kDebugSaveload, "Loading EventSensor");
+	//  Restore the event type
+	eventType = in->readSint16LE();
+}
+
 //----------------------------------------------------------------------
 //	Return the number of bytes needed to archive this object in a buffer
 
@@ -943,6 +1218,16 @@ void *EventSensor::archive(void *buf) {
 	return buf;
 }
 
+void EventSensor::write(Common::OutSaveFile *out) {
+	debugC(3, kDebugSaveload, "Saving EventSensor");
+
+	//  Let the base class archive its data
+	Sensor::write(out);
+
+	//  Store the event type
+	out->writeSint16LE(eventType);
+}
+
 //----------------------------------------------------------------------
 //	Return an integer representing the type of this sensor
 
diff --git a/engines/saga2/sensor.h b/engines/saga2/sensor.h
index f1ff981979..f1455e3c3d 100644
--- a/engines/saga2/sensor.h
+++ b/engines/saga2/sensor.h
@@ -81,8 +81,10 @@ void assertEvent(const GameEvent &ev);
 void initSensors(void);
 //  Save all active sensors in a save file
 void saveSensors(SaveFileConstructor &saveGame);
+void saveSensors(Common::OutSaveFile *out);
 //  Load sensors from a save file
 void loadSensors(SaveFileReader &saveGame);
+void loadSensors(Common::InSaveFile *in);
 //  Cleanup the active sensors
 void cleanupSensors(void);
 
@@ -127,6 +129,8 @@ public:
 	//  Constructor -- reconstruct from archive buffer
 	SensorList(void **buf);
 
+	SensorList(Common::InSaveFile *in);
+
 	//  Return the number of bytes needed to archive this object in
 	//  a buffer
 	static int32 archiveSize(void) {
@@ -136,6 +140,8 @@ public:
 	//  Archive this object in a buffer
 	void *archive(void *buf);
 
+	void write(Common::OutSaveFile *out);
+
 	GameObject *getObject(void) {
 		return obj;
 	}
@@ -162,6 +168,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	Sensor(void **buf, int16 ctr);
 
+	Sensor(Common::InSaveFile *in, int16 ctr);
+
 	//  Virtural destructor
 	virtual ~Sensor(void) {
 		deleteSensor(this);
@@ -174,6 +182,8 @@ public:
 	//  Archive this object in a buffer
 	virtual void *archive(void *buf);
 
+	virtual void write(Common::OutSaveFile *out);
+
 	//  Return an integer representing the type of this sensor
 	virtual int16 getType(void) = 0;
 
@@ -208,6 +218,10 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	ProtaganistSensor(void **buf, int16 ctr) : Sensor(buf, ctr) {}
 
+	ProtaganistSensor(Common::InSaveFile *in, int16 ctr) : Sensor(in, ctr) {
+		debugC(3, kDebugSaveload, "Loading ProtagonistSensor");
+	}
+
 	//  Return an integer representing the type of this sensor
 	int16 getType(void);
 
@@ -232,6 +246,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	ObjectSensor(void **buf, int16 ctr) : Sensor(buf, ctr) {}
 
+	ObjectSensor(Common::InSaveFile *in, int16 ctr) : Sensor(in, ctr) {}
+
 	//  Determine if the object can sense what it's looking for
 	bool check(SenseInfo &info, uint32 senseFlags);
 
@@ -264,6 +280,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	SpecificObjectSensor(void **buf, int16 ctr);
 
+	SpecificObjectSensor(Common::InSaveFile *in, int16 ctr);
+
 	//  Return the number of bytes needed to archive this object in
 	//  a buffer
 	int32 archiveSize(void);
@@ -271,6 +289,8 @@ public:
 	//  Archive this object in a buffer
 	void *archive(void *buf);
 
+	void write(Common::OutSaveFile *out);
+
 	//  Return an integer representing the type of this sensor
 	int16 getType(void);
 
@@ -303,6 +323,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	ObjectPropertySensor(void **buf, int16 ctr);
 
+	ObjectPropertySensor(Common::InSaveFile *in, int16 ctr);
+
 	//  Return the number of bytes needed to archive this object in
 	//  a buffer
 	int32 archiveSize(void);
@@ -310,6 +332,8 @@ public:
 	//  Archive this object in a buffer
 	void *archive(void *buf);
 
+	void write(Common::OutSaveFile *out);
+
 	//  Return an integer representing the type of this sensor
 	int16 getType(void);
 
@@ -332,6 +356,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	ActorSensor(void **buf, int16 ctr) : ObjectSensor(buf, ctr) {}
 
+	ActorSensor(Common::InSaveFile *in, int16 ctr) : ObjectSensor(in, ctr) {}
+
 private:
 	//  Determine if an object meets the search criteria
 	bool isObjectSought(GameObject *obj);
@@ -361,6 +387,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	SpecificActorSensor(void **buf, int16 ctr);
 
+	SpecificActorSensor(Common::InSaveFile *in, int16 ctr);
+
 	//  Return the number of bytes needed to archive this object in
 	//  a buffer
 	int32 archiveSize(void);
@@ -368,6 +396,8 @@ public:
 	//  Archive this object in a buffer
 	void *archive(void *buf);
 
+	void write(Common::OutSaveFile *out);
+
 	//  Return an integer representing the type of this sensor
 	int16 getType(void);
 
@@ -400,6 +430,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	ActorPropertySensor(void **buf, int16 ctr);
 
+	ActorPropertySensor(Common::InSaveFile *in, int16 ctr);
+
 	//  Return the number of bytes needed to archive this object in
 	//  a buffer
 	int32 archiveSize(void);
@@ -407,6 +439,8 @@ public:
 	//  Archive this object in a buffer
 	void *archive(void *buf);
 
+	void write(Common::OutSaveFile *out);
+
 	//  Return an integer representing the type of this sensor
 	int16 getType(void);
 
@@ -433,6 +467,8 @@ public:
 	//  Constructor -- reconstruct from an archive buffer
 	EventSensor(void **buf, int16 ctr);
 
+	EventSensor(Common::InSaveFile *in, int16 ctr);
+
 	//  Return the number of bytes needed to archive this object in
 	//  a buffer
 	int32 archiveSize(void);
@@ -440,6 +476,8 @@ public:
 	//  Archive this object in a buffer
 	void *archive(void *buf);
 
+	void write(Common::OutSaveFile *out);
+
 	//  Return an integer representing the type of this sensor
 	int16 getType(void);
 


Commit: 52dce2abe43411d3b4c2d0f5f268959711613162
    https://github.com/scummvm/scummvm/commit/52dce2abe43411d3b4c2d0f5f268959711613162
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement TempActorCount save/loading

Changed paths:
    engines/saga2/loadsave.cpp
    engines/saga2/objects.cpp
    engines/saga2/objects.h


diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index 4f927211a4..b1d2b8a6c4 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -164,9 +164,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveActiveRegions(out);
 	saveTimers(out);
 	saveSensors(out);
+	saveTempActorCount(out);
 
 #if 0
-	saveTempActorCount(saveGame);
 	saveMissions(saveGame);
 	saveFactionTallies(saveGame);
 	saveTileModeState(saveGame);
@@ -367,12 +367,12 @@ void loadSavedGameState(int16 saveNo) {
 			} else
 				error("Sensors loaded prematurely");
 			break;
-#if 0
 
 		case MKTAG('A', 'C', 'N', 'T'):
-			loadTempActorCount(saveGame);
+			loadTempActorCount(in, chunkSize);
 			loadFlags |= loadTempActorCountFlag;
 			break;
+#if 0
 
 		case MKTAG('M', 'I', 'S', 'S'):
 			loadMissions(saveGame);
diff --git a/engines/saga2/objects.cpp b/engines/saga2/objects.cpp
index b727bccb64..32690d693e 100644
--- a/engines/saga2/objects.cpp
+++ b/engines/saga2/objects.cpp
@@ -2802,6 +2802,16 @@ void saveTempActorCount(SaveFileConstructor &saveGame) {
 	    actorProtoCount * sizeof(uint16));
 }
 
+void saveTempActorCount(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving TempActorCount");
+
+	out->write("ACNT", 4);
+	out->writeUint32LE(actorProtoCount * sizeof(uint16));
+
+	for (int i = 0; i < actorProtoCount; ++i)
+		out->writeUint16LE(tempActorCount[i]);
+}
+
 //-------------------------------------------------------------------
 //	Load the array of temp actor counts
 
@@ -2810,6 +2820,16 @@ void loadTempActorCount(SaveFileReader &saveGame) {
 	saveGame.read(tempActorCount, saveGame.getChunkSize());
 }
 
+void loadTempActorCount(Common::InSaveFile *in, int32 chunkSize) {
+	debugC(2, kDebugSaveload, "Loading TempActorCount");
+
+	int count = chunkSize / sizeof(uint16);
+	tempActorCount = new uint16[count];
+
+	for (int i = 0; i < count; ++i)
+		tempActorCount[i] = in->readUint16LE();
+}
+
 //-------------------------------------------------------------------
 //	Cleanup the array to temp actor counts
 
diff --git a/engines/saga2/objects.h b/engines/saga2/objects.h
index 0e36c3de87..7717be45a1 100644
--- a/engines/saga2/objects.h
+++ b/engines/saga2/objects.h
@@ -1409,9 +1409,11 @@ void initTempActorCount(void);
 
 //  Save the array of temp actor counts
 void saveTempActorCount(SaveFileConstructor &saveGame);
+void saveTempActorCount(Common::OutSaveFile *out);
 
 //  Load the array of temp actor counts
 void loadTempActorCount(SaveFileReader &saveGame);
+void loadTempActorCount(Common::InSaveFile *in, int32 chunkSize);
 
 //  Cleanup the array to temp actor counts
 void cleanupTempActorCount(void);


Commit: 09a416c4ff3d0936cf2b3c5d01f61291427c18ec
    https://github.com/scummvm/scummvm/commit/09a416c4ff3d0936cf2b3c5d01f61291427c18ec
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement Mission save/loading

Changed paths:
    engines/saga2/loadsave.cpp
    engines/saga2/mission.cpp
    engines/saga2/mission.h


diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index b1d2b8a6c4..4ec6aae0d5 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -165,9 +165,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveTimers(out);
 	saveSensors(out);
 	saveTempActorCount(out);
+	saveMissions(out);
 
 #if 0
-	saveMissions(saveGame);
 	saveFactionTallies(saveGame);
 	saveTileModeState(saveGame);
 	saveSpellState(saveGame);
@@ -372,12 +372,12 @@ void loadSavedGameState(int16 saveNo) {
 			loadTempActorCount(in, chunkSize);
 			loadFlags |= loadTempActorCountFlag;
 			break;
-#if 0
 
 		case MKTAG('M', 'I', 'S', 'S'):
-			loadMissions(saveGame);
+			loadMissions(in);
 			loadFlags |= loadMissionsFlag;
 			break;
+#if 0
 
 		case MKTAG('F', 'A', 'C', 'T'):
 			loadFactionTallies(saveGame);
diff --git a/engines/saga2/mission.cpp b/engines/saga2/mission.cpp
index 5b34e0cc39..9de0973759 100644
--- a/engines/saga2/mission.cpp
+++ b/engines/saga2/mission.cpp
@@ -162,6 +162,79 @@ bool ActiveMission::removeKnowledgeID(ObjectID actor, uint16 knowledgeID) {
 //-----------------------------------------------------------------------
 //	Add record of knowledge creation to mission
 
+void ActiveMission::read(Common::InSaveFile *in) {
+	_data.missionID = in->readUint16LE();
+	_data.generatorID = in->readUint16LE();
+	_data.missionScript = in->readUint16LE();
+	_data.missionFlags = in->readUint16LE();
+
+	debugC(4, kDebugSaveload, "... missionID = %d", _data.missionID);
+	debugC(4, kDebugSaveload, "... generatorID = %d", _data.generatorID);
+	debugC(4, kDebugSaveload, "... missionScript = %d", _data.missionScript);
+	debugC(4, kDebugSaveload, "... missionFlags = %d", _data.missionFlags);
+	
+	for (int i = 0; i < ARRAYSIZE(_data.missionVars); ++i) {
+		_data.missionVars[i] = in->readByte();
+		debugC(5, kDebugSaveload, "... missionVars[%d] = %d", i, _data.missionVars[i]);
+	}
+
+	for (int i = 0; i < ARRAYSIZE(_data.missionObjectList); ++i) {
+		_data.missionObjectList[i] = in->readUint16LE();
+		debugC(5, kDebugSaveload, "... missionObjectList[%d] = %d", i, _data.missionObjectList[i]);
+	}
+	
+	for (int i = 0; i < ARRAYSIZE(_data.missionKnowledgeList); ++i) {
+		_data.missionKnowledgeList[i].id = in->readUint16LE();
+
+		_data.missionKnowledgeList[i].kID = in->readUint16LE();
+
+		debugC(5, kDebugSaveload, "... missionKnowledgeList[%d].id = %d", i, _data.missionKnowledgeList[i].id);
+		debugC(5, kDebugSaveload, "... missionKnowledgeList[%d].kID = %d", i, _data.missionKnowledgeList[i].kID);
+	}
+
+	_data.numObjectIDs = in->readUint16LE();
+	_data.numKnowledgeIDs = in->readUint16LE();
+
+	debugC(4, kDebugSaveload, "... numObjectIDs = %d", _data.numObjectIDs);
+	debugC(4, kDebugSaveload, "... numKnowledgeIDs = %d", _data.numKnowledgeIDs);
+}
+
+void ActiveMission::write(Common::OutSaveFile *out) {
+	out->writeUint16LE(_data.missionID);
+	out->writeUint16LE(_data.generatorID);
+	out->writeUint16LE(_data.missionScript);
+	out->writeUint16LE(_data.missionFlags);
+
+	debugC(4, kDebugSaveload, "... missionID = %d", _data.missionID);
+	debugC(4, kDebugSaveload, "... generatorID = %d", _data.generatorID);
+	debugC(4, kDebugSaveload, "... missionScript = %d", _data.missionScript);
+	debugC(4, kDebugSaveload, "... missionFlags = %d", _data.missionFlags);
+	
+	for (int i = 0; i < ARRAYSIZE(_data.missionVars); ++i) {
+		out->writeByte(_data.missionVars[i]);
+		debugC(5, kDebugSaveload, "... missionVars[%d] = %d", i, _data.missionVars[i]);
+	}
+
+	for (int i = 0; i < ARRAYSIZE(_data.missionObjectList); ++i) {
+		out->writeUint16LE(_data.missionObjectList[i]);
+		debugC(5, kDebugSaveload, "... missionObjectList[%d] = %d", i, _data.missionObjectList[i]);
+	}
+	
+	for (int i = 0; i < ARRAYSIZE(_data.missionKnowledgeList); ++i) {
+		out->writeUint16LE(_data.missionKnowledgeList[i].id);
+		out->writeUint16LE(_data.missionKnowledgeList[i].kID);
+
+		debugC(5, kDebugSaveload, "... missionKnowledgeList[%d].id = %d", i, _data.missionKnowledgeList[i].id);
+		debugC(5, kDebugSaveload, "... missionKnowledgeList[%d].kID = %d", i, _data.missionKnowledgeList[i].kID);
+	}
+
+	out->writeUint16LE(_data.numObjectIDs);
+	out->writeUint16LE(_data.numKnowledgeIDs);
+
+	debugC(4, kDebugSaveload, "... numObjectIDs = %d", _data.numObjectIDs);
+	debugC(4, kDebugSaveload, "... numKnowledgeIDs = %d", _data.numKnowledgeIDs);
+}
+
 void ActiveMission::cleanup(void) {
 	int             i;
 
@@ -205,6 +278,18 @@ void saveMissions(SaveFileConstructor &saveGame) {
 	    sizeof(activeMissions));
 }
 
+void saveMissions(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving Missions");
+
+	out->write("MISS", 4);
+	out->writeUint32LE(ActiveMission::kActiveMissionSize);
+
+	for (int i = 0; i < ARRAYSIZE(activeMissions); ++i) {
+		debugC(3, kDebugSaveload, "Saving Mission %d", i);
+		activeMissions[i].write(out);
+	}
+}
+
 //-----------------------------------------------------------------------
 //	Restore the active missions
 
@@ -212,4 +297,13 @@ void loadMissions(SaveFileReader &saveGame) {
 	saveGame.read(&activeMissions, sizeof(activeMissions));
 }
 
+void loadMissions(Common::InSaveFile *in) {
+	debugC(2, kDebugSaveload, "Loading Missions");
+
+	for (int i = 0; i < ARRAYSIZE(activeMissions); ++i) {
+		activeMissions[i].read(in);
+		debugC(3, kDebugSaveload, "Loading Mission %d", i);
+	}
+}
+
 } // end if namespace Saga2
diff --git a/engines/saga2/mission.h b/engines/saga2/mission.h
index 67bbb55e8c..a906acbe6f 100644
--- a/engines/saga2/mission.h
+++ b/engines/saga2/mission.h
@@ -76,6 +76,10 @@ class ActiveMission {
 
 public:
 
+	enum {
+		kActiveMissionSize = 236
+	};
+
 	ActiveMissionData _data;
 
 public:
@@ -83,6 +87,9 @@ public:
 	static int  findMission(ObjectID genID);
 	static ActiveMission *missionAddress(int index);
 
+	void read(Common::InSaveFile *in);
+	void write(Common::OutSaveFile *out);
+
 	void cleanup(void);
 
 	bool spaceForObject(void) {
@@ -115,9 +122,11 @@ void initMissions(void);
 
 //  Save the active missions
 void saveMissions(SaveFileConstructor &saveGame);
+void saveMissions(Common::OutSaveFile *out);
 
 //  Restore the active missions
 void loadMissions(SaveFileReader &saveGame);
+void loadMissions(Common::InSaveFile *in);
 
 //  Cleanup the active mission list
 inline void cleanupMissions(void) { /* do nothing */ }


Commit: 5cc7b8803c925e7449fe02c503f8bd14f4455d74
    https://github.com/scummvm/scummvm/commit/5cc7b8803c925e7449fe02c503f8bd14f4455d74
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement FactionTallies save/loading

Changed paths:
    engines/saga2/actor.cpp
    engines/saga2/actor.h
    engines/saga2/loadsave.cpp


diff --git a/engines/saga2/actor.cpp b/engines/saga2/actor.cpp
index 417bd58447..8940261f00 100644
--- a/engines/saga2/actor.cpp
+++ b/engines/saga2/actor.cpp
@@ -3884,6 +3884,18 @@ void saveFactionTallies(SaveFileConstructor &saveGame) {
 	    sizeof(factionTable));
 }
 
+void saveFactionTallies(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving Faction Tallies");
+
+	out->write("FACT", 4);
+	out->writeUint32LE(maxFactions * factionNumColumns * sizeof(int16));
+
+	for (int i = 0; i < maxFactions; ++i) {
+		for (int j = 0; j < factionNumColumns; ++j)
+			out->writeSint16LE(factionTable[i][j]);
+	}
+}
+
 //-------------------------------------------------------------------
 //	Load the faction tallies from a save file
 
@@ -3891,4 +3903,13 @@ void loadFactionTallies(SaveFileReader &saveGame) {
 	saveGame.read(&factionTable, sizeof(factionTable));
 }
 
+void loadFactionTallies(Common::InSaveFile *in) {
+	debugC(2, kDebugSaveload, "Loading Faction Tallies");
+
+	for (int i = 0; i < maxFactions; ++i) {
+		for (int j = 0; j < factionNumColumns; ++j)
+			factionTable[i][j] = in->readSint16LE();
+	}
+}
+
 }
diff --git a/engines/saga2/actor.h b/engines/saga2/actor.h
index b5c20483e7..b1a19f1a39 100644
--- a/engines/saga2/actor.h
+++ b/engines/saga2/actor.h
@@ -1125,9 +1125,11 @@ void initFactionTallies(void);
 
 //  Save the faction tallies to a save file
 void saveFactionTallies(SaveFileConstructor &saveGame);
+void saveFactionTallies(Common::OutSaveFile *out);
 
 //  Load the faction tallies from a save file
 void loadFactionTallies(SaveFileReader &saveGame);
+void loadFactionTallies(Common::InSaveFile *in);
 
 //  Cleanup the faction tally table
 inline void cleanupFactionTallies(void) { /* Nothing to do */ }
diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index 4ec6aae0d5..9b99eaeff6 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -166,9 +166,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveSensors(out);
 	saveTempActorCount(out);
 	saveMissions(out);
+	saveFactionTallies(out);
 
 #if 0
-	saveFactionTallies(saveGame);
 	saveTileModeState(saveGame);
 	saveSpellState(saveGame);
 	saveAutoMap(saveGame);
@@ -377,12 +377,12 @@ void loadSavedGameState(int16 saveNo) {
 			loadMissions(in);
 			loadFlags |= loadMissionsFlag;
 			break;
-#if 0
 
 		case MKTAG('F', 'A', 'C', 'T'):
-			loadFactionTallies(saveGame);
+			loadFactionTallies(in);
 			loadFlags |= loadFactionTalliesFlag;
 			break;
+#if 0
 
 		case MKTAG('T', 'M', 'S', 'T'):
 			if (loadFlags & loadActorsFlag) {


Commit: cbf117755078b6bf2512e2954e18213762e0a367
    https://github.com/scummvm/scummvm/commit/cbf117755078b6bf2512e2954e18213762e0a367
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement TileModeState save/loading

Changed paths:
    engines/saga2/calender.cpp
    engines/saga2/calender.h
    engines/saga2/loadsave.cpp
    engines/saga2/tilemode.cpp
    engines/saga2/tilemode.h


diff --git a/engines/saga2/calender.cpp b/engines/saga2/calender.cpp
index 7c5a0d944b..c4df357be8 100644
--- a/engines/saga2/calender.cpp
+++ b/engines/saga2/calender.cpp
@@ -52,6 +52,42 @@ const uint16 GAME_START_HOUR = 5;
    FrameAlarm member functions
  * ===================================================================== */
 
+void CalenderTime::read(Common::InSaveFile *in) {
+	years = in->readUint16LE();
+	weeks = in->readUint16LE();
+	days = in->readUint16LE();
+	dayInYear = in->readUint16LE();
+	dayInWeek = in->readUint16LE();
+	hour = in->readUint16LE();
+	frameInHour = in->readUint16LE();
+
+	debugC(3, kDebugSaveload, "... years = %d", years);
+	debugC(3, kDebugSaveload, "... weeks = %d", weeks);
+	debugC(3, kDebugSaveload, "... days = %d", days);
+	debugC(3, kDebugSaveload, "... dayInYear = %d", dayInYear);
+	debugC(3, kDebugSaveload, "... dayInWeek = %d", dayInWeek);
+	debugC(3, kDebugSaveload, "... hour = %d", hour);
+	debugC(3, kDebugSaveload, "... frameInHour = %d", frameInHour);
+}
+
+void CalenderTime::write(Common::OutSaveFile *out) {
+	out->writeUint16LE(years);
+	out->writeUint16LE(weeks);
+	out->writeUint16LE(days);
+	out->writeUint16LE(dayInYear);
+	out->writeUint16LE(dayInWeek);
+	out->writeUint16LE(hour);
+	out->writeUint16LE(frameInHour);
+
+	debugC(3, kDebugSaveload, "... years = %d", years);
+	debugC(3, kDebugSaveload, "... weeks = %d", weeks);
+	debugC(3, kDebugSaveload, "... days = %d", days);
+	debugC(3, kDebugSaveload, "... dayInYear = %d", dayInYear);
+	debugC(3, kDebugSaveload, "... dayInWeek = %d", dayInWeek);
+	debugC(3, kDebugSaveload, "... hour = %d", hour);
+	debugC(3, kDebugSaveload, "... frameInHour = %d", frameInHour);
+}
+
 void CalenderTime::update(void) {
 	const char *text = NULL;
 
@@ -250,22 +286,10 @@ void saveCalender(Common::OutSaveFile *out) {
 	out->writeUint32LE(sizeof(calenderPaused) + sizeof(calender));
 
 	out->writeByte(calenderPaused);
-	out->writeUint16LE(calender.years);
-	out->writeUint16LE(calender.weeks);
-	out->writeUint16LE(calender.days);
-	out->writeUint16LE(calender.dayInYear);
-	out->writeUint16LE(calender.dayInWeek);
-	out->writeUint16LE(calender.hour);
-	out->writeUint16LE(calender.frameInHour);
 
 	debugC(3, kDebugSaveload, "... calenderPaused = %d", calenderPaused);
-	debugC(3, kDebugSaveload, "... calender.years = %d", calender.years);
-	debugC(3, kDebugSaveload, "... calender.weeks = %d", calender.weeks);
-	debugC(3, kDebugSaveload, "... calender.days = %d", calender.days);
-	debugC(3, kDebugSaveload, "... calender.dayInYear = %d", calender.dayInYear);
-	debugC(3, kDebugSaveload, "... calender.dayInWeek = %d", calender.dayInWeek);
-	debugC(3, kDebugSaveload, "... calender.hour = %d", calender.hour);
-	debugC(3, kDebugSaveload, "... calender.frameInHour = %d", calender.frameInHour);
+
+	calender.write(out);
 }
 
 //-----------------------------------------------------------------------
@@ -283,22 +307,10 @@ void loadCalender(Common::InSaveFile *in) {
 	debugC(2, kDebugSaveload, "Loading calender");
 
 	calenderPaused = in->readByte();
-	calender.years = in->readUint16LE();
-	calender.weeks = in->readUint16LE();
-	calender.days = in->readUint16LE();
-	calender.dayInYear = in->readUint16LE();
-	calender.dayInWeek = in->readUint16LE();
-	calender.hour = in->readUint16LE();
-	calender.frameInHour = in->readUint16LE();
 
 	debugC(3, kDebugSaveload, "... calenderPaused = %d", calenderPaused);
-	debugC(3, kDebugSaveload, "... calender.years = %d", calender.years);
-	debugC(3, kDebugSaveload, "... calender.weeks = %d", calender.weeks);
-	debugC(3, kDebugSaveload, "... calender.days = %d", calender.days);
-	debugC(3, kDebugSaveload, "... calender.dayInYear = %d", calender.dayInYear);
-	debugC(3, kDebugSaveload, "... calender.dayInWeek = %d", calender.dayInWeek);
-	debugC(3, kDebugSaveload, "... calender.hour = %d", calender.hour);
-	debugC(3, kDebugSaveload, "... calender.frameInHour = %d", calender.frameInHour);
+
+	calender.read(in);
 }
 
 CalenderTime    calender;
diff --git a/engines/saga2/calender.h b/engines/saga2/calender.h
index 46567ce2a8..3b83d4c40a 100644
--- a/engines/saga2/calender.h
+++ b/engines/saga2/calender.h
@@ -61,6 +61,9 @@ public:
 	            hour,
 	            frameInHour;
 
+	void read(Common::InSaveFile *in);
+	void write(Common::OutSaveFile *out);
+
 	void update(void);
 	int lightLevel(int maxLevel);
 
diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index 9b99eaeff6..12ae153e9b 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -167,9 +167,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveTempActorCount(out);
 	saveMissions(out);
 	saveFactionTallies(out);
+	saveTileModeState(out);
 
 #if 0
-	saveTileModeState(saveGame);
 	saveSpellState(saveGame);
 	saveAutoMap(saveGame);
 	saveUIState(saveGame);
@@ -382,15 +382,15 @@ void loadSavedGameState(int16 saveNo) {
 			loadFactionTallies(in);
 			loadFlags |= loadFactionTalliesFlag;
 			break;
-#if 0
 
 		case MKTAG('T', 'M', 'S', 'T'):
 			if (loadFlags & loadActorsFlag) {
-				loadTileModeState(saveGame);
+				loadTileModeState(in);
 				loadFlags |= loadTileModeStateFlag;
 			} else
 				error("TileMode state loaded prematurely");
 			break;
+#if 0
 
 		case MKTAG('S', 'P', 'E', 'L'):
 			loadSpellState(saveGame);
diff --git a/engines/saga2/tilemode.cpp b/engines/saga2/tilemode.cpp
index eccb7b39a1..a529c66806 100644
--- a/engines/saga2/tilemode.cpp
+++ b/engines/saga2/tilemode.cpp
@@ -637,10 +637,41 @@ void saveTileModeState(SaveFileConstructor &saveGame) {
 	}
 }
 
+void saveTileModeState(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving TileModeState");
+
+	int32 size = 0;
+
+	assert(uiKeysEnabled);
+
+	//  Compute the number of bytes needed
+	size += sizeof(aggressiveActFlag)
+	        +   sizeof(inCombat)
+	        +   sizeof(combatPaused);
+	if (aggressiveActFlag)
+		size += sizeof(timeOfLastAggressiveAct);
+
+	out->write("TMST", 4);
+	out->writeUint32LE(size);
+
+	out->writeByte(aggressiveActFlag);
+	out->writeByte(inCombat);
+	out->writeByte(combatPaused);
+
+	debugC(3, kDebugSaveload, "... aggressiveActFlag = %d", aggressiveActFlag);
+	debugC(3, kDebugSaveload, "... inCombat = %d", inCombat);
+	debugC(3, kDebugSaveload, "... combatPaused = %d", combatPaused);
+
+	if (aggressiveActFlag)
+		timeOfLastAggressiveAct.write(out);
+}
+
 //-----------------------------------------------------------------------
 //	Load the tile mode state from a save file
 
 void loadTileModeState(SaveFileReader &saveGame) {
+	debugC(2, kDebugSaveload, "Loading TileModeState");
+
 	assert(uiKeysEnabled);
 
 	//  Simply read in the data
@@ -655,6 +686,24 @@ void loadTileModeState(SaveFileReader &saveGame) {
 	tileLockFlag = false;
 }
 
+void loadTileModeState(Common::InSaveFile *in) {
+	assert(uiKeysEnabled);
+
+	//  Simply read in the data
+	aggressiveActFlag = in->readByte();
+	inCombat = in->readByte();
+	combatPaused = in->readByte();
+
+	debugC(3, kDebugSaveload, "... aggressiveActFlag = %d", aggressiveActFlag);
+	debugC(3, kDebugSaveload, "... inCombat = %d", inCombat);
+	debugC(3, kDebugSaveload, "... combatPaused = %d", combatPaused);
+
+	if (aggressiveActFlag)
+		timeOfLastAggressiveAct.read(in);
+
+	tileLockFlag = false;
+}
+
 /* ===================================================================== *
    TileMode management functions
  * ===================================================================== */
diff --git a/engines/saga2/tilemode.h b/engines/saga2/tilemode.h
index 577573951c..f1f4504eb6 100644
--- a/engines/saga2/tilemode.h
+++ b/engines/saga2/tilemode.h
@@ -50,9 +50,11 @@ void initTileModeState(void);
 
 //  Save the tile mode state to a save file
 void saveTileModeState(SaveFileConstructor &saveGame);
+void saveTileModeState(Common::OutSaveFile *out);
 
 //  Load the tile mode state from a save file
 void loadTileModeState(SaveFileReader &saveGame);
+void loadTileModeState(Common::InSaveFile *in);
 
 //  Cleanup the tile mode state
 inline void cleanupTileModeState(void) { /* do nothing */ }


Commit: 1bcdc8eb36c9061243ecacdd1bb89eae8064dd6d
    https://github.com/scummvm/scummvm/commit/1bcdc8eb36c9061243ecacdd1bb89eae8064dd6d
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Fix alloc-dealloc mismatch

Changed paths:
    engines/saga2/music.cpp


diff --git a/engines/saga2/music.cpp b/engines/saga2/music.cpp
index 38a90ec4ca..4a12fbf864 100644
--- a/engines/saga2/music.cpp
+++ b/engines/saga2/music.cpp
@@ -113,7 +113,7 @@ void Music::play(uint32 resourceId, MusicFlags flags) {
 	if (_parser)
 		_parser->stopPlaying();
 
-	delete _currentMusicBuffer;
+	free(_currentMusicBuffer);
 
 	_currentMusicBuffer = (byte *)LoadResource(_musicContext, resourceId, "music data");
 	uint32 size = _musicContext->size(resourceId);


Commit: a6a98833f7bdf9cc43914b1a13d38b8897fcd41f
    https://github.com/scummvm/scummvm/commit/a6a98833f7bdf9cc43914b1a13d38b8897fcd41f
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Add Sensor debug output

Changed paths:
    engines/saga2/detection.cpp
    engines/saga2/saga2.h
    engines/saga2/sensor.h


diff --git a/engines/saga2/detection.cpp b/engines/saga2/detection.cpp
index 5e5c55cfee..bceb0c2553 100644
--- a/engines/saga2/detection.cpp
+++ b/engines/saga2/detection.cpp
@@ -40,6 +40,7 @@ static const DebugChannelDef debugFlagList[] = {
 	{Saga2::kDebugTasks,     "tasks",     "Debug the tasks"},
 	{Saga2::kDebugSound,     "sound",     "Debug the sound"},
 	{Saga2::kDebugSaveload,  "saveload",  "Debug the game saving/loading"},
+	{Saga2::kDebugSensors,   "sensors",   "Debug the sensors"},
 	DEBUG_CHANNEL_END
 };
 
diff --git a/engines/saga2/saga2.h b/engines/saga2/saga2.h
index fa2618ed5f..b33c331a0c 100644
--- a/engines/saga2/saga2.h
+++ b/engines/saga2/saga2.h
@@ -68,7 +68,8 @@ enum {
 	kDebugPath      = 1 << 9,
 	kDebugTasks     = 1 << 10,
 	kDebugSound     = 1 << 11,
-	kDebugSaveload  = 1 << 12
+	kDebugSaveload  = 1 << 12,
+	kDebugSensors   = 1 << 13
 };
 
 #define TICKSPERSECOND (728L/10L)
diff --git a/engines/saga2/sensor.h b/engines/saga2/sensor.h
index f1455e3c3d..3f704c9bb7 100644
--- a/engines/saga2/sensor.h
+++ b/engines/saga2/sensor.h
@@ -119,10 +119,14 @@ public:
 public:
 	//  Constructor -- initial construction
 	SensorList(GameObject *o) : obj(o) {
+		debugC(1, kDebugSensors, "Adding SensorList %p to %p (%s)",
+		       (void *)this, (void *)o, o->objName());
 		newSensorList(this);
 	}
 
 	~SensorList() {
+		debugC(1, kDebugSensors, "Deleting SensorList %p of %p (%s)",
+		       (void *)this, (void *)obj, obj->objName());
 		deleteSensorList(this);
 	}
 
@@ -162,6 +166,8 @@ public:
 public:
 	//  Constructor -- initial construction
 	Sensor(GameObject *o, SensorID sensorID, int16 rng) : obj(o), id(sensorID), range(rng) {
+		debugC(1, kDebugSensors, "Adding Sensor %p to %p (%s)",
+		       (void *)this, (void *)o, o->objName());
 		newSensor(this);
 	}
 
@@ -172,6 +178,8 @@ public:
 
 	//  Virtural destructor
 	virtual ~Sensor(void) {
+		debugC(1, kDebugSensors, "Deleting Sensor %p to %p (%s)",
+		       (void *)this, (void *)obj, obj->objName());
 		deleteSensor(this);
 	}
 


Commit: db9ad228cd90a6a6ad946bcf0f77b34f1cf6cc52
    https://github.com/scummvm/scummvm/commit/db9ad228cd90a6a6ad946bcf0f77b34f1cf6cc52
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement SpellState save/loading

Changed paths:
    engines/saga2/loadsave.cpp
    engines/saga2/magic.h
    engines/saga2/spellio.cpp
    engines/saga2/spellio.h
    engines/saga2/spelshow.h


diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index 12ae153e9b..5a7aa67b09 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -168,9 +168,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveMissions(out);
 	saveFactionTallies(out);
 	saveTileModeState(out);
+	saveSpellState(out);
 
 #if 0
-	saveSpellState(saveGame);
 	saveAutoMap(saveGame);
 	saveUIState(saveGame);
 	savePaletteState(saveGame);
@@ -390,12 +390,12 @@ void loadSavedGameState(int16 saveNo) {
 			} else
 				error("TileMode state loaded prematurely");
 			break;
-#if 0
 
 		case MKTAG('S', 'P', 'E', 'L'):
-			loadSpellState(saveGame);
+			loadSpellState(in);
 			loadFlags |= loadSpellStateFlag;
 			break;
+#if 0
 
 		case MKTAG('A', 'M', 'A', 'P'):
 			if (loadFlags & loadWorldsFlag) {
diff --git a/engines/saga2/magic.h b/engines/saga2/magic.h
index a70cb6d78d..966cef10d4 100644
--- a/engines/saga2/magic.h
+++ b/engines/saga2/magic.h
@@ -104,7 +104,9 @@ bool implementSpell(GameObject *enactor, GameObject *target, SkillProto *spell);
 // spell saving & loading
 void initSpellState(void);
 void saveSpellState(SaveFileConstructor &saveGame);
+void saveSpellState(Common::OutSaveFile *out);
 void loadSpellState(SaveFileReader &saveGame);
+void loadSpellState(Common::InSaveFile *in);
 void cleanupSpellState(void);
 
 } // end of namespace Saga2
diff --git a/engines/saga2/spellio.cpp b/engines/saga2/spellio.cpp
index 37513e988a..39b5eb0afa 100644
--- a/engines/saga2/spellio.cpp
+++ b/engines/saga2/spellio.cpp
@@ -223,6 +223,12 @@ void saveSpellState(SaveFileConstructor &saveGame) {
 	activeSpells.save(saveGame);
 }
 
+void saveSpellState(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving SpellState");
+
+	activeSpells.write(out);
+}
+
 // ------------------------------------------------------------------
 // read serialized active spells
 
@@ -230,6 +236,12 @@ void loadSpellState(SaveFileReader &saveGame) {
 	activeSpells.load(saveGame);
 }
 
+void loadSpellState(Common::InSaveFile *in) {
+	debugC(2, kDebugSaveload, "Loading SpellState");
+
+	activeSpells.read(in);
+}
+
 // ------------------------------------------------------------------
 // cleanup active spells
 
@@ -289,10 +301,57 @@ StorageSpellTarget::StorageSpellTarget() {
 	tag = NoActiveItem;
 }
 
+void StorageSpellTarget::read(Common::InSaveFile *in) {
+	ActiveItemID tagID;
+
+	type = in->readSint16LE();
+	loc.load(in);
+	obj = in->readUint16LE();
+	tagID = in->readSint16LE();
+	tag = ActiveItemID(tagID);
+}
+
+void StorageSpellTarget::write(Common::OutSaveFile *out) {
+	out->writeSint16LE(type);
+	loc.write(out);
+	out->writeUint16LE(obj);
+	out->writeSint16LE(tag.val);
+}
+
 StorageSpellInstance::StorageSpellInstance() : implementAge(0), effect(0), dProto(spellNone), caster(0),
 	world(0), age(0), spell(spellNone), maxAge(0), effSeq(0), eListSize(0) {
 }
 
+void StorageSpellInstance::read(Common::InSaveFile *in) {
+	implementAge = in->readSint32LE();
+	effect = in->readUint16LE();
+	warning("StorageSpellInstance::read: Check SpellID size");
+	dProto = (SpellID)in->readUint32LE();
+	caster = in->readUint16LE();
+	target.read(in);
+	world = in->readUint16LE();
+	age = in->readSint32LE();
+	spell = (SpellID)in->readUint32LE();
+	maxAge = in->readSint32LE();
+	effSeq = in->readSint16LE();
+	eListSize = in->readSint16LE();
+}
+
+void StorageSpellInstance::write(Common::OutSaveFile *out) {
+	out->writeSint32LE(implementAge);
+	out->writeUint16LE(effect);
+	warning("StorageSpellInstance::write: Check SpellID size");
+	out->writeUint32LE(dProto);
+	out->writeUint16LE(caster);
+	target.write(out);
+	out->writeUint16LE(world);
+	out->writeSint32LE(age);
+	out->writeUint32LE(spell);
+	out->writeSint32LE(maxAge);
+	out->writeSint16LE(effSeq);
+	out->writeSint16LE(eListSize);
+}
+
 SpellTarget::SpellTarget(StorageSpellTarget &sst) {
 	type = (SpellTarget::spellTargetType) sst.type;
 	loc = sst.loc;
@@ -350,6 +409,26 @@ void SpellDisplayList::save(SaveFileConstructor &saveGame) {
 	}
 }
 
+void SpellDisplayList::write(Common::OutSaveFile *out) {
+	size_t chunkSize = saveSize();
+
+	out->write("SPEL", 4);
+	out->writeUint32LE(chunkSize);
+
+	out->writeUint16LE(count);
+
+	debugC(3, kDebugSaveload, "... count = %d", count);
+
+	if (count) {
+		for (int i = 0; i < count; i++) {
+			debugC(3, kDebugSaveload, "Saving Spell Instance %d", i);
+			StorageSpellInstance ssi = StorageSpellInstance(*spells[i]);
+			ssi.write(out);
+			spells[i]->writeEffect(out);
+		}
+	}
+}
+
 void SpellDisplayList::load(SaveFileReader &saveGame) {
 	uint16 tCount;
 
@@ -368,6 +447,28 @@ void SpellDisplayList::load(SaveFileReader &saveGame) {
 	assert(tCount == count);
 }
 
+void SpellDisplayList::read(Common::InSaveFile *in) {
+	uint16 tCount;
+
+	tCount = in->readUint16LE();
+
+	debugC(3, kDebugSaveload, "... count = %d", tCount);
+
+	assert(tCount < maxCount);
+	if (tCount) {
+		for (int i = 0; i < tCount; i++) {
+			debugC(3, kDebugSaveload, "Loading Spell Instance %d", i);
+			SpellInstance *si;
+			StorageSpellInstance ssi;
+			ssi.read(in);
+			si = new SpellInstance(ssi);
+			add(si);
+			si->readEffect(in, ssi.eListSize);
+		}
+	}
+	assert(tCount == count);
+}
+
 void SpellDisplayList::wipe(void) {
 	for (int i = 0; i < maxCount; i++)
 		if (spells[i]) {
@@ -397,6 +498,14 @@ void SpellInstance::saveEffect(SaveFileConstructor &saveGame) {
 		}
 }
 
+void SpellInstance::writeEffect(Common::OutSaveFile *out) {
+	if (eList.count > 0 && !(maxAge > 0 && (age + 1) > maxAge))
+		for (int32 i = 0; i < eList.count; i++) {
+			StorageEffectron se = StorageEffectron(*eList.displayList[i].efx);
+			se.write(out);
+		}
+}
+
 void SpellInstance::loadEffect(SaveFileReader &saveGame, uint16 eListSize) {
 	assert(eListSize == effect->nodeCount);
 	eList.count = effect->nodeCount; //sdp->effCount;
@@ -409,6 +518,18 @@ void SpellInstance::loadEffect(SaveFileReader &saveGame, uint16 eListSize) {
 		}
 }
 
+void SpellInstance::readEffect(Common::InSaveFile *in, uint16 eListSize) {
+	assert(eListSize == effect->nodeCount);
+	eList.count = effect->nodeCount; //sdp->effCount;
+	if (eList.count)
+		for (int32 i = 0; i < eList.count; i++) {
+			StorageEffectron se;
+			se.read(in);
+			Effectron *e = new Effectron(se, this);
+			eList.displayList[i].efx = e;
+		}
+}
+
 StorageEffectron::StorageEffectron() {
 	flags = 0;
 	size = Extent16(0, 0);
@@ -449,6 +570,45 @@ StorageEffectron::StorageEffectron(Effectron &e) {
 	age =           e.age;
 }
 
+void StorageEffectron::read(Common::InSaveFile *in) {
+	flags = in->readUint32LE();
+	size.load(in);
+	hitBox.read(in);
+	partno = in->readSint16LE();
+	screenCoords.load(in);
+	start.load(in);
+	finish.load(in);
+	current.load(in);
+	velocity.load(in);
+	acceleration.load(in);
+	totalSteps = in->readUint16LE();
+	stepNo = in->readUint16LE();
+	hgt = in->readSint16LE();
+	brd = in->readSint16LE();
+	pos = in->readSint32LE();
+	spr = in->readSint32LE();
+	age = in->readSint32LE();
+}
+
+void StorageEffectron::write(Common::OutSaveFile *out) {
+	out->writeUint32LE(flags);
+	size.write(out);
+	hitBox.write(out);
+	out->writeSint16LE(partno);
+	screenCoords.write(out);
+	start.write(out);
+	finish.write(out);
+	current.write(out);
+	velocity.write(out);
+	acceleration.write(out);
+	out->writeUint16LE(totalSteps);
+	out->writeUint16LE(stepNo);
+	out->writeSint16LE(hgt);
+	out->writeSint16LE(brd);
+	out->writeSint32LE(pos);
+	out->writeSint32LE(spr);
+	out->writeSint32LE(age);
+}
 
 Effectron::Effectron(StorageEffectron &se, SpellInstance *si) {
 	flags =         se.flags;
diff --git a/engines/saga2/spellio.h b/engines/saga2/spellio.h
index a5f2849fa4..5d9c7bca4e 100644
--- a/engines/saga2/spellio.h
+++ b/engines/saga2/spellio.h
@@ -122,6 +122,9 @@ struct StorageSpellTarget {
 
 	StorageSpellTarget();
 	StorageSpellTarget(SpellTarget &st);
+
+	void read(Common::InSaveFile *in);
+	void write(Common::OutSaveFile *out);
 };
 
 //-------------------------------------------------------------------
@@ -143,6 +146,9 @@ struct StorageSpellInstance {
 
 	StorageSpellInstance();
 	StorageSpellInstance(SpellInstance &si);
+
+	void read(Common::InSaveFile *in);
+	void write(Common::OutSaveFile *out);
 };
 
 //-------------------------------------------------------------------
@@ -173,6 +179,9 @@ struct StorageEffectron {
 
 	StorageEffectron();
 	StorageEffectron(Effectron &e);
+
+	void read(Common::InSaveFile *in);
+	void write(Common::OutSaveFile *out);
 };
 
 } // end of namespace Saga2
diff --git a/engines/saga2/spelshow.h b/engines/saga2/spelshow.h
index 4b43ff51ca..6812bfa9ba 100644
--- a/engines/saga2/spelshow.h
+++ b/engines/saga2/spelshow.h
@@ -316,7 +316,9 @@ public:
 	void init(void);
 	void initEffect(TilePoint);
 	void loadEffect(SaveFileReader &saveGame, uint16 eListSize);
+	void readEffect(Common::InSaveFile *in, uint16 eListSize);
 	void saveEffect(SaveFileConstructor &saveGame);
+	void writeEffect(Common::OutSaveFile *out);
 	void termEffect(void);
 	size_t saveSize(void);
 
@@ -350,7 +352,9 @@ public :
 	void updateStates(int32 deltaTime);
 
 	void save(SaveFileConstructor &saveGame);
+	void write(Common::OutSaveFile *out);
 	void load(SaveFileReader &saveGame);
+	void read(Common::InSaveFile *in);
 	void wipe(void);
 	size_t saveSize(void);
 };


Commit: d2f96b708abcc8fa0e589c74d01eb2f3187ce322
    https://github.com/scummvm/scummvm/commit/d2f96b708abcc8fa0e589c74d01eb2f3187ce322
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement AutoMap save/loading

Changed paths:
    engines/saga2/loadsave.cpp
    engines/saga2/tile.cpp
    engines/saga2/tile.h


diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index 5a7aa67b09..99827f5a11 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -169,9 +169,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveFactionTallies(out);
 	saveTileModeState(out);
 	saveSpellState(out);
+	saveAutoMap(out);
 
 #if 0
-	saveAutoMap(saveGame);
 	saveUIState(saveGame);
 	savePaletteState(saveGame);
 	saveContainerNodes(saveGame);
@@ -395,15 +395,15 @@ void loadSavedGameState(int16 saveNo) {
 			loadSpellState(in);
 			loadFlags |= loadSpellStateFlag;
 			break;
-#if 0
 
 		case MKTAG('A', 'M', 'A', 'P'):
 			if (loadFlags & loadWorldsFlag) {
-				loadAutoMap(saveGame);
+				loadAutoMap(in, chunkSize);
 				loadFlags |= loadAutoMapFlag;
 			} else
 				error("Auto map loaded prematurely");
 			break;
+#if 0
 
 		case MKTAG('U', 'I', 'S', 'T'):
 			if (loadFlags & loadPlayerActorsFlag) {
diff --git a/engines/saga2/tile.cpp b/engines/saga2/tile.cpp
index 10b984857f..0d15b35599 100644
--- a/engines/saga2/tile.cpp
+++ b/engines/saga2/tile.cpp
@@ -1912,9 +1912,74 @@ void saveAutoMap(SaveFileConstructor &saveGame) {
 	free(archiveBuffer);
 }
 
+void saveAutoMap(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving AutoMap");
+
+	int32 totalMapSize = 0,
+	      totalMapIndex = 0;
+
+	uint8 *archiveBuffer;
+	int32 archiveBufSize;
+
+	for (int i = 0; i < worldCount; i++) {
+		MapHeader       *map;
+		int32           mapSize;
+
+		map = mapList[i].map;
+		mapSize = map->size;
+		mapSize *= mapSize;
+
+		totalMapSize += mapSize;
+	}
+
+	//  Compute the number of bytes needed to store the visited bit
+	//  for each map metatile slot
+	archiveBufSize = (totalMapSize + 7) >> 3;
+
+	out->write("AMAP", 4);
+	out->writeUint32LE(archiveBufSize);
+
+	archiveBuffer = (uint8 *)malloc(archiveBufSize);
+	if (archiveBuffer == nullptr)
+		error("Unable to allocate auto map archive buffer");
+
+	for (int i = 0; i < worldCount; i++) {
+		MapHeader *map;
+		int32 mapSize,
+		      mapIndex;
+
+		uint16 *mapData;
+
+		map = mapList[i].map;
+		mapSize = map->size;
+		mapSize *= mapSize;
+		mapData = map->mapData;
+
+		for (mapIndex = 0; mapIndex < mapSize; mapIndex++) {
+			if (mapData[mapIndex] & metaTileVisited) {
+				//  Set the bit in the archive buffer
+				archiveBuffer[totalMapIndex >> 3] |=
+				    (1 << (totalMapIndex & 7));
+			} else {
+				//  Clear the bit in the archive buffer
+				archiveBuffer[totalMapIndex >> 3] &=
+				    ~(1 << (totalMapIndex & 7));
+			}
+
+			totalMapIndex++;
+		}
+	}
+
+	out->write(archiveBuffer, archiveBufSize);
+
+	free(archiveBuffer);
+}
+
 //-----------------------------------------------------------------------
 
 void loadAutoMap(SaveFileReader &saveGame) {
+	debugC(2, kDebugSaveload, "Loading AutoMap");
+
 	int32       totalMapIndex = 0;
 	int16       i;
 
@@ -1958,6 +2023,49 @@ void loadAutoMap(SaveFileReader &saveGame) {
 	free(archiveBuffer);
 }
 
+void loadAutoMap(Common::InSaveFile *in, int32 chunkSize) {
+	int32       totalMapIndex = 0;
+	uint8       *archiveBuffer;
+	int32       archiveBufSize;
+
+	archiveBufSize = chunkSize;
+
+	archiveBuffer = (uint8 *)malloc(archiveBufSize);
+	if (archiveBuffer == nullptr)
+		error("Unable to allocate auto map archive buffer");
+
+	in->read(archiveBuffer, archiveBufSize);
+
+	for (int i = 0; i < worldCount; i++) {
+		MapHeader *map;
+		int32 mapSize,
+		      mapIndex;
+
+		uint16 *mapData;
+
+		map = mapList[i].map;
+		mapSize = map->size;
+		mapSize *= mapSize;
+		mapData = map->mapData;
+
+		for (mapIndex = 0; mapIndex < mapSize; mapIndex++) {
+			assert((totalMapIndex >> 3) < archiveBufSize);
+
+			//  If the bit is set in the archive buffer, set the visited
+			//  bit in the map data
+			if (archiveBuffer[totalMapIndex >> 3]
+			        & (1 << (totalMapIndex & 7)))
+				mapData[mapIndex] |= metaTileVisited;
+			else
+				mapData[mapIndex] &= ~metaTileVisited;
+
+			totalMapIndex++;
+		}
+	}
+
+	free(archiveBuffer);
+}
+
 /* ===================================================================== *
    Platform cache functions
  * ===================================================================== */
diff --git a/engines/saga2/tile.h b/engines/saga2/tile.h
index 93b56c4140..2e8cff1595 100644
--- a/engines/saga2/tile.h
+++ b/engines/saga2/tile.h
@@ -1034,7 +1034,9 @@ void cleanupTileCyclingStates(void);
 
 void initAutoMap(void);
 void saveAutoMap(SaveFileConstructor &saveGame);
+void saveAutoMap(Common::OutSaveFile *out);
 void loadAutoMap(SaveFileReader &saveGame);
+void loadAutoMap(Common::InSaveFile *in, int32 chunkSize);
 inline void cleanupAutoMap(void) { /* nothing to do */ }
 
 //  Determine if a platform is ripped


Commit: 7f359b450f5f1ed9ee73e14a8e8d6a11a9111566
    https://github.com/scummvm/scummvm/commit/7f359b450f5f1ed9ee73e14a8e8d6a11a9111566
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement UIState save/loading

Changed paths:
    engines/saga2/intrface.cpp
    engines/saga2/intrface.h
    engines/saga2/loadsave.cpp


diff --git a/engines/saga2/intrface.cpp b/engines/saga2/intrface.cpp
index 8575c52de4..b04f591278 100644
--- a/engines/saga2/intrface.cpp
+++ b/engines/saga2/intrface.cpp
@@ -2577,6 +2577,10 @@ APPFUNC(cmdManaInd) {
 struct UIStateArchive {
 	bool    indivControlsFlag;
 	uint16  indivBrother;
+
+	enum {
+		kUIStateArchiveSize = 3
+	};
 };
 
 bool isIndivMode(void) {
@@ -2602,6 +2606,19 @@ void saveUIState(SaveFileConstructor &saveGame) {
 	    sizeof(archive));
 }
 
+void saveUIState(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving UIState");
+
+	out->write("UIST", 4);
+	out->writeUint32LE(UIStateArchive::kUIStateArchiveSize);
+
+	out->writeByte(indivControlsFlag);
+	out->writeUint16LE(indivBrother);
+
+	debugC(3, kDebugSaveload, "... indivControlsFlag = %d", indivControlsFlag);
+	debugC(3, kDebugSaveload, "... indivBrother = %d", indivBrother);
+}
+
 void loadUIState(SaveFileReader &saveGame) {
 	UIStateArchive      archive;
 
@@ -2613,6 +2630,18 @@ void loadUIState(SaveFileReader &saveGame) {
 	updateAllUserControls();
 }
 
+void loadUIState(Common::InSaveFile *in) {
+	debugC(2, kDebugSaveload, "Saving UIState");
+
+	indivControlsFlag = in->readByte();
+	indivBrother = in->readUint16LE();
+
+	debugC(3, kDebugSaveload, "... indivControlsFlag = %d", indivControlsFlag);
+	debugC(3, kDebugSaveload, "... indivBrother = %d", indivBrother);
+
+	updateAllUserControls();
+}
+
 void cleanupUIState(void) {
 	if (StatusLine != nullptr)
 		StatusLine->clear();
diff --git a/engines/saga2/intrface.h b/engines/saga2/intrface.h
index 3ac2cf91e7..288ec4490c 100644
--- a/engines/saga2/intrface.h
+++ b/engines/saga2/intrface.h
@@ -90,7 +90,9 @@ void updateIndicators(void);
 
 void initUIState(void);
 void saveUIState(SaveFileConstructor &saveGame);
+void saveUIState(Common::OutSaveFile *out);
 void loadUIState(SaveFileReader &saveGame);
+void loadUIState(Common::InSaveFile *in);
 void cleanupUIState(void);
 
 //  Varargs function to write to the status line.
diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index 99827f5a11..e1b374b7c7 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -170,9 +170,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveTileModeState(out);
 	saveSpellState(out);
 	saveAutoMap(out);
+	saveUIState(out);
 
 #if 0
-	saveUIState(saveGame);
 	savePaletteState(saveGame);
 	saveContainerNodes(saveGame);
 #endif
@@ -403,15 +403,15 @@ void loadSavedGameState(int16 saveNo) {
 			} else
 				error("Auto map loaded prematurely");
 			break;
-#if 0
 
 		case MKTAG('U', 'I', 'S', 'T'):
 			if (loadFlags & loadPlayerActorsFlag) {
-				loadUIState(saveGame);
+				loadUIState(in);
 				loadFlags |= loadUIStateFlag;
 			} else
 				error("UI state loaded prematurely");
 			break;
+#if 0
 
 		case MKTAG('P', 'A', 'L', 'E'):
 			loadPaletteState(saveGame);


Commit: 3fa5f4b67f8cd7dafa31775242442ca69b38672d
    https://github.com/scummvm/scummvm/commit/3fa5f4b67f8cd7dafa31775242442ca69b38672d
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement Palette State save/loading

Changed paths:
    engines/saga2/loadsave.cpp
    engines/saga2/palette.h
    engines/saga2/vpal.cpp
    engines/saga2/vpal.h


diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index e1b374b7c7..ee430d9627 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -171,9 +171,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveSpellState(out);
 	saveAutoMap(out);
 	saveUIState(out);
+	savePaletteState(out);
 
 #if 0
-	savePaletteState(saveGame);
 	saveContainerNodes(saveGame);
 #endif
 
@@ -411,12 +411,12 @@ void loadSavedGameState(int16 saveNo) {
 			} else
 				error("UI state loaded prematurely");
 			break;
-#if 0
 
 		case MKTAG('P', 'A', 'L', 'E'):
-			loadPaletteState(saveGame);
+			loadPaletteState(in);
 			loadFlags |= loadPaletteStateFlag;
 			break;
+#if 0
 
 		case MKTAG('C', 'O', 'N', 'T'):
 			if (loadFlags & loadObjectsFlag) {
diff --git a/engines/saga2/palette.h b/engines/saga2/palette.h
index 327ae20493..b22d2447fe 100644
--- a/engines/saga2/palette.h
+++ b/engines/saga2/palette.h
@@ -77,9 +77,11 @@ void initPaletteState(void);
 //  Save the current state of the current palette and fade up/down in
 //  a save file.
 void savePaletteState(SaveFileConstructor &saveGame);
+void savePaletteState(Common::OutSaveFile *out);
 //  Load and set the current state of the current palette and fade
 //  up/down from a save file.
 void loadPaletteState(SaveFileReader &saveGame);
+void loadPaletteState(Common::InSaveFile *in);
 //  Cleanup the palette
 inline void cleanupPaletteState(void) { /* do nothing */ }
 
diff --git a/engines/saga2/vpal.cpp b/engines/saga2/vpal.cpp
index ca23a3db3c..a7c762f726 100644
--- a/engines/saga2/vpal.cpp
+++ b/engines/saga2/vpal.cpp
@@ -58,6 +58,10 @@ struct PaletteStateArchive {
 	                    destPalette;
 	int32               startTime,
 	                    totalTime;
+
+	enum {
+		kPaletteStateArchiveSize = 2312
+	};
 };
 
 /* ===================================================================== *
@@ -103,6 +107,21 @@ void assertCurrentPalette(void) {
 	}
 }
 
+void gPalette::read(Common::InSaveFile *in) {
+	for (int i = 0; i < 256; ++i) {
+		entry[i].r = in->readByte();
+		entry[i].g = in->readByte();
+		entry[i].b = in->readByte();
+	}
+}
+
+void gPalette::write(Common::OutSaveFile *out) {
+	for (int i = 0; i < 256; ++i) {
+		out->writeByte(entry[i].r);
+		out->writeByte(entry[i].g);
+		out->writeByte(entry[i].b);
+	}
+}
 
 //----------------------------------------------------------------------
 //	Initialize global palette resources
@@ -339,6 +358,22 @@ void savePaletteState(SaveFileConstructor &saveGame) {
 	    sizeof(archive));
 }
 
+void savePaletteState(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Loading Palette States");
+
+	out->write("PALE", 4);
+	out->writeUint32LE(PaletteStateArchive::kPaletteStateArchiveSize);
+
+	currentPalette.write(out);
+	oldPalette.write(out);
+	destPalette.write(out);
+	out->writeSint32LE(startTime);
+	out->writeSint32LE(totalTime);
+
+	debugC(3, kDebugSaveload, "... startTime = %d", startTime);
+	debugC(3, kDebugSaveload, "... totalTime = %d", totalTime);
+}
+
 //----------------------------------------------------------------------
 //	Load and set the current state of the current palette and fade
 //	up/down from a save file.
@@ -357,4 +392,21 @@ void loadPaletteState(SaveFileReader &saveGame) {
 	setCurrentPalette(&tempPalette);
 }
 
+void loadPaletteState(Common::InSaveFile *in) {
+	debugC(2, kDebugSaveload, "Loading Palette States");
+
+	gPalette tempPalette;
+
+	tempPalette.read(in);
+	oldPalette.read(in);
+	destPalette.read(in);
+	startTime = in->readSint32LE();
+	totalTime = in->readSint32LE();
+
+	debugC(3, kDebugSaveload, "... startTime = %d", startTime);
+	debugC(3, kDebugSaveload, "... totalTime = %d", totalTime);
+
+	setCurrentPalette(&tempPalette);
+}
+
 } // end of namespace Saga2
diff --git a/engines/saga2/vpal.h b/engines/saga2/vpal.h
index f61f9d1777..4190074375 100644
--- a/engines/saga2/vpal.h
+++ b/engines/saga2/vpal.h
@@ -43,6 +43,9 @@ struct gPaletteEntry {
 
 struct gPalette {
 	gPaletteEntry   entry[256];
+
+	void read(Common::InSaveFile *in);
+	void write(Common::OutSaveFile *out);
 };
 
 /* ===================================================================== *


Commit: 6d84b504bcd2669a60463b852bcbb7edab523ec7
    https://github.com/scummvm/scummvm/commit/6d84b504bcd2669a60463b852bcbb7edab523ec7
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Fix savePaletteState debug message

Changed paths:
    engines/saga2/vpal.cpp


diff --git a/engines/saga2/vpal.cpp b/engines/saga2/vpal.cpp
index a7c762f726..a14ce6cc23 100644
--- a/engines/saga2/vpal.cpp
+++ b/engines/saga2/vpal.cpp
@@ -359,7 +359,7 @@ void savePaletteState(SaveFileConstructor &saveGame) {
 }
 
 void savePaletteState(Common::OutSaveFile *out) {
-	debugC(2, kDebugSaveload, "Loading Palette States");
+	debugC(2, kDebugSaveload, "Saving Palette States");
 
 	out->write("PALE", 4);
 	out->writeUint32LE(PaletteStateArchive::kPaletteStateArchiveSize);


Commit: 28b91b2eef570ea241c810c4047d567d05fb385c
    https://github.com/scummvm/scummvm/commit/28b91b2eef570ea241c810c4047d567d05fb385c
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-12T13:08:48+09:00

Commit Message:
SAGA2: Implement ContainerNodes save/loading

Changed paths:
    engines/saga2/contain.cpp
    engines/saga2/contain.h
    engines/saga2/loadsave.cpp


diff --git a/engines/saga2/contain.cpp b/engines/saga2/contain.cpp
index 8d43d16879..5a499b0f35 100644
--- a/engines/saga2/contain.cpp
+++ b/engines/saga2/contain.cpp
@@ -1468,6 +1468,47 @@ void *ContainerNode::archive(void *buf) {
 	return &a[1];
 }
 
+void ContainerNode::read(Common::InSaveFile *in) {
+	//  Restore fields
+	object = in->readUint16LE();
+	type = in->readByte();
+	owner = in->readByte();
+	position.read(in);
+	mindType = in->readByte();
+	window = NULL;
+	action = 0;
+
+	bool shown = in->readByte();
+
+	//  If this container was shown, re-show it
+	if (shown)
+		markForShow();
+
+	debugC(4, kDebugSaveload, "... object = %d", object);
+	debugC(4, kDebugSaveload, "... type = %d", type);
+	debugC(4, kDebugSaveload, "... owner = %d", owner);
+	debugC(4, kDebugSaveload, "... position = (%d, %d, %d, %d)", position.x, position.y, position.width, position.height);
+	debugC(4, kDebugSaveload, "... mindType = %d", mindType);
+	debugC(4, kDebugSaveload, "... shown = %d", shown);
+}
+
+void ContainerNode::write(Common::OutSaveFile *out) {
+	//  Store fields
+	out->writeUint16LE(object);
+	out->writeByte(type);
+	out->writeByte(owner);
+	position.write(out);
+	out->writeByte(mindType);
+	out->writeByte(window != NULL);
+
+	debugC(4, kDebugSaveload, "... object = %d", object);
+	debugC(4, kDebugSaveload, "... type = %d", type);
+	debugC(4, kDebugSaveload, "... owner = %d", owner);
+	debugC(4, kDebugSaveload, "... position = (%d, %d, %d, %d)", position.x, position.y, position.width, position.height);
+	debugC(4, kDebugSaveload, "... mindType = %d", mindType);
+	debugC(4, kDebugSaveload, "... shown = %d", window != NULL);
+}
+
 //  Close the container window, but leave the node.
 void ContainerNode::hide(void) {
 	//  close the window, but don't close the object.
@@ -1831,6 +1872,48 @@ void saveContainerNodes(SaveFileConstructor &saveGame) {
 	free(archiveBuffer);
 }
 
+void saveContainerNodes(Common::OutSaveFile *out) {
+	debugC(2, kDebugSaveload, "Saving Container Nodes");
+
+	int i = 0;
+	int16 numNodes = 0;
+	int32 archiveBufSize;
+
+	//  Make sure there are no pending container view actions
+	g_vm->_containerList->doDeferredActions();
+
+	archiveBufSize = sizeof(numNodes);
+
+	//  Count the number of nodes to save
+	for (Common::List<ContainerNode *>::iterator it = g_vm->_containerList->_list.begin(); it != g_vm->_containerList->_list.end(); ++it) {
+		ContainerNode *n = *it;
+
+		if (n->getType() != ContainerNode::readyType)
+			numNodes++;
+	}
+
+	//  Compute size of archive buffer
+	archiveBufSize += numNodes * ContainerNode::archiveSize();
+
+	out->write("CONT", 4);
+	out->writeUint32LE(archiveBufSize);
+
+	//  Store the number of nodes to save
+	out->writeSint16LE(numNodes);
+
+	debugC(3, kDebugSaveload, "... numNodes = %d", numNodes);
+
+	//  Store the nodes
+	for (Common::List<ContainerNode *>::iterator it = g_vm->_containerList->_list.begin(); it != g_vm->_containerList->_list.end(); ++it) {
+		debugC(3, kDebugSaveload, "Saving ContainerNode %d", i++);
+
+		ContainerNode *n = *it;
+
+		if (n->getType() != ContainerNode::readyType)
+			n->write(out);
+	}
+}
+
 void loadContainerNodes(SaveFileReader &saveGame) {
 	ContainerNode       *node;
 	Common::List<ContainerNode *> tempList;
@@ -1870,6 +1953,32 @@ void loadContainerNodes(SaveFileReader &saveGame) {
 	free(archiveBuffer);
 }
 
+void loadContainerNodes(Common::InSaveFile *in) {
+	debugC(2, kDebugSaveload, "Loading Container Nodes");
+
+	ContainerNode *node;
+	Common::List<ContainerNode *> tempList;
+	int16 numNodes;
+
+	//  Read in the number of container nodes to restore
+	numNodes = in->readSint16LE();
+	debugC(3, kDebugSaveload, "... numNodes = %d", numNodes);
+
+	for (int i = 0; i < numNodes; i++) {
+		debugC(3, kDebugSaveload, "Loading ContainerNode %d", i);
+
+		node = new ContainerNode;
+
+		//  Restore the state of the node
+		node->read(in);
+
+		//  Add it back to the container list
+		g_vm->_containerList->add(node);
+	}
+
+	assert(tempList.empty());
+}
+
 void cleanupContainerNodes(void) {
 	for (Common::List<ContainerNode *>::iterator it = g_vm->_containerList->_list.begin(); it != g_vm->_containerList->_list.end(); ++it) {
 		ContainerNode *n = *it;
diff --git a/engines/saga2/contain.h b/engines/saga2/contain.h
index de0549ea51..3920806163 100644
--- a/engines/saga2/contain.h
+++ b/engines/saga2/contain.h
@@ -452,6 +452,9 @@ public:
 	void *restore(void *buf);
 	void *archive(void *buf);
 
+	void read(Common::InSaveFile *in);
+	void write(Common::OutSaveFile *out);
+
 	//  Hide or show this container window.
 	void hide(void);
 	void show(void);
@@ -542,7 +545,9 @@ void cleanupContainers(void);
 
 void initContainerNodes(void);
 void saveContainerNodes(SaveFileConstructor &saveGame);
+void saveContainerNodes(Common::OutSaveFile *out);
 void loadContainerNodes(SaveFileReader &saveGame);
+void loadContainerNodes(Common::InSaveFile *in);
 void cleanupContainerNodes(void);
 
 extern void updateContainerWindows(void);
diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index ee430d9627..fa475faa2a 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -172,10 +172,7 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
 	saveAutoMap(out);
 	saveUIState(out);
 	savePaletteState(out);
-
-#if 0
-	saveContainerNodes(saveGame);
-#endif
+	saveContainerNodes(out);
 
 	out->finalize();
 
@@ -416,16 +413,14 @@ void loadSavedGameState(int16 saveNo) {
 			loadPaletteState(in);
 			loadFlags |= loadPaletteStateFlag;
 			break;
-#if 0
 
 		case MKTAG('C', 'O', 'N', 'T'):
 			if (loadFlags & loadObjectsFlag) {
-				loadContainerNodes(saveGame);
+				loadContainerNodes(in);
 				loadFlags |= loadContainerNodesFlag;
 			} else
 				error("ContainerNodes loaded prematurely");
 			break;
-#endif
 		}
 
 		notEOF = nextChunk(in, id, chunkSize);




More information about the Scummvm-git-logs mailing list