From cf3887d1d26bb9f4352982989c355a4265d08888 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Mon, 29 Feb 2016 14:59:39 +0100 Subject: WINTERMUTE: Add DebuggerController --- engines/wintermute/base/base_game.h | 1 + engines/wintermute/debugger.cpp | 224 ++++++++++++++++++++- engines/wintermute/debugger.h | 93 ++++++++- .../wintermute/debugger/debugger_controller.cpp | 189 +++++++++++++++++ engines/wintermute/debugger/debugger_controller.h | 96 +++++++++ engines/wintermute/module.mk | 1 + engines/wintermute/wintermute.cpp | 7 +- engines/wintermute/wintermute.h | 8 +- 8 files changed, 608 insertions(+), 11 deletions(-) create mode 100644 engines/wintermute/debugger/debugger_controller.cpp create mode 100644 engines/wintermute/debugger/debugger_controller.h (limited to 'engines') diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index 59e3a9c504..409cc20ba4 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -34,6 +34,7 @@ #include "engines/wintermute/persistent.h" #include "engines/wintermute/coll_templ.h" #include "engines/wintermute/math/rect32.h" +#include "engines/wintermute/debugger.h" #include "common/events.h" #if EXTENDED_DEBUGGER_ENABLED == true #include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" diff --git a/engines/wintermute/debugger.cpp b/engines/wintermute/debugger.cpp index 5b617d9db9..42fba60f9a 100644 --- a/engines/wintermute/debugger.cpp +++ b/engines/wintermute/debugger.cpp @@ -21,29 +21,189 @@ */ #include "engines/wintermute/debugger.h" -#include "engines/wintermute/wintermute.h" #include "engines/wintermute/base/base_engine.h" #include "engines/wintermute/base/base_file_manager.h" -#include "engines/wintermute/base/base_game.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/debugger/debugger_controller.h" +#include "engines/wintermute/wintermute.h" + +#define CONTROLLER _engineRef->_dbgController namespace Wintermute { Console::Console(WintermuteEngine *vm) : GUI::Debugger(), _engineRef(vm) { registerCmd("show_fps", WRAP_METHOD(Console, Cmd_ShowFps)); registerCmd("dump_file", WRAP_METHOD(Console, Cmd_DumpFile)); + registerCmd("show_fps", WRAP_METHOD(Console, Cmd_ShowFps)); + registerCmd("dump_file", WRAP_METHOD(Console, Cmd_DumpFile)); + registerCmd("help", WRAP_METHOD(Console, Cmd_Help)); + // Actual (script) debugger commands + registerCmd(STEP_CMD, WRAP_METHOD(Console, Cmd_Step)); + registerCmd(CONTINUE_CMD, WRAP_METHOD(Console, Cmd_Continue)); + registerCmd(FINISH_CMD, WRAP_METHOD(Console, Cmd_Finish)); + registerCmd(BREAK_CMD, WRAP_METHOD(Console, Cmd_AddBreakpoint)); + registerCmd(LIST_CMD, WRAP_METHOD(Console, Cmd_List)); + registerCmd(REMOVE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_RemoveBreakpoint)); + registerCmd(DISABLE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_DisableBreakpoint)); + registerCmd(ENABLE_BREAKPOINT_CMD, WRAP_METHOD(Console, Cmd_EnableBreakpoint)); + registerCmd(INFO_CMD, WRAP_METHOD(Console, Cmd_Info)); + registerCmd(TOP_CMD, WRAP_METHOD(Console, Cmd_Top)); } Console::~Console(void) { +} + +bool Console::Cmd_Help(int argc, const char **argv) { + if (argc == 1) { + // Debugger::Cmd_Help(argc, argv); + debugPrintf("\nType help somecommand to get specific help.\n"); + } else { + printUsage(argv[1]); + } + return true; +} + +void Console::printUsage(const Common::String &command) { + // TODO: This is horrible and would probably benefit from a map or something. + if (command.equals(BREAK_CMD)) { + debugPrintf("Usage: %s to break at line of file \n", command.c_str()); + } else if (command.equals(REMOVE_BREAKPOINT_CMD)) { + debugPrintf("Usage: %s to remove breakpoint #id\n", command.c_str()); + } else if (command.equals(ENABLE_BREAKPOINT_CMD)) { + debugPrintf("Usage: %s to enable breakpoint #id\n", command.c_str()); + } else if (command.equals(DISABLE_BREAKPOINT_CMD)) { + debugPrintf("Usage: %s to disable breakpoint #id\n", command.c_str()); + } else if (command.equals(INFO_CMD)) { + debugPrintf("Usage: %s [watch|breakpoints]\n", command.c_str()); + } else if (command.equals(STEP_CMD)) { + debugPrintf("Usage: %s to step\n", command.c_str()); + } else if (command.equals(CONTINUE_CMD)) { + debugPrintf("Usage: %s to continue\n", command.c_str()); + } else if (command.equals(FINISH_CMD)) { + debugPrintf("Usage: %s to finish\n", command.c_str()); + } else { + debugPrintf("No help about this command, sorry."); + } +} + +bool Console::Cmd_AddBreakpoint(int argc, const char **argv) { + if (argc == 3) { + Wintermute::Error error = CONTROLLER->addBreakpoint(argv[1], atoi(argv[2])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} +bool Console::Cmd_RemoveBreakpoint(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->removeBreakpoint(atoi(argv[1])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_EnableBreakpoint(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->enableBreakpoint(atoi(argv[1])); + printError(argv[0], error); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_DisableBreakpoint(int argc, const char **argv) { + if (argc == 2) { + Error error = CONTROLLER->disableBreakpoint(atoi(argv[1])); + debugPrintf("%s: %s\n", argv[0], error.getErrorDisplayStr().c_str()); + } else { + printUsage(argv[0]); + } + return true; +} + +bool Console::Cmd_Info(int argc, const char **argv) { + if (argc == 2 && !strncmp(argv[1], "breakpoints", 10)) { + Common::Array breakpoints = CONTROLLER->getBreakpoints(); + for (uint i = 0; i < breakpoints.size(); i++) { + debugPrintf("%d %s:%d x%d, enabled: %d \n", i, breakpoints[i]._filename.c_str(), breakpoints[i]._line, breakpoints[i]._hits, breakpoints[i]._enabled); + } + return 1; + } else { + printUsage(argv[0]); + return 1; + } +} + +bool Console::Cmd_Step(int argc, const char **argv) { + if (argc == 1) { + Error error = CONTROLLER->step(); + if (error.getErrorLevel() == SUCCESS) { + return false; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + +bool Console::Cmd_Continue(int argc, const char **argv) { + if (argc == 1) { + Error error = CONTROLLER->stepContinue(); + if (error.getErrorLevel() == SUCCESS) { + return false; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + +bool Console::Cmd_Finish(int argc, const char **argv) { + if (argc == 1) { + Error error = CONTROLLER->stepFinish(); + printError(argv[0], error); + if (error.getErrorLevel() == SUCCESS) { + return false; + } else { + printError(argv[0], error); + return true; + } + } else { + printUsage(argv[0]); + return true; + } +} + +bool Console::Cmd_List(int argc, const char **argv) { + Error error = printSource(); + if (error.getErrorLevel() != SUCCESS) { + printError(argv[0], error); + } + return true; } bool Console::Cmd_ShowFps(int argc, const char **argv) { - if (argc > 1) { + if (argc == 2) { if (Common::String(argv[1]) == "true") { - _engineRef->_game->setShowFPS(true); + CONTROLLER->showFps(true); } else if (Common::String(argv[1]) == "false") { - _engineRef->_game->setShowFPS(false); + CONTROLLER->showFps(false); + } else { + debugPrintf("%s: argument 1 must be \"true\" or \"false\"\n", argv[0]); } + } else { + debugPrintf("Usage: %s [true|false]\n", argv[0]); } return true; } @@ -81,4 +241,58 @@ bool Console::Cmd_DumpFile(int argc, const char **argv) { return true; } +void Console::notifyBreakpoint(const char *filename, int line) { + debugPrintf("Breakpoint hit %s: %d\n", filename, line); + printSource(0); + attach(); + onFrame(); +} + +void Console::notifyStep(const char *filename, int line) { + debugPrintf("Step: %s:%d\n", filename, line); + printSource(0); + attach(); + onFrame(); +} + +Error Console::printSource(int n) { + + Error* error = nullptr; + Listing *listing = CONTROLLER->getListing(error); + Error err(*error); + delete error; + + if (err.getErrorLevel() == SUCCESS || err.getErrorLevel() == WARNING) { + Common::Array lines = listing->getLines(CONTROLLER->getLastLine(), n); + for (uint i = 0; i < lines.size(); i++) { + if (lines[i].number == CONTROLLER->getLastLine()) { + debugPrintf(" -> "); + } else { + debugPrintf(" "); + } + debugPrintf("%d", lines[i].number); + debugPrintf("%s", lines[i].text.c_str()); + debugPrintf("\n"); + } + } + + delete listing; + return err; +} + +bool Console::Cmd_Top(int argc, const char **argv) { + Common::Array entries = CONTROLLER->getTop(); + for (uint i = 0; i < entries.size(); i++) { + if (entries[i].current) { + debugPrintf("%d*: %s\n", i, entries[i].filename.c_str()); + } else { + debugPrintf("%d: %s\n", i, entries[i].filename.c_str()); + } + } + return true; +} + +void Console::printError(const Common::String &command, Error error) { + debugPrintf("%s: %s\n", command.c_str(), error.getErrorDisplayStr().c_str()); +} } // End of namespace Wintermute diff --git a/engines/wintermute/debugger.h b/engines/wintermute/debugger.h index 2b31dc0f88..2e427d35db 100644 --- a/engines/wintermute/debugger.h +++ b/engines/wintermute/debugger.h @@ -23,21 +23,108 @@ #ifndef WINTERMUTE_DEBUGGER_H #define WINTERMUTE_DEBUGGER_H +#define EXTENDED_DEBUGGER_ENABLED true + #include "gui/debugger.h" +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#else +#include "engines/wintermute/base/scriptables/script.h" +#endif + +#define DEFAULT_SOURCE_PADDING 5 + +#define STEP_CMD "step" +#define CONTINUE_CMD "continue" +#define FINISH_CMD "finish" +#define BREAK_CMD "break" +#define LIST_CMD "list" +#define REMOVE_BREAKPOINT_CMD "del" +#define DISABLE_BREAKPOINT_CMD "disable" +#define ENABLE_BREAKPOINT_CMD "enable" +#define INFO_CMD "info" #define SET_PATH_CMD "set_path" -namespace Wintermute { +#define TOP_CMD "top" +namespace Wintermute { class WintermuteEngine; +class Adapter; +class DebuggerController; +class Error; + class Console : public GUI::Debugger { public: Console(WintermuteEngine *vm); virtual ~Console(); - + /* + * Debug commands + */ + bool Cmd_Help(int argc, const char **argv); bool Cmd_ShowFps(int argc, const char **argv); bool Cmd_DumpFile(int argc, const char **argv); + +#if EXTENDED_DEBUGGER_ENABLED == true + /** + * Step - break again on next line + */ + bool Cmd_Step(int argc, const char **argv); + /** + * Continue execution + */ + bool Cmd_Continue(int argc, const char **argv); + /** + * Only break again when the current function is finished + * (activation record is popped) + */ + bool Cmd_Finish(int argc, const char **argv); + // Breakpoints + bool Cmd_AddBreakpoint(int argc, const char **argv); + bool Cmd_RemoveBreakpoint(int argc, const char **argv); + bool Cmd_EnableBreakpoint(int argc, const char **argv); + bool Cmd_DisableBreakpoint(int argc, const char **argv); + /** + * Print info re:watch and breakpoints. + * This differs from e.g. gdb in that we have separate lists. + */ + bool Cmd_Info(int argc, const char **argv); + /** + * Print source + */ + bool Cmd_List(int argc, const char **argv); + /** + * Set (DOS-style) source path for debugging. + * This is where you will (optionally) put your sources + * to enable printing of sources as you step through the + * scripts. + * + * Please note that we have no checksum or anything + * to make sure your source files are up to date. + * + * YOU HAVE to make sure of that. + * + * You have been warned! :) + */ + bool Cmd_SourcePath(int argc, const char **argv); + + /** + * Top + */ + bool Cmd_Top(int argc, const char **argv); + + Error printSource(int n = DEFAULT_SOURCE_PADDING); + + /** + * Hooks for the controller to open the console + */ + void notifyBreakpoint(const char *filename, int line); + void notifyStep(const char *filename, int line); +#endif + private: - WintermuteEngine *_engineRef; + const WintermuteEngine *_engineRef; + void printError(const Common::String &command, Error error); + void printUsage(const Common::String &command); }; } diff --git a/engines/wintermute/debugger/debugger_controller.cpp b/engines/wintermute/debugger/debugger_controller.cpp new file mode 100644 index 0000000000..a7f7c2ea4a --- /dev/null +++ b/engines/wintermute/debugger/debugger_controller.cpp @@ -0,0 +1,189 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/algorithm.h" +#include "common/str.h" +#include "common/tokenizer.h" +#include "engines/wintermute/debugger.h" +#include "engines/wintermute/base/base_file_manager.h" +#include "engines/wintermute/base/base_engine.h" +#include "engines/wintermute/base/base_game.h" +#include "engines/wintermute/base/scriptables/script.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/script_stack.h" +#include "engines/wintermute/debugger/breakpoint.h" +#include "engines/wintermute/debugger/debugger_controller.h" +#include "engines/wintermute/debugger/listing_providers/blank_listing_provider.h" +#define SCENGINE _engine->_game->_scEngine +#define DEBUGGER _engine->_debugger + +namespace Wintermute { + +DebuggerController::~DebuggerController() { + delete _listingProvider; +} + +DebuggerController::DebuggerController(WintermuteEngine *vm) : _engine(vm) { + _listingProvider = new BlankListingProvider(); + clear(); +} + +bool DebuggerController::bytecodeExists(const Common::String &filename) { + uint32 compSize; + byte *compBuffer = SCENGINE->getCompiledScript(filename.c_str(), &compSize); + if (!compBuffer) { + return false; + } else { + return true; + } +} + +Error DebuggerController::addBreakpoint(const char *filename, int line) { + assert(SCENGINE); + if (bytecodeExists(filename)) { + SCENGINE->_breakpoints.push_back(new Breakpoint(filename, line, this)); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BYTECODE); + } +} + +Error DebuggerController::removeBreakpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_breakpoints.size() > id) { + SCENGINE->_breakpoints.remove_at(id); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +Error DebuggerController::disableBreakpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_breakpoints.size() > id) { + SCENGINE->_breakpoints[id]->disable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +Error DebuggerController::enableBreakpoint(uint id) { + assert(SCENGINE); + if (SCENGINE->_breakpoints.size() > id) { + SCENGINE->_breakpoints[id]->enable(); + return Error(SUCCESS, OK); + } else { + return Error(ERROR, NO_SUCH_BREAKPOINT, id); + } +} + +void DebuggerController::onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script) { + _lastScript = script; + _lastLine = script->_currentLine; + DEBUGGER->notifyBreakpoint(script->dbgGetFilename().c_str(), script->_currentLine); +} + +void DebuggerController::notifyStep(DebuggableScript *script) override { + _lastScript = script; + _lastLine = script->_currentLine; + DEBUGGER->notifyStep(script->dbgGetFilename().c_str(), script->_currentLine); +} + +Error DebuggerController::step() { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + _lastScript->step(); + clear(); + return Error(SUCCESS, OK); +} + +Error DebuggerController::stepContinue() { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + _lastScript->stepContinue(); + return Error(SUCCESS, OK); +} + +Error DebuggerController::stepFinish() { + if (!_lastScript) { + return Error(ERROR, NOT_ALLOWED); + } + _lastScript->stepFinish(); + clear(); + return Error(SUCCESS, OK); +} + +void DebuggerController::clear() { + _lastScript = nullptr; + _lastLine = -1; +} + +void DebuggerController::showFps(bool show) { + _engine->_game->setShowFPS(show); +} + +Common::Array DebuggerController::getBreakpoints() const { + assert(SCENGINE); + Common::Array breakpoints; + for (uint i = 0; i < SCENGINE->_breakpoints.size(); i++) { + BreakpointInfo bpInfo; + bpInfo._filename = SCENGINE->_breakpoints[i]->getFilename(); + bpInfo._line = SCENGINE->_breakpoints[i]->getLine(); + bpInfo._hits = SCENGINE->_breakpoints[i]->getHits(); + bpInfo._enabled = SCENGINE->_breakpoints[i]->isEnabled(); + breakpoints.push_back(bpInfo); + } + return breakpoints; +} + +uint32 DebuggerController::getLastLine() const { + return _lastLine; +} + +Listing* DebuggerController::getListing(Error* &error) { + delete (error); + if (_lastScript == nullptr) { + error = new Error(ERROR, NOT_ALLOWED); + return nullptr; + } + ErrorCode err; + Listing* res = _listingProvider->getListing(SCENGINE->_currentScript->_filename, err); + error = new Error(err == OK ? SUCCESS : ERROR, err); + return res; +} + +Common::Array DebuggerController::getTop() const { + Common::Array res; + assert(SCENGINE); + for (uint i = 0; i < SCENGINE->_scripts.size(); i++) { + TopEntry entry; + entry.filename = SCENGINE->_scripts[i]->_filename; + entry.current = (SCENGINE->_scripts[i] == SCENGINE->_currentScript); + res.push_back(entry); + } + return res; +} + +} // end of namespace Wintermute diff --git a/engines/wintermute/debugger/debugger_controller.h b/engines/wintermute/debugger/debugger_controller.h new file mode 100644 index 0000000000..b4119b56d3 --- /dev/null +++ b/engines/wintermute/debugger/debugger_controller.h @@ -0,0 +1,96 @@ +/* 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef WINTERMUTE_DEBUGGER_ADAPTER_H +#define WINTERMUTE_DEBUGGER_ADAPTER_H + +#include "common/str.h" +#include "engines/wintermute/coll_templ.h" +#include "engines/wintermute/wintermute.h" +#include "engines/wintermute/debugger/listing_providers/source_listing_provider.h" +#include "script_monitor.h" +#include "error.h" +#include "listing.h" +namespace Wintermute { + +class ScScript; +class DebuggableScript; +class ScValue; + +struct BreakpointInfo { + Common::String _filename; + int _line; + int _hits; + bool _enabled; +}; + +struct TopEntry { + bool current; + Common::String filename; + int watches; + int breakpointInfo; +}; + +class DebuggerController : public ScriptMonitor { + ListingProvider *_listingProvider; + const WintermuteEngine *_engine; + DebuggableScript *_lastScript; + uint32 _lastDepth; + uint32 _lastLine; + void clear(); + bool bytecodeExists(const Common::String &filename); +public: + DebuggerController(WintermuteEngine *vm); + ~DebuggerController(); + Common::Array getTop() const; + /** + * Get the last line # we've stopped at + */ + uint32 getLastLine() const; + Error addBreakpoint(const char *filename, int line); + Error removeBreakpoint(uint id); + Error disableBreakpoint(uint id); + Error enableBreakpoint(uint id); + Common::Array getBreakpoints() const; + /** + * @brief step one instruction + */ + Error step(); + /** + * @brief continue execution and don't step until next breakpoint + */ + Error stepContinue(); + /** + * @brief continue execution and don't step until the current activation record is popped + */ + Error stepFinish(); + Listing *getListing(Error* &err); + void showFps(bool show); + /** + * Inherited from ScriptMonitor + */ + void onBreakpoint(const Breakpoint *breakpoint, DebuggableScript *script); + void notifyStep(DebuggableScript *script); +}; +} + +#endif // WINTERMUTE_DEBUGGER_H diff --git a/engines/wintermute/module.mk b/engines/wintermute/module.mk index cb5ad663bc..24a8ae2bcf 100644 --- a/engines/wintermute/module.mk +++ b/engines/wintermute/module.mk @@ -91,6 +91,7 @@ MODULE_OBJS := \ base/save_thumb_helper.o \ base/timer.o \ debugger/breakpoint.o \ + debugger/debugger_controller.o \ debugger/error.o \ debugger/listing_providers/blank_listing.o \ debugger/listing_providers/blank_listing_provider.o \ diff --git a/engines/wintermute/wintermute.cpp b/engines/wintermute/wintermute.cpp index e35bb60c3d..6f0e3edc13 100644 --- a/engines/wintermute/wintermute.cpp +++ b/engines/wintermute/wintermute.cpp @@ -41,6 +41,7 @@ #include "engines/wintermute/base/base_file_manager.h" #include "engines/wintermute/base/gfx/base_renderer.h" #include "engines/wintermute/base/scriptables/script_engine.h" +#include "engines/wintermute/debugger/debugger_controller.h" namespace Wintermute { @@ -49,6 +50,7 @@ namespace Wintermute { WintermuteEngine::WintermuteEngine() : Engine(g_system) { _game = new AdGame(""); _debugger = nullptr; + _dbgController = nullptr; _trigDebug = false; _gameDescription = nullptr; } @@ -76,6 +78,7 @@ WintermuteEngine::WintermuteEngine(OSystem *syst, const WMEGameDescription *desc _game = nullptr; _debugger = nullptr; + _dbgController = nullptr; _trigDebug = false; } @@ -112,6 +115,7 @@ Common::Error WintermuteEngine::run() { } // Create debugger console. It requires GFX to be initialized + _dbgController = new DebuggerController(this); _debugger = new Console(this); // DebugMan.enableDebugChannel("enginelog"); @@ -171,7 +175,6 @@ int WintermuteEngine::init() { } _game->initialize3(); - // initialize sound manager (non-fatal if we fail) ret = _game->_soundMgr->initialize(); if (DID_FAIL(ret)) { @@ -200,6 +203,8 @@ int WintermuteEngine::init() { _game->loadGame(slot); } + _game->_scEngine->attachMonitor(_dbgController); + // all set, ready to go return 0; } diff --git a/engines/wintermute/wintermute.h b/engines/wintermute/wintermute.h index f8f5fc7deb..5071a84d32 100644 --- a/engines/wintermute/wintermute.h +++ b/engines/wintermute/wintermute.h @@ -33,6 +33,8 @@ namespace Wintermute { class Console; class BaseGame; class SystemClassRegistry; +class DebuggerController; + // our engine debug channels enum { kWintermuteDebugLog = 1 << 0, // The debug-logs from the original engine @@ -49,7 +51,7 @@ public: WintermuteEngine(); ~WintermuteEngine(); - virtual GUI::Debugger *getDebugger() { return _debugger; } + virtual Wintermute::Console *getConsole() { return _debugger; } void trigDebugger() { _trigDebug = true; } virtual Common::Error run(); @@ -66,11 +68,13 @@ private: int init(); void deinit(); int messageLoop(); - GUI::Debugger *_debugger; + Wintermute::Console *_debugger; BaseGame *_game; + Wintermute::DebuggerController *_dbgController; const WMEGameDescription *_gameDescription; friend class Console; + friend class DebuggerController; }; } // End of namespace Wintermute -- cgit v1.2.3