[Scummvm-git-logs] scummvm master -> a55fcc622e7871b2d9311ba7ec927fd6288e52d6
sev-
noreply at scummvm.org
Tue Sep 30 08:41:06 UTC 2025
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
52451a34e7 WAGE: Fix string operant reading
a55fcc622e WAGE: Added ImGui-based debugger. Global script is displayed
Commit: 52451a34e7fc384e64fb2fea665fc5d05eb48480
https://github.com/scummvm/scummvm/commit/52451a34e7fc384e64fb2fea665fc5d05eb48480
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-30T10:40:54+02:00
Commit Message:
WAGE: Fix string operant reading
Fixes crash in castleofert when going up from the current scene.
Bug #16222
Changed paths:
engines/wage/script.cpp
diff --git a/engines/wage/script.cpp b/engines/wage/script.cpp
index 52b93b54064..bab621175bc 100644
--- a/engines/wage/script.cpp
+++ b/engines/wage/script.cpp
@@ -499,8 +499,9 @@ Script::Operand *Script::readStringOperand() {
while (true) {
byte c = _data->readByte();
- if (c >= 0x20 && c < 0x80)
- *str += c;
+
+ if (c < 0x80)
+ *str += (c < 0x20 ? ' ' : c);
else
break;
if ((c < '0' || c > '9') && !(c == '-' && str->empty()))
Commit: a55fcc622e7871b2d9311ba7ec927fd6288e52d6
https://github.com/scummvm/scummvm/commit/a55fcc622e7871b2d9311ba7ec927fd6288e52d6
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2025-09-30T10:40:54+02:00
Commit Message:
WAGE: Added ImGui-based debugger. Global script is displayed
Changed paths:
A engines/wage/debugtools.cpp
A engines/wage/debugtools.h
A engines/wage/dt-internal.h
engines/wage/configure.engine
engines/wage/detection.cpp
engines/wage/module.mk
engines/wage/wage.cpp
engines/wage/wage.h
diff --git a/engines/wage/configure.engine b/engines/wage/configure.engine
index d7cb5443685..6ac91b2932b 100644
--- a/engines/wage/configure.engine
+++ b/engines/wage/configure.engine
@@ -1,3 +1,3 @@
# This file is included from the main "configure" script
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
-add_engine wage "WAGE" yes "" "" "highres"
+add_engine wage "WAGE" yes "" "" "highres" "imgui"
diff --git a/engines/wage/debugtools.cpp b/engines/wage/debugtools.cpp
new file mode 100644
index 00000000000..54d3b21d4b3
--- /dev/null
+++ b/engines/wage/debugtools.cpp
@@ -0,0 +1,254 @@
+/* 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"
+#define IMGUI_DEFINE_MATH_OPERATORS
+
+#include "backends/imgui/imgui.h"
+#include "backends/imgui/imgui_fonts.h"
+
+#include "common/debug.h"
+#include "common/system.h"
+
+#include "graphics/managed_surface.h"
+
+#include "wage/wage.h"
+#include "wage/dt-internal.h"
+#include "wage/script.h"
+#include "wage/world.h"
+
+namespace Wage {
+
+ImGuiState *_state = nullptr;
+
+ImGuiImage getImageID(Common::Path filename, int frameNum) {
+ Common::String key = Common::String::format("%s:%d", filename.toString().c_str(), frameNum);
+
+ if (_state->_frames.contains(key))
+ return _state->_frames[key];
+
+ int sx = 10, sy = 10;
+ Graphics::ManagedSurface *surface = nullptr;
+
+ if (surface)
+ _state->_frames[key] = { (ImTextureID)g_system->getImGuiTexture(*surface->surfacePtr()), sx, sy };
+
+ delete surface;
+
+ return _state->_frames[key];
+}
+
+#if 0
+void showImage(const ImGuiImage &image, const char *name, float scale) {
+ ImVec2 size = { (float)image.width * scale, (float)image.height * scale };
+
+ ImGui::BeginGroup();
+ ImVec2 screenPos = ImGui::GetCursorScreenPos();
+ ImGui::GetWindowDrawList()->AddRect(screenPos, screenPos + ImVec2(size.x, size.y), 0xFFFFFFFF);
+
+ ImGui::Image(image.id, size);
+ ImGui::EndGroup();
+ //setToolTipImage(image, name);
+}
+
+static void displayTGA() {
+ ImGuiImage imgID;
+
+ imgID = getImageID(_state->_fileToDisplay, 0);
+
+ ImGui::Text("TGA %s: [%d x %d]", transCyrillic(_state->_fileToDisplay.toString()), imgID.width, imgID.height);
+
+ ImGui::Separator();
+
+ showImage(imgID, (char *)transCyrillic(_state->_fileToDisplay.toString()), 1.0);
+}
+
+void showArchives() {
+ if (!_state->_showArchives)
+ return;
+
+ // Calculate the viewport size
+ ImVec2 viewportSize = ImGui::GetMainViewport()->Size;
+
+ // Calculate the window size
+ ImVec2 windowSize = ImVec2(
+ viewportSize.x * 0.9f,
+ viewportSize.y * 0.9f
+ );
+
+ // Calculate the centered position
+ ImVec2 centeredPosition = ImVec2(
+ (viewportSize.x - windowSize.x) * 0.5f,
+ (viewportSize.y - windowSize.y) * 0.5f
+ );
+
+ // Set the next window position and size
+ ImGui::SetNextWindowPos(centeredPosition, ImGuiCond_FirstUseEver);
+ ImGui::SetNextWindowSize(windowSize, ImGuiCond_FirstUseEver);
+
+ if (ImGui::Begin("Archives", &_state->_showArchives)) {
+ ImGui::BeginChild("ChildL", ImVec2(ImGui::GetContentRegionAvail().x * 0.4f, ImGui::GetContentRegionAvail().y), ImGuiChildFlags_None);
+
+ ImGui::Button(ICON_MS_FILTER_ALT);
+ ImGui::SameLine();
+
+ _state->_nameFilter.Draw();
+ ImGui::Separator();
+
+ if (_state->_files.children.empty())
+ populateFileList();
+
+ displayTree(&_state->_files);
+
+ ImGui::EndChild();
+
+ ImGui::SameLine();
+
+ { // Right pane
+ ImGui::BeginChild("ChildR", ImVec2(ImGui::GetContentRegionAvail().x, ImGui::GetContentRegionAvail().y), ImGuiChildFlags_Borders);
+
+ if (_state->_displayMode == kDisplayQDA) {
+ displayQDA();
+ } else if (_state->_displayMode == kDisplayTGA) {
+ displayTGA();
+ }
+
+ ImGui::EndChild();
+ }
+
+ }
+ ImGui::End();
+}
+
+void showSceneObjects() {
+ if (!_state->_showSceneObjects)
+ return;
+
+ ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
+ ImGui::SetNextWindowSize(ImVec2(300, 250), ImGuiCond_FirstUseEver);
+
+ if (ImGui::Begin("Scene Objects", &_state->_showSceneObjects)) {
+ qdGameScene *scene;
+ qdGameDispatcher *dp = qdGameDispatcher::get_dispatcher();
+ if (dp && ((scene = dp->get_active_scene()))) {
+ if (!scene->object_list().empty()) {
+ for (auto &it : g_engine->_visible_objects) {
+ if (ImGui::Selectable((char *)transCyrillic(it->name()), _state->_objectToDisplay == it->name())) {
+ _state->_objectToDisplay = it->name();
+ }
+ }
+ }
+ }
+ }
+ ImGui::End();
+}
+#endif
+
+static void showWorld() {
+ if (!_state->_showWorld)
+ return;
+
+ ImGui::SetNextWindowPos(ImVec2(20, 20), ImGuiCond_FirstUseEver);
+ ImGui::SetNextWindowSize(ImVec2(300, 250), ImGuiCond_FirstUseEver);
+
+ if (ImGui::Begin("Scene Objects", &_state->_showWorld)) {
+ ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_None;
+ if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags)) {
+ if (ImGui::BeginTabItem("Scenes")) {
+ ImGui::Text("This is the Avocado tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ if (ImGui::BeginTabItem("Objects")) {
+ ImGui::Text("This is the Broccoli tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ if (ImGui::BeginTabItem("Characters")) {
+ ImGui::Text("This is the Cucumber tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ if (ImGui::BeginTabItem("Sounds")) {
+ ImGui::Text("This is the Sounds tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ if (ImGui::BeginTabItem("Global Script")) {
+ for (auto &t : g_wage->_world->_globalScript->_scriptText) {
+ ImGui::Text("[%4d]", t->offset);
+ ImGui::SameLine();
+ ImGui::Text("%s", t->line.c_str());
+ }
+ ImGui::EndTabItem();
+ }
+ if (ImGui::BeginTabItem("World")) {
+ ImGui::Text("This is the Global Script tab!\nblah blah blah blah blah");
+ ImGui::EndTabItem();
+ }
+ ImGui::EndTabBar();
+ }
+ }
+
+ ImGui::End();
+}
+
+void onImGuiInit() {
+ ImGuiIO &io = ImGui::GetIO();
+ io.Fonts->AddFontDefault();
+
+ ImFontConfig icons_config;
+ icons_config.MergeMode = true;
+ icons_config.PixelSnapH = false;
+ icons_config.OversampleH = 3;
+ icons_config.OversampleV = 3;
+ icons_config.GlyphOffset = {0, 4};
+
+ static const ImWchar icons_ranges[] = {ICON_MIN_MS, ICON_MAX_MS, 0};
+ ImGui::addTTFFontFromArchive("MaterialSymbolsSharp.ttf", 16.f, &icons_config, icons_ranges);
+
+ _state = new ImGuiState();
+}
+
+void onImGuiRender() {
+ if (!debugChannelSet(-1, kDebugImGui)) {
+ ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange | ImGuiConfigFlags_NoMouse;
+ return;
+ }
+
+ if (!_state)
+ return;
+
+ ImGui::GetIO().ConfigFlags &= ~(ImGuiConfigFlags_NoMouseCursorChange | ImGuiConfigFlags_NoMouse);
+
+ if (ImGui::BeginMainMenuBar()) {
+ if (ImGui::BeginMenu("View")) {
+ ImGui::MenuItem("World", NULL, &_state->_showWorld);
+ ImGui::EndMenu();
+ }
+ ImGui::EndMainMenuBar();
+ }
+
+ showWorld();
+}
+
+void onImGuiCleanup() {
+ delete _state;
+ _state = nullptr;
+}
+
+} // namespace Wage
diff --git a/engines/wage/debugtools.h b/engines/wage/debugtools.h
new file mode 100644
index 00000000000..757a8869402
--- /dev/null
+++ b/engines/wage/debugtools.h
@@ -0,0 +1,31 @@
+/* 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/>.
+ *
+ */
+
+#ifndef WAGE_DEBUGTOOLS_H
+#define WAGE_DEBUGTOOLS_H
+
+namespace Wage {
+void onImGuiInit();
+void onImGuiRender();
+void onImGuiCleanup();
+} // namespace Wage
+
+#endif // WAGE_DEBUGTOOLS_H
diff --git a/engines/wage/detection.cpp b/engines/wage/detection.cpp
index 2bc747ef29f..6ffd088aee7 100644
--- a/engines/wage/detection.cpp
+++ b/engines/wage/detection.cpp
@@ -44,6 +44,11 @@ static const PlainGameDescriptor wageGames[] = {
#include "wage/detection_tables.h"
#include "wage/detection.h"
+static const DebugChannelDef debugFlagList[] = {
+ {Wage::kDebugImGui, "imgui", "Show ImGui debug window (if available)"},
+ DEBUG_CHANNEL_END
+};
+
static ADGameDescription s_fallbackDesc = {
"wage",
"",
@@ -75,6 +80,10 @@ public:
return "World Builder (C) Silicon Beach Software";
}
+ const DebugChannelDef *getDebugChannels() const override {
+ return debugFlagList;
+ }
+
ADDetectedGame fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist, ADDetectedGameExtraInfo **extra) const override;
};
diff --git a/engines/wage/dt-internal.h b/engines/wage/dt-internal.h
new file mode 100644
index 00000000000..a7dff6829ec
--- /dev/null
+++ b/engines/wage/dt-internal.h
@@ -0,0 +1,51 @@
+/* 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/>.
+ *
+ */
+
+#ifndef WAGE_DT_INTERNAL_H
+#define WAGE_DT_INTERNAL_H
+
+namespace Wage {
+
+typedef struct ImGuiImage {
+ ImTextureID id;
+ int width;
+ int height;
+} ImGuiImage;
+
+typedef struct ImGuiState {
+ bool _showWorld = false;
+
+ Common::HashMap<Common::String, ImGuiImage> _frames;
+
+ Common::Path _fileToDisplay;
+ Common::String _objectToDisplay;
+
+ ImGuiTextFilter _nameFilter;
+
+
+ int _displayMode = -1;
+} ImGuiState;
+
+extern ImGuiState *_state;
+
+}
+
+#endif // WAGE_DT_INTERNAL_H
diff --git a/engines/wage/module.mk b/engines/wage/module.mk
index 0e19348c96e..3d086316dc7 100644
--- a/engines/wage/module.mk
+++ b/engines/wage/module.mk
@@ -3,6 +3,7 @@ MODULE := engines/wage
MODULE_OBJS := \
combat.o \
debugger.o \
+ debugtools.o \
design.o \
entities.o \
gui.o \
diff --git a/engines/wage/wage.cpp b/engines/wage/wage.cpp
index 4c664ed060c..3624451d2cb 100644
--- a/engines/wage/wage.cpp
+++ b/engines/wage/wage.cpp
@@ -58,6 +58,7 @@
#include "graphics/macgui/macdialog.h"
#include "wage/wage.h"
+#include "wage/debugtools.h"
#include "wage/entities.h"
#include "wage/gui.h"
#include "wage/script.h"
@@ -65,6 +66,8 @@
namespace Wage {
+WageEngine *g_wage = nullptr;
+
WageEngine::WageEngine(OSystem *syst, const ADGameDescription *desc) : Engine(syst), _gameDescription(desc) {
_rnd = new Common::RandomSource("wage");
@@ -89,6 +92,8 @@ WageEngine::WageEngine(OSystem *syst, const ADGameDescription *desc) : Engine(sy
_resManager = NULL;
+ g_wage = this;
+
debug("WageEngine::WageEngine()");
}
@@ -101,6 +106,7 @@ WageEngine::~WageEngine() {
delete _rnd;
g_engine = nullptr;
+ g_wage = nullptr;
}
bool WageEngine::pollEvent(Common::Event &event) {
@@ -139,6 +145,15 @@ Common::Error WageEngine::run() {
_gui = new Gui(this);
+#ifdef USE_IMGUI
+ ImGuiCallbacks callbacks;
+ bool drawImGui = debugChannelSet(-1, kDebugImGui);
+ callbacks.init = onImGuiInit;
+ callbacks.render = drawImGui ? onImGuiRender : nullptr;
+ callbacks.cleanup = onImGuiCleanup;
+ _system->setImGuiCallbacks(callbacks);
+#endif
+
_temporarilyHidden = true;
performInitialSetup();
if (ConfMan.hasKey("save_slot")) {
diff --git a/engines/wage/wage.h b/engines/wage/wage.h
index 125ca1ae877..d94e1a26b26 100644
--- a/engines/wage/wage.h
+++ b/engines/wage/wage.h
@@ -87,6 +87,10 @@ typedef Common::List<Chr *> ChrList;
#define STORAGESCENE "STORAGE@"
+enum {
+ kDebugImGui = 1,
+};
+
enum OperandType {
OBJ = 0,
CHR = 1,
@@ -261,6 +265,8 @@ private:
Audio::SoundHandle _soundHandle;
};
+extern WageEngine *g_wage;
+
} // End of namespace Wage
#endif
More information about the Scummvm-git-logs
mailing list