[Scummvm-git-logs] scummvm master -> 2e229629099055fa499c8d1048aecbbf0e00aaac
fracturehill
noreply at scummvm.org
Sun Feb 11 21:54:56 UTC 2024
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
e25018f892 NANCY: Allow later games to have 999 saves
b2231ac3cd NANCY: Implement Autotext with hotspots
88574bd47c NANCY: Fix crash in Conversation
f85277f82a NANCY: Add support for nancy9 SliderPuzzle
2e22962909 NANCY: Add support for TextBoxWrite with no string
Commit: e25018f892c9128f77c764ad9acbcb0f62d6cbd2
https://github.com/scummvm/scummvm/commit/e25018f892c9128f77c764ad9acbcb0f62d6cbd2
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T22:53:22+01:00
Commit Message:
NANCY: Allow later games to have 999 saves
Added a hidden ConfMan property that controls how many
saves are allowed, and added code that sets it to 8 at
startup, provided the game is nancy7 or earlier. This makes
sure that later games, which had infinite saves, can have
their save menus supported correctly.
Changed paths:
engines/nancy/metaengine.cpp
engines/nancy/nancy.cpp
diff --git a/engines/nancy/metaengine.cpp b/engines/nancy/metaengine.cpp
index 1ce915dcd15..2330bc7e758 100644
--- a/engines/nancy/metaengine.cpp
+++ b/engines/nancy/metaengine.cpp
@@ -146,7 +146,7 @@ Common::Error NancyMetaEngine::createInstance(OSystem *syst, Engine **engine, co
}
}
-int NancyMetaEngine::getMaximumSaveSlot() const { return 8; }
+int NancyMetaEngine::getMaximumSaveSlot() const { int r = ConfMan.getInt("nancy_max_saves"); return r ? r : AdvancedMetaEngine::getMaximumSaveSlot(); }
SaveStateDescriptor NancyMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
SaveStateDescriptor ret = AdvancedMetaEngine::querySaveMetaInfos(target, slot);
@@ -186,6 +186,7 @@ void NancyMetaEngine::registerDefaultSettings(const Common::String &target) cons
ConfMan.registerDefault("player_speech", true);
ConfMan.registerDefault("character_speech", true);
+ ConfMan.registerDefault("nancy_max_saves", 999);
}
const ADExtraGuiOptionsMap *NancyMetaEngine::getAdvancedExtraGuiOptions() const {
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index 8eaba0f8c3e..ab9cebef5e4 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -254,6 +254,13 @@ void NancyEngine::addDeferredLoader(Common::SharedPtr<DeferredLoader> &loaderPtr
Common::Error NancyEngine::run() {
setDebugger(new NancyConsole());
+
+ // Set the default number of saves for earlier games
+ if (!ConfMan.hasKey("nancy_max_saves", ConfMan.getActiveDomainName())) {
+ if (getGameType() <= kGameTypeNancy7) {
+ ConfMan.setInt("nancy_max_saves", 8, ConfMan.getActiveDomainName());
+ }
+ }
// Boot the engine
setState(NancyState::kBoot);
Commit: b2231ac3cdfbb59c8de9953dcd929c5666eb085d
https://github.com/scummvm/scummvm/commit/b2231ac3cdfbb59c8de9953dcd929c5666eb085d
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T22:53:22+01:00
Commit Message:
NANCY: Implement Autotext with hotspots
Added support for hotspots that link to a new scene,
as introduced in nancy9.
Changed paths:
engines/nancy/action/autotext.cpp
engines/nancy/action/autotext.h
engines/nancy/action/datarecords.cpp
engines/nancy/action/datarecords.h
engines/nancy/action/puzzle/peepholepuzzle.cpp
engines/nancy/action/puzzle/peepholepuzzle.h
engines/nancy/misc/hypertext.cpp
engines/nancy/puzzledata.h
diff --git a/engines/nancy/action/autotext.cpp b/engines/nancy/action/autotext.cpp
index 9b8a66b352a..7fb1895057b 100644
--- a/engines/nancy/action/autotext.cpp
+++ b/engines/nancy/action/autotext.cpp
@@ -97,14 +97,34 @@ void Autotext::execute() {
bool foundThisKey = false;
for (auto &entry : entriesForSurface) {
Common::String &stringID = entry.stringID;
- Common::String markString = entry.mark ? Common::String::format("<%u>", entry.mark) : "";
+ Common::String withTags = autotext->texts[stringID];
+
+ if (entry.mark % 10) {
+ withTags = Common::String::format("<%u>", entry.mark % 10) + withTags;
+ }
+
+ bool hasHotspot = false;
+
+ if (entry.mark >= 10 && entry.sceneID != kNoScene) {
+ // The original engine uses tags <H#> and <L>
+ withTags = "<H>" + withTags + "<L>";
+ hasHotspot = true;
+ }
if (_order == kListFIFO) {
// Add to end of string
- stringToPush += (markString + autotext->texts[stringID]);
+ stringToPush += withTags;
+
+ if (hasHotspot) {
+ _hotspotScenes.push_back(entry.sceneID);
+ }
} else {
// Add to front of string
- stringToPush = markString + autotext->texts[stringID] + stringToPush;
+ stringToPush = withTags + stringToPush;
+
+ if (hasHotspot) {
+ _hotspotScenes.insert_at(0, entry.sceneID);
+ }
}
if (!_textKey.empty() && stringID == _textKey) {
diff --git a/engines/nancy/action/autotext.h b/engines/nancy/action/autotext.h
index c7375752c6a..22b08063bf7 100644
--- a/engines/nancy/action/autotext.h
+++ b/engines/nancy/action/autotext.h
@@ -61,7 +61,9 @@ protected:
Common::String _embeddedText;
uint16 _order = kListFIFO;
- bool _shouldDrawMarks = false; // currently unused
+ bool _shouldDrawMarks = false;
+
+ Common::Array<uint16> _hotspotScenes;
Graphics::ManagedSurface _image;
};
diff --git a/engines/nancy/action/datarecords.cpp b/engines/nancy/action/datarecords.cpp
index 13468bcafff..b66a508d0e2 100644
--- a/engines/nancy/action/datarecords.cpp
+++ b/engines/nancy/action/datarecords.cpp
@@ -406,6 +406,10 @@ void ModifyListEntry::readData(Common::SeekableReadStream &stream) {
_surfaceID = stream.readUint16LE();
readFilename(stream, _stringID);
_mark = stream.readUint16LE();
+
+ if (g_nancy->getGameType() >= kGameTypeNancy9 && _mark >= 10) {
+ _sceneID = stream.readUint16LE();
+ }
}
void ModifyListEntry::execute() {
@@ -425,7 +429,7 @@ void ModifyListEntry::execute() {
switch (_type) {
case kAdd:
if (!found) {
- array.push_back(JournalData::Entry(_stringID, _mark));
+ array.push_back(JournalData::Entry(_stringID, _mark, _sceneID));
}
break;
diff --git a/engines/nancy/action/datarecords.h b/engines/nancy/action/datarecords.h
index 972faff6f73..ab322c60b01 100644
--- a/engines/nancy/action/datarecords.h
+++ b/engines/nancy/action/datarecords.h
@@ -162,6 +162,7 @@ public:
uint16 _surfaceID = 0;
Common::String _stringID;
uint16 _mark = 0;
+ uint16 _sceneID = kNoScene;
protected:
Common::String getRecordTypeName() const override;
diff --git a/engines/nancy/action/puzzle/peepholepuzzle.cpp b/engines/nancy/action/puzzle/peepholepuzzle.cpp
index 619daf91a76..c259253567c 100644
--- a/engines/nancy/action/puzzle/peepholepuzzle.cpp
+++ b/engines/nancy/action/puzzle/peepholepuzzle.cpp
@@ -332,5 +332,31 @@ void TextScroll::readExtraData(Common::SeekableReadStream &stream) {
}
}
+void TextScroll::handleInput(NancyInput &input) {
+ PeepholePuzzle::handleInput(input);
+
+ // Finally, check hotspots
+ for (uint i = 0; i < _hotspots.size(); ++i) {
+ Common::Rect hotspot = _hotspots[i];
+ hotspot.translate(_dest.left, _dest.top);
+ Common::Point innerOffset = _drawSurface.getOffsetFromOwner();
+ hotspot.translate(-innerOffset.x, -innerOffset.y);
+ hotspot.clip(_dest);
+ if (!hotspot.isEmpty() && NancySceneState.getViewport().convertViewportToScreen(hotspot).contains(input.mousePos)) {
+ g_nancy->_cursor->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Clicked on a hotspot, change to corresponding scene
+ SceneChangeDescription sceneChange;
+ sceneChange.sceneID = _hotspotScenes[i];
+ sceneChange.continueSceneSound = kContinueSceneSound;
+ NancySceneState.changeScene(sceneChange);
+ }
+
+ break;
+ }
+ }
+}
+
} // End of namespace Action
} // End of namespace Nancy
diff --git a/engines/nancy/action/puzzle/peepholepuzzle.h b/engines/nancy/action/puzzle/peepholepuzzle.h
index 53d818b02fa..f646afa18e0 100644
--- a/engines/nancy/action/puzzle/peepholepuzzle.h
+++ b/engines/nancy/action/puzzle/peepholepuzzle.h
@@ -85,6 +85,7 @@ public:
void init() override;
void execute() override { PeepholePuzzle::execute(); }
+ void handleInput(NancyInput &input) override;
void readData(Common::SeekableReadStream &stream) override;
diff --git a/engines/nancy/misc/hypertext.cpp b/engines/nancy/misc/hypertext.cpp
index f0bb5c3f714..535be263920 100644
--- a/engines/nancy/misc/hypertext.cpp
+++ b/engines/nancy/misc/hypertext.cpp
@@ -30,7 +30,7 @@ namespace Nancy {
namespace Misc {
struct MetaInfo {
- enum Type { kColor, kFont, kMark };
+ enum Type { kColor, kFont, kMark, kHotspot };
Type type;
uint numChars;
@@ -126,6 +126,22 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
hasHotspot = true;
continue;
+ case 'H' :
+ // Hotspot inside list, begin
+ if (curToken.size() != 1) {
+ break;
+ }
+
+ metaInfo.push({MetaInfo::kHotspot, numNonSpaceChars, 1});
+ continue;
+ case 'L' :
+ // Hotspot inside list, end
+ if (curToken.size() != 1) {
+ break;
+ }
+
+ metaInfo.push({MetaInfo::kHotspot, numNonSpaceChars, 0});
+ continue;
case 'n' :
// Newline
if (curToken.size() != 1) {
@@ -203,11 +219,11 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
Array<Common::String> wrappedLines;
font->wordWrap(currentLine, textBounds.width(), wrappedLines, 0);
- // Setup most of the hotspot
+ // Setup most of the hotspot; textbox
if (hasHotspot) {
hotspot.left = textBounds.left;
hotspot.top = textBounds.top + (_numDrawnLines * font->getFontHeight()) - 1;
- hotspot.setHeight(wrappedLines.size() * font->getFontHeight());
+ hotspot.setHeight(0);
hotspot.setWidth(0);
}
@@ -263,16 +279,12 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
line.deleteChar(0);
}
- // Set the width of the hotspot
- if (hasHotspot) {
- hotspot.setWidth(MAX<int16>(hotspot.width(), font->getStringWidth(line)));
- }
-
+ bool newWrappedLine = true; // Used to ensure color/font changes don't mess up hotspots
while (!line.empty()) {
Common::String subLine;
while (metaInfo.size() && totalCharsDrawn >= metaInfo.front().numChars) {
- // We have a color/font change token, or a mark at begginning of (what's left of) the current line
+ // We have a color/font change token, a hyperlink, or a mark at begginning of (what's left of) the current line
MetaInfo change = metaInfo.pop();
switch (change.type) {
case MetaInfo::kFont:
@@ -306,13 +318,42 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
_fullSurface.blitFrom(g_nancy->_graphics->_object0, markSrc, markDest);
horizontalOffset += markDest.width() + 2;
+ break;
+ }
+ case MetaInfo::kHotspot:
+ // List only
+ hasHotspot = change.index;
+
+ if (hasHotspot) {
+ hotspot.left = textBounds.left + (newLineStart ? 0 : horizontalOffset + leftOffsetNonNewline);
+ hotspot.top = textBounds.top + _numDrawnLines * font->getFontHeight() + _imageVerticalOffset - 1;
+ hotspot.setHeight(0);
+ hotspot.setWidth(0);
+ } else {
+ _hotspots.push_back(hotspot);
+ hotspot = { 0, 0, 0, 0 };
+ }
+
+ break;
}
+ }
+
+ uint lineSizeNoSpace = 0;
+ for (uint i = 0; i < line.size(); ++i) {
+ if (!isSpace(line[i])) {
+ ++lineSizeNoSpace;
}
}
- if (metaInfo.size() && totalCharsDrawn < metaInfo.front().numChars && metaInfo.front().numChars < (totalCharsDrawn + line.size())) {
+ if (metaInfo.size() && totalCharsDrawn < metaInfo.front().numChars && metaInfo.front().numChars <= (totalCharsDrawn + lineSizeNoSpace)) {
// There's a token inside the current line, so split off the part before it
- subLine = line.substr(0, metaInfo.front().numChars - totalCharsDrawn);
+ uint subSize = metaInfo.front().numChars - totalCharsDrawn;
+ for (uint i = 0; i < subSize; ++i) {
+ if (isSpace(line[i])) {
+ ++subSize;
+ }
+ }
+ subLine = line.substr(0, subSize);
line = line.substr(subLine.size());
}
@@ -328,7 +369,7 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
colorID);
// Then, draw the highlight
- if (hasHotspot) {
+ if (hasHotspot && !_textHighlightSurface.empty()) {
highlightFont->drawString( &_textHighlightSurface,
stringToDraw,
textBounds.left + horizontalOffset + (newLineStart ? leftOffsetNonNewline : 0),
@@ -344,6 +385,17 @@ void HypertextParser::drawAllText(const Common::Rect &textBounds, uint leftOffse
++totalCharsDrawn;
}
}
+
+ // Add to the width/height of the hotspot
+ if (hasHotspot) {
+ hotspot.setWidth(MAX<int16>(hotspot.width(), font->getStringWidth(stringToDraw)));
+
+ if (!stringToDraw.empty() && newWrappedLine) {
+ hotspot.setHeight(hotspot.height() + font->getFontHeight());
+ }
+ }
+
+ newWrappedLine = false;
if (subLine.size()) {
horizontalOffset += font->getStringWidth(subLine);
diff --git a/engines/nancy/puzzledata.h b/engines/nancy/puzzledata.h
index 9aa3b9a3725..672ce77b478 100644
--- a/engines/nancy/puzzledata.h
+++ b/engines/nancy/puzzledata.h
@@ -23,6 +23,8 @@
#include "common/array.h"
#include "common/hashmap.h"
+#include "engines/nancy/commontypes.h"
+
#ifndef NANCY_PUZZLEDATA_H
#define NANCY_PUZZLEDATA_H
@@ -112,10 +114,11 @@ struct JournalData : public PuzzleData {
virtual ~JournalData() {}
struct Entry {
- Entry(const Common::String &s = Common::String(), int16 m = 0) : stringID(s), mark(m) {}
+ Entry(const Common::String &s = Common::String(), uint16 m = 0, uint16 sc = kNoScene) : stringID(s), mark(m), sceneID(sc) {}
Common::String stringID;
uint16 mark = 0;
+ uint16 sceneID = kNoScene;
};
static constexpr uint32 getTag() { return MKTAG('J', 'O', 'U', 'R'); }
Commit: 88574bd47ce9e0b7609badc0affab593fa86b08e
https://github.com/scummvm/scummvm/commit/88574bd47ce9e0b7609badc0affab593fa86b08e
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T22:53:22+01:00
Commit Message:
NANCY: Fix crash in Conversation
Changed paths:
engines/nancy/action/conversation.cpp
diff --git a/engines/nancy/action/conversation.cpp b/engines/nancy/action/conversation.cpp
index 3bb4c98f4f4..59cceb0f6ef 100644
--- a/engines/nancy/action/conversation.cpp
+++ b/engines/nancy/action/conversation.cpp
@@ -315,8 +315,8 @@ void ConversationSound::execute() {
}
for (uint i : responsesToAdd) {
- NancySceneState.getTextbox().addTextLine(_responses[responsesToAdd[i]].text);
- _responses[responsesToAdd[i]].isOnScreen = true;
+ NancySceneState.getTextbox().addTextLine(_responses[i].text);
+ _responses[i].isOnScreen = true;
}
}
Commit: f85277f82a5b29d392548988a500d877124537cc
https://github.com/scummvm/scummvm/commit/f85277f82a5b29d392548988a500d877124537cc
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T22:53:22+01:00
Commit Message:
NANCY: Add support for nancy9 SliderPuzzle
The record works identically to the one in nancy1, with
the exception that the start positions are no longer pulled
from a SPUZ chunk.
Changed paths:
engines/nancy/action/puzzle/sliderpuzzle.cpp
engines/nancy/action/puzzle/sliderpuzzle.h
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.cpp b/engines/nancy/action/puzzle/sliderpuzzle.cpp
index ac96648279e..0b8976fdfc0 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.cpp
+++ b/engines/nancy/action/puzzle/sliderpuzzle.cpp
@@ -44,9 +44,6 @@ void SliderPuzzle::init() {
}
void SliderPuzzle::readData(Common::SeekableReadStream &stream) {
- _spuzData = GetEngineData(SPUZ);
- assert(_spuzData);
-
_puzzleState = (SliderPuzzleData *)NancySceneState.getPuzzleData(SliderPuzzleData::getTag());
assert(_puzzleState);
@@ -74,18 +71,32 @@ void SliderPuzzle::readData(Common::SeekableReadStream &stream) {
}
}
- _correctTileOrder.reserve(_height);
- for (uint y = 0; y < _height; ++y) {
- _correctTileOrder.push_back(Common::Array<int16>());
- _correctTileOrder.back().reserve(_width);
+ if (g_nancy->getGameType() >= kGameTypeNancy9) {
+ _retainState = stream.readByte();
- for (uint x = 0; x < _width; ++x) {
- _correctTileOrder.back().push_back(stream.readSint16LE());
+ _startTileOrder.resize(_height);
+ for (uint y = 0; y < _height; ++y) {
+ _startTileOrder[y].resize(_width);
+ for (uint x = 0; x < _width; ++x) {
+ _startTileOrder[y][x] = stream.readSint16LE();
+ }
+ stream.skip((6 - _width) * 2);
}
+ stream.skip((6 - _height) * 6 * 2);
+ } else {
+ auto *spuzData = GetEngineData(SPUZ);
+ assert(spuzData);
+ _startTileOrder = spuzData->tileOrder;
+ }
+ _correctTileOrder.resize(_height);
+ for (uint y = 0; y < _height; ++y) {
+ _correctTileOrder[y].resize(_width);
+ for (uint x = 0; x < _width; ++x) {
+ _correctTileOrder[y][x] = stream.readSint16LE();
+ }
stream.skip((6 - _width) * 2);
}
-
stream.skip((6 - _height) * 6 * 2);
_clickSound.readNormal(stream);
@@ -100,16 +111,8 @@ void SliderPuzzle::execute() {
case kBegin:
init();
registerGraphics();
- if (!_puzzleState->playerHasTriedPuzzle) {
- _puzzleState->playerTileOrder.clear();
- _puzzleState->playerTileOrder.resize(_height);
- for (uint y = 0; y < _height; ++y) {
- _puzzleState->playerTileOrder[y].resize(_width);
- for (uint x = 0; x < _width; ++x) {
- _puzzleState->playerTileOrder[y][x] = _spuzData->tileOrder[NancySceneState.getDifficulty()][y * 6 + x];
- }
- }
-
+ if (!_puzzleState->playerHasTriedPuzzle || !_retainState) {
+ _puzzleState->playerTileOrder = _startTileOrder;
_puzzleState->playerHasTriedPuzzle = true;
}
@@ -166,7 +169,7 @@ void SliderPuzzle::execute() {
}
void SliderPuzzle::handleInput(NancyInput &input) {
- if (_solveState != kNotSolved) {
+ if (_state != kRun || _solveState != kNotSolved) {
return;
}
diff --git a/engines/nancy/action/puzzle/sliderpuzzle.h b/engines/nancy/action/puzzle/sliderpuzzle.h
index 3c7cffb69d7..88af4490326 100644
--- a/engines/nancy/action/puzzle/sliderpuzzle.h
+++ b/engines/nancy/action/puzzle/sliderpuzzle.h
@@ -43,7 +43,6 @@ public:
void execute() override;
void handleInput(NancyInput &input) override;
- const SPUZ *_spuzData = nullptr;
SliderPuzzleData *_puzzleState = nullptr;
Common::Path _imageName;
@@ -51,6 +50,7 @@ public:
uint16 _height = 0;
Common::Array<Common::Array<Common::Rect>> _srcRects;
Common::Array<Common::Array<Common::Rect>> _destRects;
+ Common::Array<Common::Array<int16>> _startTileOrder;
Common::Array<Common::Array<int16>> _correctTileOrder;
SoundDescription _clickSound;
SceneChangeWithFlag _solveExitScene;
@@ -58,6 +58,8 @@ public:
SceneChangeWithFlag _exitScene;
Common::Rect _exitHotspot;
+ bool _retainState = true;
+
SolveState _solveState = kNotSolved;
Graphics::ManagedSurface _image;
Commit: 2e229629099055fa499c8d1048aecbbf0e00aaac
https://github.com/scummvm/scummvm/commit/2e229629099055fa499c8d1048aecbbf0e00aaac
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2024-02-11T22:53:22+01:00
Commit Message:
NANCY: Add support for TextBoxWrite with no string
Somewhere around nancy9 (may happen earlier, too),
the TextBoxWrite record added support for reading its
string from the Autotext chunk.
Changed paths:
engines/nancy/action/miscrecords.cpp
diff --git a/engines/nancy/action/miscrecords.cpp b/engines/nancy/action/miscrecords.cpp
index 49b06464742..02bded22ea4 100644
--- a/engines/nancy/action/miscrecords.cpp
+++ b/engines/nancy/action/miscrecords.cpp
@@ -102,19 +102,29 @@ void LightningOn::execute() {
}
void TextBoxWrite::readData(Common::SeekableReadStream &stream) {
- uint16 size = stream.readUint16LE();
+ int16 size = stream.readSint16LE();
if (size > 10000) {
error("Action Record atTextboxWrite has too many text box chars: %d", size);
}
+
+ if (size == -1) {
+ Common::String stringID;
+ readFilename(stream, stringID);
+
+ const CVTX *autotext = (const CVTX *)g_nancy->getEngineData("AUTOTEXT");
+ assert(autotext);
+
+ _text = autotext->texts[stringID];
+ } else {
+ char *buf = new char[size];
+ stream.read(buf, size);
+ buf[size - 1] = '\0';
- char *buf = new char[size];
- stream.read(buf, size);
- buf[size - 1] = '\0';
-
- assembleTextLine(buf, _text, size);
+ assembleTextLine(buf, _text, size);
- delete[] buf;
+ delete[] buf;
+ }
}
void TextBoxWrite::execute() {
More information about the Scummvm-git-logs
mailing list