[Scummvm-git-logs] scummvm master -> 4496a7603ef7a75f0bc43ba8f5892898e3213966
sev-
noreply at scummvm.org
Thu Jun 26 11:15:04 UTC 2025
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
a74081db69 DIRECTOR: XOBJ: Make FileIO always read from the data fork
4d9b0e8d0a DIRECTOR: LINGO: Move _skipFrameAdvance to Window
e89317fb94 DIRECTOR: LINGO: Improve accuracy of setting the memberNum
f88d432f7f DIRECTOR: LINGO: Fix resolveScriptEvent for mouseEnter/mouseLeave
4496a7603e DIRECTOR: Fix BITDDecoder for 16/24 bit images
Commit: a74081db69f3a88ec24f677a70b9b4ec0e85d23a
https://github.com/scummvm/scummvm/commit/a74081db69f3a88ec24f677a70b9b4ec0e85d23a
Author: Scott Percival (code at moral.net.au)
Date: 2025-06-26T13:14:58+02:00
Commit Message:
DIRECTOR: XOBJ: Make FileIO always read from the data fork
Fixes loading sequence in Plates are People Too.
Changed paths:
engines/director/lingo/xlibs/fileio.cpp
diff --git a/engines/director/lingo/xlibs/fileio.cpp b/engines/director/lingo/xlibs/fileio.cpp
index 7a5ac3781e1..08a768591b1 100644
--- a/engines/director/lingo/xlibs/fileio.cpp
+++ b/engines/director/lingo/xlibs/fileio.cpp
@@ -122,6 +122,7 @@ delete object me -- deletes the open file
*/
#include "common/file.h"
+#include "common/macresman.h"
#include "common/memstream.h"
#include "common/savefile.h"
#include "image/pict.h"
@@ -264,13 +265,12 @@ FileIOError FileObject::open(const Common::String &origpath, const Common::Strin
_inStream = saves->openForLoading(filename);
if (!_inStream) {
// Maybe we're trying to read one of the game files
- Common::File *f = new Common::File;
Common::Path location = findPath(origpath);
- if (location.empty() || !f->open(location)) {
- delete f;
+ Common::SeekableReadStream *file = Common::MacResManager::openFileOrDataFork(location);
+ if (!file) {
return saveFileError();
}
- _inStream = f;
+ _inStream = file;
}
} else if (option.equalsIgnoreCase("write")) {
// OutSaveFile is not seekable so create a separate seekable stream
@@ -283,13 +283,12 @@ FileIOError FileObject::open(const Common::String &origpath, const Common::Strin
} else if (option.equalsIgnoreCase("append")) {
Common::SeekableReadStream *inFile = saves->openForLoading(filename);
if (!inFile) {
- Common::File *f = new Common::File;
-
- if (!f->open(Common::Path(origpath, g_director->_dirSeparator))) {
- delete f;
+ Common::Path location = findPath(origpath);
+ Common::SeekableReadStream *file = Common::MacResManager::openFileOrDataFork(location);
+ if (!file) {
return saveFileError();
}
- inFile = f;
+ inFile = file;
}
_outStream = new Common::MemoryWriteStreamDynamic(DisposeAfterUse::YES);
byte b = inFile->readByte();
Commit: 4d9b0e8d0a7a1d6c6a0ec61e3c2379b8821f116d
https://github.com/scummvm/scummvm/commit/4d9b0e8d0a7a1d6c6a0ec61e3c2379b8821f116d
Author: Scott Percival (code at moral.net.au)
Date: 2025-06-26T13:14:58+02:00
Commit Message:
DIRECTOR: LINGO: Move _skipFrameAdvance to Window
It is possible for a script to use c_tell to call "go to X" inside a
child window. The switched window will be preserved, however
_skipFrameAdvance will be intercepted by the original window and miss a
call to exitFrame.
Fixes navigation in Gus Goes to the Megarific Museum.
Changed paths:
engines/director/director.cpp
engines/director/director.h
engines/director/lingo/lingo-events.cpp
engines/director/lingo/lingo-funcs.cpp
engines/director/lingo/lingo-the.cpp
engines/director/score.cpp
engines/director/window.cpp
engines/director/window.h
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 2a75102d985..91d8bb11330 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -156,7 +156,6 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
}
_playbackPaused = false;
- _skipFrameAdvance = false;
_centerStage = true;
_surface = nullptr;
diff --git a/engines/director/director.h b/engines/director/director.h
index ed4807f129f..4ef8f27c87e 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -266,7 +266,6 @@ public:
Common::HashMap<int, int> _KeyCodes;
int _machineType;
bool _playbackPaused;
- bool _skipFrameAdvance;
bool _centerStage;
char _dirSeparator;
bool _fixStageSize;
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index c4452e4ea9f..018e6b7406e 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -544,7 +544,7 @@ void Lingo::processEvents(Common::Queue<LingoEvent> &queue, bool isInputEvent) {
if (isInputEvent && !completed) {
debugC(5, kDebugEvents, "Lingo::processEvents: context frozen on an input event, stopping");
LingoState *state = g_director->getCurrentWindow()->getLastFrozenLingoState();
- if (state) {
+ if (state && !state->callstack.empty()) {
_currentInputEvent = state->callstack.front()->sp;
}
break;
diff --git a/engines/director/lingo/lingo-funcs.cpp b/engines/director/lingo/lingo-funcs.cpp
index 76bedbb6bd2..96b318ef69c 100644
--- a/engines/director/lingo/lingo-funcs.cpp
+++ b/engines/director/lingo/lingo-funcs.cpp
@@ -49,9 +49,9 @@ void Lingo::func_goto(Datum &frame, Datum &movie, bool calledfromgo) {
return;
Window *stage = _vm->getCurrentWindow();
- Score *score = _vm->getCurrentMovie()->getScore();
+ Score *score = stage->getCurrentMovie()->getScore();
- _vm->_skipFrameAdvance = true;
+ stage->_skipFrameAdvance = true;
// If there isn't already frozen Lingo (e.g. from a previous func_goto we haven't yet unfrozen),
// freeze this script context. We'll return to it after entering the next frame.
@@ -110,34 +110,37 @@ void Lingo::func_goto(Datum &frame, Datum &movie, bool calledfromgo) {
void Lingo::func_gotoloop() {
if (!_vm->getCurrentMovie())
return;
- Score *score = _vm->getCurrentMovie()->getScore();
+ Window *stage = _vm->getCurrentWindow();
+ Score *score = stage->getCurrentMovie()->getScore();
debugC(3, kDebugLingoExec, "Lingo::func_gotoloop(): looping frame %d", score->getCurrentFrameNum());
score->gotoLoop();
- _vm->_skipFrameAdvance = true;
+ stage->_skipFrameAdvance = true;
}
void Lingo::func_gotonext() {
if (!_vm->getCurrentMovie())
return;
- Score *score = _vm->getCurrentMovie()->getScore();
+ Window *stage = _vm->getCurrentWindow();
+ Score *score = stage->getCurrentMovie()->getScore();
score->gotoNext();
debugC(3, kDebugLingoExec, "Lingo::func_gotonext(): going to next frame %d", score->getNextFrame());
- _vm->_skipFrameAdvance = true;
+ stage->_skipFrameAdvance = true;
}
void Lingo::func_gotoprevious() {
if (!_vm->getCurrentMovie())
return;
- Score *score = _vm->getCurrentMovie()->getScore();
+ Window *stage = _vm->getCurrentWindow();
+ Score *score = stage->getCurrentMovie()->getScore();
score->gotoPrevious();
debugC(3, kDebugLingoExec, "Lingo::func_gotoprevious(): going to previous frame %d", score->getNextFrame());
- _vm->_skipFrameAdvance = true;
+ stage->_skipFrameAdvance = true;
}
void Lingo::func_play(Datum &frame, Datum &movie) {
@@ -198,7 +201,8 @@ void Lingo::func_play(Datum &frame, Datum &movie) {
}
void Lingo::func_cursor(Datum cursorDatum) {
- Score *score = _vm->getCurrentMovie()->getScore();
+ Window *stage = _vm->getCurrentWindow();
+ Score *score = stage->getCurrentMovie()->getScore();
if (cursorDatum.type == ARRAY){
score->_defaultCursor.readFromCast(cursorDatum);
} else {
@@ -219,14 +223,16 @@ int Lingo::func_marker(int m) {
if (!_vm->getCurrentMovie())
return 0;
- int labelNumber = _vm->getCurrentMovie()->getScore()->getCurrentLabelNumber();
+ Window *stage = _vm->getCurrentWindow();
+ Score *score = stage->getCurrentMovie()->getScore();
+ int labelNumber = score->getCurrentLabelNumber();
if (m != 0) {
if (m < 0) {
for (int marker = 0; marker > m; marker--)
- labelNumber = _vm->getCurrentMovie()->getScore()->getPreviousLabelNumber(labelNumber);
+ labelNumber = score->getPreviousLabelNumber(labelNumber);
} else {
for (int marker = 0; marker < m; marker++)
- labelNumber = _vm->getCurrentMovie()->getScore()->getNextLabelNumber(labelNumber);
+ labelNumber = score->getNextLabelNumber(labelNumber);
}
}
@@ -234,7 +240,8 @@ int Lingo::func_marker(int m) {
}
uint16 Lingo::func_label(Datum &label) {
- Score *score = _vm->getCurrentMovie()->getScore();
+ Window *stage = _vm->getCurrentWindow();
+ Score *score = stage->getCurrentMovie()->getScore();
if (!score->_labels)
return 0;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 4e2287bc8aa..b4724186ac9 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -777,9 +777,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
// TODO: How is this handled with multiple casts in D5?
Common::Point pos = g_director->getCurrentWindow()->getMousePos();
uint16 spriteId = score->getSpriteIDFromPos(pos);
- d = score->getSpriteById(spriteId)->_castId.member;
- if (d.u.i == 0)
- d = -1;
+ if (spriteId) {
+ d = score->getSpriteById(spriteId)->_castId.toMultiplex();
+ } else {
+ d = 0;
+ }
}
break;
case kTheMouseChar:
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 19d669b198d..5df4c1a6d78 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -138,7 +138,10 @@ bool Score::processFrozenPlayScript() {
if (g_lingo->_playDone) {
g_lingo->_playDone = false;
if (_window->thawLingoPlayState()) {
- Symbol currentScript = _window->getLingoState()->callstack.front()->sp;
+ Symbol currentScript;
+ LingoState *state = _window->getLingoState();
+ if (state && !state->callstack.empty())
+ currentScript = state->callstack.front()->sp;
g_lingo->switchStateFromWindow();
bool completed = g_lingo->execute();
if (!completed) {
@@ -166,7 +169,9 @@ bool Score::processFrozenScripts(bool recursion, int count) {
while (remainCount && (limit ? count > 0 : true)) {
_window->thawLingoState();
LingoState *state = _window->getLingoState();
- Symbol currentScript = state->callstack.front()->sp;
+ Symbol currentScript;
+ if (state && !state->callstack.empty())
+ currentScript = state->callstack.front()->sp;
g_lingo->switchStateFromWindow();
bool completed = g_lingo->execute();
if (!completed || (recursion ? _window->frozenLingoRecursionCount() : _window->frozenLingoStateCount()) >= remainCount) {
@@ -245,7 +250,7 @@ void Score::gotoLoop() {
_nextFrame = _currentLabel;
}
- _vm->_skipFrameAdvance = true;
+ _window->_skipFrameAdvance = true;
}
int Score::getCurrentLabelNumber() {
@@ -437,7 +442,7 @@ void Score::updateCurrentFrame() {
}
_nextFrame = 0;
- _vm->_skipFrameAdvance = false;
+ _window->_skipFrameAdvance = false;
if (nextFrameNumberToLoad >= getFramesNum()) {
Window *window = _vm->getCurrentWindow();
@@ -595,7 +600,7 @@ void Score::update() {
// When Lingo::func_goto* is called, _nextFrame is set
// and _skipFrameAdvance is set to true.
// exitFrame is not called in this case.
- if (!_vm->_skipFrameAdvance && !_exitFrameCalled) {
+ if (!_window->_skipFrameAdvance && !_exitFrameCalled) {
// Exit the current frame. This can include scopeless ScoreScripts.
_movie->processEvent(kEventExitFrame);
_exitFrameCalled = true;
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index d5ecf6a0c86..940f61ddf3b 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -61,6 +61,7 @@ Window::Window(int id, bool scrollable, bool resizable, bool editable, Graphics:
_windowType = -1;
_isModal = false;
+ _skipFrameAdvance = false;
updateBorderType();
@@ -740,6 +741,8 @@ uint32 Window::frozenLingoRecursionCount() {
for (int i = (int)_frozenLingoStates.size() - 1; i >= 0; i--) {
LingoState *state = _frozenLingoStates[i];
+ if (state->callstack.empty())
+ continue;
CFrame *frame = state->callstack.front();
if (frame->sp.name->equalsIgnoreCase("enterFrame") ||
frame->sp.name->equalsIgnoreCase("stepMovie") ||
diff --git a/engines/director/window.h b/engines/director/window.h
index cc9bf44da54..574a9362cbd 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -205,6 +205,7 @@ public:
MovieReference _nextMovie;
Common::List<MovieReference> _movieStack;
bool _newMovieStarted;
+ bool _skipFrameAdvance;
private:
uint32 _stageColor;
Commit: e89317fb944399ce9955ad2264dbbc070b262414
https://github.com/scummvm/scummvm/commit/e89317fb944399ce9955ad2264dbbc070b262414
Author: Scott Percival (code at moral.net.au)
Date: 2025-06-26T13:14:58+02:00
Commit Message:
DIRECTOR: LINGO: Improve accuracy of setting the memberNum
Changed paths:
engines/director/lingo/lingo-the.cpp
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index b4724186ac9..3e2d606f8f5 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1701,9 +1701,11 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
{
CastMemberID castId = d.asMemberID();
if (field == kTheMemberNum) {
- // Setting the cast ID as a number will preserve whatever is in castLib
- // The member part will be demultiplexed if required, and the castLib portion ignored.
- castId = CastMemberID(castId.member, sprite->_castId.castLib);
+ // If the number is multiplexed with a castLib 2 or higher, the castLib will be used.
+ // Otherwise the existing castLib will be preserved.
+ if (castId.castLib == 1) {
+ castId = CastMemberID(castId.member, sprite->_castId.castLib);
+ }
} else if (field == kTheCastLibNum) {
castId = CastMemberID(sprite->_castId.member, d.asInt());
}
Commit: f88d432f7f2ba82181eee2c8a647d4df7c33e76b
https://github.com/scummvm/scummvm/commit/f88d432f7f2ba82181eee2c8a647d4df7c33e76b
Author: Scott Percival (code at moral.net.au)
Date: 2025-06-26T13:14:58+02:00
Commit Message:
DIRECTOR: LINGO: Fix resolveScriptEvent for mouseEnter/mouseLeave
A match for CastScript needs to be determined using the passed sprite
ID, not the weird mouseDown cache entry.
Fixes Cracking the Conspiracy from going nuts.
Changed paths:
engines/director/lingo/lingo-events.cpp
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 018e6b7406e..d71d8afa8db 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -269,8 +269,11 @@ void Movie::resolveScriptEvent(LingoEvent &event) {
// call, but it -does- get a mouseUp call.
// A bit unhinged, but we have a test that proves Director does this,
// so we have to do it too.
+ //
+ // mouseEnter and mouseLeave events should also defer to the value of channelId.
CastMemberID targetCast = _currentMouseDownCastID;
- if ((event.event == kEventMouseDown) || (event.event == kEventRightMouseDown)) {
+ if ((event.event == kEventMouseDown) || (event.event == kEventRightMouseDown) ||
+ (event.event == kEventMouseEnter) || (event.event == kEventMouseLeave)) {
if (!event.channelId)
return;
Sprite *sprite = _score->getSpriteById(event.channelId);
Commit: 4496a7603ef7a75f0bc43ba8f5892898e3213966
https://github.com/scummvm/scummvm/commit/4496a7603ef7a75f0bc43ba8f5892898e3213966
Author: Scott Percival (code at moral.net.au)
Date: 2025-06-26T13:14:58+02:00
Commit Message:
DIRECTOR: Fix BITDDecoder for 16/24 bit images
RLE-compressed BITD images will convert each line of a high-colour image
into multiple 8bpp planes. Presumably because the numbers are more
likely to repeat.
Fixes rendering the switches on the sewer door in Cracking the Conspiracy.
Changed paths:
engines/director/images.cpp
diff --git a/engines/director/images.cpp b/engines/director/images.cpp
index 11b196eb49a..804d02ed2b2 100644
--- a/engines/director/images.cpp
+++ b/engines/director/images.cpp
@@ -183,7 +183,7 @@ void BITDDecoder::loadPalette(Common::SeekableReadStream &stream) {
bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
int x = 0, y = 0;
- Common::Array<uint> pixels;
+ Common::Array<byte> pixels;
// Unpacking bodges for D3 and below
bool skipCompression = false;
uint32 bytesNeed = _pitch * _surface->h;
@@ -201,10 +201,11 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
skipCompression = stream.size() == bytesNeed;
}
}
+ skipCompression |= (stream.size() == bytesNeed);
// If the stream has exactly the required number of bits for this image,
// we assume it is uncompressed.
- if (stream.size() == bytesNeed || skipCompression) {
+ if (skipCompression) {
debugC(6, kDebugImages, "Skipping compression");
for (int i = 0; i < stream.size(); i++) {
pixels.push_back((int)stream.readByte());
@@ -255,6 +256,11 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
if (offset)
offset = _surface->w % 2;
+ debugC(5, kDebugImages, "BITDDecoder::loadStream: unpacked %d bytes, width: %d, height: %d, pitch: %d, bitsPerPixel: %d", pixels.size(), _surface->w, _surface->h, _pitch, _bitsPerPixel);
+ if (debugChannelSet(8, kDebugImages)) {
+ Common::hexdump(pixels.data(), (int)pixels.size());
+ }
+
uint32 color;
if (pixels.size() > 0) {
@@ -285,7 +291,7 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
break;
case 16:
- if (_version < kFileVer400) {
+ if (skipCompression) {
color = (pixels[((y * _surface->w) * 2) + x * 2]) << 8 |
(pixels[((y * _surface->w) * 2) + x * 2 + 1]);
} else {
@@ -299,7 +305,7 @@ bool BITDDecoder::loadStream(Common::SeekableReadStream &stream) {
case 32:
// if we have the issue in D3 32bpp images, then the way to fix it should be the same as 16bpp images.
// check the code above, there is different behaviour between in D4 and D3. Currently we are only using D4.
- if (_version < kFileVer400) {
+ if (skipCompression) {
color = pixels[(((y * _surface->w * 4)) + (x * 4 + 1))] << 16 |
pixels[(((y * _surface->w * 4)) + (x * 4 + 2))] << 8 |
pixels[(((y * _surface->w * 4)) + (x * 4 + 3))];
More information about the Scummvm-git-logs
mailing list