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) {}
|
||||
|
||||
float Context::getDistance (const std::string& name) const
|
||||
float Context::getDistance (const std::string& name, const std::string& id) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace SAInterpreter
|
|||
|
||||
virtual void stopScript (const std::string& name);
|
||||
|
||||
virtual float getDistance (const std::string& name) const;
|
||||
virtual float getDistance (const std::string& name, const std::string& id = "") const;
|
||||
|
||||
virtual float getSecondsPassed() const;
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ set(GAMESCRIPT
|
|||
mwscript/cellextensions.cpp
|
||||
mwscript/miscextensions.cpp
|
||||
mwscript/guiextensions.cpp
|
||||
mwscript/soundextensions.cpp
|
||||
mwscript/extensions.cpp
|
||||
mwscript/globalscripts.cpp
|
||||
)
|
||||
|
@ -46,17 +47,16 @@ set(GAMESCRIPT_HEADER
|
|||
mwscript/cellextensions.hpp
|
||||
mwscript/miscextensions.hpp
|
||||
mwscript/guiextensions.hpp
|
||||
mwscript/soundextensions.hpp
|
||||
mwscript/extensions.hpp
|
||||
mwscript/globalscripts.hpp
|
||||
)
|
||||
source_group(apps\\openmw\\mwscript FILES ${GAMESCRIPT} ${GAMESCRIPT_HEADER})
|
||||
|
||||
set(GAMESOUND
|
||||
mwsound/soundmanager.cpp
|
||||
mwsound/extensions.cpp)
|
||||
mwsound/soundmanager.cpp)
|
||||
set(GAMESOUND_HEADER
|
||||
mwsound/soundmanager.hpp
|
||||
mwsound/extensions.hpp)
|
||||
mwsound/soundmanager.hpp)
|
||||
source_group(apps\\openmw\\mwsound FILES ${GAMESOUND} ${GAMESOUND_HEADER})
|
||||
|
||||
set(GAMEGUI
|
||||
|
|
|
@ -46,5 +46,13 @@ op 0x2000015: EnableMapMenu
|
|||
op 0x2000016: EnableStatsMenu
|
||||
op 0x2000017: EnableRest
|
||||
op 0x2000018: ShowRestMenu
|
||||
opcodes 0x2000019-0x3ffffff unused
|
||||
op 0x2000019: Say, explicit reference
|
||||
op 0x200001a: SayDone, explicit reference
|
||||
op 0x200001b: PlaySound3D, explicit reference
|
||||
op 0x200001c: PlaySound3DVP, explicit reference
|
||||
op 0x200001d: PlayLoopSound3D, explicit reference
|
||||
op 0x200001e: PlayLoopSound3DVP, explicit reference
|
||||
op 0x200001f: StopSound, explicit reference
|
||||
op 0x2000020: GetSoundPlaying, explicit reference
|
||||
opcodes 0x2000021-0x3ffffff unused
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
|
||||
#include "extensions.hpp"
|
||||
|
||||
#include "../mwsound/extensions.hpp"
|
||||
|
||||
#include "soundextensions.hpp"
|
||||
#include "cellextensions.hpp"
|
||||
#include "miscextensions.hpp"
|
||||
#include "guiextensions.hpp"
|
||||
|
@ -14,7 +13,7 @@ namespace MWScript
|
|||
Cell::registerExtensions (extensions);
|
||||
Misc::registerExtensions (extensions);
|
||||
Gui::registerExtensions (extensions);
|
||||
MWSound::registerExtensions (extensions);
|
||||
Sound::registerExtensions (extensions);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,9 @@
|
|||
|
||||
namespace MWScript
|
||||
{
|
||||
InterpreterContext::PtrWithCell InterpreterContext::getReference (
|
||||
MWWorld::Ptr InterpreterContext::getReference (
|
||||
const std::string& id, bool activeOnly)
|
||||
{
|
||||
PtrWithCell ref;
|
||||
|
||||
if (!id.empty())
|
||||
{
|
||||
return mEnvironment.mWorld->getPtr (id, activeOnly);
|
||||
|
@ -30,15 +28,13 @@ namespace MWScript
|
|||
if (mReference.isEmpty())
|
||||
throw std::runtime_error ("no implicit reference");
|
||||
|
||||
return PtrWithCell (mReference, mEnvironment.mWorld->find (mReference));
|
||||
return mReference;
|
||||
}
|
||||
}
|
||||
|
||||
InterpreterContext::CPtrWithCell InterpreterContext::getReference (
|
||||
const MWWorld::Ptr InterpreterContext::getReference (
|
||||
const std::string& id, bool activeOnly) const
|
||||
{
|
||||
CPtrWithCell ref;
|
||||
|
||||
if (!id.empty())
|
||||
{
|
||||
return mEnvironment.mWorld->getPtr (id, activeOnly);
|
||||
|
@ -48,7 +44,7 @@ namespace MWScript
|
|||
if (mReference.isEmpty())
|
||||
throw std::runtime_error ("no implicit reference");
|
||||
|
||||
return CPtrWithCell (mReference, mEnvironment.mWorld->find (mReference));
|
||||
return mReference;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,18 +172,17 @@ namespace MWScript
|
|||
mEnvironment.mGlobalScripts->removeScript (name);
|
||||
}
|
||||
|
||||
float InterpreterContext::getDistance (const std::string& name) const
|
||||
float InterpreterContext::getDistance (const std::string& name, const std::string& id) const
|
||||
{
|
||||
if (mReference.isEmpty())
|
||||
throw std::runtime_error ("no implicit reference");
|
||||
// TODO handle exterior cells (when ref and ref2 are located in different cells)
|
||||
const MWWorld::Ptr ref2 = getReference (id, false);
|
||||
|
||||
std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> ref =
|
||||
mEnvironment.mWorld->getPtr (name, true);
|
||||
const MWWorld::Ptr ref = mEnvironment.mWorld->getPtr (name, true);
|
||||
|
||||
double diff[3];
|
||||
|
||||
for (int i=0; i<3; ++i)
|
||||
diff[i] = ref.first.getCellRef().pos.pos[i] - mReference.getCellRef().pos.pos[i];
|
||||
diff[i] = ref.getCellRef().pos.pos[i] - ref2.getCellRef().pos.pos[i];
|
||||
|
||||
return std::sqrt (diff[0]*diff[0] + diff[1]*diff[1] + diff[2]*diff[2]);
|
||||
}
|
||||
|
@ -204,19 +199,19 @@ namespace MWScript
|
|||
|
||||
bool InterpreterContext::isDisabled (const std::string& id) const
|
||||
{
|
||||
CPtrWithCell ref = getReference (id, false);
|
||||
return !ref.first.getRefData().isEnabled();
|
||||
const MWWorld::Ptr ref = getReference (id, false);
|
||||
return !ref.getRefData().isEnabled();
|
||||
}
|
||||
|
||||
void InterpreterContext::enable (const std::string& id)
|
||||
{
|
||||
PtrWithCell ref = getReference (id, false);
|
||||
MWWorld::Ptr ref = getReference (id, false);
|
||||
mEnvironment.mWorld->enable (ref);
|
||||
}
|
||||
|
||||
void InterpreterContext::disable (const std::string& id)
|
||||
{
|
||||
PtrWithCell ref = getReference (id, false);
|
||||
MWWorld::Ptr ref = getReference (id, false);
|
||||
mEnvironment.mWorld->disable (ref);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,12 +22,10 @@ namespace MWScript
|
|||
Locals *mLocals;
|
||||
MWWorld::Ptr mReference;
|
||||
|
||||
typedef std::pair<MWWorld::Ptr, MWWorld::World::CellStore *> PtrWithCell;
|
||||
typedef std::pair<const MWWorld::Ptr, const MWWorld::World::CellStore *> CPtrWithCell;
|
||||
|
||||
PtrWithCell getReference (const std::string& id, bool activeOnly);
|
||||
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:
|
||||
|
||||
|
@ -70,7 +68,7 @@ namespace MWScript
|
|||
|
||||
virtual void stopScript (const std::string& name);
|
||||
|
||||
virtual float getDistance (const std::string& name) const;
|
||||
virtual float getDistance (const std::string& name, const std::string& id = "") const;
|
||||
|
||||
virtual bool hasBeenActivated() const;
|
||||
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
#include <components/interpreter/installopcodes.hpp>
|
||||
#include <components/interpreter/interpreter.hpp>
|
||||
|
||||
#include "../mwsound/extensions.hpp"
|
||||
|
||||
#include "soundextensions.hpp"
|
||||
#include "cellextensions.hpp"
|
||||
#include "miscextensions.hpp"
|
||||
#include "guiextensions.hpp"
|
||||
|
@ -125,7 +124,7 @@ namespace MWScript
|
|||
Cell::installOpcodes (interpreter);
|
||||
Misc::installOpcodes (interpreter);
|
||||
Gui::installOpcodes (interpreter);
|
||||
MWSound::installOpcodes (interpreter);
|
||||
Sound::installOpcodes (interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
398
apps/openmw/mwscript/soundextensions.cpp
Normal file
398
apps/openmw/mwscript/soundextensions.cpp
Normal file
|
@ -0,0 +1,398 @@
|
|||
|
||||
#include "extensions.hpp"
|
||||
|
||||
#include <components/compiler/extensions.hpp>
|
||||
|
||||
#include <components/interpreter/interpreter.hpp>
|
||||
#include <components/interpreter/runtime.hpp>
|
||||
#include <components/interpreter/opcodes.hpp>
|
||||
|
||||
#include "interpretercontext.hpp"
|
||||
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
namespace MWScript
|
||||
{
|
||||
namespace Sound
|
||||
{
|
||||
class OpSay : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string file = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
std::string text = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().say (context.getReference(), file, text,
|
||||
context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpSayDone : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
runtime.push (context.getSoundManager().sayDone (context.getReference(),
|
||||
context));
|
||||
}
|
||||
};
|
||||
|
||||
class OpStreamMusic : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().streamMusic (sound, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySound : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound (sound, 1.0, 1.0, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySoundVP : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
Interpreter::Type_Float volume = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
Interpreter::Type_Float pitch = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound (sound, volume, pitch, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySound3D : public Interpreter::Opcode0
|
||||
{
|
||||
bool mLoop;
|
||||
|
||||
public:
|
||||
|
||||
OpPlaySound3D (bool loop) : mLoop (loop) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound3D (context.getReference(), sound,
|
||||
1.0, 1.0, mLoop, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySoundVP3D : public Interpreter::Opcode0
|
||||
{
|
||||
bool mLoop;
|
||||
|
||||
public:
|
||||
|
||||
OpPlaySoundVP3D (bool loop) : mLoop (loop) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
Interpreter::Type_Float volume = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
Interpreter::Type_Float pitch = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound3D (context.getReference(), sound, volume,
|
||||
pitch, mLoop, context);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpStopSound : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().stopSound3D (context.getReference(), sound, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpGetSoundPlaying : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
runtime.push (context.getSoundManager().getSoundPlaying (
|
||||
context.getReference(), runtime.getStringLiteral (index), context));
|
||||
}
|
||||
};
|
||||
|
||||
class OpSayExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
std::string file = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
std::string text = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().say (context.getWorld().getPtr (id, true),
|
||||
file, text, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpSayDoneExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
runtime.push (context.getSoundManager().sayDone (
|
||||
context.getWorld().getPtr (id, true), context));
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySound3DExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
bool mLoop;
|
||||
|
||||
public:
|
||||
|
||||
OpPlaySound3DExplicit (bool loop) : mLoop (loop) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound3D (
|
||||
context.getWorld().getPtr (id, true), sound, 1.0, 1.0, mLoop, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySoundVP3DExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
bool mLoop;
|
||||
|
||||
public:
|
||||
|
||||
OpPlaySoundVP3DExplicit (bool loop) : mLoop (loop) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
Interpreter::Type_Float volume = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
Interpreter::Type_Float pitch = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound3D (
|
||||
context.getWorld().getPtr (id, true), sound, volume, pitch, mLoop, context);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpStopSoundExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().stopSound3D (
|
||||
context.getWorld().getPtr (id, true), sound, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpGetSoundPlayingExplicit : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string id = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
runtime.push (context.getSoundManager().getSoundPlaying (
|
||||
context.getWorld().getPtr (id, true),
|
||||
runtime.getStringLiteral (index), context));
|
||||
}
|
||||
};
|
||||
|
||||
const int opcodeSay = 0x2000001;
|
||||
const int opcodeSayDone = 0x2000002;
|
||||
const int opcodeStreamMusic = 0x2000003;
|
||||
const int opcodePlaySound = 0x2000004;
|
||||
const int opcodePlaySoundVP = 0x2000005;
|
||||
const int opcodePlaySound3D = 0x2000006;
|
||||
const int opcodePlaySound3DVP = 0x2000007;
|
||||
const int opcodePlayLoopSound3D = 0x2000008;
|
||||
const int opcodePlayLoopSound3DVP = 0x2000009;
|
||||
const int opcodeStopSound = 0x200000a;
|
||||
const int opcodeGetSoundPlaying = 0x200000b;
|
||||
|
||||
const int opcodeSayExplicit = 0x2000019;
|
||||
const int opcodeSayDoneExplicit = 0x200001a;
|
||||
const int opcodePlaySound3DExplicit = 0x200001b;
|
||||
const int opcodePlaySound3DVPExplicit = 0x200001c;
|
||||
const int opcodePlayLoopSound3DExplicit = 0x200001d;
|
||||
const int opcodePlayLoopSound3DVPExplicit = 0x200001e;
|
||||
const int opcodeStopSoundExplicit = 0x200001f;
|
||||
const int opcodeGetSoundPlayingExplicit = 0x2000020;
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions)
|
||||
{
|
||||
extensions.registerInstruction ("say", "SS", opcodeSay, opcodeSayExplicit);
|
||||
extensions.registerFunction ("saydone", 'l', "", opcodeSayDone, opcodeSayDoneExplicit);
|
||||
extensions.registerInstruction ("streammusic", "S", opcodeStreamMusic);
|
||||
extensions.registerInstruction ("playsound", "c", opcodePlaySound);
|
||||
extensions.registerInstruction ("playsoundvp", "cff", opcodePlaySoundVP);
|
||||
extensions.registerInstruction ("playsound3d", "c", opcodePlaySound3D,
|
||||
opcodePlaySound3DExplicit);
|
||||
extensions.registerInstruction ("playsound3dvp", "cff", opcodePlaySound3DVP,
|
||||
opcodePlaySound3DVPExplicit);
|
||||
extensions.registerInstruction ("playloopsound3d", "c", opcodePlayLoopSound3D,
|
||||
opcodePlayLoopSound3DExplicit);
|
||||
extensions.registerInstruction ("playloopsound3dvp", "cff", opcodePlayLoopSound3DVP,
|
||||
opcodePlayLoopSound3DVPExplicit);
|
||||
extensions.registerInstruction ("stopsound", "c", opcodeStopSound,
|
||||
opcodeStopSoundExplicit);
|
||||
extensions.registerFunction ("getsoundplaying", 'l', "c", opcodeGetSoundPlaying,
|
||||
opcodeGetSoundPlayingExplicit);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
{
|
||||
interpreter.installSegment5 (opcodeSay, new OpSay);
|
||||
interpreter.installSegment5 (opcodeSayDone, new OpSayDone);
|
||||
interpreter.installSegment5 (opcodeStreamMusic, new OpStreamMusic);
|
||||
interpreter.installSegment5 (opcodePlaySound, new OpPlaySound);
|
||||
interpreter.installSegment5 (opcodePlaySoundVP, new OpPlaySoundVP);
|
||||
interpreter.installSegment5 (opcodePlaySound3D, new OpPlaySound3D (false));
|
||||
interpreter.installSegment5 (opcodePlaySound3DVP, new OpPlaySoundVP3D (false));
|
||||
interpreter.installSegment5 (opcodePlayLoopSound3D, new OpPlaySound3D (true));
|
||||
interpreter.installSegment5 (opcodePlayLoopSound3DVP, new OpPlaySoundVP3D (true));
|
||||
interpreter.installSegment5 (opcodeStopSound, new OpStopSound);
|
||||
interpreter.installSegment5 (opcodeGetSoundPlaying, new OpGetSoundPlaying);
|
||||
|
||||
interpreter.installSegment5 (opcodeSayExplicit, new OpSayExplicit);
|
||||
interpreter.installSegment5 (opcodeSayDoneExplicit, new OpSayDoneExplicit);
|
||||
interpreter.installSegment5 (opcodePlaySound3DExplicit,
|
||||
new OpPlaySound3DExplicit (false));
|
||||
interpreter.installSegment5 (opcodePlaySound3DVPExplicit,
|
||||
new OpPlaySoundVP3DExplicit (false));
|
||||
interpreter.installSegment5 (opcodePlayLoopSound3DExplicit,
|
||||
new OpPlaySound3DExplicit (true));
|
||||
interpreter.installSegment5 (opcodePlayLoopSound3DVPExplicit,
|
||||
new OpPlaySoundVP3DExplicit (true));
|
||||
interpreter.installSegment5 (opcodeStopSoundExplicit, new OpStopSoundExplicit);
|
||||
interpreter.installSegment5 (opcodeGetSoundPlayingExplicit,
|
||||
new OpGetSoundPlayingExplicit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
27
apps/openmw/mwscript/soundextensions.hpp
Normal file
27
apps/openmw/mwscript/soundextensions.hpp
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef GAME_SCRIPT_SOUNDEXTENSIONS_H
|
||||
#define GAME_SCRIPT_SOUNDEXTENSIONS_H
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
class Extensions;
|
||||
}
|
||||
|
||||
namespace Interpreter
|
||||
{
|
||||
class Interpreter;
|
||||
}
|
||||
|
||||
namespace MWScript
|
||||
{
|
||||
namespace Sound
|
||||
{
|
||||
// Script-extensions related to sound
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions);
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
|
||||
#include "extensions.hpp"
|
||||
|
||||
#include <components/compiler/extensions.hpp>
|
||||
|
||||
#include <components/interpreter/interpreter.hpp>
|
||||
#include <components/interpreter/runtime.hpp>
|
||||
#include <components/interpreter/opcodes.hpp>
|
||||
|
||||
#include "../mwscript/interpretercontext.hpp"
|
||||
|
||||
#include "../mwworld/world.hpp"
|
||||
|
||||
#include "soundmanager.hpp"
|
||||
|
||||
namespace MWSound
|
||||
{
|
||||
namespace Script
|
||||
{
|
||||
class OpSay : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string file = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
std::string text = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().say (context.getReference(), file, text,
|
||||
context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpSayDone : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
runtime.push (context.getSoundManager().sayDone (context.getReference(),
|
||||
context));
|
||||
}
|
||||
};
|
||||
|
||||
class OpStreamMusic : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().streamMusic (sound, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySound : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound (sound, 1.0, 1.0, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySoundVP : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
float volume = *reinterpret_cast<float *> (&runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
float pitch = *reinterpret_cast<float *> (&runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound (sound, volume, pitch, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySound3D : public Interpreter::Opcode0
|
||||
{
|
||||
bool mLoop;
|
||||
|
||||
public:
|
||||
|
||||
OpPlaySound3D (bool loop) : mLoop (loop) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound3D (context.getReference(), sound,
|
||||
1.0, 1.0, mLoop, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpPlaySoundVP3D : public Interpreter::Opcode0
|
||||
{
|
||||
bool mLoop;
|
||||
|
||||
public:
|
||||
|
||||
OpPlaySoundVP3D (bool loop) : mLoop (loop) {}
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
float volume = *reinterpret_cast<float *> (&runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
float pitch = *reinterpret_cast<float *> (&runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().playSound3D (context.getReference(), sound, volume,
|
||||
pitch, mLoop, context);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class OpStopSound : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
std::string sound = runtime.getStringLiteral (runtime[0]);
|
||||
runtime.pop();
|
||||
|
||||
context.getSoundManager().stopSound3D (context.getReference(), sound, context);
|
||||
}
|
||||
};
|
||||
|
||||
class OpGetSoundPlaying : public Interpreter::Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Interpreter::Runtime& runtime)
|
||||
{
|
||||
MWScript::InterpreterContext& context
|
||||
= static_cast<MWScript::InterpreterContext&> (runtime.getContext());
|
||||
|
||||
int index = runtime[0];
|
||||
runtime.pop();
|
||||
|
||||
runtime.push (context.getSoundManager().getSoundPlaying (
|
||||
context.getReference(), runtime.getStringLiteral (index), context));
|
||||
}
|
||||
};
|
||||
|
||||
const int opcodeSay = 0x2000001;
|
||||
const int opcodeSayDone = 0x2000002;
|
||||
const int opcodeStreamMusic = 0x2000003;
|
||||
const int opcodePlaySound = 0x2000004;
|
||||
const int opcodePlaySoundVP = 0x2000005;
|
||||
const int opcodePlaySound3D = 0x2000006;
|
||||
const int opcodePlaySound3DVP = 0x2000007;
|
||||
const int opcodePlayLoopSound3D = 0x2000008;
|
||||
const int opcodePlayLoopSound3DVP = 0x2000009;
|
||||
const int opcodeStopSound = 0x200000a;
|
||||
const int opcodeGetSoundPlaying = 0x200000b;
|
||||
}
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions)
|
||||
{
|
||||
extensions.registerInstruction ("say", "SS", Script::opcodeSay);
|
||||
extensions.registerFunction ("saydone", 'l', "", Script::opcodeSayDone);
|
||||
extensions.registerInstruction ("streammusic", "S", Script::opcodeStreamMusic);
|
||||
extensions.registerInstruction ("playsound", "c", Script::opcodePlaySound);
|
||||
extensions.registerInstruction ("playsoundvp", "cff", Script::opcodePlaySoundVP);
|
||||
extensions.registerInstruction ("playsound3d", "c", Script::opcodePlaySound3D);
|
||||
extensions.registerInstruction ("playsound3dvp", "cff", Script::opcodePlaySound3DVP);
|
||||
extensions.registerInstruction ("playloopsound3d", "c", Script::opcodePlayLoopSound3D);
|
||||
extensions.registerInstruction ("playloopsound3dvp", "cff",
|
||||
Script::opcodePlayLoopSound3DVP);
|
||||
extensions.registerInstruction ("stopsound", "c", Script::opcodeStopSound);
|
||||
extensions.registerFunction ("getsoundplaying", 'l', "c", Script::opcodeGetSoundPlaying);
|
||||
}
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter)
|
||||
{
|
||||
interpreter.installSegment5 (Script::opcodeSay, new Script::OpSay);
|
||||
interpreter.installSegment5 (Script::opcodeSayDone, new Script::OpSayDone);
|
||||
interpreter.installSegment5 (Script::opcodeStreamMusic, new Script::OpStreamMusic);
|
||||
interpreter.installSegment5 (Script::opcodePlaySound, new Script::OpPlaySound);
|
||||
interpreter.installSegment5 (Script::opcodePlaySoundVP, new Script::OpPlaySoundVP);
|
||||
interpreter.installSegment5 (Script::opcodePlaySound3D, new Script::OpPlaySound3D (false));
|
||||
interpreter.installSegment5 (Script::opcodePlaySound3DVP,
|
||||
new Script::OpPlaySoundVP3D (false));
|
||||
interpreter.installSegment5 (Script::opcodePlayLoopSound3D,
|
||||
new Script::OpPlaySound3D (true));
|
||||
interpreter.installSegment5 (Script::opcodePlayLoopSound3DVP,
|
||||
new Script::OpPlaySoundVP3D (true));
|
||||
interpreter.installSegment5 (Script::opcodeStopSound, new Script::OpStopSound);
|
||||
interpreter.installSegment5 (Script::opcodeGetSoundPlaying, new Script::OpGetSoundPlaying);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef GAME_SOUND_EXTENSIONS_H
|
||||
#define GAME_SOUND_EXTENSIONS_H
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
class Extensions;
|
||||
}
|
||||
|
||||
namespace Interpreter
|
||||
{
|
||||
class Interpreter;
|
||||
}
|
||||
|
||||
namespace MWSound
|
||||
{
|
||||
// Script-extensions related to sound
|
||||
|
||||
void registerExtensions (Compiler::Extensions& extensions);
|
||||
|
||||
void installOpcodes (Interpreter::Interpreter& interpreter);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -15,13 +15,18 @@ namespace MWWorld
|
|||
|
||||
class Ptr
|
||||
{
|
||||
public:
|
||||
|
||||
typedef ESMS::CellStore<RefData> CellStore;
|
||||
|
||||
boost::any mPtr;
|
||||
ESM::CellRef *mCellRef;
|
||||
RefData *mRefData;
|
||||
CellStore *mCell;
|
||||
|
||||
public:
|
||||
|
||||
Ptr() : mCellRef (0), mRefData (0) {}
|
||||
Ptr() : mCellRef (0), mRefData (0), mCell (0) {}
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
|
@ -29,11 +34,12 @@ namespace MWWorld
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef)
|
||||
Ptr (ESMS::LiveCellRef<T, RefData> *liveCellRef, CellStore *cell)
|
||||
{
|
||||
mPtr = liveCellRef;
|
||||
mCellRef = &liveCellRef->ref;
|
||||
mRefData = &liveCellRef->mData;
|
||||
mCell = cell;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
@ -53,6 +59,12 @@ namespace MWWorld
|
|||
assert (mRefData);
|
||||
return *mRefData;
|
||||
}
|
||||
|
||||
Ptr::CellStore *getCell() const
|
||||
{
|
||||
assert (mCell);
|
||||
return mCell;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,8 @@ namespace
|
|||
{
|
||||
template<typename T>
|
||||
void listCellScripts (const ESMS::ESMStore& store,
|
||||
ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, MWWorld::World::ScriptList& scriptList)
|
||||
ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, MWWorld::World::ScriptList& scriptList,
|
||||
MWWorld::Ptr::CellStore *cell)
|
||||
{
|
||||
for (typename ESMS::CellRefList<T, MWWorld::RefData>::List::iterator iter (
|
||||
cellRefList.list.begin());
|
||||
|
@ -28,116 +29,102 @@ namespace
|
|||
iter->mData.setLocals (*script);
|
||||
|
||||
scriptList.push_back (
|
||||
std::make_pair (iter->base->script, MWWorld::Ptr (&*iter)));
|
||||
std::make_pair (iter->base->script, MWWorld::Ptr (&*iter, cell)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool hasReference (ESMS::CellRefList<T, MWWorld::RefData>& cellRefList, const MWWorld::Ptr& ptr)
|
||||
{
|
||||
for (typename ESMS::CellRefList<T, MWWorld::RefData>::List::iterator iter (
|
||||
cellRefList.list.begin());
|
||||
iter!=cellRefList.list.end(); ++iter)
|
||||
{
|
||||
if (&iter->mData==&ptr.getRefData())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace MWWorld
|
||||
{
|
||||
void World::insertInteriorScripts (ESMS::CellStore<RefData>& cell)
|
||||
{
|
||||
listCellScripts (mStore, cell.activators, mLocalScripts);
|
||||
listCellScripts (mStore, cell.potions, mLocalScripts);
|
||||
listCellScripts (mStore, cell.appas, mLocalScripts);
|
||||
listCellScripts (mStore, cell.armors, mLocalScripts);
|
||||
listCellScripts (mStore, cell.books, mLocalScripts);
|
||||
listCellScripts (mStore, cell.clothes, mLocalScripts);
|
||||
listCellScripts (mStore, cell.containers, mLocalScripts);
|
||||
listCellScripts (mStore, cell.creatures, mLocalScripts);
|
||||
listCellScripts (mStore, cell.doors, mLocalScripts);
|
||||
listCellScripts (mStore, cell.ingreds, mLocalScripts);
|
||||
listCellScripts (mStore, cell.lights, mLocalScripts);
|
||||
listCellScripts (mStore, cell.lockpicks, mLocalScripts);
|
||||
listCellScripts (mStore, cell.miscItems, mLocalScripts);
|
||||
listCellScripts (mStore, cell.npcs, mLocalScripts);
|
||||
listCellScripts (mStore, cell.probes, mLocalScripts);
|
||||
listCellScripts (mStore, cell.repairs, mLocalScripts);
|
||||
listCellScripts (mStore, cell.weapons, mLocalScripts);
|
||||
listCellScripts (mStore, cell.activators, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.potions, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.appas, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.armors, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.books, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.clothes, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.containers, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.creatures, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.doors, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.ingreds, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.lights, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.lockpicks, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.miscItems, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.npcs, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.probes, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.repairs, mLocalScripts, &cell);
|
||||
listCellScripts (mStore, cell.weapons, mLocalScripts, &cell);
|
||||
}
|
||||
|
||||
Ptr World::getPtr (const std::string& name, CellStore& cell)
|
||||
Ptr World::getPtr (const std::string& name, Ptr::CellStore& cell)
|
||||
{
|
||||
if (ESMS::LiveCellRef<ESM::Activator, RefData> *ref = cell.activators.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Potion, RefData> *ref = cell.potions.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Apparatus, RefData> *ref = cell.appas.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Armor, RefData> *ref = cell.armors.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Book, RefData> *ref = cell.books.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Clothing, RefData> *ref = cell.clothes.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Container, RefData> *ref = cell.containers.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Creature, RefData> *ref = cell.creatures.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Door, RefData> *ref = cell.doors.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Ingredient, RefData> *ref = cell.ingreds.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::CreatureLevList, RefData> *ref = cell.creatureLists.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::ItemLevList, RefData> *ref = cell.itemLists.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Light, RefData> *ref = cell.lights.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.lockpicks.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Misc, RefData> *ref = cell.miscItems.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::NPC, RefData> *ref = cell.npcs.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.probes.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Tool, RefData> *ref = cell.repairs.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Static, RefData> *ref = cell.statics.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
if (ESMS::LiveCellRef<ESM::Weapon, RefData> *ref = cell.weapons.find (name))
|
||||
return ref;
|
||||
return Ptr (ref, &cell);
|
||||
|
||||
return Ptr();
|
||||
}
|
||||
|
||||
MWRender::CellRender *World::searchRender (CellStore *store)
|
||||
MWRender::CellRender *World::searchRender (Ptr::CellStore *store)
|
||||
{
|
||||
CellRenderCollection::iterator iter = mActiveCells.find (store);
|
||||
|
||||
|
@ -157,7 +144,7 @@ namespace MWWorld
|
|||
|
||||
World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir,
|
||||
const std::string& master, const std::string& startCell, bool newGame)
|
||||
: mSkyManager (0), mScene (renderer), mPlayerPos (0)
|
||||
: mSkyManager (0), mScene (renderer), mPlayerPos (0), mCurrentCell (0)
|
||||
{
|
||||
boost::filesystem::path masterPath (dataDir);
|
||||
masterPath /= master;
|
||||
|
@ -169,6 +156,7 @@ namespace MWWorld
|
|||
mStore.load (mEsm);
|
||||
|
||||
mInteriors[startCell].loadInt (startCell, mStore, mEsm);
|
||||
mCurrentCell = &mInteriors[startCell];
|
||||
|
||||
insertInteriorScripts (mInteriors[startCell]);
|
||||
|
||||
|
@ -251,15 +239,12 @@ namespace MWWorld
|
|||
return iter->second;
|
||||
}
|
||||
|
||||
std::pair<Ptr, World::CellStore *> World::getPtr (const std::string& name, bool activeOnly)
|
||||
Ptr World::getPtr (const std::string& name, bool activeOnly)
|
||||
{
|
||||
// the player is always in an active cell.
|
||||
if (name=="player")
|
||||
{
|
||||
// TODO: find real cell (might need to be stored in playerPos). For now we
|
||||
// use the first active cell. This will fail the moment we move into an
|
||||
// exterior cell.
|
||||
return std::make_pair (mPlayerPos->getPlayer(), mActiveCells.begin()->first);
|
||||
return Ptr (mPlayerPos->getPlayer(), mCurrentCell);
|
||||
}
|
||||
|
||||
// active cells
|
||||
|
@ -269,7 +254,7 @@ namespace MWWorld
|
|||
Ptr ptr = getPtr (name, *iter->first);
|
||||
|
||||
if (!ptr.isEmpty())
|
||||
return std::make_pair (ptr, iter->first);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
if (!activeOnly)
|
||||
|
@ -280,58 +265,29 @@ namespace MWWorld
|
|||
throw std::runtime_error ("unknown ID: " + name);
|
||||
}
|
||||
|
||||
void World::enable (std::pair<Ptr, CellStore *>& reference)
|
||||
void World::enable (Ptr reference)
|
||||
{
|
||||
if (!reference.first.getRefData().isEnabled())
|
||||
if (!reference.getRefData().isEnabled())
|
||||
{
|
||||
reference.first.getRefData().enable();
|
||||
reference.getRefData().enable();
|
||||
|
||||
if (MWRender::CellRender *render = searchRender (reference.second))
|
||||
if (MWRender::CellRender *render = searchRender (reference.getCell()))
|
||||
{
|
||||
render->enable (reference.first.getRefData().getHandle());
|
||||
render->enable (reference.getRefData().getHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::disable (std::pair<Ptr, CellStore *>& reference)
|
||||
void World::disable (Ptr reference)
|
||||
{
|
||||
if (!reference.first.getRefData().isEnabled())
|
||||
if (!reference.getRefData().isEnabled())
|
||||
{
|
||||
reference.first.getRefData().enable();
|
||||
reference.getRefData().enable();
|
||||
|
||||
if (MWRender::CellRender *render = searchRender (reference.second))
|
||||
if (MWRender::CellRender *render = searchRender (reference.getCell()))
|
||||
{
|
||||
render->disable (reference.first.getRefData().getHandle());
|
||||
render->disable (reference.getRefData().getHandle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
World::CellStore *World::find (const Ptr& ptr)
|
||||
{
|
||||
for (CellRenderCollection::iterator iter (mActiveCells.begin()); iter!=mActiveCells.end();
|
||||
++iter)
|
||||
{
|
||||
if (
|
||||
hasReference (iter->first->activators, ptr) ||
|
||||
hasReference (iter->first->potions, ptr) ||
|
||||
hasReference (iter->first->appas, ptr) ||
|
||||
hasReference (iter->first->armors, ptr) ||
|
||||
hasReference (iter->first->books, ptr) ||
|
||||
hasReference (iter->first->clothes, ptr) ||
|
||||
hasReference (iter->first->containers, ptr) ||
|
||||
hasReference (iter->first->creatures, ptr) ||
|
||||
hasReference (iter->first->doors, ptr) ||
|
||||
hasReference (iter->first->ingreds, ptr) ||
|
||||
hasReference (iter->first->lights, ptr) ||
|
||||
hasReference (iter->first->lockpicks, ptr) ||
|
||||
hasReference (iter->first->miscItems, ptr) ||
|
||||
hasReference (iter->first->npcs, ptr) ||
|
||||
hasReference (iter->first->probes, ptr) ||
|
||||
hasReference (iter->first->repairs, ptr) ||
|
||||
hasReference (iter->first->weapons, ptr))
|
||||
return iter->first;
|
||||
}
|
||||
|
||||
throw std::runtime_error ("failed to locate reference in active cell");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,20 +36,20 @@ namespace MWWorld
|
|||
public:
|
||||
|
||||
typedef std::vector<std::pair<std::string, Ptr> > ScriptList;
|
||||
typedef ESMS::CellStore<RefData> CellStore;
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map<CellStore *, MWRender::CellRender *> CellRenderCollection;
|
||||
typedef std::map<Ptr::CellStore *, MWRender::CellRender *> CellRenderCollection;
|
||||
|
||||
MWRender::SkyManager* mSkyManager;
|
||||
MWRender::MWScene mScene;
|
||||
MWRender::PlayerPos *mPlayerPos;
|
||||
Ptr::CellStore *mCurrentCell; // the cell, the player is in
|
||||
CellRenderCollection mActiveCells;
|
||||
CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet)
|
||||
ESM::ESMReader mEsm;
|
||||
ESMS::ESMStore mStore;
|
||||
std::map<std::string, CellStore> mInteriors;
|
||||
std::map<std::string, Ptr::CellStore> mInteriors;
|
||||
ScriptList mLocalScripts;
|
||||
std::map<std::string, Interpreter::Type_Data> mGlobalVariables;
|
||||
|
||||
|
@ -59,9 +59,9 @@ namespace MWWorld
|
|||
|
||||
void insertInteriorScripts (ESMS::CellStore<RefData>& cell);
|
||||
|
||||
Ptr getPtr (const std::string& name, CellStore& cellStore);
|
||||
Ptr getPtr (const std::string& name, Ptr::CellStore& cellStore);
|
||||
|
||||
MWRender::CellRender *searchRender (CellStore *store);
|
||||
MWRender::CellRender *searchRender (Ptr::CellStore *store);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -82,16 +82,13 @@ namespace MWWorld
|
|||
|
||||
Interpreter::Type_Data& getGlobalVariable (const std::string& name);
|
||||
|
||||
std::pair<Ptr, CellStore *> getPtr (const std::string& name, bool activeOnly);
|
||||
Ptr getPtr (const std::string& name, bool activeOnly);
|
||||
///< Return a pointer to a liveCellRef with the given name.
|
||||
/// \param activeOnly do non search inactive cells.
|
||||
|
||||
void enable (std::pair<Ptr, CellStore *>& reference);
|
||||
void enable (Ptr reference);
|
||||
|
||||
void disable (std::pair<Ptr, CellStore *>& reference);
|
||||
|
||||
CellStore *find (const Ptr& ptr);
|
||||
///< Only active cells are searched.
|
||||
void disable (Ptr reference);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -311,6 +311,40 @@ namespace Compiler
|
|||
mNextOperand = false;
|
||||
return true;
|
||||
}
|
||||
else if (keyword==Scanner::K_getdistance)
|
||||
{
|
||||
mTokenLoc = loc;
|
||||
parseArguments ("c", scanner);
|
||||
|
||||
Generator::getDistance (mCode, mLiterals, mExplicit);
|
||||
mOperands.push_back ('f');
|
||||
mExplicit.clear();
|
||||
mRefOp = false;
|
||||
|
||||
mNextOperand = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// check for custom extensions
|
||||
if (const Extensions *extensions = getContext().getExtensions())
|
||||
{
|
||||
char returnType;
|
||||
std::string argumentType;
|
||||
|
||||
if (extensions->isFunction (keyword, returnType, argumentType, true))
|
||||
{
|
||||
mTokenLoc = loc;
|
||||
parseArguments (argumentType, scanner);
|
||||
|
||||
extensions->generateFunctionCode (keyword, mCode, mLiterals, mExplicit);
|
||||
mOperands.push_back (returnType);
|
||||
mExplicit.clear();
|
||||
mRefOp = false;
|
||||
|
||||
mNextOperand = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Parser::parseKeyword (keyword, loc, scanner);
|
||||
|
@ -366,7 +400,7 @@ namespace Compiler
|
|||
mTokenLoc = loc;
|
||||
parseArguments ("c", scanner);
|
||||
|
||||
Generator::getDistance (mCode);
|
||||
Generator::getDistance (mCode, mLiterals, "");
|
||||
mOperands.push_back ('f');
|
||||
|
||||
mNextOperand = false;
|
||||
|
@ -400,12 +434,12 @@ namespace Compiler
|
|||
char returnType;
|
||||
std::string argumentType;
|
||||
|
||||
if (extensions->isFunction (keyword, returnType, argumentType))
|
||||
if (extensions->isFunction (keyword, returnType, argumentType, false))
|
||||
{
|
||||
mTokenLoc = loc;
|
||||
parseArguments (argumentType, scanner);
|
||||
|
||||
extensions->generateFunctionCode (keyword, mCode);
|
||||
extensions->generateFunctionCode (keyword, mCode, mLiterals, "");
|
||||
mOperands.push_back (returnType);
|
||||
|
||||
mNextOperand = false;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdexcept>
|
||||
|
||||
#include "generator.hpp"
|
||||
#include "literals.hpp"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
|
@ -20,31 +21,39 @@ namespace Compiler
|
|||
return iter->second;
|
||||
}
|
||||
|
||||
bool Extensions::isFunction (int keyword, char& returnType, std::string& argumentType) const
|
||||
bool Extensions::isFunction (int keyword, char& returnType, std::string& argumentType,
|
||||
bool explicitReference) const
|
||||
{
|
||||
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
|
||||
|
||||
if (iter==mFunctions.end())
|
||||
return false;
|
||||
|
||||
if (explicitReference && iter->second.mCodeExplicit==-1)
|
||||
return false;
|
||||
|
||||
returnType = iter->second.mReturn;
|
||||
argumentType = iter->second.mArguments;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Extensions::isInstruction (int keyword, std::string& argumentType) const
|
||||
bool Extensions::isInstruction (int keyword, std::string& argumentType,
|
||||
bool explicitReference) const
|
||||
{
|
||||
std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword);
|
||||
|
||||
if (iter==mInstructions.end())
|
||||
return false;
|
||||
|
||||
if (explicitReference && iter->second.mCodeExplicit==-1)
|
||||
return false;
|
||||
|
||||
argumentType = iter->second.mArguments;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Extensions::registerFunction (const std::string& keyword, char returnType,
|
||||
const std::string& argumentType, int segment5code)
|
||||
const std::string& argumentType, int segment5code, int segment5codeExplicit)
|
||||
{
|
||||
assert (segment5code>=33554432 && segment5code<=67108863);
|
||||
|
||||
|
@ -56,12 +65,13 @@ namespace Compiler
|
|||
function.mReturn = returnType;
|
||||
function.mArguments = argumentType;
|
||||
function.mCode = segment5code;
|
||||
function.mCodeExplicit = segment5codeExplicit;
|
||||
|
||||
mFunctions.insert (std::make_pair (code, function));
|
||||
}
|
||||
|
||||
void Extensions::registerInstruction (const std::string& keyword,
|
||||
const std::string& argumentType, int segment5code)
|
||||
const std::string& argumentType, int segment5code, int segment5codeExplicit)
|
||||
{
|
||||
assert (segment5code>=33554432 && segment5code<=67108863);
|
||||
|
||||
|
@ -72,23 +82,34 @@ namespace Compiler
|
|||
Instruction instruction;
|
||||
instruction.mArguments = argumentType;
|
||||
instruction.mCode = segment5code;
|
||||
instruction.mCodeExplicit = segment5codeExplicit;
|
||||
|
||||
mInstructions.insert (std::make_pair (code, instruction));
|
||||
}
|
||||
|
||||
void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
|
||||
const
|
||||
void Extensions::generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
|
||||
Literals& literals, const std::string& id) const
|
||||
{
|
||||
std::map<int, Function>::const_iterator iter = mFunctions.find (keyword);
|
||||
|
||||
if (iter==mFunctions.end())
|
||||
throw std::logic_error ("unknown custom function keyword");
|
||||
|
||||
code.push_back (Generator::segment5 (iter->second.mCode));
|
||||
if (!id.empty())
|
||||
{
|
||||
if (iter->second.mCodeExplicit==-1)
|
||||
throw std::logic_error ("explicit references not supported");
|
||||
|
||||
int index = literals.addString (id);
|
||||
Generator::pushInt (code, literals, index);
|
||||
}
|
||||
|
||||
code.push_back (Generator::segment5 (
|
||||
id.empty() ? iter->second.mCode : iter->second.mCodeExplicit));
|
||||
}
|
||||
|
||||
void Extensions::generateInstructionCode (int keyword,
|
||||
std::vector<Interpreter::Type_Code>& code)
|
||||
std::vector<Interpreter::Type_Code>& code, Literals& literals, const std::string& id)
|
||||
const
|
||||
{
|
||||
std::map<int, Instruction>::const_iterator iter = mInstructions.find (keyword);
|
||||
|
@ -96,6 +117,16 @@ namespace Compiler
|
|||
if (iter==mInstructions.end())
|
||||
throw std::logic_error ("unknown custom instruction keyword");
|
||||
|
||||
code.push_back (Generator::segment5 (iter->second.mCode));
|
||||
if (!id.empty())
|
||||
{
|
||||
if (iter->second.mCodeExplicit==-1)
|
||||
throw std::logic_error ("explicit references not supported");
|
||||
|
||||
int index = literals.addString (id);
|
||||
Generator::pushInt (code, literals, index);
|
||||
}
|
||||
|
||||
code.push_back (Generator::segment5 (
|
||||
id.empty() ? iter->second.mCode : iter->second.mCodeExplicit));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
namespace Compiler
|
||||
{
|
||||
class Literals;
|
||||
|
||||
/// \brief Collection of compiler extensions
|
||||
|
||||
class Extensions
|
||||
|
@ -18,12 +20,14 @@ namespace Compiler
|
|||
char mReturn;
|
||||
std::string mArguments;
|
||||
int mCode;
|
||||
int mCodeExplicit;
|
||||
};
|
||||
|
||||
struct Instruction
|
||||
{
|
||||
std::string mArguments;
|
||||
int mCode;
|
||||
int mCodeExplicit;
|
||||
};
|
||||
|
||||
int mNextKeywordIndex;
|
||||
|
@ -40,33 +44,37 @@ namespace Compiler
|
|||
/// - if no match is found 0 is returned.
|
||||
/// - keyword must be all lower case.
|
||||
|
||||
bool isFunction (int keyword, char& returnType, std::string& argumentType) const;
|
||||
bool isFunction (int keyword, char& returnType, std::string& argumentType,
|
||||
bool explicitReference) const;
|
||||
///< Is this keyword registered with a function? If yes, return return and argument
|
||||
/// types.
|
||||
|
||||
bool isInstruction (int keyword, std::string& argumentType) const;
|
||||
bool isInstruction (int keyword, std::string& argumentType,
|
||||
bool explicitReference) const;
|
||||
///< Is this keyword registered with a function? If yes, return argument types.
|
||||
|
||||
void registerFunction (const std::string& keyword, char returnType,
|
||||
const std::string& argumentType, int segment5code);
|
||||
const std::string& argumentType, int segment5code, int segment5codeExplicit = -1);
|
||||
///< Register a custom function
|
||||
/// - keyword must be all lower case.
|
||||
/// - keyword must be unique
|
||||
/// - if explicit references are not supported, segment5codeExplicit must be set to -1
|
||||
/// \note Currently only segment 5 opcodes are supported.
|
||||
|
||||
void registerInstruction (const std::string& keyword,
|
||||
const std::string& argumentType, int segment5code);
|
||||
const std::string& argumentType, int segment5code, int segment5codeExplicit = -1);
|
||||
///< Register a custom instruction
|
||||
/// - keyword must be all lower case.
|
||||
/// - keyword must be unique
|
||||
/// - if explicit references are not supported, segment5codeExplicit must be set to -1
|
||||
/// \note Currently only segment 5 opcodes are supported.
|
||||
|
||||
void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
|
||||
const;
|
||||
void generateFunctionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
|
||||
Literals& literals, const std::string& id) const;
|
||||
///< Append code for function to \a code.
|
||||
|
||||
void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code)
|
||||
const;
|
||||
void generateInstructionCode (int keyword, std::vector<Interpreter::Type_Code>& code,
|
||||
Literals& literals, const std::string& id) const;
|
||||
///< Append code for function to \a code.
|
||||
};
|
||||
}
|
||||
|
|
|
@ -314,6 +314,11 @@ namespace
|
|||
{
|
||||
code.push_back (Compiler::Generator::segment5 (56));
|
||||
}
|
||||
|
||||
void opGetDistanceExplicit (Compiler::Generator::CodeContainer& code)
|
||||
{
|
||||
code.push_back (Compiler::Generator::segment5 (57));
|
||||
}
|
||||
}
|
||||
|
||||
namespace Compiler
|
||||
|
@ -706,10 +711,19 @@ namespace Compiler
|
|||
opStopScript (code);
|
||||
}
|
||||
|
||||
void getDistance (CodeContainer& code)
|
||||
void getDistance (CodeContainer& code, Literals& literals, const std::string id)
|
||||
{
|
||||
if (id.empty())
|
||||
{
|
||||
opGetDistance (code);
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = literals.addString (id);
|
||||
opPushInt (code, index);
|
||||
opGetDistanceExplicit (code);
|
||||
}
|
||||
}
|
||||
|
||||
void getSecondsPassed (CodeContainer& code)
|
||||
{
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace Compiler
|
|||
|
||||
void stopScript (CodeContainer& code);
|
||||
|
||||
void getDistance (CodeContainer& code);
|
||||
void getDistance (CodeContainer& code, Literals& literals, const std::string id);
|
||||
|
||||
void getSecondsPassed (CodeContainer& code);
|
||||
|
||||
|
|
|
@ -157,6 +157,21 @@ namespace Compiler
|
|||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
// check for custom extensions
|
||||
if (const Extensions *extensions = getContext().getExtensions())
|
||||
{
|
||||
std::string argumentType;
|
||||
|
||||
if (extensions->isInstruction (keyword, argumentType, mState==ExplicitState))
|
||||
{
|
||||
mExprParser.parseArguments (argumentType, scanner, mCode, true);
|
||||
|
||||
extensions->generateInstructionCode (keyword, mCode, mLiterals, mExplicit);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mState==BeginState)
|
||||
|
@ -189,21 +204,6 @@ namespace Compiler
|
|||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
|
||||
// check for custom extensions
|
||||
if (const Extensions *extensions = getContext().getExtensions())
|
||||
{
|
||||
std::string argumentType;
|
||||
|
||||
if (extensions->isInstruction (keyword, argumentType))
|
||||
{
|
||||
mExprParser.parseArguments (argumentType, scanner, mCode, true);
|
||||
|
||||
extensions->generateInstructionCode (keyword, mCode);
|
||||
mState = EndState;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mState==SetLocalVarState && keyword==Scanner::K_to)
|
||||
{
|
||||
|
|
|
@ -53,7 +53,8 @@ namespace Interpreter
|
|||
|
||||
virtual void stopScript (const std::string& name) = 0;
|
||||
|
||||
virtual float getDistance (const std::string& name) const = 0;
|
||||
virtual float getDistance (const std::string& name, const std::string& id = "") const
|
||||
= 0;
|
||||
|
||||
virtual float getSecondsPassed() const = 0;
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
if (data==0)
|
||||
|
@ -38,7 +38,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
if (data!=0)
|
||||
|
|
|
@ -115,6 +115,8 @@ op 53: push 1, if implicit reference is disabled, 0 else
|
|||
op 54: explicit reference = stack[0]; pop; enable explicit reference
|
||||
op 55: explicit reference = stack[0]; pop; disable explicit reference
|
||||
op 56: explicit reference = stack[0]; pop; push 1, if explicit reference is disabled, 0 else
|
||||
opcodes 57-33554431 unused
|
||||
op 57: explicit reference = stack[0]; pop;
|
||||
replace stack[0] with distance between explicit reference and a reference of ID stack[0]
|
||||
opcodes 58-33554431 unused
|
||||
opcodes 33554432-67108863 reserved for extensions
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime, unsigned int arg0)
|
||||
{
|
||||
runtime.push (arg0);
|
||||
runtime.push (static_cast<Type_Integer> (arg0));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -22,9 +22,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[0]);
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
Type_Float floatValue = static_cast<Type_Float> (data);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&floatValue);
|
||||
runtime[0].mFloat = floatValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -34,9 +34,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[0]);
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
Type_Integer integerValue = static_cast<Type_Integer> (data);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&integerValue);
|
||||
runtime[0].mInteger = integerValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -46,9 +46,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[0]);
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
data = -data;
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&data);
|
||||
runtime[0].mInteger = data;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,9 +58,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[0]);
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
data = -data;
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&data);
|
||||
runtime[0].mFloat = data;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -70,9 +70,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Integer data = *reinterpret_cast<Type_Integer *> (&runtime[1]);
|
||||
Type_Integer data = runtime[1].mInteger;
|
||||
Type_Float floatValue = static_cast<Type_Float> (data);
|
||||
runtime[1] = *reinterpret_cast<Type_Data *> (&floatValue);
|
||||
runtime[1].mFloat = floatValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -82,9 +82,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float data = *reinterpret_cast<Type_Float *> (&runtime[1]);
|
||||
Type_Float data = runtime[1].mFloat;
|
||||
Type_Integer integerValue = static_cast<Type_Integer> (data);
|
||||
runtime[1] = *reinterpret_cast<Type_Data *> (&integerValue);
|
||||
runtime[1].mInteger = integerValue;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ namespace Interpreter
|
|||
|
||||
// spacial
|
||||
interpreter.installSegment5 (49, new OpGetDistance);
|
||||
interpreter.installSegment5 (57, new OpGetDistanceExplicit);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
int index = runtime[1];
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
int index = runtime[1].mInteger;
|
||||
|
||||
runtime.getContext().setLocalShort (index, *reinterpret_cast<int *> (&data));
|
||||
runtime.getContext().setLocalShort (index, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
|
@ -29,10 +29,10 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
int index = runtime[1];
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
int index = runtime[1].mInteger;
|
||||
|
||||
runtime.getContext().setLocalLong (index, *reinterpret_cast<int *> (&data));
|
||||
runtime.getContext().setLocalLong (index, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
|
@ -45,10 +45,10 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
int index = runtime[1];
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
int index = runtime[1].mInteger;
|
||||
|
||||
runtime.getContext().setLocalFloat (index, *reinterpret_cast<float *> (&data));
|
||||
runtime.getContext().setLocalFloat (index, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
|
@ -61,8 +61,8 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int intValue = runtime.getIntegerLiteral (runtime[0]);
|
||||
runtime[0] = intValue;
|
||||
Type_Integer intValue = runtime.getIntegerLiteral (runtime[0].mInteger);
|
||||
runtime[0].mInteger = intValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -72,8 +72,8 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
float floatValue = runtime.getFloatLiteral (runtime[0]);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&floatValue);
|
||||
Type_Float floatValue = runtime.getFloatLiteral (runtime[0].mInteger);
|
||||
runtime[0].mFloat = floatValue;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -83,9 +83,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
int value = runtime.getContext().getLocalShort (index);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -95,9 +95,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
int value = runtime.getContext().getLocalLong (index);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -107,9 +107,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
float value = runtime.getContext().getLocalFloat (index);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -119,12 +119,12 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
int index = runtime[1];
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
int index = runtime[1].mInteger;
|
||||
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setGlobalShort (name, *reinterpret_cast<int *> (&data));
|
||||
runtime.getContext().setGlobalShort (name, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
|
@ -137,12 +137,12 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
int index = runtime[1];
|
||||
Type_Integer data = runtime[0].mInteger;
|
||||
int index = runtime[1].mInteger;
|
||||
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setGlobalLong (name, *reinterpret_cast<int *> (&data));
|
||||
runtime.getContext().setGlobalLong (name, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
|
@ -155,12 +155,12 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Data data = runtime[0];
|
||||
int index = runtime[1];
|
||||
Type_Float data = runtime[0].mFloat;
|
||||
int index = runtime[1].mInteger;
|
||||
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
|
||||
runtime.getContext().setGlobalFloat (name, *reinterpret_cast<float *> (&data));
|
||||
runtime.getContext().setGlobalFloat (name, data);
|
||||
|
||||
runtime.pop();
|
||||
runtime.pop();
|
||||
|
@ -173,10 +173,10 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
int value = runtime.getContext().getGlobalShort (name);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
Type_Integer value = runtime.getContext().getGlobalShort (name);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -186,10 +186,10 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
int value = runtime.getContext().getGlobalLong (name);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
Type_Integer value = runtime.getContext().getGlobalLong (name);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -199,10 +199,10 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
std::string name = runtime.getStringLiteral (index);
|
||||
float value = runtime.getContext().getGlobalFloat (name);
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
Type_Float value = runtime.getContext().getGlobalFloat (name);
|
||||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -16,14 +16,11 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
T result =
|
||||
*reinterpret_cast<T *> (&runtime[1])
|
||||
+
|
||||
*reinterpret_cast<T *> (&runtime[0]);
|
||||
T result = getData<T> (runtime[1]) + getData<T> (runtime[0]);
|
||||
|
||||
runtime.pop();
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&result);
|
||||
getData<T> (runtime[0]) = result;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -34,14 +31,11 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
T result =
|
||||
*reinterpret_cast<T *> (&runtime[1])
|
||||
-
|
||||
*reinterpret_cast<T *> (&runtime[0]);
|
||||
T result = getData<T> (runtime[1]) - getData<T> (runtime[0]);
|
||||
|
||||
runtime.pop();
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&result);
|
||||
getData<T> (runtime[0]) = result;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -52,14 +46,11 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
T result =
|
||||
*reinterpret_cast<T *> (&runtime[1])
|
||||
*
|
||||
*reinterpret_cast<T *> (&runtime[0]);
|
||||
T result = getData<T> (runtime[1]) * getData<T> (runtime[0]);
|
||||
|
||||
runtime.pop();
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&result);
|
||||
getData<T> (runtime[0]) = result;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -70,19 +61,16 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
T left = *reinterpret_cast<T *> (&runtime[0]);
|
||||
T left = getData<T> (runtime[0]);
|
||||
|
||||
if (left==0)
|
||||
throw std::runtime_error ("division by zero");
|
||||
|
||||
T result =
|
||||
*reinterpret_cast<T *> (&runtime[1])
|
||||
/
|
||||
left;
|
||||
T result = getData<T> (runtime[1]) / left;
|
||||
|
||||
runtime.pop();
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&result);
|
||||
getData<T> (runtime[0]) = result;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -92,7 +80,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
Type_Float value = *reinterpret_cast<Type_Float *> (&runtime[0]);
|
||||
Type_Float value = runtime[0].mFloat;
|
||||
|
||||
if (value<0)
|
||||
throw std::runtime_error (
|
||||
|
@ -100,7 +88,7 @@ namespace Interpreter
|
|||
|
||||
value = std::sqrt (value);
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
runtime[0].mFloat = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -111,13 +99,11 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int result = C() (
|
||||
*reinterpret_cast<T *> (&runtime[1]),
|
||||
*reinterpret_cast<T *> (&runtime[0]));
|
||||
int result = C() (getData<T> (runtime[1]), getData<T> (runtime[0]));
|
||||
|
||||
runtime.pop();
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&result);
|
||||
runtime[0].mInteger = result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Interpreter
|
|||
throw std::logic_error ("message box buttons not implemented yet");
|
||||
|
||||
// message
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
std::string message = runtime.getStringLiteral (index);
|
||||
|
||||
|
@ -44,13 +44,13 @@ namespace Interpreter
|
|||
|
||||
if (c=='S' || c=='s')
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
formattedMessage += runtime.getStringLiteral (index);
|
||||
}
|
||||
else if (c=='g' || c=='G')
|
||||
{
|
||||
int value = *reinterpret_cast<const int *> (&runtime[0]);
|
||||
Type_Integer value = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
|
||||
std::ostringstream out;
|
||||
|
@ -64,7 +64,7 @@ namespace Interpreter
|
|||
++i;
|
||||
}
|
||||
|
||||
float value = *reinterpret_cast<const float *> (&runtime[0]);
|
||||
float value = runtime[0].mFloat;
|
||||
runtime.pop();
|
||||
|
||||
std::ostringstream out;
|
||||
|
@ -107,7 +107,7 @@ namespace Interpreter
|
|||
{
|
||||
double r = static_cast<double> (std::rand()) / RAND_MAX; // [0, 1)
|
||||
|
||||
Type_Integer limit = *reinterpret_cast<Type_Integer *> (&runtime[0]);
|
||||
Type_Integer limit = runtime[0].mInteger;
|
||||
|
||||
if (limit<0)
|
||||
throw std::runtime_error (
|
||||
|
@ -115,7 +115,7 @@ namespace Interpreter
|
|||
|
||||
Type_Integer value = static_cast<Type_Integer> (r*limit); // [o, limit)
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&value);
|
||||
runtime[0].mInteger = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -125,9 +125,9 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
float duration = runtime.getContext().getSecondsPassed();
|
||||
Type_Float duration = runtime.getContext().getSecondsPassed();
|
||||
|
||||
runtime.push (*reinterpret_cast<Type_Data *> (&duration));
|
||||
runtime.push (duration);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -167,7 +167,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
|
||||
|
@ -181,7 +181,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
|
||||
|
@ -195,7 +195,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0];
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
|
||||
|
|
|
@ -68,11 +68,25 @@ namespace Interpreter
|
|||
mPC = PC;
|
||||
}
|
||||
|
||||
void Runtime::push (Type_Data data)
|
||||
void Runtime::push (const Data& data)
|
||||
{
|
||||
mStack.push_back (data);
|
||||
}
|
||||
|
||||
void Runtime::push (Type_Integer value)
|
||||
{
|
||||
Data data;
|
||||
data.mInteger = value;
|
||||
push (data);
|
||||
}
|
||||
|
||||
void Runtime::push (Type_Float value)
|
||||
{
|
||||
Data data;
|
||||
data.mFloat = value;
|
||||
push (data);
|
||||
}
|
||||
|
||||
void Runtime::pop()
|
||||
{
|
||||
if (mStack.empty())
|
||||
|
@ -81,7 +95,7 @@ namespace Interpreter
|
|||
mStack.resize (mStack.size()-1);
|
||||
}
|
||||
|
||||
Type_Data& Runtime::operator[] (int Index)
|
||||
Data& Runtime::operator[] (int Index)
|
||||
{
|
||||
if (Index<0 || Index>=static_cast<int> (mStack.size()))
|
||||
throw std::runtime_error ("stack index out of range");
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Interpreter
|
|||
const Type_Code *mCode;
|
||||
int mCodeSize;
|
||||
int mPC;
|
||||
std::vector<Type_Data> mStack;
|
||||
std::vector<Data> mStack;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -42,13 +42,19 @@ namespace Interpreter
|
|||
void setPC (int PC);
|
||||
///< set program counter.
|
||||
|
||||
void push (Type_Data data);
|
||||
void push (const Data& data);
|
||||
///< push data on stack
|
||||
|
||||
void push (Type_Integer value);
|
||||
///< push integer data on stack.
|
||||
|
||||
void push (Type_Float value);
|
||||
///< push float data on stack.
|
||||
|
||||
void pop();
|
||||
///< pop stack
|
||||
|
||||
Type_Data& operator[] (int Index);
|
||||
Data& operator[] (int Index);
|
||||
///< Access stack member, counted from the top.
|
||||
|
||||
Context& getContext();
|
||||
|
|
|
@ -13,8 +13,8 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
std::string name = runtime.getStringLiteral (runtime[0]);
|
||||
runtime[0] = runtime.getContext().isScriptRunning (name);
|
||||
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime[0].mInteger = runtime.getContext().isScriptRunning (name);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
std::string name = runtime.getStringLiteral (runtime[0]);
|
||||
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
runtime.getContext().startScript (name);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
std::string name = runtime.getStringLiteral (runtime[0]);
|
||||
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
runtime.pop();
|
||||
runtime.getContext().stopScript (name);
|
||||
}
|
||||
|
|
|
@ -12,11 +12,29 @@ namespace Interpreter
|
|||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
std::string name = runtime.getStringLiteral (runtime[0]);
|
||||
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
|
||||
float distance = runtime.getContext().getDistance (name);
|
||||
Type_Float distance = runtime.getContext().getDistance (name);
|
||||
|
||||
runtime[0] = *reinterpret_cast<Type_Data *> (&distance);
|
||||
runtime[0].mFloat = distance;
|
||||
}
|
||||
};
|
||||
|
||||
class OpGetDistanceExplicit : public Opcode0
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void execute (Runtime& runtime)
|
||||
{
|
||||
int index = runtime[0].mInteger;
|
||||
runtime.pop();
|
||||
std::string id = runtime.getStringLiteral (index);
|
||||
|
||||
std::string name = runtime.getStringLiteral (runtime[0].mInteger);
|
||||
|
||||
Type_Float distance = runtime.getContext().getDistance (name, id);
|
||||
|
||||
runtime[0].mFloat = distance;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef INTERPRETER_TYPES_H_INCLUDED
|
||||
#define INTERPRETER_TYPES_H_INCLUDED
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace Interpreter
|
||||
{
|
||||
typedef unsigned int Type_Code; // 32 bit
|
||||
|
@ -12,6 +14,30 @@ namespace Interpreter
|
|||
typedef int Type_Integer; // 32 bit
|
||||
|
||||
typedef float Type_Float; // 32 bit
|
||||
|
||||
union Data
|
||||
{
|
||||
Type_Integer mInteger;
|
||||
Type_Float mFloat;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
T& getData (Data& data)
|
||||
{
|
||||
throw std::runtime_error ("unsupported data type");
|
||||
}
|
||||
|
||||
template<>
|
||||
inline Type_Integer& getData (Data& data)
|
||||
{
|
||||
return data.mInteger;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline Type_Float& getData (Data& data)
|
||||
{
|
||||
return data.mFloat;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue