[Scummvm-git-logs] scummvm master -> 9766d228c3f1a7a08951dfaa867b41ceb904513f
sev-
noreply at scummvm.org
Thu Oct 2 23:00:42 UTC 2025
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
c5701936ad DIRECTOR: Add detection for empty 0x0 BitmapCastMembers
e51ad1557a DIRECTOR: Fix detection entry + quirks for pingu1
4ba38f7c52 DIRECTOR: LINGO: Allow more than 2 arguments for b_puppetSound
bfad1db6be DIRECTOR: Remove multiple inheritance from Window class
1274e6037b DIRECTOR: Only use unsigned audio for Moa when 8-bit
b34dc9e277 DIRECTOR: Fix regression in Movie::queueEvent
b97c82b200 DIRECTOR: Defer changing the current window until the main loop
9766d228c3 DIRECTOR: Add guardrail for Movie::resolveScriptEvent
Commit: c5701936add39c9f9ff4e5a1753a7521b732483b
https://github.com/scummvm/scummvm/commit/c5701936add39c9f9ff4e5a1753a7521b732483b
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: Add detection for empty 0x0 BitmapCastMembers
Fixes mountain of warnings in tunnel puzzle in pingu1.
Changed paths:
engines/director/castmember/bitmap.cpp
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index 367b39ccd43..c45991e3fdc 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -747,6 +747,12 @@ void BitmapCastMember::load() {
} else {
warning("BitmapCastMember::load(): cannot open external picture '%s'", location.toString(Common::Path::kNativeSeparator).c_str());
}
+ } else if ((!pic || (pic->size() == 0)) && (_initialRect.width() == 0) && (_initialRect.height() == 0)) {
+ // If an image is 0x0, it doesn't matter if we don't have any data.
+ _picture->_surface.create(0, 0, g_director->_wm->_pixelformat);
+ delete pic;
+ _loaded = true;
+ return;
}
} else {
realId = imgId + _cast->_castIDoffset;
Commit: e51ad1557a1c543b7f4a0efff5ff726b03bea1b4
https://github.com/scummvm/scummvm/commit/e51ad1557a1c543b7f4a0efff5ff726b03bea1b4
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: Fix detection entry + quirks for pingu1
Changed paths:
engines/director/detection_tables.h
engines/director/game-quirks.cpp
diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index fd35f295851..b811d36775b 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -7539,8 +7539,8 @@ static const DirectorGameDescription gameDescriptions[] = {
// "Pingu Screen Saver Chooser", "35dbf55e70f69e00ca016e3663379970", 705445, 500
// "Remove Pingu", "35dbf55e70f69e00ca016e3663379970", 705445, 500
MACGAME1("pingu1", "", "Pingu CD-ROM", "35dbf55e70f69e00ca016e3663379970", 705445, 500),
- WINGAME2("pingu1", "1282A", "PINGU.EXE", "2e62abdad839e42068afdcd0644d7dcf", 917473,
- "PINTITLE.DXR", "2e604dfd80ce4189dc0162dbe47ca7e2", 478854, 500),
+ WINGAME2("pingu1", "1282A", "PINGU.EXE", "t:828102166219aa43f00c7cd72c0a4fc9", 917473,
+ "PINTITLE.DXR", "d:2e604dfd80ce4189dc0162dbe47ca7e2", 478854, 500),
WINGAME2_l("pingu1", "", "PINGU.EXE", "2e62abdad839e42068afdcd0644d7dcf", 917473,
"PINTITLE.DXR", "e56af5ddd0750b8ec04cb4ea3d707066", 489234, Common::CA_ESP, 500),
WINGAME2_l("pingu1", "", "PINGU.EXE", "2e62abdad839e42068afdcd0644d7dcf", 917473,
diff --git a/engines/director/game-quirks.cpp b/engines/director/game-quirks.cpp
index 7d68bc2095f..121955cb820 100644
--- a/engines/director/game-quirks.cpp
+++ b/engines/director/game-quirks.cpp
@@ -139,6 +139,11 @@ struct CachedFile {
// Mission Code: Millennium expects the installer to have added an empty save file.
{"mcmillennium", Common::kPlatformWindows, "pc/players", (const byte *)"", 0},
+ // Pingu: A Barrel of Fun! expects a text file containing system paths to be written by InstallShield,
+ // and the placeholder text file in the archive will not work.
+ { "pingu1", Common::kPlatformWindows, "PINGUDRV.PNG", (const byte *)"C:\\\r\nC:\\\r\nD:\\\r\n", -1},
+ { "pingu1", Common::kPlatformWindows, "CHECKDRV.PNG", (const byte *)"D:\\\r\n", -1},
+
{ nullptr, Common::kPlatformUnknown, nullptr, nullptr, 0 }
};
@@ -364,7 +369,11 @@ void DirectorEngine::gameQuirks(const char *target, Common::Platform platform) {
SearchMan.remove(kQuirksCacheArchive);
}
- SearchMan.add(kQuirksCacheArchive, archive);
+ // The order of precedence for file loading should be:
+ // - Save system
+ // - Quirks list
+ // - File system
+ SearchMan.add(kQuirksCacheArchive, archive, 5);
}
}
Commit: 4ba38f7c525643264b304eee4ac1e479f50e40b0
https://github.com/scummvm/scummvm/commit/4ba38f7c525643264b304eee4ac1e479f50e40b0
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: LINGO: Allow more than 2 arguments for b_puppetSound
Fixes crash at start of pingu1.
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 5d0c45ebd46..cf93bccd81f 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -3021,8 +3021,10 @@ void LB::b_puppetPalette(int nargs) {
void LB::b_puppetSound(int nargs) {
if (nargs < 1 || nargs >= 3) {
- warning("b_puppetSound(): needs 1 or 2 args");
- return;
+ warning("b_puppetSound(): needs 1 or 2 args, got %d", nargs);
+ if (nargs < 1)
+ return;
+ g_lingo->dropStack(nargs - 2);
}
DirectorSound *sound = g_director->getCurrentWindow()->getSoundManager();
Commit: bfad1db6be608b1d2d5483cf652a64aa2d9cf233
https://github.com/scummvm/scummvm/commit/bfad1db6be608b1d2d5483cf652a64aa2d9cf233
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: Remove multiple inheritance from Window class
Previously this was both a subclass of Object<Window> and MacWindow.
This could cause issues because the lifetime of both object types is not
the same; the MacWindow object is owned by the window manager, whereas
Object<Window> is managed with reference counting. To sort this out,
split the MacWindow object to be a pointer held by Window.
Changed paths:
engines/director/castmember/bitmap.cpp
engines/director/castmember/digitalvideo.cpp
engines/director/castmember/richtext.cpp
engines/director/castmember/text.cpp
engines/director/director.cpp
engines/director/events.cpp
engines/director/lingo/lingo-object.cpp
engines/director/lingo/lingo-the.cpp
engines/director/lingo/xlibs/popupmenuxobj.cpp
engines/director/lingo/xlibs/qtvr.cpp
engines/director/lingo/xtras/qtvrxtra.cpp
engines/director/movie.cpp
engines/director/tests.cpp
engines/director/transitions.cpp
engines/director/window.cpp
engines/director/window.h
graphics/macgui/macwindow.cpp
graphics/macgui/macwindow.h
diff --git a/engines/director/castmember/bitmap.cpp b/engines/director/castmember/bitmap.cpp
index c45991e3fdc..97128181a31 100644
--- a/engines/director/castmember/bitmap.cpp
+++ b/engines/director/castmember/bitmap.cpp
@@ -385,7 +385,7 @@ Graphics::MacWidget *BitmapCastMember::createWidget(Common::Rect &bbox, Channel
}
}
- Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
+ Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow()->getMacWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
Graphics::Surface *srcSurface = _ditheredImg ? _ditheredImg : &_picture->_surface;
if ((srcSurface->w <= 0) || (srcSurface->h <= 0)) {
diff --git a/engines/director/castmember/digitalvideo.cpp b/engines/director/castmember/digitalvideo.cpp
index a725756d760..f5d55398468 100644
--- a/engines/director/castmember/digitalvideo.cpp
+++ b/engines/director/castmember/digitalvideo.cpp
@@ -390,7 +390,7 @@ Graphics::MacWidget *DigitalVideoCastMember::createWidget(Common::Rect &bbox, Ch
}
}
- Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
+ Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow()->getMacWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
_channel = channel;
diff --git a/engines/director/castmember/richtext.cpp b/engines/director/castmember/richtext.cpp
index 0b6d8308aa6..b43ff96fbfe 100644
--- a/engines/director/castmember/richtext.cpp
+++ b/engines/director/castmember/richtext.cpp
@@ -170,7 +170,7 @@ Graphics::MacWidget *RichTextCastMember::createWidget(Common::Rect &bbox, Channe
// Check if we need to dither the image
int dstBpp = g_director->_wm->_pixelformat.bytesPerPixel;
- Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
+ Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow()->getMacWindow(), bbox.left, bbox.top, bbox.width(), bbox.height(), g_director->_wm, false);
Graphics::Surface *dithered = nullptr;
diff --git a/engines/director/castmember/text.cpp b/engines/director/castmember/text.cpp
index 54c8978e13e..f398a895a61 100644
--- a/engines/director/castmember/text.cpp
+++ b/engines/director/castmember/text.cpp
@@ -293,7 +293,7 @@ bool textWindowCallback(Graphics::WindowClick click, Common::Event &event, void
Graphics::MacWidget *TextCastMember::createWindowOrWidget(Common::Rect &bbox, Common::Rect dims, Graphics::MacFont *macFont) {
Graphics::MacText *widget = nullptr;
- widget = new Graphics::MacText(g_director->getCurrentWindow(), bbox.left, bbox.top, dims.width(), dims.height(), g_director->_wm, _ftext, macFont, getForeColor(), getBackColor(), _initialRect.width(), getAlignment(), _lineSpacing, _borderSize, _gutterSize, _boxShadow, _textShadow, _textType == kTextTypeFixed || _textType == kTextTypeScrolling, _textType == kTextTypeScrolling);
+ widget = new Graphics::MacText(g_director->getCurrentWindow()->getMacWindow(), bbox.left, bbox.top, dims.width(), dims.height(), g_director->_wm, _ftext, macFont, getForeColor(), getBackColor(), _initialRect.width(), getAlignment(), _lineSpacing, _borderSize, _gutterSize, _boxShadow, _textShadow, _textType == kTextTypeFixed || _textType == kTextTypeScrolling, _textType == kTextTypeScrolling);
widget->setSelRange(g_director->getCurrentMovie()->_selStart, g_director->getCurrentMovie()->_selEnd);
widget->draw();
@@ -342,7 +342,7 @@ Graphics::MacWidget *TextCastMember::createWidget(Common::Rect &bbox, Channel *c
case kCastButton:
// note that we use _initialRect for the dimensions of the button;
// the values provided in the sprite bounding box are ignored
- widget = new Graphics::MacButton(Graphics::MacButtonType(buttonType), getAlignment(), g_director->getCurrentWindow(), bbox.left, bbox.top, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, getForeColor(), getBackColor());
+ widget = new Graphics::MacButton(Graphics::MacButtonType(buttonType), getAlignment(), g_director->getCurrentWindow()->getMacWindow(), bbox.left, bbox.top, _initialRect.width(), _initialRect.height(), g_director->_wm, _ftext, macFont, getForeColor(), getBackColor());
widget->_focusable = true;
((Graphics::MacButton *)widget)->setHilite(_hilite);
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 42432aca776..34ef5c1717d 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -210,7 +210,7 @@ Window *DirectorEngine::getOrCreateWindow(Common::String &name) {
window->setVisible(false, true);
window->move(0, 0);
window->incRefCount();
- _wm->addWindowInitialized(window);
+ _wm->addWindowInitialized(window->getMacWindow());
_windowList.push_back(window);
return window;
}
@@ -294,14 +294,14 @@ Common::Error DirectorEngine::run() {
*_stage->_refCount += 1;
// Set this as background so it doesn't come to foreground when multiple windows present
- _wm->setBackgroundWindow(_stage);
+ _wm->setBackgroundWindow(_stage->getMacWindow());
if (!desktopEnabled())
_stage->disableBorder();
_surface = new Graphics::ManagedSurface(1, 1);
_wm->setScreen(_surface);
- _wm->addWindowInitialized(_stage);
+ _wm->addWindowInitialized(_stage->getMacWindow());
_wm->setActiveWindow(_stage->getId());
setPalette(CastMemberID(kClutSystemMac, -1));
@@ -368,6 +368,7 @@ Common::Error DirectorEngine::run() {
for (size_t i = 0; i < _windowList.size(); i++) {
if (_windowList[i] == window) {
_windowList.remove_at(i);
+ // FIXME: force window to be removed from WM
window->decRefCount();
break;
}
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 1e70fa298c7..eb07a5d8af7 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -113,7 +113,7 @@ void DirectorEngine::processEventQUIT() {
}
bool Window::processEvent(Common::Event &event) {
- bool flag = MacWindow::processEvent(event);
+ bool flag = false;
if (_currentMovie && _currentMovie->processEvent(event))
flag = true;
@@ -325,48 +325,55 @@ bool Movie::processEvent(Common::Event &event) {
}
bool Window::processWMEvent(Graphics::WindowClick click, Common::Event &event) {
+ bool flag = false;
switch (click) {
case Graphics::kBorderCloseButton:
if (_currentMovie && event.type == Common::EVENT_LBUTTONUP) {
_currentMovie->processEvent(kEventCloseWindow, 0);
setVisible(false);
- return true;
+ flag = true;
}
break;
case Graphics::kBorderActivate:
sendWindowEvent(kEventActivateWindow);
- return true;
+ flag = true;
+ break;
case Graphics::kBorderDeactivate:
sendWindowEvent(kEventDeactivateWindow);
- return true;
+ flag = true;
+ break;
case Graphics::kBorderDragged:
sendWindowEvent(kEventMoveWindow);
- return true;
+ flag = true;
+ break;
case Graphics::kBorderResized:
sendWindowEvent(kEventResizeWindow);
- return true;
+ flag = true;
+ break;
case Graphics::kBorderMaximizeButton:
if (event.type == Common::EVENT_LBUTTONUP) {
sendWindowEvent(kEventZoomWindow);
- return true;
+ flag = true;
+ break;
}
break;
default:
break;
}
- return false;
+ flag |= processEvent(event);
+ return flag;
}
void Window::sendWindowEvent(LEvent event) {
- if (_currentMovie && _visible && !_isStage) {
+ if (_currentMovie && _window->isVisible() && !_isStage) {
// We cannot call processEvent here directly because it might
// be called from within another event processing (like 'on startMovie' )
// which would mess up the Lingo state.
diff --git a/engines/director/lingo/lingo-object.cpp b/engines/director/lingo/lingo-object.cpp
index 6d7f44bef17..e2faf85fb85 100644
--- a/engines/director/lingo/lingo-object.cpp
+++ b/engines/director/lingo/lingo-object.cpp
@@ -785,11 +785,11 @@ bool Window::hasField(int field) {
Datum Window::getField(int field) {
switch (field) {
case kTheTitle:
- return getTitle();
+ return _window->getTitle();
case kTheTitleVisible:
- return isTitleVisible();
+ return _window->isTitleVisible();
case kTheVisible:
- return isVisible();
+ return _window->isVisible();
case kTheWindowType:
return getWindowType();
case kTheRect:
@@ -889,7 +889,7 @@ void LM::m_forget(int nargs) {
void LM::m_open(int nargs) {
Window *me = static_cast<Window *>(g_lingo->_state->me.u.obj);
- bool wasVisible = me->isVisible();
+ bool wasVisible = me->_window->isVisible();
me->setVisible(true);
if (!wasVisible)
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index eba251f9b75..29225eca2ff 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -1032,7 +1032,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
case kTheStageBottom:
{
Window *window = _vm->getCurrentWindow();
- d = window->getInnerDimensions().bottom;
+ d = window->_window->getInnerDimensions().bottom;
}
break;
case kTheStageColor:
@@ -1042,19 +1042,19 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
case kTheStageLeft:
{
Window *window = _vm->getCurrentWindow();
- d = window->getInnerDimensions().left;
+ d = window->_window->getInnerDimensions().left;
}
break;
case kTheStageRight:
{
Window *window = _vm->getCurrentWindow();
- d = window->getInnerDimensions().right;
+ d = window->_window->getInnerDimensions().right;
}
break;
case kTheStageTop:
{
Window *window = _vm->getCurrentWindow();
- d = window->getInnerDimensions().top;
+ d = window->_window->getInnerDimensions().top;
}
break;
case kTheStillDown:
diff --git a/engines/director/lingo/xlibs/popupmenuxobj.cpp b/engines/director/lingo/xlibs/popupmenuxobj.cpp
index a6dfc1c8ec5..1914ec46e53 100644
--- a/engines/director/lingo/xlibs/popupmenuxobj.cpp
+++ b/engines/director/lingo/xlibs/popupmenuxobj.cpp
@@ -176,7 +176,7 @@ void PopUpMenuXObj::m_popNum(int nargs) {
int left = g_lingo->pop().asInt();
// Convert window coordinates to screen coordinates
- Common::Rect windowRect = g_director->getCurrentWindow()->getInnerDimensions();
+ Common::Rect windowRect = g_director->getCurrentWindow()->getMacWindow()->getInnerDimensions();
int screenTop = top + windowRect.top - 1;
int screenLeft = left + windowRect.left - 1;
@@ -193,7 +193,7 @@ void PopUpMenuXObj::m_popText(int nargs) {
int left = g_lingo->pop().asInt();
// Convert window coordinates to screen coordinates
- Common::Rect windowRect = g_director->getCurrentWindow()->getInnerDimensions();
+ Common::Rect windowRect = g_director->getCurrentWindow()->getMacWindow()->getInnerDimensions();
int screenTop = top + windowRect.top - 1;
int screenLeft = left + windowRect.left - 1;
diff --git a/engines/director/lingo/xlibs/qtvr.cpp b/engines/director/lingo/xlibs/qtvr.cpp
index c171eff4a82..1f1fe78957b 100644
--- a/engines/director/lingo/xlibs/qtvr.cpp
+++ b/engines/director/lingo/xlibs/qtvr.cpp
@@ -345,7 +345,7 @@ void QTVR::m_openMovie(int nargs) {
me->_rect = Common::Rect(left, top, left + me->_video->getWidth(), top + me->_video->getHeight());
- me->_widget = new QtvrWidget(me, g_director->getCurrentWindow(),
+ me->_widget = new QtvrWidget(me, g_director->getCurrentWindow()->getMacWindow(),
me->_rect.left, me->_rect.top, me->_rect.width(), me->_rect.height(),
g_director->getMacWindowManager());
diff --git a/engines/director/lingo/xtras/qtvrxtra.cpp b/engines/director/lingo/xtras/qtvrxtra.cpp
index d2281dcfcd8..9cb342b33aa 100644
--- a/engines/director/lingo/xtras/qtvrxtra.cpp
+++ b/engines/director/lingo/xtras/qtvrxtra.cpp
@@ -386,7 +386,7 @@ void QtvrxtraXtra::m_QTVROpen(int nargs) {
me->_video->setTargetSize(me->_rect.width(), me->_rect.height());
me->_video->setOrigin(me->_rect.left, me->_rect.top);
- me->_widget = new QtvrxtraWidget(me, g_director->getCurrentWindow(),
+ me->_widget = new QtvrxtraWidget(me, g_director->getCurrentWindow()->getMacWindow(),
me->_rect.left, me->_rect.top, me->_rect.width(), me->_rect.height(),
g_director->getMacWindowManager());
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 17b4b5bedee..2bdf3e672d0 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -46,7 +46,7 @@ Movie::Movie(Window *window) {
_lingo = _vm->getLingo();
_flags = 0;
- _stageColor = _window->_wm->_colorWhite;
+ _stageColor = _vm->_wm->_colorWhite;
_lastClickedSpriteId = 0;
_currentSpriteNum = 0;
diff --git a/engines/director/tests.cpp b/engines/director/tests.cpp
index ae36ecec978..cfb6d5aacab 100644
--- a/engines/director/tests.cpp
+++ b/engines/director/tests.cpp
@@ -56,12 +56,12 @@ void Window::testFontScaling() {
Graphics::ManagedSurface surface;
- surface.create(w, h, _wm->_pixelformat);
- surface.clear(_wm->_colorWhite);
+ surface.create(w, h, _vm->_wm->_pixelformat);
+ surface.clear(_vm->_wm->_colorWhite);
Graphics::MacFont origFont(Graphics::kMacFontNewYork, 18);
- const Graphics::MacFONTFont *font1 = (const Graphics::MacFONTFont *)_wm->_fontMan->getFont(origFont);
+ const Graphics::MacFONTFont *font1 = (const Graphics::MacFONTFont *)_vm->_wm->_fontMan->getFont(origFont);
Graphics::MacFONTFont::testBlit(font1, &surface, 0xff, x, y + 200, 500);
diff --git a/engines/director/transitions.cpp b/engines/director/transitions.cpp
index 7fac342853c..d8168e519a8 100644
--- a/engines/director/transitions.cpp
+++ b/engines/director/transitions.cpp
@@ -21,6 +21,7 @@
#include "common/system.h"
+#include "graphics/managed_surface.h"
#include "graphics/primitives.h"
#include "graphics/macgui/macwindowmanager.h"
@@ -134,12 +135,13 @@ struct {
};
void Window::exitTransition(TransParams &t, Graphics::ManagedSurface *nextFrame, Common::Rect clipRect) {
- _composeSurface->blitFrom(*nextFrame, clipRect, Common::Point(clipRect.left, clipRect.top));
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
+ composeSurface->blitFrom(*nextFrame, clipRect, Common::Point(clipRect.left, clipRect.top));
stepTransition(t, t.steps);
}
void Window::stepTransition(TransParams &t, int step) {
- _contentIsDirty = true;
+ _window->setDirty(true);
if (t.sourcePal != t.targetPal) {
for (int i = 0; i < 768; i++) {
@@ -189,28 +191,24 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
}
// Cache a copy of the frame before the transition.
- Graphics::ManagedSurface currentFrame(Graphics::ManagedSurface(_composeSurface->w, _composeSurface->h, g_director->_pixelformat));
- currentFrame.copyFrom(*_composeSurface);
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
+ Graphics::ManagedSurface currentFrame(Graphics::ManagedSurface(composeSurface->w, composeSurface->h, g_director->_pixelformat));
+ currentFrame.copyFrom(*composeSurface);
// If a transition is being played, render the frame after the transition.
- Graphics::ManagedSurface nextFrame(Graphics::ManagedSurface(_composeSurface->w, _composeSurface->h, g_director->_pixelformat));
+ Graphics::ManagedSurface nextFrame(Graphics::ManagedSurface(composeSurface->w, composeSurface->h, g_director->_pixelformat));
Common::Rect clipRect;
+ Common::Rect innerDims = _window->getInnerDimensions();
Score *score = g_director->getCurrentMovie()->getScore();
if (t.area) {
// Changed area transition
score->updateSprites(mode);
- if (_dirtyRects.size() == 0)
- return;
-
- clipRect = *_dirtyRects.begin();
-
- for (auto &i : _dirtyRects)
- clipRect.extend(i);
+ clipRect = _window->getDirtyRectBounds();
// Ensure we redraw any other sprites intersecting the non-clip area.
- _dirtyRects.clear();
+ _window->clearDirtyRects();
// Some transitions depend upon an even clipRect size
if (clipRect.width() % 2 == 1)
@@ -219,8 +217,8 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
if (clipRect.height() % 2 == 1)
clipRect.bottom += 1;
- clipRect.clip(Common::Rect(_innerDims.width(), _innerDims.height()));
- _dirtyRects.push_back(clipRect);
+ clipRect.clip(Common::Rect(innerDims.width(), innerDims.height()));
+ _window->addDirtyRect(clipRect);
render(false, &nextFrame);
} else {
@@ -228,7 +226,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
score->updateSprites(mode);
render(true, &nextFrame);
- clipRect = _innerDims;
+ clipRect = innerDims;
clipRect.moveTo(0, 0);
}
@@ -293,7 +291,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
if (transProps[t.type].algo == kTransAlgoReveal ||
transProps[t.type].algo == kTransAlgoEdgesIn) {
- _composeSurface->copyRectToSurface(nextFrame, clipRect.left, clipRect.top, clipRect);
+ composeSurface->copyRectToSurface(nextFrame, clipRect.left, clipRect.top, clipRect);
}
switch (t.type) {
@@ -372,7 +370,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
rto.translate(w - t.xStepSize * i / TSTEP_FRAC, 0);
rfrom.right -= w - clipRect.findIntersectingRect(rto).width();
rto.clip(clipRect);
- _composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
+ composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
rfrom.translate(t.xStepSize * i / TSTEP_FRAC, 0);
rfrom.setWidth(MAX((int16)0, (int16)(w - t.xStepSize * i / TSTEP_FRAC)));
@@ -382,7 +380,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
case kTransPushRight: // 12
rfrom.translate(w - t.xStepSize * i / TSTEP_FRAC, 0);
rfrom.setWidth(MAX((int16)0, (int16)(t.xStepSize * i / TSTEP_FRAC)));
- _composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
+ composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
rto.setWidth(MAX((int16)0, (int16)(w - t.xStepSize * i / TSTEP_FRAC)));
rto.translate(t.xStepSize * i / TSTEP_FRAC, 0);
@@ -393,7 +391,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
case kTransPushDown: // 13
rfrom.translate(0, h - t.yStepSize * i / TSTEP_FRAC);
rfrom.setHeight(MAX((int16)0, (int16)(t.yStepSize * i / TSTEP_FRAC)));
- _composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
+ composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
rto.setHeight(MAX((int16)0, (int16)(h - t.yStepSize * i / TSTEP_FRAC)));
rto.translate(0, t.yStepSize * i / TSTEP_FRAC);
@@ -405,7 +403,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
rto.translate(0, h - t.yStepSize * i / TSTEP_FRAC);
rfrom.bottom -= h - clipRect.findIntersectingRect(rto).height();
rto.clip(clipRect);
- _composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
+ composeSurface->blitFrom(nextFrame, rfrom, Common::Point(rto.left, rto.top));
rfrom.translate(0, t.yStepSize * i / TSTEP_FRAC);
rfrom.setHeight(MAX((int16)0, (int16)(h - t.yStepSize * i / TSTEP_FRAC)));
@@ -566,7 +564,7 @@ void Window::playTransition(uint frame, RenderMode mode, uint16 transDuration, u
if (stop)
break;
- _composeSurface->blitFrom(*blitFrom, rfrom, Common::Point(rto.left, rto.top));
+ composeSurface->blitFrom(*blitFrom, rfrom, Common::Point(rto.left, rto.top));
if (_vm->processEvents(true)) {
exitTransition(t, &nextFrame, clipRect);
@@ -615,11 +613,11 @@ static uint32 randomSeed[33] = {
};
void Window::dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
uint w = clipRect.width();
uint h = clipRect.height();
uint realw = w, realh = h;
byte pixmask[8];
-
memset(pixmask, 0, 8);
// This method treats xStepSize and yStepSize as pixel values, without TSTEP_FRAC.
@@ -746,7 +744,7 @@ void Window::dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::Man
r.clip(clipRect);
if (!r.isEmpty())
- _composeSurface->copyRectToSurface(*nextFrame, x, y, r);
+ composeSurface->copyRectToSurface(*nextFrame, x, y, r);
}
} else {
mask = pixmask[x % -t.xStepSize];
@@ -756,12 +754,12 @@ void Window::dissolveTrans(TransParams &t, Common::Rect &clipRect, Graphics::Man
y += clipRect.top;
if (g_director->_pixelformat.bytesPerPixel == 1) {
- byte *dst = (byte *)_composeSurface->getBasePtr(x, y);
+ byte *dst = (byte *)composeSurface->getBasePtr(x, y);
byte *src = (byte *)nextFrame->getBasePtr(x, y);
*dst = ((*dst & ~mask) | (*src & mask)) & 0xff;
} else {
- uint32 *dst = (uint32 *)_composeSurface->getBasePtr(x, y);
+ uint32 *dst = (uint32 *)composeSurface->getBasePtr(x, y);
uint32 *src = (uint32 *)nextFrame->getBasePtr(x, y);
*dst = ((*dst & ~mask) | (*src & mask)) & 0xff;
@@ -863,6 +861,7 @@ static byte dissolvePatterns[][8] = {
};
void Window::dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
int patternSteps = 64;
for (int i = 0; i < t.steps; i++) {
@@ -872,7 +871,7 @@ void Window::dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graph
byte pat = dissolvePatterns[patternIndex][y % 8];
if (g_director->_pixelformat.bytesPerPixel == 1) {
- byte *dst = (byte *)_composeSurface->getBasePtr(clipRect.left, y);
+ byte *dst = (byte *)composeSurface->getBasePtr(clipRect.left, y);
byte *src = (byte *)nextFrame->getBasePtr(clipRect.left, y);
for (int x = clipRect.left; x < clipRect.right;) {
@@ -887,7 +886,7 @@ void Window::dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graph
}
}
} else {
- uint32 *dst = (uint32 *)_composeSurface->getBasePtr(clipRect.left, y);
+ uint32 *dst = (uint32 *)composeSurface->getBasePtr(clipRect.left, y);
uint32 *src = (uint32 *)nextFrame->getBasePtr(clipRect.left, y);
for (int x = clipRect.left; x < clipRect.right;) {
@@ -921,6 +920,7 @@ void Window::dissolvePatternsTrans(TransParams &t, Common::Rect &clipRect, Graph
}
void Window::transMultiPass(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *nextFrame) {
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
Common::Rect rto;
uint w = clipRect.width();
uint h = clipRect.height();
@@ -1079,7 +1079,7 @@ void Window::transMultiPass(TransParams &t, Common::Rect &clipRect, Graphics::Ma
rto.clip(clipRect);
if (rto.height() > 0 && rto.width() > 0) {
- _composeSurface->blitFrom(*nextFrame, rto, Common::Point(rto.left, rto.top));
+ composeSurface->blitFrom(*nextFrame, rto, Common::Point(rto.left, rto.top));
}
}
stepTransition(t, i);
@@ -1101,6 +1101,7 @@ void Window::transMultiPass(TransParams &t, Common::Rect &clipRect, Graphics::Ma
}
void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::ManagedSurface *currentFrame, Graphics::ManagedSurface *nextFrame) {
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
Common::Rect r = clipRect;
uint w = clipRect.width();
uint h = clipRect.height();
@@ -1111,7 +1112,7 @@ void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::Managed
DirectorPlotData pd(g_director, kLineTopBottomSprite, kInkTypeReverse, 0, _wm->_colorWhite, _wm->_colorBlack);
pd.destRect = clipRect;
- pd.dst = _composeSurface;
+ pd.dst = composeSurface;
Graphics::Primitives *primitives = g_director->getInkPrimitives();
@@ -1119,7 +1120,7 @@ void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::Managed
uint32 startTime = g_system->getMillis();
// FIXME: figure out the bounding box of the drawn bits
- _composeSurface->copyRectToSurface(*currentFrame, clipRect.left, clipRect.top, clipRect);
+ composeSurface->copyRectToSurface(*currentFrame, clipRect.left, clipRect.top, clipRect);
for (int s = 2; s >= 0; s--) {
if (i - s < 0 || i - s > t.steps - 2)
@@ -1160,8 +1161,8 @@ void Window::transZoom(TransParams &t, Common::Rect &clipRect, Graphics::Managed
g_lingo->executePerFrameHook(t.frame, i, false);
}
- render(true, _composeSurface);
- _contentIsDirty = true;
+ render(true, composeSurface);
+ _window->setDirty(true);
g_director->draw();
}
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 52d2dc62f0a..9c0f6264c9d 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -39,6 +39,7 @@
#include "director/sprite.h"
#include "director/castmember/castmember.h"
#include "director/debugger/debugtools.h"
+#include "graphics/managed_surface.h"
namespace Director {
@@ -48,8 +49,9 @@ bool commandsWindowCallback(Graphics::WindowClick click, Common::Event &event, v
}
Window::Window(int id, bool scrollable, bool resizable, bool editable, Graphics::MacWindowManager *wm, DirectorEngine *vm, bool isStage)
- : MacWindow(id, scrollable, resizable, editable, wm), Object<Window>("Window") {
+: Object<Window>("Window") {
_vm = vm;
+ _wm = wm;
_isStage = isStage;
_stageColor = _wm->_colorBlack;
_puppetTransition = nullptr;
@@ -68,11 +70,13 @@ Window::Window(int id, bool scrollable, bool resizable, bool editable, Graphics:
_isModal = false;
_skipFrameAdvance = false;
- updateBorderType();
+ // Owned by the window manager
+ _window = new Graphics::MacWindow(id, scrollable, resizable, editable, wm);
+ _window->setDraggable(!_isStage);
- _draggable = !_isStage;
+ _window->setCallback(commandsWindowCallback, this);
- setCallback(commandsWindowCallback, this);
+ updateBorderType();
}
Window::~Window() {
@@ -90,7 +94,7 @@ Window::~Window() {
void Window::decRefCount() {
*_refCount -= 1;
if (*_refCount <= 0) {
- g_director->_wm->removeWindow(this);
+ g_director->_wm->removeWindow(_window);
g_director->_wm->removeMarked();
}
}
@@ -111,9 +115,11 @@ void Window::invertChannel(Channel *channel, const Common::Rect &destRect) {
int xoff = srcRect.left - channel->getBbox().left;
int yoff = srcRect.top - channel->getBbox().top;
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
+
if (_wm->_pixelformat.bytesPerPixel == 1) {
for (int i = 0; i < srcRect.height(); i++) {
- byte *src = (byte *)_composeSurface->getBasePtr(srcRect.left, srcRect.top + i);
+ byte *src = (byte *)composeSurface->getBasePtr(srcRect.left, srcRect.top + i);
const byte *msk = mask ? (const byte *)mask->getBasePtr(xoff, yoff + i) : nullptr;
for (int j = 0; j < srcRect.width(); j++, src++)
@@ -123,7 +129,7 @@ void Window::invertChannel(Channel *channel, const Common::Rect &destRect) {
} else {
for (int i = 0; i < srcRect.height(); i++) {
- uint32 *src = (uint32 *)_composeSurface->getBasePtr(srcRect.left, srcRect.top + i);
+ uint32 *src = (uint32 *)composeSurface->getBasePtr(srcRect.left, srcRect.top + i);
const byte *msk = mask ? (const byte *)mask->getBasePtr(xoff, yoff + i) : nullptr;
for (int j = 0; j < srcRect.width(); j++, src++)
@@ -161,36 +167,38 @@ bool Window::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
return false;
if (!blitTo)
- blitTo = _composeSurface;
+ blitTo = _window->getSurface();
+
+ Common::List<Common::Rect> &dirtyRects = _window->getDirtyRectList();
if (forceRedraw) {
blitTo->clear(_stageColor);
- markAllDirty();
+ _window->markAllDirty();
} else {
- if (_dirtyRects.size() == 0 && _currentMovie->_videoPlayback == false) {
+ if (dirtyRects.size() == 0 && _currentMovie->_videoPlayback == false) {
if (g_director->_debugDraw & kDebugDrawFrame) {
drawFrameCounter(blitTo);
- _contentIsDirty = true;
+ _window->setContentDirty(true);
}
return false;
}
- mergeDirtyRects();
+ _window->mergeDirtyRects();
}
Channel *hiliteChannel = _currentMovie->getScore()->getChannelById(_currentMovie->_currentHiliteChannelId);
uint32 renderStartTime = g_system->getMillis();
- debugC(7, kDebugImages, "Window::render(): Updating %d rects", _dirtyRects.size());
+ debugC(7, kDebugImages, "Window::render(): Updating %d rects", dirtyRects.size());
- for (auto &i : _dirtyRects) {
+ for (auto &i : dirtyRects) {
Common::Rect r = i;
// The inner dimensions are relative to the virtual desktop while
// r isn't, so we need to move the window to be relative to the
// same sapce.
- Common::Rect windowRect = getInnerDimensions();
+ Common::Rect windowRect = _window->getInnerDimensions();
windowRect.moveTo(r.left, r.top);
r.clip(windowRect);
@@ -264,8 +272,8 @@ bool Window::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
if (g_director->_debugDraw & kDebugDrawFrame)
drawFrameCounter(blitTo);
- _dirtyRects.clear();
- _contentIsDirty = true;
+ dirtyRects.clear();
+ _window->setContentDirty(true);
debugC(7, kDebugImages, "Window::render(): Draw finished in %d ms", g_system->getMillis() - renderStartTime);
return true;
@@ -275,19 +283,59 @@ void Window::setStageColor(uint32 stageColor, bool forceReset) {
if (stageColor != _stageColor || forceReset) {
_stageColor = stageColor;
reset();
- markAllDirty();
+ _window->markAllDirty();
}
}
void Window::setTitleVisible(bool titleVisible) {
- MacWindow::setTitleVisible(titleVisible);
+ _window->setTitleVisible(titleVisible);
updateBorderType();
}
+Graphics::ManagedSurface *Window::getSurface() {
+ return _window->getSurface();
+}
+
+void Window::addDirtyRect(const Common::Rect &r) {
+ _window->addDirtyRect(r);
+}
+
+void Window::resizeInner(int w, int h) {
+ _window->resizeInner(w, h);
+}
+
+int Window::getId() {
+ return _window->getId();
+}
+
+void Window::setDirty(bool dirty) {
+ _window->setDirty(dirty);
+}
+
+void Window::disableBorder() {
+ _window->disableBorder();
+}
+
+void Window::center(bool toCenter) {
+ _window->center(toCenter);
+}
+
+Common::Point Window::getAbsolutePos() {
+ return _window->getAbsolutePos();
+}
+
+void Window::setTitle(const Common::String &title) {
+ _window->setTitle(title);
+}
+
+void Window::move(int x, int y) {
+ _window->move(x, y);
+}
+
Datum Window::getStageRect() {
ensureMovieIsLoaded();
- Common::Rect rect = getInnerDimensions();
+ Common::Rect rect = _window->getInnerDimensions();
Datum d;
d.type = RECT;
d.u.farr = new FArray;
@@ -308,7 +356,7 @@ void Window::setStageRect(Datum datum) {
// Unpack rect from datum
Common::Rect rect = Common::Rect(datum.u.farr->arr[0].asInt(), datum.u.farr->arr[1].asInt(), datum.u.farr->arr[2].asInt(), datum.u.farr->arr[3].asInt());
- setInnerDimensions(rect);
+ _window->setInnerDimensions(rect);
}
void Window::setModal(bool modal) {
@@ -316,7 +364,7 @@ void Window::setModal(bool modal) {
_wm->setLockedWidget(nullptr);
_isModal = false;
} else if (!_isModal && modal) {
- _wm->setLockedWidget(this);
+ _wm->setLockedWidget(this->_window);
_isModal = true;
}
}
@@ -327,8 +375,9 @@ void Window::setFileName(Common::String filename) {
}
void Window::reset() {
- resizeInner(_composeSurface->w, _composeSurface->h);
- _contentIsDirty = true;
+ Graphics::ManagedSurface *composeSurface = _window->getSurface();
+ resizeInner(composeSurface->w, composeSurface->h);
+ _window->setContentDirty(true);
}
void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo) {
@@ -369,7 +418,8 @@ void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Mana
}
Common::Point Window::getMousePos() {
- return g_system->getEventManager()->getMousePos() - Common::Point(_innerDims.left, _innerDims.top);
+ Common::Rect innerDims = _window->getInnerDimensions();
+ return g_system->getEventManager()->getMousePos() - Common::Point(innerDims.left, innerDims.top);
}
void Window::setVisible(bool visible, bool silent) {
@@ -377,10 +427,10 @@ void Window::setVisible(bool visible, bool silent) {
if (!_currentMovie && !silent)
ensureMovieIsLoaded();
- BaseMacWindow::setVisible(visible);
+ _window->setVisible(visible);
if (visible)
- _wm->setActiveWindow(_id);
+ _wm->setActiveWindow(getId());
}
void Window::ensureMovieIsLoaded() {
@@ -435,11 +485,11 @@ bool Window::setNextMovie(Common::String &movieFilenameRaw) {
void Window::updateBorderType() {
if (_isStage) {
- setBorderType(3);
- } else if (!isTitleVisible()) {
- setBorderType(2);
+ _window->setBorderType(3);
+ } else if (!_window->isTitleVisible()) {
+ _window->setBorderType(2);
} else {
- setBorderType(MAX(0, MIN(_windowType, 16)));
+ _window->setBorderType(MAX(0, MIN(_windowType, 16)));
}
}
@@ -778,12 +828,14 @@ uint32 Window::frozenLingoRecursionCount() {
}
Common::String Window::formatWindowInfo() {
+ Common::Rect dims = _window->getDimensions();
+ Common::Rect innerDims = _window->getInnerDimensions();
return Common::String::format(
"name: \"%s\", movie: \"%s\", currentPath: \"%s\", dims: (%d,%d) %dx%d, innerDims: (%d, %d) %dx%d, visible: %d",
_name.c_str(), _currentMovie->getMacName().c_str(), _currentPath.c_str(),
- _dims.left, _dims.top, _dims.width(), _dims.height(),
- _innerDims.left, _innerDims.top, _innerDims.width(), _innerDims.height(),
- _visible
+ dims.left, dims.top, dims.width(), dims.height(),
+ innerDims.left, innerDims.top, innerDims.width(), innerDims.height(),
+ _window->isVisible()
);
}
diff --git a/engines/director/window.h b/engines/director/window.h
index c3120f7231c..0de1e663977 100644
--- a/engines/director/window.h
+++ b/engines/director/window.h
@@ -22,6 +22,8 @@
#ifndef DIRECTOR_STAGE_H
#define DIRECTOR_STAGE_H
+#include "graphics/macgui/macwindow.h"
+
#include "director/lingo/lingo-object.h"
namespace Common {
@@ -38,6 +40,7 @@ namespace Director {
class Channel;
class MacArchive;
+class Window;
struct MacShape;
struct LingoState;
@@ -100,7 +103,7 @@ struct TransParams {
}
};
-class Window : public Graphics::MacWindow, public Object<Window> {
+class Window : public Object<Window> {
public:
Window(int id, bool scrollable, bool resizable, bool editable, Graphics::MacWindowManager *wm, DirectorEngine *vm, bool isStage);
~Window();
@@ -129,18 +132,30 @@ public:
Common::Point getMousePos();
DirectorEngine *getVM() const { return _vm; }
+ Graphics::MacWindow *getMacWindow() const { return _window; }
Movie *getCurrentMovie() const { return _currentMovie; }
Common::String getCurrentPath() const { return _currentPath; }
DirectorSound *getSoundManager() const { return _soundManager; }
- void setVisible(bool visible, bool silent = false) override;
+ void setVisible(bool visible, bool silent = false);
bool setNextMovie(Common::String &movieFilenameRaw);
void ensureMovieIsLoaded();
void setWindowType(int type) { _windowType = type; updateBorderType(); }
int getWindowType() const { return _windowType; }
- void setTitleVisible(bool titleVisible) override;
+ void setTitleVisible(bool titleVisible);
+ Graphics::ManagedSurface *getSurface();
+ void addDirtyRect(const Common::Rect &r);
+ void resizeInner(int w, int h);
+ int getId();
+ void setDirty(bool dirty);
+ void disableBorder();
+ void center(bool toCenter = true);
+ Common::Point getAbsolutePos();
+ void setTitle(const Common::String &title);
+ void move(int x, int y);
+
Datum getStageRect();
void setStageRect(Datum datum);
void setModal(bool modal);
@@ -172,7 +187,7 @@ public:
static void inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo = nullptr);
// events.cpp
- bool processEvent(Common::Event &event) override;
+ bool processEvent(Common::Event &event);
bool processWMEvent(Graphics::WindowClick click, Common::Event &event);
void sendWindowEvent(LEvent event);
@@ -203,6 +218,9 @@ public:
Common::Path _fileName;
public:
+ Graphics::MacWindow *_window;
+ Graphics::MacWindowManager *_wm;
+
Common::List<Channel *> _dirtyChannels;
TransParams *_puppetTransition;
diff --git a/graphics/macgui/macwindow.cpp b/graphics/macgui/macwindow.cpp
index 047b9a70331..10bf2302fcf 100644
--- a/graphics/macgui/macwindow.cpp
+++ b/graphics/macgui/macwindow.cpp
@@ -531,6 +531,8 @@ WindowClick MacWindow::isInScroll(int x, int y) const {
bool MacWindow::processEvent(Common::Event &event) {
WindowClick click = isInBorder(event.mouse.x, event.mouse.y);
+ bool result = false;
+
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
if (_wm->_mouseDown && _wm->_hoveredWidget && !_wm->_hoveredWidget->_dims.contains(event.mouse.x - _dims.left, event.mouse.y - _dims.top)) {
@@ -611,21 +613,30 @@ bool MacWindow::processEvent(Common::Event &event) {
break;
case Common::EVENT_KEYDOWN:
+ if (_callback)
+ result = _callback(kBorderNone, event, _dataPtr);
+
if (!_editable && !(_wm->getActiveWidget() && _wm->getActiveWidget()->isEditable()))
- return false;
+ return result;
if (_wm->getActiveWidget())
- return _wm->getActiveWidget()->processEvent(event);
+ return _wm->getActiveWidget()->processEvent(event) || result;
- return false;
+ return result;
case Common::EVENT_WHEELUP:
case Common::EVENT_WHEELDOWN:
+ if (_callback)
+ result = _callback(kBorderNone, event, _dataPtr);
+
if (_wm->getActiveWidget() && _wm->getActiveWidget()->processEvent(event))
return true;
- return false;
+ return result;
default:
+ if (_callback)
+ return _callback(kBorderNone, event, _dataPtr);
+
return false;
}
@@ -637,13 +648,12 @@ bool MacWindow::processEvent(Common::Event &event) {
_wm->_hoveredWidget = w;
if (w->processEvent(event))
- return true;
+ result = true;
}
if (_callback)
- return (*_callback)(click, event, _dataPtr);
- else
- return false;
+ result = (*_callback)(click, event, _dataPtr) || result;
+ return result;
}
void MacWindow::setBorderType(int borderType) {
@@ -697,4 +707,15 @@ void MacWindow::mergeDirtyRects() {
}
}
+Common::Rect MacWindow::getDirtyRectBounds() {
+ Common::Rect result;
+ if (_dirtyRects.size() == 0)
+ return result;
+ result = Common::Rect(_dirtyRects.front());
+ for (auto &r : _dirtyRects) {
+ result.extend(r);
+ }
+ return result;
+}
+
} // End of namespace Graphics
diff --git a/graphics/macgui/macwindow.h b/graphics/macgui/macwindow.h
index ce366c966ec..04a7af6757d 100644
--- a/graphics/macgui/macwindow.h
+++ b/graphics/macgui/macwindow.h
@@ -176,6 +176,12 @@ public:
*/
void setCallback(bool (*callback)(WindowClick, Common::Event &, void *), void *data) { _callback = callback; _dataPtr = data; }
+ /**
+ * Mutator to change the draggable state of the window.
+ * @param draggable Target state.
+ */
+ void setDraggable(bool draggable) { _draggable = draggable; }
+
protected:
int _id;
WindowType _type;
@@ -380,10 +386,14 @@ public:
void addDirtyRect(const Common::Rect &r);
void markAllDirty();
void mergeDirtyRects();
+ Common::Rect getDirtyRectBounds();
+ void clearDirtyRects() { _dirtyRects.clear(); }
+ Common::List<Common::Rect> &getDirtyRectList() { return _dirtyRects; }
bool isDirty() override { return _borderIsDirty || _contentIsDirty; }
void setBorderDirty(bool dirty) { _borderIsDirty = true; }
+ void setContentDirty(bool dirty) { _contentIsDirty = true; }
void resizeBorderSurface();
void setMode(uint32 mode) { _mode = mode; }
Commit: 1274e6037ba053b06283a2d4cc8b4ea17a3d642a
https://github.com/scummvm/scummvm/commit/1274e6037ba053b06283a2d4cc8b4ea17a3d642a
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: Only use unsigned audio for Moa when 8-bit
Changed paths:
engines/director/sound.cpp
diff --git a/engines/director/sound.cpp b/engines/director/sound.cpp
index 7909926444f..ef55dbe3a16 100644
--- a/engines/director/sound.cpp
+++ b/engines/director/sound.cpp
@@ -1044,7 +1044,12 @@ Audio::AudioStream *MoaSoundFormatDecoder::getAudioStream(bool looping, bool for
byte *buffer = (byte *)malloc(_size);
memcpy(buffer, _data, _size);
- Audio::SeekableAudioStream *stream = Audio::makeRawStream(buffer, _size, _format.frameRate, ((_format.bitsPerSample == 16) ? Audio::RawFlags::FLAG_16BITS : 0) | ((_format.numChannels == 2) ? Audio::RawFlags::FLAG_STEREO : 0) | Audio::RawFlags::FLAG_UNSIGNED, disposeAfterUse);
+ Audio::SeekableAudioStream *stream = Audio::makeRawStream(buffer,
+ _size, _format.frameRate,
+ ((_format.bitsPerSample == 16) ? Audio::RawFlags::FLAG_16BITS : 0) |
+ ((_format.numChannels == 2) ? Audio::RawFlags::FLAG_STEREO : 0) |
+ ((_format.bitsPerSample == 8) ? Audio::RawFlags::FLAG_UNSIGNED : 0),
+ disposeAfterUse);
if (looping) {
if (_format.loopEndFrame < _format.loopStartFrame) {
Commit: b34dc9e277f316c66b6aff72a554c509b25a3b63
https://github.com/scummvm/scummvm/commit/b34dc9e277f316c66b6aff72a554c509b25a3b63
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: Fix regression in Movie::queueEvent
Fixes main menu buttons in Mean City.
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 246d73c1ad0..3bb7cc2f42a 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -539,14 +539,14 @@ void Movie::queueEvent(Common::Queue<LingoEvent> &queue, LEvent event, int targe
case kEventMouseWithin: // D6+
if (_vm->getVersion() >= 600) {
if (pointedSpriteId != 0) {
- Channel *channel = _score->_channels[channelId];
+ Channel *channel = _score->getChannelById(pointedSpriteId);
// Generate event for each behavior, and pass through for all but the last one.
// This is to allow multiple behaviors on a single sprite to each have a
// chance to handle the event.
for (uint i = 0; i < channel->_scriptInstanceList.size(); i++) {
bool passThrough = (i != channel->_scriptInstanceList.size() - 1);
- queue.push(LingoEvent(event, eventId, kSpriteHandler, passThrough, pos, channelId, i));
+ queue.push(LingoEvent(event, eventId, kSpriteHandler, passThrough, pos, pointedSpriteId, i));
}
if (event == kEventBeginSprite || event == kEventEndSprite || event == kEventMouseUpOutSide) {
Commit: b97c82b200a8d2dd81fa9089d83cf5025ba73717
https://github.com/scummvm/scummvm/commit/b97c82b200a8d2dd81fa9089d83cf5025ba73717
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: Defer changing the current window until the main loop
Changing the current window should only be done outside of Lingo
execution, or in specific context which support it like b_play.
Fixes sporadic crashes in Mean City.
Changed paths:
engines/director/director.cpp
engines/director/director.h
engines/director/lingo/lingo-events.cpp
diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 34ef5c1717d..e028d276526 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -86,6 +86,7 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
_mainArchive = nullptr;
_currentWindow = nullptr;
_cursorWindow = nullptr;
+ _windowToBeActive = nullptr;
_lingo = nullptr;
_clipBoard = nullptr;
_fixStageSize = false;
@@ -170,6 +171,10 @@ DirectorEngine::~DirectorEngine() {
for (auto &it : _windowList) {
it->decRefCount();
}
+ if (_windowToBeActive) {
+ _windowToBeActive->decRefCount();
+ _windowToBeActive = nullptr;
+ }
delete _lingo;
delete _wm;
delete _surface;
@@ -233,6 +238,18 @@ void DirectorEngine::setCurrentWindow(Window *window) {
_currentWindow->incRefCount();
}
+void DirectorEngine::setWindowToBeActive(Window *window) {
+ if (_windowToBeActive == window)
+ return;
+ if (window)
+ window->incRefCount();
+ if (_windowToBeActive) {
+ _windowToBeActive->decRefCount();
+ _windowToBeActive = nullptr;
+ }
+ _windowToBeActive = window;
+}
+
void DirectorEngine::setVersion(uint16 version) {
if (version == _version)
return;
@@ -362,6 +379,13 @@ Common::Error DirectorEngine::run() {
}
draw();
+
+ if (_windowToBeActive) {
+ setCurrentWindow(_windowToBeActive);
+ _windowToBeActive->decRefCount();
+ _windowToBeActive = nullptr;
+ }
+
while (!_windowsToForget.empty()) {
Window *window = _windowsToForget.back();
_windowsToForget.pop_back();
diff --git a/engines/director/director.h b/engines/director/director.h
index 120e68900df..1187b6d73c8 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -181,6 +181,7 @@ public:
Window *getOrCreateWindow(Common::String &name);
void forgetWindow(Window *window);
void setCurrentWindow(Window *window);
+ void setWindowToBeActive(Window *window);
Window *getCursorWindow() const { return _cursorWindow; }
void setCursorWindow(Window *window) { _cursorWindow = window; }
Movie *getCurrentMovie() const;
@@ -318,6 +319,7 @@ private:
Common::Array<Window *> _windowsToForget;
Window *_currentWindow;
Window *_cursorWindow;
+ Window *_windowToBeActive;
Graphics::MacPatterns _director3Patterns;
Graphics::MacPatterns _director3QuickDrawPatterns;
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index 3bb7cc2f42a..5354517988e 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -603,7 +603,7 @@ void Movie::queueInputEvent(LEvent event, int targetId, Common::Point pos) {
void Movie::processEvent(LEvent event, int targetId) {
Common::Queue<LingoEvent> queue;
queueEvent(queue, event, targetId);
- _vm->setCurrentWindow(this->getWindow());
+ _vm->setWindowToBeActive(this->getWindow());
_lingo->processEvents(queue, false);
}
Commit: 9766d228c3f1a7a08951dfaa867b41ceb904513f
https://github.com/scummvm/scummvm/commit/9766d228c3f1a7a08951dfaa867b41ceb904513f
Author: Scott Percival (code at moral.net.au)
Date: 2025-10-03T01:00:34+02:00
Commit Message:
DIRECTOR: Add guardrail for Movie::resolveScriptEvent
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 5354517988e..bc6874e757c 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -247,8 +247,12 @@ void Movie::resolveScriptEvent(LingoEvent &event) {
if (_vm->getVersion() >= 600) {
if (event.behaviorIndex >= 0) {
- scriptId = sprite->_behaviors[event.behaviorIndex].memberID;
- initializerParams = sprite->_behaviors[event.behaviorIndex].initializerParams;
+ if (event.behaviorIndex >= sprite->_behaviors.size()) {
+ warning("Movie::resolveScriptEvent: invalid behavior index %d, ignoring", event.behaviorIndex);
+ } else {
+ scriptId = sprite->_behaviors[event.behaviorIndex].memberID;
+ initializerParams = sprite->_behaviors[event.behaviorIndex].initializerParams;
+ }
} else {
_lastClickedSpriteId = 0;
return;
More information about the Scummvm-git-logs
mailing list