diff options
-rw-r--r-- | engines/supernova/msn_def.h | 1 | ||||
-rw-r--r-- | engines/supernova/rooms.cpp | 45 | ||||
-rw-r--r-- | engines/supernova/rooms.h | 29 | ||||
-rw-r--r-- | engines/supernova/state.cpp | 6 | ||||
-rw-r--r-- | engines/supernova/state.h | 2 | ||||
-rw-r--r-- | engines/supernova/supernova.cpp | 2 | ||||
-rw-r--r-- | engines/supernova/supernova.h | 2 |
7 files changed, 55 insertions, 32 deletions
diff --git a/engines/supernova/msn_def.h b/engines/supernova/msn_def.h index 6f57e28211..fcf57441f0 100644 --- a/engines/supernova/msn_def.h +++ b/engines/supernova/msn_def.h @@ -33,6 +33,7 @@ const int kTextSpeed[] = {19, 14, 10, 7, 4}; const int kMsecPerTick = 55; const int kMaxSection = 40; +const int kMaxDialog = 2; const int kMaxObject = 25; const int kMaxCarry = 30; diff --git a/engines/supernova/rooms.cpp b/engines/supernova/rooms.cpp index 8c32d5c611..eef4d16801 100644 --- a/engines/supernova/rooms.cpp +++ b/engines/supernova/rooms.cpp @@ -36,6 +36,8 @@ bool Room::serialize(Common::WriteStream *out) { out->writeSint32LE(_id); for (int i = 0; i < kMaxSection; ++i) out->writeByte(_shown[i]); + for (int i = 0; i < kMaxDialog ; ++i) + out->writeByte(_sentenceRemoved[i]); int numObjects = 0; while ((_objectState[numObjects]._id != INVALIDOBJECT) && (numObjects < kMaxObject)) @@ -60,14 +62,21 @@ bool Room::serialize(Common::WriteStream *out) { return !out->err(); } -bool Room::deserialize(Common::ReadStream *in) { +bool Room::deserialize(Common::ReadStream *in, int version) { if (in->err()) return false; in->readSint32LE(); + for (int i = 0; i < kMaxSection; ++i) _shown[i] = in->readByte(); + // Prior to version 3, _sentenceRemoved was part of _shown (the last two values) + // But on the other hand dialog was not implemented anyway, so we don't even try to + // recover it. + for (int i = 0; i < kMaxDialog ; ++i) + _sentenceRemoved[i] = version < 3 ? 0 : in->readByte(); + int numObjects = in->readSint32LE(); for (int i = 0; i < numObjects; ++i) { _objectState[i]._name = static_cast<StringID>(in->readSint32LE()); @@ -1634,7 +1643,7 @@ bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) { else _gm->reply(kStringArsanoEntrance14, 1, _gm->invertSection(1)); e = 0; - while ((e < 3) && (_shown[kMaxSection - 1] != 15)) { + while ((e < 3) && (!allSentencesRemoved(4, 1))) { switch (e = _gm->dialog(5, row1, _dialog1, 1)) { case 0: _gm->reply(kStringArsanoEntrance15, 1, 1 + 128); @@ -1921,11 +1930,10 @@ void ArsanoRemaining::animation() { } void ArsanoRoger::onEntrance() { - // This is not a normal shown variable, it's a dialog - if (_shown[kMaxSection - 2] == 0) { + if (!sentenceRemoved(0, 2)) { _gm->say(kStringArsanoRoger1); _gm->reply(kStringArsanoRoger2, 2, 2 + 128); - _shown[kMaxSection - 2] = 1; + removeSentence(0, 2); } } @@ -2126,18 +2134,15 @@ bool ArsanoGlider::interact(Action verb, Object &obj1, Object &obj2) { } void ArsanoMeetup2::onEntrance() { - // We don't use the enum because those are dialog status and not "real" _shown - switch (_shown[kMaxSection - 1]) { - case 1: - _gm->shipStart(); - break; - case 2: + if (sentenceRemoved(0, 1)) { + if (sentenceRemoved(1, 1)) + _vm->renderMessage(kStringArsanoMeetup2_2); // All spaceships have left the planet, except one ... + else + _gm->shipStart(); + } else if (sentenceRemoved(1, 1)) _vm->renderMessage(kStringArsanoMeetup2_1); // All spaceships have left the planet - break; - case 3: - _vm->renderMessage(kStringArsanoMeetup2_2); // All spaceships have left the planet, except one ... - } - _shown[kMaxSection - 1] = 0; + + addAllSentences(1); } bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) { @@ -2153,7 +2158,7 @@ bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) { _vm->renderImage(30, 0); _vm->paletteBrightness(); bool found; - if (_gm->_rooms[MEETUP2]->isSectionVisible(kMaxSection - 2)) { + if (sentenceRemoved(0, 2) || sentenceRemoved(1, 2)) { _gm->reply(kStringArsanoMeetup2_3, 1, 1 + 128); found = !_gm->dialog(2, row4, _dialog4, 0); if (!(found)) @@ -2162,7 +2167,7 @@ bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) { _gm->reply(kStringArsanoMeetup2_5, 1, 1 + 128); _gm->reply(kStringArsanoMeetup2_6, 1, 1 + 128); found = !_gm->dialog(2, row1, _dialog1, 0); - _gm->_rooms[MEETUP2]->setSectionVisible(kMaxSection - 2, true); + removeSentence(0, 2); } if (found) { _gm->_inventory.remove(*_gm->_rooms[ROGER]->getObject(3)); @@ -2327,7 +2332,7 @@ bool ArsanoMeetup3::interact(Action verb, Object &obj1, Object &obj2) { _gm->reply(kStringArsanoMeetup3_25, 1, 1 + 128); } removeSentence(2, 2); - } while (_shown[kMaxSection - 2] != 15); + } while (!allSentencesRemoved(4, 2)); _gm->say(kStringArsanoMeetup3_26); _gm->reply(kStringArsanoMeetup3_27, 1, 1 + 128); _gm->reply(kStringArsanoMeetup3_28, 1, 1 + 128); @@ -2581,7 +2586,7 @@ void AxacussCorridor5::onEntrance() { bool AxacussCorridor5::handleMoneyDialog() { if (_gm->dialog(2, _rows, _dialog2, 0) == 0) { _gm->reply(kStringAxacussCorridor5_5, 1, 1 + 128); - setSectionVisible(kMaxSection - 2, false); + addAllSentences(2); if (_gm->_state._money == 0) { removeSentence(2, 2); removeSentence(3, 2); diff --git a/engines/supernova/rooms.h b/engines/supernova/rooms.h index 47249f0bb6..b9dbfd19fb 100644 --- a/engines/supernova/rooms.h +++ b/engines/supernova/rooms.h @@ -38,6 +38,8 @@ public: _seen = false; for (int i = 0; i < kMaxSection; ++i) _shown[i] = kShownFalse; + for (int i = 0; i < kMaxDialog; ++i) + _sentenceRemoved[i] = 0; } bool hasSeen() { @@ -64,18 +66,32 @@ public: void removeSentence(int sentence, int number) { if (number > 0) - _shown[kMaxSection - number] |= (1 << sentence); + _sentenceRemoved[number - 1] |= (1 << sentence); } void addSentence(int sentence, int number) { if (number > 0) - _shown[kMaxSection - number] &= ~(1 << sentence); + _sentenceRemoved[number - 1] &= ~(1 << sentence); } - bool sentencedRemoved(int sentence, int number) { + void addAllSentences(int number) { + if (number > 0) + _sentenceRemoved[number - 1] = 0; + } + + bool sentenceRemoved(int sentence, int number) { + if (number <= 0) + return false; + return (_sentenceRemoved[number - 1] & (1 << sentence)); + } + + bool allSentencesRemoved(int maxSentence, int number) { if (number <= 0) return false; - return (_shown[kMaxSection - number] & (1 << sentence)); + for (int i = 0, flag = 1 ; i < maxSentence ; ++i, flag <<= 1) + if (!(_sentenceRemoved[number - 1] & flag)) + return false; + return true; } Object *getObject(uint index) { @@ -89,11 +105,12 @@ public: return false; } virtual bool serialize(Common::WriteStream *out); - virtual bool deserialize(Common::ReadStream *in); + virtual bool deserialize(Common::ReadStream *in, int version); protected: int _fileNumber; - byte _shown[kMaxSection]; + bool _shown[kMaxSection]; + byte _sentenceRemoved[kMaxDialog]; Object _objectState[kMaxObject]; RoomID _id; SupernovaEngine *_vm; diff --git a/engines/supernova/state.cpp b/engines/supernova/state.cpp index c289fbaa67..d3ab297417 100644 --- a/engines/supernova/state.cpp +++ b/engines/supernova/state.cpp @@ -75,7 +75,7 @@ bool GameManager::serialize(Common::WriteStream *out) { } -bool GameManager::deserialize(Common::ReadStream *in) { +bool GameManager::deserialize(Common::ReadStream *in, int version) { if (in->err()) return false; @@ -115,7 +115,7 @@ bool GameManager::deserialize(Common::ReadStream *in) { // Rooms _currentRoom = _rooms[static_cast<RoomID>(in->readByte())]; for (int i = 0; i < NUMROOMS; ++i) { - _rooms[i]->deserialize(in); + _rooms[i]->deserialize(in, version); } return !in->err(); @@ -852,7 +852,7 @@ void GameManager::reply(const char *text, int aus1, int aus2) { int GameManager::dialog(int num, byte rowLength[6], StringID text[6], int number) { bool remove[6]; for (int i = 0; i < 5; ++i) - remove[i] = _currentRoom->sentencedRemoved(i, number); + remove[i] = _currentRoom->sentenceRemoved(i, number); // The original does not initialize remove[5]!!! // Set it to false/0. But maybe the loop above should use 6 instead of 5? remove[5] = false; diff --git a/engines/supernova/state.h b/engines/supernova/state.h index c5f5803fa4..8b904d18a3 100644 --- a/engines/supernova/state.h +++ b/engines/supernova/state.h @@ -99,7 +99,7 @@ public: void processInput(); void executeRoom(); bool serialize(Common::WriteStream *out); - bool deserialize(Common::ReadStream *in); + bool deserialize(Common::ReadStream *in, int version); SupernovaEngine *_vm; Common::KeyState _key; diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index 65fefea7f3..c693f9e34b 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -920,7 +920,7 @@ bool SupernovaEngine::loadGame(int slot) { savefile->skip(6); setTotalPlayTime(savefile->readUint32LE() * 1000); Graphics::skipThumbnail(*savefile); - _gm->deserialize(savefile); + _gm->deserialize(savefile, saveVersion); delete savefile; diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h index 70df62f282..8ba298c751 100644 --- a/engines/supernova/supernova.h +++ b/engines/supernova/supernova.h @@ -43,7 +43,7 @@ namespace Supernova { #define SAVEGAME_HEADER MKTAG('M','S','N','1') -#define SAVEGAME_VERSION 2 +#define SAVEGAME_VERSION 3 #define SUPERNOVA_DAT "supernova.dat" #define SUPERNOVA_DAT_VERSION 1 |