aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Crozat2017-11-04 14:54:26 +0000
committerThierry Crozat2018-01-23 02:15:37 +0000
commit7bf803f6e677b9b8bf29caf55f9c211cfe175c1b (patch)
treecbb22fbbb3be74863f097e000d0be51915d0fe5d
parent21899d8716475c08aa591c087b58c63bb00927ed (diff)
downloadscummvm-rg350-7bf803f6e677b9b8bf29caf55f9c211cfe175c1b.tar.gz
scummvm-rg350-7bf803f6e677b9b8bf29caf55f9c211cfe175c1b.tar.bz2
scummvm-rg350-7bf803f6e677b9b8bf29caf55f9c211cfe175c1b.zip
SUPERNOVA: Cleanup dialog code
The main change consists in using a separate byte array for the sentence removal flags, move some functions from the GameManager to the Room class, and add a few additional functions to manipulate this new array. This allows to clarify some code related to dialogs. This change also allows to switch the _shown array back to a bool array.
-rw-r--r--engines/supernova/msn_def.h1
-rw-r--r--engines/supernova/rooms.cpp45
-rw-r--r--engines/supernova/rooms.h29
-rw-r--r--engines/supernova/state.cpp6
-rw-r--r--engines/supernova/state.h2
-rw-r--r--engines/supernova/supernova.cpp2
-rw-r--r--engines/supernova/supernova.h2
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