[Scummvm-git-logs] scummvm master -> 80c4eb59f959f94247df00acfe080757567dcffe
bluegr
noreply at scummvm.org
Tue Jun 23 17:42:45 UTC 2026
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
7868ab7fe6 NANCY: Implement RandomizeEventFlags AR for Nancy11+
47f3113ed9 NANCY: Implement the Update3DSound AR for Nancy11+
80c4eb59f9 NANCY: Implement Nancy11+ ARs StartPlayerScrolling, StopPlayerScrolling
Commit: 7868ab7fe6517a24d21643a70c18c7fe62c98d78
https://github.com/scummvm/scummvm/commit/7868ab7fe6517a24d21643a70c18c7fe62c98d78
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-23T20:42:30+03:00
Commit Message:
NANCY: Implement RandomizeEventFlags AR for Nancy11+
Changed paths:
engines/nancy/action/arfactory.cpp
engines/nancy/action/datarecords.cpp
engines/nancy/action/datarecords.h
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 3d2b434f847..836994490f8 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -290,8 +290,7 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
//warning("AutotextTextBoxWrite"); // TODO
return nullptr;
case 96: // Nancy11
- warning("UnknownAR96"); // TODO
- return nullptr;
+ return new RandomizeEventFlags();
case 97:
return new EventFlags(true);
case 98:
diff --git a/engines/nancy/action/datarecords.cpp b/engines/nancy/action/datarecords.cpp
index fec5fbc1676..b5ac2380c8c 100644
--- a/engines/nancy/action/datarecords.cpp
+++ b/engines/nancy/action/datarecords.cpp
@@ -19,6 +19,8 @@
*
*/
+#include "common/random.h"
+
#include "engines/nancy/nancy.h"
#include "engines/nancy/util.h"
@@ -396,6 +398,23 @@ void EventFlagsMultiHS::execute() {
}
}
+void RandomizeEventFlags::readData(Common::SeekableReadStream &stream) {
+ uint16 numFlags = stream.readUint16LE();
+ _flagLabels.resize(numFlags);
+ for (uint i = 0; i < numFlags; ++i) {
+ _flagLabels[i] = stream.readSint16LE();
+ }
+}
+
+void RandomizeEventFlags::execute() {
+ for (uint i = 0; i < _flagLabels.size(); ++i) {
+ NancySceneState.setEventFlag(_flagLabels[i],
+ g_nancy->_randomSource->getRandomBit() ? g_nancy->_true : g_nancy->_false);
+ }
+
+ _isDone = true;
+}
+
void DifficultyLevel::readData(Common::SeekableReadStream &stream) {
_difficulty = stream.readUint16LE();
_flag.label = stream.readSint16LE();
diff --git a/engines/nancy/action/datarecords.h b/engines/nancy/action/datarecords.h
index 9022aac7a49..9dba69646af 100644
--- a/engines/nancy/action/datarecords.h
+++ b/engines/nancy/action/datarecords.h
@@ -135,6 +135,18 @@ protected:
Common::String getRecordTypeName() const override { return _isCursor ? (_isTerse ? "EventFlagsHSTerse" : "EventFlagsCursorHS") : "EventFlagsMultiHS"; }
};
+// Nancy 11+ AR 96. Sets each of a list of event flags to a random boolean value.
+class RandomizeEventFlags : public ActionRecord {
+public:
+ void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+
+ Common::Array<int16> _flagLabels;
+
+protected:
+ Common::String getRecordTypeName() const override { return "RandomizeEventFlags"; }
+};
+
// Sets the difficulty level for the current save. Only appears at the start of the game.
// First appears in nancy1. Nancy1 and nancy2 have three difficulty values, while later games
// only have two: 0 and 2.
Commit: 47f3113ed98a6d820785b9bd7fe78262f18858a2
https://github.com/scummvm/scummvm/commit/47f3113ed98a6d820785b9bd7fe78262f18858a2
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-23T20:42:32+03:00
Commit Message:
NANCY: Implement the Update3DSound AR for Nancy11+
Changed paths:
engines/nancy/action/arfactory.cpp
engines/nancy/action/soundrecords.cpp
engines/nancy/action/soundrecords.h
engines/nancy/sound.cpp
engines/nancy/sound.h
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 836994490f8..cdb32517d49 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -400,8 +400,7 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
case 155:
return new StopSound(); // StopAndUnloadSound, but we always unload
case 156: // Nancy11
- warning("Update3DSound"); // TODO
- return nullptr;
+ return new Update3DSound();
case 157:
return new PlaySoundCC();
case 158:
diff --git a/engines/nancy/action/soundrecords.cpp b/engines/nancy/action/soundrecords.cpp
index 9a84bbbfe5d..1571a1b6375 100644
--- a/engines/nancy/action/soundrecords.cpp
+++ b/engines/nancy/action/soundrecords.cpp
@@ -74,6 +74,31 @@ void FadeSoundToSilence::execute() {
}
}
+void Update3DSound::readData(Common::SeekableReadStream &stream) {
+ _channelID = stream.readUint16LE();
+ _posX = stream.readSint32LE();
+ _posY = stream.readSint32LE();
+ _posZ = stream.readSint32LE();
+ _minDistance = stream.readSint32LE();
+ _maxDistance = stream.readSint32LE();
+}
+
+void Update3DSound::execute() {
+ if (_posX != kNoChange && _posY != kNoChange && _posZ != kNoChange) {
+ g_nancy->_sound->update3DSoundPosition(_channelID, _posX, _posY, _posZ);
+ }
+
+ if (_minDistance != kNoChange) {
+ g_nancy->_sound->update3DSoundMinDistance(_channelID, _minDistance);
+ }
+
+ if (_maxDistance != kNoChange) {
+ g_nancy->_sound->update3DSoundMaxDistance(_channelID, _maxDistance);
+ }
+
+ _isDone = true;
+}
+
void PlaySound::readData(Common::SeekableReadStream &stream) {
_sound.readDIGI(stream);
diff --git a/engines/nancy/action/soundrecords.h b/engines/nancy/action/soundrecords.h
index 02f5d34cc5a..3700c8454bb 100644
--- a/engines/nancy/action/soundrecords.h
+++ b/engines/nancy/action/soundrecords.h
@@ -58,6 +58,26 @@ private:
uint16 _startVolume = 0;
};
+// Nancy 11+ AR 156. Adjusts a playing 3D sound's position and/or its
+// min/max audible distance. A field set to kNoChange is left untouched.
+class Update3DSound : public ActionRecord {
+public:
+ void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+
+ static const int32 kNoChange = 10000;
+
+ uint16 _channelID = 0;
+ int32 _posX = 0;
+ int32 _posY = 0;
+ int32 _posZ = 0;
+ int32 _minDistance = 0;
+ int32 _maxDistance = 0;
+
+protected:
+ Common::String getRecordTypeName() const override { return "Update3DSound"; }
+};
+
// Used for sound effects. From nancy3 up it includes 3D sound data, which lets
// the sound move in 3D space as the player rotates/changes scenes. Also supports
// changing the scene and/or setting a flag
diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index 1d5f606cef3..6be6300ae40 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -532,6 +532,48 @@ void SoundManager::setVolume(const Common::String &chunkName, uint16 volume) {
setVolume(_commonSounds[chunkName], volume);
}
+void SoundManager::update3DSoundPosition(uint16 channelID, int32 x, int32 y, int32 z) {
+ if (channelID >= _channels.size())
+ return;
+
+ Channel &chan = _channels[channelID];
+
+ // The original only repositions sounds that play at a fixed point in 3D space
+ if (!chan.effectData || chan.playCommands != kPlaySequentialPosition)
+ return;
+
+ chan.effectData->fixedPosX = x;
+ chan.effectData->fixedPosY = y;
+ chan.effectData->fixedPosZ = z;
+ chan.position.set(x, y, z);
+
+ _shouldRecalculate = true;
+}
+
+void SoundManager::update3DSoundMinDistance(uint16 channelID, uint32 minDistance) {
+ if (channelID >= _channels.size())
+ return;
+
+ Channel &chan = _channels[channelID];
+ if (!chan.effectData)
+ return;
+
+ chan.effectData->minDistance = minDistance;
+ _shouldRecalculate = true;
+}
+
+void SoundManager::update3DSoundMaxDistance(uint16 channelID, uint32 maxDistance) {
+ if (channelID >= _channels.size())
+ return;
+
+ Channel &chan = _channels[channelID];
+ if (!chan.effectData)
+ return;
+
+ chan.effectData->maxDistance = maxDistance;
+ _shouldRecalculate = true;
+}
+
uint32 SoundManager::getRate(uint16 channelID) {
if (channelID >= _channels.size())
return 0;
diff --git a/engines/nancy/sound.h b/engines/nancy/sound.h
index 6f6d219081c..50f35796a54 100644
--- a/engines/nancy/sound.h
+++ b/engines/nancy/sound.h
@@ -94,6 +94,12 @@ public:
void setVolume(const SoundDescription &description, uint16 volume);
void setVolume(const Common::String &chunkName, uint16 volume);
+ // Nancy 11+ Update3DSound (AR 156). Adjusts a playing fixed-position
+ // 3D sound's position and/or its min/max audible distance.
+ void update3DSoundPosition(uint16 channelID, int32 x, int32 y, int32 z);
+ void update3DSoundMinDistance(uint16 channelID, uint32 minDistance);
+ void update3DSoundMaxDistance(uint16 channelID, uint32 maxDistance);
+
uint32 getRate(uint16 channelID);
uint32 getRate(const SoundDescription &description);
uint32 getRate(const Common::String &chunkName);
Commit: 80c4eb59f959f94247df00acfe080757567dcffe
https://github.com/scummvm/scummvm/commit/80c4eb59f959f94247df00acfe080757567dcffe
Author: Filippos Karapetis (bluegr at gmail.com)
Date: 2026-06-23T20:42:34+03:00
Commit Message:
NANCY: Implement Nancy11+ ARs StartPlayerScrolling, StopPlayerScrolling
This is used to disable viewport movement entirely.
Since this flag is now synced in saved games, this will *break* existing
Nancy11 saved games
Changed paths:
engines/nancy/action/arfactory.cpp
engines/nancy/action/miscrecords.cpp
engines/nancy/action/miscrecords.h
engines/nancy/state/scene.cpp
engines/nancy/state/scene.h
engines/nancy/ui/viewport.cpp
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index cdb32517d49..f12443812a0 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -181,11 +181,9 @@ ActionRecord *ActionManager::createActionRecord(uint16 type, Common::SeekableRea
// Nancy 10+
return new ControlUIItems();
case 30: // Nancy11
- warning("StopPlayerScrolling"); // TODO
- return nullptr;
+ return new StopPlayerScrolling();
case 31: // Nancy11
- warning("StartPlayerScrolling"); // TODO
- return nullptr;
+ return new StartPlayerScrolling();
case 32:
// Nancy 10+
return new UIPopupPrepScene();
diff --git a/engines/nancy/action/miscrecords.cpp b/engines/nancy/action/miscrecords.cpp
index 7ac1e104dcd..bdb2ce9b121 100644
--- a/engines/nancy/action/miscrecords.cpp
+++ b/engines/nancy/action/miscrecords.cpp
@@ -413,6 +413,24 @@ void StopTimer::execute() {
_isDone = true;
}
+void StopPlayerScrolling::readData(Common::SeekableReadStream &stream) {
+ stream.skip(1);
+}
+
+void StopPlayerScrolling::execute() {
+ NancySceneState.setPlayerScrolling(false);
+ _isDone = true;
+}
+
+void StartPlayerScrolling::readData(Common::SeekableReadStream &stream) {
+ stream.skip(1);
+}
+
+void StartPlayerScrolling::execute() {
+ NancySceneState.setPlayerScrolling(true);
+ _isDone = true;
+}
+
void GotoMenu::readData(Common::SeekableReadStream &stream) {
stream.skip(1);
}
diff --git a/engines/nancy/action/miscrecords.h b/engines/nancy/action/miscrecords.h
index b5dd38cc958..ac589091ae9 100644
--- a/engines/nancy/action/miscrecords.h
+++ b/engines/nancy/action/miscrecords.h
@@ -293,6 +293,27 @@ protected:
Common::String getRecordTypeName() const override { return "StopTimer"; }
};
+// Nancy 11+ AR 30. Disables the player's ability to scroll/pan the viewport
+// (both mouse-edge and keyboard movement). State persists across scene changes.
+class StopPlayerScrolling : public ActionRecord {
+public:
+ void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+
+protected:
+ Common::String getRecordTypeName() const override { return "StopPlayerScrolling"; }
+};
+
+// Nancy 11+ AR 31. Re-enables the player's ability to scroll/pan the viewport.
+class StartPlayerScrolling : public ActionRecord {
+public:
+ void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+
+protected:
+ Common::String getRecordTypeName() const override { return "StartPlayerScrolling"; }
+};
+
// Returns the player back to the main menu
class GotoMenu : public ActionRecord {
public:
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index 503c202f03d..11368fef74f 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -822,6 +822,8 @@ void Scene::synchronize(Common::Serializer &ser) {
}
}
+ ser.syncAsByte(_playerScrollingEnabled, kGameTypeNancy11);
+
_isRunningAd = false;
ConfMan.removeKey("restore_after_ad", Common::ConfigManager::kTransientDomain);
@@ -1315,6 +1317,9 @@ void Scene::initStaticData() {
auto *bootSummary = GetEngineData(BSUM);
assert(bootSummary);
+ // Nancy 11+ AR 30/31. Player scrolling defaults to enabled at game start.
+ _playerScrollingEnabled = true;
+
Common::Path imageName = "FRAME";
if (g_nancy->getGameType() <= kGameTypeNancy9) {
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index 049557d6f61..f99ba40d4d9 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -170,6 +170,11 @@ public:
Time getMovementTimeDelta(bool fast) const { return fast ? _sceneState.summary.fastMoveTimeDelta : _sceneState.summary.slowMoveTimeDelta; }
+ // Nancy 11+ AR 30/31. Toggles whether the player may scroll/pan the viewport.
+ // Persists across scene changes until changed by another StartPlayerScrolling/StopPlayerScrolling.
+ void setPlayerScrolling(bool enabled) { _playerScrollingEnabled = enabled; }
+ bool getPlayerScrolling() const { return _playerScrollingEnabled; }
+
void registerGraphics();
void synchronize(Common::Serializer &serializer);
@@ -333,6 +338,9 @@ private:
bool _destroyOnExit;
bool _isRunningAd;
+ // Nancy 11+ AR 30/31. Whether the player is currently allowed to scroll the viewport.
+ bool _playerScrollingEnabled = true;
+
State _state;
};
diff --git a/engines/nancy/ui/viewport.cpp b/engines/nancy/ui/viewport.cpp
index 5d67681aad8..fc7e1b116d1 100644
--- a/engines/nancy/ui/viewport.cpp
+++ b/engines/nancy/ui/viewport.cpp
@@ -185,6 +185,11 @@ void Viewport::handleInput(NancyInput &input) {
}
}
+ // Nancy 11+ StopPlayerScrolling/StartPlayerScrolling can disable viewport movement entirely
+ if (!NancySceneState.getPlayerScrolling()) {
+ direction = 0;
+ }
+
// Perform the movement
if (direction) {
Time movementDelta = NancySceneState.getMovementTimeDelta(direction & kMoveFast);
More information about the Scummvm-git-logs
mailing list