[Scummvm-git-logs] scummvm master -> 6c2c8e9303037f37afaa13ea8d6d49743ddd59b9
sev-
noreply at scummvm.org
Sun Mar 8 19:00:40 UTC 2026
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
b6eaad36c5 DIRECTOR: DT: Fix frame navigation in Control Panel UI
fb9911d559 DIRECTOR: DT: Add ignore-mouse option to debugger UI
00e92e1873 DIRECTOR: Support ignoring mouse events when debugging
08d3fe121e DIRECTOR: DT: Select channel in debugger on stage click
e46d732d84 DIRECTOR: DT: Select channel when clicking active sprite span in Score
15d47cec93 DIRECTOR: DT: Add Multi-Viewport toggle to debugger settings
87e4a555f2 DIRECTOR: DT: Double-click Score cells to jump to frame
18672e375c DIRECTOR: DT: Fix channel hiding in debugger UI
a9afc765be DIRECTOR: DT: Fix channel selection blocking clicks and row height
6c2c8e9303 DIRECTOR: DT: Fix ImGui crash when updating UI with paused submovies
Commit: b6eaad36c5dd12ce0af0344a0f5921f948c6994d
https://github.com/scummvm/scummvm/commit/b6eaad36c5dd12ce0af0344a0f5921f948c6994d
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Fix frame navigation in Control Panel UI
Changed paths:
engines/director/debugger/dt-controlpanel.cpp
diff --git a/engines/director/debugger/dt-controlpanel.cpp b/engines/director/debugger/dt-controlpanel.cpp
index 305dcc05fba..d0fd862aec2 100644
--- a/engines/director/debugger/dt-controlpanel.cpp
+++ b/engines/director/debugger/dt-controlpanel.cpp
@@ -141,6 +141,7 @@ void showControlPanel() {
float bgX1 = -4.0f, bgX2 = 21.0f;
int frameNum = score->getCurrentFrameNum();
+ int maxFrame = score->getFramesNum() - 1;
if (_state->_prevFrame != -1 && _state->_prevFrame != frameNum) {
score->_playState = kPlayPaused;
@@ -152,7 +153,9 @@ void showControlPanel() {
if (ImGui::IsItemClicked(0)) {
score->_playState = kPlayStarted;
- score->setCurrentFrame(1);
+ Datum frameDatum(1);
+ Datum movieDatum;
+ g_lingo->func_goto(frameDatum, movieDatum, true);
}
if (ImGui::IsItemHovered())
@@ -172,7 +175,11 @@ void showControlPanel() {
if (ImGui::IsItemClicked(0)) {
score->_playState = kPlayStarted;
- score->setCurrentFrame(frameNum - 1);
+ int targetFrame = (frameNum <= 1) ? maxFrame : (frameNum - 1);
+ Datum frameDatum(targetFrame);
+ Datum movieDatum;
+ g_lingo->func_goto(frameDatum, movieDatum, true);
+
_state->_prevFrame = frameNum;
}
@@ -216,7 +223,11 @@ void showControlPanel() {
if (ImGui::IsItemClicked(0)) {
score->_playState = kPlayStarted;
- score->setCurrentFrame(frameNum + 1);
+ int targetFrame = (frameNum >= maxFrame) ? 1 : (frameNum + 1);
+ Datum frameDatum(targetFrame);
+ Datum movieDatum;
+ g_lingo->func_goto(frameDatum, movieDatum, true);
+
_state->_prevFrame = frameNum;
}
@@ -261,7 +272,20 @@ void showControlPanel() {
snprintf(buf, 6, "%d", score->getCurrentFrameNum());
ImGui::SetNextItemWidth(35);
- ImGui::InputText("##frame", buf, 5, ImGuiInputTextFlags_CharsDecimal);
+ if (ImGui::InputText("##frame", buf, 5, ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_EnterReturnsTrue)) {
+ int newFrame = atoi(buf);
+ newFrame = (newFrame < 1) ? 1 : (newFrame > maxFrame ? maxFrame : newFrame);
+
+ if (newFrame != frameNum) {
+ score->_playState = kPlayStarted;
+
+ Datum frameDatum(newFrame);
+ Datum movieDatum;
+ g_lingo->func_goto(frameDatum, movieDatum, true);
+
+ _state->_prevFrame = frameNum;
+ }
+ }
ImGui::SetItemTooltip("Frame");
{
Commit: fb9911d559039e127678b8888b08c26c7cbce462
https://github.com/scummvm/scummvm/commit/fb9911d559039e127678b8888b08c26c7cbce462
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Add ignore-mouse option to debugger UI
Changed paths:
engines/director/debugger/debugtools.cpp
engines/director/debugger/debugtools.h
engines/director/debugger/dt-internal.h
diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index dcff9c3be01..d8a3f5532bd 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -649,6 +649,10 @@ static void showSettings() {
}
_state->_logger->drawColorOptions();
+
+ ImGui::SeparatorText("Debugger Behavior");
+ ImGui::Checkbox("Ignore Mouse Events", &_state->_ignoreMouse);
+ ImGui::SetItemTooltip("Block mouse events from reaching Director.\nHold SHIFT to temporarily allow them.\nPress Ctrl+F1 to toggle this setting.");
}
ImGui::End();
}
@@ -709,6 +713,13 @@ void onImGuiRender() {
ImGuiIO &io = ImGui::GetIO();
io.ConfigFlags &= ~(ImGuiConfigFlags_NoMouseCursorChange | ImGuiConfigFlags_NoMouse);
+ if (ImGui::IsKeyChordPressed(ImGuiMod_Ctrl | ImGuiKey_F1)) {
+ _state->_ignoreMouse = !_state->_ignoreMouse;
+
+ Common::String msg = Common::String::format("Debug Mouse Ignore: %s", _state->_ignoreMouse ? "ON" : "OFF");
+ g_system->displayMessageOnOSD(Common::U32String(msg));
+ }
+
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
if (ImGui::BeginMainMenuBar()) {
@@ -793,6 +804,18 @@ int getSelectedChannel(){
return _state ? _state->_selectedChannel : -1;
}
+bool isMouseInputIgnored() {
+ if (!_state || !_state->_ignoreMouse)
+ return false;
+
+ // Holding Shift temporarily allows mouse events to pass to the engine
+ ImGuiIO &io = ImGui::GetIO();
+ if (io.KeyShift)
+ return false;
+
+ return true;
+}
+
Common::String formatHandlerName(int scriptId, int castId, Common::String handlerName, ScriptType scriptType, bool childScript) {
Common::String formatted = Common::String();
// Naming convention: <script id> (<cast id/cast id of parent script>): name of handler: script type
diff --git a/engines/director/debugger/debugtools.h b/engines/director/debugger/debugtools.h
index 68e18857d8e..df4e5f6f48e 100644
--- a/engines/director/debugger/debugtools.h
+++ b/engines/director/debugger/debugtools.h
@@ -28,6 +28,7 @@ void onImGuiInit();
void onImGuiRender();
void onImGuiCleanup();
int getSelectedChannel();
+bool isMouseInputIgnored();
} // namespace DT
} // namespace Director
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index 37be478c097..80ccbcd5274 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -287,6 +287,7 @@ typedef struct ImGuiState {
} _archive;
ImGuiEx::ImGuiLogger *_logger = nullptr;
+ bool _ignoreMouse = false;
} ImGuiState;
// debugtools.cpp
Commit: 00e92e18732c56948e90913b2594e7bb62959edc
https://github.com/scummvm/scummvm/commit/00e92e18732c56948e90913b2594e7bb62959edc
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: Support ignoring mouse events when debugging
Changed paths:
engines/director/debugger/dt-save-state.cpp
engines/director/events.cpp
engines/director/lingo/lingo-the.cpp
engines/director/movie.cpp
engines/director/movie.h
engines/director/score.cpp
engines/director/window.cpp
diff --git a/engines/director/debugger/dt-save-state.cpp b/engines/director/debugger/dt-save-state.cpp
index 4bab8cc1f96..c614e768e32 100644
--- a/engines/director/debugger/dt-save-state.cpp
+++ b/engines/director/debugger/dt-save-state.cpp
@@ -94,6 +94,7 @@ void saveCurrentState() {
json["ScoreWindow"] = new Common::JSONValue(_state->_scoreWindow);
json["ChannelsWindow"] = new Common::JSONValue(_state->_channelsWindow);
json["CastWindow"] = new Common::JSONValue(_state->_castWindow);
+ json["IgnoreMouse"] = new Common::JSONValue(_state->_ignoreMouse);
// Save the JSON
Common::JSONValue save(json);
@@ -177,6 +178,7 @@ void loadSavedState() {
_state->_scoreWindow = saved->asObject()["ScoreWindow"]->asString();
_state->_channelsWindow = saved->asObject()["ChannelsWindow"]->asString();
_state->_castWindow = saved->asObject()["CastWindow"]->asString();
+ _state->_ignoreMouse = saved->asObject()["IgnoreMouse"]->asBool();
free(data);
delete saved;
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 94d1578624a..c8733199068 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -37,6 +37,7 @@
#include "director/sprite.h"
#include "director/window.h"
#include "director/castmember/castmember.h"
+#include "director/debugger/debugtools.h"
namespace Director {
@@ -58,6 +59,12 @@ bool DirectorEngine::processEvents(bool captureClick, bool skipWindowManager) {
Common::Event event;
while (pollEvent(event)) {
+ if (Director::DT::isMouseInputIgnored()) {
+ if (Common::isMouseEvent(event)) {
+ continue;
+ }
+ }
+
if (skipWindowManager || !_wm->processEvent(event)) {
// We only want to handle these events if the event
// wasn't handled by the window manager.
@@ -143,6 +150,7 @@ bool Movie::processEvent(Common::Event &event) {
spriteId = _score->getMouseSpriteIDFromPos(event.mouse);
_currentHoveredSpriteId = spriteId;
+ _lastMousePos = event.mouse;
}
Common::Point pos;
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 14f0b894fe7..3e128d824de 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -42,6 +42,7 @@
#include "director/lingo/lingo-builtins.h"
#include "director/lingo/lingo-code.h"
#include "director/lingo/lingo-the.h"
+#include "director/debugger/debugtools.h"
namespace Director {
@@ -856,7 +857,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
}
break;
case kTheMouseDown:
- d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_LEFT | 1 << Common::MOUSE_BUTTON_RIGHT) ? 1 : 0;
+ if (Director::DT::isMouseInputIgnored()) {
+ d = 0;
+ } else {
+ d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_LEFT | 1 << Common::MOUSE_BUTTON_RIGHT) ? 1 : 0;
+ }
break;
case kTheMouseDownScript:
d.type = STRING;
@@ -896,7 +901,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
}
break;
case kTheMouseUp:
- d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_LEFT | 1 << Common::MOUSE_BUTTON_RIGHT) ? 0 : 1;
+ if (Director::DT::isMouseInputIgnored()) {
+ d = 1;
+ } else {
+ d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_LEFT | 1 << Common::MOUSE_BUTTON_RIGHT) ? 0 : 1;
+ }
break;
case kTheMouseUpScript:
d.type = STRING;
@@ -1003,10 +1012,18 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
d = g_lingo->_theResult;
break;
case kTheRightMouseDown:
- d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_RIGHT) ? 1 : 0;
+ if (Director::DT::isMouseInputIgnored()) {
+ d = 0;
+ } else {
+ d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_RIGHT) ? 1 : 0;
+ }
break;
case kTheRightMouseUp:
- d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_RIGHT) ? 0 : 1;
+ if (Director::DT::isMouseInputIgnored()) {
+ d = 1;
+ } else {
+ d = g_system->getEventManager()->getButtonState() & (1 << Common::MOUSE_BUTTON_RIGHT) ? 0 : 1;
+ }
break;
case kTheRollOver:
d = score->getSpriteIDFromPos(g_director->getCurrentWindow()->getMousePos());
@@ -1119,7 +1136,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
}
break;
case kTheStillDown:
- d = _vm->_wm->_mouseDown;
+ if (Director::DT::isMouseInputIgnored()) {
+ d = 0;
+ } else {
+ d = _vm->_wm->_mouseDown;
+ }
break;
case kTheSwitchColorDepth:
getTheEntitySTUB(kTheSwitchColorDepth);
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index 2bdf3e672d0..b840a3a4770 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -55,6 +55,7 @@ Movie::Movie(Window *window) {
_lastKeyTime = _lastEventTime;
_lastClickTime = _lastEventTime;
_lastClickTime2 = 0;
+ _lastMousePos = Common::Point(0, 0);
_lastRollTime = _lastEventTime;
_lastTimerReset = _lastEventTime;
_nextEventId = 0;
diff --git a/engines/director/movie.h b/engines/director/movie.h
index a463a1d6b6e..3388b320a56 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -167,6 +167,7 @@ public:
uint32 _lastClickTime;
uint32 _lastClickTime2;
Common::Point _lastClickPos;
+ Common::Point _lastMousePos;
uint32 _lastKeyTime;
uint32 _lastTimerReset;
uint32 _stageColor;
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index db9bb484895..1dd509dff5e 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -49,6 +49,7 @@
#include "director/castmember/castmember.h"
#include "director/castmember/filmloop.h"
#include "director/castmember/transition.h"
+#include "director/debugger/debugtools.h"
namespace Director {
@@ -363,7 +364,8 @@ void Score::step() {
_soundManager->processCuePoints();
} else if (_version >= kFileVer500) {
// In D5, these events are only generated if a mouse button is pressed
- if (_movie->_currentHoveredSpriteId && g_system->getEventManager()->getButtonState() != 0) {
+ bool isButtonDown = !Director::DT::isMouseInputIgnored() && (g_system->getEventManager()->getButtonState() != 0);
+ if (_movie->_currentHoveredSpriteId && isButtonDown) {
_movie->processEvent(kEventMouseWithin, _movie->_currentHoveredSpriteId);
}
}
@@ -1398,6 +1400,10 @@ void Score::renderPaletteCycle(RenderMode mode) {
}
void Score::renderCursor(Common::Point pos, bool forceUpdate) {
+ if (Director::DT::isMouseInputIgnored()) {
+ pos = _movie->_lastMousePos;
+ }
+
if (_window != _vm->getCursorWindow()) {
// The cursor is outside of this window.
return;
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 3834bace3b2..5e9437b9389 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -413,6 +413,10 @@ void Window::inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::Mana
}
Common::Point Window::getMousePos() {
+ if (Director::DT::isMouseInputIgnored() && _currentMovie) {
+ return _currentMovie->_lastMousePos;
+ }
+
Common::Rect innerDims = _window->getInnerDimensions();
return g_system->getEventManager()->getMousePos() - Common::Point(innerDims.left, innerDims.top);
}
Commit: 08d3fe121e7b48f01dd1e0315b3be3f77dac1b5d
https://github.com/scummvm/scummvm/commit/08d3fe121e7b48f01dd1e0315b3be3f77dac1b5d
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Select channel in debugger on stage click
Changed paths:
engines/director/debugger/debugtools.cpp
engines/director/debugger/debugtools.h
engines/director/debugger/dt-internal.h
engines/director/debugger/dt-score.cpp
engines/director/events.cpp
diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index d8a3f5532bd..12beacad8f8 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -804,6 +804,17 @@ int getSelectedChannel(){
return _state ? _state->_selectedChannel : -1;
}
+void setSelectedChannel(int channel) {
+ if (_state) {
+ _state->_selectedChannel = channel;
+
+ if (channel > 0) {
+ _state->_scrollToChannel = true;
+ _state->_w.channels = true;
+ }
+ }
+}
+
bool isMouseInputIgnored() {
if (!_state || !_state->_ignoreMouse)
return false;
diff --git a/engines/director/debugger/debugtools.h b/engines/director/debugger/debugtools.h
index df4e5f6f48e..dd554659144 100644
--- a/engines/director/debugger/debugtools.h
+++ b/engines/director/debugger/debugtools.h
@@ -28,6 +28,7 @@ void onImGuiInit();
void onImGuiRender();
void onImGuiCleanup();
int getSelectedChannel();
+void setSelectedChannel(int channel);
bool isMouseInputIgnored();
} // namespace DT
} // namespace Director
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index 80ccbcd5274..3d825b03396 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -269,6 +269,7 @@ typedef struct ImGuiState {
int _scoreFrameOffset = 1;
int _scorePageSlider = 0;
int _selectedChannel = -1;
+ bool _scrollToChannel = false;
ImFont *_tinyFont = nullptr;
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index 59ca362c027..8638b21a8a9 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -1217,6 +1217,11 @@ void showChannels() {
ImGui::TableNextRow();
+ if (_state->_selectedChannel == i + 1 && _state->_scrollToChannel) {
+ ImGui::SetScrollHereY(0.5f);
+ _state->_scrollToChannel = false;
+ }
+
{ // Playback toggle
ImGui::TableNextColumn();
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index c8733199068..21b1d987bda 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -61,6 +61,19 @@ bool DirectorEngine::processEvents(bool captureClick, bool skipWindowManager) {
while (pollEvent(event)) {
if (Director::DT::isMouseInputIgnored()) {
if (Common::isMouseEvent(event)) {
+ if (event.type == Common::EVENT_LBUTTONDOWN) {
+ Window *window = g_director->getCurrentWindow();
+ Score *score = window->getCurrentMovie()->getScore();
+ uint16 spriteId = 0;
+
+ if (g_director->getVersion() < 400)
+ spriteId = score->getActiveSpriteIDFromPos(event.mouse);
+ else
+ spriteId = score->getMouseSpriteIDFromPos(event.mouse);
+
+ Director::DT::setSelectedChannel(spriteId);
+ window->render(true);
+ }
continue;
}
}
Commit: e46d732d8427b9b91119f0fc78c09e34e60e2d68
https://github.com/scummvm/scummvm/commit/e46d732d8427b9b91119f0fc78c09e34e60e2d68
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Select channel when clicking active sprite span in Score
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 8638b21a8a9..6b6a4573c7a 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -24,6 +24,7 @@
#include "backends/imgui/IconsMaterialSymbols.h"
#include "director/director.h"
#include "director/debugger/dt-internal.h"
+#include "director/debugger/debugtools.h"
#include "director/cast.h"
#include "director/castmember/castmember.h"
@@ -730,6 +731,12 @@ static void drawSpriteGrid(ImDrawList *dl, ImVec2 startPos, Score *score, Cast *
_state->_selectedScoreCast.frame = rf;
_state->_selectedScoreCast.channel = ch;
_state->_selectedScoreCast.isMainChannel = false;
+
+ int playheadIdx = score->getCurrentFrameNum() - 1;
+ if (playheadIdx >= spanStart && playheadIdx <= spanEnd) {
+ Director::DT::setSelectedChannel(ch);
+ window->render(true);
+ }
}
if (ImGui::IsItemHovered()) {
Commit: 15d47cec93aa42e05e40d274e40773640b48c3ec
https://github.com/scummvm/scummvm/commit/15d47cec93aa42e05e40d274e40773640b48c3ec
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Add Multi-Viewport toggle to debugger settings
Changed paths:
engines/director/debugger/debugtools.cpp
engines/director/debugger/dt-internal.h
engines/director/debugger/dt-save-state.cpp
diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index 12beacad8f8..cac3485c667 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -653,6 +653,16 @@ static void showSettings() {
ImGui::SeparatorText("Debugger Behavior");
ImGui::Checkbox("Ignore Mouse Events", &_state->_ignoreMouse);
ImGui::SetItemTooltip("Block mouse events from reaching Director.\nHold SHIFT to temporarily allow them.\nPress Ctrl+F1 to toggle this setting.");
+
+ ImGuiIO &io = ImGui::GetIO();
+ if (ImGui::Checkbox("Enable Multi-Viewport", &_state->_enableMultiViewport)) {
+ if (_state->_enableMultiViewport) {
+ io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
+ } else {
+ io.ConfigFlags &= ~ImGuiConfigFlags_ViewportsEnable;
+ }
+ }
+ ImGui::SetItemTooltip("When disabled, all debugger windows are forced to stay inside the main ScummVM window.");
}
ImGui::End();
}
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index 3d825b03396..fd2e1ea8832 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -289,6 +289,7 @@ typedef struct ImGuiState {
ImGuiEx::ImGuiLogger *_logger = nullptr;
bool _ignoreMouse = false;
+ bool _enableMultiViewport = true;
} ImGuiState;
// debugtools.cpp
diff --git a/engines/director/debugger/dt-save-state.cpp b/engines/director/debugger/dt-save-state.cpp
index c614e768e32..0180968d6ee 100644
--- a/engines/director/debugger/dt-save-state.cpp
+++ b/engines/director/debugger/dt-save-state.cpp
@@ -95,6 +95,7 @@ void saveCurrentState() {
json["ChannelsWindow"] = new Common::JSONValue(_state->_channelsWindow);
json["CastWindow"] = new Common::JSONValue(_state->_castWindow);
json["IgnoreMouse"] = new Common::JSONValue(_state->_ignoreMouse);
+ json["EnableMultiViewport"] = new Common::JSONValue(_state->_enableMultiViewport);
// Save the JSON
Common::JSONValue save(json);
@@ -179,6 +180,14 @@ void loadSavedState() {
_state->_channelsWindow = saved->asObject()["ChannelsWindow"]->asString();
_state->_castWindow = saved->asObject()["CastWindow"]->asString();
_state->_ignoreMouse = saved->asObject()["IgnoreMouse"]->asBool();
+ _state->_enableMultiViewport = saved->asObject()["EnableMultiViewport"]->asBool();
+
+ ImGuiIO &io = ImGui::GetIO();
+ if (_state->_enableMultiViewport) {
+ io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
+ } else {
+ io.ConfigFlags &= ~ImGuiConfigFlags_ViewportsEnable;
+ }
free(data);
delete saved;
Commit: 87e4a555f2149333a7da6a2aa39b6be43a560cf6
https://github.com/scummvm/scummvm/commit/87e4a555f2149333a7da6a2aa39b6be43a560cf6
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Double-click Score cells to jump to frame
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 6b6a4573c7a..63809e503d9 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -739,6 +739,19 @@ static void drawSpriteGrid(ImDrawList *dl, ImVec2 startPos, Score *score, Cast *
}
}
+ if (ImGui::IsItemHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
+ score->_playState = kPlayStarted;
+
+ Datum frameDatum(rf + 1);
+ Datum movieDatum;
+ g_lingo->func_goto(frameDatum, movieDatum, true);
+
+ _state->_prevFrame = score->getCurrentFrameNum();
+
+ Director::DT::setSelectedChannel(ch);
+ window->render(true);
+ }
+
if (ImGui::IsItemHovered()) {
_state->_hoveredScoreCast.frame = rf;
_state->_hoveredScoreCast.channel = ch;
Commit: 18672e375c6e2e09eb9fecb998bfa8af14442a3c
https://github.com/scummvm/scummvm/commit/18672e375c6e2e09eb9fecb998bfa8af14442a3c
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Fix channel hiding in debugger UI
Changed paths:
engines/director/channel.cpp
engines/director/channel.h
engines/director/debugger/debugtools.cpp
engines/director/debugger/dt-internal.h
engines/director/debugger/dt-score.cpp
engines/director/window.cpp
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 0909843da10..916038bba78 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -62,6 +62,7 @@ Channel::Channel(Score *sc, Sprite *sp, int priority) {
_visible = true;
_dirty = true;
+ _hideFromStage = false;
if (sp) {
_startFrame = sp->_spriteInfo.startFrame;
@@ -95,6 +96,7 @@ Channel& Channel::operator=(const Channel &channel) {
_visible = channel._visible;
_dirty = channel._dirty;
+ _hideFromStage = channel._hideFromStage;
_startFrame = channel._startFrame;
_endFrame = channel._endFrame;
diff --git a/engines/director/channel.h b/engines/director/channel.h
index 3e50aaeb6c8..69bde1c55ce 100644
--- a/engines/director/channel.h
+++ b/engines/director/channel.h
@@ -107,6 +107,7 @@ public:
bool _dirty;
bool _visible;
+ bool _hideFromStage; // Used in DT for hiding the channel from rendering
uint _constraint;
Graphics::ManagedSurface *_mask;
diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index cac3485c667..f07deac74b9 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -499,6 +499,7 @@ static const DebuggerTheme themes[kThemeCount] = {
IM_COL32(0xC8, 0x32, 0x00, 0xFF), // playhead_color
IM_COL32(0xFF, 0xFF, 0x00, 0x20), // current_statement_bg
IM_COL32(0x30, 0x30, 0xFF, 0xFF), // channel_toggle
+ IM_COL32(0xB4, 0x32, 0x32, 0xC8), // channel_hide_bg
IM_COL32(0x94, 0x00, 0xD3, 0xFF), // channelSelectedCol
IM_COL32(0xFF, 0xFF, 0x00, 0x3C), // channelHoveredCol
{ // contColors
@@ -556,6 +557,7 @@ static const DebuggerTheme themes[kThemeCount] = {
IM_COL32(0xC8, 0x32, 0x00, 0xFF), // playhead_color
IM_COL32(0xFF, 0xFF, 0x00, 0x60), // current_statement_bg
IM_COL32(0x00, 0x00, 0xB0, 0xFF), // channel_toggle
+ IM_COL32(0xDC, 0x3C, 0x3C, 0xC8), // channel_hide_bg
IM_COL32(0x94, 0x00, 0xD3, 0xFF), // channelSelectedCol
IM_COL32(0xD0, 0x90, 0x00, 0x50), // channelHoveredCol
{ // contColors
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index fd2e1ea8832..2501aac6e72 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -125,6 +125,7 @@ struct DebuggerTheme {
ImU32 playhead_color;
ImU32 current_statement_bg;
ImU32 channel_toggle;
+ ImU32 channel_hide_bg;
ImU32 channelSelectedCol;
ImU32 channelHoveredCol;
ImU32 contColors[6];
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index 63809e503d9..f96a8d037ed 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -297,7 +297,17 @@ static void drawSidebar2(ImDrawList *dl, ImVec2 startPos, Score *score) {
ImVec2 center(rowMin.x + pad + radius, rowMax.y - pad - radius);
- if (score->_channels[ch]->_visible)
+ bool isEngineVis = score->_channels[ch]->_visible;
+ bool isHiddenFromStage = score->_channels[ch]->_hideFromStage;
+
+ if (isHiddenFromStage) {
+ float offset = 6.0f;
+ ImVec2 boxMin(center.x - offset, center.y - offset);
+ ImVec2 boxMax(center.x + offset, center.y + offset);
+ dl->AddRectFilled(boxMin, boxMax, _state->theme->channel_hide_bg);
+ }
+
+ if (isEngineVis)
dl->AddCircleFilled(center, radius, _state->theme->channel_toggle);
else
dl->AddCircle(center, radius, _state->theme->channel_toggle);
@@ -307,7 +317,7 @@ static void drawSidebar2(ImDrawList *dl, ImVec2 startPos, Score *score) {
if (ImGui::IsItemHovered())
setTooltip("Playback toggle");
if (ImGui::IsItemClicked()) { // determines what happens on toggle of the button
- score->_channels[ch]->_visible = !score->_channels[ch]->_visible;
+ score->_channels[ch]->_hideFromStage = !isHiddenFromStage;
}
// channel num and extra stuff if extended mode
@@ -1242,6 +1252,9 @@ void showChannels() {
_state->_scrollToChannel = false;
}
+ bool isEngineVis = channel._visible;
+ bool isHiddenFromStage = channel._hideFromStage;
+
{ // Playback toggle
ImGui::TableNextColumn();
@@ -1254,12 +1267,18 @@ void showChannels() {
ImGui::SetItemTooltip("Playback toggle");
if (ImGui::IsItemClicked(0)) {
- score->_channels[i]->_visible = !score->_channels[i]->_visible;
-
+ channel._hideFromStage = !isHiddenFromStage;
selectedWindow->render(true);
}
- if (score->_channels[i]->_visible)
+ if (isHiddenFromStage) {
+ float offset = 6.0f;
+ ImVec2 boxMin(mid.x - offset, mid.y - offset);
+ ImVec2 boxMax(mid.x + offset, mid.y + offset);
+ dl->AddRectFilled(boxMin, boxMax, _state->theme->channel_hide_bg);
+ }
+
+ if (isEngineVis)
dl->AddCircleFilled(mid, 4.0f, _state->theme->channel_toggle);
else
dl->AddCircle(mid, 4.0f, _state->theme->channel_toggle);
@@ -1290,7 +1309,9 @@ void showChannels() {
ImGui::Text("%s", sprite._castId.asString().c_str());
ImGui::TableNextColumn();
colN = "##vis" + chNum;
- ImGui::Checkbox(colN.c_str(), &channel._visible);
+ if (ImGui::Checkbox(colN.c_str(), &channel._visible)) {
+ selectedWindow->render(true);
+ }
ImGui::TableNextColumn();
ImGui::Text("0x%02x", sprite._inkData);
ImGui::TableNextColumn();
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 5e9437b9389..fb588074cdb 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -202,7 +202,9 @@ bool Window::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
bool shouldClear = true;
Channel *trailChannel = nullptr;
for (auto &j : _dirtyChannels) {
- if (j->_visible && r == j->getBbox() && j->isTrail()) {
+ bool isHidden = false;
+ isHidden = j->_hideFromStage;
+ if (j->_visible && !isHidden && r == j->getBbox() && j->isTrail()) {
shouldClear = false;
trailChannel = j;
break;
@@ -227,6 +229,9 @@ bool Window::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
continue;
}
+ if (j->_hideFromStage)
+ continue;
+
if (j->_visible) {
if (j->hasSubChannels()) {
Common::Array<Channel> *list = j->getSubChannels();
Commit: a9afc765bec1f2e51fbe2444a175457365a20b21
https://github.com/scummvm/scummvm/commit/a9afc765bec1f2e51fbe2444a175457365a20b21
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Fix channel selection blocking clicks and row height
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 f96a8d037ed..4f78cf3a9f8 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -1289,7 +1289,9 @@ void showChannels() {
ImGui::TableNextColumn();
bool isSelected = (_state->_selectedChannel == i + 1);
- if (ImGui::Selectable(Common::String::format("%-3d", i + 1).c_str(), isSelected, ImGuiSelectableFlags_SpanAllColumns)) {
+ int numLines = (score->_version >= kFileVer600) ? MAX<int>(1, sprite._behaviors.size()) : 1;
+ float rowHeight = (ImGui::GetTextLineHeightWithSpacing() * numLines) + (ImGui::GetStyle().CellPadding.y * 2);
+ if (ImGui::Selectable(Common::String::format("%-3d", i + 1).c_str(), isSelected, ImGuiSelectableFlags_SpanAllColumns | ImGuiSelectableFlags_AllowOverlap, ImVec2(0, rowHeight))) {
if (isSelected) {
_state->_selectedChannel = -1;
} else {
Commit: 6c2c8e9303037f37afaa13ea8d6d49743ddd59b9
https://github.com/scummvm/scummvm/commit/6c2c8e9303037f37afaa13ea8d6d49743ddd59b9
Author: Krish Ganatra (ganatrakrish2882005 at gmail.com)
Date: 2026-03-08T20:00:26+01:00
Commit Message:
DIRECTOR: DT: Fix ImGui crash when updating UI with paused submovies
Problem: Calling window->render(true) directly from UI clicks crashes the engine if it's paused and a submovie is active.
Fix: Instead of forcing an immediate render, push a full-screen dirty rect at the end of onImGuiRender().
Changed paths:
engines/director/debugger/debugtools.cpp
engines/director/debugger/dt-internal.h
engines/director/debugger/dt-score.cpp
diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index f07deac74b9..ee94369c17c 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -722,6 +722,18 @@ void onImGuiRender() {
if (!_state)
return;
+ if (_state->_windowToRedraw) {
+ Graphics::ManagedSurface *surface = _state->_windowToRedraw->getSurface();
+ if (surface) {
+ Common::Rect fullScreen(0, 0, surface->w, surface->h);
+
+ _state->_windowToRedraw->addDirtyRect(fullScreen);
+ _state->_windowToRedraw->setDirty(true);
+ }
+
+ _state->_windowToRedraw = nullptr;
+ }
+
ImGuiIO &io = ImGui::GetIO();
io.ConfigFlags &= ~(ImGuiConfigFlags_NoMouseCursorChange | ImGuiConfigFlags_NoMouse);
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index 2501aac6e72..a3056963860 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -34,6 +34,7 @@
#include "backends/imgui/components/imgui_memory_editor.h"
#include "director/types.h"
+#include "director/window.h"
#include "director/lingo/lingo.h"
#include "director/lingo/lingodec/ast.h"
#include "director/lingo/lingodec/handler.h"
@@ -291,6 +292,8 @@ typedef struct ImGuiState {
ImGuiEx::ImGuiLogger *_logger = nullptr;
bool _ignoreMouse = false;
bool _enableMultiViewport = true;
+
+ Window *_windowToRedraw = nullptr;
} ImGuiState;
// debugtools.cpp
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index 4f78cf3a9f8..5eb3deb928f 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -745,7 +745,7 @@ static void drawSpriteGrid(ImDrawList *dl, ImVec2 startPos, Score *score, Cast *
int playheadIdx = score->getCurrentFrameNum() - 1;
if (playheadIdx >= spanStart && playheadIdx <= spanEnd) {
Director::DT::setSelectedChannel(ch);
- window->render(true);
+ _state->_windowToRedraw = window;
}
}
@@ -759,7 +759,7 @@ static void drawSpriteGrid(ImDrawList *dl, ImVec2 startPos, Score *score, Cast *
_state->_prevFrame = score->getCurrentFrameNum();
Director::DT::setSelectedChannel(ch);
- window->render(true);
+ _state->_windowToRedraw = window;
}
if (ImGui::IsItemHovered()) {
@@ -1268,7 +1268,7 @@ void showChannels() {
if (ImGui::IsItemClicked(0)) {
channel._hideFromStage = !isHiddenFromStage;
- selectedWindow->render(true);
+ _state->_windowToRedraw = selectedWindow;
}
if (isHiddenFromStage) {
@@ -1298,7 +1298,7 @@ void showChannels() {
_state->_selectedChannel = i + 1;
}
- selectedWindow->render(true);
+ _state->_windowToRedraw = selectedWindow;
}
ImGui::TableNextColumn();
@@ -1312,7 +1312,7 @@ void showChannels() {
ImGui::TableNextColumn();
colN = "##vis" + chNum;
if (ImGui::Checkbox(colN.c_str(), &channel._visible)) {
- selectedWindow->render(true);
+ _state->_windowToRedraw = selectedWindow;
}
ImGui::TableNextColumn();
ImGui::Text("0x%02x", sprite._inkData);
More information about the Scummvm-git-logs
mailing list