Merge branch 'scriptconsole'

actorid
Marc Zinnschlag 13 years ago
commit db10baafe1

@ -39,7 +39,7 @@ add_openmw_dir (mwscript
locals scriptmanager compilercontext interpretercontext cellextensions miscextensions
guiextensions soundextensions skyextensions statsextensions containerextensions
aiextensions controlextensions extensions globalscripts ref dialogueextensions
animationextensions transformationextensions
animationextensions transformationextensions consoleextensions userextensions
)
add_openmw_dir (mwsound

@ -129,6 +129,7 @@ OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
, mCompileAll (false)
, mScriptContext (0)
, mFSStrict (false)
, mScriptConsoleMode (false)
, mCfgMgr(configurationManager)
{
std::srand ( std::time(NULL) );
@ -326,7 +327,8 @@ void OMW::Engine::go()
MWScript::registerExtensions (mExtensions);
mEnvironment.setWindowManager (new MWGui::WindowManager(
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/")));
mExtensions, mFpsLevel, mNewGame, mOgre, mCfgMgr.getLogPath().string() + std::string("/"),
mScriptConsoleMode));
// Create sound system
mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound));
@ -388,6 +390,9 @@ void OMW::Engine::go()
<< std::endl;
}
if (!mStartupScript.empty())
MWBase::Environment::get().getWindowManager()->executeInConsole (mStartupScript);
// Start the main rendering loop
mOgre->start();
@ -490,3 +495,13 @@ void OMW::Engine::setFallbackValues(std::map<std::string,std::string> fallbackMa
{
mFallbackMap = fallbackMap;
}
void OMW::Engine::setScriptConsoleMode (bool enabled)
{
mScriptConsoleMode = enabled;
}
void OMW::Engine::setStartupScript (const std::string& path)
{
mStartupScript = path;
}

@ -73,6 +73,8 @@ namespace OMW
bool mCompileAll;
std::string mFocusName;
std::map<std::string,std::string> mFallbackMap;
bool mScriptConsoleMode;
std::string mStartupScript;
Compiler::Extensions mExtensions;
Compiler::Context *mScriptContext;
@ -158,6 +160,12 @@ namespace OMW
void setFallbackValues(std::map<std::string,std::string> map);
/// Enable console-only script functionality
void setScriptConsoleMode (bool enabled);
/// Set path for a script that is run on startup in the console.
void setStartupScript (const std::string& path);
private:
Files::ConfigurationManager& mCfgMgr;
};

@ -124,12 +124,20 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("script-verbose", bpo::value<bool>()->implicit_value(true)
->default_value(false), "verbose script output")
("new-game", bpo::value<bool>()->implicit_value(true)
->default_value(false), "activate char gen/new game mechanics")
("script-all", bpo::value<bool>()->implicit_value(true)
->default_value(false), "compile all scripts (excluding dialogue scripts) at startup")
("script-console", bpo::value<bool>()->implicit_value(true)
->default_value(false), "enable console-only script functionality")
("script-run", bpo::value<std::string>()->default_value(""),
"select a file that is executed in the console on startup\n\n"
"Note: The file contains a list of script lines, but not a complete scripts. "
"That means no begin/end and no variable declarations.")
("new-game", bpo::value<bool>()->implicit_value(true)
->default_value(false), "activate char gen/new game mechanics")
("fs-strict", bpo::value<bool>()->implicit_value(true)
->default_value(false), "strict file system handling (no case folding)")
@ -249,6 +257,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.setCompileAll(variables["script-all"].as<bool>());
engine.setAnimationVerbose(variables["anim-verbose"].as<bool>());
engine.setFallbackValues(variables["fallback"].as<FallbackMap>().mMap);
engine.setScriptConsoleMode (variables["script-console"].as<bool>());
engine.setStartupScript (variables["script-run"].as<std::string>());
return true;
}

@ -2,6 +2,7 @@
#include "console.hpp"
#include <algorithm>
#include <fstream>
#include <components/esm_store/reclists.hpp>
#include <components/esm_store/store.hpp>
@ -105,9 +106,10 @@ namespace MWGui
}
}
Console::Console(int w, int h, const Compiler::Extensions& extensions)
Console::Console(int w, int h, bool consoleOnlyScripts)
: Layout("openmw_console.layout"),
mCompilerContext (MWScript::CompilerContext::Type_Console)
mCompilerContext (MWScript::CompilerContext::Type_Console),
mConsoleOnlyScripts (consoleOnlyScripts)
{
setCoord(10,10, w-10, h/2);
@ -126,7 +128,8 @@ namespace MWGui
history->setVisibleVScroll(true);
// compiler
mCompilerContext.setExtensions (&extensions);
MWScript::registerExtensions (mExtensions, mConsoleOnlyScripts);
mCompilerContext.setExtensions (&mExtensions);
}
void Console::enable()
@ -173,6 +176,47 @@ namespace MWGui
print("#FF2222" + msg + "\n");
}
void Console::execute (const std::string& command)
{
// Log the command
print("#FFFFFF> " + command + "\n");
Compiler::Locals locals;
Compiler::Output output (locals);
if (compile (command + "\n", output))
{
try
{
ConsoleInterpreterContext interpreterContext (*this, mPtr);
Interpreter::Interpreter interpreter;
MWScript::installOpcodes (interpreter, mConsoleOnlyScripts);
std::vector<Interpreter::Type_Code> code;
output.getCode (code);
interpreter.run (&code[0], code.size(), interpreterContext);
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
}
}
}
void Console::executeFile (const std::string& path)
{
std::ifstream stream (path.c_str());
if (!stream.is_open())
printError ("failed to open file: " + path);
else
{
std::string line;
while (std::getline (stream, line))
execute (line);
}
}
void Console::keyPress(MyGUI::WidgetPtr _sender,
MyGUI::KeyCode key,
MyGUI::Char _char)
@ -234,28 +278,7 @@ namespace MWGui
current = command_history.end();
editString.clear();
// Log the command
print("#FFFFFF> " + cm + "\n");
Compiler::Locals locals;
Compiler::Output output (locals);
if (compile (cm + "\n", output))
{
try
{
ConsoleInterpreterContext interpreterContext (*this, mPtr);
Interpreter::Interpreter interpreter;
MWScript::installOpcodes (interpreter);
std::vector<Interpreter::Type_Code> code;
output.getCode (code);
interpreter.run (&code[0], code.size(), interpreterContext);
}
catch (const std::exception& error)
{
printError (std::string ("An exception has been thrown: ") + error.what());
}
}
execute (cm);
command->setCaption("");
}

@ -11,6 +11,7 @@
#include <components/compiler/scanner.hpp>
#include <components/compiler/locals.hpp>
#include <components/compiler/output.hpp>
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include "../mwscript/compilercontext.hpp"
@ -24,8 +25,10 @@ namespace MWGui
{
private:
Compiler::Extensions mExtensions;
MWScript::CompilerContext mCompilerContext;
std::vector<std::string> mNames;
bool mConsoleOnlyScripts;
bool compile (const std::string& cmd, Compiler::Output& output);
@ -62,7 +65,7 @@ namespace MWGui
StringList::iterator current;
std::string editString;
Console(int w, int h, const Compiler::Extensions& extensions);
Console(int w, int h, bool consoleOnlyScripts);
void enable();
@ -86,6 +89,10 @@ namespace MWGui
/// Error message
void printError(const std::string &msg);
void execute (const std::string& command);
void executeFile (const std::string& command);
private:
void keyPress(MyGUI::WidgetPtr _sender,

@ -41,7 +41,7 @@
using namespace MWGui;
WindowManager::WindowManager(
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath)
const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, bool consoleOnlyScripts)
: mGuiManager(NULL)
, mHud(NULL)
, mMap(NULL)
@ -113,7 +113,7 @@ WindowManager::WindowManager(
mMenu = new MainMenu(w,h);
mMap = new MapWindow(*this);
mStatsWindow = new StatsWindow(*this);
mConsole = new Console(w,h, extensions);
mConsole = new Console(w,h, consoleOnlyScripts);
mJournal = new JournalWindow(*this);
mMessageBoxManager = new MessageBoxManager(this);
mInventoryWindow = new InventoryWindow(*this,mDragAndDrop);
@ -740,3 +740,8 @@ bool WindowManager::getWorldMouseOver()
{
return mHud->getWorldMouseOver();
}
void WindowManager::executeInConsole (const std::string& path)
{
mConsole->executeFile (path);
}

@ -94,7 +94,7 @@ namespace MWGui
typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList;
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath);
WindowManager(const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, const std::string& logpath, bool consoleOnlyScripts);
virtual ~WindowManager();
/**
@ -237,6 +237,8 @@ namespace MWGui
void processChangedSettings(const Settings::CategorySettingVector& changed);
void executeInConsole (const std::string& path);
private:
OEngine::GUI::MyGUIManager *mGuiManager;
HUD *mHud;

@ -0,0 +1,24 @@
#include "consoleextensions.hpp"
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
namespace MWScript
{
namespace Console
{
void registerExtensions (Compiler::Extensions& extensions)
{
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
}
}
}

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_CONSOLEEXTENSIONS_H
#define GAME_SCRIPT_CONSOLEEXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief Script functionality limited to the console
namespace Console
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

@ -169,5 +169,14 @@ op 0x2000164: SetScale
op 0x2000165: SetScale, explicit reference
op 0x2000166: SetAngle
op 0x2000167: SetAngle, explicit reference
opcodes 0x2000168-0x3ffffff unused
op 0x2000168: GetScale
op 0x2000169: GetScale, explicit reference
op 0x200016a: GetAngle
op 0x200016b: GetAngle, explicit reference
op 0x200016c: user1 (console only, requires --script-console switch)
op 0x200016d: user2 (console only, requires --script-console switch)
op 0x200016e: user3, explicit reference (console only, requires --script-console switch)
op 0x200016f: user3 (implicit reference, console only, requires --script-console switch)
op 0x2000170: user4, explicit reference (console only, requires --script-console switch)
op 0x2000171: user4 (implicit reference, console only, requires --script-console switch)
opcodes 0x2000172-0x3ffffff unused

@ -16,10 +16,12 @@
#include "dialogueextensions.hpp"
#include "animationextensions.hpp"
#include "transformationextensions.hpp"
#include "consoleextensions.hpp"
#include "userextensions.hpp"
namespace MWScript
{
void registerExtensions (Compiler::Extensions& extensions)
void registerExtensions (Compiler::Extensions& extensions, bool consoleOnly)
{
Cell::registerExtensions (extensions);
Misc::registerExtensions (extensions);
@ -33,9 +35,15 @@ namespace MWScript
Dialogue::registerExtensions (extensions);
Animation::registerExtensions (extensions);
Transformation::registerExtensions (extensions);
if (consoleOnly)
{
Console::registerExtensions (extensions);
User::registerExtensions (extensions);
}
}
void installOpcodes (Interpreter::Interpreter& interpreter)
void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly)
{
Interpreter::installOpcodes (interpreter);
Cell::installOpcodes (interpreter);
@ -50,5 +58,11 @@ namespace MWScript
Dialogue::installOpcodes (interpreter);
Animation::installOpcodes (interpreter);
Transformation::installOpcodes (interpreter);
if (consoleOnly)
{
Console::installOpcodes (interpreter);
User::installOpcodes (interpreter);
}
}
}

@ -13,9 +13,11 @@ namespace Interpreter
namespace MWScript
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
void registerExtensions (Compiler::Extensions& extensions, bool consoleOnly = false);
///< \param consoleOnly include console only extensions
void installOpcodes (Interpreter::Interpreter& interpreter, bool consoleOnly = false);
///< \param consoleOnly include console only opcodes
}
#endif

@ -0,0 +1,91 @@
#include "userextensions.hpp"
#include <components/compiler/extensions.hpp>
#include <components/interpreter/interpreter.hpp>
#include <components/interpreter/runtime.hpp>
#include <components/interpreter/opcodes.hpp>
#include <components/interpreter/context.hpp>
#include "ref.hpp"
namespace MWScript
{
/// Temporary script extensions.
///
/// \attention Do not commit changes to this file to a git repository!
namespace User
{
class OpUser1 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.getContext().report ("user1: not in use");
}
};
class OpUser2 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
runtime.getContext().report ("user2: not in use");
}
};
template<class R>
class OpUser3 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
// MWWorld::Ptr ptr = R()(runtime);
runtime.getContext().report ("user3: not in use");
}
};
template<class R>
class OpUser4 : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
// MWWorld::Ptr ptr = R()(runtime);
runtime.getContext().report ("user4: not in use");
}
};
const int opcodeUser1 = 0x200016c;
const int opcodeUser2 = 0x200016d;
const int opcodeUser3 = 0x200016e;
const int opcodeUser3Explicit = 0x200016f;
const int opcodeUser4 = 0x2000170;
const int opcodeUser4Explicit = 0x2000171;
void registerExtensions (Compiler::Extensions& extensions)
{
extensions.registerInstruction ("user1", "", opcodeUser1);
extensions.registerInstruction ("user2", "", opcodeUser2);
extensions.registerInstruction ("user3", "", opcodeUser3, opcodeUser3);
extensions.registerInstruction ("user4", "", opcodeUser4, opcodeUser4);
}
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (opcodeUser1, new OpUser1);
interpreter.installSegment5 (opcodeUser2, new OpUser2);
interpreter.installSegment5 (opcodeUser3, new OpUser3<ImplicitRef>);
interpreter.installSegment5 (opcodeUser3Explicit, new OpUser3<ExplicitRef>);
interpreter.installSegment5 (opcodeUser4, new OpUser4<ImplicitRef>);
interpreter.installSegment5 (opcodeUser4Explicit, new OpUser4<ExplicitRef>);
}
}
}

@ -0,0 +1,25 @@
#ifndef GAME_SCRIPT_USEREXTENSIONS_H
#define GAME_SCRIPT_USEREXTENSIONS_H
namespace Compiler
{
class Extensions;
}
namespace Interpreter
{
class Interpreter;
}
namespace MWScript
{
/// \brief Temporaty script functionality limited to the console
namespace User
{
void registerExtensions (Compiler::Extensions& extensions);
void installOpcodes (Interpreter::Interpreter& interpreter);
}
}
#endif

@ -66,9 +66,16 @@ Allowed options:
--debug [=arg(=1)] (=0) debug mode
--nosound [=arg(=1)] (=0) disable all sounds
--script-verbose [=arg(=1)] (=0) verbose script output
--new-game [=arg(=1)] (=0) activate char gen/new game mechanics
--script-all [=arg(=1)] (=0) compile all scripts (excluding dialogue scri
pts) at startup
--script-console [=arg(=1)] (=0) enable console-only script functionality
--script-run arg select a file that is executed in the consol
e on startup
Note: The file contains a list of script
lines, but not a complete scripts. That mean
s no begin/end and no variable declarations.
--new-game [=arg(=1)] (=0) activate char gen/new game mechanics
--fs-strict [=arg(=1)] (=0) strict file system handling (no case folding
)
--encoding arg (=win1252) Character encoding used in OpenMW game messa

Loading…
Cancel
Save