forked from mirror/openmw-tes3mp
Merge branch 'master' into oengine
This commit is contained in:
commit
186bf8c1a1
34 changed files with 829 additions and 559 deletions
|
@ -110,7 +110,7 @@ namespace SAInterpreter
|
||||||
|
|
||||||
void Context::stopScript (const std::string& name) {}
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ namespace SAInterpreter
|
||||||
|
|
||||||
virtual void stopScript (const std::string& name);
|
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;
|
virtual float getSecondsPassed() const;
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ set(GAMESCRIPT
|
||||||
mwscript/cellextensions.cpp
|
mwscript/cellextensions.cpp
|
||||||
mwscript/miscextensions.cpp
|
mwscript/miscextensions.cpp
|
||||||
mwscript/guiextensions.cpp
|
mwscript/guiextensions.cpp
|
||||||
|
mwscript/soundextensions.cpp
|
||||||
mwscript/extensions.cpp
|
mwscript/extensions.cpp
|
||||||
mwscript/globalscripts.cpp
|
mwscript/globalscripts.cpp
|
||||||
)
|
)
|
||||||
|
@ -46,17 +47,16 @@ set(GAMESCRIPT_HEADER
|
||||||
mwscript/cellextensions.hpp
|
mwscript/cellextensions.hpp
|
||||||
mwscript/miscextensions.hpp
|
mwscript/miscextensions.hpp
|
||||||
mwscript/guiextensions.hpp
|
mwscript/guiextensions.hpp
|
||||||
|
mwscript/soundextensions.hpp
|
||||||
mwscript/extensions.hpp
|
mwscript/extensions.hpp
|
||||||
mwscript/globalscripts.hpp
|
mwscript/globalscripts.hpp
|
||||||
)
|
)
|
||||||
source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER})
|
source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER})
|
||||||
|
|
||||||
set(GAMESOUND
|
set(GAMESOUND
|
||||||
mwsound/soundmanager.cpp
|
mwsound/soundmanager.cpp)
|
||||||
mwsound/extensions.cpp)
|
|
||||||
set(GAMESOUND_HEADER
|
set(GAMESOUND_HEADER
|
||||||
mwsound/soundmanager.hpp
|
mwsound/soundmanager.hpp)
|
||||||
mwsound/extensions.hpp)
|
|
||||||
source_group(apps\\openmw\\mwsound FILES ${GAMESOUND} ${GAMESOUND_HEADER})
|
source_group(apps\\openmw\\mwsound FILES ${GAMESOUND} ${GAMESOUND_HEADER})
|
||||||
|
|
||||||
set(GAMEGUI
|
set(GAMEGUI
|
||||||
|
|
|
@ -46,5 +46,13 @@ op 0x2000015: EnableMapMenu
|
||||||
op 0x2000016: EnableStatsMenu
|
op 0x2000016: EnableStatsMenu
|
||||||
op 0x2000017: EnableRest
|
op 0x2000017: EnableRest
|
||||||
op 0x2000018: ShowRestMenu
|
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 "extensions.hpp"
|
||||||
|
|
||||||
#include "../mwsound/extensions.hpp"
|
#include "soundextensions.hpp"
|
||||||
|
|
||||||
#include "cellextensions.hpp"
|
#include "cellextensions.hpp"
|
||||||
#include "miscextensions.hpp"
|
#include "miscextensions.hpp"
|
||||||
#include "guiextensions.hpp"
|
#include "guiextensions.hpp"
|
||||||
|
@ -14,7 +13,7 @@ namespace MWScript
|
||||||
Cell::registerExtensions (extensions);
|
Cell::registerExtensions (extensions);
|
||||||
Misc::registerExtensions (extensions);
|
Misc::registerExtensions (extensions);
|
||||||
Gui::registerExtensions (extensions);
|
Gui::registerExtensions (extensions);
|
||||||
MWSound::registerExtensions (extensions);
|
Sound::registerExtensions (extensions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,9 @@
|
||||||
|
|
||||||
namespace MWScript
|
namespace MWScript
|
||||||
{
|
{
|
||||||
InterpreterContext::PtrWithCell InterpreterContext::getReference (
|
MWWorld::Ptr InterpreterContext::getReference (
|
||||||
const std::string& id, bool activeOnly)
|
const std::string& id, bool activeOnly)
|
||||||
{
|
{
|
||||||
PtrWithCell ref;
|
|
||||||
|
|
||||||
if (!id.empty())
|
if (!id.empty())
|
||||||
{
|
{
|
||||||
return mEnvironment.mWorld->getPtr (id, activeOnly);
|
return mEnvironment.mWorld->getPtr (id, activeOnly);
|
||||||
|
@ -30,15 +28,13 @@ namespace MWScript
|
||||||
if (mReference.isEmpty())
|
if (mReference.isEmpty())
|
||||||
throw std::runtime_error ("no implicit reference");
|
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
|
const std::string& id, bool activeOnly) const
|
||||||
{
|
{
|
||||||
CPtrWithCell ref;
|
|
||||||
|
|
||||||
if (!id.empty())
|
if (!id.empty())
|
||||||
{
|
{
|
||||||
return mEnvironment.mWorld->getPtr (id, activeOnly);
|
return mEnvironment.mWorld->getPtr (id, activeOnly);
|
||||||
|
@ -48,7 +44,7 @@ namespace MWScript
|
||||||
if (mReference.isEmpty())
|
if (mReference.isEmpty())
|
||||||
throw std::runtime_error ("no implicit reference");
|
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);
|
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())
|
// TODO handle exterior cells (when ref and ref2 are located in different cells)
|
||||||
throw std::runtime_error ("no implicit reference");
|
const MWWorld::Ptr ref2 = getReference (id, false);
|
||||||
|
|
||||||
std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> ref =
|
const MWWorld::Ptr ref = mEnvironment.mWorld->getPtr (name, true);
|
||||||
mEnvironment.mWorld->getPtr (name, true);
|
|
||||||
|
|
||||||
double diff[3];
|
double diff[3];
|
||||||
|
|
||||||
for (int i=0; i<3; ++i)
|
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]);
|
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
|
bool InterpreterContext::isDisabled (const std::string& id) const
|
||||||
{
|
{
|
||||||
CPtrWithCell ref = getReference (id, false);
|
const MWWorld::Ptr ref = getReference (id, false);
|
||||||
return !ref.first.getRefData().isEnabled();
|
return !ref.getRefData().isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::enable (const std::string& id)
|
void InterpreterContext::enable (const std::string& id)
|
||||||
{
|
{
|
||||||
PtrWithCell ref = getReference (id, false);
|
MWWorld::Ptr ref = getReference (id, false);
|
||||||
mEnvironment.mWorld->enable (ref);
|
mEnvironment.mWorld->enable (ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterpreterContext::disable (const std::string& id)
|
void InterpreterContext::disable (const std::string& id)
|
||||||
{
|
{
|
||||||
PtrWithCell ref = getReference (id, false);
|
MWWorld::Ptr ref = getReference (id, false);
|
||||||
mEnvironment.mWorld->disable (ref);
|
mEnvironment.mWorld->disable (ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,10 @@ namespace MWScript
|
||||||
Locals *mLocals;
|
Locals *mLocals;
|
||||||
MWWorld::Ptr mReference;
|
MWWorld::Ptr mReference;
|
||||||
|
|
||||||
typedef std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> PtrWithCell;
|
|
||||||
typedef std::pair<const MWWorld::Ptr, const MWWorld::World::CellStore *> CPtrWithCell;
|
|
||||||
|
|
||||||
PtrWithCell getReference (const std::string& id, bool activeOnly);
|
MWWorld::Ptr getReference (const std::string& id, bool activeOnly);
|
||||||
|
|
||||||
CPtrWithCell getReference (const std::string& id, bool activeOnly) const;
|
const MWWorld::Ptr getReference (const std::string& id, bool activeOnly) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -70,7 +68,7 @@ namespace MWScript
|
||||||
|
|
||||||
virtual void stopScript (const std::string& name);
|
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;
|
virtual bool hasBeenActivated() const;
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
#include <components/interpreter/installopcodes.hpp>
|
#include <components/interpreter/installopcodes.hpp>
|
||||||
#include <components/interpreter/interpreter.hpp>
|
#include <components/interpreter/interpreter.hpp>
|
||||||
|
|
||||||
#include "../mwsound/extensions.hpp"
|
#include "soundextensions.hpp"
|
||||||
|
|
||||||
#include "cellextensions.hpp"
|
#include "cellextensions.hpp"
|
||||||
#include "miscextensions.hpp"
|
#include "miscextensions.hpp"
|
||||||
#include "guiextensions.hpp"
|
#include "guiextensions.hpp"
|
||||||
|
@ -125,7 +124,7 @@ namespace MWScript
|
||||||
Cell::installOpcodes (interpreter);
|
Cell::installOpcodes (interpreter);
|
||||||
Misc::installOpcodes (interpreter);
|
Misc::installOpcodes (interpreter);
|
||||||
Gui::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
|
class Ptr
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef ESMS::CellStore<RefData> CellStore;
|
||||||
|
|
||||||
boost::any mPtr;
|
boost::any mPtr;
|
||||||
ESM::CellRef *mCellRef;
|
ESM::CellRef *mCellRef;
|
||||||
RefData *mRefData;
|
RefData *mRefData;
|
||||||
|
CellStore *mCell;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Ptr() : mCellRef (0), mRefData (0) {}
|
Ptr() : mCellRef (0), mRefData (0), mCell (0) {}
|
||||||
|
|
||||||
bool isEmpty() const
|
bool isEmpty() const
|
||||||
{
|
{
|
||||||
|
@ -29,11 +34,12 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef)
|
Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef, CellStore *cell)
|
||||||
{
|
{
|
||||||
mPtr = liveCellRef;
|
mPtr = liveCellRef;
|
||||||
mCellRef = &liveCellRef->ref;
|
mCellRef = &liveCellRef->ref;
|
||||||
mRefData = &liveCellRef->mData;
|
mRefData = &liveCellRef->mData;
|
||||||
|
mCell = cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
@ -53,6 +59,12 @@ namespace MWWorld
|
||||||
assert (mRefData);
|
assert (mRefData);
|
||||||
return *mRefData;
|
return *mRefData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ptr::CellStore *getCell() const
|
||||||
|
{
|
||||||
|
assert (mCell);
|
||||||
|
return mCell;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,8 @@ namespace
|
||||||
{
|
{
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void listCellScripts (const ESMS::ESMStore& store,
|
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 (
|
for (typename ESMS::CellRefList<T, MWWorld::RefData>::List::iterator iter (
|
||||||
cellRefList.list.begin());
|
cellRefList.list.begin());
|
||||||
|
@ -28,116 +29,102 @@ namespace
|
||||||
iter->mData.setLocals (*script);
|
iter->mData.setLocals (*script);
|
||||||
|
|
||||||
scriptList.push_back (
|
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
|
namespace MWWorld
|
||||||
{
|
{
|
||||||
void World::insertInteriorScripts (ESMS::CellStore<RefData>& cell)
|
void World::insertInteriorScripts (ESMS::CellStore<RefData>& cell)
|
||||||
{
|
{
|
||||||
listCellScripts (mStore, cell.activators, mLocalScripts);
|
listCellScripts (mStore, cell.activators, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.potions, mLocalScripts);
|
listCellScripts (mStore, cell.potions, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.appas, mLocalScripts);
|
listCellScripts (mStore, cell.appas, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.armors, mLocalScripts);
|
listCellScripts (mStore, cell.armors, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.books, mLocalScripts);
|
listCellScripts (mStore, cell.books, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.clothes, mLocalScripts);
|
listCellScripts (mStore, cell.clothes, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.containers, mLocalScripts);
|
listCellScripts (mStore, cell.containers, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.creatures, mLocalScripts);
|
listCellScripts (mStore, cell.creatures, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.doors, mLocalScripts);
|
listCellScripts (mStore, cell.doors, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.ingreds, mLocalScripts);
|
listCellScripts (mStore, cell.ingreds, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.lights, mLocalScripts);
|
listCellScripts (mStore, cell.lights, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.lockpicks, mLocalScripts);
|
listCellScripts (mStore, cell.lockpicks, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.miscItems, mLocalScripts);
|
listCellScripts (mStore, cell.miscItems, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.npcs, mLocalScripts);
|
listCellScripts (mStore, cell.npcs, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.probes, mLocalScripts);
|
listCellScripts (mStore, cell.probes, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.repairs, mLocalScripts);
|
listCellScripts (mStore, cell.repairs, mLocalScripts, &cell);
|
||||||
listCellScripts (mStore, cell.weapons, mLocalScripts);
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
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))
|
if (ESMS::LiveCellRef<ESM::Weapon, RefData> *ref = cell.weapons.find (name))
|
||||||
return ref;
|
return Ptr (ref, &cell);
|
||||||
|
|
||||||
return Ptr();
|
return Ptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
MWRender::CellRender *World::searchRender (CellStore *store)
|
MWRender::CellRender *World::searchRender (Ptr::CellStore *store)
|
||||||
{
|
{
|
||||||
CellRenderCollection::iterator iter = mActiveCells.find (store);
|
CellRenderCollection::iterator iter = mActiveCells.find (store);
|
||||||
|
|
||||||
|
@ -157,7 +144,7 @@ namespace MWWorld
|
||||||
|
|
||||||
World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||||
const std::string& master, const std::string& startCell, bool newGame)
|
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);
|
boost::filesystem::path masterPath (dataDir);
|
||||||
masterPath /= master;
|
masterPath /= master;
|
||||||
|
@ -169,6 +156,7 @@ namespace MWWorld
|
||||||
mStore.load (mEsm);
|
mStore.load (mEsm);
|
||||||
|
|
||||||
mInteriors[startCell].loadInt (startCell, mStore, mEsm);
|
mInteriors[startCell].loadInt (startCell, mStore, mEsm);
|
||||||
|
mCurrentCell = &mInteriors[startCell];
|
||||||
|
|
||||||
insertInteriorScripts (mInteriors[startCell]);
|
insertInteriorScripts (mInteriors[startCell]);
|
||||||
|
|
||||||
|
@ -251,15 +239,12 @@ namespace MWWorld
|
||||||
return iter->second;
|
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.
|
// the player is always in an active cell.
|
||||||
if (name=="player")
|
if (name=="player")
|
||||||
{
|
{
|
||||||
// TODO: find real cell (might need to be stored in playerPos). For now we
|
return Ptr (mPlayerPos->getPlayer(), mCurrentCell);
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// active cells
|
// active cells
|
||||||
|
@ -269,7 +254,7 @@ namespace MWWorld
|
||||||
Ptr ptr = getPtr (name, *iter->first);
|
Ptr ptr = getPtr (name, *iter->first);
|
||||||
|
|
||||||
if (!ptr.isEmpty())
|
if (!ptr.isEmpty())
|
||||||
return std::make_pair (ptr, iter->first);
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!activeOnly)
|
if (!activeOnly)
|
||||||
|
@ -280,58 +265,29 @@ namespace MWWorld
|
||||||
throw std::runtime_error ("unknown ID: " + name);
|
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:
|
public:
|
||||||
|
|
||||||
typedef std::vector<std::pair<std::string, Ptr> > ScriptList;
|
typedef std::vector<std::pair<std::string, Ptr> > ScriptList;
|
||||||
typedef ESMS::CellStore<RefData> CellStore;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
typedef std::map<CellStore *, MWRender::CellRender *> CellRenderCollection;
|
typedef std::map<Ptr::CellStore *, MWRender::CellRender *> CellRenderCollection;
|
||||||
|
|
||||||
MWRender::SkyManager* mSkyManager;
|
MWRender::SkyManager* mSkyManager;
|
||||||
MWRender::MWScene mScene;
|
MWRender::MWScene mScene;
|
||||||
MWRender::PlayerPos *mPlayerPos;
|
MWRender::PlayerPos *mPlayerPos;
|
||||||
|
Ptr::CellStore *mCurrentCell; // the cell, the player is in
|
||||||
CellRenderCollection mActiveCells;
|
CellRenderCollection mActiveCells;
|
||||||
CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet)
|
CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet)
|
||||||
ESM::ESMReader mEsm;
|
ESM::ESMReader mEsm;
|
||||||
ESMS::ESMStore mStore;
|
ESMS::ESMStore mStore;
|
||||||
std::map<std::string, CellStore> mInteriors;
|
std::map<std::string, Ptr::CellStore> mInteriors;
|
||||||
ScriptList mLocalScripts;
|
ScriptList mLocalScripts;
|
||||||
std::map<std::string, Interpreter::Type_Data> mGlobalVariables;
|
std::map<std::string, Interpreter::Type_Data> mGlobalVariables;
|
||||||
|
|
||||||
|
@ -59,9 +59,9 @@ namespace MWWorld
|
||||||
|
|
||||||
void insertInteriorScripts (ESMS::CellStore<RefData>& cell);
|
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:
|
public:
|
||||||
|
|
||||||
|
@ -82,16 +82,13 @@ namespace MWWorld
|
||||||
|
|
||||||
Interpreter::Type_Data& getGlobalVariable (const std::string& name);
|
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.
|
///< Return a pointer to a liveCellRef with the given name.
|
||||||
/// \param activeOnly do non search inactive cells.
|
/// \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);
|
void disable (Ptr reference);
|
||||||
|
|
||||||
CellStore *find (const Ptr& ptr);
|
|
||||||
///< Only active cells are searched.
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,40 @@ namespace Compiler
|
||||||
mNextOperand = false;
|
mNextOperand = false;
|
||||||
return true;
|
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);
|
return Parser::parseKeyword (keyword, loc, scanner);
|
||||||
|
@ -360,18 +394,18 @@ namespace Compiler
|
||||||
|
|
||||||
mNextOperand = false;
|
mNextOperand = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (keyword==Scanner::K_getdistance)
|
else if (keyword==Scanner::K_getdistance)
|
||||||
{
|
{
|
||||||
mTokenLoc = loc;
|
mTokenLoc = loc;
|
||||||
parseArguments ("c", scanner);
|
parseArguments ("c", scanner);
|
||||||
|
|
||||||
Generator::getDistance (mCode);
|
Generator::getDistance (mCode, mLiterals, "");
|
||||||
mOperands.push_back ('f');
|
mOperands.push_back ('f');
|
||||||
|
|
||||||
mNextOperand = false;
|
mNextOperand = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (keyword==Scanner::K_getsecondspassed)
|
else if (keyword==Scanner::K_getsecondspassed)
|
||||||
{
|
{
|
||||||
mTokenLoc = loc;
|
mTokenLoc = loc;
|
||||||
|
@ -400,12 +434,12 @@ namespace Compiler
|
||||||
char returnType;
|
char returnType;
|
||||||
std::string argumentType;
|
std::string argumentType;
|
||||||
|
|
||||||
if (extensions->isFunction (keyword, returnType, argumentType))
|
if (extensions->isFunction (keyword, returnType, argumentType, false))
|
||||||
{
|
{
|
||||||
mTokenLoc = loc;
|
mTokenLoc = loc;
|
||||||
parseArguments (argumentType, scanner);
|
parseArguments (argumentType, scanner);
|
||||||
|
|
||||||
extensions->generateFunctionCode (keyword, mCode);
|
extensions->generateFunctionCode (keyword, mCode, mLiterals, "");
|
||||||
mOperands.push_back (returnType);
|
mOperands.push_back (returnType);
|
||||||
|
|
||||||
mNextOperand = false;
|
mNextOperand = false;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
#include "generator.hpp"
|
#include "generator.hpp"
|
||||||
|
#include "literals.hpp"
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
@ -20,31 +21,39 @@ namespace Compiler
|
||||||
return iter->second;
|
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);
|
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
|
||||||
|
|
||||||
if (iter==mFunctions.end())
|
if (iter==mFunctions.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (explicitReference && iter->second.mCodeExplicit==-1)
|
||||||
|
return false;
|
||||||
|
|
||||||
returnType = iter->second.mReturn;
|
returnType = iter->second.mReturn;
|
||||||
argumentType = iter->second.mArguments;
|
argumentType = iter->second.mArguments;
|
||||||
return true;
|
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);
|
std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword);
|
||||||
|
|
||||||
if (iter==mInstructions.end())
|
if (iter==mInstructions.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (explicitReference && iter->second.mCodeExplicit==-1)
|
||||||
|
return false;
|
||||||
|
|
||||||
argumentType = iter->second.mArguments;
|
argumentType = iter->second.mArguments;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extensions::registerFunction (const std::string& keyword, char returnType,
|
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);
|
assert (segment5code>=33554432 && segment5code<=67108863);
|
||||||
|
|
||||||
|
@ -56,12 +65,13 @@ namespace Compiler
|
||||||
function.mReturn = returnType;
|
function.mReturn = returnType;
|
||||||
function.mArguments = argumentType;
|
function.mArguments = argumentType;
|
||||||
function.mCode = segment5code;
|
function.mCode = segment5code;
|
||||||
|
function.mCodeExplicit = segment5codeExplicit;
|
||||||
|
|
||||||
mFunctions.insert (std::make_pair (code, function));
|
mFunctions.insert (std::make_pair (code, function));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extensions::registerInstruction (const std::string& keyword,
|
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);
|
assert (segment5code>=33554432 && segment5code<=67108863);
|
||||||
|
|
||||||
|
@ -72,23 +82,34 @@ namespace Compiler
|
||||||
Instruction instruction;
|
Instruction instruction;
|
||||||
instruction.mArguments = argumentType;
|
instruction.mArguments = argumentType;
|
||||||
instruction.mCode = segment5code;
|
instruction.mCode = segment5code;
|
||||||
|
instruction.mCodeExplicit = segment5codeExplicit;
|
||||||
|
|
||||||
mInstructions.insert (std::make_pair (code, instruction));
|
mInstructions.insert (std::make_pair (code, instruction));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
|
void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
|
||||||
const
|
Literals& literals, const std::string& id) const
|
||||||
{
|
{
|
||||||
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
|
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
|
||||||
|
|
||||||
if (iter==mFunctions.end())
|
if (iter==mFunctions.end())
|
||||||
throw std::logic_error ("unknown custom function keyword");
|
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,
|
void Extensions::generateInstructionCode (int keyword,
|
||||||
std::vector<Interpreter::Type_Code>& code)
|
std::vector<Interpreter::Type_Code>& code, Literals& literals, const std::string& id)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword);
|
std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword);
|
||||||
|
@ -96,6 +117,16 @@ namespace Compiler
|
||||||
if (iter==mInstructions.end())
|
if (iter==mInstructions.end())
|
||||||
throw std::logic_error ("unknown custom instruction keyword");
|
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
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
class Literals;
|
||||||
|
|
||||||
/// \brief Collection of compiler extensions
|
/// \brief Collection of compiler extensions
|
||||||
|
|
||||||
class Extensions
|
class Extensions
|
||||||
|
@ -18,12 +20,14 @@ namespace Compiler
|
||||||
char mReturn;
|
char mReturn;
|
||||||
std::string mArguments;
|
std::string mArguments;
|
||||||
int mCode;
|
int mCode;
|
||||||
|
int mCodeExplicit;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Instruction
|
struct Instruction
|
||||||
{
|
{
|
||||||
std::string mArguments;
|
std::string mArguments;
|
||||||
int mCode;
|
int mCode;
|
||||||
|
int mCodeExplicit;
|
||||||
};
|
};
|
||||||
|
|
||||||
int mNextKeywordIndex;
|
int mNextKeywordIndex;
|
||||||
|
@ -40,33 +44,37 @@ namespace Compiler
|
||||||
/// - if no match is found 0 is returned.
|
/// - if no match is found 0 is returned.
|
||||||
/// - keyword must be all lower case.
|
/// - 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
|
///< Is this keyword registered with a function? If yes, return return and argument
|
||||||
/// types.
|
/// 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.
|
///< Is this keyword registered with a function? If yes, return argument types.
|
||||||
|
|
||||||
void registerFunction (const std::string& keyword, char returnType,
|
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
|
///< Register a custom function
|
||||||
/// - keyword must be all lower case.
|
/// - keyword must be all lower case.
|
||||||
/// - keyword must be unique
|
/// - keyword must be unique
|
||||||
|
/// - if explicit references are not supported, segment5codeExplicit must be set to -1
|
||||||
/// \note Currently only segment 5 opcodes are supported.
|
/// \note Currently only segment 5 opcodes are supported.
|
||||||
|
|
||||||
void registerInstruction (const std::string& keyword,
|
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
|
///< Register a custom instruction
|
||||||
/// - keyword must be all lower case.
|
/// - keyword must be all lower case.
|
||||||
/// - keyword must be unique
|
/// - keyword must be unique
|
||||||
|
/// - if explicit references are not supported, segment5codeExplicit must be set to -1
|
||||||
/// \note Currently only segment 5 opcodes are supported.
|
/// \note Currently only segment 5 opcodes are supported.
|
||||||
|
|
||||||
void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
|
void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
|
||||||
const;
|
Literals& literals, const std::string& id) const;
|
||||||
///< Append code for function to \a code.
|
///< Append code for function to \a code.
|
||||||
|
|
||||||
void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
|
void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
|
||||||
const;
|
Literals& literals, const std::string& id) const;
|
||||||
///< Append code for function to \a code.
|
///< Append code for function to \a code.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -314,6 +314,11 @@ namespace
|
||||||
{
|
{
|
||||||
code.push_back (Compiler::Generator::segment5 (56));
|
code.push_back (Compiler::Generator::segment5 (56));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void opGetDistanceExplicit (Compiler::Generator::CodeContainer& code)
|
||||||
|
{
|
||||||
|
code.push_back (Compiler::Generator::segment5 (57));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
|
@ -706,9 +711,18 @@ namespace Compiler
|
||||||
opStopScript (code);
|
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)
|
void getSecondsPassed (CodeContainer& code)
|
||||||
|
|
|
@ -107,7 +107,7 @@ namespace Compiler
|
||||||
|
|
||||||
void stopScript (CodeContainer& code);
|
void stopScript (CodeContainer& code);
|
||||||
|
|
||||||
void getDistance (CodeContainer& code);
|
void getDistance (CodeContainer& code, Literals& literals, const std::string id);
|
||||||
|
|
||||||
void getSecondsPassed (CodeContainer& code);
|
void getSecondsPassed (CodeContainer& code);
|
||||||
|
|
||||||
|
|
|
@ -157,6 +157,21 @@ namespace Compiler
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
return true;
|
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)
|
if (mState==BeginState)
|
||||||
|
@ -189,21 +204,6 @@ namespace Compiler
|
||||||
mState = EndState;
|
mState = EndState;
|
||||||
return true;
|
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)
|
else if (mState==SetLocalVarState && keyword==Scanner::K_to)
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,8 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void stopScript (const std::string& name) = 0;
|
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;
|
virtual float getSecondsPassed() const = 0;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Integer data = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
if (data==0)
|
if (data==0)
|
||||||
|
@ -38,7 +38,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Integer data = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
if (data!=0)
|
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 54: explicit reference = stack[0]; pop; enable explicit reference
|
||||||
op 55: explicit reference = stack[0]; pop; disable 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
|
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
|
opcodes 33554432-67108863 reserved for extensions
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime, unsigned int arg0)
|
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)
|
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);
|
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)
|
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);
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[0]);
|
Type_Integer data = runtime[0].mInteger;
|
||||||
data = -data;
|
data = -data;
|
||||||
runtime[0] = *reinterpret_cast<Type_Data *> (&data);
|
runtime[0].mInteger = data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[0]);
|
Type_Float data = runtime[0].mFloat;
|
||||||
data = -data;
|
data = -data;
|
||||||
runtime[0] = *reinterpret_cast<Type_Data *> (&data);
|
runtime[0].mFloat = data;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -70,9 +70,9 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
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);
|
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)
|
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);
|
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
|
// spacial
|
||||||
interpreter.installSegment5 (49, new OpGetDistance);
|
interpreter.installSegment5 (49, new OpGetDistance);
|
||||||
|
interpreter.installSegment5 (57, new OpGetDistanceExplicit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Integer data = runtime[0].mInteger;
|
||||||
int index = runtime[1];
|
int index = runtime[1].mInteger;
|
||||||
|
|
||||||
runtime.getContext().setLocalShort (index, *reinterpret_cast<int *> (&data));
|
runtime.getContext().setLocalShort (index, data);
|
||||||
|
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
@ -29,10 +29,10 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Integer data = runtime[0].mInteger;
|
||||||
int index = runtime[1];
|
int index = runtime[1].mInteger;
|
||||||
|
|
||||||
runtime.getContext().setLocalLong (index, *reinterpret_cast<int *> (&data));
|
runtime.getContext().setLocalLong (index, data);
|
||||||
|
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
@ -45,10 +45,10 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Float data = runtime[0].mFloat;
|
||||||
int index = runtime[1];
|
int index = runtime[1].mInteger;
|
||||||
|
|
||||||
runtime.getContext().setLocalFloat (index, *reinterpret_cast<float *> (&data));
|
runtime.getContext().setLocalFloat (index, data);
|
||||||
|
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
@ -61,8 +61,8 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int intValue = runtime.getIntegerLiteral (runtime[0]);
|
Type_Integer intValue = runtime.getIntegerLiteral (runtime[0].mInteger);
|
||||||
runtime[0] = intValue;
|
runtime[0].mInteger = intValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,8 +72,8 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
float floatValue = runtime.getFloatLiteral (runtime[0]);
|
Type_Float floatValue = runtime.getFloatLiteral (runtime[0].mInteger);
|
||||||
runtime[0] = *reinterpret_cast<Type_Data *> (&floatValue);
|
runtime[0].mFloat = floatValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -83,9 +83,9 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
int value = runtime.getContext().getLocalShort (index);
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
int value = runtime.getContext().getLocalLong (index);
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
float value = runtime.getContext().getLocalFloat (index);
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Integer data = runtime[0].mInteger;
|
||||||
int index = runtime[1];
|
int index = runtime[1].mInteger;
|
||||||
|
|
||||||
std::string name = runtime.getStringLiteral (index);
|
std::string name = runtime.getStringLiteral (index);
|
||||||
|
|
||||||
runtime.getContext().setGlobalShort (name, *reinterpret_cast<int *> (&data));
|
runtime.getContext().setGlobalShort (name, data);
|
||||||
|
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
@ -137,12 +137,12 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Integer data = runtime[0].mInteger;
|
||||||
int index = runtime[1];
|
int index = runtime[1].mInteger;
|
||||||
|
|
||||||
std::string name = runtime.getStringLiteral (index);
|
std::string name = runtime.getStringLiteral (index);
|
||||||
|
|
||||||
runtime.getContext().setGlobalLong (name, *reinterpret_cast<int *> (&data));
|
runtime.getContext().setGlobalLong (name, data);
|
||||||
|
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
@ -155,12 +155,12 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Data data = runtime[0];
|
Type_Float data = runtime[0].mFloat;
|
||||||
int index = runtime[1];
|
int index = runtime[1].mInteger;
|
||||||
|
|
||||||
std::string name = runtime.getStringLiteral (index);
|
std::string name = runtime.getStringLiteral (index);
|
||||||
|
|
||||||
runtime.getContext().setGlobalFloat (name, *reinterpret_cast<float *> (&data));
|
runtime.getContext().setGlobalFloat (name, data);
|
||||||
|
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
@ -173,10 +173,10 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
std::string name = runtime.getStringLiteral (index);
|
std::string name = runtime.getStringLiteral (index);
|
||||||
int value = runtime.getContext().getGlobalShort (name);
|
Type_Integer value = runtime.getContext().getGlobalShort (name);
|
||||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
runtime[0].mInteger = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -186,10 +186,10 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
std::string name = runtime.getStringLiteral (index);
|
std::string name = runtime.getStringLiteral (index);
|
||||||
int value = runtime.getContext().getGlobalLong (name);
|
Type_Integer value = runtime.getContext().getGlobalLong (name);
|
||||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
runtime[0].mInteger = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -199,10 +199,10 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
std::string name = runtime.getStringLiteral (index);
|
std::string name = runtime.getStringLiteral (index);
|
||||||
float value = runtime.getContext().getGlobalFloat (name);
|
Type_Float value = runtime.getContext().getGlobalFloat (name);
|
||||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
runtime[0].mFloat = value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,11 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
T result =
|
T result = getData<T> (runtime[1]) + getData<T> (runtime[0]);
|
||||||
*reinterpret_cast<T *> (&runtime[1])
|
|
||||||
+
|
|
||||||
*reinterpret_cast<T *> (&runtime[0]);
|
|
||||||
|
|
||||||
runtime.pop();
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
T result =
|
T result = getData<T> (runtime[1]) - getData<T> (runtime[0]);
|
||||||
*reinterpret_cast<T *> (&runtime[1])
|
|
||||||
-
|
|
||||||
*reinterpret_cast<T *> (&runtime[0]);
|
|
||||||
|
|
||||||
runtime.pop();
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
T result =
|
T result = getData<T> (runtime[1]) * getData<T> (runtime[0]);
|
||||||
*reinterpret_cast<T *> (&runtime[1])
|
|
||||||
*
|
|
||||||
*reinterpret_cast<T *> (&runtime[0]);
|
|
||||||
|
|
||||||
runtime.pop();
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
T left = *reinterpret_cast<T *> (&runtime[0]);
|
T left = getData<T> (runtime[0]);
|
||||||
|
|
||||||
if (left==0)
|
if (left==0)
|
||||||
throw std::runtime_error ("division by zero");
|
throw std::runtime_error ("division by zero");
|
||||||
|
|
||||||
T result =
|
T result = getData<T> (runtime[1]) / left;
|
||||||
*reinterpret_cast<T *> (&runtime[1])
|
|
||||||
/
|
|
||||||
left;
|
|
||||||
|
|
||||||
runtime.pop();
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
Type_Float value = *reinterpret_cast<Type_Float *> (&runtime[0]);
|
Type_Float value = runtime[0].mFloat;
|
||||||
|
|
||||||
if (value<0)
|
if (value<0)
|
||||||
throw std::runtime_error (
|
throw std::runtime_error (
|
||||||
|
@ -100,7 +88,7 @@ namespace Interpreter
|
||||||
|
|
||||||
value = std::sqrt (value);
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int result = C() (
|
int result = C() (getData<T> (runtime[1]), getData<T> (runtime[0]));
|
||||||
*reinterpret_cast<T *> (&runtime[1]),
|
|
||||||
*reinterpret_cast<T *> (&runtime[0]));
|
|
||||||
|
|
||||||
runtime.pop();
|
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");
|
throw std::logic_error ("message box buttons not implemented yet");
|
||||||
|
|
||||||
// message
|
// message
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
std::string message = runtime.getStringLiteral (index);
|
std::string message = runtime.getStringLiteral (index);
|
||||||
|
|
||||||
|
@ -44,13 +44,13 @@ namespace Interpreter
|
||||||
|
|
||||||
if (c=='S' || c=='s')
|
if (c=='S' || c=='s')
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
formattedMessage += runtime.getStringLiteral (index);
|
formattedMessage += runtime.getStringLiteral (index);
|
||||||
}
|
}
|
||||||
else if (c=='g' || c=='G')
|
else if (c=='g' || c=='G')
|
||||||
{
|
{
|
||||||
int value = *reinterpret_cast<const int *> (&runtime[0]);
|
Type_Integer value = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
@ -64,7 +64,7 @@ namespace Interpreter
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
float value = *reinterpret_cast<const float *> (&runtime[0]);
|
float value = runtime[0].mFloat;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
@ -107,7 +107,7 @@ namespace Interpreter
|
||||||
{
|
{
|
||||||
double r = static_cast<double> (std::rand()) / RAND_MAX; // [0, 1)
|
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)
|
if (limit<0)
|
||||||
throw std::runtime_error (
|
throw std::runtime_error (
|
||||||
|
@ -115,7 +115,7 @@ namespace Interpreter
|
||||||
|
|
||||||
Type_Integer value = static_cast<Type_Integer> (r*limit); // [o, limit)
|
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)
|
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)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
std::string id = runtime.getStringLiteral (index);
|
std::string id = runtime.getStringLiteral (index);
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
std::string id = runtime.getStringLiteral (index);
|
std::string id = runtime.getStringLiteral (index);
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
int index = runtime[0];
|
int index = runtime[0].mInteger;
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
std::string id = runtime.getStringLiteral (index);
|
std::string id = runtime.getStringLiteral (index);
|
||||||
|
|
||||||
|
|
|
@ -68,11 +68,25 @@ namespace Interpreter
|
||||||
mPC = PC;
|
mPC = PC;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Runtime::push (Type_Data data)
|
void Runtime::push (const Data& data)
|
||||||
{
|
{
|
||||||
mStack.push_back (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()
|
void Runtime::pop()
|
||||||
{
|
{
|
||||||
if (mStack.empty())
|
if (mStack.empty())
|
||||||
|
@ -81,7 +95,7 @@ namespace Interpreter
|
||||||
mStack.resize (mStack.size()-1);
|
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()))
|
if (Index<0 || Index>=static_cast<int> (mStack.size()))
|
||||||
throw std::runtime_error ("stack index out of range");
|
throw std::runtime_error ("stack index out of range");
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace Interpreter
|
||||||
const Type_Code *mCode;
|
const Type_Code *mCode;
|
||||||
int mCodeSize;
|
int mCodeSize;
|
||||||
int mPC;
|
int mPC;
|
||||||
std::vector<Type_Data> mStack;
|
std::vector<Data> mStack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -42,13 +42,19 @@ namespace Interpreter
|
||||||
void setPC (int PC);
|
void setPC (int PC);
|
||||||
///< set program counter.
|
///< set program counter.
|
||||||
|
|
||||||
void push (Type_Data data);
|
void push (const Data& data);
|
||||||
///< push data on stack
|
///< 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();
|
void pop();
|
||||||
///< pop stack
|
///< pop stack
|
||||||
|
|
||||||
Type_Data& operator[] (int Index);
|
Data& operator[] (int Index);
|
||||||
///< Access stack member, counted from the top.
|
///< Access stack member, counted from the top.
|
||||||
|
|
||||||
Context& getContext();
|
Context& getContext();
|
||||||
|
|
|
@ -13,8 +13,8 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
std::string name = runtime.getStringLiteral (runtime[0]);
|
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime[0] = runtime.getContext().isScriptRunning (name);
|
runtime[0].mInteger = runtime.getContext().isScriptRunning (name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
std::string name = runtime.getStringLiteral (runtime[0]);
|
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.getContext().startScript (name);
|
runtime.getContext().startScript (name);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
virtual void execute (Runtime& runtime)
|
||||||
{
|
{
|
||||||
std::string name = runtime.getStringLiteral (runtime[0]);
|
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
runtime.getContext().stopScript (name);
|
runtime.getContext().stopScript (name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,31 @@ namespace Interpreter
|
||||||
|
|
||||||
virtual void execute (Runtime& runtime)
|
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
|
#endif
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef INTERPRETER_TYPES_H_INCLUDED
|
#ifndef INTERPRETER_TYPES_H_INCLUDED
|
||||||
#define INTERPRETER_TYPES_H_INCLUDED
|
#define INTERPRETER_TYPES_H_INCLUDED
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace Interpreter
|
namespace Interpreter
|
||||||
{
|
{
|
||||||
typedef unsigned int Type_Code; // 32 bit
|
typedef unsigned int Type_Code; // 32 bit
|
||||||
|
@ -12,6 +14,30 @@ namespace Interpreter
|
||||||
typedef int Type_Integer; // 32 bit
|
typedef int Type_Integer; // 32 bit
|
||||||
|
|
||||||
typedef float Type_Float; // 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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue