mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-29 03:26:38 +00:00 
			
		
		
		
	Merge branch 'master' of http://github.com/zinnschlag/openmw
This commit is contained in:
		
						commit
						b4084081ed
					
				
					 34 changed files with 829 additions and 559 deletions
				
			
		|  | @ -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; | ||||
|     } | ||||
|  |  | |||
|  | @ -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; | ||||
|              | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -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); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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; | ||||
|         }     | ||||
|     } | ||||
|      | ||||
|  | @ -176,18 +172,17 @@ 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"); | ||||
|              | ||||
|         std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> ref = | ||||
|             mEnvironment.mWorld->getPtr (name, true); | ||||
|         // TODO handle exterior cells (when ref and ref2 are located in different cells)
 | ||||
|         const MWWorld::Ptr ref2 = getReference (id, false); | ||||
|                      | ||||
|         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] - mReference.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); | ||||
|     } | ||||
|      | ||||
|  |  | |||
|  | @ -22,12 +22,10 @@ namespace MWScript | |||
|             Locals *mLocals; | ||||
|             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; | ||||
|             MWWorld::Ptr getReference (const std::string& id, bool activeOnly); | ||||
| 
 | ||||
|             const MWWorld::Ptr getReference (const std::string& id, bool activeOnly) const; | ||||
| 
 | ||||
|         public: | ||||
|          | ||||
|  | @ -70,7 +68,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; | ||||
|              | ||||
|  |  | |||
|  | @ -15,8 +15,7 @@ | |||
| #include <components/interpreter/installopcodes.hpp> | ||||
| #include <components/interpreter/interpreter.hpp> | ||||
| 
 | ||||
| #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); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										398
									
								
								apps/openmw/mwscript/soundextensions.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								apps/openmw/mwscript/soundextensions.cpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,398 @@ | |||
| 
 | ||||
| #include "extensions.hpp" | ||||
| 
 | ||||
| #include <components/compiler/extensions.hpp> | ||||
| 
 | ||||
| #include <components/interpreter/interpreter.hpp> | ||||
| #include <components/interpreter/runtime.hpp> | ||||
| #include <components/interpreter/opcodes.hpp> | ||||
| 
 | ||||
| #include "interpretercontext.hpp" | ||||
| 
 | ||||
| #include "../mwworld/world.hpp" | ||||
| 
 | ||||
| #include "../mwsound/soundmanager.hpp" | ||||
| 
 | ||||
| namespace MWScript | ||||
| { | ||||
|     namespace Sound | ||||
|     { | ||||
|         class OpSay : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string file = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     std::string text = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().say (context.getReference(), file, text, | ||||
|                         context); | ||||
|                 }  | ||||
|         };    | ||||
|              | ||||
|         class OpSayDone : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                          | ||||
|                     runtime.push (context.getSoundManager().sayDone (context.getReference(), | ||||
|                         context)); | ||||
|                 }  | ||||
|         };     | ||||
|      | ||||
|         class OpStreamMusic : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().streamMusic (sound, context); | ||||
|                 }  | ||||
|         };       | ||||
| 
 | ||||
|         class OpPlaySound : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().playSound (sound, 1.0, 1.0, context); | ||||
|                 }  | ||||
|         };       | ||||
|      | ||||
|         class OpPlaySoundVP : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                      | ||||
|                     Interpreter::Type_Float volume = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     Interpreter::Type_Float pitch = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().playSound (sound, volume, pitch, context); | ||||
|                 }  | ||||
|         };       | ||||
|      | ||||
|         class OpPlaySound3D : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 bool mLoop; | ||||
|                  | ||||
|             public: | ||||
|              | ||||
|                 OpPlaySound3D (bool loop) : mLoop (loop) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     context.getSoundManager().playSound3D (context.getReference(), sound, | ||||
|                         1.0, 1.0, mLoop, context); | ||||
|                 }  | ||||
|         };       | ||||
|      | ||||
|         class OpPlaySoundVP3D : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 bool mLoop; | ||||
|                       | ||||
|             public: | ||||
|              | ||||
|                 OpPlaySoundVP3D (bool loop) : mLoop (loop) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                          | ||||
|                     Interpreter::Type_Float volume = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     Interpreter::Type_Float pitch = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().playSound3D (context.getReference(), sound, volume, | ||||
|                         pitch, mLoop, context); | ||||
| 
 | ||||
|                 }  | ||||
|         };      | ||||
| 
 | ||||
|         class OpStopSound : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     context.getSoundManager().stopSound3D (context.getReference(), sound, context); | ||||
|                 }  | ||||
|         };       | ||||
|                                  | ||||
|         class OpGetSoundPlaying : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                          | ||||
|                     int index = runtime[0].mInteger; | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     runtime.push (context.getSoundManager().getSoundPlaying ( | ||||
|                         context.getReference(), runtime.getStringLiteral (index), context)); | ||||
|                 }  | ||||
|         }; | ||||
|          | ||||
|         class OpSayExplicit : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                     | ||||
|                     std::string file = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     std::string text = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().say (context.getWorld().getPtr (id, true), | ||||
|                         file, text, context); | ||||
|                 }  | ||||
|         };    | ||||
|              | ||||
|         class OpSayDoneExplicit : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     runtime.push (context.getSoundManager().sayDone ( | ||||
|                         context.getWorld().getPtr (id, true), 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<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                         | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     context.getSoundManager().playSound3D ( | ||||
|                         context.getWorld().getPtr (id, true), 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<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                         | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                          | ||||
|                     Interpreter::Type_Float volume = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     Interpreter::Type_Float pitch = runtime[0].mFloat; | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().playSound3D ( | ||||
|                         context.getWorld().getPtr (id, true), sound, volume, pitch, mLoop, context); | ||||
| 
 | ||||
|                 }  | ||||
|         };      | ||||
| 
 | ||||
|         class OpStopSoundExplicit : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop();                    | ||||
|                      | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     context.getSoundManager().stopSound3D ( | ||||
|                         context.getWorld().getPtr (id, true), sound, context); | ||||
|                 }  | ||||
|         };       | ||||
|                                  | ||||
|         class OpGetSoundPlayingExplicit : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
| 
 | ||||
|                     std::string id = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     int index = runtime[0].mInteger; | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     runtime.push (context.getSoundManager().getSoundPlaying ( | ||||
|                         context.getWorld().getPtr (id, true), | ||||
|                         runtime.getStringLiteral (index), context)); | ||||
|                 }  | ||||
|         };         | ||||
|              | ||||
|         const int opcodeSay = 0x2000001; | ||||
|         const int opcodeSayDone = 0x2000002; | ||||
|         const int opcodeStreamMusic = 0x2000003; | ||||
|         const int opcodePlaySound = 0x2000004; | ||||
|         const int opcodePlaySoundVP = 0x2000005; | ||||
|         const int opcodePlaySound3D = 0x2000006; | ||||
|         const int opcodePlaySound3DVP = 0x2000007; | ||||
|         const int opcodePlayLoopSound3D = 0x2000008; | ||||
|         const int opcodePlayLoopSound3DVP = 0x2000009; | ||||
|         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, 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, | ||||
|                 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) | ||||
|         { | ||||
|             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); | ||||
|              | ||||
|             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); | ||||
|         } | ||||
|     }     | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										27
									
								
								apps/openmw/mwscript/soundextensions.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								apps/openmw/mwscript/soundextensions.hpp
									
									
									
									
									
										Normal file
									
								
							|  | @ -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 | ||||
| 
 | ||||
|  | @ -1,236 +0,0 @@ | |||
| 
 | ||||
| #include "extensions.hpp" | ||||
| 
 | ||||
| #include <components/compiler/extensions.hpp> | ||||
| 
 | ||||
| #include <components/interpreter/interpreter.hpp> | ||||
| #include <components/interpreter/runtime.hpp> | ||||
| #include <components/interpreter/opcodes.hpp> | ||||
| 
 | ||||
| #include "../mwscript/interpretercontext.hpp" | ||||
| 
 | ||||
| #include "../mwworld/world.hpp" | ||||
| 
 | ||||
| #include "soundmanager.hpp" | ||||
| 
 | ||||
| namespace MWSound | ||||
| { | ||||
|     namespace Script | ||||
|     { | ||||
|         class OpSay : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string file = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     std::string text = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().say (context.getReference(), file, text, | ||||
|                         context); | ||||
|                 }  | ||||
|         };    | ||||
|              | ||||
|         class OpSayDone : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                          | ||||
|                     runtime.push (context.getSoundManager().sayDone (context.getReference(), | ||||
|                         context)); | ||||
|                 }  | ||||
|         };     | ||||
|      | ||||
|         class OpStreamMusic : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().streamMusic (sound, context); | ||||
|                 }  | ||||
|         };       | ||||
| 
 | ||||
|         class OpPlaySound : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().playSound (sound, 1.0, 1.0, context); | ||||
|                 }  | ||||
|         };       | ||||
|      | ||||
|         class OpPlaySoundVP : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                      | ||||
|                     float volume = *reinterpret_cast<float *> (&runtime[0]); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     float pitch = *reinterpret_cast<float *> (&runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().playSound (sound, volume, pitch, context); | ||||
|                 }  | ||||
|         };       | ||||
|      | ||||
|         class OpPlaySound3D : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 bool mLoop; | ||||
|                  | ||||
|             public: | ||||
|              | ||||
|                 OpPlaySound3D (bool loop) : mLoop (loop) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     context.getSoundManager().playSound3D (context.getReference(), sound, | ||||
|                         1.0, 1.0, mLoop, context); | ||||
|                 }  | ||||
|         };       | ||||
|      | ||||
|         class OpPlaySoundVP3D : public Interpreter::Opcode0 | ||||
|         { | ||||
|                 bool mLoop; | ||||
|                       | ||||
|             public: | ||||
|              | ||||
|                 OpPlaySoundVP3D (bool loop) : mLoop (loop) {} | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                                          | ||||
|                     float volume = *reinterpret_cast<float *> (&runtime[0]); | ||||
|                     runtime.pop(); | ||||
| 
 | ||||
|                     float pitch = *reinterpret_cast<float *> (&runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     context.getSoundManager().playSound3D (context.getReference(), sound, volume, | ||||
|                         pitch, mLoop, context); | ||||
| 
 | ||||
|                 }  | ||||
|         };      | ||||
| 
 | ||||
|         class OpStopSound : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                     | ||||
|                     std::string sound = runtime.getStringLiteral (runtime[0]); | ||||
|                     runtime.pop(); | ||||
|                                              | ||||
|                     context.getSoundManager().stopSound3D (context.getReference(), sound, context); | ||||
|                 }  | ||||
|         };       | ||||
|                                  | ||||
|         class OpGetSoundPlaying : public Interpreter::Opcode0 | ||||
|         { | ||||
|             public: | ||||
|              | ||||
|                 virtual void execute (Interpreter::Runtime& runtime) | ||||
|                 { | ||||
|                     MWScript::InterpreterContext& context | ||||
|                         = static_cast<MWScript::InterpreterContext&> (runtime.getContext()); | ||||
|                          | ||||
|                     int index = runtime[0]; | ||||
|                     runtime.pop(); | ||||
|                          | ||||
|                     runtime.push (context.getSoundManager().getSoundPlaying ( | ||||
|                         context.getReference(), runtime.getStringLiteral (index), context)); | ||||
|                 }  | ||||
|         }; | ||||
|              | ||||
|         const int opcodeSay = 0x2000001; | ||||
|         const int opcodeSayDone = 0x2000002; | ||||
|         const int opcodeStreamMusic = 0x2000003; | ||||
|         const int opcodePlaySound = 0x2000004; | ||||
|         const int opcodePlaySoundVP = 0x2000005; | ||||
|         const int opcodePlaySound3D = 0x2000006; | ||||
|         const int opcodePlaySound3DVP = 0x2000007; | ||||
|         const int opcodePlayLoopSound3D = 0x2000008; | ||||
|         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); | ||||
|     } | ||||
| } | ||||
|  | @ -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 | ||||
| 
 | ||||
|  | @ -15,13 +15,18 @@ namespace MWWorld | |||
|      | ||||
|     class Ptr | ||||
|     { | ||||
|         public: | ||||
|          | ||||
|             typedef ESMS::CellStore<RefData> 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<typename T> | ||||
|             Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef) | ||||
|             Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef, CellStore *cell) | ||||
|             { | ||||
|                 mPtr = liveCellRef; | ||||
|                 mCellRef = &liveCellRef->ref; | ||||
|                 mRefData = &liveCellRef->mData; | ||||
|                 mCell = cell; | ||||
|             } | ||||
|              | ||||
|             template<typename T> | ||||
|  | @ -53,6 +59,12 @@ namespace MWWorld | |||
|                 assert (mRefData); | ||||
|                 return *mRefData; | ||||
|             } | ||||
|              | ||||
|             Ptr::CellStore *getCell() const | ||||
|             { | ||||
|                 assert (mCell); | ||||
|                 return mCell; | ||||
|             } | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,7 +15,8 @@ namespace | |||
| { | ||||
|     template<typename T> | ||||
|     void listCellScripts (const ESMS::ESMStore& store, | ||||
|         ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, MWWorld::World::ScriptList& scriptList) | ||||
|         ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, MWWorld::World::ScriptList& scriptList, | ||||
|         MWWorld::Ptr::CellStore *cell) | ||||
|     { | ||||
|         for (typename ESMS::CellRefList<T, MWWorld::RefData>::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<typename T> | ||||
|     bool hasReference (ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, const MWWorld::Ptr& ptr) | ||||
|     { | ||||
|         for (typename ESMS::CellRefList<T, MWWorld::RefData>::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<RefData>& 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<ESM::Activator, RefData> *ref = cell.activators.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
| 
 | ||||
|         if (ESMS::LiveCellRef<ESM::Potion, RefData> *ref = cell.potions.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Apparatus, RefData> *ref = cell.appas.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Armor, RefData> *ref = cell.armors.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Book, RefData> *ref = cell.books.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Clothing, RefData> *ref = cell.clothes.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Container, RefData> *ref = cell.containers.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Creature, RefData> *ref = cell.creatures.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Door, RefData> *ref = cell.doors.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Ingredient, RefData> *ref = cell.ingreds.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::CreatureLevList, RefData> *ref = cell.creatureLists.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::ItemLevList, RefData> *ref = cell.itemLists.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Light, RefData> *ref = cell.lights.find (name)) | ||||
|             return ref; | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.lockpicks.find (name)) | ||||
|             return ref;                 | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Misc, RefData> *ref = cell.miscItems.find (name)) | ||||
|             return ref;                 | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::NPC, RefData> *ref = cell.npcs.find (name)) | ||||
|             return ref;                 | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.probes.find (name)) | ||||
|             return ref;                 | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.repairs.find (name)) | ||||
|             return ref;                 | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Static, RefData> *ref = cell.statics.find (name)) | ||||
|             return ref;                 | ||||
|             return Ptr (ref, &cell); | ||||
|              | ||||
|         if (ESMS::LiveCellRef<ESM::Weapon, RefData> *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<Ptr, World::CellStore *> 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<Ptr, CellStore *>& 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<Ptr, CellStore *>& 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"); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -36,20 +36,20 @@ namespace MWWorld | |||
|         public: | ||||
|          | ||||
|             typedef std::vector<std::pair<std::string, Ptr> > ScriptList; | ||||
|             typedef ESMS::CellStore<RefData> CellStore; | ||||
|          | ||||
|         private: | ||||
|          | ||||
|             typedef std::map<CellStore *, MWRender::CellRender *> CellRenderCollection; | ||||
|             typedef std::map<Ptr::CellStore *, MWRender::CellRender *> 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<std::string, CellStore> mInteriors; | ||||
|             std::map<std::string, Ptr::CellStore> mInteriors; | ||||
|             ScriptList mLocalScripts; | ||||
|             std::map<std::string, Interpreter::Type_Data> mGlobalVariables; | ||||
|      | ||||
|  | @ -59,9 +59,9 @@ namespace MWWorld | |||
|      | ||||
|             void insertInteriorScripts (ESMS::CellStore<RefData>& 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<Ptr, CellStore *> 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<Ptr, CellStore *>& reference); | ||||
|             void enable (Ptr reference); | ||||
|              | ||||
|             void disable (std::pair<Ptr, CellStore *>& reference); | ||||
|              | ||||
|             CellStore *find (const Ptr& ptr); | ||||
|             ///< Only active cells are searched.
 | ||||
|             void disable (Ptr reference); | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -311,6 +311,40 @@ 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; | ||||
|                 }                    | ||||
| 
 | ||||
|                 // check for custom extensions
 | ||||
|                 if (const Extensions *extensions = getContext().getExtensions()) | ||||
|                 { | ||||
|                     char returnType; | ||||
|                     std::string argumentType; | ||||
|                      | ||||
|                     if (extensions->isFunction (keyword, returnType, argumentType, true)) | ||||
|                     { | ||||
|                         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); | ||||
|  | @ -360,18 +394,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;         | ||||
|  | @ -400,12 +434,12 @@ 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); | ||||
|                          | ||||
|                         extensions->generateFunctionCode (keyword, mCode); | ||||
|                         extensions->generateFunctionCode (keyword, mCode, mLiterals, ""); | ||||
|                         mOperands.push_back (returnType); | ||||
|                          | ||||
|                         mNextOperand = false; | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include <stdexcept> | ||||
| 
 | ||||
| #include "generator.hpp" | ||||
| #include "literals.hpp" | ||||
| 
 | ||||
| namespace Compiler | ||||
| { | ||||
|  | @ -20,31 +21,39 @@ 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<int, Function>::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<int, Instruction>::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; | ||||
|     } | ||||
|          | ||||
|     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 +65,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 +82,34 @@ 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<Interpreter::Type_Code>& code) | ||||
|         const | ||||
|     void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code, | ||||
|         Literals& literals, const std::string& id) const | ||||
|     { | ||||
|         std::map<int, Function>::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()) | ||||
|         { | ||||
|             if (iter->second.mCodeExplicit==-1) | ||||
|                 throw std::logic_error ("explicit references not supported"); | ||||
|          | ||||
|             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<Interpreter::Type_Code>& code) | ||||
|         std::vector<Interpreter::Type_Code>& code, Literals& literals, const std::string& id) | ||||
|         const | ||||
|     { | ||||
|         std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword); | ||||
|  | @ -96,6 +117,16 @@ 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()) | ||||
|         { | ||||
|             if (iter->second.mCodeExplicit==-1) | ||||
|                 throw std::logic_error ("explicit references not supported"); | ||||
|          | ||||
|             int index = literals.addString (id); | ||||
|             Generator::pushInt (code, literals, index);         | ||||
|         } | ||||
|                          | ||||
|         code.push_back (Generator::segment5 ( | ||||
|             id.empty() ? iter->second.mCode : iter->second.mCodeExplicit)); | ||||
|     }     | ||||
| } | ||||
|  |  | |||
|  | @ -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; | ||||
|  | @ -40,33 +44,37 @@ 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, | ||||
|                 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<Interpreter::Type_Code>& code) | ||||
|                 const; | ||||
|             void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code, | ||||
|                 Literals& literals, const std::string& id) const; | ||||
|             ///< Append code for function to \a code.
 | ||||
|              | ||||
|             void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code) | ||||
|                 const; | ||||
|             void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code, | ||||
|                 Literals& literals, const std::string& id) const; | ||||
|             ///< Append code for function to \a code.            
 | ||||
|     }; | ||||
| } | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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); | ||||
|          | ||||
|  |  | |||
|  | @ -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, mState==ExplicitState)) | ||||
|                 { | ||||
|                     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) | ||||
|         { | ||||
|  |  | |||
|  | @ -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; | ||||
|              | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime, unsigned int arg0) | ||||
|             { | ||||
|                 runtime.push (arg0); | ||||
|                 runtime.push (static_cast<Type_Integer> (arg0)); | ||||
|             }         | ||||
|     }; | ||||
|      | ||||
|  | @ -22,9 +22,9 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[0]); | ||||
|                 Type_Integer data = runtime[0].mInteger; | ||||
|                 Type_Float floatValue = static_cast<Type_Float> (data); | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&floatValue); | ||||
|                 runtime[0].mFloat = floatValue; | ||||
|             }            | ||||
|     }; | ||||
|      | ||||
|  | @ -34,9 +34,9 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[0]); | ||||
|                 Type_Float data = runtime[0].mFloat; | ||||
|                 Type_Integer integerValue = static_cast<Type_Integer> (data); | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&integerValue); | ||||
|                 runtime[0].mInteger = integerValue; | ||||
|             }            | ||||
|     };     | ||||
|      | ||||
|  | @ -46,9 +46,9 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[0]); | ||||
|                 Type_Integer data = runtime[0].mInteger; | ||||
|                 data = -data; | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&data); | ||||
|                 runtime[0].mInteger = data; | ||||
|             }            | ||||
|     };     | ||||
|      | ||||
|  | @ -58,9 +58,9 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[0]); | ||||
|                 Type_Float data = runtime[0].mFloat; | ||||
|                 data = -data; | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&data); | ||||
|                 runtime[0].mFloat = data; | ||||
|             }            | ||||
|     }; | ||||
|      | ||||
|  | @ -70,9 +70,9 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[1]); | ||||
|                 Type_Integer data = runtime[1].mInteger; | ||||
|                 Type_Float floatValue = static_cast<Type_Float> (data); | ||||
|                 runtime[1] = *reinterpret_cast<Type_Data *> (&floatValue); | ||||
|                 runtime[1].mFloat = floatValue; | ||||
|             }            | ||||
|     }; | ||||
|      | ||||
|  | @ -82,9 +82,9 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[1]); | ||||
|                 Type_Float data = runtime[1].mFloat; | ||||
|                 Type_Integer integerValue = static_cast<Type_Integer> (data); | ||||
|                 runtime[1] = *reinterpret_cast<Type_Data *> (&integerValue); | ||||
|                 runtime[1].mInteger = integerValue; | ||||
|             }            | ||||
|     };             | ||||
| } | ||||
|  |  | |||
|  | @ -103,6 +103,7 @@ namespace Interpreter | |||
|          | ||||
|         // spacial
 | ||||
|         interpreter.installSegment5 (49, new OpGetDistance); | ||||
|         interpreter.installSegment5 (57, new OpGetDistanceExplicit); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -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<int *> (&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<int *> (&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<float *> (&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<Type_Data *> (&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<Type_Data *> (&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<Type_Data *> (&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<Type_Data *> (&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<int *> (&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<int *> (&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<float *> (&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<Type_Data *> (&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<Type_Data *> (&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<Type_Data *> (&value); | ||||
|                 Type_Float value = runtime.getContext().getGlobalFloat (name); | ||||
|                 runtime[0].mFloat = value; | ||||
|             }            | ||||
|     };         | ||||
| } | ||||
|  |  | |||
|  | @ -16,14 +16,11 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 T result = | ||||
|                     *reinterpret_cast<T *> (&runtime[1]) | ||||
|                     +  | ||||
|                     *reinterpret_cast<T *> (&runtime[0]); | ||||
|                 T result = getData<T> (runtime[1]) + getData<T> (runtime[0]); | ||||
|                  | ||||
|                 runtime.pop(); | ||||
|                  | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&result); | ||||
|                 getData<T> (runtime[0]) = result; | ||||
|             }            | ||||
|     }; | ||||
| 
 | ||||
|  | @ -34,14 +31,11 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 T result = | ||||
|                     *reinterpret_cast<T *> (&runtime[1]) | ||||
|                     -  | ||||
|                     *reinterpret_cast<T *> (&runtime[0]); | ||||
|                 T result = getData<T> (runtime[1]) - getData<T> (runtime[0]); | ||||
|                  | ||||
|                 runtime.pop(); | ||||
|                  | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&result); | ||||
| 
 | ||||
|                 getData<T> (runtime[0]) = result; | ||||
|             }            | ||||
|     }; | ||||
| 
 | ||||
|  | @ -52,14 +46,11 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 T result = | ||||
|                     *reinterpret_cast<T *> (&runtime[1]) | ||||
|                     *  | ||||
|                     *reinterpret_cast<T *> (&runtime[0]); | ||||
|                 T result = getData<T> (runtime[1]) * getData<T> (runtime[0]); | ||||
|                  | ||||
|                 runtime.pop(); | ||||
|                  | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&result); | ||||
| 
 | ||||
|                 getData<T> (runtime[0]) = result; | ||||
|             }            | ||||
|     }; | ||||
| 
 | ||||
|  | @ -70,19 +61,16 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 T left = *reinterpret_cast<T *> (&runtime[0]); | ||||
|                 T left = getData<T> (runtime[0]); | ||||
|              | ||||
|                 if (left==0) | ||||
|                     throw std::runtime_error ("division by zero"); | ||||
|              | ||||
|                 T result = | ||||
|                     *reinterpret_cast<T *> (&runtime[1]) | ||||
|                     /  | ||||
|                     left; | ||||
|                 T result = getData<T> (runtime[1]) / left; | ||||
|                  | ||||
|                 runtime.pop(); | ||||
|                  | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&result); | ||||
| 
 | ||||
|                 getData<T> (runtime[0]) = result; | ||||
|             }            | ||||
|     }; | ||||
|      | ||||
|  | @ -92,7 +80,7 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 Type_Float value = *reinterpret_cast<Type_Float *> (&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<Type_Data *> (&value); | ||||
|                 runtime[0].mFloat = value; | ||||
|             }            | ||||
|     };     | ||||
|      | ||||
|  | @ -111,13 +99,11 @@ namespace Interpreter | |||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 int result = C() ( | ||||
|                     *reinterpret_cast<T *> (&runtime[1]), | ||||
|                     *reinterpret_cast<T *> (&runtime[0])); | ||||
|                 int result = C() (getData<T> (runtime[1]), getData<T> (runtime[0])); | ||||
|                  | ||||
|                 runtime.pop(); | ||||
|                  | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&result); | ||||
|                 runtime[0].mInteger = result; | ||||
|             }            | ||||
|     };     | ||||
| } | ||||
|  |  | |||
|  | @ -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<const int *> (&runtime[0]); | ||||
|                                 Type_Integer value = runtime[0].mInteger; | ||||
|                                 runtime.pop(); | ||||
|                                  | ||||
|                                 std::ostringstream out; | ||||
|  | @ -64,7 +64,7 @@ namespace Interpreter | |||
|                                     ++i; | ||||
|                                 } | ||||
|                              | ||||
|                                 float value = *reinterpret_cast<const float *> (&runtime[0]); | ||||
|                                 float value = runtime[0].mFloat; | ||||
|                                 runtime.pop(); | ||||
|                                  | ||||
|                                 std::ostringstream out; | ||||
|  | @ -107,7 +107,7 @@ namespace Interpreter | |||
|             { | ||||
|                 double r = static_cast<double> (std::rand()) / RAND_MAX; // [0, 1)
 | ||||
|                  | ||||
|                 Type_Integer limit = *reinterpret_cast<Type_Integer *> (&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<Type_Integer> (r*limit); // [o, limit)
 | ||||
|                  | ||||
|                 runtime[0] = *reinterpret_cast<Type_Data *> (&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<Type_Data *> (&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); | ||||
|              | ||||
|  |  | |||
|  | @ -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<int> (mStack.size())) | ||||
|             throw std::runtime_error ("stack index out of range"); | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ namespace Interpreter | |||
|             const Type_Code *mCode; | ||||
|             int mCodeSize; | ||||
|             int mPC; | ||||
|             std::vector<Type_Data> mStack; | ||||
|             std::vector<Data> 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(); | ||||
|  |  | |||
|  | @ -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); | ||||
|             }            | ||||
|  |  | |||
|  | @ -12,13 +12,31 @@ 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<Type_Data *> (&distance); | ||||
|                 runtime[0].mFloat = distance; | ||||
|             }             | ||||
|     }; | ||||
|      | ||||
|     class OpGetDistanceExplicit : public Opcode0 | ||||
|     { | ||||
|         public: | ||||
|          | ||||
|             virtual void execute (Runtime& runtime) | ||||
|             { | ||||
|                 int index = runtime[0].mInteger; | ||||
|                 runtime.pop(); | ||||
|                 std::string id = runtime.getStringLiteral (index); | ||||
|                              | ||||
|                 std::string name = runtime.getStringLiteral (runtime[0].mInteger); | ||||
|                  | ||||
|                 Type_Float distance = runtime.getContext().getDistance (name, id); | ||||
|                  | ||||
|                 runtime[0].mFloat = distance; | ||||
|             }             | ||||
|     };     | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| #ifndef INTERPRETER_TYPES_H_INCLUDED | ||||
| #define INTERPRETER_TYPES_H_INCLUDED | ||||
| 
 | ||||
| #include <stdexcept> | ||||
| 
 | ||||
| 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<typename T> | ||||
|     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 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue