1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-29 18:32:36 +00:00

Merge branch 'project_warp_speed' into 'master'

[Lua] Set simulation time scale

See merge request OpenMW/openmw!2053
This commit is contained in:
Petr Mikheev 2022-07-03 12:51:29 +00:00
commit 132031c136
13 changed files with 63 additions and 20 deletions

View File

@ -1082,7 +1082,7 @@ void OMW::Engine::go()
const double dt = std::chrono::duration_cast<std::chrono::duration<double>>(std::min(
frameRateLimiter.getLastFrameDuration(),
maxSimulationInterval
)).count();
)).count() * mEnvironment.getWorld()->getSimulationTimeScale();
mViewer->advance(simulationTime);

View File

@ -43,6 +43,8 @@ namespace MWSound
* much. */
NoPlayerLocal = 1<<3, /* (3D only) Don't play the sound local to the listener even if the
* player is making it. */
NoScaling = 1<<4, /* Don't scale audio with simulation time */
NoEnvNoScaling = NoEnv | NoScaling,
LoopNoEnv = Loop | NoEnv,
LoopRemoveAtDistance = Loop | RemoveAtDistance
};
@ -72,6 +74,8 @@ namespace MWBase
using PlayMode = MWSound::PlayMode;
using Type = MWSound::Type;
float mSimulationTimeScale = 1.0;
public:
SoundManager() {}
virtual ~SoundManager() {}
@ -181,6 +185,9 @@ namespace MWBase
virtual void updatePtr(const MWWorld::ConstPtr& old, const MWWorld::ConstPtr& updated) = 0;
void setSimulationTimeScale(float scale) { mSimulationTimeScale = scale; }
float getSimulationTimeScale() const { return mSimulationTimeScale; }
virtual void clear() = 0;
};
}

View File

@ -255,6 +255,10 @@ namespace MWBase
virtual float getTimeScaleFactor() const = 0;
virtual float getSimulationTimeScale() const = 0;
virtual void setSimulationTimeScale(float scale) = 0;
virtual void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent=true) = 0;
///< Move to interior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes

View File

@ -2098,7 +2098,7 @@ namespace MWGui
if (soundId.empty())
return;
MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnv);
MWBase::Environment::get().getSoundManager()->playSound(soundId, volume, pitch, MWSound::Type::Sfx, MWSound::PlayMode::NoEnvNoScaling);
}
void WindowManager::updateSpellWindow()

View File

@ -13,6 +13,7 @@
#include "eventqueue.hpp"
#include "worldview.hpp"
#include "luamanagerimp.hpp"
#include "types/types.hpp"
namespace MWLua
@ -20,8 +21,10 @@ namespace MWLua
static void addTimeBindings(sol::table& api, const Context& context, bool global)
{
MWBase::World* world = MWBase::Environment::get().getWorld();
api["getSimulationTime"] = [world=context.mWorldView]() { return world->getSimulationTime(); };
api["getSimulationTimeScale"] = [world=context.mWorldView]() { return world->getSimulationTimeScale(); };
api["getSimulationTimeScale"] = [world]() { return world->getSimulationTimeScale(); };
api["getGameTime"] = [world=context.mWorldView]() { return world->getGameTime(); };
api["getGameTimeScale"] = [world=context.mWorldView]() { return world->getGameTimeScale(); };
api["isWorldPaused"] = [world=context.mWorldView]() { return world->isPaused(); };
@ -35,8 +38,12 @@ namespace MWLua
api["setGameTimeScale"] = [world=context.mWorldView](double scale) { world->setGameTimeScale(scale); };
// TODO: Ability to make game time slower or faster than real time (needed for example for mechanics like VATS)
// api["setSimulationTimeScale"] = [](double scale) {};
api["setSimulationTimeScale"] = [context, world](float scale)
{
context.mLuaManager->addAction([scale, world] {
world->setSimulationTimeScale(scale);
});
};
// TODO: Ability to pause/resume world from Lua (needed for UI dehardcoding)
// api["pause"] = []() {};
@ -47,7 +54,7 @@ namespace MWLua
{
auto* lua = context.mLua;
sol::table api(lua->sol(), sol::create);
api["API_REVISION"] = 26;
api["API_REVISION"] = 27;
api["quit"] = [lua]()
{
Log(Debug::Warning) << "Quit requested by a Lua script.\n" << lua->debugTraceback();

View File

@ -30,7 +30,6 @@ namespace MWLua
// The number of seconds passed from the beginning of the game.
double getSimulationTime() const { return mSimulationTime; }
void setSimulationTime(double t) { mSimulationTime = t; }
double getSimulationTimeScale() const { return 1.0; }
// The game time (in game seconds) passed from the beginning of the game.
// Note that game time generally goes faster than the simulation time.

View File

@ -1126,7 +1126,7 @@ bool OpenAL_Output::playSound(Sound *sound, Sound_Handle data, float offset)
}
source = mFreeSources.front();
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(),
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound),
sound->getIsLooping(), sound->getUseEnv());
alSourcei(source, AL_BUFFER, GET_PTRID(data));
alSourcef(source, AL_SEC_OFFSET, offset);
@ -1166,7 +1166,7 @@ bool OpenAL_Output::playSound3D(Sound *sound, Sound_Handle data, float offset)
source = mFreeSources.front();
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
sound->getRealVolume(), sound->getPitch(), sound->getIsLooping(),
sound->getRealVolume(), getTimeScaledPitch(sound), sound->getIsLooping(),
sound->getUseEnv());
alSourcei(source, AL_BUFFER, GET_PTRID(data));
alSourcef(source, AL_SEC_OFFSET, offset);
@ -1228,7 +1228,7 @@ void OpenAL_Output::updateSound(Sound *sound)
ALuint source = GET_PTRID(sound->mHandle);
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
sound->getPitch(), sound->getUseEnv());
getTimeScaledPitch(sound), sound->getUseEnv());
getALError();
}
@ -1245,7 +1245,7 @@ bool OpenAL_Output::streamSound(DecoderPtr decoder, Stream *sound, bool getLoudn
if(sound->getIsLooping())
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), sound->getPitch(),
initCommon2D(source, sound->getPosition(), sound->getRealVolume(), getTimeScaledPitch(sound),
false, sound->getUseEnv());
if(getALError() != AL_NO_ERROR)
return false;
@ -1277,7 +1277,7 @@ bool OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream *sound, bool getLou
Log(Debug::Warning) << "Warning: cannot loop stream \"" << decoder->getName() << "\"";
initCommon3D(source, sound->getPosition(), sound->getMinDistance(), sound->getMaxDistance(),
sound->getRealVolume(), sound->getPitch(), false, sound->getUseEnv());
sound->getRealVolume(), getTimeScaledPitch(sound), false, sound->getUseEnv());
if(getALError() != AL_NO_ERROR)
return false;
@ -1354,7 +1354,7 @@ void OpenAL_Output::updateStream(Stream *sound)
ALuint source = stream->mSource;
updateCommon(source, sound->getPosition(), sound->getMaxDistance(), sound->getRealVolume(),
sound->getPitch(), sound->getUseEnv());
getTimeScaledPitch(sound), sound->getUseEnv());
getALError();
}
@ -1510,4 +1510,10 @@ OpenAL_Output::~OpenAL_Output()
OpenAL_Output::deinit();
}
float OpenAL_Output::getTimeScaledPitch(SoundBase *sound)
{
const bool shouldScale = !(sound->mParams.mFlags & PlayMode::NoScaling);
return shouldScale ? sound->getPitch() * mManager.getSimulationTimeScale() : sound->getPitch();
}
}

View File

@ -15,6 +15,7 @@
namespace MWSound
{
class SoundManager;
class SoundBase;
class Sound;
class Stream;
@ -55,6 +56,8 @@ namespace MWSound
void updateCommon(ALuint source, const osg::Vec3f &pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv);
float getTimeScaledPitch(SoundBase *sound);
OpenAL_Output& operator=(const OpenAL_Output &rhs);
OpenAL_Output(const OpenAL_Output &rhs);

View File

@ -248,7 +248,7 @@ namespace MWSound
mMusic->init([&] {
SoundParams params;
params.mBaseVolume = volumeFromType(Type::Music);
params.mFlags = PlayMode::NoEnv | Type::Music | Play_2D;
params.mFlags = PlayMode::NoEnvNoScaling | Type::Music | Play_2D;
return params;
} ());
mOutput->streamSound(decoder, mMusic.get());
@ -462,7 +462,7 @@ namespace MWSound
track->init([&] {
SoundParams params;
params.mBaseVolume = volumeFromType(type);
params.mFlags = PlayMode::NoEnv | type | Play_2D;
params.mFlags = PlayMode::NoEnvNoScaling | type | Play_2D;
return params;
} ());
if(!mOutput->streamSound(decoder, track.get()))

View File

@ -5,11 +5,11 @@ namespace MWSound
{
enum class Type
{
Sfx = 1 << 4, /* Normal SFX sound */
Voice = 1 << 5, /* Voice sound */
Foot = 1 << 6, /* Footstep sound */
Music = 1 << 7, /* Music track */
Movie = 1 << 8, /* Movie audio track */
Sfx = 1 << 5, /* Normal SFX sound */
Voice = 1 << 6, /* Voice sound */
Foot = 1 << 7, /* Footstep sound */
Music = 1 << 8, /* Music track */
Movie = 1 << 9, /* Movie audio track */
Mask = Sfx | Voice | Foot | Music | Movie
};
}

View File

@ -921,6 +921,12 @@ namespace MWWorld
return mCurrentDate->getTimeScaleFactor();
}
void World::setSimulationTimeScale(float scale)
{
mSimulationTimeScale = std::max(0.f, scale);
MWBase::Environment::get().getSoundManager()->setSimulationTimeScale(mSimulationTimeScale);
}
TimeStamp World::getTimeStamp() const
{
return mCurrentDate->getTimeStamp();

View File

@ -134,6 +134,8 @@ namespace MWWorld
uint32_t mRandomSeed{};
float mSimulationTimeScale = 1.0;
// not implemented
World (const World&);
World& operator= (const World&);
@ -347,6 +349,10 @@ namespace MWWorld
float getTimeScaleFactor() const override;
float getSimulationTimeScale() const override { return mSimulationTimeScale; }
void setSimulationTimeScale(float scale) override;
void changeToInteriorCell (const std::string& cellName, const ESM::Position& position, bool adjustPlayerPos, bool changeEvent = true) override;
///< Move to interior cell.
///< @param changeEvent If false, do not trigger cell change flag or detect worldspace changes

View File

@ -34,6 +34,11 @@
-- @function [parent=#world] getSimulationTimeScale
-- @return #number
---
-- Set the simulation time scale.
-- @function [parent=#world] setSimulationTimeScale
-- @param #number scale
---
-- Game time in seconds.
-- @function [parent=#world] getGameTime