[Scummvm-git-logs] scummvm master -> 8c5ad09c1af92a6bbb9bd5231e2ce5e5c628f3d7
sev-
noreply at scummvm.org
Sun Sep 14 20:35:40 UTC 2025
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
6e39a2fc88 DIRECTOR: Switch Score to _version instead of vm->getVersion()
0ae103b567 DIRECTOR: Compute maximum number of channels used in Score
e38046806f DIRECTOR: DT: Do not show long tail of unused sprites in score
18814581c2 DIRECTOR: Load behavior details on frame loading
a5553a246c DIRECTOR: DT: Use preloaded behaviors when displaying Channels
8c5ad09c1a DIRECTOR: Read Script channel behavior
Commit: 6e39a2fc88fd9c6cd11c4e2fe293308416504e09
https://github.com/scummvm/scummvm/commit/6e39a2fc88fd9c6cd11c4e2fe293308416504e09
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-14T22:35:27+02:00
Commit Message:
DIRECTOR: Switch Score to _version instead of vm->getVersion()
Since we are dealing with the internal Score structure, I believe,
this approach is more consistent.
Changed paths:
engines/director/score.cpp
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 025d5df3c54..14b84c677f4 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -322,7 +322,7 @@ void Score::startPlay() {
return;
}
- if (_vm->getVersion() >= 300)
+ if (_version >= kFileVer300)
_movie->processEvent(kEventStartMovie);
// load first frame (either 1 or _nextFrame)
@@ -349,7 +349,7 @@ void Score::step() {
if (!_movie->_inputEventQueue.empty() && !_window->frozenLingoStateCount()) {
_lingo->processEvents(_movie->_inputEventQueue, true);
}
- if (_vm->getVersion() >= 300 && !_window->_newMovieStarted && _playState != kPlayStopped) {
+ if (_version >= kFileVer300 && !_window->_newMovieStarted && _playState != kPlayStopped) {
_movie->processEvent(kEventIdle);
}
@@ -374,7 +374,7 @@ void Score::stopPlay() {
if (_stopPlayCalled)
return;
_stopPlayCalled = true;
- if (_vm->getVersion() >= 300)
+ if (_version >= kFileVer300)
_movie->processEvent(kEventStopMovie);
_lingo->executePerFrameHook(-1, 0);
}
@@ -482,7 +482,7 @@ void Score::updateCurrentFrame() {
// Cache the previous bounding box for the purposes of rollOver.
// If the sprite is blank, D4 and below will use whatever the previous valid bounding
// box was for rollOver testing.
- if (g_director->getVersion() < 500) {
+ if (_version < kFileVer500) {
for (uint ch = 0; ch < _channels.size(); ch++) {
if (_channels[ch]->_sprite->_castId.member != 0) {
_channels[ch]->_rollOverBbox = _channels[ch]->getBbox();
@@ -524,11 +524,11 @@ void Score::updateNextFrameTime() {
}
if (tempo) {
- const bool waitForClickOnly = _vm->getVersion() < 300;
+ const bool waitForClickOnly = _version < kFileVer300;
int maxDelay = 60;
- if (_vm->getVersion() < 300) {
+ if (_version < kFileVer300) {
maxDelay = 120;
- } else if (_vm->getVersion() < 400) {
+ } else if (_version < kFileVer400) {
// Director 3 has a slider that goes up to 120, but any value
// beyond 95 gets converted into a video wait instruction.
maxDelay = 95;
@@ -650,7 +650,7 @@ void Score::update() {
uint32 count = _window->frozenLingoStateCount();
// Director 4 and below will allow infinite recursion via the perFrameHook.
- if (_vm->getVersion() < 500) {
+ if (_version < kFileVer500) {
// new frame, first call the perFrameHook (if one exists)
if (!_window->_newMovieStarted && !_vm->_playbackPaused) {
// Call the perFrameHook as soon as a frame switch is done.
@@ -665,7 +665,7 @@ void Score::update() {
}
// Check to see if we've hit the recursion limit
- if (_vm->getVersion() >= 400 && _window->frozenLingoRecursionCount() >= 2) {
+ if (_version >= kFileVer400 && _window->frozenLingoRecursionCount() >= 2) {
debugC(1, kDebugEvents, "Score::update(): hitting D4 recursion depth limit, defrosting");
processFrozenScripts(true);
return;
@@ -676,7 +676,7 @@ void Score::update() {
}
// Director 5 and above actually check for recursion for the perFrameHook.
- if (_vm->getVersion() >= 500) {
+ if (_version >= kFileVer500) {
// new frame, first call the perFrameHook (if one exists)
if (!_window->_newMovieStarted && !_vm->_playbackPaused) {
// Call the perFrameHook as soon as a frame switch is done.
@@ -690,7 +690,7 @@ void Score::update() {
return;
}
- if (_vm->getVersion() >= 600) {
+ if (_version >= kFileVer600) {
// _movie->processEvent(kEventBeginSprite);
// TODO: Director 6 step: send beginSprite event to any sprites whose span begin in the upcoming frame
// _movie->processEvent(kEventPrepareFrame);
@@ -704,7 +704,7 @@ void Score::update() {
// then call the stepMovie hook (if one exists)
// D4 and above only call it if _allowOutdatedLingo is enabled.
count = _window->frozenLingoStateCount();
- if (!_vm->_playbackPaused && (_vm->getVersion() < 400 || _movie->_allowOutdatedLingo)) {
+ if (!_vm->_playbackPaused && (_version < kFileVer400 || _movie->_allowOutdatedLingo)) {
_movie->processEvent(kEventStepMovie);
}
// If this stepMovie call is frozen, drop the next enterFrame event
@@ -712,7 +712,7 @@ void Score::update() {
return;
// If we've hit the recursion limit, don't enterFrame
- if (_vm->getVersion() >= 400 && _window->frozenLingoRecursionCount() >= 2) {
+ if (_version >= kFileVer400 && _window->frozenLingoRecursionCount() >= 2) {
debugC(1, kDebugEvents, "Score::update: exiting early due to recursion depth limit");
return;
}
@@ -721,7 +721,7 @@ void Score::update() {
count = _window->frozenLingoStateCount();
if (!_vm->_playbackPaused) {
_exitFrameCalled = false;
- if (_vm->getVersion() >= 400) {
+ if (_version >= kFileVer400) {
_movie->processEvent(kEventEnterFrame);
}
}
@@ -930,7 +930,7 @@ bool Score::renderPrePaletteCycle(RenderMode mode) {
int frameDelay = 1000 / 60;
int fadeFrames = kFadeColorFrames[frameRate - 1];
- if (_vm->getVersion() >= 500)
+ if (_version >= kFileVer500)
fadeFrames = kFadeColorFramesD5[frameRate - 1];
byte calcPal[768];
@@ -1260,7 +1260,7 @@ void Score::renderPaletteCycle(RenderMode mode) {
int frameDelay = 1000 / 60;
int fadeFrames = kFadeColorFrames[frameRate - 1];
- if (_vm->getVersion() >= 500)
+ if (_version >= kFileVer500)
fadeFrames = kFadeColorFramesD5[frameRate - 1];
// Wait for a fixed time
@@ -1725,7 +1725,7 @@ void Score::playSoundChannel(bool puppetOnly) {
}
// Channels above 2 are only usable by Lingo.
- if (g_director->getVersion() >= 300) {
+ if (_version >= kFileVer300) {
sound->playPuppetSound(3);
sound->playPuppetSound(4);
}
@@ -1932,7 +1932,7 @@ bool Score::readOneFrame() {
while (frameSize != 0) {
- if (_vm->getVersion() < 400) {
+ if (_version < kFileVer400) {
channelSize = _framesStream->readByte() * 2;
channelOffset = _framesStream->readByte() * 2;
frameSize -= channelSize + 2;
Commit: 0ae103b567742bd5851678943f55c43537541b3c
https://github.com/scummvm/scummvm/commit/0ae103b567742bd5851678943f55c43537541b3c
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-14T22:35:27+02:00
Commit Message:
DIRECTOR: Compute maximum number of channels used in Score
Changed paths:
engines/director/score.cpp
engines/director/score.h
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 14b84c677f4..4e0ca9699b5 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1751,6 +1751,7 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
}
_frameDataOffset = 0;
+ _maxChannelsUsed = 0;
if (version < kFileVer400) {
_framesStreamSize = _framesStream->readUint32();
@@ -1844,6 +1845,11 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
// numOfFrames in the header is often incorrect
for (_numFrames = 1; loadFrame(_numFrames, false); _numFrames++) {
_scoreCache.push_back(new Frame(*_currentFrame));
+
+ for (int i = 0; i < _currentFrame->_sprites.size(); i++) {
+ if (_currentFrame->_sprites[i]->_castId.member && i > _maxChannelsUsed)
+ _maxChannelsUsed = i;
+ }
}
debugC(1, kDebugLoading, "Score::loadFrames(): Calculated, total number of frames %d!", _numFrames);
diff --git a/engines/director/score.h b/engines/director/score.h
index 342cbda65f1..5c28448e35f 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -255,6 +255,8 @@ public:
int16 _numChannelsDisplayed; // D7+, no-op in earlier versions
// 20 bytes in total
+ int16 _maxChannelsUsed; // max channel number used in the score, used to optimize rendering
+
uint _firstFramePosition;
uint _indexStart = 0;
uint _frameDataOffset = 0;
Commit: e38046806f567f2e9cce9591c3783c80d67f65b5
https://github.com/scummvm/scummvm/commit/e38046806f567f2e9cce9591c3783c80d67f65b5
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-14T22:35:27+02:00
Commit Message:
DIRECTOR: DT: Do not show long tail of unused sprites in score
Changed paths:
engines/director/debugger.cpp
engines/director/debugger/dt-score.cpp
diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 0a9ca695d04..96ecce2e850 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -332,7 +332,7 @@ bool Debugger::cmdMovie(int argc, const char **argv) {
bool Debugger::cmdChannels(int argc, const char **argv) {
Score *score = g_director->getCurrentMovie()->getScore();
- int maxSize = (int)score->getFramesNum();
+ int maxSize = MIN<int>(score->_maxChannelsUsed + 3, score->_scoreCache[0]->_sprites.size());
int frameId = score->getCurrentFrameNum();
if (argc == 1) {
debugPrintf("Channel info for current frame %d of %d\n", frameId, maxSize);
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index fa78b61a109..199d5d19e64 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -571,7 +571,7 @@ void showScore() {
ImGui::EndChild();
}
- uint numChannels = score->_scoreCache[0]->_sprites.size();
+ uint numChannels = MIN<int>(score->_scoreCache[0]->_sprites.size(), score->_maxChannelsUsed + 10);
uint tableColumns = MAX(numFrames + 5, 25U); // Set minimal table width to 25
if (tableColumns > kMaxColumnsInTable - 3) // Current restriction of ImGui
@@ -793,7 +793,8 @@ void showChannels() {
ImGui::TableSetupColumn("movieTime", flags);
ImGui::TableAngledHeadersRow();
- for (int i = 0; i < frame._numChannels; i++) {
+
+ for (int i = 0; i < MIN<int>(frame._numChannels, score->_maxChannelsUsed + 10); i++) {
Channel &channel = *score->_channels[i + 1];
Sprite &sprite = *channel._sprite;
Commit: 18814581c258ef41b526e7f3e7035a8f63972706
https://github.com/scummvm/scummvm/commit/18814581c258ef41b526e7f3e7035a8f63972706
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-14T22:35:27+02:00
Commit Message:
DIRECTOR: Load behavior details on frame loading
Changed paths:
engines/director/score.cpp
engines/director/score.h
engines/director/sprite.cpp
engines/director/sprite.h
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 4e0ca9699b5..bd311902e27 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1861,6 +1861,35 @@ void Score::loadFrames(Common::SeekableReadStreamEndian &stream, uint16 version)
debugC(1, kDebugLoading, "Score::loadFrames(): Number of frames: %d, framesStreamSize: %d", _numFrames, _framesStreamSize);
}
+void Score::loadFrameSpriteDetails() {
+ for (int i = 0; i < _currentFrame->_sprites.size(); i++) {
+ Sprite *sprite = _currentFrame->_sprites[i];
+ if (sprite->_spriteListIdx) {
+ Common::MemoryReadStreamEndian *stream = getSpriteDetailsStream(sprite->_spriteListIdx + 1);
+ if (stream) {
+ BehaviorElement behavior;
+
+ while (stream->pos() < stream->size()) {
+ behavior.read(*stream);
+
+ if (behavior.initializerIndex) {
+ Common::MemoryReadStreamEndian *stream1 = getSpriteDetailsStream(behavior.initializerIndex);
+
+ if (stream1) {
+ behavior.initializerParams = stream1->readString();
+ delete stream1;
+ }
+ }
+
+ sprite->_behaviors.push_back(behavior);
+ }
+ delete stream;
+ }
+ }
+ }
+}
+
+
void Score::seekToMemberInList(int frameNum) {
if (frameNum < 1 || frameNum >= _numOfFrames) {
warning("Score::seekToMemberInList(): frameNum %d out of bounds [1, %d)", frameNum, _numOfFrames);
@@ -1907,6 +1936,9 @@ bool Score::loadFrame(int frameNum, bool loadCast) {
if (!isFrameRead)
return false;
+ if (_version >= kFileVer600)
+ loadFrameSpriteDetails();
+
// We have read the frame, now update current frame number
_curFrameNumber = targetFrame;
diff --git a/engines/director/score.h b/engines/director/score.h
index 5c28448e35f..eacf4881333 100644
--- a/engines/director/score.h
+++ b/engines/director/score.h
@@ -61,17 +61,6 @@ struct Label {
Label(Common::String name1, uint16 number1, Common::String comment1) { name = name1; number = number1; comment = comment1;}
};
-struct BehaviorElement {
- CastMemberID memberID;
- int32 initializerIndex = 0;
-
- void read(Common::ReadStreamEndian &stream) {
- memberID.castLib = (int16)stream.readUint16();
- memberID.member = (int16)stream.readUint16();
- initializerIndex = (int32)stream.readUint32();
- }
-};
-
struct TweenInfo{
int32 curvature;
int32 flags;
@@ -229,6 +218,8 @@ private:
void seekToMemberInList(int frame);
+ void loadFrameSpriteDetails();
+
public:
Common::Array<Channel *> _channels;
Common::SortedArray<Label *> *_labels;
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 009cbf98bcd..c048fb541cd 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -137,6 +137,8 @@ Sprite& Sprite::operator=(const Sprite &sprite) {
_angleRot = sprite._angleRot;
_angleSkew = sprite._angleSkew;
+ _behaviors = sprite._behaviors;
+
return *this;
}
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 99f86104651..d5d29724db4 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -63,6 +63,18 @@ enum ThicknessFlags {
kTTweened = 0x80,
};
+struct BehaviorElement {
+ CastMemberID memberID;
+ int32 initializerIndex = 0;
+ Common::String initializerParams;
+
+ void read(Common::ReadStreamEndian &stream) {
+ memberID.castLib = (int16)stream.readUint16();
+ memberID.member = (int16)stream.readUint16();
+ initializerIndex = (int32)stream.readUint32();
+ }
+};
+
class Sprite {
public:
Sprite(Frame *frame = nullptr);
@@ -156,6 +168,8 @@ public:
byte _bgColorG, _bgColorB; // R component sits in _backColor
int32 _angleRot;
int32 _angleSkew;
+
+ Common::Array<BehaviorElement> _behaviors;
};
} // End of namespace Director
Commit: a5553a246c1d5d49f5d221715c76a61dfbed93e8
https://github.com/scummvm/scummvm/commit/a5553a246c1d5d49f5d221715c76a61dfbed93e8
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-14T22:35:27+02:00
Commit Message:
DIRECTOR: DT: Use preloaded behaviors when displaying Channels
Changed paths:
engines/director/debugger/dt-score.cpp
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index 199d5d19e64..ab9425d6629 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -878,32 +878,15 @@ void showChannels() {
ImGui::TableNextColumn();
if (score->_version >= kFileVer600) {
- if (sprite._spriteListIdx) {
- Common::MemoryReadStreamEndian *stream = score->getSpriteDetailsStream(sprite._spriteListIdx + 1);
-
- if (stream) {
- BehaviorElement behavior;
- while (stream->pos() < stream->size()) {
- behavior.read(*stream);
- displayScriptRef(behavior.memberID);
- ImGui::SameLine();
-
- if (behavior.initializerIndex) {
- Common::MemoryReadStreamEndian *stream1 = score->getSpriteDetailsStream(behavior.initializerIndex);
-
- if (stream1) {
- Common::String init = stream1->readString();
- ImGui::Text("(%s)", init.c_str());
-
- delete stream1;
- } else {
- ImGui::Text("(\"\")");
- }
- }
+ if (sprite._behaviors.size() > 0) {
+ for (uint j = 0; j < sprite._behaviors.size(); j++) {
+ displayScriptRef(sprite._behaviors[j].memberID);
+ ImGui::SameLine();
+ if (sprite._behaviors[j].initializerIndex) {
+ ImGui::Text("(%s)", sprite._behaviors[j].initializerParams.c_str());
+ } else {
+ ImGui::Text("(\"\")");
}
- delete stream;
- } else {
- ImGui::Text(" ");
}
} else {
ImGui::PushID(i + 1);
Commit: 8c5ad09c1af92a6bbb9bd5231e2ce5e5c628f3d7
https://github.com/scummvm/scummvm/commit/8c5ad09c1af92a6bbb9bd5231e2ce5e5c628f3d7
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-14T22:35:28+02:00
Commit Message:
DIRECTOR: Read Script channel behavior
Changed paths:
engines/director/frame.h
engines/director/score.cpp
engines/director/sprite.h
diff --git a/engines/director/frame.h b/engines/director/frame.h
index e30f6f848ac..40d47b9cf1b 100644
--- a/engines/director/frame.h
+++ b/engines/director/frame.h
@@ -95,9 +95,22 @@ struct PaletteInfo {
}
};
+struct BehaviorElement {
+ CastMemberID memberID;
+ int32 initializerIndex = 0;
+ Common::String initializerParams;
+
+ void read(Common::ReadStreamEndian &stream) {
+ memberID.castLib = (int16)stream.readUint16();
+ memberID.member = (int16)stream.readUint16();
+ initializerIndex = (int32)stream.readUint32();
+ }
+};
+
struct MainChannels {
CastMemberID actionId;
uint32 scriptSpriteListIdx; // D6+
+ BehaviorElement behavior; // D6+
uint16 transDuration;
uint8 transArea; // 1 - Whole Window, 0 - Changing Area
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index bd311902e27..7145a8a3f28 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -1887,6 +1887,23 @@ void Score::loadFrameSpriteDetails() {
}
}
}
+
+ if (_currentFrame->_mainChannels.scriptSpriteListIdx) {
+ Common::MemoryReadStreamEndian *stream = getSpriteDetailsStream(_currentFrame->_mainChannels.scriptSpriteListIdx);
+ if (stream) {
+ _currentFrame->_mainChannels.behavior.read(*stream);
+ delete stream;
+
+ if (_currentFrame->_mainChannels.behavior.initializerIndex) {
+ Common::MemoryReadStreamEndian *stream1 = getSpriteDetailsStream(_currentFrame->_mainChannels.behavior.initializerIndex);
+
+ if (stream1) {
+ _currentFrame->_mainChannels.behavior.initializerParams = stream1->readString();
+ delete stream1;
+ }
+ }
+ }
+ }
}
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index d5d29724db4..379d6584bfc 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -63,18 +63,7 @@ enum ThicknessFlags {
kTTweened = 0x80,
};
-struct BehaviorElement {
- CastMemberID memberID;
- int32 initializerIndex = 0;
- Common::String initializerParams;
-
- void read(Common::ReadStreamEndian &stream) {
- memberID.castLib = (int16)stream.readUint16();
- memberID.member = (int16)stream.readUint16();
- initializerIndex = (int32)stream.readUint32();
- }
-};
-
+struct BehaviorElement;
class Sprite {
public:
Sprite(Frame *frame = nullptr);
More information about the Scummvm-git-logs
mailing list