diff options
author | Eugene Sandulenko | 2016-07-24 23:03:19 +0300 |
---|---|---|
committer | GitHub | 2016-07-24 23:03:19 +0300 |
commit | 5f6c79db0335e0a9c3df49cf306e7305b3804cbc (patch) | |
tree | ea543fc6ab56219792c238f35fa3776509394697 /engines/wintermute/base | |
parent | bed2141369bad43c567364209d3f085824787f28 (diff) | |
parent | 3724918626bcdb0fc8a177cead9fe35b5530ca60 (diff) | |
download | scummvm-rg350-5f6c79db0335e0a9c3df49cf306e7305b3804cbc.tar.gz scummvm-rg350-5f6c79db0335e0a9c3df49cf306e7305b3804cbc.tar.bz2 scummvm-rg350-5f6c79db0335e0a9c3df49cf306e7305b3804cbc.zip |
Merge pull request #687 from tobiatesan/wme_debugger_rewrite
WME: Debugger for WME, 2016 rewrite
Diffstat (limited to 'engines/wintermute/base')
23 files changed, 452 insertions, 37 deletions
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_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..409cc20ba4 100644 --- a/engines/wintermute/base/base_game.h +++ b/engines/wintermute/base/base_game.h @@ -34,7 +34,11 @@ #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" +#endif namespace Wintermute { @@ -148,7 +152,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_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_script_holder.cpp b/engines/wintermute/base/base_script_holder.cpp index 5b1c961479..7427a9b082 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("<unnamed>"); - + _ready = false; _freezable = true; _filename = nullptr; } @@ -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<DebuggableScEngine*>(_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/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; }; 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..5a2291894f --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.cpp @@ -0,0 +1,148 @@ +/* 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/tokenizer.h" +#include "debuggable_script.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) { + _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) { + 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); + } + } + + for (uint i = 0; i < _watchInstances.size(); i++) { + this->_watchInstances[i]->evaluate(); + } + +} + +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); +} + +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); + + return res; +} + +uint DebuggableScript::dbgGetLine() const { + return _currentLine; +} + +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. + delete _watchInstances[i]; + _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 new file mode 100644 index 0000000000..b32a5ca4af --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script.h @@ -0,0 +1,67 @@ +/* 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 Watch; +class WatchInstance; +class DebuggableScEngine; + +class DebuggableScript : public ScScript { + static const int kDefaultStepDepth = -2; + int32 _stepDepth; + DebuggableScEngine *_engine; + BaseArray<WatchInstance *> _watchInstances; + virtual void preInstHook(uint32 inst) override; + virtual void postInstHook(uint32 inst) override; + void setStepDepth(int depth); +public: + DebuggableScript(BaseGame *inGame, DebuggableScEngine *engine); + virtual ~DebuggableScript(); + ScValue *resolveName(const Common::String &name); + /** + * 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(); + void updateWatches(); +}; + +} // 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..28a00cd4ae --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.cpp @@ -0,0 +1,35 @@ +/* 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" +#include "engines/wintermute/debugger/watch_instance.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..a4d9d2bfe7 --- /dev/null +++ b/engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h @@ -0,0 +1,110 @@ +/* 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/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<Watch *> { + Common::Array<DebuggableScript *> _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<Watch *>::push_back(newElement); + notifySubscribers(); + } + + size_type size() { + return Common::Array<Watch *>::size(); + } + + iterator begin() { + return Common::Array<Watch *>::begin(); + } + + iterator end() { + return Common::Array<Watch *>::end(); + } + + Watch *&operator[](size_type idx) { + return Common::Array<Watch *>::operator[](idx); + } + Watch *remove_at(size_type idx) { + Watch *res = Common::Array<Watch *>::remove_at(idx); + notifySubscribers(); + return res; + } +}; + +class DebuggableScEngine : public ScEngine { + Common::Array<Breakpoint *> _breakpoints; + PublisherWArray _watches; + ScriptMonitor *_monitor; +public: + DebuggableScEngine(BaseGame *inGame); + void attachMonitor(ScriptMonitor *); + + friend class DebuggerController; + friend class DebuggableScript; + friend class ScScript; + friend class WatchableScriptArray; +}; + +} // 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 44fd117e61..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<DebuggableScEngine*>(_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)) { @@ -1434,18 +1447,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) { @@ -1466,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 1edeae5b55..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<int> _breakpoints; @@ -50,7 +53,7 @@ public: bool copyParameters(ScStack *stack); void afterLoad(); -private: +protected: ScValue *_operand; ScValue *_reg1; public: @@ -125,7 +128,7 @@ public: ScValue *_globals; ScEngine *_engine; int32 _currentLine; - bool executeInstruction(); + virtual bool executeInstruction(); char *getString(); uint32 getDWORD(); double getFloat(); @@ -162,11 +165,8 @@ private: bool initScript(); bool initTables(); - -// IWmeDebugScript interface implementation -public: - virtual int dbgGetLine(); - virtual const char *dbgGetFilename(); + 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<DebuggableScEngine*>(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); 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<int> _lines; - }; - public: bool clearGlobals(bool includingNatives = false); bool tickUnbreakable(); |