diff options
-rw-r--r-- | engines/hugo/file.cpp | 6 | ||||
-rw-r--r-- | engines/hugo/hugo.h | 2 | ||||
-rw-r--r-- | engines/hugo/schedule.cpp | 87 | ||||
-rw-r--r-- | engines/hugo/schedule.h | 4 |
4 files changed, 98 insertions, 1 deletions
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp index effa00001b..dcd84d7d04 100644 --- a/engines/hugo/file.cpp +++ b/engines/hugo/file.cpp @@ -390,6 +390,9 @@ bool FileManager::saveGame(int16 slot, Common::String descrip) { // Now save current time and all current events in event queue _vm->_scheduler->saveEvents(out); + // Now save current actions + _vm->_scheduler->saveActions(out); + // Save palette table _vm->_screen->savePal(out); @@ -495,6 +498,9 @@ bool FileManager::restoreGame(int16 slot) { // Now restore time of the save and the event queue _vm->_scheduler->restoreEvents(in); + // Now restore actions + _vm->_scheduler->restoreActions(in); + // Restore palette and change it if necessary _vm->_screen->restorePal(in); diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h index 13ef74fe3a..1aaecdf0ec 100644 --- a/engines/hugo/hugo.h +++ b/engines/hugo/hugo.h @@ -58,7 +58,7 @@ class RandomSource; */ namespace Hugo { -static const int kSavegameVersion = 2; +static const int kSavegameVersion = 3; static const int kInvDx = 32; // Width of an inventory icon static const int kInvDy = 32; // Height of inventory icon static const int kMaxTunes = 16; // Max number of tunes diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp index 948feec4d1..f23923589a 100644 --- a/engines/hugo/schedule.cpp +++ b/engines/hugo/schedule.cpp @@ -47,6 +47,7 @@ namespace Hugo { Scheduler::Scheduler(HugoEngine *vm) : _vm(vm), _actListArr(0) { + memset(_events, 0, sizeof(_events)); } Scheduler::~Scheduler() { @@ -896,6 +897,12 @@ void Scheduler::saveEvents(Common::WriteStream *f) { for (int16 i = 0; i < kMaxEvents; i++) { event_t *wrkEvent = &_events[i]; saveEventArr[i] = *wrkEvent; + + // fix up action pointer (to do better) + int16 index, subElem; + findAction(saveEventArr[i].action, &index, &subElem); + saveEventArr[i].action = (act*)((index << 16)| subElem); + saveEventArr[i].prevEvent = (wrkEvent->prevEvent == 0) ? (event_t *) - 1 : (event_t *)(wrkEvent->prevEvent - _events); saveEventArr[i].nextEvent = (wrkEvent->nextEvent == 0) ? (event_t *) - 1 : (event_t *)(wrkEvent->nextEvent - _events); } @@ -904,6 +911,79 @@ void Scheduler::saveEvents(Common::WriteStream *f) { warning("TODO: serialize saveEventArr"); } +/** +* Restore the action data from file with handle f +*/ + +void Scheduler::restoreActions(Common::SeekableReadStream *f) { + + for (int i = 0; i < _actListArrSize; i++) { + + // read all the sub elems + int j = 0; + do { + + // handle special case for a3, keep list pointer + int* responsePtr = 0; + if (_actListArr[i][j].a3.actType == PROMPT) { + responsePtr = _actListArr[i][j].a3.responsePtr; + } + + f->read(&_actListArr[i][j], sizeof(act)); + + // handle special case for a3, reset list pointer + if (_actListArr[i][j].a3.actType == PROMPT) { + _actListArr[i][j].a3.responsePtr = responsePtr; + } + j++; + } while (_actListArr[i][j-1].a0.actType != ANULL); + } +} + +/* +* Save the action data in the file with handle f +*/ + +void Scheduler::saveActions(Common::WriteStream* f) { + for (int i = 0; i < _actListArrSize; i++) { + // write all the sub elems data + + int j = 0; + do { + f->write(&_actListArr[i][j], sizeof(act)); + j++; + } while (_actListArr[i][j-1].a0.actType != ANULL); + } +} + +/* +* Find the index in the action list to be able to serialize the action to save game +*/ + +void Scheduler::findAction(act* action, int16* index, int16* subElem) { + + assert(index && subElem); + if (!action) { + *index = -1; + *subElem = -1; + return; + } + + for (int i = 0; i < _actListArrSize; i++) { + int j = 0; + do { + if (action == &_actListArr[i][j]) { + *index = i; + *subElem = j; + return; + } + j++; + } while (_actListArr[i][j-1].a0.actType != ANULL); + } + // action not found ?? + assert(0); +} + /** * Restore the event list from file with handle f */ @@ -923,6 +1003,13 @@ void Scheduler::restoreEvents(Common::SeekableReadStream *f) { for (int i = 0; i < kMaxEvents; i++) { wrkEvent = &savedEvents[i]; _events[i] = *wrkEvent; + // fix up action pointer (to do better) + int32 val = (size_t)_events[i].action; + if ((val & 0xffff) == 0xffff) { + _events[i].action = 0; + } else { + _events[i].action = (act*)&_actListArr[val >> 16][val & 0xffff]; + } _events[i].prevEvent = (wrkEvent->prevEvent == (event_t *) - 1) ? (event_t *)0 : &_events[(size_t)wrkEvent->prevEvent ]; _events[i].nextEvent = (wrkEvent->nextEvent == (event_t *) - 1) ? (event_t *)0 : &_events[(size_t)wrkEvent->nextEvent ]; } diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h index 33d3eb2bd2..f3d24cad77 100644 --- a/engines/hugo/schedule.h +++ b/engines/hugo/schedule.h @@ -471,6 +471,10 @@ public: void saveEvents(Common::WriteStream *f); void waitForRefresh(void); + void findAction(act* action, int16* index, int16* subElem); + void saveActions(Common::WriteStream* f); + void restoreActions(Common::SeekableReadStream *f); + protected: HugoEngine *_vm; static const int kFilenameLength = 12; // Max length of a DOS file name |