[Scummvm-git-logs] scummvm master -> 8a378fb89b03229f11154685838de209681ffd2f
fracturehill
noreply at scummvm.org
Fri Mar 3 15:39:52 UTC 2023
This automated email contains information about 7 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
5fb49e2fe8 NANCY: Implement HotMultiframeMultisceneChange action record type
bfff477734 NANCY: Add support for secondary movie in The Vampire Diaries
a367dfe519 DEVTOOLS: Update create-nancy
5908e0b2d4 NANCY: Add facilities to load nancy.dat
2c9443ecf9 NANCY: Load conditional dialogue and hints from nancy.dat
900e4666c0 NANCY: Upgrade debug console
8a378fb89b NANCY: Remove cheat dialogs
Commit: 5fb49e2fe87ad18cc6b9073dbcc231e1a15d4b3f
https://github.com/scummvm/scummvm/commit/5fb49e2fe87ad18cc6b9073dbcc231e1a15d4b3f
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:56+02:00
Commit Message:
NANCY: Implement HotMultiframeMultisceneChange action record type
Implemented the HotMultiframeMultisceneChange action record,
which chooses between two different scene transitions depending on
some condition.
Changed paths:
engines/nancy/action/recordtypes.cpp
engines/nancy/action/recordtypes.h
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index 0fc8df7ce18..5379bebdca8 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -106,9 +106,66 @@ void Hot1FrSceneChange::execute() {
}
void HotMultiframeMultisceneChange::readData(Common::SeekableReadStream &stream) {
- stream.seek(0x14, SEEK_CUR);
- uint size = stream.readUint16LE() * 0x12;
- stream.skip(size);
+ _onTrue.readData(stream);
+ _onFalse.readData(stream);
+ _condType = (ConditionType)stream.readByte();
+ _conditionID = stream.readUint16LE();
+ _conditionPayload = stream.readByte();
+ uint numHotspots = stream.readUint16LE();
+
+ _hotspots.resize(numHotspots);
+
+ for (uint i = 0; i < numHotspots; ++i) {
+ _hotspots[i].readData(stream);
+ }
+}
+
+void HotMultiframeMultisceneChange::execute() {
+ switch (_state) {
+ case kBegin:
+ // set something to 1
+ _state = kRun;
+ // fall through
+ case kRun:
+ _hasHotspot = false;
+
+ for (HotspotDescription &desc : _hotspots) {
+ if (desc.frameID == NancySceneState.getSceneInfo().frameID) {
+ _hotspot = desc.coords;
+ _hasHotspot = true;
+ }
+ }
+
+ break;
+ case kActionTrigger: {
+ bool conditionMet = false;
+ switch (_condType) {
+ case kEventFlag:
+ if (NancySceneState.getEventFlag(_conditionID, (NancyFlag)_conditionPayload)) {
+ conditionMet = true;
+ }
+ break;
+ case kItem:
+ if (NancySceneState.hasItem(_conditionID) == _conditionPayload) {
+ conditionMet = true;
+ }
+ break;
+ case kItemHeld:
+ if (NancySceneState.getHeldItem() == _conditionPayload) {
+ conditionMet = true;
+ }
+ break;
+ }
+
+ if (conditionMet) {
+ NancySceneState.changeScene(_onTrue);
+ } else {
+ NancySceneState.changeScene(_onFalse);
+ }
+
+ break;
+ }
+ }
}
void PaletteThisScene::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index ee99e028ca0..0e0cf611e53 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -79,7 +79,17 @@ protected:
class HotMultiframeMultisceneChange : public Unimplemented {
public:
+ enum ConditionType { kEventFlag = 1, kItem = 2, kItemHeld = 3 };
+
void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+
+ SceneChangeDescription _onTrue;
+ SceneChangeDescription _onFalse;
+ ConditionType _condType;
+ uint16 _conditionID;
+ byte _conditionPayload;
+ Common::Array<HotspotDescription> _hotspots;
protected:
Common::String getRecordTypeName() const override { return "HotMultiframeMultisceneChange"; }
Commit: bfff477734d8ce911bdc72b2ca4de884cd80c8f6
https://github.com/scummvm/scummvm/commit/bfff477734d8ce911bdc72b2ca4de884cd80c8f6
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:56+02:00
Commit Message:
NANCY: Add support for secondary movie in The Vampire Diaries
Made changes to PlaySecondaryMovie to support The Vampire Diaries'
slightly different data format.
Changed paths:
engines/nancy/action/secondarymovie.cpp
engines/nancy/action/secondarymovie.h
diff --git a/engines/nancy/action/secondarymovie.cpp b/engines/nancy/action/secondarymovie.cpp
index bbc59ca0dda..14d89b67aeb 100644
--- a/engines/nancy/action/secondarymovie.cpp
+++ b/engines/nancy/action/secondarymovie.cpp
@@ -28,6 +28,8 @@
#include "engines/nancy/state/scene.h"
+#include "common/serializer.h"
+
namespace Nancy {
namespace Action {
@@ -40,29 +42,44 @@ PlaySecondaryMovie::~PlaySecondaryMovie() {
}
void PlaySecondaryMovie::readData(Common::SeekableReadStream &stream) {
- readFilename(stream, _videoName);
+ Common::Serializer ser(&stream, nullptr);
+ ser.setVersion(g_nancy->getGameType());
- stream.skip(0x12);
- _unknown = stream.readUint16LE();
- _hideMouse = (NancyFlag)stream.readUint16LE();
- _isReverse = (NancyFlag)stream.readUint16LE();
- _firstFrame = (NancyFlag)stream.readUint16LE();
- _lastFrame = (NancyFlag)stream.readUint16LE();
-
- for (uint i = 0; i < 15; ++i) {
- _frameFlags[i].frameID = stream.readSint16LE();
- _frameFlags[i].flagDesc.label = stream.readSint16LE();
- _frameFlags[i].flagDesc.flag = (NancyFlag)stream.readUint16LE();
+ readFilename(stream, _videoName);
+ readFilename(stream, _paletteName);
+ ser.skip(10, kGameTypeVampire, kGameTypeVampire); // skip _bitmapOverlayName for now
+
+ ser.skip(0x2); // videoPlaySource
+
+ ser.syncAsUint16LE(_isTransparent, kGameTypeVampire, kGameTypeVampire);
+ ser.skip(4, kGameTypeVampire, kGameTypeVampire); // paletteStart, paletteSize
+ ser.skip(2, kGameTypeVampire, kGameTypeVampire); // hasBitmapOverlaySurface
+ ser.skip(2, kGameTypeVampire, kGameTypeVampire); // unknown, probably related to playing a sfx
+
+ ser.syncAsUint16LE(_unknown);
+ ser.syncAsUint16LE(_hideMouse);
+ ser.syncAsUint16LE(_isReverse);
+ ser.syncAsUint16LE(_firstFrame);
+ ser.syncAsUint16LE(_lastFrame);
+
+ if (ser.getVersion() >= kGameTypeNancy1) {
+ _frameFlags.resize(15);
+ for (uint i = 0; i < 15; ++i) {
+ ser.syncAsSint16LE(_frameFlags[i].frameID);
+ ser.syncAsSint16LE(_frameFlags[i].flagDesc.label);
+ ser.syncAsUint16LE(_frameFlags[i].flagDesc.flag);
+ }
}
_triggerFlags.readData(stream);
_sound.read(stream, SoundDescription::kNormal);
_sceneChange.readData(stream);
+ ser.skip(3, kGameTypeVampire, kGameTypeVampire); // unknown 3 sceneChange bytes
- uint16 numVideoDescs = stream.readUint16LE();
- _videoDescs.reserve(numVideoDescs);
+ uint16 numVideoDescs;
+ ser.syncAsUint16LE(numVideoDescs);
+ _videoDescs.resize(numVideoDescs);
for (uint i = 0; i < numVideoDescs; ++i) {
- _videoDescs.push_back(SecondaryVideoDescription());
_videoDescs[i].readData(stream);
}
}
@@ -76,6 +93,15 @@ void PlaySecondaryMovie::init() {
error("Couldn't load video file %s", _videoName.c_str());
}
_drawSurface.create(_decoder.getWidth(), _decoder.getHeight(), g_nancy->_graphicsManager->getInputPixelFormat());
+ if (_paletteName.size()) {
+ GraphicsManager::loadSurfacePalette(_fullFrame, _paletteName);
+ }
+
+ if (_isTransparent) {
+ setTransparent(true);
+ _fullFrame.setTransparentColor(_drawSurface.getTransparentColor());
+ }
+
_screenPosition = _drawSurface.getBounds();
RenderObject::init();
@@ -106,7 +132,9 @@ void PlaySecondaryMovie::updateGraphics() {
}
}
- _drawSurface.blitFrom(*_decoder.decodeNextFrame(), _videoDescs[descID].srcRect, Common::Point());
+ GraphicsManager::copyToManaged(*_decoder.decodeNextFrame(), _fullFrame, _paletteName.size() > 0);
+ _drawSurface.create(_fullFrame, _fullFrame.getBounds());
+ moveTo(_videoDescs[descID].destRect);
_needsRedraw = true;
for (auto f : _frameFlags) {
diff --git a/engines/nancy/action/secondarymovie.h b/engines/nancy/action/secondarymovie.h
index eaefb2d0888..62991e6e537 100644
--- a/engines/nancy/action/secondarymovie.h
+++ b/engines/nancy/action/secondarymovie.h
@@ -49,13 +49,16 @@ public:
void execute() override;
Common::String _videoName; // 0x00
+ Common::String _paletteName;
+ //Common::String _bitmapOverlayName
+ NancyFlag _isTransparent = kFalse;
uint16 _unknown = 0; // 0x1C
NancyFlag _hideMouse = NancyFlag::kFalse; // 0x1E
- NancyFlag _isReverse = NancyFlag::kFalse; // 0x20
- uint16 _firstFrame = 0; // 0x22
- uint16 _lastFrame = 0; // 0x24
- FlagAtFrame _frameFlags[15]; // 0x26
+ NancyFlag _isReverse = NancyFlag::kFalse; // 0x20, 2E
+ uint16 _firstFrame = 0; // 0x22, 30
+ uint16 _lastFrame = 0; // 0x24, 32
+ Common::Array<FlagAtFrame> _frameFlags; // 0x26
MultiEventFlagDescription _triggerFlags; // 0x80
SoundDescription _sound; // 0xA8
@@ -68,6 +71,7 @@ protected:
bool isViewportRelative() const override { return true; }
AVFDecoder _decoder;
+ Graphics::ManagedSurface _fullFrame;
int _curViewportFrame = -1;
bool _isFinished = false;
};
Commit: a367dfe5192735d5e89dceef9ea855be9b8361c4
https://github.com/scummvm/scummvm/commit/a367dfe5192735d5e89dceef9ea855be9b8361c4
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:57+02:00
Commit Message:
DEVTOOLS: Update create-nancy
Updated the format for nancy.dat to make multilanguage arrays
much easier to read.
Changed paths:
devtools/create_nancy/file.cpp
devtools/create_nancy/types.h
dists/engine-data/nancy.dat
diff --git a/devtools/create_nancy/file.cpp b/devtools/create_nancy/file.cpp
index 7b5a8f06a1a..c027b6099db 100644
--- a/devtools/create_nancy/file.cpp
+++ b/devtools/create_nancy/file.cpp
@@ -220,11 +220,10 @@ void writeToFile(File &file, const Hint &obj) {
}
void writeMultilangArray(File &file, const Common::Array<Common::Array<const char *>> &array) {
- file.writeUint16(array.size());
Common::Array<uint32> offsets;
uint32 offsetsOffset = file.pos();
- file.skip(array.size() * 4);
+ file.skip(array.size() * 4 + 4 + 2);
for (uint i = 0; i < array.size(); ++i) {
offsets.push_back(file.pos());
@@ -234,6 +233,8 @@ void writeMultilangArray(File &file, const Common::Array<Common::Array<const cha
uint end = file.pos();
file.seek(offsetsOffset);
+ file.writeUint16(array.size());
+ file.writeUint32(end);
for (uint i = 0; i < array.size(); ++i) {
file.writeUint32(offsets[i]);
}
diff --git a/devtools/create_nancy/types.h b/devtools/create_nancy/types.h
index cf5c6677d1d..f6191ef4250 100644
--- a/devtools/create_nancy/types.h
+++ b/devtools/create_nancy/types.h
@@ -61,7 +61,7 @@ struct ConditionalDialogue {
};
struct GoodbyeSceneChange {
- Common::Array<int16> sceneIDs;
+ Common::Array<uint16> sceneIDs;
Common::Array<EventFlagDescription> flagConditions;
EventFlagDescription flagToSet;
};
diff --git a/dists/engine-data/nancy.dat b/dists/engine-data/nancy.dat
index 59684a3f665..1d238387232 100644
Binary files a/dists/engine-data/nancy.dat and b/dists/engine-data/nancy.dat differ
Commit: 5908e0b2d433b400e658c374614b9584a09587ca
https://github.com/scummvm/scummvm/commit/5908e0b2d433b400e658c374614b9584a09587ca
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:57+02:00
Commit Message:
NANCY: Add facilities to load nancy.dat
Added functions for loading the data inside nancy.dat. Removed
constants.h and .cpp.
Changed paths:
R engines/nancy/constants.cpp
R engines/nancy/constants.h
engines/nancy/commontypes.cpp
engines/nancy/commontypes.h
engines/nancy/cursor.cpp
engines/nancy/module.mk
engines/nancy/nancy.cpp
engines/nancy/nancy.h
engines/nancy/state/logo.cpp
engines/nancy/state/scene.cpp
engines/nancy/ui/inventorybox.cpp
diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index 387c9ca0612..f7d490ca348 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -101,4 +101,201 @@ void SoundDescription::read(Common::SeekableReadStream &stream, Type type) {
stream.skip(2);
}
+void ConditionalDialogue::readData(Common::SeekableReadStream &stream) {
+ textID = stream.readByte();
+ sceneID = stream.readUint16LE();
+ soundID = stream.readString();
+
+ uint16 num = stream.readUint16LE();
+ flagConditions.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ flagConditions[i].label = stream.readSint16LE();
+ flagConditions[i].flag = (NancyFlag)stream.readByte();
+ }
+
+ num = stream.readUint16LE();
+ inventoryConditions.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ inventoryConditions[i].label = stream.readSint16LE();
+ inventoryConditions[i].flag = (NancyFlag)stream.readByte();
+ }
+}
+
+void GoodbyeSceneChange::readData(Common::SeekableReadStream &stream) {
+ uint16 num = stream.readUint16LE();
+ sceneIDs.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ sceneIDs[i] = stream.readSint16LE();
+ }
+
+ num = stream.readUint16LE();
+ flagConditions.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ flagConditions[i].label = stream.readSint16LE();
+ flagConditions[i].flag = (NancyFlag)stream.readByte();
+ }
+
+ flagToSet.label = stream.readSint16LE();
+ flagToSet.flag = (NancyFlag)stream.readByte();
+}
+
+void Goodbye::readData(Common::SeekableReadStream &stream) {
+ soundID = stream.readString();
+
+ uint16 num = stream.readUint16LE();
+ sceneChanges.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ sceneChanges[i].readData(stream);
+ }
+}
+
+void Hint::readData(Common::SeekableReadStream &stream) {
+ textID = stream.readByte();
+ hintWeight = stream.readSint16LE();
+ sceneChange.readData(stream);
+ soundIDs[0] = stream.readString();
+ soundIDs[1] = stream.readString();
+ soundIDs[2] = stream.readString();
+
+ uint16 num = stream.readUint16LE();
+ flagConditions.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ flagConditions[i].label = stream.readSint16LE();
+ flagConditions[i].flag = (NancyFlag)stream.readByte();
+ }
+
+ num = stream.readUint16LE();
+ inventoryConditions.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ inventoryConditions[i].label = stream.readSint16LE();
+ inventoryConditions[i].flag = (NancyFlag)stream.readByte();
+ }
+}
+
+void StaticData::readData(Common::SeekableReadStream &stream, Common::Language language) {
+ numItems = stream.readUint16LE();
+ numEventFlags = stream.readUint16LE();
+
+ uint16 num = stream.readUint16LE();
+ mapAccessSceneIDs.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ mapAccessSceneIDs[i] = stream.readUint16LE();
+ }
+
+ num = stream.readUint16LE();
+ genericEventFlags.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ genericEventFlags[i] = stream.readUint16LE();
+ }
+
+ numNonItemCursors = stream.readUint16LE();
+ numCurtainAnimationFrames = stream.readUint16LE();
+ logoEndAfter = stream.readUint32LE();
+
+ // Check for language
+ num = stream.readUint16LE();
+ int languageID = -1;
+ for (uint16 i = 0; i < num; ++i) {
+ if (stream.readByte() == language) {
+ languageID = i;
+ }
+ }
+
+ if (languageID == -1) {
+ error("Language not present in nancy.dat");
+ }
+
+ // Read the strings logic
+ num = stream.readUint16LE();
+ conditionalDialogue.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ uint16 num2 = stream.readUint16LE();
+ conditionalDialogue[i].resize(num2);
+ for (uint j = 0; j < num2; ++j) {
+ conditionalDialogue[i][j].readData(stream);
+ }
+ }
+
+ num = stream.readUint16LE();
+ goodbyes.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ goodbyes[i].readData(stream);
+ }
+
+ num = stream.readUint16LE();
+ hints.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ uint16 num2 = stream.readUint16LE();
+ hints[i].resize(num2);
+ for (uint j = 0; j < num2; ++j) {
+ hints[i][j].readData(stream);
+ }
+ }
+
+ // Read the in-game strings, making sure to pick the correct language
+ num = stream.readUint16LE();
+ if (num > 0) {
+ uint32 endOffset = stream.readUint32LE();
+ stream.skip(languageID * 4);
+ stream.seek(stream.readUint32LE());
+ num = stream.readUint16LE();
+ conditionalDialogueTexts.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ conditionalDialogueTexts[i] = stream.readString();
+ }
+
+ stream.seek(endOffset);
+ }
+
+ num = stream.readUint16LE();
+ if (num > 0) {
+ uint32 endOffset = stream.readUint32LE();
+ stream.skip(languageID * 4);
+ stream.seek(stream.readUint32LE());
+ num = stream.readUint16LE();
+ goodbyeTexts.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ goodbyeTexts[i] = stream.readString();
+ }
+
+ stream.seek(endOffset);
+ }
+
+ num = stream.readUint16LE();
+ if (num > 0) {
+ uint32 endOffset = stream.readUint32LE();
+ stream.skip(languageID * 4);
+ stream.seek(stream.readUint32LE());
+ num = stream.readUint16LE();
+ hintTexts.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ hintTexts[i] = stream.readString();
+ }
+
+ stream.seek(endOffset);
+ }
+
+ num = stream.readUint16LE();
+ for (int i = 0; i < num; ++i) {
+ if (i == languageID) {
+ ringingText = stream.readString();
+ } else {
+ stream.readString();
+ }
+ }
+
+ // Read debug strings
+ num = stream.readUint16LE();
+ itemNames.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ itemNames[i] = stream.readString();
+ }
+
+ num = stream.readUint16LE();
+ eventFlagNames.resize(num);
+ for (uint16 i = 0; i < num; ++i) {
+ eventFlagNames[i] = stream.readString();
+ }
+}
+
} // End of namespace Nancy
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 2bdd4bcd814..8453307b625 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -23,6 +23,8 @@
#define NANCY_COMMONYPES_H
#include "common/rect.h"
+#include "common/array.h"
+#include "common/str.h"
namespace Common {
class SeekableReadStream;
@@ -122,6 +124,72 @@ struct SoundDescription {
void read(Common::SeekableReadStream &stream, Type type);
};
+// Structs inside nancy.dat, which contains all the data that was
+// originally stored inside the executable
+
+struct ConditionalDialogue {
+ byte textID;
+ uint16 sceneID;
+ Common::String soundID;
+ Common::Array<EventFlagDescription> flagConditions;
+ Common::Array<EventFlagDescription> inventoryConditions;
+
+ void readData(Common::SeekableReadStream &stream);
+};
+
+struct GoodbyeSceneChange {
+ Common::Array<uint16> sceneIDs;
+ Common::Array<EventFlagDescription> flagConditions;
+ EventFlagDescription flagToSet;
+
+ void readData(Common::SeekableReadStream &stream);
+};
+
+struct Goodbye {
+ Common::String soundID;
+ Common::Array<GoodbyeSceneChange> sceneChanges;
+
+ void readData(Common::SeekableReadStream &stream);
+};
+
+struct Hint {
+ byte textID;
+ int16 hintWeight;
+ SceneChangeDescription sceneChange;
+ Common::String soundIDs[3];
+ Common::Array<EventFlagDescription> flagConditions;
+ Common::Array<EventFlagDescription> inventoryConditions;
+
+ void readData(Common::SeekableReadStream &stream);
+};
+
+struct StaticData {
+ // Default values are for nancy1, provided for debugging purposes
+ uint16 numItems = 11;
+ uint16 numEventFlags = 168;
+ Common::Array<uint16> mapAccessSceneIDs;
+ Common::Array<uint16> genericEventFlags;
+ uint16 numNonItemCursors = 12;
+ uint16 numCurtainAnimationFrames = 7;
+ uint32 logoEndAfter = 7000;
+
+ // In-game strings and related logic
+ Common::Array<Common::Array<ConditionalDialogue>> conditionalDialogue;
+ Common::Array<Goodbye> goodbyes;
+ Common::Array<Common::Array<Hint>> hints;
+
+ Common::Array<Common::String> conditionalDialogueTexts;
+ Common::Array<Common::String> goodbyeTexts;
+ Common::Array<Common::String> hintTexts;
+ Common::String ringingText;
+
+ // Debug strings
+ Common::Array<Common::String> itemNames;
+ Common::Array<Common::String> eventFlagNames;
+
+ void readData(Common::SeekableReadStream &stream, Common::Language language);
+};
+
} // End of namespace Nancy
#endif // NANCY_COMMONYPES_H
diff --git a/engines/nancy/constants.cpp b/engines/nancy/constants.cpp
deleted file mode 100644
index 6db75949194..00000000000
--- a/engines/nancy/constants.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "engines/nancy/constants.h"
-
-namespace Nancy {
-
-const GameConstants gameConstants[] {
- // The Vampire Diaries
- {
- 24,
- 120,
- { 0, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 125, 219, 220, -1 },
- { 110, 111, 112, 113, 114, -1 },
- 8,
- 10,
- 167000
- },
-
- // Nancy Drew: Secrets Can Kill
- {
- 11,
- 168,
- { 9, 10, 11, 666, 888, 1200, 1250, 1666, -1 },
- { 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
- 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
- 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, -1 },
- 12,
- 7,
- 7000
- },
-
- // Nancy Drew: Stay Tuned For Danger
- {
- 18,
- 240,
- { -1 }, // No dedicated Map state
- { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1 },
- 12, // TODO
- 7, // TODO
- 7000 // TODO
- }
-};
-
-} // End of namespace Nancy
diff --git a/engines/nancy/constants.h b/engines/nancy/constants.h
deleted file mode 100644
index e8fb08560fe..00000000000
--- a/engines/nancy/constants.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef NANCY_CONSTANTS_H
-#define NANCY_CONSTANTS_H
-
-#include "common/scummsys.h"
-
-namespace Nancy {
-
-// A struct containing various data that was hardcoded in the original engine but changed between titles
-struct GameConstants {
- uint numItems;
- uint numEventFlags;
- int mapAccessSceneIDs[18];
- int eventFlagsToClearOnSceneChange[32];
- uint numNonItemCursors;
- uint numCurtainAnimationFrames;
- uint logoEndAfter;
-};
-
-extern const GameConstants gameConstants[];
-
-} // End of namespace Nancy
-
-#endif // NANCY_CONSTANTS_H
diff --git a/engines/nancy/cursor.cpp b/engines/nancy/cursor.cpp
index 1f5e113d585..69fe7800a6e 100644
--- a/engines/nancy/cursor.cpp
+++ b/engines/nancy/cursor.cpp
@@ -26,18 +26,17 @@
#include "engines/nancy/graphics.h"
#include "engines/nancy/resource.h"
#include "engines/nancy/util.h"
-#include "engines/nancy/constants.h"
namespace Nancy {
void CursorManager::init() {
Common::SeekableReadStream *chunk = g_nancy->getBootChunkStream("INV");
- chunk->seek(0xD6 + g_nancy->getConstants().numCurtainAnimationFrames * 0x20 + 0x1C);
+ chunk->seek(0xD6 + g_nancy->getStaticData().numCurtainAnimationFrames * 0x20 + 0x1C);
Common::String inventoryCursorsImageName = chunk->readString();
chunk = g_nancy->getBootChunkStream("CURS");
chunk->seek(0);
- uint numCursors = g_nancy->getConstants().numNonItemCursors + g_nancy->getConstants().numItems * 4;
+ uint numCursors = g_nancy->getStaticData().numNonItemCursors + g_nancy->getStaticData().numItems * 4;
_cursors.reserve(numCursors);
for (uint i = 0; i < numCursors; ++i) {
_cursors.push_back(Cursor());
@@ -95,7 +94,7 @@ void CursorManager::setCursor(CursorType type, int16 itemID) {
itemID = 0;
} else {
// Item held
- itemsOffset = g_nancy->getConstants().numNonItemCursors;
+ itemsOffset = g_nancy->getStaticData().numNonItemCursors;
hasItem = true;
}
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index 128025c9e2f..18870ea1530 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -30,7 +30,6 @@ MODULE_OBJS = \
state/scene.o \
commontypes.o \
console.o \
- constants.o \
cursor.o \
decompress.o \
dialogs.o \
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 66524deb26a..1bcf5874c21 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -35,7 +35,6 @@
#include "engines/nancy/graphics.h"
#include "engines/nancy/dialogs.h"
#include "engines/nancy/console.h"
-#include "engines/nancy/constants.h"
#include "engines/nancy/util.h"
#include "engines/nancy/action/primaryvideo.h"
@@ -51,7 +50,13 @@ namespace Nancy {
NancyEngine *g_nancy;
-NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) : Engine(syst), _gameDescription(gd), _system(syst) {
+NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
+ Engine(syst),
+ _gameDescription(gd),
+ _system(syst),
+ _datFileMajorVersion(0),
+ _datFileMinorVersion(1) {
+
g_nancy = this;
_randomSource = new Common::RandomSource("Nancy");
@@ -151,8 +156,8 @@ Common::Platform NancyEngine::getPlatform() const {
return _gameDescription->desc.platform;
}
-const GameConstants &NancyEngine::getConstants() const {
- return gameConstants[getGameType() - 1];
+const StaticData &NancyEngine::getStaticData() const {
+ return _staticData;
}
void NancyEngine::setState(NancyState::NancyState state, NancyState::NancyState overridePrevious) {
@@ -318,6 +323,9 @@ void NancyEngine::bootGameEngine() {
_resource = new ResourceManager();
_resource->initialize();
+ // Read nancy.dat
+ readDatFile();
+
// Setup mixer
syncSoundSettings();
@@ -338,9 +346,7 @@ void NancyEngine::bootGameEngine() {
"MAP", "CD", "TBOX", "CURS", "VIEW", "MSND",
"BUOK", "BUDE", "BULS", "GLOB", "SLID",
"SET", "CURT", "CANT", "TH1", "TH2",
- "QUOT", "TMOD",
- // Used in nancy2
- "CLOK", "SPEC"
+ "QUOT", "TMOD", "CLOK", "SPEC"
};
for (auto const &n : names) {
@@ -488,6 +494,36 @@ void NancyEngine::readBootSummary(const IFF &boot) {
}
}
+void NancyEngine::readDatFile() {
+ Common::SeekableReadStream *datFile = SearchMan.createReadStreamForMember("nancy.dat");
+ if (!datFile) {
+ error("Unable to find nancy.dat");
+ }
+
+ if (datFile->readUint32BE() != MKTAG('N', 'N', 'C', 'Y')) {
+ error("nancy.dat is invalid");
+ }
+
+ byte major = datFile->readByte();
+ byte minor = datFile->readByte();
+ if (major != _datFileMajorVersion || minor != _datFileMinorVersion) {
+ error("Incorrect nancy.dat version. Expected '%d.%d', found %d.%d",
+ _datFileMajorVersion, _datFileMinorVersion, major, minor);
+ }
+
+ uint16 numGames = datFile->readUint16LE();
+ if (getGameType() > numGames) {
+ warning("Data for game type %d is not in nancy.dat", numGames);
+ return;
+ }
+
+ // Seek to offset containing current game
+ datFile->skip((getGameType() - 1) * 4);
+ datFile->seek(datFile->readUint32LE());
+
+ _staticData.readData(*datFile, _gameDescription->desc.language);
+}
+
Common::Error NancyEngine::synchronize(Common::Serializer &ser) {
Common::SeekableReadStream *bsum = getBootChunkStream("BSUM");
bsum->seek(0);
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index ef4cd8067e8..19099cf2994 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -64,7 +64,6 @@ class GraphicsManager;
class CursorManager;
class CheatDialog;
class NancyConsole;
-struct GameConstants;
namespace State {
class State;
@@ -93,7 +92,7 @@ public:
GameType getGameType() const;
Common::Platform getPlatform() const;
- const GameConstants &getConstants() const;
+ const StaticData &getStaticData() const;
void setState(NancyState::NancyState state, NancyState::NancyState overridePrevious = NancyState::kNone);
NancyState::NancyState getState() { return _gameFlow.curState; }
@@ -150,6 +149,7 @@ private:
void readChunkList(const IFF &boot, Common::Serializer &ser, const Common::String &prefix);
void readBootSummary(const IFF &boot);
+ void readDatFile();
Common::Error synchronize(Common::Serializer &serializer);
@@ -157,6 +157,10 @@ private:
bool _cheatTypeIsEventFlag;
+ StaticData _staticData;
+ const byte _datFileMajorVersion;
+ const byte _datFileMinorVersion;
+
GameFlow _gameFlow;
OSystem *_system;
diff --git a/engines/nancy/state/logo.cpp b/engines/nancy/state/logo.cpp
index 4bd43889f79..0b4c74a0cda 100644
--- a/engines/nancy/state/logo.cpp
+++ b/engines/nancy/state/logo.cpp
@@ -24,7 +24,6 @@
#include "engines/nancy/nancy.h"
#include "engines/nancy/sound.h"
#include "engines/nancy/input.h"
-#include "engines/nancy/constants.h"
#include "engines/nancy/state/logo.h"
@@ -73,7 +72,7 @@ void Logo::startSound() {
}
void Logo::run() {
- if ((g_nancy->getTotalPlayTime() - _startTicks >= g_nancy->getConstants().logoEndAfter) ||
+ if ((g_nancy->getTotalPlayTime() - _startTicks >= g_nancy->getStaticData().logoEndAfter) ||
(g_nancy->_input->getInput().input & NancyInput::kLeftMouseButtonDown)) {
_state = kStop;
}
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index d6d2910af8e..69a3c717638 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -29,7 +29,6 @@
#include "engines/nancy/graphics.h"
#include "engines/nancy/cursor.h"
#include "engines/nancy/util.h"
-#include "engines/nancy/constants.h"
#include "engines/nancy/state/scene.h"
@@ -235,7 +234,7 @@ void Scene::setHeldItem(int16 id) {
}
void Scene::setEventFlag(int16 label, NancyFlag flag) {
- if (label > -1 && (uint)label < g_nancy->getConstants().numEventFlags) {
+ if (label > -1 && (uint)label < g_nancy->getStaticData().numEventFlags) {
_flags.eventFlags[label] = flag;
}
}
@@ -245,7 +244,7 @@ void Scene::setEventFlag(EventFlagDescription eventFlag) {
}
bool Scene::getEventFlag(int16 label, NancyFlag flag) const {
- if (label > -1 && (uint)label < g_nancy->getConstants().numEventFlags) {
+ if (label > -1 && (uint)label < g_nancy->getStaticData().numEventFlags) {
return _flags.eventFlags[label] == flag;
} else {
return false;
@@ -345,7 +344,7 @@ void Scene::synchronize(Common::Serializer &ser) {
// TODO hardcoded inventory size
auto &order = getInventoryBox()._order;
uint prevSize = getInventoryBox()._order.size();
- getInventoryBox()._order.resize(g_nancy->getConstants().numItems);
+ getInventoryBox()._order.resize(g_nancy->getStaticData().numItems);
if (ser.isSaving()) {
for (uint i = prevSize; i < order.size(); ++i) {
@@ -353,7 +352,7 @@ void Scene::synchronize(Common::Serializer &ser) {
}
}
- ser.syncArray(order.data(), g_nancy->getConstants().numItems, Common::Serializer::Sint16LE);
+ ser.syncArray(order.data(), g_nancy->getStaticData().numItems, Common::Serializer::Sint16LE);
while (order.size() && order.back() == -1) {
order.pop_back();
@@ -365,7 +364,7 @@ void Scene::synchronize(Common::Serializer &ser) {
}
// TODO hardcoded inventory size
- ser.syncArray(_flags.items.data(), g_nancy->getConstants().numItems, Common::Serializer::Byte);
+ ser.syncArray(_flags.items.data(), g_nancy->getStaticData().numItems, Common::Serializer::Byte);
ser.syncAsSint16LE(_flags.heldItem);
g_nancy->_cursorManager->setCursorItemID(_flags.heldItem);
@@ -380,7 +379,7 @@ void Scene::synchronize(Common::Serializer &ser) {
g_nancy->setTotalPlayTime((uint32)_timers.lastTotalTime);
// TODO hardcoded number of event flags
- ser.syncArray(_flags.eventFlags.data(), g_nancy->getConstants().numEventFlags, Common::Serializer::Byte);
+ ser.syncArray(_flags.eventFlags.data(), g_nancy->getStaticData().numEventFlags, Common::Serializer::Byte);
ser.syncArray<uint16>(_flags.sceneHitCount, (uint16)2001, Common::Serializer::Uint16LE);
@@ -414,14 +413,14 @@ void Scene::synchronize(Common::Serializer &ser) {
}
void Scene::init() {
- _flags.eventFlags = Common::Array<NancyFlag>(g_nancy->getConstants().numEventFlags, kFalse);
+ _flags.eventFlags = Common::Array<NancyFlag>(g_nancy->getStaticData().numEventFlags, kFalse);
// Does this ever get used?
for (uint i = 0; i < 2001; ++i) {
_flags.sceneHitCount[i] = 0;
}
- _flags.items = Common::Array<NancyFlag>(g_nancy->getConstants().numItems, kFalse);
+ _flags.items = Common::Array<NancyFlag>(g_nancy->getStaticData().numItems, kFalse);
_timers.lastTotalTime = 0;
_timers.playerTime = g_nancy->_startTimeHours * 3600000;
@@ -619,12 +618,8 @@ void Scene::run() {
}
// Handle invisible map button
- for (uint i = 0; i < ARRAYSIZE(g_nancy->getConstants().mapAccessSceneIDs); ++i) {
- if (g_nancy->getConstants().mapAccessSceneIDs[i] == -1) {
- break;
- }
-
- if ((int)_sceneState.currentScene.sceneID == g_nancy->getConstants().mapAccessSceneIDs[i]) {
+ for (uint16 id : g_nancy->getStaticData().mapAccessSceneIDs) {
+ if ((int)_sceneState.currentScene.sceneID == id) {
if (_mapHotspot.contains(input.mousePos)) {
g_nancy->_cursorManager->setCursorType(CursorManager::kHotspotArrow);
@@ -632,6 +627,8 @@ void Scene::run() {
requestStateChange(NancyState::kMap);
}
}
+
+ break;
}
}
@@ -682,13 +679,9 @@ void Scene::initStaticData() {
}
void Scene::clearSceneData() {
- // only clear select flags
- for (uint i = 0; i < ARRAYSIZE(g_nancy->getConstants().eventFlagsToClearOnSceneChange); ++i) {
- if (g_nancy->getConstants().eventFlagsToClearOnSceneChange[i] == -1) {
- break;
- }
-
- _flags.eventFlags[g_nancy->getConstants().eventFlagsToClearOnSceneChange[i]] = kFalse;
+ // Clear generic flags only
+ for (uint16 id : g_nancy->getStaticData().genericEventFlags) {
+ _flags.eventFlags[id] = kFalse;
}
clearLogicConditions();
diff --git a/engines/nancy/ui/inventorybox.cpp b/engines/nancy/ui/inventorybox.cpp
index f88ac99730d..2546ac4cf60 100644
--- a/engines/nancy/ui/inventorybox.cpp
+++ b/engines/nancy/ui/inventorybox.cpp
@@ -26,7 +26,6 @@
#include "engines/nancy/sound.h"
#include "engines/nancy/input.h"
#include "engines/nancy/util.h"
-#include "engines/nancy/constants.h"
#include "engines/nancy/ui/inventorybox.h"
@@ -64,7 +63,7 @@ void InventoryBox::init() {
stream.seek(0xD6, SEEK_SET);
- uint numFrames = g_nancy->getConstants().numCurtainAnimationFrames;
+ uint numFrames = g_nancy->getStaticData().numCurtainAnimationFrames;
_curtainsSrc.resize(numFrames * 2);
for (uint i = 0; i < numFrames * 2; ++i) {
readRect(stream, _curtainsSrc[i]);
@@ -83,8 +82,8 @@ void InventoryBox::init() {
char itemName[20];
uint itemNameLength = g_nancy->getGameType() == kGameTypeVampire ? 15 : 20;
- _itemDescriptions.reserve(g_nancy->getConstants().numItems);
- for (uint i = 0; i < g_nancy->getConstants().numItems; ++i) {
+ _itemDescriptions.reserve(g_nancy->getStaticData().numItems);
+ for (uint i = 0; i < g_nancy->getStaticData().numItems; ++i) {
stream.read(itemName, itemNameLength);
itemName[itemNameLength - 1] = '\0';
_itemDescriptions.push_back(ItemDescription());
@@ -96,7 +95,7 @@ void InventoryBox::init() {
g_nancy->_resource->loadImage(inventoryBoxIconsImageName, _iconsSurface);
- _fullInventorySurface.create(_screenPosition.width(), _screenPosition.height() * ((g_nancy->getConstants().numItems / 4) + 1), g_nancy->_graphicsManager->getScreenPixelFormat());
+ _fullInventorySurface.create(_screenPosition.width(), _screenPosition.height() * ((g_nancy->getStaticData().numItems / 4) + 1), g_nancy->_graphicsManager->getScreenPixelFormat());
Common::Rect sourceRect = _screenPosition;
sourceRect.moveTo(0, 0);
_drawSurface.create(_fullInventorySurface, sourceRect);
@@ -249,7 +248,7 @@ void InventoryBox::Curtains::init() {
void InventoryBox::Curtains::updateGraphics() {
Time time = g_nancy->getTotalPlayTime();
if (_areOpen) {
- if (_curFrame < g_nancy->getConstants().numCurtainAnimationFrames && time > _nextFrameTime) {
+ if (_curFrame < g_nancy->getStaticData().numCurtainAnimationFrames && time > _nextFrameTime) {
setAnimationFrame(++_curFrame);
_nextFrameTime = time + _parent->_curtainsFrameTime;
@@ -270,7 +269,7 @@ void InventoryBox::Curtains::updateGraphics() {
}
}
- if (_curFrame == 0 || _curFrame == g_nancy->getConstants().numCurtainAnimationFrames) {
+ if (_curFrame == 0 || _curFrame == g_nancy->getStaticData().numCurtainAnimationFrames) {
_soundTriggered = false;
}
}
@@ -280,7 +279,7 @@ void InventoryBox::Curtains::setAnimationFrame(uint frame) {
Common::Rect srcRect;
Common::Point destPoint;
- if (frame > g_nancy->getConstants().numCurtainAnimationFrames - 1) {
+ if (frame > (uint)(g_nancy->getStaticData().numCurtainAnimationFrames - 1)) {
setVisible(false);
return;
} else {
Commit: 2c9443ecf921a548031d5031286082c1e8ddaee7
https://github.com/scummvm/scummvm/commit/2c9443ecf921a548031d5031286082c1e8ddaee7
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:58+02:00
Commit Message:
NANCY: Load conditional dialogue and hints from nancy.dat
Added facilities to load conditional dialogue and hints from
nancy.dat. Removed unnecessary files. Bumped save game version
up by one.
Changed paths:
R engines/nancy/action/responses.cpp
R engines/nancy/dialogueresponses.cpp
R engines/nancy/dialogueresponses.h
engines/nancy/action/primaryvideo.cpp
engines/nancy/action/primaryvideo.h
engines/nancy/action/recordtypes.cpp
engines/nancy/action/recordtypes.h
engines/nancy/nancy.h
engines/nancy/state/scene.cpp
engines/nancy/state/scene.h
diff --git a/engines/nancy/action/primaryvideo.cpp b/engines/nancy/action/primaryvideo.cpp
index 89dbfbe28d1..7ab861e7c8a 100644
--- a/engines/nancy/action/primaryvideo.cpp
+++ b/engines/nancy/action/primaryvideo.cpp
@@ -31,7 +31,6 @@
#include "engines/nancy/graphics.h"
#include "engines/nancy/action/primaryvideo.h"
-#include "engines/nancy/action/responses.cpp"
#include "engines/nancy/state/scene.h"
@@ -281,7 +280,7 @@ void PlayPrimaryVideoChan0::execute() {
// Add responses when conditions have been satisfied
if (_conditionalResponseCharacterID != 10) {
- addConditionalResponses();
+ addConditionalDialogue();
}
if (_goodbyeResponseCharacterID != 10) {
@@ -374,15 +373,54 @@ void PlayPrimaryVideoChan0::handleInput(NancyInput &input) {
}
}
-void PlayPrimaryVideoChan0::addConditionalResponses() {
- for (const auto &res : nancy1ConditionalResponses) {
- if (res.characterID == _conditionalResponseCharacterID) {
+void PlayPrimaryVideoChan0::addConditionalDialogue() {
+ for (const auto &res : g_nancy->getStaticData().conditionalDialogue[_conditionalResponseCharacterID]) {
+ bool isSatisfied = true;
+
+ for (const auto &cond : res.flagConditions) {
+ if (!NancySceneState.getEventFlag(cond.label, cond.flag)) {
+ isSatisfied = false;
+ break;
+ }
+ }
+
+ for (const auto &cond : res.inventoryConditions) {
+ if (NancySceneState.hasItem(cond.label) != cond.flag) {
+ isSatisfied = false;
+ break;
+ }
+ }
+
+ if (isSatisfied) {
+ _responses.push_back(ResponseStruct());
+ ResponseStruct &newResponse = _responses.back();
+ newResponse.soundName = res.soundID;
+ newResponse.text = g_nancy->getStaticData().conditionalDialogueTexts[res.textID];
+ newResponse.sceneChange.sceneID = res.sceneID;
+ newResponse.sceneChange.doNotStartSound = true;
+ }
+ }
+}
+
+void PlayPrimaryVideoChan0::addGoodbye() {
+ auto &res = g_nancy->getStaticData().goodbyes[_goodbyeResponseCharacterID];
+ _responses.push_back(ResponseStruct());
+ ResponseStruct &newResponse = _responses.back();
+ newResponse.soundName = res.soundID;
+ newResponse.text = g_nancy->getStaticData().goodbyeTexts[_goodbyeResponseCharacterID];
+
+ // Evaluate conditions to pick from the collection of replies
+ uint sceneChangeID;
+ for (uint i = 0; i < res.sceneChanges.size(); ++i) {
+ const GoodbyeSceneChange &sc = res.sceneChanges[i];
+ if (sc.flagConditions.size() == 0) {
+ // No conditions, default choice
+ sceneChangeID = i;
+ break;
+ } else {
bool isSatisfied = true;
- for (const auto & cond : res.conditions) {
- if (cond.label == -1) {
- break;
- }
+ for (const auto &cond : sc.flagConditions) {
if (!NancySceneState.getEventFlag(cond.label, cond.flag)) {
isSatisfied = false;
break;
@@ -390,49 +428,21 @@ void PlayPrimaryVideoChan0::addConditionalResponses() {
}
if (isSatisfied) {
- Common::File file;
- char snd[9];
-
- file.open("game.exe");
- file.seek(nancy1ResponseBaseFileOffset + res.fileOffset);
- file.read(snd, 8);
- snd[8] = '\0';
-
- _responses.push_back(ResponseStruct());
- ResponseStruct &newResponse = _responses.back();
- newResponse.soundName = snd;
- newResponse.text = file.readString();
- newResponse.sceneChange.sceneID = res.sceneID;
- newResponse.sceneChange.doNotStartSound = true;
-
- file.close();
+ sceneChangeID = i;
+ break;
}
}
}
-}
-void PlayPrimaryVideoChan0::addGoodbye() {
- for (const auto &res : nancy1Goodbyes) {
- if (res.characterID == _goodbyeResponseCharacterID) {
- Common::File file;
- char snd[9];
+ const GoodbyeSceneChange &sceneChange = res.sceneChanges[sceneChangeID];
+
+ // The reply from the character is picked randomly
+ newResponse.sceneChange.sceneID = sceneChange.sceneIDs[g_nancy->_randomSource->getRandomNumber(sceneChange.sceneIDs.size() - 1)];
- file.open("game.exe");
- file.seek(nancy1ResponseBaseFileOffset + res.fileOffset);
- file.read(snd, 8);
- snd[8] = '\0';
+ // Set an event flag if applicable
+ NancySceneState.setEventFlag(sceneChange.flagToSet);
- _responses.push_back(ResponseStruct());
- ResponseStruct &newResponse = _responses.back();
- newResponse.soundName = snd;
- newResponse.text = file.readString();
- // response is picked randomly
- newResponse.sceneChange.sceneID = res.sceneIDs[g_nancy->_randomSource->getRandomNumber(3)];
- newResponse.sceneChange.doNotStartSound = true;
-
- file.close();
- }
- }
+ newResponse.sceneChange.doNotStartSound = true;
}
} // End of namespace Action
diff --git a/engines/nancy/action/primaryvideo.h b/engines/nancy/action/primaryvideo.h
index 03aca322a0f..99602ab015d 100644
--- a/engines/nancy/action/primaryvideo.h
+++ b/engines/nancy/action/primaryvideo.h
@@ -81,7 +81,7 @@ public:
void handleInput(NancyInput &input) override;
// Functions for handling the built-in dialogue responses found in the executable
- void addConditionalResponses();
+ void addConditionalDialogue();
void addGoodbye();
Common::String _videoName;
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index 5379bebdca8..99e69469921 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -27,7 +27,6 @@
#include "engines/nancy/util.h"
#include "engines/nancy/action/recordtypes.h"
-#include "engines/nancy/action/responses.cpp"
#include "engines/nancy/state/scene.h"
@@ -672,14 +671,11 @@ void HintSystem::readData(Common::SeekableReadStream &stream) {
void HintSystem::execute() {
switch (_state) {
case kBegin:
- if (NancySceneState.getHintsRemaining() > 0) {
- selectHint();
- } else {
- getHint(0, NancySceneState.getDifficulty());
- }
+ selectHint();
+ _genericSound.name = selectedHint->soundIDs[NancySceneState.getDifficulty()];
NancySceneState.getTextbox().clear();
- NancySceneState.getTextbox().addTextLine(_text);
+ NancySceneState.getTextbox().addTextLine(g_nancy->getStaticData().hintTexts[selectedHint->textID + NancySceneState.getDifficulty()]);
g_nancy->_sound->loadSound(_genericSound);
g_nancy->_sound->playSound(_genericSound);
@@ -695,10 +691,10 @@ void HintSystem::execute() {
// fall through
case kActionTrigger:
- NancySceneState.useHint(_hintID, _hintWeight);
+ NancySceneState.useHint(_characterID, _hintID);
NancySceneState.getTextbox().clear();
- NancySceneState.changeScene(_sceneChange);
+ NancySceneState.changeScene(selectedHint->sceneChange);
_isDone = true;
break;
@@ -706,10 +702,13 @@ void HintSystem::execute() {
}
void HintSystem::selectHint() {
- for (const auto &hint : nancy1Hints) {
- if (hint.characterID != _characterID) {
- continue;
- }
+ if (NancySceneState.getHintsRemaining() == 0) {
+ selectedHint = &g_nancy->getStaticData().hints[_characterID][0];
+ }
+
+ // Start from 1 since the first hint is always the "I give up" option
+ for (uint i = 1; i < g_nancy->getStaticData().hints[_characterID].size(); ++i) {
+ const auto &hint = g_nancy->getStaticData().hints[_characterID][i];
bool satisfied = true;
@@ -724,7 +723,7 @@ void HintSystem::selectHint() {
}
}
- for (const auto &inv : hint.inventoryCondition) {
+ for (const auto &inv : hint.inventoryConditions) {
if (inv.label == -1) {
break;
}
@@ -736,44 +735,11 @@ void HintSystem::selectHint() {
}
if (satisfied) {
- getHint(hint.hintID, NancySceneState.getDifficulty());
+ selectedHint = &hint;
break;
}
}
}
-void HintSystem::getHint(uint hint, uint difficulty) {
- uint fileOffset = 0;
- if (_characterID < 3) {
- fileOffset = nancy1HintOffsets[_characterID];
- }
-
- fileOffset += 0x288 * hint;
-
- Common::File file;
- file.open("game.exe");
- file.seek(fileOffset);
-
- _hintID = file.readSint16LE();
- _hintWeight = file.readSint16LE();
-
- file.seek(difficulty * 10, SEEK_CUR);
-
- readFilename(file, _genericSound.name);
-
- file.seek(-(difficulty * 10) - 10, SEEK_CUR);
- file.seek(30 + difficulty * 200, SEEK_CUR);
-
- char textBuf[200];
- file.read(textBuf, 200);
- textBuf[199] = '\0';
- _text = textBuf;
-
- file.seek(-(difficulty * 200) - 200, SEEK_CUR);
- file.seek(600, SEEK_CUR);
-
- _sceneChange.readData(file);
-}
-
} // End of namespace Action
} // End of namespace Nancy
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index 0e0cf611e53..6eeef3c0694 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -508,13 +508,10 @@ public:
byte _characterID; // 0x00
SoundDescription _genericSound; // 0x01
- Common::String _text;
- SceneChangeDescription _sceneChange;
- uint16 _hintID;
- int16 _hintWeight;
+ const Hint *selectedHint;
+ int16 _hintID;
void selectHint();
- void getHint(uint hint, uint difficulty);
protected:
Common::String getRecordTypeName() const override { return "HintSystem"; }
diff --git a/engines/nancy/action/responses.cpp b/engines/nancy/action/responses.cpp
deleted file mode 100644
index 5be91e8d6d1..00000000000
--- a/engines/nancy/action/responses.cpp
+++ /dev/null
@@ -1,956 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "engines/nancy/commontypes.h"
-
-namespace Nancy {
-namespace Action {
-
-// For whatever reason the games don't use the conditional dialogue code
-// inside primary video, and instead have a bunch of functions that manually
-// check hardcoded event flag IDs and extract strings embedded inside the exe.
-// These tables contain the extracted data and offsets for the string data, but if
-// there happen to be many versions of the same game it might be a better idea to just
-// directly copy the dialogue strings in here.
-
-struct ConditionalResponseDesc {
- byte characterID; // 0: Daryl, 1: Connie, 2: Hal, 3: Hulk
- uint fileOffset;
- uint16 sceneID;
- EventFlagDescription conditions[7];
-};
-
-struct GoodbyeDesc {
- byte characterID;
- uint fileOffset;
- uint16 sceneIDs[4];
-};
-
-struct HintDesc {
- byte characterID; // 0: Ned, 1: Bess, 2: George
- byte hintID;
- EventFlagDescription flagConditions[4];
- EventFlagDescription inventoryCondition[2];
-};
-
-static const uint nancy1ResponseBaseFileOffset = 0xB1FE0; // TODO there could be more than one version of the exe
-static const uint nancy1HintOffsets[] = { 0xABB88, 0xAD760, 0xAF338 }; // Ned, Bess, George
-
-#define EMPTY_DESC { -1, kFalse }
-
-static const GoodbyeDesc nancy1Goodbyes[] = {
- // Daryl
- {
- 0,
- 0x11B0,
- { 0xC94, 0xC95, 0xC96, 0xC97}
- },
-
- // Connie
- {
- 1,
- 0x11D8,
- { 0xFC, 0x9D8, 0x9D9, 0x9DB }
- },
-
- // Hal
- {
- 2,
- 0x11FC,
- { 0x1C3, 0x1C4, 0x1C5, 0x1C6}
- },
-
- // Hulk
- {
- 3,
- 0x1228,
- { 0xCE2, 0xCE0, 0xCE2, 0xCE0 } // only two responses
- }
-};
-
-static const ConditionalResponseDesc nancy1ConditionalResponses[] = {
- // Daryl
- {
- 0,
- 0x840,
- 0x7C,
- {
- { 0x1D, kTrue },
- { 0x39, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x804,
- 0x7F,
- {
- { 0x13, kTrue },
- { 0x37, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x7BC,
- 0x81,
- {
- { 0xB, kTrue },
- { 0x38, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x750,
- 0x83,
- {
- { 0, kTrue },
- { 1, kFalse },
- { 0x6B, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x6F4,
- 0x84,
- {
- { 0x64, kTrue },
- { 0x1E, kFalse },
- { 0x14, kFalse },
- { 0xC, kFalse },
- { 0x6C, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x5EC,
- 0x86,
- {
- { 0x6D, kFalse },
- { 0x6, kTrue },
- { 0x8, kTrue },
- { 0x5E, kTrue },
- { 0x17, kTrue },
- { 0x24, kTrue },
- { 0x9, kTrue }
- }
- },
-
- {
- 0,
- 0x554,
- 0x8B,
- {
- { 0x6E, kFalse },
- { 0x24, kTrue },
- { 0x9, kTrue },
- { 0x5E, kFalse },
- { 0x8, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x4F0,
- 0x8D,
- {
- { 0x6F, kFalse },
- { 0x5E, kTrue },
- { 0x24, kTrue },
- { 0x9, kTrue },
- { 0x8, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x458,
- 0x8F,
- {
- { 0x70, kFalse },
- { 0x24, kTrue },
- { 0x9, kTrue },
- { 0x6, kTrue },
- { 0x8, kTrue },
- { 0x5E, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x3BC,
- 0x90,
- {
- { 0x71, kFalse },
- { 0x5E, kTrue },
- { 0x24, kFalse },
- { 0x8, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x320,
- 0x91,
- {
- { 0x72, kFalse },
- { 0x5E, kTrue },
- { 0x8, kTrue },
- { 0x6, kTrue },
- { 0x24, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x2AC,
- 0x92,
- {
- { 0x73, kFalse },
- { 0x8, kTrue },
- { 0x6, kTrue },
- { 0x5E, kFalse },
- { 0x24, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x1F0,
- 0x96,
- {
- { 0x74, kFalse },
- { 0x1D, kTrue },
- { 0x13, kTrue },
- { 0xB, kTrue },
- { 0x5E, kFalse },
- { 0x24, kFalse },
- { 0x8, kFalse }
- }
- },
-
- {
- 0,
- 0x190,
- 0x97,
- {
- { 0x27, kFalse },
- { 0x5, kTrue },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0xF0,
- 0x9C,
- {
- { 0x28, kTrue },
- { 0x75, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x94,
- 0x93,
- {
- { 0xC, kFalse },
- { 0x6, kTrue },
- { 0x76, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0x58,
- 0x94,
- {
- { 0x14, kFalse },
- { 0x4, kTrue },
- { 0x77, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 0,
- 0x95,
- {
- { 0x1E, kFalse },
- { 0x63, kTrue },
- { 0x78, kFalse },
- EMPTY_DESC
- }
- },
-
- // Connie
- {
- 1,
- 0xBE4,
- 0xE9,
- {
- { 0x1D, kTrue },
- { 0x18, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0xB8C,
- 0xEA,
- {
- { 0x1F, kTrue },
- { 0x19, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0xB54,
- 0xEB,
- {
- { 0xB, kTrue },
- { 0x1A, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0xB14,
- 0xEC,
- {
- { 0x26, kTrue },
- { 0x1C, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0xABC,
- 0xED,
- {
- { 0, kTrue },
- { 1, kFalse },
- { 0x79, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0xA00,
- 0xEE,
- {
- { 2, kTrue },
- { 3, kTrue },
- { 0x17, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0x6F4,
- 0xEF,
- {
- { 0x64, kTrue },
- { 0x16, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0x968,
- 0xF0,
- {
- { 0x5, kTrue },
- { 0x14, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0x8C8,
- 0xF5,
- {
- { 0x28, kTrue },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 0x884,
- 0xE7,
- {
- { 0xD, kTrue },
- { 0x5E, kFalse },
- EMPTY_DESC
- }
- },
-
- // Hal
- {
- 2,
- 0xED0,
- 0x1B3,
- {
- { 0x1D, kTrue },
- { 0x11, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0x804,
- 0x1B5,
- {
- { 0x13, kTrue },
- { 0xE, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0xE74,
- 0x1B6,
- {
- { 0x1B, kTrue },
- { 0xF, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0xE2C,
- 0x1B7,
- {
- { 0x26, kTrue },
- { 0x10, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0xDD4,
- 0x1B9,
- {
- { 0, kTrue },
- { 1, kFalse },
- { 0x68, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0xD48,
- 0x1BA,
- {
- { 0, kTrue },
- { 1, kFalse },
- { 0x20, kTrue },
- { 0x69, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0x6F4,
- 0x1BB,
- {
- { 0x6A, kFalse },
- { 0x64, kTrue },
- { 0x5, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0xCC8,
- 0x1BC,
- {
- { 0x8, kTrue },
- { 0x6, kTrue },
- { 0xC, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 0xC2C,
- 0x1BE,
- {
- { 0x28, kTrue },
- EMPTY_DESC
- }
- },
-
- // Hulk
- {
- 3,
- 0x1164,
- 0x14D,
- {
- { 0x13, kTrue },
- { 0x3A, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 3,
- 0xB54,
- 0x150,
- {
- { 0xB, kTrue },
- { 0x25, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 3,
- 0x10D8,
- 0x153,
- {
- { 0x12, kTrue },
- { 0x21, kFalse },
- EMPTY_DESC
- }
- },
-
- {
-
- 3,
- 0xE2C,
- 0x154,
- {
- { 0x26, kTrue },
- { 0x22, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 3,
- 0x108C,
- 0x155,
- {
- { 0, kTrue },
- { 1, kFalse },
- { 0x66, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 3,
- 0x6F4,
- 0x156,
- {
- { 0x67, kFalse },
- { 0x64, kTrue },
- EMPTY_DESC
- }
- },
-
- {
- 3,
- 0x1028,
- 0x157,
- {
- { 0x63, kTrue },
- { 0x24, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 3,
- 0xFB0,
- 0x158,
- {
- { 0x5, kTrue },
- { 0x1E, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 3,
- 0xF10,
- 0x159,
- {
- { 0x28, kTrue },
- EMPTY_DESC
- }
- }
-};
-
-static const HintDesc nancy1Hints[] {
- // Ned
- {
- 0,
- 1,
- {
- { 0, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 2,
- {
- { 0, kTrue },
- { 1, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 3,
- {
- { 1, kFalse },
- EMPTY_DESC
- },
- {
- { 3, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 4,
- {
- { 0x55, kFalse },
- EMPTY_DESC
- },
- {
- { 3, kTrue },
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 5,
- {
- { 0x55, kTrue },
- { 0x56, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 6,
- {
- { 0x57, kFalse },
- { 0x56, kTrue },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 0,
- 8,
- {
- { 0xA, kTrue },
- { 0x3B, kTrue },
- EMPTY_DESC
- },
- {
- { 7, kFalse },
- EMPTY_DESC
- }
- },
-
- // Bess
- {
- 1,
- 1,
- {
- { 0x57, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 2,
- {
- { 0x57, kTrue },
- { 0x3C, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 3,
- {
- { 0x5A, kFalse },
- { 0x3C, kTrue },
- { 0x56, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 4,
- {
- { 0x5A, kTrue },
- { 0x56, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 6,
- {
- { 0x5A, kFalse },
- { 0x3C, kTrue },
- { 0x56, kTrue },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 7,
- {
- { 0x59, kTrue },
- { 0xA, kFalse },
- EMPTY_DESC
- },
- {
- { 0, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 1,
- 8,
- {
- { 0xA, kTrue },
- { 0x3B, kTrue },
- EMPTY_DESC
- },
- {
- { 0, kTrue },
- { 7, kFalse }
- }
- },
-
- {
- 1,
- 9,
- {
- { 0x59, kFalse },
- { 0xA, kTrue },
- { 0x3B, kTrue },
- EMPTY_DESC
- },
- {
- { 7, kFalse },
- EMPTY_DESC
- }
- },
-
- // George
- {
- 2,
- 0xA,
- {
- { 0x4A, kTrue },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 1,
- {
- { 0x5B, kFalse },
- EMPTY_DESC
- },
- {
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 2,
- {
- { 0x5B, kTrue },
- EMPTY_DESC
- },
- {
- { 9, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 3,
- {
- { 0x5B, kTrue },
- { 0x5C, kFalse },
- { 0x5D, kFalse },
- EMPTY_DESC
- },
- {
- { 9, kTrue },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 4,
- {
- { 0x5B, kTrue },
- { 0x5C, kTrue },
- { 0x5D, kFalse },
- EMPTY_DESC
- },
- {
- { 9, kFalse },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 5,
- {
- { 0x5B, kTrue },
- { 0x5C, kTrue },
- { 0x5D, kTrue },
- { 0x3B, kFalse }
- },
- {
- { 9, kTrue },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 6,
- {
- { 0xA, kFalse },
- { 0x3B, kTrue },
- EMPTY_DESC
- },
- {
- { 9, kTrue },
- EMPTY_DESC
- }
- },
-
- {
- 2,
- 7,
- {
- { 0x3B, kTrue },
- { 0xA, kTrue },
- EMPTY_DESC
- },
- {
- { 7, kFalse },
- EMPTY_DESC
- }
- }
-};
-
-} // End of namespace Action
-} // End of namespace Nancy
diff --git a/engines/nancy/dialogueresponses.cpp b/engines/nancy/dialogueresponses.cpp
deleted file mode 100644
index 981f33de723..00000000000
--- a/engines/nancy/dialogueresponses.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "engines/nancy/nancy.h"
-#include "engines/nancy/dialogueresponses.h"
-
-#include "engines/nancy/state/scene.h"
-
-namespace Nancy {
-
-struct ResponseInFile {
- uint address;
- uint scene;
-};
-
-static const ResponseInFile nancy1ResponsesDaryl[] = {
- { 0xB2820, 0x7C },
- { 0xB27E4, 0x7F },
- { 0xB279C, 0x81 },
- { 0xB2730, 0x83 },
- { 0xB26D4, 0x84 },
- { 0xB25CC, 0x86 },
- { 0xB2534, 0x8B },
- { 0xB24D0, 0x8D },
- { 0xB2438, 0x8F },
- { 0xB239C, 0x90 },
- { 0xB2300, 0x91 },
- { 0xB228C, 0x92 },
- { 0xB21D0, 0x96 },
- { 0xB2170, 0x97 },
- { 0xB20D0, 0x9C },
- { 0xB2074, 0x93 },
- { 0xB2038, 0x94 },
- { 0xB1FE0, 0x95 }
-};
-
-static const ResponseInFile nancy1ResponsesConnie[] = {
- { 0xB2BC4, 0xE9 },
- { 0xB2B6C, 0xEA },
- { 0xB2B34, 0xEB },
- { 0xB2AF4, 0xEC },
- { 0xB2A9C, 0xED },
- { 0xB29E0, 0xEE },
- { 0xB26D4, 0xEF },
- { 0xB2948, 0xF0 },
- { 0xB28A8, 0xF5 },
- { 0xB2864, 0xE7 }
-};
-
-static const ResponseInFile nancy1ResponsesHal[] = {
- { 0xB2EB0, 0x1B3 },
- { 0xB27E4, 0x1B5 },
- { 0xB2E54, 0x1B6 },
- { 0xB2E0C, 0x1B7 },
- { 0xB2DB4, 0x1B9 },
- { 0xB2D28, 0x1BA },
- { 0xB26D4, 0x1BB },
- { 0xB2CA8, 0x1BC },
- { 0xB2C0C, 0x1BE }
-};
-
-static const ResponseInFile nancy1ResponsesHulk[] = {
- { 0xB3144, 0x14D },
- { 0xB2B34, 0x150 },
- { 0xB30B8, 0x153 },
- { 0xB2E0C, 0x154 },
- { 0xB306C, 0x155 },
- { 0xB26D4, 0x156 },
- { 0xB3008, 0x157 },
- { 0xB2F90, 0x158 },
- { 0xB2EF0, 0x159 }
-};
-
-#define ADD_RESPONSE(x) responses.push_back(PlayerResponse()); responses.back().sceneChange.sceneID = x.scene; responses.back().sceneChange.doNotStartSound = true; addresses.push_back(x.address);
-
-const Common::Array<PlayerResponse> getResponsesNancy1(uint characterID) {
- Common::Array<PlayerResponse> responses;
- Common::Array<uint> addresses;
- State::Scene &scene = NancySceneState;
-
- switch (characterID) {
- case 0: // Daryl
- if ( scene.getEventFlag(0x1D, kTrue) &&
- scene.getEventFlag(0x39, kFalse)) {
- ADD_RESPONSE(nancy1ResponsesDaryl[0])
- }
-
- if ( scene.getEventFlag(0x13, kTrue) &&
- scene.getEventFlag(0x37, kFalse)) {
- ADD_RESPONSE(nancy1ResponsesDaryl[1])
- }
-
- if ( scene.getEventFlag(0xB, kTrue) &&
- scene.getEventFlag(0x38, kFalse)) {
- ADD_RESPONSE(nancy1ResponsesDaryl[2])
- }
-
- if ( scene.getEventFlag(0, kTrue) &&
- scene.getEventFlag(1, kFalse) &&
- scene.getEventFlag(0x68, kFalse)) {
- ADD_RESPONSE(nancy1ResponsesDaryl[3])
- }
-
-
-
- break;
- case 1: // Connie
-
- break;
- case 2: // Hal
-
- break;
- case 3: // Hulk
-
- break;
- }
-
- return responses;
-}
-
-const Common::Array<PlayerResponse> getResponses(const uint characterID) {
- switch (g_nancy->getGameType()) {
- case kGameTypeNancy1:
- return getResponsesNancy1(characterID);
- default:
- return Common::Array<PlayerResponse>();
- }
-}
-
-} // End of namespace Nancy
diff --git a/engines/nancy/dialogueresponses.h b/engines/nancy/dialogueresponses.h
deleted file mode 100644
index 38c802d4e2c..00000000000
--- a/engines/nancy/dialogueresponses.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef NANCY_DIALOGUERESPONSES_H
-#define NANCY_DIALOGUERESPONSES_H
-
-#include "engines/nancy/commontypes.h"
-
-namespace Nancy {
-
-struct PlayerResponse {
- Common::String text;
- Common::String soundName;
- SceneChangeDescription sceneChange;
-};
-
-const Common::Array<PlayerResponse> getResponses(const uint characterID);
-
-} // End of namespace Nancy
-
-#endif // NANCY_DIALOGUERESPONSES_H
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index 19099cf2994..d48a9a010ef 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -52,7 +52,7 @@ class Serializer;
*/
namespace Nancy {
-static const int kSavegameVersion = 1;
+static const int kSavegameVersion = 2;
struct NancyGameDescription;
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 69a3c717638..152098df169 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -93,7 +93,8 @@ void Scene::SceneSummary::read(Common::SeekableReadStream &stream) {
Scene::Scene() :
_state (kInit),
- _lastHint(-1),
+ _lastHintCharacter(-1),
+ _lastHintID(-1),
_gameStateRequested(NancyState::kNone),
_frame(),
_viewport(),
@@ -277,10 +278,11 @@ void Scene::clearLogicConditions() {
}
}
-void Scene::useHint(int hintID, int hintWeight) {
- if (_lastHint != hintID) {
- _hintsRemaining[_difficulty] += hintWeight;
- _lastHint = hintID;
+void Scene::useHint(uint16 characterID, uint16 hintID) {
+ if (_lastHintID != hintID || _lastHintCharacter != characterID) {
+ _hintsRemaining[_difficulty] += g_nancy->getStaticData().hints[characterID][hintID].hintWeight;
+ _lastHintCharacter = characterID;
+ _lastHintID = hintID;
}
}
@@ -385,7 +387,9 @@ void Scene::synchronize(Common::Serializer &ser) {
ser.syncAsUint16LE(_difficulty);
ser.syncArray<uint16>(_hintsRemaining.data(), _hintsRemaining.size(), Common::Serializer::Uint16LE);
- ser.syncAsSint16LE(_lastHint);
+
+ ser.syncAsSint16LE(_lastHintCharacter);
+ ser.syncAsSint16LE(_lastHintID);
// Synchronize SliderPuzzle static data
ser.syncAsByte(_sliderPuzzleState.playerHasTriedPuzzle);
@@ -445,7 +449,7 @@ void Scene::init() {
_hintsRemaining.push_back(chunk->readByte());
}
- _lastHint = -1;
+ _lastHintCharacter = _lastHintID = -1;
}
_sliderPuzzleState.playerHasTriedPuzzle = false;
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 76a07d96884..788a53c52af 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -146,7 +146,7 @@ public:
uint16 getDifficulty() const { return _difficulty; }
byte getHintsRemaining() const { return _hintsRemaining[_difficulty]; }
- void useHint(int hintID, int hintWeight);
+ void useHint(uint16 characterID, uint16 hintID);
void requestStateChange(NancyState::NancyState state) { _gameStateRequested = state; }
void resetStateToInit() { _state = kInit; }
@@ -252,7 +252,8 @@ private:
SliderPuzzleState _sliderPuzzleState;
uint16 _difficulty;
Common::Array<uint16> _hintsRemaining;
- int16 _lastHint;
+ int16 _lastHintCharacter;
+ int16 _lastHintID;
NancyState::NancyState _gameStateRequested;
Common::Rect _mapHotspot;
Commit: 900e4666c02f094549848676d89518744dab0bb1
https://github.com/scummvm/scummvm/commit/900e4666c02f094549848676d89518744dab0bb1
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:58+02:00
Commit Message:
NANCY: Upgrade debug console
Added several new console commands and made changes to
existing ones in preparation of the removal of the Cheat dialogs.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/action/actionmanager.h
engines/nancy/action/actionrecord.h
engines/nancy/console.cpp
engines/nancy/console.h
engines/nancy/graphics.cpp
engines/nancy/graphics.h
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 68da5f248fe..200dab318dd 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -146,89 +146,6 @@ bool ActionManager::addNewActionRecord(Common::SeekableReadStream &inputData) {
_records.push_back(newRecord);
- debugC(1, kDebugActionRecord, "Loaded action record %i, type %s, typeID %i, description \"%s\", execType == %s",
- _records.size() - 1,
- newRecord->getRecordTypeName().c_str(),
- newRecord->_type,
- newRecord->_description.c_str(),
- newRecord->_execType == ActionRecord::kRepeating ? "kRepeating" : "kOneShot");
- for (uint i = 0; i < newRecord->_dependencies.size(); ++i) {
- debugCN(1, kDebugActionRecord, "\tDependency %i: type ", i);
- DependencyRecord &dep = newRecord->_dependencies[i];
- switch (dep.type) {
- case DependencyType::kNone :
- debugCN(1, kDebugActionRecord, "kNone");
- break;
- case DependencyType::kInventory :
- debugCN(1, kDebugActionRecord, "kInventory, item ID %i %s",
- dep.label,
- dep.condition == kTrue ? "is in possession" : "is not in possession");
- break;
- case DependencyType::kEventFlag :
- debugCN(1, kDebugActionRecord, "kEventFlag, flag ID %i == %s",
- dep.label,
- dep.condition == kTrue ? "true" : "false");
- break;
- case DependencyType::kLogicCondition :
- debugCN(1, kDebugActionRecord, "kLogicCondition, logic condition ID %i == %s",
- dep.label,
- dep.condition == kTrue ? "true" : "false");
- break;
- case DependencyType::kTotalTime :
- debugCN(1, kDebugActionRecord, "kTotalTime, %i hours, %i minutes, %i seconds, %i milliseconds",
- dep.hours,
- dep.minutes,
- dep.seconds,
- dep.milliseconds);
- break;
- case DependencyType::kSceneTime :
- debugCN(1, kDebugActionRecord, "kSceneTime, %i hours, %i minutes, %i seconds, %i milliseconds",
- dep.hours,
- dep.minutes,
- dep.seconds,
- dep.milliseconds);
- break;
- case DependencyType::kPlayerTime :
- debugCN(1, kDebugActionRecord, "kPlayerTime, %i days, %i hours, %i minutes, %i seconds",
- dep.hours,
- dep.minutes,
- dep.seconds,
- dep.milliseconds);
- break;
- case DependencyType::kSceneCount :
- debugCN(1, kDebugActionRecord, "kSceneCount, scene ID %i, hit count %s %i",
- dep.hours,
- dep.milliseconds == 1 ? ">" : dep.milliseconds == 2 ? "<" : "==",
- dep.seconds);
- break;
- case DependencyType::kResetOnNewDay :
- debugCN(1, kDebugActionRecord, "kResetOnNewDay");
- break;
- case DependencyType::kUseItem :
- debugCN(1, kDebugActionRecord, "kUseItem, item ID %i %s",
- dep.label,
- dep.condition == kTrue ? "is held" : "is not held");
- break;
- case DependencyType::kTimeOfDay :
- debugCN(1, kDebugActionRecord, "kTimeOfDay, %s",
- dep.label == 0 ? "day" : dep.label == 1 ? "night" : "dusk/dawn");
- break;
- case DependencyType::kTimerNotDone :
- debugCN(1, kDebugActionRecord, "kTimerNotDone");
- break;
- case DependencyType::kTimerDone :
- debugCN(1, kDebugActionRecord, "kTimerDone");
- break;
- case DependencyType::kDifficultyLevel :
- debugCN(1, kDebugActionRecord, "kDifficultyLevel, level %i", dep.condition);
- break;
- default:
- debugCN(1, kDebugActionRecord, "unknown");
- break;
- }
- debugC(1, kDebugActionRecord, ", orFlag == %s", dep.orFlag == true ? "true" : "false");
- }
-
return true;
}
diff --git a/engines/nancy/action/actionmanager.h b/engines/nancy/action/actionmanager.h
index 115806b88d7..f099602f241 100644
--- a/engines/nancy/action/actionmanager.h
+++ b/engines/nancy/action/actionmanager.h
@@ -32,6 +32,7 @@ class SeekableReadStream;
namespace Nancy {
class NancyEngine;
+class NancyConsole;
struct NancyInput;
namespace State {
@@ -45,6 +46,7 @@ class ActionRecord;
// The class that handles ActionRecords and their execution
class ActionManager {
friend class Nancy::State::Scene;
+ friend class Nancy::NancyConsole;
public:
ActionManager() {}
diff --git a/engines/nancy/action/actionrecord.h b/engines/nancy/action/actionrecord.h
index 9b5006669be..9f693be5699 100644
--- a/engines/nancy/action/actionrecord.h
+++ b/engines/nancy/action/actionrecord.h
@@ -32,6 +32,7 @@ class SeekableReadStream;
namespace Nancy {
class NancyEngine;
+class NancyConsole;
struct NancyInput;
namespace Action {
@@ -78,6 +79,8 @@ struct DependencyRecord {
// will have to also subclass RenderObject.
class ActionRecord {
friend class ActionManager;
+ friend class Nancy::NancyConsole;
+
public:
enum ExecutionState { kBegin, kRun, kActionTrigger };
enum ExecutionType { kOneShot = 1, kRepeating = 2 };
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 4a5ed89c051..60e2d00df14 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -34,6 +34,8 @@
#include "engines/nancy/state/scene.h"
+#include "engines/nancy/action/actionrecord.h"
+
namespace Nancy {
NancyConsole::NancyConsole() : GUI::Debugger() {
@@ -49,10 +51,18 @@ NancyConsole::NancyConsole() : GUI::Debugger() {
registerCmd("play_audio", WRAP_METHOD(NancyConsole, Cmd_playAudio));
registerCmd("load_scene", WRAP_METHOD(NancyConsole, Cmd_loadScene));
registerCmd("scene_id", WRAP_METHOD(NancyConsole, Cmd_sceneID));
+ registerCmd("list_actionrecords", WRAP_METHOD(NancyConsole, Cmd_listAcionRecords));
+ registerCmd("get_eventflags", WRAP_METHOD(NancyConsole, Cmd_getEventFlags));
+ registerCmd("set_eventflags", WRAP_METHOD(NancyConsole, Cmd_setEventFlags));
+ registerCmd("get_inventory", WRAP_METHOD(NancyConsole, Cmd_getInventory));
+ registerCmd("set_inventory", WRAP_METHOD(NancyConsole, Cmd_setInventory));
+ registerCmd("get_player_time", WRAP_METHOD(NancyConsole, Cmd_getPlayerTime));
+ registerCmd("set_player_time", WRAP_METHOD(NancyConsole, Cmd_setPlayerTime));
+ registerCmd("get_difficulty", WRAP_METHOD(NancyConsole, Cmd_getDifficulty));
+ registerCmd("set_difficulty", WRAP_METHOD(NancyConsole, Cmd_setDifficulty));
}
-NancyConsole::~NancyConsole() {
-}
+NancyConsole::~NancyConsole() {}
void NancyConsole::postEnter() {
GUI::Debugger::postEnter();
@@ -60,6 +70,12 @@ void NancyConsole::postEnter() {
Video::VideoDecoder *dec = new AVFDecoder;
if (dec->loadFile(_videoFile)) {
+ Graphics::ManagedSurface surf;
+
+ if (_paletteFile.size()) {
+ GraphicsManager::loadSurfacePalette(surf, _paletteFile);
+ }
+
dec->start();
Common::EventManager *ev = g_system->getEventManager();
while (!g_nancy->shouldQuit() && !dec->endOfVideo()) {
@@ -73,7 +89,8 @@ void NancyConsole::postEnter() {
if (dec->needsUpdate()) {
const Graphics::Surface *frame = dec->decodeNextFrame();
if (frame) {
- g_nancy->_graphicsManager->debugDrawToScreen(*frame);
+ GraphicsManager::copyToManaged(*frame, surf, _paletteFile.size());
+ g_nancy->_graphicsManager->debugDrawToScreen(surf);
}
}
@@ -86,14 +103,18 @@ void NancyConsole::postEnter() {
}
_videoFile.clear();
+ _paletteFile.clear();
delete dec;
}
if (!_imageFile.empty()) {
- Graphics::Surface surf;
+ Graphics::ManagedSurface surf;
if (g_nancy->_resource->loadImage(_imageFile, surf)) {
+ if (_paletteFile.size()) {
+ GraphicsManager::loadSurfacePalette(surf, _paletteFile);
+ }
+
g_nancy->_graphicsManager->debugDrawToScreen(surf);
- surf.free();
Common::EventManager *ev = g_system->getEventManager();
while (!g_nancy->shouldQuit()) {
@@ -115,6 +136,7 @@ void NancyConsole::postEnter() {
}
_imageFile.clear();
+ _paletteFile.clear();
}
// After calling the console, action end events get sent to it and the input manager
@@ -125,7 +147,7 @@ void NancyConsole::postEnter() {
bool NancyConsole::Cmd_cifHexDump(int argc, const char **argv) {
if (argc < 2 || argc > 3) {
debugPrintf("Dumps the specified resource to standard output\n");
- debugPrintf("Usage: %s name [cal]\n", argv[0]);
+ debugPrintf("Usage: %s <name> [cal]\n", argv[0]);
return true;
}
@@ -144,7 +166,7 @@ bool NancyConsole::Cmd_cifHexDump(int argc, const char **argv) {
bool NancyConsole::Cmd_cifExport(int argc, const char **argv) {
if (argc < 2 || argc > 3) {
debugPrintf("Exports the specified resource to .cif file\n");
- debugPrintf("Usage: %s name [cal]\n", argv[0]);
+ debugPrintf("Usage: %s <name> [cal]\n", argv[0]);
return true;
}
@@ -158,7 +180,7 @@ bool NancyConsole::Cmd_cifList(int argc, const char **argv) {
if (argc < 2 || argc > 3) {
debugPrintf("List resources of a certain type\n");
debugPrintf("Types - 0: all, 2: image, 3: script\n");
- debugPrintf("Usage: %s type [cal]\n", argv[0]);
+ debugPrintf("Usage: %s <type> [cal]\n", argv[0]);
return true;
}
@@ -178,7 +200,7 @@ bool NancyConsole::Cmd_cifList(int argc, const char **argv) {
bool NancyConsole::Cmd_cifInfo(int argc, const char **argv) {
if (argc < 2 || argc > 3) {
debugPrintf("Prints information about a resource\n");
- debugPrintf("Usage: %s name [cal]\n", argv[0]);
+ debugPrintf("Usage: %s <name> [cal]\n", argv[0]);
return true;
}
@@ -189,7 +211,7 @@ bool NancyConsole::Cmd_cifInfo(int argc, const char **argv) {
bool NancyConsole::Cmd_chunkHexDump(int argc, const char **argv) {
if (argc < 3 || argc > 4) {
debugPrintf("Hexdumps an IFF chunk\n");
- debugPrintf("Usage: %s iffname chunkname [index]\n", argv[0]);
+ debugPrintf("Usage: %s <iffname> <chunkname> [index]\n", argv[0]);
return true;
}
@@ -224,7 +246,7 @@ bool NancyConsole::Cmd_chunkHexDump(int argc, const char **argv) {
bool NancyConsole::Cmd_chunkList(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("List chunks inside an IFF\n");
- debugPrintf("Usage: %s iffname\n", argv[0]);
+ debugPrintf("Usage: %s <iffname>\n", argv[0]);
return true;
}
@@ -248,14 +270,51 @@ bool NancyConsole::Cmd_chunkList(int argc, const char **argv) {
}
bool NancyConsole::Cmd_showImage(int argc, const char **argv) {
- if (argc != 2) {
- debugPrintf("Draws an image on the screen\n");
- debugPrintf("Usage: %s name [cal]\n", argv[0]);
- return true;
+ if (g_nancy->getGameType() == kGameTypeVampire) {
+ if (argc != 3) {
+ debugPrintf("Draws an image on the screen\n");
+ debugPrintf("Usage: %s <name> <paletteFile>\n", argv[0]);
+ return true;
+ }
+
+ _imageFile = argv[1];
+ _paletteFile = argv[2];
+ return cmdExit(0, nullptr);
+ } else {
+ if (argc != 2) {
+ debugPrintf("Draws an image on the screen\n");
+ debugPrintf("Usage: %s <name>\n", argv[0]);
+ return true;
+ }
+
+ _imageFile = argv[1];
+ return cmdExit(0, nullptr);
}
+}
- _imageFile = argv[1];
- return cmdExit(0, nullptr);
+bool NancyConsole::Cmd_playVideo(int argc, const char **argv) {
+ if (g_nancy->getGameType() == kGameTypeVampire) {
+ if (argc != 3) {
+ debugPrintf("Plays a video\n");
+ debugPrintf("Usage: %s <name> <paletteFile>\n", argv[0]);
+ return true;
+ }
+
+ _videoFile = argv[1];
+ _videoFile += ".avf";
+ _paletteFile = argv[2];
+ return cmdExit(0, nullptr);
+ } else {
+ if (argc != 2) {
+ debugPrintf("Plays a video\n");
+ debugPrintf("Usage: %s <name>\n", argv[0]);
+ return true;
+ }
+
+ _videoFile = argv[1];
+ _videoFile += ".avf";
+ return cmdExit(0, nullptr);
+ }
}
bool NancyConsole::Cmd_loadCal(int argc, const char **argv) {
@@ -270,18 +329,6 @@ bool NancyConsole::Cmd_loadCal(int argc, const char **argv) {
return true;
}
-bool NancyConsole::Cmd_playVideo(int argc, const char **argv) {
- if (argc != 2) {
- debugPrintf("Plays a video\n");
- debugPrintf("Usage: %s <name>\n", argv[0]);
- return true;
- }
-
- _videoFile = argv[1];
- _videoFile += ".avf";
- return cmdExit(0, nullptr);
-}
-
bool NancyConsole::Cmd_playAudio(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Plays an audio file\n");
@@ -310,7 +357,7 @@ bool NancyConsole::Cmd_playAudio(int argc, const char **argv) {
bool NancyConsole::Cmd_loadScene(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Loads a scene\n");
- debugPrintf("Usage: %s sceneID\n", argv[0]);
+ debugPrintf("Usage: %s <sceneID>\n", argv[0]);
return true;
}
@@ -341,4 +388,340 @@ bool NancyConsole::Cmd_sceneID(int argc, const char **argv) {
return true;
}
+bool NancyConsole::Cmd_listAcionRecords(int argc, const char **argv) {
+ using namespace Nancy::Action;
+
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ Common::Array<ActionRecord *> &records = NancySceneState.getActionManager()._records;
+
+ debugPrintf("Scene %u has %u action records:\n\n", NancySceneState.getSceneInfo().sceneID, records.size());
+
+ for (ActionRecord *rec : records) {
+ debugPrintf("\n%s\n\ttype: %i, %s\n\texecType: %s",
+ rec->_description.c_str(),
+ rec->_type,
+ rec->getRecordTypeName().c_str(),
+ rec->_execType == ActionRecord::kRepeating ? "kRepeating" : "kOneShot");
+
+ if (rec->_dependencies.size()) {
+ debugPrintf("\n\tDependencies:");
+
+ for (DependencyRecord &dep : rec->_dependencies) {
+ debugPrintf("\n\t\t");
+ switch (dep.type) {
+ case DependencyType::kNone :
+ debugPrintf("kNone");
+ break;
+ case DependencyType::kInventory :
+ debugPrintf("kInventory, item %u, %s, %s",
+ dep.label,
+ g_nancy->getStaticData().itemNames[dep.label].c_str(),
+ dep.condition == kTrue ? "kTrue" : "kFalse");
+ break;
+ case DependencyType::kEventFlag :
+ debugPrintf("kEventFlag, flag %u, %s, %s",
+ dep.label,
+ g_nancy->getStaticData().eventFlagNames[dep.label].c_str(),
+ dep.condition == kTrue ? "kTrue" : "kFalse");
+ break;
+ case DependencyType::kLogicCondition :
+ debugPrintf("kLogicCondition, flag %u, %s",
+ dep.label,
+ dep.condition == kTrue ? "kTrue" : "kFalse");
+ break;
+ case DependencyType::kTotalTime :
+ debugPrintf("kTotalTime, %i hours, %i minutes, %i seconds, %i milliseconds",
+ dep.hours,
+ dep.minutes,
+ dep.seconds,
+ dep.milliseconds);
+ break;
+ case DependencyType::kSceneTime :
+ debugPrintf("kSceneTime, %i hours, %i minutes, %i seconds, %i milliseconds",
+ dep.hours,
+ dep.minutes,
+ dep.seconds,
+ dep.milliseconds);
+ break;
+ case DependencyType::kPlayerTime :
+ debugPrintf("kPlayerTime, %i hours, %i minutes, %i seconds, %i milliseconds",
+ dep.hours,
+ dep.minutes,
+ dep.seconds,
+ dep.milliseconds);
+ break;
+ case DependencyType::kSceneCount :
+ debugPrintf("kSceneCount, scene ID %i, hit count %s %i",
+ dep.hours,
+ dep.milliseconds == 1 ? ">" : dep.milliseconds == 2 ? "<" : "==",
+ dep.seconds);
+ break;
+ case DependencyType::kResetOnNewDay :
+ debugPrintf("kResetOnNewDay");
+ break;
+ case DependencyType::kUseItem :
+ debugPrintf("kUseItem, item %u, %s, %s",
+ dep.label,
+ g_nancy->getStaticData().itemNames[dep.label].c_str(),
+ dep.condition == kTrue ? "kTrue" : "kFalse");
+ break;
+ case DependencyType::kTimeOfDay :
+ debugPrintf("kTimeOfDay, %s",
+ dep.label == 0 ? "day" : dep.label == 1 ? "night" : "dusk/dawn");
+ break;
+ case DependencyType::kTimerNotDone :
+ debugPrintf("kTimerNotDone");
+ break;
+ case DependencyType::kTimerDone :
+ debugPrintf("kTimerDone");
+ break;
+ case DependencyType::kDifficultyLevel :
+ debugPrintf("kDifficultyLevel, level %i", dep.condition);
+ break;
+ default:
+ debugPrintf("unknown type %u", (uint)dep.type);
+ break;
+ }
+
+ debugPrintf("\n\t\t\torFlag == %s", dep.orFlag == true ? "true" : "false");
+ }
+ }
+
+ debugPrintf("\n\n");
+ }
+
+ return true;
+}
+
+bool NancyConsole::Cmd_getEventFlags(int argc, const char **argv) {
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ uint numEventFlags = g_nancy->getStaticData().numEventFlags;
+
+ debugPrintf("Total number of event flags: %u\n", numEventFlags);
+
+ if (argc == 1) {
+ for (uint i = 0; i < numEventFlags; ++i) {
+ debugPrintf("\nFlag %u, %s, %s",
+ i,
+ g_nancy->getStaticData().eventFlagNames[i].c_str(),
+ NancySceneState.getEventFlag(i) == true ? "kTrue" : "kFalse");
+ }
+ } else {
+ for (int i = 1; i < argc; ++i) {
+ int flagID = atoi(argv[i]);
+ if (flagID < 0 || flagID >= (int)numEventFlags) {
+ debugPrintf("\nInvalid flag %s", argv[i]);
+ continue;
+ }
+ debugPrintf("\nFlag %u, %s, %s",
+ flagID,
+ g_nancy->getStaticData().eventFlagNames[flagID].c_str(),
+ NancySceneState.getEventFlag(flagID) == true ? "kTrue" : "kFalse");
+
+ }
+ }
+
+ debugPrintf("\n");
+
+ return true;
+}
+
+bool NancyConsole::Cmd_setEventFlags(int argc, const char **argv) {
+ if (argc < 2 || argc % 2 == 0) {
+ debugPrintf("Sets one or more event flags to the provided value.\n");
+ debugPrintf("Usage: %s <flagID> <true/false>...\n", argv[0]);
+ return true;
+ }
+
+ for (int i = 1; i < argc; i += 2) {
+ int flagID = atoi(argv[i]);
+ if (flagID < 0 || flagID >= (int)g_nancy->getStaticData().numEventFlags) {
+ debugPrintf("Invalid flag %s\n", argv[i]);
+ continue;
+ }
+
+ if (Common::String(argv[i + 1]).compareTo("true") == 0) {
+ NancySceneState.setEventFlag(flagID, Nancy::kTrue);
+ debugPrintf("Set flag %i, %s, to kTrue\n",
+ flagID,
+ g_nancy->getStaticData().eventFlagNames[flagID].c_str());
+ } else if (Common::String(argv[i + 1]).compareTo("false") == 0) {
+ NancySceneState.setEventFlag(flagID, Nancy::kFalse);
+ debugPrintf("Set flag %i, %s, to kFalse\n",
+ flagID,
+ g_nancy->getStaticData().eventFlagNames[flagID].c_str());
+ } else {
+ debugPrintf("Invalid value %s\n", argv[i + 1]);
+ continue;
+ }
+ }
+
+ return cmdExit(0, nullptr);
+}
+
+bool NancyConsole::Cmd_getInventory(int argc, const char **argv) {
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ uint numItems = g_nancy->getStaticData().numItems;
+
+ debugPrintf("Total number of inventory items: %u\n", numItems);
+
+ if (argc == 1) {
+ for (uint i = 0; i < numItems; ++i) {
+ debugPrintf("\nItem %u, %s, %s",
+ i,
+ g_nancy->getStaticData().itemNames[i].c_str(),
+ NancySceneState.hasItem(i) == NancyFlag::kTrue ? "kTrue" : "kFalse");
+ }
+ } else {
+ for (int i = 1; i < argc; ++i) {
+ int flagID = atoi(argv[i]);
+ if (flagID < 0 || flagID >= (int)numItems) {
+ debugPrintf("\nInvalid flag %s", argv[i]);
+ continue;
+ }
+ debugPrintf("\nItem %u, %s, %s",
+ flagID,
+ g_nancy->getStaticData().itemNames[flagID].c_str(),
+ NancySceneState.hasItem(i) == NancyFlag::kTrue ? "kTrue" : "kFalse");
+
+ }
+ }
+
+ debugPrintf("\n");
+
+ return true;
+}
+
+bool NancyConsole::Cmd_setInventory(int argc, const char **argv) {
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ if (argc < 2 || argc % 2 == 0) {
+ debugPrintf("Sets one or more inventory items to the provided value.\n");
+ debugPrintf("Usage: %s <itemID> <true/false>...\n", argv[0]);
+ return true;
+ }
+
+ for (int i = 1; i < argc; i += 2) {
+ int itemID = atoi(argv[i]);
+ if (itemID < 0 || itemID >= (int)g_nancy->getStaticData().numItems) {
+ debugPrintf("Invalid item %s\n", argv[i]);
+ continue;
+ }
+
+ if (Common::String(argv[i + 1]).compareTo("true") == 0) {
+ NancySceneState.addItemToInventory(itemID);
+ debugPrintf("Added item %i, %s, to inventory\n",
+ itemID,
+ g_nancy->getStaticData().itemNames[itemID].c_str());
+ } else if (Common::String(argv[i + 1]).compareTo("false") == 0) {
+ NancySceneState.removeItemFromInventory(itemID, false);
+ debugPrintf("Removed item %i, %s, from inventory\n",
+ itemID,
+ g_nancy->getStaticData().itemNames[itemID].c_str());
+ } else {
+ debugPrintf("Invalid value %s\n", argv[i + 1]);
+ continue;
+ }
+ }
+
+ return cmdExit(0, nullptr);
+}
+
+bool NancyConsole::Cmd_getPlayerTime(int argc, const char **argv) {
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ Time time = NancySceneState._timers.playerTime;
+ debugPrintf("Player time: %u days, %u hours, %u minutes; %u\n",
+ time.getDays(),
+ time.getHours(),
+ time.getMinutes(),
+ (uint32)time);
+ return true;
+}
+
+bool NancyConsole::Cmd_setPlayerTime(int argc, const char **argv) {
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ if (argc != 2 && argc != 4) {
+ debugPrintf("Sets the in-game time.\n");
+ debugPrintf("Usage: %s <milliseconds> or %s <days> <hours> <minutes>\n", argv[0], argv[0]);
+ return true;
+ }
+
+ Time &time = NancySceneState._timers.playerTime;
+
+ if (argc == 2) {
+ time = atoi(argv[1]);
+ } else {
+ time = atoi(argv[1]) * 86400000 + // days
+ atoi(argv[2]) * 3600000 + // hours
+ atoi(argv[3]) * 60000; // minutes
+ }
+
+ debugPrintf("Set player time to: %u days, %u hours, %u minutes; %u\n",
+ time.getDays(),
+ time.getHours(),
+ time.getMinutes(),
+ (uint32)time);
+
+ return cmdExit(0, nullptr);
+}
+
+bool NancyConsole::Cmd_getDifficulty(int argc, const char **argv) {
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ debugPrintf("Difficulty: %u\n", NancySceneState.getDifficulty());
+
+ return true;
+}
+
+bool NancyConsole::Cmd_setDifficulty(int argc, const char **argv) {
+ if (g_nancy->_gameFlow.curState != NancyState::kScene) {
+ debugPrintf("Not in the kScene state\n");
+ return true;
+ }
+
+ if (argc != 2) {
+ debugPrintf("Set the game difficulty.\n");
+ debugPrintf("Usage: %s <difficulty>\n", argv[0]);
+ return true;
+ }
+
+ int diff = atoi(argv[1]);
+
+ if (diff < 0 || diff > 2) {
+ debugPrintf("Invalid difficulty %s\n", argv[1]);
+ return true;
+ }
+
+ NancySceneState.setDifficulty(diff);
+ debugPrintf("Set difficulty to %i\n", diff);
+
+ return cmdExit(0, nullptr);
+}
+
} // End of namespace Nancy
diff --git a/engines/nancy/console.h b/engines/nancy/console.h
index 051f413f524..c43e88d1ea3 100644
--- a/engines/nancy/console.h
+++ b/engines/nancy/console.h
@@ -48,9 +48,19 @@ private:
bool Cmd_playAudio(int argc, const char **argv);
bool Cmd_loadScene(int argc, const char **argv);
bool Cmd_sceneID(int argc, const char **argv);
+ bool Cmd_listAcionRecords(int argc, const char **argv);
+ bool Cmd_getEventFlags(int argc, const char **argv);
+ bool Cmd_setEventFlags(int argc, const char **argv);
+ bool Cmd_getInventory(int argc, const char **argv);
+ bool Cmd_setInventory(int argc, const char **argv);
+ bool Cmd_getPlayerTime(int argc, const char **argv);
+ bool Cmd_setPlayerTime(int argc, const char **argv);
+ bool Cmd_getDifficulty(int argc, const char **argv);
+ bool Cmd_setDifficulty(int argc, const char **argv);
Common::String _videoFile;
Common::String _imageFile;
+ Common::String _paletteFile;
};
} // End of namespace Nancy
diff --git a/engines/nancy/graphics.cpp b/engines/nancy/graphics.cpp
index dd79e7649ce..58c6fd1ab36 100644
--- a/engines/nancy/graphics.cpp
+++ b/engines/nancy/graphics.cpp
@@ -253,7 +253,7 @@ void GraphicsManager::copyToManaged(void *src, Graphics::ManagedSurface &dst, ui
copyToManaged(surf, dst, verticalFlip, doubleSize);
}
-void GraphicsManager::debugDrawToScreen(const Graphics::Surface &surf) {
+void GraphicsManager::debugDrawToScreen(const Graphics::ManagedSurface &surf) {
_screen.blitFrom(surf, Common::Point());
_screen.update();
}
diff --git a/engines/nancy/graphics.h b/engines/nancy/graphics.h
index 89ddfae0a86..6ac6a1e3ef5 100644
--- a/engines/nancy/graphics.h
+++ b/engines/nancy/graphics.h
@@ -58,7 +58,7 @@ public:
static void copyToManaged(void *src, Graphics::ManagedSurface &dst, uint srcW, uint srcH, const Graphics::PixelFormat &format, bool verticalFlip = false, bool doubleSize = false);
// Debug
- void debugDrawToScreen(const Graphics::Surface &surf);
+ void debugDrawToScreen(const Graphics::ManagedSurface &surf);
Graphics::ManagedSurface _object0;
Commit: 8a378fb89b03229f11154685838de209681ffd2f
https://github.com/scummvm/scummvm/commit/8a378fb89b03229f11154685838de209681ffd2f
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-03-03T17:35:58+02:00
Commit Message:
NANCY: Remove cheat dialogs
Removed the cheat and event flags dialogs, since they were always
a hacky solution and console commands are much easier to maintain.
Changed paths:
engines/nancy/commontypes.h
engines/nancy/dialogs.cpp
engines/nancy/dialogs.h
engines/nancy/input.cpp
engines/nancy/input.h
engines/nancy/nancy.cpp
engines/nancy/nancy.h
engines/nancy/state/scene.h
diff --git a/engines/nancy/commontypes.h b/engines/nancy/commontypes.h
index 8453307b625..486271f1e69 100644
--- a/engines/nancy/commontypes.h
+++ b/engines/nancy/commontypes.h
@@ -52,7 +52,7 @@ enum NancyState {
kHelp,
kScene,
// CD change
- kCheat,
+ // Cheat,
kQuit,
// regain focus
kNone,
diff --git a/engines/nancy/dialogs.cpp b/engines/nancy/dialogs.cpp
index 5a4bdaf4fd8..e7ced7f3ab6 100644
--- a/engines/nancy/dialogs.cpp
+++ b/engines/nancy/dialogs.cpp
@@ -83,308 +83,4 @@ bool NancyOptionsWidget::isInGame() const {
return _domain.equals(ConfMan.getActiveDomainName());
}
-// TODO rewrite this class so its layout is not hardcoded
-CheatDialog::CheatDialog() : GUI::Dialog(20, 20, 600, 440) {
- _backgroundType = GUI::ThemeEngine::kDialogBackgroundSpecial;
- Common::WinResources *res = Common::WinResources::createFromEXE("game.exe");
- Common::Array<Common::WinResourceID> dialogIDs = res->getIDList(Common::kWinDialog);
- State::SceneInfo scene = NancySceneState.getSceneInfo();
- Time playerTime = NancySceneState._timers.playerTime;
- Time timerTime = NancySceneState._timers.timerTime;
- bool timerIsActive = NancySceneState._timers.timerIsActive;
- if (!timerIsActive) {
- timerTime = 0;
- }
-
- GUI::TabWidget *_tabs = new GUI::TabWidget(this, 0, 0, 600, 370);
- new GUI::ButtonWidget(this, 420, 410, 60, 20, _("Cancel"), Common::U32String(), GUI::kCloseCmd);
- new GUI::ButtonWidget(this, 520, 410, 60, 20, _("OK"), Common::U32String(), GUI::kOKCmd);
-
- _tabs->addTab(_("General"), "Cheat.General");
-
- new GUI::StaticTextWidget(_tabs, 30, 20, 150, 20, _("Scene Data"), Graphics::kTextAlignLeft);
- _restartScene = new GUI::CheckboxWidget(_tabs, 35, 50, 150, 20, _("Restart the Scene"));
- _scene = new GUI::EditTextWidget(_tabs, 35, 75, 45, 20, Common::U32String::format("%u", scene.sceneID), Common::U32String(), kInputSceneNr, kInputSceneNr);
- new GUI::StaticTextWidget(_tabs, 85, 75, 150, 20, _("Scene Number"), Graphics::kTextAlignLeft);
- _frame = new GUI::EditTextWidget(_tabs, 35, 100, 45, 20, Common::U32String::format("%u", scene.frameID), Common::U32String(), kInputFrameNr, kInputFrameNr);
- new GUI::StaticTextWidget(_tabs, 85, 100, 150, 20, _("Frame Number"), Graphics::kTextAlignLeft);
- _offset = new GUI::EditTextWidget(_tabs, 35, 125, 45, 20, Common::U32String::format("%u", scene.verticalOffset), Common::U32String(), kInputScroll, kInputScroll);
-
- // I18N: The Y position (a.k.a vertical scroll) of the background
- new GUI::StaticTextWidget(_tabs, 85, 125, 150, 20, _("Background Top (Y)"), Graphics::kTextAlignLeft);
-
- new GUI::StaticTextWidget(_tabs, 30, 160, 150, 20, _("Hints Remaining"), Graphics::kTextAlignLeft);
- new GUI::StaticTextWidget(_tabs, 35, 185, 45, 20, _("Easy"), Graphics::kTextAlignLeft);
- _hintsRemainingEasy = new GUI::EditTextWidget(_tabs, 35, 205, 45, 20, Common::U32String::format("%u", NancySceneState._hintsRemaining[0]), Common::U32String(), kInputHintsEasy, kInputHintsEasy);
- new GUI::StaticTextWidget(_tabs, 85, 185, 45, 20, _("Medium"), Graphics::kTextAlignLeft);
- _hintsRemainingMedium = new GUI::EditTextWidget(_tabs, 85, 205, 45, 20, Common::U32String::format("%u", NancySceneState._hintsRemaining[1]), Common::U32String(), kInputHintsMedium, kInputHintsMedium);
- new GUI::StaticTextWidget(_tabs, 135, 185, 45, 20, _("Hard"), Graphics::kTextAlignLeft);
- _hintsRemainingHard = new GUI::EditTextWidget(_tabs, 135, 205, 45, 20, Common::U32String::format("%u", NancySceneState._hintsRemaining[2]), Common::U32String(), kInputHintsHard, kInputHintsHard);
-
- new GUI::StaticTextWidget(_tabs, 250, 20, 150, 20, _("Player Data"), Graphics::kTextAlignLeft);
- new GUI::StaticTextWidget(_tabs, 255, 50, 150, 20, _("Player Time:"), Graphics::kTextAlignLeft);
- _playerTimeDays = new GUI::EditTextWidget(_tabs, 255, 75, 35, 20, Common::U32String::format("%u", playerTime.getDays()), Common::U32String(), kInputPlayerTime, kInputPlayerTime);
- new GUI::StaticTextWidget(_tabs, 295, 75, 40, 20, _("Days"), Graphics::kTextAlignLeft);
- _playerTimeHours = new GUI::EditTextWidget(_tabs, 335, 75, 35, 20, Common::U32String::format("%u", playerTime.getHours()), Common::U32String(), kInputPlayerTime, kInputPlayerTime);
- new GUI::StaticTextWidget(_tabs, 375, 75, 40, 20, _("Hours"), Graphics::kTextAlignLeft);
- _playerTimeMinutes = new GUI::EditTextWidget(_tabs, 415, 75, 35, 20, Common::U32String::format("%u", playerTime.getMinutes()), Common::U32String(), kInputPlayerTime, kInputPlayerTime);
- new GUI::StaticTextWidget(_tabs, 455, 75, 50, 20, _("Minutes"), Graphics::kTextAlignLeft);
- _difficulty = new GUI::EditTextWidget(_tabs, 255, 105, 35, 20, Common::U32String::format("%u", NancySceneState._difficulty), Common::U32String(), kInputDifficulty, kInputDifficulty);
- new GUI::StaticTextWidget(_tabs, 295, 105, 150, 20, _("Player Difficulty Level"), Graphics::kTextAlignLeft);
-
- new GUI::StaticTextWidget(_tabs, 250, 140, 150, 20, _("Software Timer"), Graphics::kTextAlignLeft);
- _timerOn = new GUI::CheckboxWidget(_tabs, 255, 170, 150, 20, _("Timer On"));
- _timerOn->setState(timerIsActive);
- _timerHours = new GUI::EditTextWidget(_tabs, 255, 195, 35, 20, Common::U32String::format("%u", timerTime.getTotalHours()), Common::U32String(), kInputTimer, kInputTimer);
- new GUI::StaticTextWidget(_tabs, 295, 195, 40, 20, _("Hours"), Graphics::kTextAlignLeft);
- _timerMinutes = new GUI::EditTextWidget(_tabs, 335, 195, 35, 20, Common::U32String::format("%u", timerTime.getMinutes()), Common::U32String(), kInputTimer, kInputTimer);
- new GUI::StaticTextWidget(_tabs, 375, 195, 50, 20, _("Minutes"), Graphics::kTextAlignLeft);
- _timerSeconds = new GUI::EditTextWidget(_tabs, 425, 195, 35, 20, Common::U32String::format("%u", timerTime.getSeconds()), Common::U32String(), kInputTimer, kInputTimer);
- new GUI::StaticTextWidget(_tabs, 465, 195, 50, 20, _("Seconds"), Graphics::kTextAlignLeft);
-
- _tabs->addTab(_("Inventory"), "Cheat.Inventory");
-
- for (uint i = 0; i < dialogIDs.size(); ++i) {
- Common::SeekableReadStream *resStream = res->getResource(Common::kWinDialog, dialogIDs[i].getID());
-
- Common::String idString;
- resStream->skip(0x16);
- while (true) {
- char add = resStream->readByte();
- if (add != 0) {
- idString += add;
- resStream->skip(1);
- } else {
- resStream->skip(1);
- break;
- }
- }
-
- if (!idString.hasPrefix("Inventory")) {
- continue;
- }
-
- idString.trim();
- uint numItems = 0;
-
- while (resStream->pos() < resStream->size()) {
- if (resStream->readUint16LE() == 0xFFFF && resStream->readSint16LE() == 0x80) {
- // Found a resource, read its string id
- Common::String itemLabel;
-
- while (true) {
- char add = resStream->readByte();
- if (add != 0) {
- itemLabel += add;
- resStream->skip(1);
- } else {
- resStream->skip(1);
- break;
- }
- }
- GUI::CheckboxWidget *box = new GUI::CheckboxWidget(_tabs, 250 * (numItems / 10) + 20, (350 / 10) * (numItems % 10) + 15, 250, 250/10, Common::U32String(itemLabel));
- box->setState(NancySceneState.hasItem(numItems) == kTrue);
- _inventory.push_back(box);
-
- ++numItems;
- }
- }
-
- break;
- }
-
- _tabs->setActiveTab(0);
-}
-
-void CheatDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
- switch (cmd) {
- case GUI::kOKCmd: {
- if (_restartScene->getState()) {
- uint sceneID = atoi(Common::String(_scene->getEditString()).c_str());
- IFF iff(Common::String::format("S%u", sceneID));
- if (iff.load()) {
- NancySceneState.changeScene(
- atoi(Common::String(_scene->getEditString()).c_str()),
- atoi(Common::String(_frame->getEditString()).c_str()),
- atoi(Common::String(_offset->getEditString()).c_str()),
- true);
- } else {
- new GUI::StaticTextWidget(this, 20, 410, 150, 20, _("Invalid Scene ID!"), Graphics::kTextAlignLeft);
- return;
- }
- }
-
- if (_timerOn->getState()) {
- NancySceneState._timers.timerIsActive = true;
- Time &timer = NancySceneState._timers.timerTime;
- timer = 0;
- timer += 1000 * atoi(Common::String(_timerSeconds->getEditString()).c_str());
- timer += 60000 * atoi(Common::String(_timerMinutes->getEditString()).c_str());
- timer += 3600000 * atoi(Common::String(_timerHours->getEditString()).c_str());
- } else {
- NancySceneState.stopTimer();
- }
-
- Time &playerTime = NancySceneState._timers.timerTime;
- playerTime = 0;
- playerTime += 60000 * atoi(Common::String(_playerTimeMinutes->getEditString()).c_str());
- playerTime += 3600000 * atoi(Common::String(_playerTimeHours->getEditString()).c_str());
- playerTime += 86400000 * atoi(Common::String(_playerTimeMinutes->getEditString()).c_str());
-
- NancySceneState._difficulty = atoi(Common::String(_difficulty->getEditString()).c_str());
- NancySceneState._hintsRemaining[0] = atoi(Common::String(_hintsRemainingEasy->getEditString()).c_str());
- NancySceneState._hintsRemaining[1] = atoi(Common::String(_hintsRemainingMedium->getEditString()).c_str());
- NancySceneState._hintsRemaining[2] = atoi(Common::String(_hintsRemainingHard->getEditString()).c_str());
-
- for (uint i = 0; i < _inventory.size(); ++i) {
- if (NancySceneState.hasItem(i) == kTrue && !_inventory[i]->getState()) {
- NancySceneState.removeItemFromInventory(i, false);
- } else if (NancySceneState.hasItem(i) == kFalse && _inventory[i]->getState()) {
- NancySceneState.addItemToInventory(i);
- }
- }
- cmd = GUI::kCloseCmd;
-
- break;
- }
- case kInputSceneNr:
- sanitizeInput(_scene);
- break;
- case kInputFrameNr:
- sanitizeInput(_frame);
- break;
- case kInputScroll:
- sanitizeInput(_offset);
- break;
- case kInputDifficulty:
- sanitizeInput(_scene, 2);
- break;
- case kInputHintsEasy:
- sanitizeInput(_hintsRemainingEasy);
- break;
- case kInputHintsMedium:
- sanitizeInput(_hintsRemainingMedium);
- break;
- case kInputHintsHard:
- sanitizeInput(_hintsRemainingHard);
- break;
- case kInputPlayerTime:
- sanitizeInput(_playerTimeMinutes, 59);
- sanitizeInput(_playerTimeHours, 23);
- sanitizeInput(_playerTimeDays);
- break;
- case kInputTimer:
- sanitizeInput(_timerSeconds, 59);
- sanitizeInput(_timerMinutes, 59);
- sanitizeInput(_timerHours, 23);
- break;
- default:
- break;
- }
-
- Dialog::handleCommand(sender, cmd, data);
-}
-
-void CheatDialog::sanitizeInput(GUI::EditTextWidget *textWidget, int maxValue) {
- const Common::U32String &str = textWidget->getEditString();
- for (uint i = 0; i < str.size(); ++i) {
- if (!Common::isDigit(str[i])) {
- textWidget->setEditString(str.substr(0, i));
- break;
- }
- }
-
- if (maxValue > -1) {
- int number = atoi(Common::String(str).c_str());
- if (number > maxValue) {
- textWidget->setEditString(Common::U32String::format("%d", maxValue));
- }
- }
-
- textWidget->setCaretPos(str.size());
-}
-
-EventFlagDialog::EventFlagDialog() : GUI::Dialog(20, 20, 600, 440) {
- _backgroundType = GUI::ThemeEngine::kDialogBackgroundSpecial;
- Common::WinResources *res = Common::WinResources::createFromEXE("game.exe");
- Common::Array<Common::WinResourceID> dialogIDs = res->getIDList(Common::kWinDialog);
-
- GUI::TabWidget *_tabs = new GUI::TabWidget(this, 0, 0, 600, 370);
- new GUI::ButtonWidget(this, 520, 410, 60, 20, _("Close"), Common::U32String(), GUI::kCloseCmd);
-
- for (uint i = 0; i < dialogIDs.size(); ++i) {
- Common::SeekableReadStream *resStream = res->getResource(Common::kWinDialog, dialogIDs[i].getID());
-
- Common::String idString;
- resStream->skip(0x16);
- while (true) {
- char add = resStream->readByte();
- if (add != 0) {
- idString += add;
- resStream->skip(1);
- } else {
- resStream->skip(1);
- break;
- }
- }
-
- if (!idString.hasPrefix("Event")) {
- continue;
- }
-
- idString.trim();
- _tabs->addTab(idString, Common::String("tab " + idString));
- uint numFlags = 0;
-
- while (resStream->pos() < resStream->size()) {
- if (resStream->readUint16LE() == 0xFFFF && resStream->readSint16LE() == 0x80) {
- // Found a resource, read its string id
- Common::String flagLabel;
-
- while (true) {
- char add = resStream->readByte();
- if (add != 0) {
- flagLabel += add;
- resStream->skip(1);
- } else {
- resStream->skip(1);
- break;
- }
- }
-
- // String begins with number so we assume it's an event flag radio button
- if (Common::isDigit(flagLabel.firstChar())) {
- Common::String num;
- uint j = 0;
- while (true) {
- if (Common::isDigit(flagLabel[j])) {
- num += flagLabel[j];
- } else {
- break;
- }
- ++j;
- }
-
- uint32 command = atoi(num.c_str()) << 16 | 'ev';
-
- GUI::CheckboxWidget *box = new GUI::CheckboxWidget(_tabs, 300 * (numFlags / 12) + 20, (350 / 12) * (numFlags % 12) + 15, 300, 350/12, Common::U32String(flagLabel), Common::U32String(), command);
- box->setState(NancySceneState.getEventFlag(command >> 16));
-
- ++numFlags;
- }
- }
- }
- }
-
- _tabs->setActiveTab(0);
-}
-
-void EventFlagDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
- Dialog::handleCommand(sender, cmd, data);
- if (cmd & 'ev') {
- cmd >>= 16;
- NancySceneState.setEventFlag(cmd, data == 0 ? kFalse : kTrue);
- }
-}
-
} // End of namespace Nancy
diff --git a/engines/nancy/dialogs.h b/engines/nancy/dialogs.h
index f2f881a76ad..e989ced50a9 100644
--- a/engines/nancy/dialogs.h
+++ b/engines/nancy/dialogs.h
@@ -45,56 +45,6 @@ private:
GUI::CheckboxWidget *_secondChanceCheckbox;
};
-class CheatDialog : public GUI::Dialog {
-public:
- CheatDialog();
-
-protected:
- enum Commands {
- kInputSceneNr = 'isnr',
- kInputFrameNr = 'ifnr',
- kInputScroll = 'iscr',
- kInputHintsEasy = 'ihea',
- kInputHintsMedium = 'ihme',
- kInputHintsHard = 'ihha',
- kInputPlayerTime = 'plti',
- kInputDifficulty = 'diff',
- kInputTimer = 'time'
- };
-
- void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
- static void sanitizeInput(GUI::EditTextWidget *textWidget, int maxValue = -1);
-
- GUI::CheckboxWidget *_restartScene;
- GUI::EditTextWidget *_scene;
- GUI::EditTextWidget *_frame;
- GUI::EditTextWidget *_offset;
-
- GUI::EditTextWidget *_hintsRemainingEasy;
- GUI::EditTextWidget *_hintsRemainingMedium;
- GUI::EditTextWidget *_hintsRemainingHard;
-
- GUI::EditTextWidget *_playerTimeDays;
- GUI::EditTextWidget *_playerTimeHours;
- GUI::EditTextWidget *_playerTimeMinutes;
- GUI::EditTextWidget *_difficulty;
-
- GUI::CheckboxWidget *_timerOn;
- GUI::EditTextWidget *_timerHours;
- GUI::EditTextWidget *_timerMinutes;
- GUI::EditTextWidget *_timerSeconds;
-
- Common::Array<GUI::CheckboxWidget *> _inventory;
-};
-
-class EventFlagDialog : public GUI::Dialog {
-public:
- EventFlagDialog();
-
-protected:
- void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) override;
-};
-
} // End of namespace Nancy
#endif // NANCY_DIALOGS_H
diff --git a/engines/nancy/input.cpp b/engines/nancy/input.cpp
index eded7c57fa9..092f3d32ff9 100644
--- a/engines/nancy/input.cpp
+++ b/engines/nancy/input.cpp
@@ -75,12 +75,6 @@ void InputManager::processEvents() {
case kNancyActionMoveFast:
_inputs |= NancyInput::kMoveFastModifier;
break;
- case kNancyActionRequestCheatMenu:
- g_nancy->callCheatMenu(false);
- break;
- case kNancyActionRequestEventMenu:
- g_nancy->callCheatMenu(true);
- break;
default:
break;
}
@@ -247,16 +241,6 @@ void InputManager::initKeymaps(Common::KeymapArray &keymaps) {
act->addDefaultInputMapping("C+S+TAB+m");
debugKeymap->addAction(act);
- act = new Action("CHEAT", _("Open general cheat menu"));
- act->setCustomEngineActionEvent(kNancyActionRequestCheatMenu);
- act->addDefaultInputMapping("C+S+TAB+c");
- debugKeymap->addAction(act);
-
- act = new Action("EVENT", _("Open event flags cheat menu"));
- act->setCustomEngineActionEvent(kNancyActionRequestEventMenu);
- act->addDefaultInputMapping("C+S+TAB+v");
- debugKeymap->addAction(act);
-
keymaps.push_back(mainKeymap);
keymaps.push_back(debugKeymap);
}
diff --git a/engines/nancy/input.h b/engines/nancy/input.h
index 4af93d192ad..9f73126ef5c 100644
--- a/engines/nancy/input.h
+++ b/engines/nancy/input.h
@@ -81,9 +81,7 @@ enum NancyAction {
kNancyActionRequestSaveLoad,
kNancyActionRequestSetupMenu,
kNancyActionRequestCredits,
- kNancyActionRequestMap,
- kNancyActionRequestCheatMenu,
- kNancyActionRequestEventMenu
+ kNancyActionRequestMap
};
public:
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 1bcf5874c21..c0e98b77de0 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -70,7 +70,6 @@ NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
_resource = nullptr;
_startTimeHours = 0;
_overrideMovementTimeDeltas = false;
- _cheatTypeIsEventFlag = false;
_horizontalEdgesSize = 0;
_verticalEdgesSize = 0;
}
@@ -194,18 +193,6 @@ void NancyEngine::setState(NancyState::NancyState state, NancyState::NancyState
return;
}
- case NancyState::kCheat:
- if (_cheatTypeIsEventFlag) {
- EventFlagDialog *dialog = new EventFlagDialog();
- runDialog(*dialog);
- delete dialog;
- } else {
- CheatDialog *dialog = new CheatDialog();
- runDialog(*dialog);
- delete dialog;
- }
- _input->forceCleanInput();
- return;
default:
break;
}
@@ -249,11 +236,6 @@ void NancyEngine::setMouseEnabled(bool enabled) {
_cursorManager->showCursor(enabled); _input->setMouseInputEnabled(enabled);
}
-void NancyEngine::callCheatMenu(bool eventFlags) {
- _cheatTypeIsEventFlag = eventFlags;
- setState(NancyState::kCheat);
-}
-
Common::Error NancyEngine::run() {
setDebugger(new NancyConsole());
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index d48a9a010ef..98c60321c1f 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -62,7 +62,6 @@ class InputManager;
class SoundManager;
class GraphicsManager;
class CursorManager;
-class CheatDialog;
class NancyConsole;
namespace State {
@@ -103,8 +102,6 @@ public:
void setMouseEnabled(bool enabled);
- void callCheatMenu(bool eventFlags);
-
// Managers
ResourceManager *_resource;
GraphicsManager *_graphicsManager;
@@ -155,8 +152,6 @@ private:
bool isCompressed();
- bool _cheatTypeIsEventFlag;
-
StaticData _staticData;
const byte _datFileMajorVersion;
const byte _datFileMinorVersion;
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 788a53c52af..eda65d3fa58 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -44,7 +44,6 @@ namespace Nancy {
class NancyEngine;
class NancyConsole;
-class CheatDialog;
struct SceneChangeDescription;
namespace Action {
@@ -74,7 +73,6 @@ class Scene : public State, public Common::Singleton<Scene> {
friend class Nancy::Action::SliderPuzzle;
friend class Nancy::NancyConsole;
friend class Nancy::NancyEngine;
- friend class Nancy::CheatDialog;
public:
enum GameStateChange : byte {
More information about the Scummvm-git-logs
mailing list