SAGA2: Implement Sensor save/loading

This commit is contained in:
a/ 2021-07-12 06:25:37 +09:00
parent 09ed7592bd
commit a9f7ee09d7
3 changed files with 326 additions and 3 deletions

View File

@ -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);

View File

@ -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

View File

@ -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);