[Scummvm-git-logs] scummvm master -> a9bab56f4421761206e93899999c318746f58736
a-yyg
76591232+a-yyg at users.noreply.github.com
Sun Jul 11 10:02:22 UTC 2021
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d822b43468 SAGA2: Fix for list traversal in checkTimers
a9bab56f44 SAGA2: Implement Timers save/loading
Commit: d822b43468092611a9e1fed115aace2a4dbc7c98
https://github.com/scummvm/scummvm/commit/d822b43468092611a9e1fed115aace2a4dbc7c98
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-11T19:01:23+09:00
Commit Message:
SAGA2: Fix for list traversal in checkTimers
Changed paths:
engines/saga2/objects.cpp
engines/saga2/timers.cpp
engines/saga2/timers.h
diff --git a/engines/saga2/objects.cpp b/engines/saga2/objects.cpp
index 9cc0b63a3b..b727bccb64 100644
--- a/engines/saga2/objects.cpp
+++ b/engines/saga2/objects.cpp
@@ -1860,6 +1860,7 @@ bool GameObject::addTimer(TimerID id, int16 frameInterval) {
assert((*it)->getObject() == this);
if (newTimer->thisID() == (*it)->thisID()) {
+ deleteTimer(*it);
delete *it;
timerList->_timers.erase(it);
@@ -1883,7 +1884,7 @@ void GameObject::removeTimer(TimerID id) {
if ((timerList = fetchTimerList(this)) != nullptr) {
for (Common::List<Timer *>::iterator it = timerList->_timers.begin(); it != timerList->_timers.end(); ++it) {
if ((*it)->thisID() == id) {
- delete *it;
+ (*it)->_active = false;
timerList->_timers.erase(it);
if (timerList->_timers.empty())
@@ -1903,8 +1904,10 @@ void GameObject::removeAllTimers(void) {
// Get this object's timer list
if ((timerList = fetchTimerList(this)) != nullptr) {
- for (Common::List<Timer *>::iterator it = timerList->_timers.begin(); it != timerList->_timers.end(); ++it)
+ for (Common::List<Timer *>::iterator it = timerList->_timers.begin(); it != timerList->_timers.end(); ++it) {
+ deleteTimer(*it);
delete *it;
+ }
timerList->_timers.clear();
diff --git a/engines/saga2/timers.cpp b/engines/saga2/timers.cpp
index d37b469de8..6ae2228669 100644
--- a/engines/saga2/timers.cpp
+++ b/engines/saga2/timers.cpp
@@ -138,20 +138,30 @@ TimerList *fetchTimerList(GameObject *obj) {
return nullptr;
}
+void deleteTimer(Timer *t) {
+ g_vm->_timers.remove(t);
+}
+
//----------------------------------------------------------------------
// Check all active Timers
void checkTimers(void) {
- Common::List<Timer *>::iterator nextIt;
+ for (Common::List<Timer *>::iterator it = g_vm->_timers.begin(); it != g_vm->_timers.end(); it++) {
+ if ((*it)->_active == false)
+ continue;
- for (Common::List<Timer *>::iterator it = g_vm->_timers.begin(); it != g_vm->_timers.end(); it = nextIt) {
- nextIt = it;
- ++nextIt;
if ((*it)->check()) {
debugC(2, kDebugTimers, "Timer tick for %p (%s): %p (duration %d)", (void *)(*it)->getObject(), (*it)->getObject()->objName(), (void *)(*it), (*it)->getInterval());
(*it)->reset();
(*it)->getObject()->timerTick((*it)->thisID());
}
}
+
+ for (Common::List<Timer *>::iterator it = g_vm->_timers.begin(); it != g_vm->_timers.end(); it++) {
+ if ((*it)->_active == false) {
+ delete *it;
+ it = g_vm->_timers.erase(it);
+ }
+ }
}
//----------------------------------------------------------------------
@@ -387,7 +397,6 @@ Timer::Timer(void **buf) {
Timer::~Timer() {
debugC(1, kDebugTimers, "Deleting timer %p (obj %p)",
(void *)this, (void *)_obj);
- g_vm->_timers.remove(this);
}
//----------------------------------------------------------------------
diff --git a/engines/saga2/timers.h b/engines/saga2/timers.h
index 9705f62217..3ca99a2d58 100644
--- a/engines/saga2/timers.h
+++ b/engines/saga2/timers.h
@@ -33,11 +33,14 @@
namespace Saga2 {
+class Timer;
class TimerList;
// Fetch a specified actor's TimerList
TimerList *fetchTimerList(GameObject *obj);
+void deleteTimer(Timer *t);
+
// Check all active Timers
void checkTimers(void);
@@ -93,8 +96,10 @@ class Timer {
FrameAlarm _alarm;
public:
+ bool _active;
+
// Constructor -- initial construction
- Timer(GameObject *o, TimerID timerID, int16 frameInterval) : _obj(o), _id(timerID), _interval(frameInterval) {
+ Timer(GameObject *o, TimerID timerID, int16 frameInterval) : _obj(o), _id(timerID), _interval(frameInterval), _active(true) {
_alarm.set(_interval);
debugC(1, kDebugTimers, "Creating timer %p for %p (%s)",
(void *)this, (void *)o, o->objName());
Commit: a9bab56f4421761206e93899999c318746f58736
https://github.com/scummvm/scummvm/commit/a9bab56f4421761206e93899999c318746f58736
Author: a/ (yuri.kgpps at gmail.com)
Date: 2021-07-11T19:01:24+09:00
Commit Message:
SAGA2: Implement Timers save/loading
Changed paths:
engines/saga2/calender.cpp
engines/saga2/calender.h
engines/saga2/loadsave.cpp
engines/saga2/timers.cpp
engines/saga2/timers.h
diff --git a/engines/saga2/calender.cpp b/engines/saga2/calender.cpp
index 5a87c0e9a1..7c5a0d944b 100644
--- a/engines/saga2/calender.cpp
+++ b/engines/saga2/calender.cpp
@@ -137,6 +137,16 @@ int CalenderTime::lightLevel(int maxLevel) {
FrameAlarm member functions
* ===================================================================== */
+void FrameAlarm::write(Common::OutSaveFile *out) {
+ out->writeUint16LE(baseFrame);
+ out->writeUint16LE(duration);
+}
+
+void FrameAlarm::read(Common::InSaveFile *in) {
+ baseFrame = in->readUint16LE();
+ duration = in->readUint16LE();
+}
+
void FrameAlarm::set(uint16 dur) {
baseFrame = calender.frameInDay();
duration = dur;
diff --git a/engines/saga2/calender.h b/engines/saga2/calender.h
index b6aa1f58b5..46567ce2a8 100644
--- a/engines/saga2/calender.h
+++ b/engines/saga2/calender.h
@@ -80,6 +80,9 @@ public:
void set(uint16 dur);
bool check(void);
uint16 elapsed(void);
+
+ void write(Common::OutSaveFile *out);
+ void read(Common::InSaveFile *in);
};
/* ===================================================================== *
diff --git a/engines/saga2/loadsave.cpp b/engines/saga2/loadsave.cpp
index 7cca8bfc7d..b22b1e54b2 100644
--- a/engines/saga2/loadsave.cpp
+++ b/engines/saga2/loadsave.cpp
@@ -162,9 +162,9 @@ Common::Error saveGameState(int16 saveNo, char *saveName) {
saveTileTasks(out);
saveSpeechTasks(out);
saveActiveRegions(out);
+ saveTimers(out);
#if 0
- saveTimers(saveGame);
saveSensors(saveGame);
saveTempActorCount(saveGame);
saveMissions(saveGame);
@@ -351,15 +351,15 @@ void loadSavedGameState(int16 saveNo) {
loadActiveRegions(in);
loadFlags |= loadActiveRegionsFlag;
break;
-#if 0
case MKTAG('T', 'I', 'M', 'R'):
if (loadFlags & loadActorsFlag) {
- loadTimers(saveGame);
+ loadTimers(in);
loadFlags |= loadTimersFlag;
} else
error("Timers loaded prematurely");
break;
+#if 0
case MKTAG('S', 'E', 'N', 'S'):
if (loadFlags & loadActorsFlag) {
diff --git a/engines/saga2/timers.cpp b/engines/saga2/timers.cpp
index 6ae2228669..c59e89844f 100644
--- a/engines/saga2/timers.cpp
+++ b/engines/saga2/timers.cpp
@@ -241,6 +241,72 @@ void saveTimers(SaveFileConstructor &saveGame) {
#endif
}
+static int getTimerListID(TimerList *t) {
+ int i = 0;
+ for (Common::List<TimerList *>::iterator it = g_vm->_timerLists.begin(); it != g_vm->_timerLists.end(); it++, i++) {
+ if ((*it) == t)
+ return i;
+ }
+ return -1;
+}
+
+static int getTimerID(Timer *t) {
+ int i = 0;
+ for (Common::List<Timer *>::iterator it = g_vm->_timers.begin(); it != g_vm->_timers.end(); it++, i++) {
+ if ((*it) == t)
+ return i;
+ }
+ return -1;
+}
+
+void saveTimers(Common::OutSaveFile *out) {
+ debugC(2, kDebugSaveload, "Saving Timers");
+
+ int16 timerListCount = 0,
+ timerCount = 0;
+
+ int32 archiveBufSize = 0;
+
+ // Add the sizes of the timer list count an timer count
+ archiveBufSize += sizeof(timerListCount) + sizeof(timerCount);
+
+ // Tally the timer lists
+ timerListCount = g_vm->_timerLists.size();
+
+ // Add the total archive size of all of the timer lists
+ archiveBufSize += timerListCount * TimerList::archiveSize();
+
+ // Tally the timers
+ timerCount = g_vm->_timers.size();
+
+ debugC(3, kDebugSaveload, "... timerListCount = %d", timerListCount);
+ debugC(3, kDebugSaveload, "... timerCount = %d", timerCount);
+
+ // Add the total archive size of all of the timers
+ archiveBufSize += timerCount * Timer::archiveSize();
+
+ out->write("TIMR", 4);
+ out->writeUint32LE(archiveBufSize);
+
+ // Store the timer list count and timer count
+ out->writeSint16LE(timerListCount);
+ out->writeSint16LE(timerCount);
+
+ // Archive all timer lists
+ for (Common::List<TimerList *>::iterator it = g_vm->_timerLists.begin(); it != g_vm->_timerLists.end(); it++) {
+ debugC(3, kDebugSaveload, "Saving TimerList %d", getTimerListID(*it));
+ (*it)->write(out);
+ }
+
+ for (Common::List<Timer *>::iterator it = g_vm->_timers.begin(); it != g_vm->_timers.end(); it++) {
+ if ((*it)->_active == false)
+ continue;
+ debugC(3, kDebugSaveload, "Saving Timer %d", getTimerID(*it));
+
+ (*it)->write(out);
+ }
+}
+
//----------------------------------------------------------------------
// Load the Timers from a save file
@@ -298,6 +364,46 @@ void loadTimers(SaveFileReader &saveGame) {
#endif
}
+void loadTimers(Common::InSaveFile *in) {
+ debugC(2, kDebugSaveload, "Loading Timers");
+
+ int16 timerListCount,
+ timerCount;
+
+ // Get the timer list count and timer count
+ timerListCount = in->readSint16LE();
+ timerCount = in->readSint16LE();
+
+ debugC(3, kDebugSaveload, "... timerListCount = %d", timerListCount);
+ debugC(3, kDebugSaveload, "... timerCount = %d", timerCount);
+
+ // Restore all timer lists
+ for (int i = 0; i < timerListCount; i++) {
+ debugC(3, kDebugSaveload, "Loading TimerList %d", i);
+ new TimerList(in);
+ }
+
+ // Restore all timers
+ for (int i = 0; i < timerCount; i++) {
+ Timer *timer;
+ TimerList *timerList;
+
+ debugC(3, kDebugSaveload, "Loading Timer %d", i);
+
+ timer = new Timer(in);
+
+ assert(timer != NULL);
+
+ // Get the objects's timer list
+ timerList = fetchTimerList(timer->getObject());
+
+ assert(timerList != NULL);
+
+ // Append this timer to the objects's timer list
+ timerList->_timers.push_back(timer);
+ }
+}
+
//----------------------------------------------------------------------
// Cleanup the active Timers
@@ -342,6 +448,17 @@ TimerList::TimerList(void **buf) {
g_vm->_timerLists.push_back(this);
}
+TimerList::TimerList(Common::InSaveFile *in) {
+ ObjectID id = in->readUint16LE();
+
+ assert(isObject(id) || isActor(id));
+
+ // Restore the object pointer
+ _obj = GameObject::objectAddress(id);
+
+ g_vm->_timerLists.push_back(this);
+}
+
TimerList::~TimerList() {
debugC(1, kDebugTimers, "Deleting timer list %p for %p (%s))",
(void *)this, (void *)_obj, _obj->objName());
@@ -359,6 +476,11 @@ void *TimerList::archive(void *buf) {
return buf;
}
+void TimerList::write(Common::OutSaveFile *out) {
+ // Store the object's ID
+ out->writeUint16LE(_obj->thisID());
+}
+
/* ===================================================================== *
Timer member functions
* ===================================================================== */
@@ -394,6 +516,26 @@ Timer::Timer(void **buf) {
g_vm->_timers.push_back(this);
}
+Timer::Timer(Common::InSaveFile *in) {
+ ObjectID id = in->readUint16LE();
+
+ assert(isObject(id) || isActor(id));
+
+ // Restore the object pointer
+ _obj = GameObject::objectAddress(id);
+
+ // Restore the timer's ID
+ _id = in->readSint16LE();
+
+ // Restore the frame interval
+ _interval = in->readSint16LE();
+
+ // Restore the alarm
+ _alarm.read(in);
+
+ g_vm->_timers.push_back(this);
+}
+
Timer::~Timer() {
debugC(1, kDebugTimers, "Deleting timer %p (obj %p)",
(void *)this, (void *)_obj);
@@ -432,4 +574,18 @@ void *Timer::archive(void *buf) {
return buf;
}
+void Timer::write(Common::OutSaveFile *out) {
+ // Store the obj's ID
+ out->writeUint16LE(_obj->thisID());
+
+ // Store the timer's ID
+ out->writeSint16LE(_id);
+
+ // Store the frame interval
+ out->writeSint16LE(_interval);
+
+ // Store the alarm
+ _alarm.write(out);
+}
+
} // end of namespace Saga2
diff --git a/engines/saga2/timers.h b/engines/saga2/timers.h
index 3ca99a2d58..e9b61f130b 100644
--- a/engines/saga2/timers.h
+++ b/engines/saga2/timers.h
@@ -48,8 +48,10 @@ void checkTimers(void);
void initTimers(void);
// Save the active Timers in a save file
void saveTimers(SaveFileConstructor &saveGame);
+void saveTimers(Common::OutSaveFile *out);
// Load Timers from a save file
void loadTimers(SaveFileReader &saveGame);
+void loadTimers(Common::InSaveFile *in);
// Cleanup the active Timers
void cleanupTimers(void);
@@ -67,6 +69,8 @@ public:
// Constructor -- reconstruct from archive buffer
TimerList(void **buf);
+ TimerList(Common::InSaveFile *in);
+
~TimerList();
// Return the number of bytes needed to archive this object in
@@ -78,6 +82,8 @@ public:
// Archive this object in a buffer
void *archive(void *buf);
+ void write(Common::OutSaveFile *out);
+
GameObject *getObject(void) {
return _obj;
}
@@ -109,6 +115,9 @@ public:
// Constructor -- reconstruct from archive buffer
Timer(void **buf);
+
+ Timer(Common::InSaveFile *in);
+
~Timer();
// Return the number of bytes needed to archive this object in
@@ -118,6 +127,8 @@ public:
// Archive this object in a buffer
void *archive(void *buf);
+ void write(Common::OutSaveFile *out);
+
GameObject *getObject(void) {
return _obj;
}
More information about the Scummvm-git-logs
mailing list