mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
TSAGE: Reworked the saving code to fix crashes
Note that this undoes the recent compilation fix for GCC, since it didn't work. For now, used an explicit void ** conversion as previously suggested.
This commit is contained in:
parent
d18f8e8564
commit
5dcfd1e32c
@ -728,6 +728,7 @@ public:
|
||||
}
|
||||
SynchronisedList<SceneObject *>::iterator begin() { return _objList.begin(); }
|
||||
SynchronisedList<SceneObject *>::iterator end() { return _objList.end(); }
|
||||
int size() const { return _objList.size(); }
|
||||
bool contains(SceneObject *sceneObj) { return tSage::contains(_objList, sceneObj); }
|
||||
void push_back(SceneObject *sceneObj) { _objList.push_back(sceneObj); }
|
||||
void push_front(SceneObject *sceneObj) { _objList.push_front(sceneObj); }
|
||||
|
@ -151,13 +151,13 @@ Common::Error Saver::save(int slot, const Common::String &saveName) {
|
||||
}
|
||||
|
||||
Common::Error Saver::restore(int slot) {
|
||||
assert(!getMacroSaveFlag());
|
||||
assert(!getMacroRestoreFlag());
|
||||
|
||||
// Signal any objects registered for notification
|
||||
_loadNotifiers.notify(false);
|
||||
|
||||
// Set fields
|
||||
_macroSaveFlag = true;
|
||||
_macroRestoreFlag = true;
|
||||
_saveSlot = slot;
|
||||
_unresolvedPtrs.clear();
|
||||
|
||||
@ -335,7 +335,7 @@ bool Saver::savegamesExist() const {
|
||||
*/
|
||||
int Saver::blockIndexOf(SavedObject *p) {
|
||||
int objIndex = 1;
|
||||
SynchronisedList<SavedObject *>::iterator iObj;
|
||||
Common::List<SavedObject *>::iterator iObj;
|
||||
|
||||
for (iObj = _objList.begin(); iObj != _objList.end(); ++iObj, ++objIndex) {
|
||||
SavedObject *iObjP = *iObj;
|
||||
@ -346,6 +346,30 @@ int Saver::blockIndexOf(SavedObject *p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of objects in the object list registry
|
||||
*/
|
||||
int Saver::getObjectCount() const {
|
||||
int count = 0;
|
||||
Common::List<SavedObject *>::const_iterator i;
|
||||
|
||||
for (i = _objList.begin(); i != _objList.end(); ++i, ++count)
|
||||
;
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* List any currently active objects
|
||||
*/
|
||||
void Saver::listObjects() {
|
||||
Common::List<SavedObject *>::iterator i;
|
||||
int count = 1;
|
||||
|
||||
for (i = _objList.begin(); i != _objList.end(); ++i, ++count)
|
||||
debug("%d - %s", count, (*i)->getClassName().c_str());
|
||||
debug("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pointer associated with the specified object index
|
||||
*/
|
||||
@ -358,12 +382,14 @@ void Saver::resolveLoadPointers() {
|
||||
int objIndex = 1;
|
||||
for (SynchronisedList<SavedObject *>::iterator iObj = _objList.begin(); iObj != _objList.end(); ++iObj, ++objIndex) {
|
||||
Common::List<SavedObjectRef>::iterator iPtr;
|
||||
SavedObject *pObj = *iObj;
|
||||
|
||||
for (iPtr = _unresolvedPtrs.begin(); iPtr != _unresolvedPtrs.end(); ) {
|
||||
SavedObjectRef &r = *iPtr;
|
||||
if (r._objIndex == objIndex) {
|
||||
// Found an unresolved pointer to this object
|
||||
*r._savedObject = *iObj;
|
||||
SavedObject **objPP = r._savedObject;
|
||||
*objPP = pObj;
|
||||
iPtr = _unresolvedPtrs.erase(iPtr);
|
||||
} else {
|
||||
++iPtr;
|
||||
|
@ -54,8 +54,8 @@ struct tSageSavegameHeader {
|
||||
// FIXME: workaround to supress spurious strict-alias warnings on older GCC
|
||||
// versions. this should be resolved with the savegame rewrite
|
||||
#define SYNC_POINTER(x) do { \
|
||||
SavedObject *y = (SavedObject *)x; \
|
||||
s.syncPointer(&y); \
|
||||
SavedObject **y = (SavedObject **)((void *)&x); \
|
||||
s.syncPointer(y); \
|
||||
} while (false)
|
||||
|
||||
#define SYNC_ENUM(FIELD, TYPE) int v_##FIELD = (int)FIELD; s.syncAsUint16LE(v_##FIELD); \
|
||||
@ -176,7 +176,7 @@ typedef SavedObject *(*SavedObjectFactory)(const Common::String &className);
|
||||
|
||||
class Saver {
|
||||
private:
|
||||
SynchronisedList<SavedObject *> _objList;
|
||||
Common::List<SavedObject *> _objList;
|
||||
FunctionList<bool> _saveNotifiers;
|
||||
FunctionList<bool> _loadNotifiers;
|
||||
Common::List<SaveListener *> _listeners;
|
||||
@ -212,6 +212,8 @@ public:
|
||||
bool getMacroSaveFlag() const { return _macroSaveFlag; }
|
||||
bool getMacroRestoreFlag() const { return _macroRestoreFlag; }
|
||||
int blockIndexOf(SavedObject *p);
|
||||
int getObjectCount() const;
|
||||
void listObjects();
|
||||
};
|
||||
|
||||
extern Saver *_saver;
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "tsage/globals.h"
|
||||
#include "tsage/ringworld_logic.h"
|
||||
#include "tsage/tsage.h"
|
||||
#include "tsage/saveload.h"
|
||||
|
||||
namespace tSage {
|
||||
|
||||
@ -39,6 +40,7 @@ SceneManager::SceneManager() {
|
||||
_fadeMode = FADEMODE_GRADUAL;
|
||||
_scrollerRect = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
_saver->addListener(this);
|
||||
_objectCount = 0;
|
||||
}
|
||||
|
||||
SceneManager::~SceneManager() {
|
||||
@ -107,6 +109,12 @@ void SceneManager::sceneChange() {
|
||||
// Free any regions
|
||||
disposeRegions();
|
||||
|
||||
// Ensure that the same number of objects are registered now as when the scene started
|
||||
if (_objectCount > 0) {
|
||||
assert(_objectCount == _saver->getObjectCount());
|
||||
}
|
||||
_objectCount = _saver->getObjectCount();
|
||||
|
||||
// Instantiate and set the new scene
|
||||
_scene = getNewScene();
|
||||
_scene->postInit();
|
||||
|
@ -88,6 +88,7 @@ public:
|
||||
int _sceneLoadCount;
|
||||
Rect _scrollerRect;
|
||||
SceneObjectList _altSceneObjects;
|
||||
int _objectCount;
|
||||
public:
|
||||
SceneManager();
|
||||
virtual ~SceneManager();
|
||||
|
Loading…
Reference in New Issue
Block a user