implemented enable, disable and getdisabled with explicit references

actorid
Marc Zinnschlag 15 years ago
parent ce74ee8618
commit d4ac3b506e

@ -120,14 +120,14 @@ namespace SAInterpreter
return 0; return 0;
} }
bool Context::isDisabled() const bool Context::isDisabled (const std::string& id) const
{ {
return false; return false;
} }
void Context::enable() {} void Context::enable (const std::string& id) {}
void Context::disable() {} void Context::disable (const std::string& id) {}
void Context::report() void Context::report()
{ {

@ -62,11 +62,11 @@ namespace SAInterpreter
virtual float getSecondsPassed() const; virtual float getSecondsPassed() const;
virtual bool isDisabled() const; virtual bool isDisabled (const std::string& id = "") const;
virtual void enable(); virtual void enable (const std::string& id = "");
virtual void disable(); virtual void disable (const std::string& id = "");
void report(); void report();
///< Write state to std::cout ///< Write state to std::cout

@ -16,6 +16,42 @@
namespace MWScript namespace MWScript
{ {
InterpreterContext::PtrWithCell InterpreterContext::getReference (
const std::string& id, bool activeOnly)
{
PtrWithCell ref;
if (!id.empty())
{
return mEnvironment.mWorld->getPtr (id, activeOnly);
}
else
{
if (mReference.isEmpty())
throw std::runtime_error ("no implicit reference");
return PtrWithCell (mReference, mEnvironment.mWorld->find (mReference));
}
}
InterpreterContext::CPtrWithCell InterpreterContext::getReference (
const std::string& id, bool activeOnly) const
{
CPtrWithCell ref;
if (!id.empty())
{
return mEnvironment.mWorld->getPtr (id, activeOnly);
}
else
{
if (mReference.isEmpty())
throw std::runtime_error ("no implicit reference");
return CPtrWithCell (mReference, mEnvironment.mWorld->find (mReference));
}
}
InterpreterContext::InterpreterContext (MWWorld::Environment& environment, InterpreterContext::InterpreterContext (MWWorld::Environment& environment,
MWScript::Locals *locals, MWWorld::Ptr reference) MWScript::Locals *locals, MWWorld::Ptr reference)
: mEnvironment (environment), mLocals (locals), mReference (reference) : mEnvironment (environment), mLocals (locals), mReference (reference)
@ -166,33 +202,21 @@ namespace MWScript
return mEnvironment.mFrameDuration; return mEnvironment.mFrameDuration;
} }
bool InterpreterContext::isDisabled() const bool InterpreterContext::isDisabled (const std::string& id) const
{ {
if (mReference.isEmpty()) CPtrWithCell ref = getReference (id, false);
throw std::runtime_error ("no implicit reference"); return !ref.first.getRefData().isEnabled();
return !mReference.getRefData().isEnabled();
} }
void InterpreterContext::enable() void InterpreterContext::enable (const std::string& id)
{ {
if (mReference.isEmpty()) PtrWithCell ref = getReference (id, false);
throw std::runtime_error ("no implicit reference");
std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> ref
(mReference, mEnvironment.mWorld->find (mReference));
mEnvironment.mWorld->enable (ref); mEnvironment.mWorld->enable (ref);
} }
void InterpreterContext::disable() void InterpreterContext::disable (const std::string& id)
{ {
if (mReference.isEmpty()) PtrWithCell ref = getReference (id, false);
throw std::runtime_error ("no implicit reference");
std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> ref
(mReference, mEnvironment.mWorld->find (mReference));
mEnvironment.mWorld->disable (ref); mEnvironment.mWorld->disable (ref);
} }

@ -5,11 +5,7 @@
#include "../mwworld/ptr.hpp" #include "../mwworld/ptr.hpp"
#include "../mwworld/environment.hpp" #include "../mwworld/environment.hpp"
#include "../mwworld/world.hpp"
namespace MWWorld
{
class World;
}
namespace MWSound namespace MWSound
{ {
@ -26,6 +22,13 @@ namespace MWScript
Locals *mLocals; Locals *mLocals;
MWWorld::Ptr mReference; MWWorld::Ptr mReference;
typedef std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> PtrWithCell;
typedef std::pair<const MWWorld::Ptr, const MWWorld::World::CellStore *> CPtrWithCell;
PtrWithCell getReference (const std::string& id, bool activeOnly);
CPtrWithCell getReference (const std::string& id, bool activeOnly) const;
public: public:
InterpreterContext (MWWorld::Environment& environment, InterpreterContext (MWWorld::Environment& environment,
@ -73,11 +76,11 @@ namespace MWScript
virtual float getSecondsPassed() const; virtual float getSecondsPassed() const;
virtual bool isDisabled() const; virtual bool isDisabled (const std::string& id = "") const;
virtual void enable(); virtual void enable (const std::string& id = "");
virtual void disable(); virtual void disable (const std::string& id = "");
MWWorld::World& getWorld(); MWWorld::World& getWorld();

@ -203,6 +203,9 @@ namespace Compiler
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
{ {
if (!mExplicit.empty())
return Parser::parseInt (value, loc, scanner);
mFirst = false; mFirst = false;
if (mNextOperand) if (mNextOperand)
@ -221,6 +224,9 @@ namespace Compiler
bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner) bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
{ {
if (!mExplicit.empty())
return Parser::parseFloat (value, loc, scanner);
mFirst = false; mFirst = false;
if (mNextOperand) if (mNextOperand)
@ -240,6 +246,9 @@ namespace Compiler
bool ExprParser::parseName (const std::string& name, const TokenLoc& loc, bool ExprParser::parseName (const std::string& name, const TokenLoc& loc,
Scanner& scanner) Scanner& scanner)
{ {
if (!mExplicit.empty())
return Parser::parseName (name, loc, scanner);
mFirst = false; mFirst = false;
if (mNextOperand) if (mNextOperand)
@ -255,7 +264,6 @@ namespace Compiler
mOperands.push_back (type=='f' ? 'f' : 'l'); mOperands.push_back (type=='f' ? 'f' : 'l');
return true; return true;
} }
type = getContext().getGlobalType (name2); type = getContext().getGlobalType (name2);
@ -266,6 +274,12 @@ namespace Compiler
mOperands.push_back (type=='f' ? 'f' : 'l'); mOperands.push_back (type=='f' ? 'f' : 'l');
return true; return true;
} }
if (mOperands.empty() && mOperators.empty() && mExplicit.empty())
{
mExplicit = name;
return true;
}
} }
else else
{ {
@ -280,7 +294,28 @@ namespace Compiler
bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) bool ExprParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
{ {
mFirst = false; mFirst = false;
if (!mExplicit.empty())
{
if (mRefOp && mNextOperand)
{
if (keyword==Scanner::K_getdisabled)
{
mTokenLoc = loc;
Generator::getDisabled (mCode, mLiterals, mExplicit);
mOperands.push_back ('l');
mExplicit.clear();
mRefOp = false;
mNextOperand = false;
return true;
}
}
return Parser::parseKeyword (keyword, loc, scanner);
}
if (mNextOperand) if (mNextOperand)
{ {
if (keyword==Scanner::K_getsquareroot) if (keyword==Scanner::K_getsquareroot)
@ -351,7 +386,7 @@ namespace Compiler
{ {
mTokenLoc = loc; mTokenLoc = loc;
Generator::getDisabled (mCode); Generator::getDisabled (mCode, mLiterals, "");
mOperands.push_back ('l'); mOperands.push_back ('l');
mNextOperand = false; mNextOperand = false;
@ -391,6 +426,17 @@ namespace Compiler
bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
{ {
if (!mExplicit.empty())
{
if (!mRefOp && code==Scanner::S_ref)
{
mRefOp = true;
return true;
}
return Parser::parseSpecial (code, loc, scanner);
}
if (code==Scanner::S_comma) if (code==Scanner::S_comma)
{ {
mTokenLoc = loc; mTokenLoc = loc;
@ -498,6 +544,8 @@ namespace Compiler
mNextOperand = true; mNextOperand = true;
mCode.clear(); mCode.clear();
mFirst = true; mFirst = true;
mExplicit.clear();
mRefOp = false;
} }
char ExprParser::append (std::vector<Interpreter::Type_Code>& code) char ExprParser::append (std::vector<Interpreter::Type_Code>& code)

@ -24,6 +24,8 @@ namespace Compiler
std::vector<Interpreter::Type_Code> mCode; std::vector<Interpreter::Type_Code> mCode;
bool mFirst; bool mFirst;
bool mArgument; bool mArgument;
std::string mExplicit;
bool mRefOp;
int getPriority (char op) const; int getPriority (char op) const;

@ -300,6 +300,20 @@ namespace
code.push_back (Compiler::Generator::segment5 (53)); code.push_back (Compiler::Generator::segment5 (53));
} }
void opEnableExplicit (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (54));
}
void opDisableExplicit (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (55));
}
void opGetDisabledExplicit (Compiler::Generator::CodeContainer& code)
{
code.push_back (Compiler::Generator::segment5 (56));
}
} }
namespace Compiler namespace Compiler
@ -702,19 +716,46 @@ namespace Compiler
opGetSecondsPassed (code); opGetSecondsPassed (code);
} }
void getDisabled (CodeContainer& code) void getDisabled (CodeContainer& code, Literals& literals, const std::string id)
{ {
opGetDisabled (code); if (id.empty())
{
opGetDisabled (code);
}
else
{
int index = literals.addString (id);
opPushInt (code, index);
opGetDisabledExplicit (code);
}
} }
void enable (CodeContainer& code) void enable (CodeContainer& code, Literals& literals, const std::string id)
{ {
opEnable (code); if (id.empty())
{
opEnable (code);
}
else
{
int index = literals.addString (id);
opPushInt (code, index);
opEnableExplicit (code);
}
} }
void disable (CodeContainer& code) void disable (CodeContainer& code, Literals& literals, const std::string id)
{ {
opDisable (code); if (id.empty())
{
opDisable (code);
}
else
{
int index = literals.addString (id);
opPushInt (code, index);
opDisableExplicit (code);
}
} }
} }
} }

@ -111,11 +111,11 @@ namespace Compiler
void getSecondsPassed (CodeContainer& code); void getSecondsPassed (CodeContainer& code);
void getDisabled (CodeContainer& code); void getDisabled (CodeContainer& code, Literals& literals, const std::string id);
void enable (CodeContainer& code); void enable (CodeContainer& code, Literals& literals, const std::string id);
void disable (CodeContainer& code); void disable (CodeContainer& code, Literals& literals, const std::string id);
} }
} }

@ -129,11 +129,36 @@ namespace Compiler
return false; return false;
} }
if (mState==BeginState)
{
mState = PotentialExplicitState;
mExplicit = toLower (name);
return true;
}
return Parser::parseName (name, loc, scanner); return Parser::parseName (name, loc, scanner);
} }
bool LineParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner) bool LineParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
{ {
if (mState==BeginState || mState==ExplicitState)
{
switch (keyword)
{
case Scanner::K_enable:
Generator::enable (mCode, mLiterals, mExplicit);
mState = EndState;
return true;
case Scanner::K_disable:
Generator::disable (mCode, mLiterals, mExplicit);
mState = EndState;
return true;
}
}
if (mState==BeginState) if (mState==BeginState)
{ {
switch (keyword) switch (keyword)
@ -163,18 +188,6 @@ namespace Compiler
Generator::stopScript (mCode); Generator::stopScript (mCode);
mState = EndState; mState = EndState;
return true; return true;
case Scanner::K_enable:
Generator::enable (mCode);
mState = EndState;
return true;
case Scanner::K_disable:
Generator::disable (mCode);
mState = EndState;
return true;
} }
// check for custom extensions // check for custom extensions
@ -233,6 +246,12 @@ namespace Compiler
mState = MessageCommaState; mState = MessageCommaState;
return true; return true;
} }
if (code==Scanner::S_ref && mState==PotentialExplicitState)
{
mState = ExplicitState;
return true;
}
return Parser::parseSpecial (code, loc, scanner); return Parser::parseSpecial (code, loc, scanner);
} }
@ -241,6 +260,7 @@ namespace Compiler
{ {
mState = BeginState; mState = BeginState;
mName.clear(); mName.clear();
mExplicit.clear();
} }
} }

@ -23,7 +23,8 @@ namespace Compiler
ShortState, LongState, FloatState, ShortState, LongState, FloatState,
SetState, SetLocalVarState, SetGlobalVarState, SetState, SetLocalVarState, SetGlobalVarState,
MessageState, MessageCommaState, MessageState, MessageCommaState,
EndState EndState,
PotentialExplicitState, ExplicitState
}; };
Locals& mLocals; Locals& mLocals;
@ -31,6 +32,7 @@ namespace Compiler
std::vector<Interpreter::Type_Code>& mCode; std::vector<Interpreter::Type_Code>& mCode;
State mState; State mState;
std::string mName; std::string mName;
std::string mExplicit;
char mType; char mType;
ExprParser mExprParser; ExprParser mExprParser;

@ -57,11 +57,11 @@ namespace Interpreter
virtual float getSecondsPassed() const = 0; virtual float getSecondsPassed() const = 0;
virtual bool isDisabled() const = 0; virtual bool isDisabled (const std::string& id = "") const = 0;
virtual void enable() = 0; virtual void enable (const std::string& id = "") = 0;
virtual void disable() = 0; virtual void disable (const std::string& id = "") = 0;
}; };
} }

@ -112,6 +112,9 @@ op 50: push frame duration (float)
op 51: enable implicit reference op 51: enable implicit reference
op 52: disable implicit reference op 52: disable implicit reference
op 53: push 1, if implicit reference is disabled, 0 else op 53: push 1, if implicit reference is disabled, 0 else
opcodes 54-33554431 unused op 54: explicit reference = stack[0]; pop; enable explicit reference
op 55: explicit reference = stack[0]; pop; disable explicit reference
op 56: explicit reference = stack[0]; pop; push 1, if explicit reference is disabled, 0 else
opcodes 57-33554431 unused
opcodes 33554432-67108863 reserved for extensions opcodes 33554432-67108863 reserved for extensions

@ -92,7 +92,10 @@ namespace Interpreter
interpreter.installSegment5 (51, new OpEnable); interpreter.installSegment5 (51, new OpEnable);
interpreter.installSegment5 (52, new OpDisable); interpreter.installSegment5 (52, new OpDisable);
interpreter.installSegment5 (53, new OpGetDisabled); interpreter.installSegment5 (53, new OpGetDisabled);
interpreter.installSegment5 (54, new OpEnableExplicit);
interpreter.installSegment5 (55, new OpDisableExplicit);
interpreter.installSegment5 (56, new OpGetDisabledExplicit);
// script control // script control
interpreter.installSegment5 (46, new OpScriptRunning); interpreter.installSegment5 (46, new OpScriptRunning);
interpreter.installSegment5 (47, new OpStartScript); interpreter.installSegment5 (47, new OpStartScript);

@ -161,6 +161,48 @@ namespace Interpreter
} }
}; };
class OpEnableExplicit : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
int index = runtime[0];
runtime.pop();
std::string id = runtime.getStringLiteral (index);
runtime.getContext().enable (id);
}
};
class OpDisableExplicit : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
int index = runtime[0];
runtime.pop();
std::string id = runtime.getStringLiteral (index);
runtime.getContext().disable (id);
}
};
class OpGetDisabledExplicit : public Opcode0
{
public:
virtual void execute (Runtime& runtime)
{
int index = runtime[0];
runtime.pop();
std::string id = runtime.getStringLiteral (index);
runtime.push (runtime.getContext().isDisabled (id));
}
};
} }
#endif #endif

Loading…
Cancel
Save