From e59340e191d94c6ad58c0d9c8554e24e54324536 Mon Sep 17 00:00:00 2001 From: Walter van Niftrik Date: Sat, 4 Aug 2018 00:34:59 +0200 Subject: ADL: Add debug function to load commands from file --- engines/adl/adl.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++-- engines/adl/adl.h | 11 +++++- engines/adl/adl_v2.cpp | 19 ++++++++--- engines/adl/adl_v2.h | 7 ---- engines/adl/console.cpp | 38 +++++++++++++++++++++ engines/adl/console.h | 3 ++ 6 files changed, 155 insertions(+), 14 deletions(-) (limited to 'engines') diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp index bf04860d14..f4f306aa8f 100644 --- a/engines/adl/adl.cpp +++ b/engines/adl/adl.cpp @@ -29,6 +29,7 @@ #include "common/events.h" #include "common/stream.h" #include "common/savefile.h" +#include "common/random.h" #include "engines/util.h" @@ -48,6 +49,8 @@ AdlEngine::~AdlEngine() { delete _graphics; delete _console; delete _dumpFile; + delete _inputScript; + delete _random; } AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) : @@ -62,6 +65,9 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) : _isQuitting(false), _abortScript(false), _gameDescription(gd), + _inputScript(nullptr), + _scriptDelay(1000), + _scriptPaused(false), _console(nullptr), _messageIds(), _saveVerb(0), @@ -71,6 +77,7 @@ AdlEngine::AdlEngine(OSystem *syst, const AdlGameDescription *gd) : _canSaveNow(false), _canRestoreNow(false) { + _random = new Common::RandomSource("adl"); DebugMan.addDebugChannel(kDebugChannelScript, "Script", "Trace script execution"); } @@ -139,6 +146,9 @@ Common::String AdlEngine::getItemDescription(const Item &item) const { } void AdlEngine::delay(uint32 ms) const { + if (_inputScript && !_scriptPaused) + return; + uint32 now = g_system->getMillis(); const uint32 end = now + ms; @@ -159,8 +169,36 @@ Common::String AdlEngine::inputString(byte prompt) const { while (1) { byte b = inputKey(); + if (_inputScript) { + // If debug script is active, read input line from file + Common::String line(getScriptLine()); + + // Debug script terminated, go back to keyboard input + if (line.empty()) + continue; + + line += '\r'; + + Common::String native; + + for (uint i = 0; i < line.size(); ++i) + native += APPLECHAR(line[i]); + + _display->printString(native); + // Set pause flag to activate regular behaviour of delay and inputKey + _scriptPaused = true; + + if (_scriptDelay > 0) + delay(_scriptDelay); + else + inputKey(); + + _scriptPaused = false; + return native; + } + if (shouldQuit() || _isRestoring) - return 0; + return Common::String(); if (b == 0) continue; @@ -193,6 +231,10 @@ Common::String AdlEngine::inputString(byte prompt) const { byte AdlEngine::inputKey(bool showCursor) const { byte key = 0; + // If debug script is active, we fake a return press for the text overflow handling + if (_inputScript && !_scriptPaused) + return APPLECHAR('\r'); + if (showCursor) _display->showCursor(true); @@ -213,6 +255,10 @@ byte AdlEngine::inputKey(bool showCursor) const { }; } + // If debug script was activated in the meantime, abort input + if (_inputScript && !_scriptPaused) + return APPLECHAR('\r'); + _display->updateTextScreen(); g_system->delayMillis(16); } @@ -481,6 +527,9 @@ void AdlEngine::bell(uint count) const { } bool AdlEngine::playTones(const Tones &tones, bool isMusic, bool allowSkip) const { + if (_inputScript && !_scriptPaused) + return false; + Audio::SoundHandle handle; Audio::AudioStream *stream = new Sound(tones); @@ -721,6 +770,44 @@ bool AdlEngine::hasFeature(EngineFeature f) const { } } +Common::String AdlEngine::getScriptLine() const { + Common::String line; + + do { + line = _inputScript->readLine(); + + if (_inputScript->eos() || _inputScript->err()) { + stopScript(); + return Common::String(); + } + + line.trim(); + } while (line.size() == 0 || line.firstChar() == ';'); + + return line; +} + +void AdlEngine::runScript(const char *filename) const { + // Debug functionality to read input from a text file + _inputScript = new Common::File; + if (!_inputScript->open(filename)) { + stopScript(); + return; + } + + Common::String line(getScriptLine()); + + if (!line.empty()) { + // Read random seed + _random->setSeed((uint32)line.asUint64()); + } +} + +void AdlEngine::stopScript() const { + delete _inputScript; + _inputScript = nullptr; +} + void AdlEngine::loadState(Common::ReadStream &stream) { _state.room = stream.readByte(); _state.moves = stream.readByte(); @@ -935,7 +1022,7 @@ Common::String AdlEngine::getLine() { Common::String line = inputString(APPLECHAR('?')); if (shouldQuit() || _isRestoring) - return ""; + return Common::String(); if ((byte)line[0] == ('\r' | 0x80)) { _textMode = !_textMode; diff --git a/engines/adl/adl.h b/engines/adl/adl.h index d53cf5a67c..5de53ca02f 100644 --- a/engines/adl/adl.h +++ b/engines/adl/adl.h @@ -48,6 +48,7 @@ class WriteStream; class SeekableReadStream; class File; struct Event; +class RandomSource; } namespace Adl { @@ -399,9 +400,14 @@ protected: bool _isRestarting, _isRestoring, _isQuitting; bool _canSaveNow, _canRestoreNow; bool _abortScript; + Common::RandomSource *_random; const AdlGameDescription *_gameDescription; + mutable Common::File *_inputScript; + mutable uint _scriptDelay; + mutable bool _scriptPaused; + private: virtual void runIntro() { } virtual void init() = 0; @@ -411,7 +417,10 @@ private: virtual void loadRoom(byte roomNr) = 0; virtual void showRoom() = 0; virtual void switchRegion(byte region) { } - + void runScript(const char *filename) const; + void stopScript() const; + void setScriptDelay(uint delay) const { _scriptDelay = delay; } + Common::String getScriptLine() const; // Engine Common::Error run(); bool hasFeature(EngineFeature f) const; diff --git a/engines/adl/adl_v2.cpp b/engines/adl/adl_v2.cpp index 4eb12c339f..4089ab3e30 100644 --- a/engines/adl/adl_v2.cpp +++ b/engines/adl/adl_v2.cpp @@ -31,7 +31,6 @@ namespace Adl { AdlEngine_v2::~AdlEngine_v2() { - delete _random; delete _disk; } @@ -43,9 +42,7 @@ AdlEngine_v2::AdlEngine_v2(OSystem *syst, const AdlGameDescription *gd) : _itemRemoved(false), _roomOnScreen(0), _picOnScreen(0), - _itemsOnScreen(0) { - _random = new Common::RandomSource("adl"); -} + _itemsOnScreen(0) { } void AdlEngine_v2::insertDisk(byte volume) { delete _disk; @@ -170,6 +167,20 @@ void AdlEngine_v2::checkTextOverflow(char c) { void AdlEngine_v2::handleTextOverflow() { _linesPrinted = 0; _display->updateTextScreen(); + + if (_inputScript) { + // Set pause flag to activate regular behaviour of delay and inputKey + _scriptPaused = true; + + if (_scriptDelay > 0) + delay(_scriptDelay); + else + inputKey(); + + _scriptPaused = false; + return; + } + bell(); while (true) { diff --git a/engines/adl/adl_v2.h b/engines/adl/adl_v2.h index 1b4ee4ddd2..861694a434 100644 --- a/engines/adl/adl_v2.h +++ b/engines/adl/adl_v2.h @@ -25,10 +25,6 @@ #include "adl/adl.h" -namespace Common { -class RandomSource; -} - namespace Adl { class AdlEngine_v2 : public AdlEngine { @@ -97,9 +93,6 @@ protected: bool _itemRemoved; byte _roomOnScreen, _picOnScreen, _itemsOnScreen; Common::Array _brokenRooms; - -private: - Common::RandomSource *_random; }; } // End of namespace Adl diff --git a/engines/adl/console.cpp b/engines/adl/console.cpp index e1242fa64f..527a575198 100644 --- a/engines/adl/console.cpp +++ b/engines/adl/console.cpp @@ -44,6 +44,9 @@ Console::Console(AdlEngine *engine) : GUI::Debugger() { registerCmd("vars", WRAP_METHOD(Console, Cmd_Vars)); registerCmd("var", WRAP_METHOD(Console, Cmd_Var)); registerCmd("convert_disk", WRAP_METHOD(Console, Cmd_ConvertDisk)); + registerCmd("run_script", WRAP_METHOD(Console, Cmd_RunScript)); + registerCmd("stop_script", WRAP_METHOD(Console, Cmd_StopScript)); + registerCmd("set_script_delay", WRAP_METHOD(Console, Cmd_SetScriptDelay)); } Common::String Console::toAscii(const Common::String &str) { @@ -423,4 +426,39 @@ bool Console::Cmd_ConvertDisk(int argc, const char **argv) { return true; } +bool Console::Cmd_RunScript(int argc, const char **argv) { + if (argc != 2) { + debugPrintf("Usage: %s \n", argv[0]); + return true; + } + + _engine->runScript(argv[1]); + + return false; +} + +bool Console::Cmd_StopScript(int argc, const char **argv) { + if (argc != 1) { + debugPrintf("Usage: %s\n", argv[0]); + return true; + } + + _engine->stopScript(); + + return true; +} + +bool Console::Cmd_SetScriptDelay(int argc, const char **argv) { + if (argc != 2) { + debugPrintf("Usage: %s \n", argv[0]); + debugPrintf("A delay of zero indicates wait-for-key\n"); + return true; + } + + Common::String value(argv[1]); + _engine->setScriptDelay((uint)value.asUint64()); + + return true; +} + } // End of namespace Adl diff --git a/engines/adl/console.h b/engines/adl/console.h index 338fc42147..db2e8ca0bf 100644 --- a/engines/adl/console.h +++ b/engines/adl/console.h @@ -55,6 +55,9 @@ private: bool Cmd_Vars(int argc, const char **argv); bool Cmd_Var(int argc, const char **argv); bool Cmd_ConvertDisk(int argc, const char **argv); + bool Cmd_RunScript(int argc, const char **argv); + bool Cmd_StopScript(int argc, const char **argv); + bool Cmd_SetScriptDelay(int argc, const char **argv); void printItem(const Item &item); void printWordMap(const Common::HashMap &wordMap); -- cgit v1.2.3