[Scummvm-git-logs] scummvm master -> 35a75d077b5eda6698f9d9b60dcb9926bd0d708c

sev- noreply at scummvm.org
Thu Mar 12 01:51:50 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:
9d759e2a59 DIRECTOR: DT: Minor function changes
358587ea25 DIRECTOR: LINGO: Call varWriteHook for GLOBALREF assignments
75615d8df3 DIRECTOR: DT: Add search for vars
46a3c09701 JANITORIAL: Add correct indentation
7bb2f03d8f DIRECTOR: DT: Add minor changes to search
35a75d077b DIRECTOR: DT: Remove unnecessary headers


Commit: 9d759e2a597442fddb30a675d3a139ccf033492d
    https://github.com/scummvm/scummvm/commit/9d759e2a597442fddb30a675d3a139ccf033492d
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-03-12T02:51:42+01:00

Commit Message:
DIRECTOR: DT: Minor function changes

Changed paths:
    engines/director/debugger/debugtools.cpp
    engines/director/debugger/dt-internal.h
    engines/director/debugger/dt-score.cpp
    engines/director/debugger/dt-scripts.cpp


diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index ee94369c17c..053672c74bf 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -397,6 +397,11 @@ static void addScriptCastToDisplay(CastMemberID &id) {
 	_state->_scriptCasts.push_back(id);
 }
 
+void addToOpenHandlers(ImGuiScript handler) {
+	_state->_openHandlers.erase(handler.id.member);
+	_state->_openHandlers[handler.id.member] = handler;
+}
+
 void setScriptToDisplay(const ImGuiScript &script) {
 	ScriptData *scriptData = &_state->_functions._windowScriptData.getOrCreateVal(g_director->getCurrentWindow());
 	uint index = scriptData->_scripts.size();
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index a3056963860..1bebbdc370b 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -300,6 +300,7 @@ typedef struct ImGuiState {
 ImGuiScript toImGuiScript(ScriptType scriptType, CastMemberID id, const Common::String &handlerId);
 ScriptContext *getScriptContext(CastMemberID id);
 ScriptContext *getScriptContext(uint32 nameIndex, CastMemberID castId, Common::String handler);
+void addToOpenHandlers(ImGuiScript handler);
 void setScriptToDisplay(const ImGuiScript &script);
 Director::Breakpoint *getBreakpoint(const Common::String &handlerName, uint16 scriptId, uint pc);
 void displayScriptRef(CastMemberID &scriptId);
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index 5eb3deb928f..056d45f4cc9 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -971,8 +971,7 @@ static void drawMainChannelGrid(ImDrawList *dl, ImVec2 startPos, Score *score) {
 				case kChScript: // open script in script editor
 					if (mc.actionId.member) {
 						ImGuiScript script = toImGuiScript(kScoreScript, mc.actionId, "");
-						setScriptToDisplay(script);
-						_state->_w.funcList = true;
+						addToOpenHandlers(script);
 					}
 					break;
 				}
diff --git a/engines/director/debugger/dt-scripts.cpp b/engines/director/debugger/dt-scripts.cpp
index 2dd5a15189d..0b3dc39c2ce 100644
--- a/engines/director/debugger/dt-scripts.cpp
+++ b/engines/director/debugger/dt-scripts.cpp
@@ -221,11 +221,6 @@ void showScriptCasts() {
 	}
 }
 
-static void addToOpenHandlers(ImGuiScript handler) {
-	_state->_openHandlers.erase(handler.id.member);
-	_state->_openHandlers[handler.id.member] = handler;
-}
-
 static bool showHandler(ImGuiScript handler) {
 	ScriptContext *ctx = getScriptContext(handler.id);
 	Common::String wName;


Commit: 358587ea25d01f3788d6807f4140f514ecc681e0
    https://github.com/scummvm/scummvm/commit/358587ea25d01f3788d6807f4140f514ecc681e0
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-03-12T02:51:42+01:00

Commit Message:
DIRECTOR: LINGO: Call varWriteHook for GLOBALREF assignments

Changed paths:
    engines/director/lingo/lingo.cpp


diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index ee491afd675..c3a2681de79 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -1736,6 +1736,7 @@ void Lingo::varAssign(const Datum &var, const Datum &value) {
 		// So while we require other variable types to be initialized before assigning to them,
 		// let's not enforce that for globals.
 		_globalvars[*var.u.s] = value;
+		g_debugger->varWriteHook(*var.u.s);
 		break;
 	case LOCALREF:
 		{


Commit: 75615d8df3b1b65d5f30b8d9dc0a08ec13b39cc3
    https://github.com/scummvm/scummvm/commit/75615d8df3b1b65d5f30b8d9dc0a08ec13b39cc3
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-03-12T02:51:42+01:00

Commit Message:
DIRECTOR: DT: Add search for vars

Changed paths:
  A engines/director/debugger/dt-search.cpp
    engines/director/debugger.cpp
    engines/director/debugger/debugtools.cpp
    engines/director/debugger/dt-internal.h
    engines/director/debugger/dt-lists.cpp
    engines/director/module.mk


diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index 6dca2360080..e6d2aeb0df1 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -38,6 +38,10 @@
 #include "director/lingo/lingo-object.h"
 #include "director/lingo/lingo-the.h"
 
+#ifdef USE_IMGUI
+#include "director/debugger/dt-internal.h"
+#endif
+
 namespace Director {
 
 #define PROMPT "lingo) "
@@ -1369,20 +1373,57 @@ void Debugger::varReadHook(const Common::String &name) {
 }
 
 void Debugger::varWriteHook(const Common::String &name) {
-	if (name.empty())
-		return;
-	if (_bpCheckVarWrite) {
-		for (auto &it : g_lingo->getBreakpoints()) {
-			if (it.type == kBreakpointVariable && it.varWrite && it.varName.equalsIgnoreCase(name)) {
-				debugPrintf("Hit a breakpoint:\n");
-				debugPrintf("%s\n", it.format().c_str());
-				cmdScriptFrame(0, nullptr);
-				attach();
-				g_system->updateScreen();
-				break;
-			}
-		}
-	}
+    if (name.empty())
+        return;
+    if (_bpCheckVarWrite) {
+        for (auto &it : g_lingo->getBreakpoints()) {
+            if (it.type == kBreakpointVariable && it.varWrite && it.varName.equalsIgnoreCase(name)) {
+                debugPrintf("Hit a breakpoint:\n");
+                debugPrintf("%s\n", it.format().c_str());
+                cmdScriptFrame(0, nullptr);
+                attach();
+                g_system->updateScreen();
+                break;
+            }
+        }
+    }
+
+#ifdef USE_IMGUI
+    if (!DT::_state || !DT::_state->_variables.contains(name))
+        return;
+
+    DT::ImGuiState::WatchLogEntry entry;
+    entry.varName = name;
+
+    entry.value = "(unknown)";
+    if (g_lingo->_state->localVars && g_lingo->_state->localVars->contains(name))
+        entry.value = formatStringForDump(g_lingo->_state->localVars->getVal(name).asString(true));
+    else if (g_lingo->_globalvars.contains(name))
+        entry.value = formatStringForDump(g_lingo->_globalvars.getVal(name).asString(true));
+
+    entry.scriptRef = "(unknown)";
+    if (!g_lingo->_state->callstack.empty()) {
+        CFrame *head = g_lingo->_state->callstack.back();
+        if (head && head->sp.ctx && head->sp.name) {
+            entry.scriptRef = DT::formatHandlerName(
+                head->sp.ctx->_scriptId,
+                head->sp.ctx->_id,
+                *head->sp.name,
+                head->sp.ctx->_scriptType,
+                false
+            );
+        }
+    }
+
+    DT::_state->_watchLog.push_back(entry);
+    if (DT::_state->_watchLog.size() > 100)
+        DT::_state->_watchLog.remove_at(0);
+
+    debug("Var write: '%s' = %s  [%s]",
+        entry.varName.c_str(),
+        entry.value.c_str(),
+        entry.scriptRef.c_str());
+#endif
 }
 
 void Debugger::entityReadHook(int entity, int field) {
diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index 053672c74bf..4856407ff1f 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -79,6 +79,9 @@ const LingoDec::Handler *getHandler(const Cast *cast, CastMemberID id, const Com
 
 const LingoDec::Handler *getHandler(CastMemberID id, const Common::String &handlerId) {
 	const Director::Movie *movie = g_director->getCurrentMovie();
+	if (id.castLib == SHARED_CAST_LIB)
+        return getHandler(movie->getSharedCast(), id, handlerId);
+
 	const Cast *cast = movie->getCasts()->getVal(id.castLib);
 
 	const LingoDec::Handler *handler = getHandler(cast, id, handlerId);
@@ -126,6 +129,11 @@ ScriptContext *getScriptContext(CastMemberID id) {
 	const Director::Movie *movie = g_director->getCurrentMovie();;
 	const Cast *cast = movie->getCasts()->getVal(id.castLib);
 
+	if (id.castLib == SHARED_CAST_LIB)
+		cast = movie->getSharedCast();
+	else
+		cast = movie->getCasts()->getVal(id.castLib);
+
 	if (!cast) {
 		return nullptr;
 	}
@@ -774,6 +782,7 @@ void onImGuiRender() {
 
 			ImGui::MenuItem("Control Panel", NULL, &_state->_w.controlPanel);
 			ImGui::MenuItem("Score", NULL, &_state->_w.score);
+			ImGui::MenuItem("Search", NULL, &_state->_w.search);
 			ImGui::MenuItem("Functions", NULL, &_state->_w.funcList);
 			ImGui::MenuItem("Cast", NULL, &_state->_w.cast);
 			ImGui::MenuItem("Channels", NULL, &_state->_w.channels);
@@ -810,6 +819,7 @@ void onImGuiRender() {
 	showCastDetails();
 	showFuncList();
 	showScore();
+	showSearchBar();
 	showBreakpointList();
 	showSettings();
 	showArchive();
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index 1bebbdc370b..8e3c303d24e 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -97,6 +97,7 @@ typedef struct ImGuiWindows {
 	bool archive = false;
 	bool watchedVars = false;
 	bool executionContext = false;
+	bool search = false;
 } ImGuiWindows;
 
 typedef struct ScriptData {
@@ -117,6 +118,12 @@ enum ThemeID {
 	kThemeCount
 };
 
+enum SearchMode {
+    kSearchAll = 0,
+    kSearchHandlerNames,
+    kSearchScriptBody,
+};
+
 struct DebuggerTheme {
 	ImU32 tableLightColor;
 	ImU32 tableDarkColor;
@@ -227,6 +234,12 @@ typedef struct ImGuiState {
 		uint _callstackSize = 0;
 	} _dbg;
 
+	struct {
+		char input[256] = {};
+		bool dirty = false;
+		int mode = kSearchAll;
+		Common::Array<ImGuiScript> results;
+	} _search;
 
 	struct {
 		DatumHash _locals;
@@ -345,6 +358,9 @@ void saveCurrentState();
 void loadSavedState();
 Common::Array<WindowFlag> getWindowFlags();
 
+// dt-search.cpp
+void showSearchBar();
+
 extern ImGuiState *_state;
 
 } // End of namespace DT
diff --git a/engines/director/debugger/dt-lists.cpp b/engines/director/debugger/dt-lists.cpp
index 7f312f0a59c..ccfbb798e87 100644
--- a/engines/director/debugger/dt-lists.cpp
+++ b/engines/director/debugger/dt-lists.cpp
@@ -127,38 +127,58 @@ void showVars() {
 }
 
 void showWatchedVars() {
-	if (!_state->_w.watchedVars)
-		return;
-
-	cacheVars();
-
-	ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
-	ImGui::SetNextWindowSize(ImVec2(300, 250), ImGuiCond_FirstUseEver);
-	if (ImGui::Begin("Watched Vars", &_state->_w.watchedVars)) {
-		int id = -1;
-		for (auto &v : _state->_variables) {
-			Datum name(v._key);
-			name.type = VARREF;
-			Datum val = g_lingo->varFetch(name, true);
-
-			bool outOfScope = false;
-			if (val.type == VOID) {
-				outOfScope = true;
-			}
-
-			id += 1;
-			ImGui::PushID(id);
-			displayVariable(v._key, false, outOfScope);
-			ImGui::PopID();
-
-			ImGui::SameLine();
-			ImGui::Text(" - [%s] %s", val.type2str(), formatStringForDump(val.asString(true)).c_str());
-		}
-
-		if (_state->_variables.empty())
-			ImGui::Text("(no watched variables)");
-	}
-	ImGui::End();
+    if (!_state->_w.watchedVars)
+        return;
+
+    cacheVars();
+
+    ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
+    ImGui::SetNextWindowSize(ImVec2(300, 250), ImGuiCond_FirstUseEver);
+    if (ImGui::Begin("Watched Vars", &_state->_w.watchedVars)) {
+        int id = -1;
+        for (auto &v : _state->_variables) {
+            Datum name(v._key);
+            name.type = VARREF;
+            Datum val = g_lingo->varFetch(name, true);
+
+            bool outOfScope = (val.type == VOID);
+
+            id += 1;
+            ImGui::PushID(id);
+            displayVariable(v._key, false, outOfScope);
+            ImGui::PopID();
+
+            ImGui::SameLine();
+            ImGui::Text(" - [%s] %s", val.type2str(), formatStringForDump(val.asString(true)).c_str());
+        }
+
+        if (_state->_variables.empty())
+            ImGui::Text("(no watched variables)");
+
+        ImGui::Separator();
+        if (ImGui::CollapsingHeader("Write Log")) {
+            if (ImGui::BeginChild("##watchlog", ImVec2(0, 150), true)) {
+                for (int i = (int)_state->_watchLog.size() - 1; i >= 0; i--) {
+                    ImGuiState::WatchLogEntry &entry = _state->_watchLog[i];
+                    ImGui::TextColored(
+                        ImVec4(1.0f, 0.4f, 0.4f, 1.0f),
+                        "write '%s': %s  [%s]",
+                        entry.varName.c_str(),
+                        entry.value.c_str(),
+                        entry.scriptRef.c_str()
+                    );
+                }
+
+                if (_state->_watchLog.empty())
+                    ImGui::Text("(no writes logged)");
+            }
+            ImGui::EndChild();
+
+            if (ImGui::Button("Clear Log"))
+                _state->_watchLog.clear();
+        }
+    }
+    ImGui::End();
 }
 
 // Make the UI compact because there are so many fields
diff --git a/engines/director/debugger/dt-search.cpp b/engines/director/debugger/dt-search.cpp
new file mode 100644
index 00000000000..ad766a7d5f5
--- /dev/null
+++ b/engines/director/debugger/dt-search.cpp
@@ -0,0 +1,189 @@
+#include "backends/imgui/IconsMaterialSymbols.h"
+
+#include "graphics/macgui/mactext.h"
+
+#include "image/png.h"
+
+#include "common/debug.h"
+
+#include "director/director.h"
+#include "director/lingo/lingodec/context.h"
+#include "director/lingo/lingodec/script.h"
+#include "director/cast.h"
+#include "director/castmember/bitmap.h"
+#include "director/castmember/shape.h"
+#include "director/castmember/text.h"
+#include "director/debugger.h"
+#include "director/movie.h"
+#include "director/window.h"
+#include "director/score.h"
+#include "director/channel.h"
+#include "director/picture.h"
+
+#include "director/debugger/debugtools.h"
+#include "director/debugger/dt-internal.h"
+
+namespace Director {
+namespace DT {
+
+static const char *searchModeNames[] = {
+	"All",
+	"Handler Names",
+	"Script Body",
+};
+
+static void searchCast(Cast *cast, int castLibID, const Common::String &query, Director::Lingo *lingo, Movie *movie, SearchMode mode) {
+	if (!cast) return;
+	if (!cast->_lingoArchive) return;
+
+	for (int i = 0; i <= kMaxScriptType; i++) {
+		if (cast->_lingoArchive->scriptContexts[i].empty())
+			continue;
+
+		for (auto &scriptContext : cast->_lingoArchive->scriptContexts[i]) {
+			for (auto &functionHandler : scriptContext._value->_functionHandlers) {
+				bool found = false;
+
+				// Search handler name
+				if (mode == kSearchAll || mode == kSearchHandlerNames) {
+					Common::String handlerLower = functionHandler._key;
+					handlerLower.toLowercase();
+					if (handlerLower.contains(query.c_str()))
+						found = true;
+
+					// Search property and global names
+					if (!found) {
+						CastMemberID memberID(scriptContext._key, castLibID);
+						ImGuiScript script = toImGuiScript(scriptContext._value->_scriptType, memberID, functionHandler._key);
+						for (auto &name : script.propertyNames) {
+							Common::String n = name;
+							n.toLowercase();
+							if (n.contains(query.c_str())) { found = true; break; }
+						}
+						if (!found) {
+							for (auto &name : script.globalNames) {
+								Common::String n = name;
+								n.toLowercase();
+								if (n.contains(query.c_str())) { found = true; break; }
+							}
+						}
+					}
+				}
+
+				// Search script body via decodeInstruction
+				if (!found && lingo && (mode == kSearchAll || mode == kSearchScriptBody)) {
+					Symbol &sym = functionHandler._value;
+					if (sym.type == HANDLER && sym.u.defn) {
+						uint pc = 0;
+						while (pc < sym.u.defn->size()) {
+							Common::String line = lingo->decodeInstruction(sym.u.defn, pc, &pc);
+							line.toLowercase();
+							if (line.contains(query.c_str())) {
+								found = true;
+								break;
+							}
+						}
+					}
+				}
+
+				if (found) {
+					CastMemberID memberID(scriptContext._key, castLibID);
+					ImGuiScript script = toImGuiScript(scriptContext._value->_scriptType, memberID, functionHandler._key);
+					script.byteOffsets = scriptContext._value->_functionByteOffsets[script.handlerId];
+					script.moviePath = movie->getArchive()->getPathName().toString();
+					Common::String handlerName;
+					if (functionHandler._value.ctx && functionHandler._value.ctx->_id)
+						handlerName = Common::String::format("%d:", functionHandler._value.ctx->_id);
+					handlerName += g_lingo->formatFunctionName(functionHandler._value);
+					script.handlerName = handlerName;
+					_state->_search.results.push_back(script);
+				}
+			}
+		}
+	}
+}
+
+static void runSearch(const Common::String &query, SearchMode mode) {
+	_state->_search.results.clear();
+
+	Movie *movie = g_director->getCurrentMovie();
+	if (!movie)
+		return;
+
+	Director::Lingo *lingo = g_director->getLingo();
+
+	for (auto it : *movie->getCasts())
+		searchCast(it._value, it._key, query, lingo, movie, mode);
+	searchCast(movie->getSharedCast(), SHARED_CAST_LIB, query, lingo, movie, mode);
+}
+
+void showSearchBar() {
+	if (!_state->_w.search)
+		return;
+
+	Movie *movie = g_director->getCurrentMovie();
+	if (!movie)
+		return;
+
+	auto &search = _state->_search;
+
+	ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
+	ImGui::SetNextWindowSize(ImVec2(480, 240), ImGuiCond_FirstUseEver);
+
+	if (!ImGui::Begin("Search", &_state->_w.search)) {
+		ImGui::End();
+		return;
+	}
+
+	ImGui::SetNextItemWidth(120);
+	if (ImGui::Combo("##searchmode", &search.mode, searchModeNames, ARRAYSIZE(searchModeNames)))
+		search.dirty = true;
+
+	ImGui::SameLine();
+	ImGui::SetNextItemWidth(-80);
+	if (ImGui::InputText("##search", search.input, sizeof(search.input),
+			ImGuiInputTextFlags_EnterReturnsTrue))
+		search.dirty = true;
+
+	ImGui::SameLine();
+	if (ImGui::Button("Search"))
+		search.dirty = true;
+
+	if (search.dirty) {
+		search.dirty = false;
+		Common::String query(search.input);
+		query.toLowercase();
+		if (!query.empty())
+			runSearch(query, (SearchMode)search.mode);
+	}
+
+	// display results
+	ImGui::Separator();
+	ImGui::Text("Results: %d", (int)search.results.size());
+	ImGui::Separator();
+
+	if (ImGui::BeginTable("##results", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg)) {
+		ImGui::TableSetupColumn("Handler", 0, 240.f);
+		ImGui::TableSetupColumn("Cast", ImGuiTableColumnFlags_WidthStretch, 240.f);
+		ImGui::TableHeadersRow();
+
+		for (int i = 0; i < (int)search.results.size(); i++) {
+			auto &script = search.results[i];
+			ImGui::PushID(i);
+			ImGui::TableNextRow();
+			ImGui::TableNextColumn();
+			if (ImGui::Selectable(script.handlerName.c_str()))
+				addToOpenHandlers(script);
+			ImGui::TableNextColumn();
+			ImGui::Text("%s", script.id.asString().c_str());
+			ImGui::PopID();
+		}
+		ImGui::EndTable();
+	}
+
+	ImGui::End();
+}
+
+
+}
+}
diff --git a/engines/director/module.mk b/engines/director/module.mk
index b4a6616d2c4..bc922d454c7 100644
--- a/engines/director/module.mk
+++ b/engines/director/module.mk
@@ -217,7 +217,8 @@ MODULE_OBJS += \
 	debugger/dt-score.o \
 	debugger/dt-script-d2.o \
 	debugger/dt-script-d4.o \
-	debugger/dt-scripts.o
+	debugger/dt-scripts.o \
+	debugger/dt-search.o
 
 endif
 


Commit: 46a3c097016f82f892a03437fd86ba226f05e79b
    https://github.com/scummvm/scummvm/commit/46a3c097016f82f892a03437fd86ba226f05e79b
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-03-12T02:51:42+01:00

Commit Message:
JANITORIAL: Add correct indentation

Changed paths:
    engines/director/debugger.cpp
    engines/director/debugger/debugtools.cpp
    engines/director/debugger/dt-internal.h
    engines/director/debugger/dt-lists.cpp


diff --git a/engines/director/debugger.cpp b/engines/director/debugger.cpp
index e6d2aeb0df1..ffdcec94a30 100644
--- a/engines/director/debugger.cpp
+++ b/engines/director/debugger.cpp
@@ -1373,56 +1373,56 @@ void Debugger::varReadHook(const Common::String &name) {
 }
 
 void Debugger::varWriteHook(const Common::String &name) {
-    if (name.empty())
-        return;
-    if (_bpCheckVarWrite) {
-        for (auto &it : g_lingo->getBreakpoints()) {
-            if (it.type == kBreakpointVariable && it.varWrite && it.varName.equalsIgnoreCase(name)) {
-                debugPrintf("Hit a breakpoint:\n");
-                debugPrintf("%s\n", it.format().c_str());
-                cmdScriptFrame(0, nullptr);
-                attach();
-                g_system->updateScreen();
-                break;
-            }
-        }
-    }
+	if (name.empty())
+		return;
+	if (_bpCheckVarWrite) {
+		for (auto &it : g_lingo->getBreakpoints()) {
+			if (it.type == kBreakpointVariable && it.varWrite && it.varName.equalsIgnoreCase(name)) {
+				debugPrintf("Hit a breakpoint:\n");
+				debugPrintf("%s\n", it.format().c_str());
+				cmdScriptFrame(0, nullptr);
+				attach();
+				g_system->updateScreen();
+				break;
+			}
+		}
+	}
 
 #ifdef USE_IMGUI
-    if (!DT::_state || !DT::_state->_variables.contains(name))
-        return;
-
-    DT::ImGuiState::WatchLogEntry entry;
-    entry.varName = name;
-
-    entry.value = "(unknown)";
-    if (g_lingo->_state->localVars && g_lingo->_state->localVars->contains(name))
-        entry.value = formatStringForDump(g_lingo->_state->localVars->getVal(name).asString(true));
-    else if (g_lingo->_globalvars.contains(name))
-        entry.value = formatStringForDump(g_lingo->_globalvars.getVal(name).asString(true));
-
-    entry.scriptRef = "(unknown)";
-    if (!g_lingo->_state->callstack.empty()) {
-        CFrame *head = g_lingo->_state->callstack.back();
-        if (head && head->sp.ctx && head->sp.name) {
-            entry.scriptRef = DT::formatHandlerName(
-                head->sp.ctx->_scriptId,
-                head->sp.ctx->_id,
-                *head->sp.name,
-                head->sp.ctx->_scriptType,
-                false
-            );
-        }
-    }
-
-    DT::_state->_watchLog.push_back(entry);
-    if (DT::_state->_watchLog.size() > 100)
-        DT::_state->_watchLog.remove_at(0);
-
-    debug("Var write: '%s' = %s  [%s]",
-        entry.varName.c_str(),
-        entry.value.c_str(),
-        entry.scriptRef.c_str());
+	if (!DT::_state || !DT::_state->_variables.contains(name))
+		return;
+
+	DT::ImGuiState::WatchLogEntry entry;
+	entry.varName = name;
+
+	entry.value = "(unknown)";
+	if (g_lingo->_state->localVars && g_lingo->_state->localVars->contains(name))
+		entry.value = formatStringForDump(g_lingo->_state->localVars->getVal(name).asString(true));
+	else if (g_lingo->_globalvars.contains(name))
+		entry.value = formatStringForDump(g_lingo->_globalvars.getVal(name).asString(true));
+
+	entry.scriptRef = "(unknown)";
+	if (!g_lingo->_state->callstack.empty()) {
+		CFrame *head = g_lingo->_state->callstack.back();
+		if (head && head->sp.ctx && head->sp.name) {
+			entry.scriptRef = DT::formatHandlerName(
+				head->sp.ctx->_scriptId,
+				head->sp.ctx->_id,
+				*head->sp.name,
+				head->sp.ctx->_scriptType,
+				false
+			);
+		}
+	}
+
+	DT::_state->_watchLog.push_back(entry);
+	if (DT::_state->_watchLog.size() > 100)
+		DT::_state->_watchLog.remove_at(0);
+
+	debug("Var write: '%s' = %s  [%s]",
+		entry.varName.c_str(),
+		entry.value.c_str(),
+		entry.scriptRef.c_str());
 #endif
 }
 
diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index 4856407ff1f..4a3f40c2eb7 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -80,7 +80,7 @@ const LingoDec::Handler *getHandler(const Cast *cast, CastMemberID id, const Com
 const LingoDec::Handler *getHandler(CastMemberID id, const Common::String &handlerId) {
 	const Director::Movie *movie = g_director->getCurrentMovie();
 	if (id.castLib == SHARED_CAST_LIB)
-        return getHandler(movie->getSharedCast(), id, handlerId);
+		return getHandler(movie->getSharedCast(), id, handlerId);
 
 	const Cast *cast = movie->getCasts()->getVal(id.castLib);
 
@@ -515,7 +515,7 @@ static const DebuggerTheme themes[kThemeCount] = {
 		IM_COL32(0xB4, 0x32, 0x32, 0xC8), // channel_hide_bg
 		IM_COL32(0x94, 0x00, 0xD3, 0xFF), // channelSelectedCol
 		IM_COL32(0xFF, 0xFF, 0x00, 0x3C), // channelHoveredCol
-		{                                 // contColors
+		{								 // contColors
 			IM_COL32(0xCE, 0xCE, 0xFF, 0x80),
 			IM_COL32(0xFF, 0xFF, 0xCE, 0x80),
 			IM_COL32(0xCE, 0xFF, 0xCE, 0x80),
@@ -573,7 +573,7 @@ static const DebuggerTheme themes[kThemeCount] = {
 		IM_COL32(0xDC, 0x3C, 0x3C, 0xC8), // channel_hide_bg
 		IM_COL32(0x94, 0x00, 0xD3, 0xFF), // channelSelectedCol
 		IM_COL32(0xD0, 0x90, 0x00, 0x50), // channelHoveredCol
-		{                                 // contColors
+		{								 // contColors
 			IM_COL32(0xCE, 0xCE, 0xFF, 0x80),
 			IM_COL32(0xFF, 0xFF, 0xCE, 0x80),
 			IM_COL32(0xCE, 0xFF, 0xCE, 0x80),
@@ -602,21 +602,21 @@ static const DebuggerTheme themes[kThemeCount] = {
 		ImVec4(0.80f, 0.00f, 0.00f, 1.0f), // var_ref_changed
 		ImVec4(0.60f, 0.00f, 0.60f, 1.0f), // var_ref_out_of_scope
 
-		ImVec4(0.1f, 0.1f, 0.1f, 1.0f),    // cp_color
-		ImVec4(0.8f, 0.0f, 0.0f, 1.0f),    // cp_color_red
-		ImVec4(0.8f, 0.4f, 0.0f, 1.0f),    // cp_active_color
-		ImVec4(0.7f, 0.8f, 1.0f, 0.5f),    // cp_bgcolor
-		ImVec4(0.0f, 0.0f, 0.8f, 1.0f),    // cp_playing_color
+		ImVec4(0.1f, 0.1f, 0.1f, 1.0f),	// cp_color
+		ImVec4(0.8f, 0.0f, 0.0f, 1.0f),	// cp_color_red
+		ImVec4(0.8f, 0.4f, 0.0f, 1.0f),	// cp_active_color
+		ImVec4(0.7f, 0.8f, 1.0f, 0.5f),	// cp_bgcolor
+		ImVec4(0.0f, 0.0f, 0.8f, 1.0f),	// cp_playing_color
 		ImVec4(0.55f, 0.42f, 0.05f, 1.0f), // cp_path_color
 
-		ImVec4(0.8f, 0.0f, 0.0f, 1.0f),    // logger_error_b
-		ImVec4(0.8f, 0.4f, 0.0f, 1.0f),    // logger_warning_b
-		ImVec4(0.1f, 0.1f, 0.1f, 1.0f),    // logger_info_b
-		ImVec4(0.4f, 0.4f, 0.4f, 1.0f),    // logger_debug_b
-		ImVec4(0.7f, 0.0f, 0.0f, 1.0f),    // logger_error
-		ImVec4(0.7f, 0.4f, 0.0f, 1.0f),    // logger_warning
+		ImVec4(0.8f, 0.0f, 0.0f, 1.0f),	// logger_error_b
+		ImVec4(0.8f, 0.4f, 0.0f, 1.0f),	// logger_warning_b
+		ImVec4(0.1f, 0.1f, 0.1f, 1.0f),	// logger_info_b
+		ImVec4(0.4f, 0.4f, 0.4f, 1.0f),	// logger_debug_b
+		ImVec4(0.7f, 0.0f, 0.0f, 1.0f),	// logger_error
+		ImVec4(0.7f, 0.4f, 0.0f, 1.0f),	// logger_warning
 		ImVec4(0.15f, 0.15f, 0.15f, 1.0f), // logger_info
-		ImVec4(0.4f, 0.4f, 0.4f, 1.0f)     // logger_debug
+		ImVec4(0.4f, 0.4f, 0.4f, 1.0f)	 // logger_debug
 	}
 };
 
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index 8e3c303d24e..53732bb47f9 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -119,9 +119,9 @@ enum ThemeID {
 };
 
 enum SearchMode {
-    kSearchAll = 0,
-    kSearchHandlerNames,
-    kSearchScriptBody,
+	kSearchAll = 0,
+	kSearchHandlerNames,
+	kSearchScriptBody,
 };
 
 struct DebuggerTheme {
diff --git a/engines/director/debugger/dt-lists.cpp b/engines/director/debugger/dt-lists.cpp
index ccfbb798e87..f6eb6018138 100644
--- a/engines/director/debugger/dt-lists.cpp
+++ b/engines/director/debugger/dt-lists.cpp
@@ -127,58 +127,58 @@ void showVars() {
 }
 
 void showWatchedVars() {
-    if (!_state->_w.watchedVars)
-        return;
-
-    cacheVars();
-
-    ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
-    ImGui::SetNextWindowSize(ImVec2(300, 250), ImGuiCond_FirstUseEver);
-    if (ImGui::Begin("Watched Vars", &_state->_w.watchedVars)) {
-        int id = -1;
-        for (auto &v : _state->_variables) {
-            Datum name(v._key);
-            name.type = VARREF;
-            Datum val = g_lingo->varFetch(name, true);
-
-            bool outOfScope = (val.type == VOID);
-
-            id += 1;
-            ImGui::PushID(id);
-            displayVariable(v._key, false, outOfScope);
-            ImGui::PopID();
-
-            ImGui::SameLine();
-            ImGui::Text(" - [%s] %s", val.type2str(), formatStringForDump(val.asString(true)).c_str());
-        }
-
-        if (_state->_variables.empty())
-            ImGui::Text("(no watched variables)");
-
-        ImGui::Separator();
-        if (ImGui::CollapsingHeader("Write Log")) {
-            if (ImGui::BeginChild("##watchlog", ImVec2(0, 150), true)) {
-                for (int i = (int)_state->_watchLog.size() - 1; i >= 0; i--) {
-                    ImGuiState::WatchLogEntry &entry = _state->_watchLog[i];
-                    ImGui::TextColored(
-                        ImVec4(1.0f, 0.4f, 0.4f, 1.0f),
-                        "write '%s': %s  [%s]",
-                        entry.varName.c_str(),
-                        entry.value.c_str(),
-                        entry.scriptRef.c_str()
-                    );
-                }
-
-                if (_state->_watchLog.empty())
-                    ImGui::Text("(no writes logged)");
-            }
-            ImGui::EndChild();
-
-            if (ImGui::Button("Clear Log"))
-                _state->_watchLog.clear();
-        }
-    }
-    ImGui::End();
+	if (!_state->_w.watchedVars)
+		return;
+
+	cacheVars();
+
+	ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
+	ImGui::SetNextWindowSize(ImVec2(300, 250), ImGuiCond_FirstUseEver);
+	if (ImGui::Begin("Watched Vars", &_state->_w.watchedVars)) {
+		int id = -1;
+		for (auto &v : _state->_variables) {
+			Datum name(v._key);
+			name.type = VARREF;
+			Datum val = g_lingo->varFetch(name, true);
+
+			bool outOfScope = (val.type == VOID);
+
+			id += 1;
+			ImGui::PushID(id);
+			displayVariable(v._key, false, outOfScope);
+			ImGui::PopID();
+
+			ImGui::SameLine();
+			ImGui::Text(" - [%s] %s", val.type2str(), formatStringForDump(val.asString(true)).c_str());
+		}
+
+		if (_state->_variables.empty())
+			ImGui::Text("(no watched variables)");
+
+		ImGui::Separator();
+		if (ImGui::CollapsingHeader("Write Log")) {
+			if (ImGui::BeginChild("##watchlog", ImVec2(0, 150), true)) {
+				for (int i = (int)_state->_watchLog.size() - 1; i >= 0; i--) {
+					ImGuiState::WatchLogEntry &entry = _state->_watchLog[i];
+					ImGui::TextColored(
+						ImVec4(1.0f, 0.4f, 0.4f, 1.0f),
+						"write '%s': %s  [%s]",
+						entry.varName.c_str(),
+						entry.value.c_str(),
+						entry.scriptRef.c_str()
+					);
+				}
+
+				if (_state->_watchLog.empty())
+					ImGui::Text("(no writes logged)");
+			}
+			ImGui::EndChild();
+
+			if (ImGui::Button("Clear Log"))
+				_state->_watchLog.clear();
+		}
+	}
+	ImGui::End();
 }
 
 // Make the UI compact because there are so many fields


Commit: 7bb2f03d8ffca315826dfd9d1ad18e7abd554d08
    https://github.com/scummvm/scummvm/commit/7bb2f03d8ffca315826dfd9d1ad18e7abd554d08
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-03-12T02:51:42+01:00

Commit Message:
DIRECTOR: DT: Add minor changes to search

Changed paths:
    engines/director/debugger/debugtools.cpp
    engines/director/debugger/dt-internal.h
    engines/director/debugger/dt-score.cpp
    engines/director/debugger/dt-script-d2.cpp
    engines/director/debugger/dt-script-d4.cpp
    engines/director/debugger/dt-scripts.cpp
    engines/director/debugger/dt-search.cpp


diff --git a/engines/director/debugger/debugtools.cpp b/engines/director/debugger/debugtools.cpp
index 4a3f40c2eb7..f64822a6aac 100644
--- a/engines/director/debugger/debugtools.cpp
+++ b/engines/director/debugger/debugtools.cpp
@@ -160,6 +160,105 @@ ScriptContext *getScriptContext(uint32 nameIndex, CastMemberID id, Common::Strin
 	return nullptr;
 }
 
+static ScriptContext *findHandlerContext(Cast *cast, const Common::String &handlerName) {
+	if (!cast || !cast->_lingoArchive)
+		return nullptr;
+
+	for (int i = 0; i <= kMaxScriptType; i++) {
+		if (cast->_lingoArchive->scriptContexts[i].empty())
+			continue;
+		for (auto &scriptContext : cast->_lingoArchive->scriptContexts[i]) {
+			if (scriptContext._value && scriptContext._value->_functionHandlers.contains(handlerName))
+				return scriptContext._value;
+		}
+	}
+	return nullptr;
+}
+
+ScriptContext *resolveHandlerContext(int32 nameIndex, const CastMemberID &refId, const Common::String &handlerName) {
+	Movie *movie = g_director->getCurrentMovie();
+	if (!movie)
+		return nullptr;
+
+	Cast *cast = nullptr;
+	if (refId.castLib == SHARED_CAST_LIB) {
+		cast = movie->getSharedCast();
+	} else {
+		cast = movie->getCasts()->getVal(refId.castLib);
+	}
+
+	if (cast && cast->_lingoArchive && nameIndex >= 0 && (uint32)nameIndex < cast->_lingoArchive->names.size()) {
+		if (cast->_lingoArchive->names[nameIndex] != handlerName) {
+			ScriptContext *local = cast->_lingoArchive->findScriptContext(refId.member);
+			if (local && local->_functionHandlers.contains(handlerName))
+				return local;
+		}
+	}
+
+	if (ScriptContext *ctx = findHandlerContext(cast, handlerName))
+		return ctx;
+
+	Cast *shared = movie->getSharedCast();
+	if (shared && shared != cast) {
+		if (ScriptContext *ctx = findHandlerContext(shared, handlerName))
+			return ctx;
+	}
+
+	return nullptr;
+}
+
+ImGuiScript buildImGuiHandlerScript(ScriptContext *ctx, int castLibID, const Common::String &handlerName, const Common::String &moviePath) {
+	ImGuiScript script;
+	if (!ctx)
+		return script;
+
+	Movie *movie = g_director->getCurrentMovie();
+	Cast *cast = nullptr;
+	if (castLibID == SHARED_CAST_LIB) {
+		cast = movie ? movie->getSharedCast() : nullptr;
+	} else {
+		cast = movie ? movie->getCasts()->getVal(castLibID) : nullptr;
+	}
+
+	int castId = ctx->_id;
+	bool childScript = false;
+	if (castId == -1) {
+		childScript = true;
+		if (cast) {
+			castId = cast->getCastIdByScriptId(ctx->_parentNumber);
+		}
+	}
+
+	CastMemberID memberID(castId, castLibID);
+	script = toImGuiScript(ctx->_scriptType, memberID, handlerName);
+	script.byteOffsets = ctx->_functionByteOffsets[script.handlerId];
+	script.moviePath = moviePath;
+	script.handlerName = formatHandlerName(ctx->_scriptId, castId, script.handlerId, ctx->_scriptType, childScript);
+	return script;
+}
+
+void maybeHighlightLastItem(const Common::String &text) {
+	if (!_state)
+		return;
+	const Common::String &q = _state->_dbg._highlightQuery;
+	if (q.empty() || text.empty() || _state->_dbg._suppressHighlight)
+		return;
+
+	Common::String lower = text;
+	lower.toLowercase();
+	if (!lower.contains(q.c_str()))
+		return;
+
+	ImDrawList *dl = ImGui::GetWindowDrawList();
+	const ImVec2 min = ImGui::GetItemRectMin();
+	const ImVec2 max = ImGui::GetItemRectMax();
+	if (max.x <= min.x || max.y <= min.y)
+		return;
+
+	ImU32 col = IM_COL32(255, 230, 0, 90);
+	dl->AddRectFilled(min, max, col, 2.0f);
+}
+
 Director::Breakpoint *getBreakpoint(const Common::String &handlerName, uint16 scriptId, uint pc) {
 	auto &bps = g_lingo->getBreakpoints();
 	for (uint i = 0; i < bps.size(); i++) {
diff --git a/engines/director/debugger/dt-internal.h b/engines/director/debugger/dt-internal.h
index 53732bb47f9..1f008597947 100644
--- a/engines/director/debugger/dt-internal.h
+++ b/engines/director/debugger/dt-internal.h
@@ -100,6 +100,13 @@ typedef struct ImGuiWindows {
 	bool search = false;
 } ImGuiWindows;
 
+
+enum SearchMode {
+	kSearchAll = 0,
+	kSearchHandlerNames,
+	kSearchScriptBody,
+};
+
 typedef struct ScriptData {
 	Common::Array<ImGuiScript> _scripts;
 	uint _current = 0;
@@ -118,12 +125,6 @@ enum ThemeID {
 	kThemeCount
 };
 
-enum SearchMode {
-	kSearchAll = 0,
-	kSearchHandlerNames,
-	kSearchScriptBody,
-};
-
 struct DebuggerTheme {
 	ImU32 tableLightColor;
 	ImU32 tableDarkColor;
@@ -186,7 +187,6 @@ typedef struct ImGuiState {
 		Common::String varName;
 		Common::String value;
 		Common::String scriptRef;
-		bool isWrite;
 	};
 
 	struct ScoreConfig {
@@ -232,6 +232,8 @@ typedef struct ImGuiState {
 		bool _scrollToPC = false;
 		uint _lastLinePC = 0;
 		uint _callstackSize = 0;
+		Common::String _highlightQuery; // lowercased, empty disables highlight
+		bool _suppressHighlight = false; // used to disable highlighting in Execution Context
 	} _dbg;
 
 	struct {
@@ -313,6 +315,9 @@ typedef struct ImGuiState {
 ImGuiScript toImGuiScript(ScriptType scriptType, CastMemberID id, const Common::String &handlerId);
 ScriptContext *getScriptContext(CastMemberID id);
 ScriptContext *getScriptContext(uint32 nameIndex, CastMemberID castId, Common::String handler);
+ScriptContext *resolveHandlerContext(int32 nameIndex, const CastMemberID &refId, const Common::String &handlerName);
+ImGuiScript buildImGuiHandlerScript(ScriptContext *ctx, int castLibID, const Common::String &handlerName, const Common::String &moviePath);
+void maybeHighlightLastItem(const Common::String &text);
 void addToOpenHandlers(ImGuiScript handler);
 void setScriptToDisplay(const ImGuiScript &script);
 Director::Breakpoint *getBreakpoint(const Common::String &handlerName, uint16 scriptId, uint pc);
diff --git a/engines/director/debugger/dt-score.cpp b/engines/director/debugger/dt-score.cpp
index 056d45f4cc9..3e0901fefc4 100644
--- a/engines/director/debugger/dt-score.cpp
+++ b/engines/director/debugger/dt-score.cpp
@@ -396,7 +396,7 @@ static void drawSpriteInspector(Score *score, Cast *cast, uint numFrames) {
 		CastMember *castMember = nullptr;
 		bool shape = false;
 
-		if (_state->_selectedScoreCast.frame != -1)
+		if (_state->_selectedScoreCast.frame != -1 && !_state->_selectedScoreCast.isMainChannel)
 			sprite = score->_scoreCache[_state->_selectedScoreCast.frame]->_sprites[_state->_selectedScoreCast.channel];
 
 		if (sprite) {
@@ -970,8 +970,14 @@ static void drawMainChannelGrid(ImDrawList *dl, ImVec2 startPos, Score *score) {
 					break;
 				case kChScript: // open script in script editor
 					if (mc.actionId.member) {
-						ImGuiScript script = toImGuiScript(kScoreScript, mc.actionId, "");
-						addToOpenHandlers(script);
+						ScriptContext *ctx = getScriptContext(mc.actionId);
+						for (auto &handler : ctx->_functionHandlers) {
+							ImGuiScript script = toImGuiScript(kScoreScript, mc.actionId, handler._key);
+							script.byteOffsets = ctx->_functionByteOffsets[script.handlerId];
+							script.moviePath = g_director->getCurrentMovie()->getArchive()->getPathName().toString();
+							script.handlerName = formatHandlerName(ctx->_scriptId, mc.actionId.member, handler._key, kScoreScript, false);
+							addToOpenHandlers(script);
+						}
 					}
 					break;
 				}
diff --git a/engines/director/debugger/dt-script-d2.cpp b/engines/director/debugger/dt-script-d2.cpp
index 350af024e27..2e07fb5c042 100644
--- a/engines/director/debugger/dt-script-d2.cpp
+++ b/engines/director/debugger/dt-script-d2.cpp
@@ -489,9 +489,10 @@ public:
 	}
 
 	virtual bool visitFuncNode(FuncNode *node) {
-		const bool isBuiltin = g_lingo->_builtinCmds.contains(*node->name);
+		const bool isBuiltin = g_lingo->_builtinCmds.contains(*node->name) || g_lingo->_builtinFuncs.contains(*node->name);
 		const ImVec4 color = (ImVec4)ImColor(isBuiltin ? _state->theme->builtin_color : _state->theme->call_color);
 		ImGui::TextColored(color, "%s(", node->name->c_str());
+		maybeHighlightLastItem(*node->name);
 		if (!isBuiltin && ImGui::IsItemHovered() && ImGui::BeginTooltip()) {
 			ImGui::Text("Go to definition");
 			ImGui::EndTooltip();
@@ -505,21 +506,9 @@ public:
 				}
 			}
 
-			ScriptContext *context = getScriptContext(obj, _script.id, *node->name);
+			ScriptContext *context = resolveHandlerContext(obj, _script.id, *node->name);
 			if (context) {
-				ImGuiScript script = toImGuiScript(_script.type, CastMemberID(context->_id, _script.id.castLib), *node->name);
-				const Director::Movie *movie = g_director->getCurrentMovie();
-
-				int castId = context->_id;
-				bool childScript = false;
-				if (castId == -1) {
-					castId = movie->getCast()->getCastIdByScriptId(context->_parentNumber);
-					childScript = true;
-				}
-				script.byteOffsets = context->_functionByteOffsets[script.handlerId];
-				script.moviePath = _script.moviePath;
-
-				script.handlerName = formatHandlerName(context->_scriptId, castId, script.handlerId, context->_scriptType, childScript);
+				ImGuiScript script = buildImGuiHandlerScript(context, _script.id.castLib, *node->name, _script.moviePath);
 				setScriptToDisplay(script);
 				_state->_dbg._goToDefinition = true;
 			}
@@ -871,7 +860,7 @@ private:
 };
 
 void renderOldScriptAST(ImGuiScript &script, bool showByteCode, bool scrollTo) {
-    RenderOldScriptVisitor oldVisitor(script, scrollTo);
+	RenderOldScriptVisitor oldVisitor(script, scrollTo);
 	script.oldAst->accept(&oldVisitor);
 }
 
diff --git a/engines/director/debugger/dt-script-d4.cpp b/engines/director/debugger/dt-script-d4.cpp
index 7f74b91508a..5d7cc2d1627 100644
--- a/engines/director/debugger/dt-script-d4.cpp
+++ b/engines/director/debugger/dt-script-d4.cpp
@@ -103,14 +103,17 @@ public:
 			renderIndentation();
 		}
 
-		const ImVec4 color = (ImVec4)ImColor(g_lingo->_builtinCmds.contains(node.name) ? _state->theme->builtin_color : _state->theme->call_color);
+		bool builtIn = g_lingo->_builtinCmds.contains(node.name) || g_lingo->_builtinFuncs.contains(node.name);
+
+		const ImVec4 color = (ImVec4)ImColor( builtIn ? _state->theme->builtin_color : _state->theme->call_color);
 		ImGui::TextColored(color, "%s", node.name.c_str());
+		maybeHighlightLastItem(node.name);
 		// TODO: we should test Director::builtins too (but inaccessible)
-		if (!g_lingo->_builtinFuncs.contains(node.name) && ImGui::IsItemHovered() && ImGui::BeginTooltip()) {
+		if (!builtIn && ImGui::IsItemHovered() && ImGui::BeginTooltip()) {
 			ImGui::Text("Go to definition");
 			ImGui::EndTooltip();
 		}
-		if (!g_lingo->_builtinFuncs.contains(node.name) && ImGui::IsItemClicked()) {
+		if (!builtIn && ImGui::IsItemClicked()) {
 			int32 obj = 0;
 			for (uint i = 0; i < _script.bytecodeArray.size(); i++) {
 				if (node._startOffset == _script.bytecodeArray[i].pos) {
@@ -120,22 +123,9 @@ public:
 					break;
 				}
 			}
-			ScriptContext *context = getScriptContext(obj, _script.id, node.name);
-
+			ScriptContext *context = resolveHandlerContext(obj, _script.id, node.name);
 			if (context) {
-				ImGuiScript script = toImGuiScript(_script.type, CastMemberID(context->_id, _script.id.castLib), node.name);
-				const Director::Movie *movie = g_director->getCurrentMovie();
-
-				script.byteOffsets = context->_functionByteOffsets[script.handlerId];
-				script.moviePath = _script.moviePath;
-				int castId = context->_id;
-				bool childScript = false;
-				if (castId == -1) {
-					castId = movie->getCast()->getCastIdByScriptId(context->_parentNumber);
-					childScript = true;
-				}
-
-				script.handlerName = formatHandlerName(context->_scriptId, castId, script.handlerId, context->_scriptType, childScript);
+				ImGuiScript script = buildImGuiHandlerScript(context, _script.id.castLib, node.name, _script.moviePath);
 				setScriptToDisplay(script);
 				_state->_dbg._goToDefinition = true;
 			}
@@ -852,6 +842,7 @@ public:
 			renderIndentation();
 		}
 		ImGui::Text("%s", code._str.c_str());
+		maybeHighlightLastItem(code._str);
 	}
 
 private:
@@ -1123,6 +1114,7 @@ private:
 		renderLine(offset);
 		renderIndentation();
 		ImGui::TextColored(color, "%s", code.c_str());
+		maybeHighlightLastItem(code);
 	}
 
 	void writeByteCode(uint32 offset, const Common::String &code) {
diff --git a/engines/director/debugger/dt-scripts.cpp b/engines/director/debugger/dt-scripts.cpp
index 0b3dc39c2ce..7c3ab1460eb 100644
--- a/engines/director/debugger/dt-scripts.cpp
+++ b/engines/director/debugger/dt-scripts.cpp
@@ -574,6 +574,10 @@ void showExecutionContext() {
 		updateCurrentScript();
 
 		if (scriptData->_showScript) {
+			// disable highlighting while rendering scripts in Execution Context
+			bool oldSuppress = _state->_dbg._suppressHighlight;
+			_state->_dbg._suppressHighlight = true;
+
 			ImGuiScript &current = scriptData->_scripts[scriptData->_current];
 
 			// Get all the handlers from the script
@@ -586,6 +590,7 @@ void showExecutionContext() {
 			ImGui::BeginDisabled(scriptData->_scripts.empty() || scriptData->_current == 0);
 			if (ImGui::Button(ICON_MS_ARROW_BACK)) {
 				scriptData->_current--;
+				_state->_dbg._goToDefinition = true;
 			}
 			ImGui::EndDisabled();
 			ImGui::SetItemTooltip("Backward");
@@ -594,6 +599,7 @@ void showExecutionContext() {
 			ImGui::BeginDisabled(scriptData->_current >= scriptData->_scripts.size() - 1);
 			if (ImGui::Button(ICON_MS_ARROW_FORWARD)) {
 				scriptData->_current++;
+				_state->_dbg._goToDefinition = true;
 			}
 			ImGui::EndDisabled();
 			ImGui::SetItemTooltip("Forward");
@@ -609,9 +615,11 @@ void showExecutionContext() {
 				for (uint i = 0; i < scriptData->_scripts.size(); i++) {
 					auto &script = scriptData->_scripts[i];
 					bool selected = i == scriptData->_current;
+					ImGui::PushID(i);
 					if (ImGui::Selectable(script.handlerName.c_str(), &selected)) {
 						scriptData->_current = i;
 					}
+					ImGui::PopID();
 				}
 				ImGui::EndCombo();
 			}
@@ -650,6 +658,7 @@ void showExecutionContext() {
 			scriptsRendered = true;
 
 			ImGui::EndChild();
+			_state->_dbg._suppressHighlight = oldSuppress;
 		}
 
 		ImGui::EndChild();
@@ -685,6 +694,8 @@ void showExecutionContext() {
 			updateCurrentScript();
 
 			if (scriptData->_showScript) {
+				bool oldSuppress = _state->_dbg._suppressHighlight;
+				_state->_dbg._suppressHighlight = true;
 				ImGuiScript &current = scriptData->_scripts[scriptData->_current];
 
 				// Get all the handlers from the script
@@ -766,6 +777,7 @@ void showExecutionContext() {
 
 				scriptsRendered = true;
 				ImGui::EndChild();
+				_state->_dbg._suppressHighlight = oldSuppress;
 			}
 
 			ImGui::EndChild();
diff --git a/engines/director/debugger/dt-search.cpp b/engines/director/debugger/dt-search.cpp
index ad766a7d5f5..ff5f6da5a91 100644
--- a/engines/director/debugger/dt-search.cpp
+++ b/engines/director/debugger/dt-search.cpp
@@ -1,3 +1,24 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
 #include "backends/imgui/IconsMaterialSymbols.h"
 
 #include "graphics/macgui/mactext.h"
@@ -88,9 +109,8 @@ static void searchCast(Cast *cast, int castLibID, const Common::String &query, D
 
 				if (found) {
 					CastMemberID memberID(scriptContext._key, castLibID);
-					ImGuiScript script = toImGuiScript(scriptContext._value->_scriptType, memberID, functionHandler._key);
-					script.byteOffsets = scriptContext._value->_functionByteOffsets[script.handlerId];
-					script.moviePath = movie->getArchive()->getPathName().toString();
+					const Common::String moviePath = movie->getArchive()->getPathName().toString();
+					ImGuiScript script = buildImGuiHandlerScript(scriptContext._value, castLibID, functionHandler._key, moviePath);
 					Common::String handlerName;
 					if (functionHandler._value.ctx && functionHandler._value.ctx->_id)
 						handlerName = Common::String::format("%d:", functionHandler._value.ctx->_id);
@@ -131,6 +151,7 @@ void showSearchBar() {
 	ImGui::SetNextWindowSize(ImVec2(480, 240), ImGuiCond_FirstUseEver);
 
 	if (!ImGui::Begin("Search", &_state->_w.search)) {
+		_state->_dbg._highlightQuery = "";
 		ImGui::End();
 		return;
 	}
@@ -172,8 +193,14 @@ void showSearchBar() {
 			ImGui::PushID(i);
 			ImGui::TableNextRow();
 			ImGui::TableNextColumn();
-			if (ImGui::Selectable(script.handlerName.c_str()))
+			if (ImGui::Selectable(script.handlerName.c_str())) {
+				Common::String q(search.input);
+				q.toLowercase();
+				_state->_dbg._highlightQuery = q;
+
 				addToOpenHandlers(script);
+				_state->_dbg._goToDefinition = true;
+			}
 			ImGui::TableNextColumn();
 			ImGui::Text("%s", script.id.asString().c_str());
 			ImGui::PopID();


Commit: 35a75d077b5eda6698f9d9b60dcb9926bd0d708c
    https://github.com/scummvm/scummvm/commit/35a75d077b5eda6698f9d9b60dcb9926bd0d708c
Author: ramyak-sharma (ramyaksharma1 at gmail.com)
Date: 2026-03-12T02:51:42+01:00

Commit Message:
DIRECTOR: DT: Remove unnecessary headers

Changed paths:
    engines/director/debugger/dt-search.cpp


diff --git a/engines/director/debugger/dt-search.cpp b/engines/director/debugger/dt-search.cpp
index ff5f6da5a91..51edf530b28 100644
--- a/engines/director/debugger/dt-search.cpp
+++ b/engines/director/debugger/dt-search.cpp
@@ -19,30 +19,12 @@
  *
  */
 
-#include "backends/imgui/IconsMaterialSymbols.h"
-
-#include "graphics/macgui/mactext.h"
-
-#include "image/png.h"
-
-#include "common/debug.h"
-
 #include "director/director.h"
-#include "director/lingo/lingodec/context.h"
-#include "director/lingo/lingodec/script.h"
+#include "director/debugger/dt-internal.h"
+
 #include "director/cast.h"
-#include "director/castmember/bitmap.h"
-#include "director/castmember/shape.h"
 #include "director/castmember/text.h"
-#include "director/debugger.h"
 #include "director/movie.h"
-#include "director/window.h"
-#include "director/score.h"
-#include "director/channel.h"
-#include "director/picture.h"
-
-#include "director/debugger/debugtools.h"
-#include "director/debugger/dt-internal.h"
 
 namespace Director {
 namespace DT {




More information about the Scummvm-git-logs mailing list