[Scummvm-git-logs] scummvm master -> 1ee443b999325ef6771e7f063180e167853b2bbb
sev-
noreply at scummvm.org
Mon Aug 24 22:59:55 UTC 2026
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:
3625b9f8c4 DIRECTOR: Don't abort on inside() with a non-point/rect argument
0f093d095d DIRECTOR: Stop fixed text sprites growing on every widget rebuild
b52fb55377 DIRECTOR: Compare points, rects and linear lists by value in Lingo equality
7e15d8fd17 DIRECTOR: Return the intersection rect from the intersect() builtin
4555fe218b DIRECTOR: Implement MovUtils mStageToCast
1ee443b999 DIRECTOR: Track cast size and registration when the picture changes
Commit: 3625b9f8c4b7c1d739c97e6968c4de2a33097039
https://github.com/scummvm/scummvm/commit/3625b9f8c4b7c1d739c97e6968c4de2a33097039
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-08-25T00:59:49+02:00
Commit Message:
DIRECTOR: Don't abort on inside() with a non-point/rect argument
inside() ran TYPECHECK on its arguments and returned without a value when one
was not a POINT/RECT (e.g. the rect of a sprite whose number is void before its
init handler runs), which the FBLTIN dispatch turns into a fatal error. Return
FALSE instead.
Fixes an abort in Gus Paint.
Changed paths:
engines/director/lingo/lingo-builtins.cpp
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 10925e4c0a0..1d9999b108e 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3855,8 +3855,15 @@ void LB::b_inside(int nargs) {
Datum d;
Datum r2 = g_lingo->pop();
Datum p1 = g_lingo->pop();
- TYPECHECK(r2, RECT);
- TYPECHECK(p1, POINT);
+
+ // A sprite reference can be void before its init handler runs, giving a void
+ // rect; return FALSE rather than aborting the builtin with no value.
+ if (p1.type != POINT || r2.type != RECT) {
+ warning("LB::b_inside(): expected a point and a rect, got %s and %s", p1.type2str(), r2.type2str());
+ d = 0;
+ g_lingo->push(d);
+ return;
+ }
Common::Rect rect2(r2.u.farr->arr[0].asInt(), r2.u.farr->arr[1].asInt(), r2.u.farr->arr[2].asInt(), r2.u.farr->arr[3].asInt());
Common::Point point1(p1.u.farr->arr[0].asInt(), p1.u.farr->arr[1].asInt());
Commit: 0f093d095d6728fefe0087d37fc8e6cf2014ef4d
https://github.com/scummvm/scummvm/commit/0f093d095d6728fefe0087d37fc8e6cf2014ef4d
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-08-25T00:59:49+02:00
Commit Message:
DIRECTOR: Stop fixed text sprites growing on every widget rebuild
replaceWidget wrote the widget's shadow-inflated dims back to the sprite for
all text, so a fixed text field rebuilt every frame crept larger and larger.
Gate that writeback on !getFixDims(), matching updateTextCast.
Fixes the text tool's input box growing on each keystroke in Gus Paint.
Changed paths:
engines/director/channel.cpp
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 7587340aea5..83b86879347 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -772,8 +772,10 @@ void Channel::replaceWidget(CastMemberID previousCastId, bool force) {
_widget->_priority = _priority;
_widget->draw();
- if (_sprite->_cast->_type == kCastText || _sprite->_cast->_type == kCastButton) {
-
+ // Only auto-expanding text (and buttons) size the sprite from the widget:
+ // fixed text would re-add its shadow chrome each rebuild and creep larger.
+ if (_sprite->_cast->_type == kCastButton ||
+ (_sprite->_cast->_type == kCastText && !((Graphics::MacText *)_widget)->getFixDims())) {
_sprite->_width = _widget->_dims.width();
_sprite->_height = _widget->_dims.height();
}
Commit: b52fb55377d896fe76b11e46e1fac8163e527538
https://github.com/scummvm/scummvm/commit/b52fb55377d896fe76b11e46e1fac8163e527538
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-08-25T00:59:49+02:00
Commit Message:
DIRECTOR: Compare points, rects and linear lists by value in Lingo equality
Datum::equalTo() had no case for POINT, RECT or ARRAY, so getAlignedType()
returned the list type and the comparison fell through to the default,
always returning 0. This made "=" between two rects (or points, or lists)
never true. Compare them element by element instead.
Changed paths:
engines/director/lingo/lingo.cpp
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 85fcb6633b9..7093e82ab41 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1465,6 +1465,17 @@ int Datum::equalTo(const Datum &d, bool ignoreCase) const {
} else {
return compareStringEquality(asString(), d.asString());
}
+ case ARRAY:
+ case POINT:
+ case RECT:
+ // Compare element by element.
+ if (u.farr->arr.size() != d.u.farr->arr.size())
+ return 0;
+ for (uint i = 0; i < u.farr->arr.size(); i++) {
+ if (!u.farr->arr[i].equalTo(d.u.farr->arr[i], ignoreCase))
+ return 0;
+ }
+ return 1;
case MEDIA:
case OBJECT:
return u.obj == d.u.obj;
Commit: 7e15d8fd17acafc026d1a552326d38b86a9b2e4b
https://github.com/scummvm/scummvm/commit/7e15d8fd17acafc026d1a552326d38b86a9b2e4b
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-08-25T00:59:49+02:00
Commit Message:
DIRECTOR: Return the intersection rect from the intersect() builtin
intersect() was returning the boolean result of Rect::intersects() rather
than the overlapping rectangle. Return the intersection as a rect (or
rect(0,0,0,0) when the rects do not overlap), matching Lingo semantics.
Fixes the paint tools not drawing in Gus Paint.
Changed paths:
engines/director/lingo/lingo-builtins.cpp
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 1d9999b108e..908ff385023 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3817,7 +3817,15 @@ void LB::b_intersect(int nargs) {
Common::Rect rect1(r1.u.farr->arr[0].asInt(), r1.u.farr->arr[1].asInt(), r1.u.farr->arr[2].asInt(), r1.u.farr->arr[3].asInt());
Common::Rect rect2(r2.u.farr->arr[0].asInt(), r2.u.farr->arr[1].asInt(), r2.u.farr->arr[2].asInt(), r2.u.farr->arr[3].asInt());
- d = rect1.intersects(rect2);
+ // Return the overlapping area as a rect (rect(0,0,0,0) if none).
+ Common::Rect inter = rect1.findIntersectingRect(rect2);
+
+ d.type = RECT;
+ d.u.farr = new FArray;
+ d.u.farr->arr.push_back(Datum((int)inter.left));
+ d.u.farr->arr.push_back(Datum((int)inter.top));
+ d.u.farr->arr.push_back(Datum((int)inter.right));
+ d.u.farr->arr.push_back(Datum((int)inter.bottom));
g_lingo->push(d);
}
Commit: 4555fe218b17009501465e5f3cfea18ebffeb0c4
https://github.com/scummvm/scummvm/commit/4555fe218b17009501465e5f3cfea18ebffeb0c4
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-08-25T00:59:49+02:00
Commit Message:
DIRECTOR: Implement MovUtils mStageToCast
mStageToCast was a stub that pushed 0, so assigning its result to the
picture of a bitmap cast member failed with a type error. Capture the
requested region of the stage into a picture with the current palette and
return it as a picture reference.
Fixes drawing not being committed to the canvas in Gus Paint.
Changed paths:
engines/director/lingo/xlibs/m/movutils.cpp
diff --git a/engines/director/lingo/xlibs/m/movutils.cpp b/engines/director/lingo/xlibs/m/movutils.cpp
index 98df94e46c2..38f260b7104 100644
--- a/engines/director/lingo/xlibs/m/movutils.cpp
+++ b/engines/director/lingo/xlibs/m/movutils.cpp
@@ -20,8 +20,11 @@
*/
#include "common/util.h"
+#include "graphics/managed_surface.h"
#include "director/director.h"
+#include "director/picture.h"
+#include "director/window.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingo-object.h"
#include "director/lingo/lingo-utils.h"
@@ -371,7 +374,45 @@ XOBJSTUB(MovUtilsXObj::m_bitOr, 0)
XOBJSTUB(MovUtilsXObj::m_bitXOr, 0)
XOBJSTUB(MovUtilsXObj::m_bitNot, 0)
XOBJSTUB(MovUtilsXObj::m_bitStringToNumber, 0)
-XOBJSTUB(MovUtilsXObj::m_stageToCast, 0)
+void MovUtilsXObj::m_stageToCast(int nargs) {
+ Datum result(0);
+ if (nargs != 1) {
+ warning("MovUtilsXObj::m_stageToCast(): expected 1 arg");
+ g_lingo->dropStack(nargs);
+ } else {
+ Datum rectArg = g_lingo->pop();
+ if (rectArg.type != RECT) {
+ warning("MovUtilsXObj::m_stageToCast(): expected a rect, got %s", rectArg.type2str());
+ } else {
+ Graphics::ManagedSurface *stage = g_director->getStage()->getSurface();
+ Common::Rect rect(rectArg.u.farr->arr[0].asInt(), rectArg.u.farr->arr[1].asInt(),
+ rectArg.u.farr->arr[2].asInt(), rectArg.u.farr->arr[3].asInt());
+ rect.clip(Common::Rect(stage->w, stage->h));
+
+ if (rect.isEmpty()) {
+ warning("MovUtilsXObj::m_stageToCast(): capture rect is empty");
+ } else {
+ // Snapshot the requested region of the stage into a picture.
+ Picture *pic = new Picture();
+ pic->_surface.copyFrom(stage->getSubArea(rect));
+
+ const byte *palette = g_director->_wm->getPalette();
+ if (palette) {
+ int numColors = MIN<int>(g_director->_wm->getPaletteSize(), 256);
+ pic->_paletteColors = numColors;
+ memcpy(pic->_palette, palette, numColors * 3);
+ }
+
+ PictureReference *ref = new PictureReference;
+ ref->_picture = pic;
+ result.type = PICTUREREF;
+ result.u.picture = ref;
+ }
+ }
+ }
+ g_lingo->push(result);
+}
+
XOBJSTUB(MovUtilsXObj::m_stageToDIB, 0)
XOBJSTUB(MovUtilsXObj::m_stageToPICT, 0)
XOBJSTUB(MovUtilsXObj::m_cRtoCRLF, "")
Commit: 1ee443b999325ef6771e7f063180e167853b2bbb
https://github.com/scummvm/scummvm/commit/1ee443b999325ef6771e7f063180e167853b2bbb
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-08-25T00:59:49+02:00
Commit Message:
DIRECTOR: Track cast size and registration when the picture changes
Setting the picture of a bitmap cast member reset its bounding box but left
the registration point and the dimensions of any sprite showing it stale,
so a resized picture rendered off-centre and clipped to the old size.
Recenter the registration point on the new image (rounded to nearest, so an
odd dimension lands on the pixel the sprite is centred on and repeated
stage-capture assignments stay stable), and resize the unstretched sprites
that display the cast, mirroring the setCast dimension update that a castId
change would otherwise perform.
Fixes the canvas clearing when switching tools in Gus Paint.
Changed paths:
engines/director/castmember/bitmap.cpp
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 43fda27397a..6c928ccbd31 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -33,9 +33,11 @@
#include "director/director.h"
#include "director/cast.h"
#include "director/images.h"
+#include "director/channel.h"
#include "director/movie.h"
#include "director/picture.h"
#include "director/score.h"
+#include "director/sprite.h"
#include "director/types.h"
#include "director/window.h"
#include "director/castmember/bitmap.h"
@@ -1100,10 +1102,24 @@ void BitmapCastMember::setField(int field, const Datum &d) {
// This is a random PICT from somewhere,
// set the external flag so we remap the palette.
_external = true;
- // Remove the canvas-space transformation
- _regX -= _initialRect.left;
- _regY -= _initialRect.top;
+ // Recenter the registration point on the new image, rounded to nearest.
_initialRect = Common::Rect(_picture->_surface.w, _picture->_surface.h);
+ _regX = (_picture->_surface.w + 1) / 2;
+ _regY = (_picture->_surface.h + 1) / 2;
+
+ // The castId is unchanged, so resize the sprites showing this cast.
+ Movie *movie = g_director->getCurrentMovie();
+ Score *score = movie ? movie->getScore() : nullptr;
+ if (score) {
+ for (uint i = 0; i < score->_channels.size(); i++) {
+ Channel *ch = score->_channels[i];
+ if (ch && ch->_sprite && ch->_sprite->_cast == this && !ch->_sprite->_stretch) {
+ ch->_sprite->_width = _initialRect.width();
+ ch->_sprite->_height = _initialRect.height();
+ ch->setDirty();
+ }
+ }
+ }
} else {
warning("BitmapCastMember::setField(): Wrong Datum type %d for kThePicture (or nullptr)", d.type);
}
More information about the Scummvm-git-logs
mailing list