From 04a96689c28a4b9ec12fe2c127e22523fe562ca3 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Tue, 23 Feb 2016 14:53:47 +0100 Subject: WINTERMUTE: Remove dead code from vestigial remnants of WME debugger --- engines/wintermute/base/scriptables/script.cpp | 12 ------------ engines/wintermute/base/scriptables/script.h | 6 ------ engines/wintermute/base/scriptables/script_engine.h | 14 -------------- 3 files changed, 32 deletions(-) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/scriptables/script.cpp b/engines/wintermute/base/scriptables/script.cpp index 44fd117e61..de2f76d033 100644 --- a/engines/wintermute/base/scriptables/script.cpp +++ b/engines/wintermute/base/scriptables/script.cpp @@ -1434,18 +1434,6 @@ bool ScScript::finishThreads() { return STATUS_OK; } - -////////////////////////////////////////////////////////////////////////// -// IWmeDebugScript interface implementation -int ScScript::dbgGetLine() { - return _currentLine; -} - -////////////////////////////////////////////////////////////////////////// -const char *ScScript::dbgGetFilename() { - return _filename; -} - ////////////////////////////////////////////////////////////////////////// void ScScript::afterLoad() { if (_buffer == nullptr) { diff --git a/engines/wintermute/base/scriptables/script.h b/engines/wintermute/base/scriptables/script.h index 1edeae5b55..2fd041d924 100644 --- a/engines/wintermute/base/scriptables/script.h +++ b/engines/wintermute/base/scriptables/script.h @@ -161,12 +161,6 @@ private: bool initScript(); bool initTables(); - - -// IWmeDebugScript interface implementation -public: - virtual int dbgGetLine(); - virtual const char *dbgGetFilename(); }; } // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/script_engine.h b/engines/wintermute/base/scriptables/script_engine.h index bdb139e1f8..8b7e4acd19 100644 --- a/engines/wintermute/base/scriptables/script_engine.h +++ b/engines/wintermute/base/scriptables/script_engine.h @@ -66,20 +66,6 @@ public: Common::String _filename; }; - class CScBreakpoint { - public: - CScBreakpoint(const char *filename) { - _filename = filename; - } - - ~CScBreakpoint() { - _lines.clear(); - } - - Common::String _filename; - BaseArray _lines; - }; - public: bool clearGlobals(bool includingNatives = false); bool tickUnbreakable(); -- cgit v1.2.3 From cd5d60e44c24a82e5b757cd404a9f5a8a098c315 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Fri, 26 Feb 2016 15:49:35 +0100 Subject: WINTERMUTE: Make _operand protected in script.h --- engines/wintermute/base/scriptables/script.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/scriptables/script.h b/engines/wintermute/base/scriptables/script.h index 2fd041d924..304424accc 100644 --- a/engines/wintermute/base/scriptables/script.h +++ b/engines/wintermute/base/scriptables/script.h @@ -50,7 +50,7 @@ public: bool copyParameters(ScStack *stack); void afterLoad(); -private: +protected: ScValue *_operand; ScValue *_reg1; public: -- cgit v1.2.3 From 4e9b113f3f042022fcd0f53ee368f8c73a4d23a3 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Tue, 2 Jul 2013 02:37:56 +0200 Subject: WINTERMUTE: Add debuggerToString --- engines/wintermute/base/base_frame.cpp | 3 +++ engines/wintermute/base/base_frame.h | 2 ++ engines/wintermute/base/base_region.cpp | 3 +++ engines/wintermute/base/base_region.h | 2 ++ engines/wintermute/base/base_scriptable.cpp | 5 +++++ engines/wintermute/base/base_scriptable.h | 1 + engines/wintermute/base/base_sprite.cpp | 3 +++ engines/wintermute/base/base_sprite.h | 1 + engines/wintermute/base/base_sub_frame.cpp | 4 ++++ engines/wintermute/base/base_sub_frame.h | 1 + engines/wintermute/base/base_viewport.cpp | 3 +++ engines/wintermute/base/base_viewport.h | 1 + 12 files changed, 29 insertions(+) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/base_frame.cpp b/engines/wintermute/base/base_frame.cpp index 471185f2d2..910ab64a76 100644 --- a/engines/wintermute/base/base_frame.cpp +++ b/engines/wintermute/base/base_frame.cpp @@ -764,4 +764,7 @@ const char *BaseFrame::scToString() { return "[frame]"; } +Common::String BaseFrame::debuggerToString() const { + return Common::String::format("%p: Frame \"%s\": #subframes %d ", (const void *)this, getName(), _subframes.size()); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_frame.h b/engines/wintermute/base/base_frame.h index ff9e67a166..8d261c9e71 100644 --- a/engines/wintermute/base/base_frame.h +++ b/engines/wintermute/base/base_frame.h @@ -65,6 +65,8 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; + virtual Common::String debuggerToString() const override; + private: bool _keyframe; bool _editorExpanded; diff --git a/engines/wintermute/base/base_region.cpp b/engines/wintermute/base/base_region.cpp index 9a31f5cd66..02ab365eff 100644 --- a/engines/wintermute/base/base_region.cpp +++ b/engines/wintermute/base/base_region.cpp @@ -532,4 +532,7 @@ bool BaseRegion::mimic(BaseRegion *region, float scale, int x, int y) { return createRegion() ? STATUS_OK : STATUS_FAILED; } +Common::String BaseRegion::debuggerToString() const { + return Common::String::format("%p: Region \"%s\": Rect (top, right, bottom, left): (%d, %d, %d, %d), active: %d ", (const void *)this, getName(), _rect.top, _rect.right, _rect.bottom, _rect.left, _active); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_region.h b/engines/wintermute/base/base_region.h index fc3389c501..4cb5dd85d6 100644 --- a/engines/wintermute/base/base_region.h +++ b/engines/wintermute/base/base_region.h @@ -59,6 +59,8 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; + virtual Common::String debuggerToString() const override; + private: float _lastMimicScale; int32 _lastMimicX; diff --git a/engines/wintermute/base/base_scriptable.cpp b/engines/wintermute/base/base_scriptable.cpp index c65d30d941..01f6f9e02f 100644 --- a/engines/wintermute/base/base_scriptable.cpp +++ b/engines/wintermute/base/base_scriptable.cpp @@ -188,4 +188,9 @@ ScScript *BaseScriptable::invokeMethodThread(const char *methodName) { return nullptr; } +Common::String BaseScriptable::debuggerToString() const { + return Common::String::format("%p: BaseScriptable %s", (const void *)this, getName()); +} + + } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_scriptable.h b/engines/wintermute/base/base_scriptable.h index b32668d6c8..7b4f269871 100644 --- a/engines/wintermute/base/base_scriptable.h +++ b/engines/wintermute/base/base_scriptable.h @@ -63,6 +63,7 @@ public: virtual void scSetBool(bool val); virtual int scCompare(BaseScriptable *val); virtual void scDebuggerDesc(char *buf, int bufSize); + virtual Common::String debuggerToString() const; int32 _refCount; ScValue *_scValue; ScValue *_scProp; diff --git a/engines/wintermute/base/base_sprite.cpp b/engines/wintermute/base/base_sprite.cpp index 09e138a1fd..f282004a59 100644 --- a/engines/wintermute/base/base_sprite.cpp +++ b/engines/wintermute/base/base_sprite.cpp @@ -826,4 +826,7 @@ bool BaseSprite::killAllSounds() { return STATUS_OK; } +Common::String BaseSprite::debuggerToString() const { + return Common::String::format("%p: Sprite \"%s\"", (const void *)this, getName()); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_sprite.h b/engines/wintermute/base/base_sprite.h index ec71512ec9..2313b7b3dc 100644 --- a/engines/wintermute/base/base_sprite.h +++ b/engines/wintermute/base/base_sprite.h @@ -69,6 +69,7 @@ public: virtual bool scSetProperty(const char *name, ScValue *value) override; virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override; virtual const char *scToString() override; + Common::String debuggerToString() const override; private: BaseObject *_owner; bool _canBreak; diff --git a/engines/wintermute/base/base_sub_frame.cpp b/engines/wintermute/base/base_sub_frame.cpp index 6d0c48ff17..8068e61168 100644 --- a/engines/wintermute/base/base_sub_frame.cpp +++ b/engines/wintermute/base/base_sub_frame.cpp @@ -673,4 +673,8 @@ bool BaseSubFrame::setSurfaceSimple() { } } +Common::String BaseSubFrame::debuggerToString() const { + return Common::String::format("%p: BaseSubFrame \"%s\" - Mirror:(%d, %d), Hotspot:(%d, %d), ", (const void *)this, getName(), _mirrorX, _mirrorY, _hotspotX, _hotspotY); +} + } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_sub_frame.h b/engines/wintermute/base/base_sub_frame.h index f156c332d6..0fd38f9548 100644 --- a/engines/wintermute/base/base_sub_frame.h +++ b/engines/wintermute/base/base_sub_frame.h @@ -86,6 +86,7 @@ public: virtual bool scSetProperty(const char *name, ScValue *value); virtual bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name); virtual const char *scToString(); + Common::String debuggerToString() const override; }; diff --git a/engines/wintermute/base/base_viewport.cpp b/engines/wintermute/base/base_viewport.cpp index bf3700a14e..aed0355eb9 100644 --- a/engines/wintermute/base/base_viewport.cpp +++ b/engines/wintermute/base/base_viewport.cpp @@ -96,4 +96,7 @@ int BaseViewport::getHeight() const { return _rect.bottom - _rect.top; } +Common::String BaseViewport::debuggerToString() const { + return Common::String::format("%p: BaseViewport: (top, right, bottom, left): (%d, %d, %d, %d)", (const void *)this, _rect.top, _rect.right, _rect.bottom, _rect.left); +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/base_viewport.h b/engines/wintermute/base/base_viewport.h index eae756f9c6..d8f1ed117f 100644 --- a/engines/wintermute/base/base_viewport.h +++ b/engines/wintermute/base/base_viewport.h @@ -48,6 +48,7 @@ public: BaseObject *_mainObject; BaseViewport(BaseGame *inGame = nullptr); virtual ~BaseViewport(); + virtual Common::String debuggerToString() const override; private: Rect32 _rect; }; -- cgit v1.2.3 From fb3a8f7899ee8b6955a6a9f5ede17ebb76836b54 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Fri, 26 Feb 2016 15:49:42 +0100 Subject: WINTERMUTE: Init _ready in BaseScriptHolder --- engines/wintermute/base/base_script_holder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/base_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp index 5b1c961479..bf53c0253c 100644 --- a/engines/wintermute/base/base_script_holder.cpp +++ b/engines/wintermute/base/base_script_holder.cpp @@ -42,7 +42,7 @@ IMPLEMENT_PERSISTENT(BaseScriptHolder, false) ////////////////////////////////////////////////////////////////////// BaseScriptHolder::BaseScriptHolder(BaseGame *inGame) : BaseScriptable(inGame) { setName(""); - + _ready = false; _freezable = true; _filename = nullptr; } -- cgit v1.2.3 From d4f94b7d19bd7584f41d78c2bee0fbe159e37fdc Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Sun, 28 Feb 2016 19:24:04 +0100 Subject: WINTERMUTE: Add DebuggableScript and DebuggableScriptEngine classes These extend the script engine and allow for monitoring and adding pre/post instruction hooks --- engines/wintermute/base/base_game.cpp | 8 +++ engines/wintermute/base/base_game.h | 7 +++ engines/wintermute/base/base_script_holder.cpp | 13 ++++- .../scriptables/debuggable/debuggable_script.cpp | 63 ++++++++++++++++++++++ .../scriptables/debuggable/debuggable_script.h | 63 ++++++++++++++++++++++ .../debuggable/debuggable_script_engine.cpp | 34 ++++++++++++ .../debuggable/debuggable_script_engine.h | 52 ++++++++++++++++++ engines/wintermute/base/scriptables/script.cpp | 21 +++++++- engines/wintermute/base/scriptables/script.h | 8 ++- .../wintermute/base/scriptables/script_engine.cpp | 8 +++ 10 files changed, 273 insertions(+), 4 deletions(-) create mode 100644 engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp create mode 100644 engines/wintermute/base/scriptables/debuggable/debuggable_script.h create mode 100644 engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp create mode 100644 engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/base_game.cpp b/engines/wintermute/base/base_game.cpp index 668053bb3a..ce4c5fdda5 100644 --- a/engines/wintermute/base/base_game.cpp +++ b/engines/wintermute/base/base_game.cpp @@ -71,6 +71,10 @@ #include "common/system.h" #include "common/file.h" +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" +#endif + namespace Wintermute { ////////////////////////////////////////////////////////////////////// @@ -398,7 +402,11 @@ bool BaseGame::initialize1() { break; } +#if EXTENDED_DEBUGGER_ENABLED == true + _scEngine = new DebuggableScEngine(this); +#else _scEngine = new ScEngine(this); +#endif if (_scEngine == nullptr) { break; } diff --git a/engines/wintermute/base/base_game.h b/engines/wintermute/base/base_game.h index e535cc9618..59e3a9c504 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -35,6 +35,9 @@ #include "engines/wintermute/coll_templ.h" #include "engines/wintermute/math/rect32.h" #include "common/events.h" +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" +#endif namespace Wintermute { @@ -148,7 +151,11 @@ public: BaseRenderer *_renderer; BaseSoundMgr *_soundMgr; +#if EXTENDED_DEBUGGER_ENABLED == true + DebuggableScEngine *_scEngine; +#else ScEngine *_scEngine; +#endif BaseScriptable *_mathClass; BaseSurfaceStorage *_surfaceStorage; BaseFontStorage *_fontStorage; diff --git a/engines/wintermute/base/base_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp index bf53c0253c..7427a9b082 100644 --- a/engines/wintermute/base/base_script_holder.cpp +++ b/engines/wintermute/base/base_script_holder.cpp @@ -312,7 +312,11 @@ bool BaseScriptHolder::addScript(const char *filename) { if (!scr) { if (_gameRef->_editorForceScripts) { // editor hack +#if EXTENDED_DEBUGGER_ENABLED + scr = new DebuggableScript(_gameRef, _gameRef->_scEngine); +#else scr = new ScScript(_gameRef, _gameRef->_scEngine); +#endif scr->_filename = new char[strlen(filename) + 1]; strcpy(scr->_filename, filename); scr->_state = SCRIPT_ERROR; @@ -462,8 +466,15 @@ void BaseScriptHolder::makeFreezable(bool freezable) { ScScript *BaseScriptHolder::invokeMethodThread(const char *methodName) { for (int i = _scripts.size() - 1; i >= 0; i--) { if (_scripts[i]->canHandleMethod(methodName)) { - +#if EXTENDED_DEBUGGER_ENABLED == true + DebuggableScEngine* debuggableEngine; + debuggableEngine = dynamic_cast(_scripts[i]->_engine); + // TODO: Not pretty + assert(debuggableEngine); + ScScript *thread = new DebuggableScript(_gameRef, debuggableEngine); +#else ScScript *thread = new ScScript(_gameRef, _scripts[i]->_engine); +#endif if (thread) { bool ret = thread->createMethodThread(_scripts[i], methodName); if (DID_SUCCEED(ret)) { diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp new file mode 100644 index 0000000000..71f78a8d28 --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -0,0 +1,63 @@ +/* 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 "debuggable_script.h" +#include "debuggable_script_engine.h" +#include "engines/wintermute/base/scriptables/script_stack.h" + +namespace Wintermute { + +DebuggableScript::DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine) : ScScript(inGame, engine), _engine(engine), _stepDepth(kDefaultStepDepth) {} + +DebuggableScript::~DebuggableScript() {} + +void DebuggableScript::preInstHook(uint32 inst) {} + +void DebuggableScript::postInstHook(uint32 inst) {} + +void DebuggableScript::setStepDepth(int depth) { + _stepDepth = depth; +} + +void DebuggableScript::step() { + setStepDepth(_callStack->_sP); + // TODO double check +} + +void DebuggableScript::stepContinue() { + setStepDepth(kDefaultStepDepth); +} + +void DebuggableScript::stepFinish() { + setStepDepth(_callStack->_sP - 1); +} + +uint DebuggableScript::dbgGetLine() const { + return _currentLine; +} + +Common::String DebuggableScript::dbgGetFilename() const { + return _filename; +} + +} // End of namespace Wintermute + diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h new file mode 100644 index 0000000000..dc9accece9 --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h @@ -0,0 +1,63 @@ +/* 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 DEBUGGABLE_SCRIPT_H_ +#define DEBUGGABLE_SCRIPT_H_ + +#include "engines/wintermute/base/scriptables/script.h" + +namespace Wintermute { +class ScriptMonitor; +class DebuggableScEngine; + +class DebuggableScript : public ScScript { + static const int kDefaultStepDepth = -2; + int32 _stepDepth; + DebuggableScEngine *_engine; + virtual void preInstHook(uint32 inst) override; + virtual void postInstHook(uint32 inst) override; + void setStepDepth(int depth); +public: + DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine); + virtual ~DebuggableScript(); + /** + * Return argument to last II_DBG_LINE encountered + */ + virtual uint dbgGetLine() const; + virtual Common::String dbgGetFilename() const; + /** + * Execute one more instruction + */ + void step(); + /** + * Continue execution + */ + void stepContinue(); + /** + * Continue execution until the activation record on top of the stack is popped + */ + void stepFinish(); +}; + +} // End of namespace Wintermute + +#endif /* DEBUGGABLE_SCRIPT_H_ */ diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp new file mode 100644 index 0000000000..f1f1bf776e --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp @@ -0,0 +1,34 @@ +/* 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 "debuggable_script_engine.h" +#include "debuggable_script.h" + +namespace Wintermute { + +DebuggableScEngine::DebuggableScEngine(BaseGame *inGame) : ScEngine(inGame), _monitor(nullptr) {} + +void DebuggableScEngine::attachMonitor(ScriptMonitor *monitor) { + _monitor = monitor; +} + +} // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h new file mode 100644 index 0000000000..8469ecdc25 --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h @@ -0,0 +1,52 @@ +/* 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 DEBUGGABLE_SCRIPT_ENGINE_H_ +#define DEBUGGABLE_SCRIPT_ENGINE_H_ + +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#include "engines/wintermute/base/scriptables/script_engine.h" +#include "engines/wintermute/coll_templ.h" +#include "common/algorithm.h" + +namespace Wintermute { + +class Breakpoint; +class DebuggableScript; +class DebuggableScEngine; +class ScriptMonitor; + +class DebuggableScEngine : public ScEngine { + Common::Array _breakpoints; + ScriptMonitor *_monitor; +public: + DebuggableScEngine(BaseGame *inGame); + void attachMonitor(ScriptMonitor *); + + friend class DebuggerController; + friend class DebuggableScript; + friend class ScScript; +}; + +} // End of namespace Wintermute + +#endif /* DEBUGGABLE_SCRIPT_ENGINE_H_ */ diff --git a/engines/wintermute/base/scriptables/script.cpp b/engines/wintermute/base/scriptables/script.cpp index de2f76d033..938ec031da 100644 --- a/engines/wintermute/base/scriptables/script.cpp +++ b/engines/wintermute/base/scriptables/script.cpp @@ -32,7 +32,9 @@ #include "engines/wintermute/base/scriptables/script_engine.h" #include "engines/wintermute/base/scriptables/script_stack.h" #include "common/memstream.h" - +#if EXTENDED_DEBUGGER_ENABLED == true +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" +#endif namespace Wintermute { IMPLEMENT_PERSISTENT(ScScript, false) @@ -522,6 +524,9 @@ bool ScScript::executeInstruction() { ScValue *op2; uint32 inst = getDWORD(); + + preInstHook(inst); + switch (inst) { case II_DEF_VAR: @@ -1092,6 +1097,7 @@ bool ScScript::executeInstruction() { ret = STATUS_FAILED; } // switch(instruction) + postInstHook(inst); //delete op; return ret; @@ -1314,8 +1320,15 @@ ScScript *ScScript::invokeEventHandler(const Common::String &eventName, bool unb if (!pos) { return nullptr; } - +#if EXTENDED_DEBUGGER_ENABLED == true + // TODO: Not pretty + DebuggableScEngine* debuggableEngine; + debuggableEngine = dynamic_cast(_engine); + assert(debuggableEngine); + ScScript *thread = new DebuggableScript(_gameRef, debuggableEngine); +#else ScScript *thread = new ScScript(_gameRef, _engine); +#endif if (thread) { bool ret = thread->createThread(this, pos, eventName); if (DID_SUCCEED(ret)) { @@ -1454,4 +1467,8 @@ void ScScript::afterLoad() { } } +void ScScript::preInstHook(uint32 inst) {} + +void ScScript::postInstHook(uint32 inst) {} + } // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/script.h b/engines/wintermute/base/scriptables/script.h index 304424accc..c1d1cce4ee 100644 --- a/engines/wintermute/base/scriptables/script.h +++ b/engines/wintermute/base/scriptables/script.h @@ -33,12 +33,15 @@ #include "engines/wintermute/base/base.h" #include "engines/wintermute/base/scriptables/dcscript.h" // Added by ClassView #include "engines/wintermute/coll_templ.h" +#include "engines/wintermute/persistent.h" namespace Wintermute { class BaseScriptHolder; class BaseObject; class ScEngine; class ScStack; +class ScValue; + class ScScript : public BaseClass { public: BaseArray _breakpoints; @@ -125,7 +128,7 @@ public: ScValue *_globals; ScEngine *_engine; int32 _currentLine; - bool executeInstruction(); + virtual bool executeInstruction(); char *getString(); uint32 getDWORD(); double getFloat(); @@ -161,6 +164,9 @@ private: bool initScript(); bool initTables(); + + virtual void preInstHook(uint32 inst); + virtual void postInstHook(uint32 inst); }; } // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/script_engine.cpp b/engines/wintermute/base/scriptables/script_engine.cpp index cdf55a304c..26122094f1 100644 --- a/engines/wintermute/base/scriptables/script_engine.cpp +++ b/engines/wintermute/base/scriptables/script_engine.cpp @@ -144,7 +144,15 @@ ScScript *ScEngine::runScript(const char *filename, BaseScriptHolder *owner) { } // add new script +#if EXTENDED_DEBUGGER_ENABLED == true + DebuggableScEngine* debuggableEngine; + debuggableEngine = dynamic_cast(this); + // TODO: Not pretty + assert(debuggableEngine); + ScScript *script = new DebuggableScript(_gameRef, debuggableEngine); +#else ScScript *script = new ScScript(_gameRef, this); +#endif bool ret = script->create(filename, compBuffer, compSize, owner); if (DID_FAIL(ret)) { _gameRef->LOG(ret, "Error running script '%s'...", filename); -- cgit v1.2.3 From 06021d1aab3213b36015c39361c9f5d14536383a Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Sun, 28 Feb 2016 20:56:53 +0100 Subject: WINTERMUTE: Add post instruction hook to DebuggableScript --- .../base/scriptables/debuggable/debuggable_script.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp index 71f78a8d28..670a6d4045 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -21,8 +21,11 @@ */ #include "debuggable_script.h" -#include "debuggable_script_engine.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" #include "engines/wintermute/base/scriptables/script_stack.h" +#include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/debugger/breakpoint.h" +#include "engines/wintermute/debugger/script_monitor.h" namespace Wintermute { @@ -32,7 +35,17 @@ DebuggableScript::~DebuggableScript() {} void DebuggableScript::preInstHook(uint32 inst) {} -void DebuggableScript::postInstHook(uint32 inst) {} +void DebuggableScript::postInstHook(uint32 inst) { + if (inst == II_DBG_LINE) { + for (uint j = 0; j < _engine->_breakpoints.size(); j++) { + _engine->_breakpoints[j]->evaluate(this); + } + + if (_callStack->_sP <= _stepDepth) { + _engine->_monitor->notifyStep(this); + } + } +} void DebuggableScript::setStepDepth(int depth) { _stepDepth = depth; -- cgit v1.2.3 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 + 1 file changed, 1 insertion(+) (limited to 'engines/wintermute/base') 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" -- cgit v1.2.3 From dae732814c7c368f74f09174080e9bdd610982d2 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Mon, 29 Feb 2016 11:37:06 +0100 Subject: WINTERMUTE: Add name resolution to DebuggableScript --- .../scriptables/debuggable/debuggable_script.cpp | 38 ++++++++++++++++++++++ .../scriptables/debuggable/debuggable_script.h | 1 + 2 files changed, 39 insertions(+) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp index 670a6d4045..1aa318bdbf 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -20,6 +20,7 @@ * */ +#include "common/tokenizer.h" #include "debuggable_script.h" #include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" #include "engines/wintermute/base/scriptables/script_stack.h" @@ -64,6 +65,43 @@ void DebuggableScript::stepFinish() { setStepDepth(_callStack->_sP - 1); } +ScValue *DebuggableScript::resolveName(const Common::String &name) { + + Common::String trimmed = name; + trimmed.trim(); + Common::StringTokenizer st = Common::StringTokenizer(trimmed.c_str(), "."); + Common::String nextToken; + + nextToken = st.nextToken(); + + + char cstr[256]; // TODO not pretty + Common::strlcpy(cstr, nextToken.c_str(), nextToken.size() + 1); + cstr[255] = '\0'; // We 0-terminate it just in case it's > 256 chars. + + ScValue *value = getVar(cstr); + ScValue *res = new ScValue(_gameRef); + + if (value == nullptr) { + return res; + } + + nextToken = st.nextToken(); + + while (nextToken.size() > 0 && (value->isObject() || value->isNative())) { + value = value->getProp(nextToken.c_str()); + nextToken = st.nextToken(); + if (value == nullptr) { + return res; + } + } + + res->copy(value); + delete value; + + return res; +} + uint DebuggableScript::dbgGetLine() const { return _currentLine; } diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h index dc9accece9..c5c0896f11 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h @@ -39,6 +39,7 @@ class DebuggableScript : public ScScript { public: DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine); virtual ~DebuggableScript(); + ScValue *resolveName(const Common::String &name); /** * Return argument to last II_DBG_LINE encountered */ -- cgit v1.2.3 From a120aa855990f045d38d3b603306490305a48a39 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Mon, 29 Feb 2016 15:39:42 +0100 Subject: WINTERMUTE: Add Watch functionality --- .../scriptables/debuggable/debuggable_script.cpp | 42 +++++++++++++-- .../scriptables/debuggable/debuggable_script.h | 5 +- .../debuggable/debuggable_script_engine.cpp | 1 + .../debuggable/debuggable_script_engine.h | 62 +++++++++++++++++++++- 4 files changed, 103 insertions(+), 7 deletions(-) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp index 1aa318bdbf..73ecd3fc89 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -22,18 +22,28 @@ #include "common/tokenizer.h" #include "debuggable_script.h" -#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" #include "engines/wintermute/base/scriptables/script_stack.h" #include "engines/wintermute/base/scriptables/script_value.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h" #include "engines/wintermute/debugger/breakpoint.h" #include "engines/wintermute/debugger/script_monitor.h" +#include "engines/wintermute/debugger/watch_instance.h" namespace Wintermute { -DebuggableScript::DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine) : ScScript(inGame, engine), _engine(engine), _stepDepth(kDefaultStepDepth) {} - -DebuggableScript::~DebuggableScript() {} +DebuggableScript::DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine) : ScScript(inGame, engine), _engine(engine), _stepDepth(kDefaultStepDepth) { + _engine->_watches.subscribe(this); + for (uint i = 0; i < _engine->_watches.size(); i++) { + _watchInstances.push_back(new WatchInstance(_engine->_watches[i], this)); + } +} +DebuggableScript::~DebuggableScript() { + for (uint i = 0; i < _watchInstances.size(); i++) { + delete _watchInstances[i]; + } + _engine->_watches.unsubscribe(this); +} void DebuggableScript::preInstHook(uint32 inst) {} void DebuggableScript::postInstHook(uint32 inst) { @@ -46,6 +56,11 @@ void DebuggableScript::postInstHook(uint32 inst) { _engine->_monitor->notifyStep(this); } } + + for (uint i = 0; i < _watchInstances.size(); i++) { + this->_watchInstances[i]->evaluate(); + } + } void DebuggableScript::setStepDepth(int depth) { @@ -110,5 +125,24 @@ Common::String DebuggableScript::dbgGetFilename() const { return _filename; } +void DebuggableScript::updateWatches() { + // We drop obsolete watches + for (uint i = 0; i < _watchInstances.size(); i++) { + Watch *findMe = _watchInstances[i]->_watch; + if (Common::find(_engine->_watches.begin(), _engine->_watches.end(), findMe) == _engine->_watches.end()) { + // Not found on engine-wide list, must have been removed from watches. Must remove it from local list. + _watchInstances.remove_at(i); + } + } + + // We add any new watches + for (uint i = 0; i < _engine->_watches.size(); i++) { + Watch *findMe = _engine->_watches[i]; + if (Common::find(_engine->_watches.begin(), _engine->_watches.end(), findMe) == _engine->_watches.end()) { + // Not found on local list, must be a new one. + _watchInstances.push_back(new WatchInstance(_engine->_watches[i], this)); + } + } +} } // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h index c5c0896f11..b32a5ca4af 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.h +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h @@ -22,17 +22,19 @@ #ifndef DEBUGGABLE_SCRIPT_H_ #define DEBUGGABLE_SCRIPT_H_ - #include "engines/wintermute/base/scriptables/script.h" namespace Wintermute { class ScriptMonitor; +class Watch; +class WatchInstance; class DebuggableScEngine; class DebuggableScript : public ScScript { static const int kDefaultStepDepth = -2; int32 _stepDepth; DebuggableScEngine *_engine; + BaseArray _watchInstances; virtual void preInstHook(uint32 inst) override; virtual void postInstHook(uint32 inst) override; void setStepDepth(int depth); @@ -57,6 +59,7 @@ public: * Continue execution until the activation record on top of the stack is popped */ void stepFinish(); + void updateWatches(); }; } // End of namespace Wintermute diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp index f1f1bf776e..28a00cd4ae 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp @@ -22,6 +22,7 @@ #include "debuggable_script_engine.h" #include "debuggable_script.h" +#include "engines/wintermute/debugger/watch_instance.h" namespace Wintermute { diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h index 8469ecdc25..a4d9d2bfe7 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h @@ -22,21 +22,78 @@ #ifndef DEBUGGABLE_SCRIPT_ENGINE_H_ #define DEBUGGABLE_SCRIPT_ENGINE_H_ - -#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" #include "engines/wintermute/base/scriptables/script_engine.h" #include "engines/wintermute/coll_templ.h" #include "common/algorithm.h" +#include "engines/wintermute/base/scriptables/debuggable/debuggable_script.h" namespace Wintermute { class Breakpoint; +class Watch; class DebuggableScript; class DebuggableScEngine; class ScriptMonitor; +class PublisherWArray : private Common::Array { + Common::Array _subscribers; + void notifySubscribers() { + for (uint i = 0; i < _subscribers.size(); i++) { + _subscribers[i]->updateWatches(); + } + } +public: + void subscribe(DebuggableScript *script) { + if (Common::find(_subscribers.begin(), _subscribers.end(), script) == _subscribers.end()) { + // If not already contained + _subscribers.push_back(script); + } + } + + void unsubscribe(DebuggableScript *script) { + int location = -1; + for (uint i = 0; i < _subscribers.size() && location == -1; i++) { + if (_subscribers[i] == script) { + location = i; + } + } + if (location >= 0) { + _subscribers.remove_at(location); + } else { + // TODO: If this happens... it's funny. Some script out there forgot to subscribe. + } + } + + void push_back(Watch *newElement) { + Common::Array::push_back(newElement); + notifySubscribers(); + } + + size_type size() { + return Common::Array::size(); + } + + iterator begin() { + return Common::Array::begin(); + } + + iterator end() { + return Common::Array::end(); + } + + Watch *&operator[](size_type idx) { + return Common::Array::operator[](idx); + } + Watch *remove_at(size_type idx) { + Watch *res = Common::Array::remove_at(idx); + notifySubscribers(); + return res; + } +}; + class DebuggableScEngine : public ScEngine { Common::Array _breakpoints; + PublisherWArray _watches; ScriptMonitor *_monitor; public: DebuggableScEngine(BaseGame *inGame); @@ -45,6 +102,7 @@ public: friend class DebuggerController; friend class DebuggableScript; friend class ScScript; + friend class WatchableScriptArray; }; } // End of namespace Wintermute -- cgit v1.2.3 From bf9865ebbba264eb05c3788b273406eb55182086 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Mon, 29 Feb 2016 19:09:08 +0100 Subject: WINTERMUTE: Do not delete a pointer we do not own in resolveName --- engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp index 73ecd3fc89..cfecc28d4f 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -112,7 +112,6 @@ ScValue *DebuggableScript::resolveName(const Common::String &name) { } res->copy(value); - delete value; return res; } -- cgit v1.2.3 From cd5229bc733028fc477110ba140068602f77e441 Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Mon, 29 Feb 2016 20:32:10 +0100 Subject: WINTERMUTE: Remember to delete watch instances --- engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'engines/wintermute/base') diff --git a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp index cfecc28d4f..5a2291894f 100644 --- a/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -130,6 +130,7 @@ void DebuggableScript::updateWatches() { Watch *findMe = _watchInstances[i]->_watch; if (Common::find(_engine->_watches.begin(), _engine->_watches.end(), findMe) == _engine->_watches.end()) { // Not found on engine-wide list, must have been removed from watches. Must remove it from local list. + delete _watchInstances[i]; _watchInstances.remove_at(i); } } -- cgit v1.2.3