forked from mirror/openmw-tes3mp
Merge branch 'master' of http://github.com/zinnschlag/openmw
This commit is contained in:
commit
ff64c1fbf0
15 changed files with 449 additions and 135 deletions
|
@ -37,6 +37,7 @@ set(GAMEGUI_HEADER
|
||||||
)
|
)
|
||||||
set(GAMEGUI
|
set(GAMEGUI
|
||||||
mwgui/window_manager.cpp
|
mwgui/window_manager.cpp
|
||||||
|
mwgui/console.cpp
|
||||||
)
|
)
|
||||||
source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI})
|
source_group(apps\\openmw\\mwgui FILES ${GAMEGUI_HEADER} ${GAMEGUI})
|
||||||
|
|
||||||
|
@ -87,9 +88,9 @@ set(GAMEWORLD_HEADER
|
||||||
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
source_group(apps\\openmw\\mwworld FILES ${GAMEWORLD} ${GAMEWORLD_HEADER})
|
||||||
|
|
||||||
|
|
||||||
set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD} ${GAMEGUI})
|
set(OPENMW_CPP ${GAME} ${GAMEREND} ${GAMEINPUT} ${GAMESCRIPT} ${GAMESOUND} ${GAMEGUI} ${GAMEWORLD})
|
||||||
set(OPENMW_HEADER ${GAME_HEADER} ${GAMEREND_HEADER} ${GAMEINPUT_HEADER} ${GAMESCRIPT_HEADER}
|
set(OPENMW_HEADER ${GAME_HEADER} ${GAMEREND_HEADER} ${GAMEINPUT_HEADER} ${GAMESCRIPT_HEADER}
|
||||||
${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER} ${GAMEGUI_HEADER})
|
${GAMESOUND_HEADER} ${GAMEGUI_HEADER} ${GAMEWORLD_HEADER})
|
||||||
|
|
||||||
# Main executable
|
# Main executable
|
||||||
add_executable(openmw
|
add_executable(openmw
|
||||||
|
|
|
@ -51,8 +51,10 @@ bool OMW::Engine::frameStarted(const Ogre::FrameEvent& evt)
|
||||||
// global scripts
|
// global scripts
|
||||||
mEnvironment.mGlobalScripts->run (mEnvironment);
|
mEnvironment.mGlobalScripts->run (mEnvironment);
|
||||||
|
|
||||||
// passing of time (30 times as fast as RL time)
|
// passing of time
|
||||||
mEnvironment.mWorld->advanceTime ((mEnvironment.mFrameDuration*30)/3600);
|
if (mEnvironment.mWindowManager->getMode()==MWGui::GM_Game)
|
||||||
|
mEnvironment.mWorld->advanceTime (
|
||||||
|
mEnvironment.mFrameDuration*mEnvironment.mWorld->getTimeScaleFactor()/3600);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -206,12 +208,13 @@ void OMW::Engine::go()
|
||||||
mOgre.getScene());
|
mOgre.getScene());
|
||||||
|
|
||||||
// Create window manager - this manages all the MW-specific GUI windows
|
// Create window manager - this manages all the MW-specific GUI windows
|
||||||
mEnvironment.mWindowManager = new MWGui::WindowManager(mGuiManager->getGui());
|
MWScript::registerExtensions (mExtensions);
|
||||||
|
|
||||||
|
mEnvironment.mWindowManager = new MWGui::WindowManager(mGuiManager->getGui(), mEnvironment,
|
||||||
|
mExtensions, mNewGame);
|
||||||
|
|
||||||
mEnvironment.mSoundManager = new MWSound::SoundManager;
|
mEnvironment.mSoundManager = new MWSound::SoundManager;
|
||||||
|
|
||||||
MWScript::registerExtensions (mExtensions);
|
|
||||||
|
|
||||||
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full,
|
mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full,
|
||||||
mEnvironment);
|
mEnvironment);
|
||||||
mScriptContext->setExtensions (&mExtensions);
|
mScriptContext->setExtensions (&mExtensions);
|
||||||
|
|
219
apps/openmw/mwgui/console.cpp
Normal file
219
apps/openmw/mwgui/console.cpp
Normal file
|
@ -0,0 +1,219 @@
|
||||||
|
|
||||||
|
#include "console.hpp"
|
||||||
|
|
||||||
|
#include <components/compiler/exception.hpp>
|
||||||
|
|
||||||
|
#include "../mwscript/extensions.hpp"
|
||||||
|
|
||||||
|
namespace MWGui
|
||||||
|
{
|
||||||
|
class ConsoleInterpreterContext : public MWScript::InterpreterContext
|
||||||
|
{
|
||||||
|
Console& mConsole;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ConsoleInterpreterContext (Console& console, MWWorld::Environment& environment,
|
||||||
|
MWWorld::Ptr reference);
|
||||||
|
|
||||||
|
virtual void messageBox (const std::string& message,
|
||||||
|
const std::vector<std::string>& buttons);
|
||||||
|
};
|
||||||
|
|
||||||
|
ConsoleInterpreterContext::ConsoleInterpreterContext (Console& console,
|
||||||
|
MWWorld::Environment& environment, MWWorld::Ptr reference)
|
||||||
|
: MWScript::InterpreterContext (environment,
|
||||||
|
reference.isEmpty() ? 0 : &reference.getRefData().getLocals(), reference),
|
||||||
|
mConsole (console)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void ConsoleInterpreterContext::messageBox (const std::string& message,
|
||||||
|
const std::vector<std::string>& buttons)
|
||||||
|
{
|
||||||
|
if (!buttons.empty())
|
||||||
|
mConsole.printError ("MessageBox doesn't support buttons while in console mode");
|
||||||
|
else
|
||||||
|
mConsole.printOK (message);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Console::compile (const std::string& cmd, Compiler::Output& output)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ErrorHandler::reset();
|
||||||
|
|
||||||
|
std::istringstream input (cmd + '\n');
|
||||||
|
|
||||||
|
Compiler::Scanner scanner (*this, input, mCompilerContext.getExtensions());
|
||||||
|
|
||||||
|
Compiler::LineParser parser (*this, mCompilerContext, output.getLocals(),
|
||||||
|
output.getLiterals(), output.getCode(), true);
|
||||||
|
|
||||||
|
scanner.scan (parser);
|
||||||
|
|
||||||
|
return isGood();
|
||||||
|
}
|
||||||
|
catch (const Compiler::SourceException& error)
|
||||||
|
{
|
||||||
|
// error has already been reported via error handler
|
||||||
|
}
|
||||||
|
catch (const std::exception& error)
|
||||||
|
{
|
||||||
|
printError (std::string ("An exception has been thrown: ") + error.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::report (const std::string& message, const Compiler::TokenLoc& loc, Type type)
|
||||||
|
{
|
||||||
|
std::ostringstream error;
|
||||||
|
error << "column " << loc.mColumn << " (" << loc.mLiteral << "):";
|
||||||
|
|
||||||
|
printError (error.str());
|
||||||
|
printError ((type==ErrorMessage ? "error: " : "warning: ") + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::report (const std::string& message, Type type)
|
||||||
|
{
|
||||||
|
printError ((type==ErrorMessage ? "error: " : "warning: ") + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
Console::Console(int w, int h, MWWorld::Environment& environment,
|
||||||
|
const Compiler::Extensions& extensions)
|
||||||
|
: Layout("openmw_console_layout.xml"),
|
||||||
|
mCompilerContext (MWScript::CompilerContext::Type_Console, environment),
|
||||||
|
mEnvironment (environment)
|
||||||
|
{
|
||||||
|
setCoord(10,10, w-10, h/2);
|
||||||
|
|
||||||
|
getWidget(command, "edit_Command");
|
||||||
|
getWidget(history, "list_History");
|
||||||
|
|
||||||
|
// Set up the command line box
|
||||||
|
command->eventEditSelectAccept =
|
||||||
|
newDelegate(this, &Console::acceptCommand);
|
||||||
|
command->eventKeyButtonPressed =
|
||||||
|
newDelegate(this, &Console::keyPress);
|
||||||
|
|
||||||
|
// Set up the log window
|
||||||
|
history->setOverflowToTheLeft(true);
|
||||||
|
history->setEditStatic(true);
|
||||||
|
history->setVisibleVScroll(true);
|
||||||
|
|
||||||
|
// compiler
|
||||||
|
mCompilerContext.setExtensions (&extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::enable()
|
||||||
|
{
|
||||||
|
setVisible(true);
|
||||||
|
|
||||||
|
// Give keyboard focus to the combo box whenever the console is
|
||||||
|
// turned on
|
||||||
|
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::disable()
|
||||||
|
{
|
||||||
|
setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::setFont(const std::string &fntName)
|
||||||
|
{
|
||||||
|
history->setFontName(fntName);
|
||||||
|
command->setFontName(fntName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::clearHistory()
|
||||||
|
{
|
||||||
|
history->setCaption("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::print(const std::string &msg)
|
||||||
|
{
|
||||||
|
history->addText(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::printOK(const std::string &msg)
|
||||||
|
{
|
||||||
|
print("#FF00FF" + msg + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::printError(const std::string &msg)
|
||||||
|
{
|
||||||
|
print("#FF2222" + msg + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::keyPress(MyGUI::WidgetPtr _sender,
|
||||||
|
MyGUI::KeyCode key,
|
||||||
|
MyGUI::Char _char)
|
||||||
|
{
|
||||||
|
if(command_history.empty()) return;
|
||||||
|
|
||||||
|
// Traverse history with up and down arrows
|
||||||
|
if(key == MyGUI::KeyCode::ArrowUp)
|
||||||
|
{
|
||||||
|
// If the user was editing a string, store it for later
|
||||||
|
if(current == command_history.end())
|
||||||
|
editString = command->getCaption();
|
||||||
|
|
||||||
|
if(current != command_history.begin())
|
||||||
|
{
|
||||||
|
current--;
|
||||||
|
command->setCaption(*current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(key == MyGUI::KeyCode::ArrowDown)
|
||||||
|
{
|
||||||
|
if(current != command_history.end())
|
||||||
|
{
|
||||||
|
current++;
|
||||||
|
|
||||||
|
if(current != command_history.end())
|
||||||
|
command->setCaption(*current);
|
||||||
|
else
|
||||||
|
// Restore the edit string
|
||||||
|
command->setCaption(editString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Console::acceptCommand(MyGUI::EditPtr _sender)
|
||||||
|
{
|
||||||
|
const std::string &cm = command->getCaption();
|
||||||
|
if(cm.empty()) return;
|
||||||
|
|
||||||
|
// Add the command to the history, and set the current pointer to
|
||||||
|
// the end of the list
|
||||||
|
command_history.push_back(cm);
|
||||||
|
current = command_history.end();
|
||||||
|
editString.clear();
|
||||||
|
|
||||||
|
// Log the command
|
||||||
|
print("#FFFFFF> " + cm + "\n");
|
||||||
|
|
||||||
|
Compiler::Locals locals;
|
||||||
|
Compiler::Output output (locals);
|
||||||
|
|
||||||
|
if (compile (cm, output))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ConsoleInterpreterContext interpreterContext (*this, mEnvironment, MWWorld::Ptr());
|
||||||
|
Interpreter::Interpreter interpreter (interpreterContext);
|
||||||
|
MWScript::installOpcodes (interpreter);
|
||||||
|
std::vector<Interpreter::Type_Code> code;
|
||||||
|
output.getCode (code);
|
||||||
|
interpreter.run (&code[0], code.size());
|
||||||
|
}
|
||||||
|
catch (const std::exception& error)
|
||||||
|
{
|
||||||
|
printError (std::string ("An exception has been thrown: ") + error.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
command->setCaption("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,11 +4,35 @@
|
||||||
#include <openengine/gui/layout.hpp>
|
#include <openengine/gui/layout.hpp>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <components/compiler/errorhandler.hpp>
|
||||||
|
#include <components/compiler/lineparser.hpp>
|
||||||
|
#include <components/compiler/scanner.hpp>
|
||||||
|
#include <components/compiler/locals.hpp>
|
||||||
|
#include <components/compiler/output.hpp>
|
||||||
|
#include <components/interpreter/interpreter.hpp>
|
||||||
|
|
||||||
|
#include "../mwscript/compilercontext.hpp"
|
||||||
|
#include "../mwscript/interpretercontext.hpp"
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class Console : private OEngine::GUI::Layout
|
class Console : private OEngine::GUI::Layout, private Compiler::ErrorHandler
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
MWScript::CompilerContext mCompilerContext;
|
||||||
|
MWWorld::Environment& mEnvironment;
|
||||||
|
|
||||||
|
bool compile (const std::string& cmd, Compiler::Output& output);
|
||||||
|
|
||||||
|
/// Report error to the user.
|
||||||
|
virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type);
|
||||||
|
|
||||||
|
/// Report a file related error
|
||||||
|
virtual void report (const std::string& message, Type type);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MyGUI::EditPtr command;
|
MyGUI::EditPtr command;
|
||||||
MyGUI::EditPtr history;
|
MyGUI::EditPtr history;
|
||||||
|
@ -20,127 +44,35 @@ namespace MWGui
|
||||||
StringList::iterator current;
|
StringList::iterator current;
|
||||||
std::string editString;
|
std::string editString;
|
||||||
|
|
||||||
Console(int w, int h)
|
Console(int w, int h, MWWorld::Environment& environment, const Compiler::Extensions& extensions);
|
||||||
: Layout("openmw_console_layout.xml")
|
|
||||||
{
|
|
||||||
setCoord(10,10, w-10, h/2);
|
|
||||||
|
|
||||||
getWidget(command, "edit_Command");
|
void enable();
|
||||||
getWidget(history, "list_History");
|
|
||||||
|
|
||||||
// Set up the command line box
|
void disable();
|
||||||
command->eventEditSelectAccept =
|
|
||||||
newDelegate(this, &Console::acceptCommand);
|
|
||||||
command->eventKeyButtonPressed =
|
|
||||||
newDelegate(this, &Console::keyPress);
|
|
||||||
|
|
||||||
// Set up the log window
|
void setFont(const std::string &fntName);
|
||||||
history->setOverflowToTheLeft(true);
|
|
||||||
history->setEditStatic(true);
|
|
||||||
history->setVisibleVScroll(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void enable()
|
void clearHistory();
|
||||||
{
|
|
||||||
setVisible(true);
|
|
||||||
|
|
||||||
// Give keyboard focus to the combo box whenever the console is
|
|
||||||
// turned on
|
|
||||||
MyGUI::InputManager::getInstance().setKeyFocusWidget(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disable()
|
|
||||||
{
|
|
||||||
setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFont(const std::string &fntName)
|
|
||||||
{
|
|
||||||
history->setFontName(fntName);
|
|
||||||
command->setFontName(fntName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearHistory()
|
|
||||||
{
|
|
||||||
history->setCaption("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print a message to the console. Messages may contain color
|
// Print a message to the console. Messages may contain color
|
||||||
// code, eg. "#FFFFFF this is white".
|
// code, eg. "#FFFFFF this is white".
|
||||||
void print(const std::string &msg)
|
void print(const std::string &msg);
|
||||||
{ history->addText(msg); }
|
|
||||||
|
|
||||||
// These are pre-colored versions that you should use.
|
// These are pre-colored versions that you should use.
|
||||||
|
|
||||||
/// Output from successful console command
|
/// Output from successful console command
|
||||||
void printOK(const std::string &msg)
|
void printOK(const std::string &msg);
|
||||||
{ print("#FF00FF" + msg + "\n"); }
|
|
||||||
|
|
||||||
/// Error message
|
/// Error message
|
||||||
void printError(const std::string &msg)
|
void printError(const std::string &msg);
|
||||||
{ print("#FF2222" + msg + "\n"); }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void keyPress(MyGUI::WidgetPtr _sender,
|
void keyPress(MyGUI::WidgetPtr _sender,
|
||||||
MyGUI::KeyCode key,
|
MyGUI::KeyCode key,
|
||||||
MyGUI::Char _char)
|
MyGUI::Char _char);
|
||||||
{
|
|
||||||
if(command_history.empty()) return;
|
|
||||||
|
|
||||||
// Traverse history with up and down arrows
|
void acceptCommand(MyGUI::EditPtr _sender);
|
||||||
if(key == MyGUI::KeyCode::ArrowUp)
|
|
||||||
{
|
|
||||||
// If the user was editing a string, store it for later
|
|
||||||
if(current == command_history.end())
|
|
||||||
editString = command->getCaption();
|
|
||||||
|
|
||||||
if(current != command_history.begin())
|
|
||||||
{
|
|
||||||
current--;
|
|
||||||
command->setCaption(*current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(key == MyGUI::KeyCode::ArrowDown)
|
|
||||||
{
|
|
||||||
if(current != command_history.end())
|
|
||||||
{
|
|
||||||
current++;
|
|
||||||
|
|
||||||
if(current != command_history.end())
|
|
||||||
command->setCaption(*current);
|
|
||||||
else
|
|
||||||
// Restore the edit string
|
|
||||||
command->setCaption(editString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void acceptCommand(MyGUI::EditPtr _sender)
|
|
||||||
{
|
|
||||||
const std::string &cm = command->getCaption();
|
|
||||||
if(cm.empty()) return;
|
|
||||||
|
|
||||||
// Add the command to the history, and set the current pointer to
|
|
||||||
// the end of the list
|
|
||||||
command_history.push_back(cm);
|
|
||||||
current = command_history.end();
|
|
||||||
editString.clear();
|
|
||||||
|
|
||||||
// Log the command
|
|
||||||
print("#FFFFFF> " + cm + "\n");
|
|
||||||
|
|
||||||
/* NOTE: This is where the console command should be
|
|
||||||
handled.
|
|
||||||
|
|
||||||
The console command is in the string 'cm'. Output from the
|
|
||||||
command should be put back into the console with the
|
|
||||||
printOK() or printError() functions.
|
|
||||||
*/
|
|
||||||
printOK("OK - echoing line " + cm);
|
|
||||||
|
|
||||||
command->setCaption("");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
|
|
||||||
using namespace MWGui;
|
using namespace MWGui;
|
||||||
|
|
||||||
WindowManager::WindowManager(MyGUI::Gui *_gui)
|
WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment,
|
||||||
: gui(_gui), mode(GM_Game), shown(GW_ALL), allowed(GW_ALL)
|
const Compiler::Extensions& extensions, bool newGame)
|
||||||
|
: gui(_gui), mode(GM_Game), shown(GW_ALL), allowed(newGame ? GW_None : GW_ALL)
|
||||||
{
|
{
|
||||||
// Get size info from the Gui object
|
// Get size info from the Gui object
|
||||||
assert(gui);
|
assert(gui);
|
||||||
|
@ -19,7 +20,7 @@ WindowManager::WindowManager(MyGUI::Gui *_gui)
|
||||||
menu = new MainMenu(w,h);
|
menu = new MainMenu(w,h);
|
||||||
map = new MapWindow();
|
map = new MapWindow();
|
||||||
stats = new StatsWindow();
|
stats = new StatsWindow();
|
||||||
console = new Console(w,h);
|
console = new Console(w,h, environment, extensions);
|
||||||
|
|
||||||
// The HUD is always on
|
// The HUD is always on
|
||||||
hud->setVisible(true);
|
hud->setVisible(true);
|
||||||
|
|
|
@ -15,6 +15,16 @@ namespace MyGUI
|
||||||
class Gui;
|
class Gui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Compiler
|
||||||
|
{
|
||||||
|
class Extensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWWorld
|
||||||
|
{
|
||||||
|
class Environment;
|
||||||
|
}
|
||||||
|
|
||||||
namespace MWGui
|
namespace MWGui
|
||||||
{
|
{
|
||||||
class HUD;
|
class HUD;
|
||||||
|
@ -91,11 +101,15 @@ namespace MWGui
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The constructor needs the main Gui object
|
/// The constructor needs the main Gui object
|
||||||
WindowManager(MyGUI::Gui *_gui);
|
WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment,
|
||||||
|
const Compiler::Extensions& extensions, bool newGame);
|
||||||
virtual ~WindowManager();
|
virtual ~WindowManager();
|
||||||
|
|
||||||
void setMode(GuiMode newMode)
|
void setMode(GuiMode newMode)
|
||||||
{
|
{
|
||||||
|
if (newMode==GM_Inventory && allowed==GW_None)
|
||||||
|
return;
|
||||||
|
|
||||||
mode = newMode;
|
mode = newMode;
|
||||||
updateVisible();
|
updateVisible();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,19 +17,7 @@ namespace MWScript
|
||||||
|
|
||||||
char CompilerContext::getGlobalType (const std::string& name) const
|
char CompilerContext::getGlobalType (const std::string& name) const
|
||||||
{
|
{
|
||||||
if (const ESM::Global *global = mEnvironment.mWorld->getStore().globals.find (name))
|
return mEnvironment.mWorld->getGlobalVariableType (name);
|
||||||
{
|
|
||||||
switch (global->type)
|
|
||||||
{
|
|
||||||
case ESM::VT_Short: return 's';
|
|
||||||
case ESM::VT_Int: return 'l';
|
|
||||||
case ESM::VT_Float: return 'f';
|
|
||||||
|
|
||||||
default: return ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ' ';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CompilerContext::isId (const std::string& name) const
|
bool CompilerContext::isId (const std::string& name) const
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace MWWorld
|
||||||
case ESM::VT_Short:
|
case ESM::VT_Short:
|
||||||
|
|
||||||
type = 's';
|
type = 's';
|
||||||
value.mShort = *reinterpret_cast<const Interpreter::Type_Integer *> (
|
value.mShort = *reinterpret_cast<const Interpreter::Type_Float *> (
|
||||||
&iter->second.value);
|
&iter->second.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -145,5 +145,15 @@ namespace MWWorld
|
||||||
default: throw std::runtime_error ("unsupported global variable type");
|
default: throw std::runtime_error ("unsupported global variable type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char Globals::getType (const std::string& name) const
|
||||||
|
{
|
||||||
|
Collection::const_iterator iter = mVariables.find (name);
|
||||||
|
|
||||||
|
if (iter==mVariables.end())
|
||||||
|
return ' ';
|
||||||
|
|
||||||
|
return iter->second.first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
Interpreter::Type_Float mFloat;
|
Interpreter::Type_Float mFloat;
|
||||||
Interpreter::Type_Float mLong; // Why Morrowind, why? :(
|
Interpreter::Type_Float mLong; // Why Morrowind, why? :(
|
||||||
Interpreter::Type_Integer mShort;
|
Interpreter::Type_Float mShort;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<std::string, std::pair<char, Data> > Collection;
|
typedef std::map<std::string, std::pair<char, Data> > Collection;
|
||||||
|
@ -53,6 +53,9 @@ namespace MWWorld
|
||||||
|
|
||||||
float getFloat (const std::string& name) const;
|
float getFloat (const std::string& name) const;
|
||||||
///< Get value independently from real type.
|
///< Get value independently from real type.
|
||||||
|
|
||||||
|
char getType (const std::string& name) const;
|
||||||
|
///< If there is no global variable with this name, ' ' is returned.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,11 @@ namespace MWWorld
|
||||||
return (*mGlobalVariables)[name];
|
return (*mGlobalVariables)[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char World::getGlobalVariableType (const std::string& name) const
|
||||||
|
{
|
||||||
|
return mGlobalVariables->getType (name);
|
||||||
|
}
|
||||||
|
|
||||||
Ptr World::getPtr (const std::string& name, bool activeOnly)
|
Ptr World::getPtr (const std::string& name, bool activeOnly)
|
||||||
{
|
{
|
||||||
// the player is always in an active cell.
|
// the player is always in an active cell.
|
||||||
|
@ -358,4 +363,9 @@ namespace MWWorld
|
||||||
{
|
{
|
||||||
mSkyManager->setMoonColour (red);
|
mSkyManager->setMoonColour (red);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float World::getTimeScaleFactor() const
|
||||||
|
{
|
||||||
|
return mGlobalVariables->getInt ("timescale");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,9 @@ namespace MWWorld
|
||||||
|
|
||||||
Globals::Data& getGlobalVariable (const std::string& name);
|
Globals::Data& getGlobalVariable (const std::string& name);
|
||||||
|
|
||||||
|
char getGlobalVariableType (const std::string& name) const;
|
||||||
|
///< Return ' ', if there is no global variable with this name.
|
||||||
|
|
||||||
Ptr getPtr (const std::string& name, bool activeOnly);
|
Ptr getPtr (const std::string& name, bool activeOnly);
|
||||||
///< Return a pointer to a liveCellRef with the given name.
|
///< Return a pointer to a liveCellRef with the given name.
|
||||||
/// \param activeOnly do non search inactive cells.
|
/// \param activeOnly do non search inactive cells.
|
||||||
|
@ -103,6 +106,8 @@ namespace MWWorld
|
||||||
int getSecundaPhase() const;
|
int getSecundaPhase() const;
|
||||||
|
|
||||||
void setMoonColour (bool red);
|
void setMoonColour (bool red);
|
||||||
|
|
||||||
|
float getTimeScaleFactor() const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ namespace Compiler
|
||||||
|
|
||||||
class SourceException : public std::exception
|
class SourceException : public std::exception
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
virtual const char *what() const throw() { return "compile error";}
|
virtual const char *what() const throw() { return "compile error";}
|
||||||
///< Return error message
|
///< Return error message
|
||||||
};
|
};
|
||||||
|
@ -17,6 +19,8 @@ namespace Compiler
|
||||||
|
|
||||||
class FileException : public SourceException
|
class FileException : public SourceException
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
virtual const char *what() const throw() { return "can't read file"; }
|
virtual const char *what() const throw() { return "can't read file"; }
|
||||||
///< Return error message
|
///< Return error message
|
||||||
};
|
};
|
||||||
|
@ -24,7 +28,10 @@ namespace Compiler
|
||||||
/// \brief Exception: EOF condition encountered
|
/// \brief Exception: EOF condition encountered
|
||||||
|
|
||||||
class EOFException : public SourceException
|
class EOFException : public SourceException
|
||||||
{ virtual const char *what() const throw() { return "end of file"; }
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual const char *what() const throw() { return "end of file"; }
|
||||||
///< Return error message
|
///< Return error message
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,19 +11,67 @@
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
void LineParser::parseExpression (Scanner& scanner, const TokenLoc& loc)
|
||||||
|
{
|
||||||
|
mExprParser.reset();
|
||||||
|
|
||||||
|
if (!mExplicit.empty())
|
||||||
|
{
|
||||||
|
mExprParser.parseName (mExplicit, loc, scanner);
|
||||||
|
mExprParser.parseSpecial (Scanner::S_ref, loc, scanner);
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner.scan (mExprParser);
|
||||||
|
|
||||||
|
char type = mExprParser.append (mCode);
|
||||||
|
mState = EndState;
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
|
||||||
|
Generator::message (mCode, mLiterals, "%g", 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
|
||||||
|
Generator::message (mCode, mLiterals, "%f", 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
throw std::runtime_error ("unknown expression result type");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
LineParser::LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||||
Literals& literals, std::vector<Interpreter::Type_Code>& code)
|
Literals& literals, std::vector<Interpreter::Type_Code>& code, bool allowExpression)
|
||||||
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals), mCode (code),
|
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals), mCode (code),
|
||||||
mState (BeginState), mExprParser (errorHandler, context, locals, literals)
|
mState (BeginState), mExprParser (errorHandler, context, locals, literals),
|
||||||
|
mAllowExpression (allowExpression)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
bool LineParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||||
{
|
{
|
||||||
|
if (mAllowExpression && mState==BeginState)
|
||||||
|
{
|
||||||
|
scanner.putbackInt (value, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return Parser::parseInt (value, loc, scanner);
|
return Parser::parseInt (value, loc, scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LineParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
|
bool LineParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
|
||||||
{
|
{
|
||||||
|
if (mAllowExpression && mState==BeginState)
|
||||||
|
{
|
||||||
|
scanner.putbackFloat (value, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return Parser::parseFloat (value, loc, scanner);
|
return Parser::parseFloat (value, loc, scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +177,29 @@ namespace Compiler
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mState==BeginState && mAllowExpression)
|
||||||
|
{
|
||||||
|
std::string name2 = toLower (name);
|
||||||
|
|
||||||
|
char type = mLocals.getType (name2);
|
||||||
|
|
||||||
|
if (type!=' ')
|
||||||
|
{
|
||||||
|
scanner.putbackName (name, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = getContext().getGlobalType (name2);
|
||||||
|
|
||||||
|
if (type!=' ')
|
||||||
|
{
|
||||||
|
scanner.putbackName (name, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mState==BeginState && getContext().isId (name))
|
if (mState==BeginState && getContext().isId (name))
|
||||||
{
|
{
|
||||||
mState = PotentialExplicitState;
|
mState = PotentialExplicitState;
|
||||||
|
@ -172,6 +243,30 @@ namespace Compiler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mAllowExpression)
|
||||||
|
{
|
||||||
|
if (keyword==Scanner::K_getdisabled || keyword==Scanner::K_getdistance)
|
||||||
|
{
|
||||||
|
scanner.putbackKeyword (keyword, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const Extensions *extensions = getContext().getExtensions())
|
||||||
|
{
|
||||||
|
char returnType;
|
||||||
|
std::string argumentType;
|
||||||
|
|
||||||
|
if (extensions->isFunction (keyword, returnType, argumentType,
|
||||||
|
!mExplicit.empty()))
|
||||||
|
{
|
||||||
|
scanner.putbackKeyword (keyword, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mState==BeginState)
|
if (mState==BeginState)
|
||||||
|
@ -233,12 +328,24 @@ namespace Compiler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mAllowExpression)
|
||||||
|
{
|
||||||
|
if (keyword==Scanner::K_getsquareroot || keyword==Scanner::K_menumode ||
|
||||||
|
keyword==Scanner::K_random || keyword==Scanner::K_scriptrunning ||
|
||||||
|
keyword==Scanner::K_getsecondspassed)
|
||||||
|
{
|
||||||
|
scanner.putbackKeyword (keyword, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Parser::parseKeyword (keyword, loc, scanner);
|
return Parser::parseKeyword (keyword, loc, scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LineParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
|
bool LineParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
|
||||||
{
|
{
|
||||||
if (code==Scanner::S_newline && mState==EndState)
|
if (code==Scanner::S_newline && (mState==EndState || mState==BeginState))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (code==Scanner::S_comma && mState==MessageState)
|
if (code==Scanner::S_comma && mState==MessageState)
|
||||||
|
@ -253,6 +360,14 @@ namespace Compiler
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mAllowExpression && mState==BeginState &&
|
||||||
|
(code==Scanner::S_open || code==Scanner::S_minus))
|
||||||
|
{
|
||||||
|
scanner.putbackSpecial (code, loc);
|
||||||
|
parseExpression (scanner, loc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return Parser::parseSpecial (code, loc, scanner);
|
return Parser::parseSpecial (code, loc, scanner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,17 @@ namespace Compiler
|
||||||
std::string mExplicit;
|
std::string mExplicit;
|
||||||
char mType;
|
char mType;
|
||||||
ExprParser mExprParser;
|
ExprParser mExprParser;
|
||||||
|
bool mAllowExpression;
|
||||||
|
|
||||||
|
void parseExpression (Scanner& scanner, const TokenLoc& loc);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
LineParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||||
Literals& literals, std::vector<Interpreter::Type_Code>& code);
|
Literals& literals, std::vector<Interpreter::Type_Code>& code,
|
||||||
|
bool allowExpression = false);
|
||||||
|
///< \param allowExpression Allow lines consisting of a naked expression
|
||||||
|
/// (result is send to the messagebox interface)
|
||||||
|
|
||||||
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
|
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
|
||||||
///< Handle an int token.
|
///< Handle an int token.
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c04d72cbe380217c2d1d60f8a2c6e4810fe4c050
|
Subproject commit 82a3c071e56f2df451618e1371424c39aa299690
|
Loading…
Reference in a new issue