From 69e607e140266eee37ee5eb5ccadfd08d5428851 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Jul 2010 20:55:39 +0200 Subject: [PATCH 1/9] implemented getdistance with explicit references --- apps/mwinterpreter/context.cpp | 2 +- apps/mwinterpreter/context.hpp | 2 +- apps/openmw/mwscript/interpretercontext.cpp | 10 +++++----- apps/openmw/mwscript/interpretercontext.hpp | 2 +- components/compiler/exprparser.cpp | 19 ++++++++++++++++--- components/compiler/generator.cpp | 18 ++++++++++++++++-- components/compiler/generator.hpp | 2 +- components/interpreter/context.hpp | 3 ++- components/interpreter/docs/vmformat.txt | 4 +++- components/interpreter/installopcodes.cpp | 1 + components/interpreter/spatialopcodes.hpp | 18 ++++++++++++++++++ 11 files changed, 65 insertions(+), 16 deletions(-) diff --git a/apps/mwinterpreter/context.cpp b/apps/mwinterpreter/context.cpp index cbe379f0f..7924f1dc7 100644 --- a/apps/mwinterpreter/context.cpp +++ b/apps/mwinterpreter/context.cpp @@ -110,7 +110,7 @@ namespace SAInterpreter void Context::stopScript (const std::string& name) {} - float Context::getDistance (const std::string& name) const + float Context::getDistance (const std::string& name, const std::string& id) const { return 0; } diff --git a/apps/mwinterpreter/context.hpp b/apps/mwinterpreter/context.hpp index 1ee3129f7..6cf4f8cd7 100644 --- a/apps/mwinterpreter/context.hpp +++ b/apps/mwinterpreter/context.hpp @@ -58,7 +58,7 @@ namespace SAInterpreter virtual void stopScript (const std::string& name); - virtual float getDistance (const std::string& name) const; + virtual float getDistance (const std::string& name, const std::string& id = "") const; virtual float getSecondsPassed() const; diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 064ac583d..a0f1d9d95 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -176,18 +176,18 @@ namespace MWScript mEnvironment.mGlobalScripts->removeScript (name); } - float InterpreterContext::getDistance (const std::string& name) const + float InterpreterContext::getDistance (const std::string& name, const std::string& id) const { - if (mReference.isEmpty()) - throw std::runtime_error ("no implicit reference"); - + // TODO handle exterior cells (when ref and ref2 are located in different cells) + CPtrWithCell ref2 = getReference (id, false); + std::pair ref = mEnvironment.mWorld->getPtr (name, true); double diff[3]; for (int i=0; i<3; ++i) - diff[i] = ref.first.getCellRef().pos.pos[i] - mReference.getCellRef().pos.pos[i]; + diff[i] = ref.first.getCellRef().pos.pos[i] - ref2.first.getCellRef().pos.pos[i]; return std::sqrt (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]); } diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index bdc871a01..14c0a9e85 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -70,7 +70,7 @@ namespace MWScript virtual void stopScript (const std::string& name); - virtual float getDistance (const std::string& name) const; + virtual float getDistance (const std::string& name, const std::string& id = "") const; virtual bool hasBeenActivated() const; diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index e11dde521..2938bbae3 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -311,6 +311,19 @@ namespace Compiler mNextOperand = false; return true; } + else if (keyword==Scanner::K_getdistance) + { + mTokenLoc = loc; + parseArguments ("c", scanner); + + Generator::getDistance (mCode, mLiterals, mExplicit); + mOperands.push_back ('f'); + mExplicit.clear(); + mRefOp = false; + + mNextOperand = false; + return true; + } } return Parser::parseKeyword (keyword, loc, scanner); @@ -360,18 +373,18 @@ namespace Compiler mNextOperand = false; return true; - } + } else if (keyword==Scanner::K_getdistance) { mTokenLoc = loc; parseArguments ("c", scanner); - Generator::getDistance (mCode); + Generator::getDistance (mCode, mLiterals, ""); mOperands.push_back ('f'); mNextOperand = false; return true; - } + } else if (keyword==Scanner::K_getsecondspassed) { mTokenLoc = loc; diff --git a/components/compiler/generator.cpp b/components/compiler/generator.cpp index ece1bebaf..0be2c4151 100644 --- a/components/compiler/generator.cpp +++ b/components/compiler/generator.cpp @@ -314,6 +314,11 @@ namespace { code.push_back (Compiler::Generator::segment5 (56)); } + + void opGetDistanceExplicit (Compiler::Generator::CodeContainer& code) + { + code.push_back (Compiler::Generator::segment5 (57)); + } } namespace Compiler @@ -706,9 +711,18 @@ namespace Compiler opStopScript (code); } - void getDistance (CodeContainer& code) + void getDistance (CodeContainer& code, Literals& literals, const std::string id) { - opGetDistance (code); + if (id.empty()) + { + opGetDistance (code); + } + else + { + int index = literals.addString (id); + opPushInt (code, index); + opGetDistanceExplicit (code); + } } void getSecondsPassed (CodeContainer& code) diff --git a/components/compiler/generator.hpp b/components/compiler/generator.hpp index 9623b7226..a7559f7e9 100644 --- a/components/compiler/generator.hpp +++ b/components/compiler/generator.hpp @@ -107,7 +107,7 @@ namespace Compiler void stopScript (CodeContainer& code); - void getDistance (CodeContainer& code); + void getDistance (CodeContainer& code, Literals& literals, const std::string id); void getSecondsPassed (CodeContainer& code); diff --git a/components/interpreter/context.hpp b/components/interpreter/context.hpp index aae0051bd..0d77903f4 100644 --- a/components/interpreter/context.hpp +++ b/components/interpreter/context.hpp @@ -53,7 +53,8 @@ namespace Interpreter virtual void stopScript (const std::string& name) = 0; - virtual float getDistance (const std::string& name) const = 0; + virtual float getDistance (const std::string& name, const std::string& id = "") const + = 0; virtual float getSecondsPassed() const = 0; diff --git a/components/interpreter/docs/vmformat.txt b/components/interpreter/docs/vmformat.txt index dcf204473..40ce3535b 100644 --- a/components/interpreter/docs/vmformat.txt +++ b/components/interpreter/docs/vmformat.txt @@ -115,6 +115,8 @@ op 53: push 1, if implicit reference is disabled, 0 else 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 +op 57: explicit reference = stack[0]; pop; + replace stack[0] with distance between explicit reference and a reference of ID stack[0] +opcodes 58-33554431 unused opcodes 33554432-67108863 reserved for extensions diff --git a/components/interpreter/installopcodes.cpp b/components/interpreter/installopcodes.cpp index 522f77b95..2e22d10e5 100644 --- a/components/interpreter/installopcodes.cpp +++ b/components/interpreter/installopcodes.cpp @@ -103,6 +103,7 @@ namespace Interpreter // spacial interpreter.installSegment5 (49, new OpGetDistance); + interpreter.installSegment5 (57, new OpGetDistanceExplicit); } } diff --git a/components/interpreter/spatialopcodes.hpp b/components/interpreter/spatialopcodes.hpp index 2a401ae8a..d897ff69d 100644 --- a/components/interpreter/spatialopcodes.hpp +++ b/components/interpreter/spatialopcodes.hpp @@ -19,6 +19,24 @@ namespace Interpreter runtime[0] = *reinterpret_cast (&distance); } }; + + class OpGetDistanceExplicit : public Opcode0 + { + public: + + virtual void execute (Runtime& runtime) + { + int index = runtime[0]; + runtime.pop(); + std::string id = runtime.getStringLiteral (index); + + std::string name = runtime.getStringLiteral (runtime[0]); + + float distance = runtime.getContext().getDistance (name, id); + + runtime[0] = *reinterpret_cast (&distance); + } + }; } #endif From 71c710f9f65f809ced7000259b997a6926fbb9dd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 9 Jul 2010 22:01:24 +0200 Subject: [PATCH 2/9] enhanced compiler extenion system to support new instructions and functions with explicit references --- components/compiler/exprparser.cpp | 23 +++++++++++++++++++++- components/compiler/extensions.cpp | 31 +++++++++++++++++++++++------- components/compiler/extensions.hpp | 18 +++++++++++------ components/compiler/lineparser.cpp | 30 ++++++++++++++--------------- 4 files changed, 73 insertions(+), 29 deletions(-) diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index 2938bbae3..db7f8a2d2 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -324,6 +324,27 @@ namespace Compiler mNextOperand = false; return true; } + + // check for custom extensions + if (const Extensions *extensions = getContext().getExtensions()) + { + char returnType; + std::string argumentType; + + if (extensions->isFunction (keyword, returnType, argumentType)) + { + mTokenLoc = loc; + parseArguments (argumentType, scanner); + + extensions->generateFunctionCode (keyword, mCode, mLiterals, mExplicit); + mOperands.push_back (returnType); + mExplicit.clear(); + mRefOp = false; + + mNextOperand = false; + return true; + } + } } return Parser::parseKeyword (keyword, loc, scanner); @@ -418,7 +439,7 @@ namespace Compiler mTokenLoc = loc; parseArguments (argumentType, scanner); - extensions->generateFunctionCode (keyword, mCode); + extensions->generateFunctionCode (keyword, mCode, mLiterals, ""); mOperands.push_back (returnType); mNextOperand = false; diff --git a/components/compiler/extensions.cpp b/components/compiler/extensions.cpp index ff05208de..9a6ea7f63 100644 --- a/components/compiler/extensions.cpp +++ b/components/compiler/extensions.cpp @@ -5,6 +5,7 @@ #include #include "generator.hpp" +#include "literals.hpp" namespace Compiler { @@ -44,7 +45,7 @@ namespace Compiler } void Extensions::registerFunction (const std::string& keyword, char returnType, - const std::string& argumentType, int segment5code) + const std::string& argumentType, int segment5code, int segment5codeExplicit) { assert (segment5code>=33554432 && segment5code<=67108863); @@ -56,12 +57,13 @@ namespace Compiler function.mReturn = returnType; function.mArguments = argumentType; function.mCode = segment5code; + function.mCodeExplicit = segment5codeExplicit; mFunctions.insert (std::make_pair (code, function)); } void Extensions::registerInstruction (const std::string& keyword, - const std::string& argumentType, int segment5code) + const std::string& argumentType, int segment5code, int segment5codeExplicit) { assert (segment5code>=33554432 && segment5code<=67108863); @@ -72,23 +74,31 @@ namespace Compiler Instruction instruction; instruction.mArguments = argumentType; instruction.mCode = segment5code; + instruction.mCodeExplicit = segment5codeExplicit; mInstructions.insert (std::make_pair (code, instruction)); } - void Extensions::generateFunctionCode (int keyword, std::vector& code) - const + void Extensions::generateFunctionCode (int keyword, std::vector& code, + Literals& literals, const std::string& id) const { std::map::const_iterator iter = mFunctions.find (keyword); if (iter==mFunctions.end()) throw std::logic_error ("unknown custom function keyword"); - code.push_back (Generator::segment5 (iter->second.mCode)); + if (!id.empty()) + { + int index = literals.addString (id); + Generator::pushInt (code, literals, index); + } + + code.push_back (Generator::segment5 ( + id.empty() ? iter->second.mCode : iter->second.mCodeExplicit)); } void Extensions::generateInstructionCode (int keyword, - std::vector& code) + std::vector& code, Literals& literals, const std::string& id) const { std::map::const_iterator iter = mInstructions.find (keyword); @@ -96,6 +106,13 @@ namespace Compiler if (iter==mInstructions.end()) throw std::logic_error ("unknown custom instruction keyword"); - code.push_back (Generator::segment5 (iter->second.mCode)); + if (!id.empty()) + { + int index = literals.addString (id); + Generator::pushInt (code, literals, index); + } + + code.push_back (Generator::segment5 ( + id.empty() ? iter->second.mCode : iter->second.mCodeExplicit)); } } diff --git a/components/compiler/extensions.hpp b/components/compiler/extensions.hpp index f864daf1b..f1a856818 100644 --- a/components/compiler/extensions.hpp +++ b/components/compiler/extensions.hpp @@ -9,6 +9,8 @@ namespace Compiler { + class Literals; + /// \brief Collection of compiler extensions class Extensions @@ -18,12 +20,14 @@ namespace Compiler char mReturn; std::string mArguments; int mCode; + int mCodeExplicit; }; struct Instruction { std::string mArguments; int mCode; + int mCodeExplicit; }; int mNextKeywordIndex; @@ -48,25 +52,27 @@ namespace Compiler ///< Is this keyword registered with a function? If yes, return argument types. void registerFunction (const std::string& keyword, char returnType, - const std::string& argumentType, int segment5code); + const std::string& argumentType, int segment5code, int segment5codeExplicit = -1); ///< Register a custom function /// - keyword must be all lower case. /// - keyword must be unique + /// - if explicit references are not supported, segment5codeExplicit must be set to -1 /// \note Currently only segment 5 opcodes are supported. void registerInstruction (const std::string& keyword, - const std::string& argumentType, int segment5code); + const std::string& argumentType, int segment5code, int segment5codeExplicit = -1); ///< Register a custom instruction /// - keyword must be all lower case. /// - keyword must be unique + /// - if explicit references are not supported, segment5codeExplicit must be set to -1 /// \note Currently only segment 5 opcodes are supported. - void generateFunctionCode (int keyword, std::vector& code) - const; + void generateFunctionCode (int keyword, std::vector& code, + Literals& literals, const std::string& id) const; ///< Append code for function to \a code. - void generateInstructionCode (int keyword, std::vector& code) - const; + void generateInstructionCode (int keyword, std::vector& code, + Literals& literals, const std::string& id) const; ///< Append code for function to \a code. }; } diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index d46d5f093..3be38bce4 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -157,6 +157,21 @@ namespace Compiler mState = EndState; return true; } + + // check for custom extensions + if (const Extensions *extensions = getContext().getExtensions()) + { + std::string argumentType; + + if (extensions->isInstruction (keyword, argumentType)) + { + mExprParser.parseArguments (argumentType, scanner, mCode, true); + + extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit); + mState = EndState; + return true; + } + } } if (mState==BeginState) @@ -189,21 +204,6 @@ namespace Compiler mState = EndState; return true; } - - // check for custom extensions - if (const Extensions *extensions = getContext().getExtensions()) - { - std::string argumentType; - - if (extensions->isInstruction (keyword, argumentType)) - { - mExprParser.parseArguments (argumentType, scanner, mCode, true); - - extensions->generateInstructionCode (keyword, mCode); - mState = EndState; - return true; - } - } } else if (mState==SetLocalVarState && keyword==Scanner::K_to) { From 31b4d83fac82e634f9b18825e77614c454d3331f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Jul 2010 11:48:05 +0200 Subject: [PATCH 3/9] moved sound extensions from mwsound to mwscript (reduces coupling between openmw components) --- apps/openmw/CMakeLists.txt | 8 +-- apps/openmw/mwscript/extensions.cpp | 5 +- apps/openmw/mwscript/scriptmanager.cpp | 5 +- .../soundextensions.cpp} | 72 +++++++++---------- apps/openmw/mwscript/soundextensions.hpp | 27 +++++++ apps/openmw/mwsound/extensions.hpp | 24 ------- 6 files changed, 69 insertions(+), 72 deletions(-) rename apps/openmw/{mwsound/extensions.cpp => mwscript/soundextensions.cpp} (76%) create mode 100644 apps/openmw/mwscript/soundextensions.hpp delete mode 100644 apps/openmw/mwsound/extensions.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 216627786..78b06d2b4 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -35,6 +35,7 @@ set(GAMESCRIPT mwscript/cellextensions.cpp mwscript/miscextensions.cpp mwscript/guiextensions.cpp + mwscript/soundextensions.cpp mwscript/extensions.cpp mwscript/globalscripts.cpp ) @@ -46,17 +47,16 @@ set(GAMESCRIPT_HEADER mwscript/cellextensions.hpp mwscript/miscextensions.hpp mwscript/guiextensions.hpp + mwscript/soundextensions.hpp mwscript/extensions.hpp mwscript/globalscripts.hpp ) source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER}) set(GAMESOUND - mwsound/soundmanager.cpp - mwsound/extensions.cpp) + mwsound/soundmanager.cpp) set(GAMESOUND_HEADER - mwsound/soundmanager.hpp - mwsound/extensions.hpp) + mwsound/soundmanager.hpp) source_group(apps\\openmw\\mwsound FILES ${GAMESOUND} ${GAMESOUND_HEADER}) set(GAMEGUI diff --git a/apps/openmw/mwscript/extensions.cpp b/apps/openmw/mwscript/extensions.cpp index e309d632c..b688b2037 100644 --- a/apps/openmw/mwscript/extensions.cpp +++ b/apps/openmw/mwscript/extensions.cpp @@ -1,8 +1,7 @@ #include "extensions.hpp" -#include "../mwsound/extensions.hpp" - +#include "soundextensions.hpp" #include "cellextensions.hpp" #include "miscextensions.hpp" #include "guiextensions.hpp" @@ -14,7 +13,7 @@ namespace MWScript Cell::registerExtensions (extensions); Misc::registerExtensions (extensions); Gui::registerExtensions (extensions); - MWSound::registerExtensions (extensions); + Sound::registerExtensions (extensions); } } diff --git a/apps/openmw/mwscript/scriptmanager.cpp b/apps/openmw/mwscript/scriptmanager.cpp index 912e959ae..926dcb699 100644 --- a/apps/openmw/mwscript/scriptmanager.cpp +++ b/apps/openmw/mwscript/scriptmanager.cpp @@ -15,8 +15,7 @@ #include #include -#include "../mwsound/extensions.hpp" - +#include "soundextensions.hpp" #include "cellextensions.hpp" #include "miscextensions.hpp" #include "guiextensions.hpp" @@ -125,7 +124,7 @@ namespace MWScript Cell::installOpcodes (interpreter); Misc::installOpcodes (interpreter); Gui::installOpcodes (interpreter); - MWSound::installOpcodes (interpreter); + Sound::installOpcodes (interpreter); } } diff --git a/apps/openmw/mwsound/extensions.cpp b/apps/openmw/mwscript/soundextensions.cpp similarity index 76% rename from apps/openmw/mwsound/extensions.cpp rename to apps/openmw/mwscript/soundextensions.cpp index 4aee9827c..33de38103 100644 --- a/apps/openmw/mwsound/extensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -7,15 +7,15 @@ #include #include -#include "../mwscript/interpretercontext.hpp" +#include "interpretercontext.hpp" #include "../mwworld/world.hpp" -#include "soundmanager.hpp" +#include "../mwsound/soundmanager.hpp" -namespace MWSound +namespace MWScript { - namespace Script + namespace Sound { class OpSay : public Interpreter::Opcode0 { @@ -198,39 +198,35 @@ namespace MWSound const int opcodePlayLoopSound3DVP = 0x2000009; const int opcodeStopSound = 0x200000a; const int opcodeGetSoundPlaying = 0x200000b; - } - void registerExtensions (Compiler::Extensions& extensions) - { - extensions.registerInstruction ("say", "SS", Script::opcodeSay); - extensions.registerFunction ("saydone", 'l', "", Script::opcodeSayDone); - extensions.registerInstruction ("streammusic", "S", Script::opcodeStreamMusic); - extensions.registerInstruction ("playsound", "c", Script::opcodePlaySound); - extensions.registerInstruction ("playsoundvp", "cff", Script::opcodePlaySoundVP); - extensions.registerInstruction ("playsound3d", "c", Script::opcodePlaySound3D); - extensions.registerInstruction ("playsound3dvp", "cff", Script::opcodePlaySound3DVP); - extensions.registerInstruction ("playloopsound3d", "c", Script::opcodePlayLoopSound3D); - extensions.registerInstruction ("playloopsound3dvp", "cff", - Script::opcodePlayLoopSound3DVP); - extensions.registerInstruction ("stopsound", "c", Script::opcodeStopSound); - extensions.registerFunction ("getsoundplaying", 'l', "c", Script::opcodeGetSoundPlaying); - } - - void installOpcodes (Interpreter::Interpreter& interpreter) - { - interpreter.installSegment5 (Script::opcodeSay, new Script::OpSay); - interpreter.installSegment5 (Script::opcodeSayDone, new Script::OpSayDone); - interpreter.installSegment5 (Script::opcodeStreamMusic, new Script::OpStreamMusic); - interpreter.installSegment5 (Script::opcodePlaySound, new Script::OpPlaySound); - interpreter.installSegment5 (Script::opcodePlaySoundVP, new Script::OpPlaySoundVP); - interpreter.installSegment5 (Script::opcodePlaySound3D, new Script::OpPlaySound3D (false)); - interpreter.installSegment5 (Script::opcodePlaySound3DVP, - new Script::OpPlaySoundVP3D (false)); - interpreter.installSegment5 (Script::opcodePlayLoopSound3D, - new Script::OpPlaySound3D (true)); - interpreter.installSegment5 (Script::opcodePlayLoopSound3DVP, - new Script::OpPlaySoundVP3D (true)); - interpreter.installSegment5 (Script::opcodeStopSound, new Script::OpStopSound); - interpreter.installSegment5 (Script::opcodeGetSoundPlaying, new Script::OpGetSoundPlaying); - } + void registerExtensions (Compiler::Extensions& extensions) + { + extensions.registerInstruction ("say", "SS", opcodeSay); + extensions.registerFunction ("saydone", 'l', "", opcodeSayDone); + extensions.registerInstruction ("streammusic", "S", opcodeStreamMusic); + extensions.registerInstruction ("playsound", "c", opcodePlaySound); + extensions.registerInstruction ("playsoundvp", "cff", opcodePlaySoundVP); + extensions.registerInstruction ("playsound3d", "c", opcodePlaySound3D); + extensions.registerInstruction ("playsound3dvp", "cff", opcodePlaySound3DVP); + extensions.registerInstruction ("playloopsound3d", "c", opcodePlayLoopSound3D); + extensions.registerInstruction ("playloopsound3dvp", "cff", opcodePlayLoopSound3DVP); + extensions.registerInstruction ("stopsound", "c", opcodeStopSound); + extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying); + } + + void installOpcodes (Interpreter::Interpreter& interpreter) + { + interpreter.installSegment5 (opcodeSay, new OpSay); + interpreter.installSegment5 (opcodeSayDone, new OpSayDone); + interpreter.installSegment5 (opcodeStreamMusic, new OpStreamMusic); + interpreter.installSegment5 (opcodePlaySound, new OpPlaySound); + interpreter.installSegment5 (opcodePlaySoundVP, new OpPlaySoundVP); + interpreter.installSegment5 (opcodePlaySound3D, new OpPlaySound3D (false)); + interpreter.installSegment5 (opcodePlaySound3DVP, new OpPlaySoundVP3D (false)); + interpreter.installSegment5 (opcodePlayLoopSound3D, new OpPlaySound3D (true)); + interpreter.installSegment5 (opcodePlayLoopSound3DVP, new OpPlaySoundVP3D (true)); + interpreter.installSegment5 (opcodeStopSound, new OpStopSound); + interpreter.installSegment5 (opcodeGetSoundPlaying, new OpGetSoundPlaying); + } + } } diff --git a/apps/openmw/mwscript/soundextensions.hpp b/apps/openmw/mwscript/soundextensions.hpp new file mode 100644 index 000000000..85416a6df --- /dev/null +++ b/apps/openmw/mwscript/soundextensions.hpp @@ -0,0 +1,27 @@ +#ifndef GAME_SCRIPT_SOUNDEXTENSIONS_H +#define GAME_SCRIPT_SOUNDEXTENSIONS_H + +namespace Compiler +{ + class Extensions; +} + +namespace Interpreter +{ + class Interpreter; +} + +namespace MWScript +{ + namespace Sound + { + // Script-extensions related to sound + + void registerExtensions (Compiler::Extensions& extensions); + + void installOpcodes (Interpreter::Interpreter& interpreter); + } +} + +#endif + diff --git a/apps/openmw/mwsound/extensions.hpp b/apps/openmw/mwsound/extensions.hpp deleted file mode 100644 index 0e860952a..000000000 --- a/apps/openmw/mwsound/extensions.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef GAME_SOUND_EXTENSIONS_H -#define GAME_SOUND_EXTENSIONS_H - -namespace Compiler -{ - class Extensions; -} - -namespace Interpreter -{ - class Interpreter; -} - -namespace MWSound -{ - // Script-extensions related to sound - - void registerExtensions (Compiler::Extensions& extensions); - - void installOpcodes (Interpreter::Interpreter& interpreter); -} - -#endif - From 211b723137fb908989cd4d843a70d25c6737a271 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Jul 2010 12:16:45 +0200 Subject: [PATCH 4/9] better error checking for extensions with explicit references --- components/compiler/extensions.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/compiler/extensions.cpp b/components/compiler/extensions.cpp index 9a6ea7f63..8aef21407 100644 --- a/components/compiler/extensions.cpp +++ b/components/compiler/extensions.cpp @@ -89,6 +89,9 @@ namespace Compiler if (!id.empty()) { + if (iter->second.mCodeExplicit==-1) + throw std::logic_error ("explicit references not supported"); + int index = literals.addString (id); Generator::pushInt (code, literals, index); } @@ -108,6 +111,9 @@ namespace Compiler if (!id.empty()) { + if (iter->second.mCodeExplicit==-1) + throw std::logic_error ("explicit references not supported"); + int index = literals.addString (id); Generator::pushInt (code, literals, index); } From 7f48c64efe00a838f2c09ae6d79d6e763969a5be Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Jul 2010 12:24:41 +0200 Subject: [PATCH 5/9] implemented sound related script instructions and functions with explicit references --- apps/openmw/mwscript/docs/vmformat.txt | 10 +- apps/openmw/mwscript/soundextensions.cpp | 185 ++++++++++++++++++++++- 2 files changed, 186 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 1cda9aeaa..d968239bc 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -46,5 +46,13 @@ op 0x2000015: EnableMapMenu op 0x2000016: EnableStatsMenu op 0x2000017: EnableRest op 0x2000018: ShowRestMenu -opcodes 0x2000019-0x3ffffff unused +op 0x2000019: Say, explicit reference +op 0x200001a: SayDone, explicit reference +op 0x200001b: PlaySound3D, explicit reference +op 0x200001c: PlaySound3DVP, explicit reference +op 0x200001d: PlayLoopSound3D, explicit reference +op 0x200001e: PlayLoopSound3DVP, explicit reference +op 0x200001f: StopSound, explicit reference +op 0x2000020: GetSoundPlaying, explicit reference +opcodes 0x2000021-0x3ffffff unused diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index 33de38103..4a6be48b5 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -186,6 +186,145 @@ namespace MWScript context.getReference(), runtime.getStringLiteral (index), context)); } }; + + class OpSayExplicit : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + std::string file = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + std::string text = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + context.getSoundManager().say (context.getWorld().getPtr (id, true).first, + file, text, context); + } + }; + + class OpSayDoneExplicit : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + runtime.push (context.getSoundManager().sayDone ( + context.getWorld().getPtr (id, true).first, + context)); + } + }; + + class OpPlaySound3DExplicit : public Interpreter::Opcode0 + { + bool mLoop; + + public: + + OpPlaySound3DExplicit (bool loop) : mLoop (loop) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + std::string sound = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + context.getSoundManager().playSound3D ( + context.getWorld().getPtr (id, true).first, sound, + 1.0, 1.0, mLoop, context); + } + }; + + class OpPlaySoundVP3DExplicit : public Interpreter::Opcode0 + { + bool mLoop; + + public: + + OpPlaySoundVP3DExplicit (bool loop) : mLoop (loop) {} + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + std::string sound = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + float volume = *reinterpret_cast (&runtime[0]); + runtime.pop(); + + float pitch = *reinterpret_cast (&runtime[0]); + runtime.pop(); + + context.getSoundManager().playSound3D ( + context.getWorld().getPtr (id, true).first, sound, volume, + pitch, mLoop, context); + + } + }; + + class OpStopSoundExplicit : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + std::string sound = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + context.getSoundManager().stopSound3D ( + context.getWorld().getPtr (id, true).first, sound, context); + } + }; + + class OpGetSoundPlayingExplicit : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWScript::InterpreterContext& context + = static_cast (runtime.getContext()); + + std::string id = runtime.getStringLiteral (runtime[0]); + runtime.pop(); + + int index = runtime[0]; + runtime.pop(); + + runtime.push (context.getSoundManager().getSoundPlaying ( + context.getWorld().getPtr (id, true).first, + runtime.getStringLiteral (index), context)); + } + }; const int opcodeSay = 0x2000001; const int opcodeSayDone = 0x2000002; @@ -199,19 +338,34 @@ namespace MWScript const int opcodeStopSound = 0x200000a; const int opcodeGetSoundPlaying = 0x200000b; + const int opcodeSayExplicit = 0x2000019; + const int opcodeSayDoneExplicit = 0x200001a; + const int opcodePlaySound3DExplicit = 0x200001b; + const int opcodePlaySound3DVPExplicit = 0x200001c; + const int opcodePlayLoopSound3DExplicit = 0x200001d; + const int opcodePlayLoopSound3DVPExplicit = 0x200001e; + const int opcodeStopSoundExplicit = 0x200001f; + const int opcodeGetSoundPlayingExplicit = 0x2000020; + void registerExtensions (Compiler::Extensions& extensions) { - extensions.registerInstruction ("say", "SS", opcodeSay); - extensions.registerFunction ("saydone", 'l', "", opcodeSayDone); + extensions.registerInstruction ("say", "SS", opcodeSay, opcodeSayExplicit); + extensions.registerFunction ("saydone", 'l', "", opcodeSayDone, opcodeSayDoneExplicit); extensions.registerInstruction ("streammusic", "S", opcodeStreamMusic); extensions.registerInstruction ("playsound", "c", opcodePlaySound); extensions.registerInstruction ("playsoundvp", "cff", opcodePlaySoundVP); - extensions.registerInstruction ("playsound3d", "c", opcodePlaySound3D); - extensions.registerInstruction ("playsound3dvp", "cff", opcodePlaySound3DVP); - extensions.registerInstruction ("playloopsound3d", "c", opcodePlayLoopSound3D); - extensions.registerInstruction ("playloopsound3dvp", "cff", opcodePlayLoopSound3DVP); - extensions.registerInstruction ("stopsound", "c", opcodeStopSound); - extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying); + extensions.registerInstruction ("playsound3d", "c", opcodePlaySound3D, + opcodePlaySound3DExplicit); + extensions.registerInstruction ("playsound3dvp", "cff", opcodePlaySound3DVP, + opcodePlaySound3DVPExplicit); + extensions.registerInstruction ("playloopsound3d", "c", opcodePlayLoopSound3D, + opcodePlayLoopSound3DExplicit); + extensions.registerInstruction ("playloopsound3dvp", "cff", opcodePlayLoopSound3DVP, + opcodePlayLoopSound3DVPExplicit); + extensions.registerInstruction ("stopsound", "c", opcodeStopSound, + opcodeStopSoundExplicit); + extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying, + opcodeGetSoundPlayingExplicit); } void installOpcodes (Interpreter::Interpreter& interpreter) @@ -227,6 +381,21 @@ namespace MWScript interpreter.installSegment5 (opcodePlayLoopSound3DVP, new OpPlaySoundVP3D (true)); interpreter.installSegment5 (opcodeStopSound, new OpStopSound); interpreter.installSegment5 (opcodeGetSoundPlaying, new OpGetSoundPlaying); + + interpreter.installSegment5 (opcodeSayExplicit, new OpSayExplicit); + interpreter.installSegment5 (opcodeSayDoneExplicit, new OpSayDoneExplicit); + interpreter.installSegment5 (opcodePlaySound3DExplicit, + new OpPlaySound3DExplicit (false)); + interpreter.installSegment5 (opcodePlaySound3DVPExplicit, + new OpPlaySoundVP3DExplicit (false)); + interpreter.installSegment5 (opcodePlayLoopSound3DExplicit, + new OpPlaySound3DExplicit (true)); + interpreter.installSegment5 (opcodePlayLoopSound3DVPExplicit, + new OpPlaySoundVP3DExplicit (true)); + interpreter.installSegment5 (opcodeStopSoundExplicit, new OpStopSoundExplicit); + interpreter.installSegment5 (opcodeGetSoundPlayingExplicit, + new OpGetSoundPlayingExplicit); } } } + From 0f742ce7f9deb3fed38ff1d21d61b6c27e6776ed Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Jul 2010 12:31:00 +0200 Subject: [PATCH 6/9] even better error checking for extensions with explicit references --- components/compiler/exprparser.cpp | 4 ++-- components/compiler/extensions.cpp | 12 ++++++++++-- components/compiler/extensions.hpp | 6 ++++-- components/compiler/lineparser.cpp | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/components/compiler/exprparser.cpp b/components/compiler/exprparser.cpp index db7f8a2d2..d0138078e 100644 --- a/components/compiler/exprparser.cpp +++ b/components/compiler/exprparser.cpp @@ -331,7 +331,7 @@ namespace Compiler char returnType; std::string argumentType; - if (extensions->isFunction (keyword, returnType, argumentType)) + if (extensions->isFunction (keyword, returnType, argumentType, true)) { mTokenLoc = loc; parseArguments (argumentType, scanner); @@ -434,7 +434,7 @@ namespace Compiler char returnType; std::string argumentType; - if (extensions->isFunction (keyword, returnType, argumentType)) + if (extensions->isFunction (keyword, returnType, argumentType, false)) { mTokenLoc = loc; parseArguments (argumentType, scanner); diff --git a/components/compiler/extensions.cpp b/components/compiler/extensions.cpp index 8aef21407..78ae0fdfd 100644 --- a/components/compiler/extensions.cpp +++ b/components/compiler/extensions.cpp @@ -21,24 +21,32 @@ namespace Compiler return iter->second; } - bool Extensions::isFunction (int keyword, char& returnType, std::string& argumentType) const + bool Extensions::isFunction (int keyword, char& returnType, std::string& argumentType, + bool explicitReference) const { std::map::const_iterator iter = mFunctions.find (keyword); if (iter==mFunctions.end()) return false; + if (explicitReference && iter->second.mCodeExplicit==-1) + return false; + returnType = iter->second.mReturn; argumentType = iter->second.mArguments; return true; } - bool Extensions::isInstruction (int keyword, std::string& argumentType) const + bool Extensions::isInstruction (int keyword, std::string& argumentType, + bool explicitReference) const { std::map::const_iterator iter = mInstructions.find (keyword); if (iter==mInstructions.end()) return false; + + if (explicitReference && iter->second.mCodeExplicit==-1) + return false; argumentType = iter->second.mArguments; return true; diff --git a/components/compiler/extensions.hpp b/components/compiler/extensions.hpp index f1a856818..85a761951 100644 --- a/components/compiler/extensions.hpp +++ b/components/compiler/extensions.hpp @@ -44,11 +44,13 @@ namespace Compiler /// - if no match is found 0 is returned. /// - keyword must be all lower case. - bool isFunction (int keyword, char& returnType, std::string& argumentType) const; + bool isFunction (int keyword, char& returnType, std::string& argumentType, + bool explicitReference) const; ///< Is this keyword registered with a function? If yes, return return and argument /// types. - bool isInstruction (int keyword, std::string& argumentType) const; + bool isInstruction (int keyword, std::string& argumentType, + bool explicitReference) const; ///< Is this keyword registered with a function? If yes, return argument types. void registerFunction (const std::string& keyword, char returnType, diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 3be38bce4..22f7f458d 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -163,7 +163,7 @@ namespace Compiler { std::string argumentType; - if (extensions->isInstruction (keyword, argumentType)) + if (extensions->isInstruction (keyword, argumentType, mState==ExplicitState)) { mExprParser.parseArguments (argumentType, scanner, mCode, true); From 8134c5b7602b5fe31c4d59082b707683c6763732 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 10 Jul 2010 13:19:04 +0200 Subject: [PATCH 7/9] integrated CellStore pointer into Ptr class --- apps/openmw/mwscript/interpretercontext.cpp | 27 ++-- apps/openmw/mwscript/interpretercontext.hpp | 8 +- apps/openmw/mwscript/soundextensions.cpp | 15 +- apps/openmw/mwworld/ptr.hpp | 16 +- apps/openmw/mwworld/world.cpp | 158 +++++++------------- apps/openmw/mwworld/world.hpp | 19 +-- 6 files changed, 99 insertions(+), 144 deletions(-) diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index a0f1d9d95..239c558bd 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -16,11 +16,9 @@ namespace MWScript { - InterpreterContext::PtrWithCell InterpreterContext::getReference ( + MWWorld::Ptr InterpreterContext::getReference ( const std::string& id, bool activeOnly) { - PtrWithCell ref; - if (!id.empty()) { return mEnvironment.mWorld->getPtr (id, activeOnly); @@ -30,15 +28,13 @@ namespace MWScript if (mReference.isEmpty()) throw std::runtime_error ("no implicit reference"); - return PtrWithCell (mReference, mEnvironment.mWorld->find (mReference)); + return mReference; } } - InterpreterContext::CPtrWithCell InterpreterContext::getReference ( + const MWWorld::Ptr InterpreterContext::getReference ( const std::string& id, bool activeOnly) const { - CPtrWithCell ref; - if (!id.empty()) { return mEnvironment.mWorld->getPtr (id, activeOnly); @@ -48,7 +44,7 @@ namespace MWScript if (mReference.isEmpty()) throw std::runtime_error ("no implicit reference"); - return CPtrWithCell (mReference, mEnvironment.mWorld->find (mReference)); + return mReference; } } @@ -179,15 +175,14 @@ namespace MWScript float InterpreterContext::getDistance (const std::string& name, const std::string& id) const { // TODO handle exterior cells (when ref and ref2 are located in different cells) - CPtrWithCell ref2 = getReference (id, false); + const MWWorld::Ptr ref2 = getReference (id, false); - std::pair ref = - mEnvironment.mWorld->getPtr (name, true); + const MWWorld::Ptr ref = mEnvironment.mWorld->getPtr (name, true); double diff[3]; for (int i=0; i<3; ++i) - diff[i] = ref.first.getCellRef().pos.pos[i] - ref2.first.getCellRef().pos.pos[i]; + diff[i] = ref.getCellRef().pos.pos[i] - ref2.getCellRef().pos.pos[i]; return std::sqrt (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]); } @@ -204,19 +199,19 @@ namespace MWScript bool InterpreterContext::isDisabled (const std::string& id) const { - CPtrWithCell ref = getReference (id, false); - return !ref.first.getRefData().isEnabled(); + const MWWorld::Ptr ref = getReference (id, false); + return !ref.getRefData().isEnabled(); } void InterpreterContext::enable (const std::string& id) { - PtrWithCell ref = getReference (id, false); + MWWorld::Ptr ref = getReference (id, false); mEnvironment.mWorld->enable (ref); } void InterpreterContext::disable (const std::string& id) { - PtrWithCell ref = getReference (id, false); + MWWorld::Ptr ref = getReference (id, false); mEnvironment.mWorld->disable (ref); } diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index 14c0a9e85..ac719f151 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -22,12 +22,10 @@ namespace MWScript Locals *mLocals; MWWorld::Ptr mReference; - typedef std::pair PtrWithCell; - typedef std::pair CPtrWithCell; - PtrWithCell getReference (const std::string& id, bool activeOnly); - - CPtrWithCell getReference (const std::string& id, bool activeOnly) const; + MWWorld::Ptr getReference (const std::string& id, bool activeOnly); + + const MWWorld::Ptr getReference (const std::string& id, bool activeOnly) const; public: diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index 4a6be48b5..d7aada989 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -205,7 +205,7 @@ namespace MWScript std::string text = runtime.getStringLiteral (runtime[0]); runtime.pop(); - context.getSoundManager().say (context.getWorld().getPtr (id, true).first, + context.getSoundManager().say (context.getWorld().getPtr (id, true), file, text, context); } }; @@ -223,8 +223,7 @@ namespace MWScript runtime.pop(); runtime.push (context.getSoundManager().sayDone ( - context.getWorld().getPtr (id, true).first, - context)); + context.getWorld().getPtr (id, true), context)); } }; @@ -248,8 +247,7 @@ namespace MWScript runtime.pop(); context.getSoundManager().playSound3D ( - context.getWorld().getPtr (id, true).first, sound, - 1.0, 1.0, mLoop, context); + context.getWorld().getPtr (id, true), sound, 1.0, 1.0, mLoop, context); } }; @@ -279,8 +277,7 @@ namespace MWScript runtime.pop(); context.getSoundManager().playSound3D ( - context.getWorld().getPtr (id, true).first, sound, volume, - pitch, mLoop, context); + context.getWorld().getPtr (id, true), sound, volume, pitch, mLoop, context); } }; @@ -301,7 +298,7 @@ namespace MWScript runtime.pop(); context.getSoundManager().stopSound3D ( - context.getWorld().getPtr (id, true).first, sound, context); + context.getWorld().getPtr (id, true), sound, context); } }; @@ -321,7 +318,7 @@ namespace MWScript runtime.pop(); runtime.push (context.getSoundManager().getSoundPlaying ( - context.getWorld().getPtr (id, true).first, + context.getWorld().getPtr (id, true), runtime.getStringLiteral (index), context)); } }; diff --git a/apps/openmw/mwworld/ptr.hpp b/apps/openmw/mwworld/ptr.hpp index 9d031512d..a65fcb7cc 100644 --- a/apps/openmw/mwworld/ptr.hpp +++ b/apps/openmw/mwworld/ptr.hpp @@ -15,13 +15,18 @@ namespace MWWorld class Ptr { + public: + + typedef ESMS::CellStore CellStore; + boost::any mPtr; ESM::CellRef *mCellRef; RefData *mRefData; + CellStore *mCell; public: - Ptr() : mCellRef (0), mRefData (0) {} + Ptr() : mCellRef (0), mRefData (0), mCell (0) {} bool isEmpty() const { @@ -29,11 +34,12 @@ namespace MWWorld } template - Ptr (ESMS::LiveCellRef *liveCellRef) + Ptr (ESMS::LiveCellRef *liveCellRef, CellStore *cell) { mPtr = liveCellRef; mCellRef = &liveCellRef->ref; mRefData = &liveCellRef->mData; + mCell = cell; } template @@ -53,6 +59,12 @@ namespace MWWorld assert (mRefData); return *mRefData; } + + Ptr::CellStore *getCell() const + { + assert (mCell); + return mCell; + } }; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index 8fb635ef3..840a88d7d 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -15,7 +15,8 @@ namespace { template void listCellScripts (const ESMS::ESMStore& store, - ESMS::CellRefList& cellRefList, MWWorld::World::ScriptList& scriptList) + ESMS::CellRefList& cellRefList, MWWorld::World::ScriptList& scriptList, + MWWorld::Ptr::CellStore *cell) { for (typename ESMS::CellRefList::List::iterator iter ( cellRefList.list.begin()); @@ -28,116 +29,102 @@ namespace iter->mData.setLocals (*script); scriptList.push_back ( - std::make_pair (iter->base->script, MWWorld::Ptr (&*iter))); + std::make_pair (iter->base->script, MWWorld::Ptr (&*iter, cell))); } } } } - - template - bool hasReference (ESMS::CellRefList& cellRefList, const MWWorld::Ptr& ptr) - { - for (typename ESMS::CellRefList::List::iterator iter ( - cellRefList.list.begin()); - iter!=cellRefList.list.end(); ++iter) - { - if (&iter->mData==&ptr.getRefData()) - return true; - } - - return false; - } } namespace MWWorld { void World::insertInteriorScripts (ESMS::CellStore& cell) { - listCellScripts (mStore, cell.activators, mLocalScripts); - listCellScripts (mStore, cell.potions, mLocalScripts); - listCellScripts (mStore, cell.appas, mLocalScripts); - listCellScripts (mStore, cell.armors, mLocalScripts); - listCellScripts (mStore, cell.books, mLocalScripts); - listCellScripts (mStore, cell.clothes, mLocalScripts); - listCellScripts (mStore, cell.containers, mLocalScripts); - listCellScripts (mStore, cell.creatures, mLocalScripts); - listCellScripts (mStore, cell.doors, mLocalScripts); - listCellScripts (mStore, cell.ingreds, mLocalScripts); - listCellScripts (mStore, cell.lights, mLocalScripts); - listCellScripts (mStore, cell.lockpicks, mLocalScripts); - listCellScripts (mStore, cell.miscItems, mLocalScripts); - listCellScripts (mStore, cell.npcs, mLocalScripts); - listCellScripts (mStore, cell.probes, mLocalScripts); - listCellScripts (mStore, cell.repairs, mLocalScripts); - listCellScripts (mStore, cell.weapons, mLocalScripts); + listCellScripts (mStore, cell.activators, mLocalScripts, &cell); + listCellScripts (mStore, cell.potions, mLocalScripts, &cell); + listCellScripts (mStore, cell.appas, mLocalScripts, &cell); + listCellScripts (mStore, cell.armors, mLocalScripts, &cell); + listCellScripts (mStore, cell.books, mLocalScripts, &cell); + listCellScripts (mStore, cell.clothes, mLocalScripts, &cell); + listCellScripts (mStore, cell.containers, mLocalScripts, &cell); + listCellScripts (mStore, cell.creatures, mLocalScripts, &cell); + listCellScripts (mStore, cell.doors, mLocalScripts, &cell); + listCellScripts (mStore, cell.ingreds, mLocalScripts, &cell); + listCellScripts (mStore, cell.lights, mLocalScripts, &cell); + listCellScripts (mStore, cell.lockpicks, mLocalScripts, &cell); + listCellScripts (mStore, cell.miscItems, mLocalScripts, &cell); + listCellScripts (mStore, cell.npcs, mLocalScripts, &cell); + listCellScripts (mStore, cell.probes, mLocalScripts, &cell); + listCellScripts (mStore, cell.repairs, mLocalScripts, &cell); + listCellScripts (mStore, cell.weapons, mLocalScripts, &cell); } - Ptr World::getPtr (const std::string& name, CellStore& cell) + Ptr World::getPtr (const std::string& name, Ptr::CellStore& cell) { if (ESMS::LiveCellRef *ref = cell.activators.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.potions.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.appas.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.armors.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.books.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.clothes.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.containers.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.creatures.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.doors.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.ingreds.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.creatureLists.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.itemLists.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.lights.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.lockpicks.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.miscItems.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.npcs.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.probes.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.repairs.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.statics.find (name)) - return ref; + return Ptr (ref, &cell); if (ESMS::LiveCellRef *ref = cell.weapons.find (name)) - return ref; + return Ptr (ref, &cell); return Ptr(); } - MWRender::CellRender *World::searchRender (CellStore *store) + MWRender::CellRender *World::searchRender (Ptr::CellStore *store) { CellRenderCollection::iterator iter = mActiveCells.find (store); @@ -157,7 +144,7 @@ namespace MWWorld World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir, const std::string& master, const std::string& startCell, bool newGame) - : mSkyManager (0), mScene (renderer), mPlayerPos (0) + : mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0) { boost::filesystem::path masterPath (dataDir); masterPath /= master; @@ -169,6 +156,7 @@ namespace MWWorld mStore.load (mEsm); mInteriors[startCell].loadInt (startCell, mStore, mEsm); + mCurrentCell = &mInteriors[startCell]; insertInteriorScripts (mInteriors[startCell]); @@ -251,15 +239,12 @@ namespace MWWorld return iter->second; } - std::pair 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. if (name=="player") { - // TODO: find real cell (might need to be stored in playerPos). For now we - // use the first active cell. This will fail the moment we move into an - // exterior cell. - return std::make_pair (mPlayerPos->getPlayer(), mActiveCells.begin()->first); + return Ptr (mPlayerPos->getPlayer(), mCurrentCell); } // active cells @@ -269,7 +254,7 @@ namespace MWWorld Ptr ptr = getPtr (name, *iter->first); if (!ptr.isEmpty()) - return std::make_pair (ptr, iter->first); + return ptr; } if (!activeOnly) @@ -280,58 +265,29 @@ namespace MWWorld throw std::runtime_error ("unknown ID: " + name); } - void World::enable (std::pair& reference) + void World::enable (Ptr reference) { - if (!reference.first.getRefData().isEnabled()) + if (!reference.getRefData().isEnabled()) { - reference.first.getRefData().enable(); + reference.getRefData().enable(); - if (MWRender::CellRender *render = searchRender (reference.second)) + if (MWRender::CellRender *render = searchRender (reference.getCell())) { - render->enable (reference.first.getRefData().getHandle()); + render->enable (reference.getRefData().getHandle()); } } } - void World::disable (std::pair& reference) + void World::disable (Ptr reference) { - if (!reference.first.getRefData().isEnabled()) + if (!reference.getRefData().isEnabled()) { - reference.first.getRefData().enable(); + reference.getRefData().enable(); - if (MWRender::CellRender *render = searchRender (reference.second)) + if (MWRender::CellRender *render = searchRender (reference.getCell())) { - render->disable (reference.first.getRefData().getHandle()); + render->disable (reference.getRefData().getHandle()); } } } - - World::CellStore *World::find (const Ptr& ptr) - { - for (CellRenderCollection::iterator iter (mActiveCells.begin()); iter!=mActiveCells.end(); - ++iter) - { - if ( - hasReference (iter->first->activators, ptr) || - hasReference (iter->first->potions, ptr) || - hasReference (iter->first->appas, ptr) || - hasReference (iter->first->armors, ptr) || - hasReference (iter->first->books, ptr) || - hasReference (iter->first->clothes, ptr) || - hasReference (iter->first->containers, ptr) || - hasReference (iter->first->creatures, ptr) || - hasReference (iter->first->doors, ptr) || - hasReference (iter->first->ingreds, ptr) || - hasReference (iter->first->lights, ptr) || - hasReference (iter->first->lockpicks, ptr) || - hasReference (iter->first->miscItems, ptr) || - hasReference (iter->first->npcs, ptr) || - hasReference (iter->first->probes, ptr) || - hasReference (iter->first->repairs, ptr) || - hasReference (iter->first->weapons, ptr)) - return iter->first; - } - - throw std::runtime_error ("failed to locate reference in active cell"); - } } diff --git a/apps/openmw/mwworld/world.hpp b/apps/openmw/mwworld/world.hpp index 0c299b9f9..d6df3b826 100644 --- a/apps/openmw/mwworld/world.hpp +++ b/apps/openmw/mwworld/world.hpp @@ -36,20 +36,20 @@ namespace MWWorld public: typedef std::vector > ScriptList; - typedef ESMS::CellStore CellStore; private: - typedef std::map CellRenderCollection; + typedef std::map CellRenderCollection; MWRender::SkyManager* mSkyManager; MWRender::MWScene mScene; MWRender::PlayerPos *mPlayerPos; + Ptr::CellStore *mCurrentCell; // the cell, the player is in CellRenderCollection mActiveCells; CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet) ESM::ESMReader mEsm; ESMS::ESMStore mStore; - std::map mInteriors; + std::map mInteriors; ScriptList mLocalScripts; std::map mGlobalVariables; @@ -59,9 +59,9 @@ namespace MWWorld void insertInteriorScripts (ESMS::CellStore& cell); - Ptr getPtr (const std::string& name, CellStore& cellStore); + Ptr getPtr (const std::string& name, Ptr::CellStore& cellStore); - MWRender::CellRender *searchRender (CellStore *store); + MWRender::CellRender *searchRender (Ptr::CellStore *store); public: @@ -82,16 +82,13 @@ namespace MWWorld Interpreter::Type_Data& getGlobalVariable (const std::string& name); - std::pair 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. /// \param activeOnly do non search inactive cells. - void enable (std::pair& reference); + void enable (Ptr reference); - void disable (std::pair& reference); - - CellStore *find (const Ptr& ptr); - ///< Only active cells are searched. + void disable (Ptr reference); }; } From c9a63359180234ebc2d674f448501a4a0cfff077 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 14 Jul 2010 15:28:55 +0200 Subject: [PATCH 8/9] replaced flat Type_Data stack with a union --- apps/openmw/mwscript/soundextensions.cpp | 54 ++++++++--------- components/interpreter/controlopcodes.hpp | 4 +- components/interpreter/genericopcodes.hpp | 26 ++++---- components/interpreter/localopcodes.hpp | 74 +++++++++++------------ components/interpreter/mathopcodes.hpp | 46 +++++--------- components/interpreter/miscopcodes.hpp | 22 +++---- components/interpreter/runtime.cpp | 18 +++++- components/interpreter/runtime.hpp | 12 +++- components/interpreter/scriptopcodes.hpp | 8 +-- components/interpreter/spatialopcodes.hpp | 14 ++--- components/interpreter/types.hpp | 26 ++++++++ 11 files changed, 168 insertions(+), 136 deletions(-) diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index d7aada989..40229475e 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -26,10 +26,10 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string file = runtime.getStringLiteral (runtime[0]); + std::string file = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - std::string text = runtime.getStringLiteral (runtime[0]); + std::string text = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().say (context.getReference(), file, text, @@ -60,7 +60,7 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().streamMusic (sound, context); @@ -76,7 +76,7 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().playSound (sound, 1.0, 1.0, context); @@ -92,13 +92,13 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - float volume = *reinterpret_cast (&runtime[0]); + Interpreter::Type_Float volume = runtime[0].mFloat; runtime.pop(); - float pitch = *reinterpret_cast (&runtime[0]); + Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); context.getSoundManager().playSound (sound, volume, pitch, context); @@ -118,7 +118,7 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().playSound3D (context.getReference(), sound, @@ -139,13 +139,13 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - float volume = *reinterpret_cast (&runtime[0]); + Interpreter::Type_Float volume = runtime[0].mFloat; runtime.pop(); - float pitch = *reinterpret_cast (&runtime[0]); + Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); context.getSoundManager().playSound3D (context.getReference(), sound, volume, @@ -163,7 +163,7 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().stopSound3D (context.getReference(), sound, context); @@ -179,7 +179,7 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); runtime.push (context.getSoundManager().getSoundPlaying ( @@ -196,13 +196,13 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0]); + std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - std::string file = runtime.getStringLiteral (runtime[0]); + std::string file = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - std::string text = runtime.getStringLiteral (runtime[0]); + std::string text = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().say (context.getWorld().getPtr (id, true), @@ -219,7 +219,7 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0]); + std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); runtime.push (context.getSoundManager().sayDone ( @@ -240,10 +240,10 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0]); + std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().playSound3D ( @@ -264,16 +264,16 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0]); + std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - float volume = *reinterpret_cast (&runtime[0]); + Interpreter::Type_Float volume = runtime[0].mFloat; runtime.pop(); - float pitch = *reinterpret_cast (&runtime[0]); + Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); context.getSoundManager().playSound3D ( @@ -291,10 +291,10 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0]); + std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - std::string sound = runtime.getStringLiteral (runtime[0]); + std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); context.getSoundManager().stopSound3D ( @@ -311,10 +311,10 @@ namespace MWScript MWScript::InterpreterContext& context = static_cast (runtime.getContext()); - std::string id = runtime.getStringLiteral (runtime[0]); + std::string id = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); runtime.push (context.getSoundManager().getSoundPlaying ( diff --git a/components/interpreter/controlopcodes.hpp b/components/interpreter/controlopcodes.hpp index cf9185a69..534ccc4dd 100644 --- a/components/interpreter/controlopcodes.hpp +++ b/components/interpreter/controlopcodes.hpp @@ -24,7 +24,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; + Type_Integer data = runtime[0].mInteger; runtime.pop(); if (data==0) @@ -38,7 +38,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; + Type_Integer data = runtime[0].mInteger; runtime.pop(); if (data!=0) diff --git a/components/interpreter/genericopcodes.hpp b/components/interpreter/genericopcodes.hpp index 116b586e4..44ef3fc6b 100644 --- a/components/interpreter/genericopcodes.hpp +++ b/components/interpreter/genericopcodes.hpp @@ -12,7 +12,7 @@ namespace Interpreter virtual void execute (Runtime& runtime, unsigned int arg0) { - runtime.push (arg0); + runtime.push (static_cast (arg0)); } }; @@ -22,9 +22,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Integer data = *reinterpret_cast (&runtime[0]); + Type_Integer data = runtime[0].mInteger; Type_Float floatValue = static_cast (data); - runtime[0] = *reinterpret_cast (&floatValue); + runtime[0].mFloat = floatValue; } }; @@ -34,9 +34,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Float data = *reinterpret_cast (&runtime[0]); + Type_Float data = runtime[0].mFloat; Type_Integer integerValue = static_cast (data); - runtime[0] = *reinterpret_cast (&integerValue); + runtime[0].mInteger = integerValue; } }; @@ -46,9 +46,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Integer data = *reinterpret_cast (&runtime[0]); + Type_Integer data = runtime[0].mInteger; data = -data; - runtime[0] = *reinterpret_cast (&data); + runtime[0].mInteger = data; } }; @@ -58,9 +58,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Float data = *reinterpret_cast (&runtime[0]); + Type_Float data = runtime[0].mFloat; data = -data; - runtime[0] = *reinterpret_cast (&data); + runtime[0].mFloat = data; } }; @@ -70,9 +70,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Integer data = *reinterpret_cast (&runtime[1]); + Type_Integer data = runtime[1].mInteger; Type_Float floatValue = static_cast (data); - runtime[1] = *reinterpret_cast (&floatValue); + runtime[1].mFloat = floatValue; } }; @@ -82,9 +82,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Float data = *reinterpret_cast (&runtime[1]); + Type_Float data = runtime[1].mFloat; Type_Integer integerValue = static_cast (data); - runtime[1] = *reinterpret_cast (&integerValue); + runtime[1].mInteger = integerValue; } }; } diff --git a/components/interpreter/localopcodes.hpp b/components/interpreter/localopcodes.hpp index 427b4b574..ea62b7ad8 100644 --- a/components/interpreter/localopcodes.hpp +++ b/components/interpreter/localopcodes.hpp @@ -13,10 +13,10 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; - int index = runtime[1]; + Type_Integer data = runtime[0].mInteger; + int index = runtime[1].mInteger; - runtime.getContext().setLocalShort (index, *reinterpret_cast (&data)); + runtime.getContext().setLocalShort (index, data); runtime.pop(); runtime.pop(); @@ -29,10 +29,10 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; - int index = runtime[1]; + Type_Integer data = runtime[0].mInteger; + int index = runtime[1].mInteger; - runtime.getContext().setLocalLong (index, *reinterpret_cast (&data)); + runtime.getContext().setLocalLong (index, data); runtime.pop(); runtime.pop(); @@ -45,10 +45,10 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; - int index = runtime[1]; + Type_Float data = runtime[0].mFloat; + int index = runtime[1].mInteger; - runtime.getContext().setLocalFloat (index, *reinterpret_cast (&data)); + runtime.getContext().setLocalFloat (index, data); runtime.pop(); runtime.pop(); @@ -61,8 +61,8 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int intValue = runtime.getIntegerLiteral (runtime[0]); - runtime[0] = intValue; + Type_Integer intValue = runtime.getIntegerLiteral (runtime[0].mInteger); + runtime[0].mInteger = intValue; } }; @@ -72,8 +72,8 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - float floatValue = runtime.getFloatLiteral (runtime[0]); - runtime[0] = *reinterpret_cast (&floatValue); + Type_Float floatValue = runtime.getFloatLiteral (runtime[0].mInteger); + runtime[0].mFloat = floatValue; } }; @@ -83,9 +83,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; int value = runtime.getContext().getLocalShort (index); - runtime[0] = *reinterpret_cast (&value); + runtime[0].mInteger = value; } }; @@ -95,9 +95,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; int value = runtime.getContext().getLocalLong (index); - runtime[0] = *reinterpret_cast (&value); + runtime[0].mInteger = value; } }; @@ -107,9 +107,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; float value = runtime.getContext().getLocalFloat (index); - runtime[0] = *reinterpret_cast (&value); + runtime[0].mFloat = value; } }; @@ -119,12 +119,12 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; - int index = runtime[1]; + Type_Integer data = runtime[0].mInteger; + int index = runtime[1].mInteger; std::string name = runtime.getStringLiteral (index); - runtime.getContext().setGlobalShort (name, *reinterpret_cast (&data)); + runtime.getContext().setGlobalShort (name, data); runtime.pop(); runtime.pop(); @@ -137,12 +137,12 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; - int index = runtime[1]; + Type_Integer data = runtime[0].mInteger; + int index = runtime[1].mInteger; std::string name = runtime.getStringLiteral (index); - runtime.getContext().setGlobalLong (name, *reinterpret_cast (&data)); + runtime.getContext().setGlobalLong (name, data); runtime.pop(); runtime.pop(); @@ -155,12 +155,12 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Data data = runtime[0]; - int index = runtime[1]; + Type_Float data = runtime[0].mFloat; + int index = runtime[1].mInteger; std::string name = runtime.getStringLiteral (index); - runtime.getContext().setGlobalFloat (name, *reinterpret_cast (&data)); + runtime.getContext().setGlobalFloat (name, data); runtime.pop(); runtime.pop(); @@ -173,10 +173,10 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; std::string name = runtime.getStringLiteral (index); - int value = runtime.getContext().getGlobalShort (name); - runtime[0] = *reinterpret_cast (&value); + Type_Integer value = runtime.getContext().getGlobalShort (name); + runtime[0].mInteger = value; } }; @@ -186,10 +186,10 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; std::string name = runtime.getStringLiteral (index); - int value = runtime.getContext().getGlobalLong (name); - runtime[0] = *reinterpret_cast (&value); + Type_Integer value = runtime.getContext().getGlobalLong (name); + runtime[0].mInteger = value; } }; @@ -199,10 +199,10 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; std::string name = runtime.getStringLiteral (index); - float value = runtime.getContext().getGlobalFloat (name); - runtime[0] = *reinterpret_cast (&value); + Type_Float value = runtime.getContext().getGlobalFloat (name); + runtime[0].mFloat = value; } }; } diff --git a/components/interpreter/mathopcodes.hpp b/components/interpreter/mathopcodes.hpp index d569a5470..14d5d98df 100644 --- a/components/interpreter/mathopcodes.hpp +++ b/components/interpreter/mathopcodes.hpp @@ -16,14 +16,11 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - T result = - *reinterpret_cast (&runtime[1]) - + - *reinterpret_cast (&runtime[0]); + T result = getData (runtime[1]) + getData (runtime[0]); runtime.pop(); - runtime[0] = *reinterpret_cast (&result); + getData (runtime[0]) = result; } }; @@ -34,14 +31,11 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - T result = - *reinterpret_cast (&runtime[1]) - - - *reinterpret_cast (&runtime[0]); + T result = getData (runtime[1]) - getData (runtime[0]); runtime.pop(); - - runtime[0] = *reinterpret_cast (&result); + + getData (runtime[0]) = result; } }; @@ -52,14 +46,11 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - T result = - *reinterpret_cast (&runtime[1]) - * - *reinterpret_cast (&runtime[0]); + T result = getData (runtime[1]) * getData (runtime[0]); runtime.pop(); - - runtime[0] = *reinterpret_cast (&result); + + getData (runtime[0]) = result; } }; @@ -70,19 +61,16 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - T left = *reinterpret_cast (&runtime[0]); + T left = getData (runtime[0]); if (left==0) throw std::runtime_error ("division by zero"); - T result = - *reinterpret_cast (&runtime[1]) - / - left; + T result = getData (runtime[1]) / left; runtime.pop(); - - runtime[0] = *reinterpret_cast (&result); + + getData (runtime[0]) = result; } }; @@ -92,7 +80,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - Type_Float value = *reinterpret_cast (&runtime[0]); + Type_Float value = runtime[0].mFloat; if (value<0) throw std::runtime_error ( @@ -100,7 +88,7 @@ namespace Interpreter value = std::sqrt (value); - runtime[0] = *reinterpret_cast (&value); + runtime[0].mFloat = value; } }; @@ -111,13 +99,11 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int result = C() ( - *reinterpret_cast (&runtime[1]), - *reinterpret_cast (&runtime[0])); + int result = C() (getData (runtime[1]), getData (runtime[0])); runtime.pop(); - runtime[0] = *reinterpret_cast (&result); + runtime[0].mInteger = result; } }; } diff --git a/components/interpreter/miscopcodes.hpp b/components/interpreter/miscopcodes.hpp index 852d2d154..8d05c58da 100644 --- a/components/interpreter/miscopcodes.hpp +++ b/components/interpreter/miscopcodes.hpp @@ -22,7 +22,7 @@ namespace Interpreter throw std::logic_error ("message box buttons not implemented yet"); // message - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); std::string message = runtime.getStringLiteral (index); @@ -44,13 +44,13 @@ namespace Interpreter if (c=='S' || c=='s') { - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); formattedMessage += runtime.getStringLiteral (index); } else if (c=='g' || c=='G') { - int value = *reinterpret_cast (&runtime[0]); + Type_Integer value = runtime[0].mInteger; runtime.pop(); std::ostringstream out; @@ -64,7 +64,7 @@ namespace Interpreter ++i; } - float value = *reinterpret_cast (&runtime[0]); + float value = runtime[0].mFloat; runtime.pop(); std::ostringstream out; @@ -107,7 +107,7 @@ namespace Interpreter { double r = static_cast (std::rand()) / RAND_MAX; // [0, 1) - Type_Integer limit = *reinterpret_cast (&runtime[0]); + Type_Integer limit = runtime[0].mInteger; if (limit<0) throw std::runtime_error ( @@ -115,7 +115,7 @@ namespace Interpreter Type_Integer value = static_cast (r*limit); // [o, limit) - runtime[0] = *reinterpret_cast (&value); + runtime[0].mInteger = value; } }; @@ -125,9 +125,9 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - float duration = runtime.getContext().getSecondsPassed(); + Type_Float duration = runtime.getContext().getSecondsPassed(); - runtime.push (*reinterpret_cast (&duration)); + runtime.push (duration); } }; @@ -167,7 +167,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); std::string id = runtime.getStringLiteral (index); @@ -181,7 +181,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); std::string id = runtime.getStringLiteral (index); @@ -195,7 +195,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); std::string id = runtime.getStringLiteral (index); diff --git a/components/interpreter/runtime.cpp b/components/interpreter/runtime.cpp index 746be60d2..f3a3a905d 100644 --- a/components/interpreter/runtime.cpp +++ b/components/interpreter/runtime.cpp @@ -68,11 +68,25 @@ namespace Interpreter mPC = PC; } - void Runtime::push (Type_Data data) + void Runtime::push (const Data& data) { mStack.push_back (data); } + void Runtime::push (Type_Integer value) + { + Data data; + data.mInteger = value; + push (data); + } + + void Runtime::push (Type_Float value) + { + Data data; + data.mFloat = value; + push (data); + } + void Runtime::pop() { if (mStack.empty()) @@ -81,7 +95,7 @@ namespace Interpreter mStack.resize (mStack.size()-1); } - Type_Data& Runtime::operator[] (int Index) + Data& Runtime::operator[] (int Index) { if (Index<0 || Index>=static_cast (mStack.size())) throw std::runtime_error ("stack index out of range"); diff --git a/components/interpreter/runtime.hpp b/components/interpreter/runtime.hpp index 73e90f68a..e9ba01041 100644 --- a/components/interpreter/runtime.hpp +++ b/components/interpreter/runtime.hpp @@ -18,7 +18,7 @@ namespace Interpreter const Type_Code *mCode; int mCodeSize; int mPC; - std::vector mStack; + std::vector mStack; public: @@ -42,13 +42,19 @@ namespace Interpreter void setPC (int PC); ///< set program counter. - void push (Type_Data data); + void push (const Data& data); ///< push data on stack + void push (Type_Integer value); + ///< push integer data on stack. + + void push (Type_Float value); + ///< push float data on stack. + void pop(); ///< pop stack - Type_Data& operator[] (int Index); + Data& operator[] (int Index); ///< Access stack member, counted from the top. Context& getContext(); diff --git a/components/interpreter/scriptopcodes.hpp b/components/interpreter/scriptopcodes.hpp index 84fd546fb..56502d510 100644 --- a/components/interpreter/scriptopcodes.hpp +++ b/components/interpreter/scriptopcodes.hpp @@ -13,8 +13,8 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - std::string name = runtime.getStringLiteral (runtime[0]); - runtime[0] = runtime.getContext().isScriptRunning (name); + std::string name = runtime.getStringLiteral (runtime[0].mInteger); + runtime[0].mInteger = runtime.getContext().isScriptRunning (name); } }; @@ -24,7 +24,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - std::string name = runtime.getStringLiteral (runtime[0]); + std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); runtime.getContext().startScript (name); } @@ -36,7 +36,7 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - std::string name = runtime.getStringLiteral (runtime[0]); + std::string name = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); runtime.getContext().stopScript (name); } diff --git a/components/interpreter/spatialopcodes.hpp b/components/interpreter/spatialopcodes.hpp index d897ff69d..e37df8116 100644 --- a/components/interpreter/spatialopcodes.hpp +++ b/components/interpreter/spatialopcodes.hpp @@ -12,11 +12,11 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - std::string name = runtime.getStringLiteral (runtime[0]); + std::string name = runtime.getStringLiteral (runtime[0].mInteger); - float distance = runtime.getContext().getDistance (name); + Type_Float distance = runtime.getContext().getDistance (name); - runtime[0] = *reinterpret_cast (&distance); + runtime[0].mFloat = distance; } }; @@ -26,15 +26,15 @@ namespace Interpreter virtual void execute (Runtime& runtime) { - int index = runtime[0]; + int index = runtime[0].mInteger; runtime.pop(); std::string id = runtime.getStringLiteral (index); - std::string name = runtime.getStringLiteral (runtime[0]); + std::string name = runtime.getStringLiteral (runtime[0].mInteger); - float distance = runtime.getContext().getDistance (name, id); + Type_Float distance = runtime.getContext().getDistance (name, id); - runtime[0] = *reinterpret_cast (&distance); + runtime[0].mFloat = distance; } }; } diff --git a/components/interpreter/types.hpp b/components/interpreter/types.hpp index 2747d1447..89529189f 100644 --- a/components/interpreter/types.hpp +++ b/components/interpreter/types.hpp @@ -1,6 +1,8 @@ #ifndef INTERPRETER_TYPES_H_INCLUDED #define INTERPRETER_TYPES_H_INCLUDED +#include + namespace Interpreter { typedef unsigned int Type_Code; // 32 bit @@ -12,6 +14,30 @@ namespace Interpreter typedef int Type_Integer; // 32 bit typedef float Type_Float; // 32 bit + + union Data + { + Type_Integer mInteger; + Type_Float mFloat; + }; + + template + T& getData (Data& data) + { + throw std::runtime_error ("unsupported data type"); + } + + template<> + inline Type_Integer& getData (Data& data) + { + return data.mInteger; + } + + template<> + inline Type_Float& getData (Data& data) + { + return data.mFloat; + } } #endif From 72f20e7d62629f1284d493f43495747dd61c276d Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Fri, 16 Jul 2010 10:29:15 +0200 Subject: [PATCH 9/9] Mangle update --- libs/mangle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/mangle b/libs/mangle index eed875ae0..9f21081c1 160000 --- a/libs/mangle +++ b/libs/mangle @@ -1 +1 @@ -Subproject commit eed875ae043c3c48fd23e18342c17d6f2331cc17 +Subproject commit 9f21081c13f70bc41e20b50c19ed2dac9b458833