mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-07 08:21:04 +00:00
Merge branch 'master' of https://github.com/rheit/zdoom
This commit is contained in:
commit
f4e4221da7
6 changed files with 128 additions and 57 deletions
|
@ -193,7 +193,7 @@ set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEB_C_FLAGS} -D_DEBUG" )
|
||||||
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
option(FORCE_INTERNAL_ZLIB "Use internal zlib")
|
||||||
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
option(FORCE_INTERNAL_JPEG "Use internal jpeg")
|
||||||
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
option(FORCE_INTERNAL_BZIP2 "Use internal bzip2")
|
||||||
option(FORCE_INTERNAL_GME "Use internal gme" ON)
|
option(FORCE_INTERNAL_GME "Use internal gme")
|
||||||
|
|
||||||
# Fast math flags, required by some subprojects
|
# Fast math flags, required by some subprojects
|
||||||
set( ZD_FASTMATH_FLAG "" )
|
set( ZD_FASTMATH_FLAG "" )
|
||||||
|
|
|
@ -301,9 +301,9 @@ void DFlicker::Tick ()
|
||||||
DFlicker::DFlicker (sector_t *sector, int upper, int lower)
|
DFlicker::DFlicker (sector_t *sector, int upper, int lower)
|
||||||
: DLighting (sector)
|
: DLighting (sector)
|
||||||
{
|
{
|
||||||
m_MaxLight = upper;
|
m_MaxLight = sector_t::ClampLight(upper);
|
||||||
m_MinLight = lower;
|
m_MinLight = sector_t::ClampLight(lower);
|
||||||
sector->lightlevel = upper;
|
sector->lightlevel = m_MaxLight;
|
||||||
m_Count = (pr_flicker()&64)+1;
|
m_Count = (pr_flicker()&64)+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ static oalloadentry oalfuncs[] = {
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef IN_IDE_PARSER
|
||||||
#define alEnable p_alEnable
|
#define alEnable p_alEnable
|
||||||
#define alDisable p_alDisable
|
#define alDisable p_alDisable
|
||||||
#define alIsEnabled p_alIsEnabled
|
#define alIsEnabled p_alIsEnabled
|
||||||
|
@ -116,6 +116,7 @@ static oalloadentry oalfuncs[] = {
|
||||||
#define alcCaptureStart p_alcCaptureStart
|
#define alcCaptureStart p_alcCaptureStart
|
||||||
#define alcCaptureStop p_alcCaptureStop
|
#define alcCaptureStop p_alcCaptureStop
|
||||||
#define alcCaptureSamples p_alcCaptureSamples
|
#define alcCaptureSamples p_alcCaptureSamples
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
|
@ -40,6 +40,9 @@
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include "except.h"
|
#include "except.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
@ -69,7 +72,7 @@ static void* hmodOpenAL;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define OPENALLIB "OpenAL.framework/OpenAL"
|
#define OPENALLIB "OpenAL.framework/OpenAL"
|
||||||
#else
|
#else
|
||||||
#define OPENALLIB "libopenal.so"
|
#define OPENALLIB "libopenal.so.1"
|
||||||
#endif
|
#endif
|
||||||
#define LoadLibrary(x) dlopen((x), RTLD_LAZY)
|
#define LoadLibrary(x) dlopen((x), RTLD_LAZY)
|
||||||
#define GetProcAddress(a,b) dlsym((a),(b))
|
#define GetProcAddress(a,b) dlsym((a),(b))
|
||||||
|
@ -273,6 +276,8 @@ class OpenALSoundStream : public SoundStream
|
||||||
alSourcei(Source, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
alSourcei(Source, AL_DIRECT_FILTER, AL_FILTER_NULL);
|
||||||
alSource3i(Source, AL_AUXILIARY_SEND_FILTER, 0, 0, AL_FILTER_NULL);
|
alSource3i(Source, AL_AUXILIARY_SEND_FILTER, 0, 0, AL_FILTER_NULL);
|
||||||
}
|
}
|
||||||
|
if(Renderer->AL.EXT_SOURCE_RADIUS)
|
||||||
|
alSourcef(Source, AL_SOURCE_RADIUS, 0.f);
|
||||||
|
|
||||||
alGenBuffers(BufferCount, Buffers);
|
alGenBuffers(BufferCount, Buffers);
|
||||||
return (getALError() == AL_NO_ERROR);
|
return (getALError() == AL_NO_ERROR);
|
||||||
|
@ -626,12 +631,21 @@ public:
|
||||||
|
|
||||||
extern ReverbContainer *ForcedEnvironment;
|
extern ReverbContainer *ForcedEnvironment;
|
||||||
|
|
||||||
#define AREA_SOUND_RADIUS (128.f)
|
#define AREA_SOUND_RADIUS (32.f)
|
||||||
|
|
||||||
#define PITCH_MULT (0.7937005f) /* Approx. 4 semitones lower; what Nash suggested */
|
#define PITCH_MULT (0.7937005f) /* Approx. 4 semitones lower; what Nash suggested */
|
||||||
|
|
||||||
#define PITCH(pitch) (snd_pitched ? (pitch)/128.f : 1.f)
|
#define PITCH(pitch) (snd_pitched ? (pitch)/128.f : 1.f)
|
||||||
|
|
||||||
|
static size_t GetChannelCount(ChannelConfig chans)
|
||||||
|
{
|
||||||
|
switch(chans)
|
||||||
|
{
|
||||||
|
case ChannelConfig_Mono: return 1;
|
||||||
|
case ChannelConfig_Stereo: return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static float GetRolloff(const FRolloffInfo *rolloff, float distance)
|
static float GetRolloff(const FRolloffInfo *rolloff, float distance)
|
||||||
{
|
{
|
||||||
|
@ -686,7 +700,12 @@ template<typename T>
|
||||||
static void LoadALFunc(const char *name, T *x)
|
static void LoadALFunc(const char *name, T *x)
|
||||||
{ *x = reinterpret_cast<T>(alGetProcAddress(name)); }
|
{ *x = reinterpret_cast<T>(alGetProcAddress(name)); }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void LoadALCFunc(ALCdevice *device, const char *name, T *x)
|
||||||
|
{ *x = reinterpret_cast<T>(alcGetProcAddress(device, name)); }
|
||||||
|
|
||||||
#define LOAD_FUNC(x) (LoadALFunc(#x, &x))
|
#define LOAD_FUNC(x) (LoadALFunc(#x, &x))
|
||||||
|
#define LOAD_DEV_FUNC(d, x) (LoadALCFunc(d, #x, &x))
|
||||||
OpenALSoundRenderer::OpenALSoundRenderer()
|
OpenALSoundRenderer::OpenALSoundRenderer()
|
||||||
: Device(NULL), Context(NULL), SFXPaused(0), PrevEnvironment(NULL), EnvSlot(0)
|
: Device(NULL), Context(NULL), SFXPaused(0), PrevEnvironment(NULL), EnvSlot(0)
|
||||||
{
|
{
|
||||||
|
@ -744,8 +763,10 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
||||||
DPrintf(" Extensions: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_EXTENSIONS));
|
DPrintf(" Extensions: " TEXTCOLOR_ORANGE"%s\n", alGetString(AL_EXTENSIONS));
|
||||||
|
|
||||||
ALC.EXT_EFX = !!alcIsExtensionPresent(Device, "ALC_EXT_EFX");
|
ALC.EXT_EFX = !!alcIsExtensionPresent(Device, "ALC_EXT_EFX");
|
||||||
ALC.EXT_disconnect = !!alcIsExtensionPresent(Device, "ALC_EXT_disconnect");;
|
ALC.EXT_disconnect = !!alcIsExtensionPresent(Device, "ALC_EXT_disconnect");
|
||||||
|
ALC.SOFT_pause_device = !!alcIsExtensionPresent(Device, "ALC_SOFT_pause_device");
|
||||||
AL.EXT_source_distance_model = !!alIsExtensionPresent("AL_EXT_source_distance_model");
|
AL.EXT_source_distance_model = !!alIsExtensionPresent("AL_EXT_source_distance_model");
|
||||||
|
AL.EXT_SOURCE_RADIUS = !!alIsExtensionPresent("AL_EXT_SOURCE_RADIUS");
|
||||||
AL.SOFT_deferred_updates = !!alIsExtensionPresent("AL_SOFT_deferred_updates");
|
AL.SOFT_deferred_updates = !!alIsExtensionPresent("AL_SOFT_deferred_updates");
|
||||||
AL.SOFT_loop_points = !!alIsExtensionPresent("AL_SOFT_loop_points");
|
AL.SOFT_loop_points = !!alIsExtensionPresent("AL_SOFT_loop_points");
|
||||||
|
|
||||||
|
@ -766,6 +787,12 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
||||||
alProcessUpdatesSOFT = _wrap_ProcessUpdatesSOFT;
|
alProcessUpdatesSOFT = _wrap_ProcessUpdatesSOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ALC.SOFT_pause_device)
|
||||||
|
{
|
||||||
|
LOAD_DEV_FUNC(Device, alcDevicePauseSOFT);
|
||||||
|
LOAD_DEV_FUNC(Device, alcDeviceResumeSOFT);
|
||||||
|
}
|
||||||
|
|
||||||
ALenum err = getALError();
|
ALenum err = getALError();
|
||||||
if(err != AL_NO_ERROR)
|
if(err != AL_NO_ERROR)
|
||||||
{
|
{
|
||||||
|
@ -905,6 +932,7 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
||||||
if(EnvSlot)
|
if(EnvSlot)
|
||||||
Printf(" EFX enabled\n");
|
Printf(" EFX enabled\n");
|
||||||
}
|
}
|
||||||
|
#undef LOAD_DEV_FUNC
|
||||||
#undef LOAD_FUNC
|
#undef LOAD_FUNC
|
||||||
|
|
||||||
OpenALSoundRenderer::~OpenALSoundRenderer()
|
OpenALSoundRenderer::~OpenALSoundRenderer()
|
||||||
|
@ -1042,7 +1070,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int
|
||||||
{
|
{
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for(int c = 0;c < channels;c++)
|
for(int c = 0;c < channels;c++)
|
||||||
sum = ((short*)sfxdata)[i*channels + c];
|
sum += ((short*)sfxdata)[i*channels + c];
|
||||||
((short*)sfxdata)[i] = sum / channels;
|
((short*)sfxdata)[i] = sum / channels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1052,7 +1080,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(BYTE *sfxdata, int
|
||||||
{
|
{
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
for(int c = 0;c < channels;c++)
|
for(int c = 0;c < channels;c++)
|
||||||
sum = sfxdata[i*channels + c] - 128;
|
sum += sfxdata[i*channels + c] - 128;
|
||||||
sfxdata[i] = (sum / channels) + 128;
|
sfxdata[i] = (sum / channels) + 128;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1124,7 +1152,7 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(BYTE *sfxdata, int le
|
||||||
SampleType type;
|
SampleType type;
|
||||||
int srate;
|
int srate;
|
||||||
|
|
||||||
SoundDecoder *decoder = CreateDecoder(&reader);
|
std::unique_ptr<SoundDecoder> decoder(CreateDecoder(&reader));
|
||||||
if(!decoder) return std::make_pair(retval, true);
|
if(!decoder) return std::make_pair(retval, true);
|
||||||
|
|
||||||
decoder->getInfo(&srate, &chans, &type);
|
decoder->getInfo(&srate, &chans, &type);
|
||||||
|
@ -1143,46 +1171,53 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(BYTE *sfxdata, int le
|
||||||
{
|
{
|
||||||
Printf("Unsupported audio format: %s, %s\n", GetChannelConfigName(chans),
|
Printf("Unsupported audio format: %s, %s\n", GetChannelConfigName(chans),
|
||||||
GetSampleTypeName(type));
|
GetSampleTypeName(type));
|
||||||
delete decoder;
|
|
||||||
return std::make_pair(retval, true);
|
return std::make_pair(retval, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray<char> data = decoder->readAll();
|
TArray<char> data = decoder->readAll();
|
||||||
if(chans != ChannelConfig_Mono && monoize)
|
if(chans != ChannelConfig_Mono && monoize)
|
||||||
{
|
{
|
||||||
// TODO: Handle this better if ChannelConfig ever gets more channel configurations.
|
size_t chancount = GetChannelCount(chans);
|
||||||
size_t frames = data.Size() / 2 / (type == SampleType_Int16 ? 2 : 1);
|
size_t frames = data.Size() / chancount /
|
||||||
|
(type == SampleType_Int16 ? 2 : 1);
|
||||||
if(type == SampleType_Int16)
|
if(type == SampleType_Int16)
|
||||||
{
|
{
|
||||||
short *sfxdata = (short*)&data[0];
|
short *sfxdata = (short*)&data[0];
|
||||||
for(size_t i = 0;i < frames;i++)
|
for(size_t i = 0;i < frames;i++)
|
||||||
sfxdata[i] = (sfxdata[i*2 + 0]-0 + sfxdata[i*2 + 1]-0)/2;
|
{
|
||||||
|
int sum = 0;
|
||||||
|
for(size_t c = 0;c < chancount;c++)
|
||||||
|
sum += sfxdata[i*chancount + c];
|
||||||
|
sfxdata[i] = sum / chancount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(type == SampleType_UInt8)
|
else if(type == SampleType_UInt8)
|
||||||
{
|
{
|
||||||
BYTE *sfxdata = (BYTE*)&data[0];
|
BYTE *sfxdata = (BYTE*)&data[0];
|
||||||
for(size_t i = 0;i < frames;i++)
|
for(size_t i = 0;i < frames;i++)
|
||||||
sfxdata[i] = (sfxdata[i*2 + 0]-128 + sfxdata[i*2 + 1]-128)/2 + 128;
|
{
|
||||||
|
int sum = 0;
|
||||||
|
for(size_t c = 0;c < chancount;c++)
|
||||||
|
sum += sfxdata[i*chancount + c] - 128;
|
||||||
|
sfxdata[i] = (sum / chancount) + 128;
|
||||||
}
|
}
|
||||||
data.Resize(data.Size()/2);
|
}
|
||||||
|
data.Resize(data.Size()/chancount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALenum err;
|
||||||
ALuint buffer = 0;
|
ALuint buffer = 0;
|
||||||
alGenBuffers(1, &buffer);
|
alGenBuffers(1, &buffer);
|
||||||
alBufferData(buffer, format, &data[0], data.Size(), srate);
|
alBufferData(buffer, format, &data[0], data.Size(), srate);
|
||||||
|
|
||||||
ALenum err;
|
|
||||||
if((err=getALError()) != AL_NO_ERROR)
|
if((err=getALError()) != AL_NO_ERROR)
|
||||||
{
|
{
|
||||||
Printf("Failed to buffer data: %s\n", alGetString(err));
|
Printf("Failed to buffer data: %s\n", alGetString(err));
|
||||||
alDeleteBuffers(1, &buffer);
|
alDeleteBuffers(1, &buffer);
|
||||||
getALError();
|
getALError();
|
||||||
delete decoder;
|
|
||||||
return std::make_pair(retval, true);
|
return std::make_pair(retval, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
retval.data = MAKE_PTRID(buffer);
|
retval.data = MAKE_PTRID(buffer);
|
||||||
delete decoder;
|
|
||||||
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1262,6 +1297,8 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
||||||
alSourcef(source, AL_ROLLOFF_FACTOR, 0.f);
|
alSourcef(source, AL_ROLLOFF_FACTOR, 0.f);
|
||||||
alSourcef(source, AL_MAX_GAIN, SfxVolume);
|
alSourcef(source, AL_MAX_GAIN, SfxVolume);
|
||||||
alSourcef(source, AL_GAIN, SfxVolume*vol);
|
alSourcef(source, AL_GAIN, SfxVolume*vol);
|
||||||
|
if(AL.EXT_SOURCE_RADIUS)
|
||||||
|
alSourcef(source, AL_SOURCE_RADIUS, 0.f);
|
||||||
|
|
||||||
if(EnvSlot)
|
if(EnvSlot)
|
||||||
{
|
{
|
||||||
|
@ -1282,7 +1319,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
||||||
else
|
else
|
||||||
alSourcef(source, AL_PITCH, PITCH(pitch));
|
alSourcef(source, AL_PITCH, PITCH(pitch));
|
||||||
|
|
||||||
if(!reuse_chan)
|
if(!reuse_chan || reuse_chan->StartTime.AsOne == 0)
|
||||||
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1290,8 +1327,11 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
||||||
alSourcef(source, AL_SEC_OFFSET, reuse_chan->StartTime.Lo/1000.f);
|
alSourcef(source, AL_SEC_OFFSET, reuse_chan->StartTime.Lo/1000.f);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// FIXME: set offset based on the current time and the StartTime
|
float offset = std::chrono::duration_cast<std::chrono::duration<float>>(
|
||||||
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
std::chrono::steady_clock::now().time_since_epoch() -
|
||||||
|
std::chrono::steady_clock::time_point::duration(reuse_chan->StartTime.AsOne)
|
||||||
|
).count();
|
||||||
|
if(offset > 0.f) alSourcef(source, AL_SEC_OFFSET, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(getALError() != AL_NO_ERROR)
|
if(getALError() != AL_NO_ERROR)
|
||||||
|
@ -1321,7 +1361,6 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
||||||
chan->Rolloff.RolloffType = ROLLOFF_Log;
|
chan->Rolloff.RolloffType = ROLLOFF_Log;
|
||||||
chan->Rolloff.RolloffFactor = 0.f;
|
chan->Rolloff.RolloffFactor = 0.f;
|
||||||
chan->Rolloff.MinDistance = 1.f;
|
chan->Rolloff.MinDistance = 1.f;
|
||||||
chan->DistanceScale = 1.f;
|
|
||||||
chan->DistanceSqr = 0.f;
|
chan->DistanceSqr = 0.f;
|
||||||
chan->ManualRolloff = false;
|
chan->ManualRolloff = false;
|
||||||
|
|
||||||
|
@ -1404,7 +1443,16 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale);
|
float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale);
|
||||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
||||||
}
|
}
|
||||||
if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
if(AL.EXT_SOURCE_RADIUS)
|
||||||
|
{
|
||||||
|
/* Since the OpenAL distance is decoupled from the sound's distance, get the OpenAL
|
||||||
|
* distance that corresponds to the area radius. */
|
||||||
|
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ?
|
||||||
|
// Clamp in case the max distance is <= the area radius
|
||||||
|
1.f/MAX<float>(GetRolloff(rolloff, AREA_SOUND_RADIUS), 0.00001f) : 0.f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||||
{
|
{
|
||||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
|
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
|
||||||
float a = sqrtf(dist_sqr) / AREA_SOUND_RADIUS;
|
float a = sqrtf(dist_sqr) / AREA_SOUND_RADIUS;
|
||||||
|
@ -1414,9 +1462,14 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
|
|
||||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FVector3 dir = pos;
|
||||||
|
if(AL.EXT_SOURCE_RADIUS)
|
||||||
|
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ? AREA_SOUND_RADIUS : 0.f);
|
||||||
else if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
else if((chanflags&SNDF_AREA) && dist_sqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||||
{
|
{
|
||||||
FVector3 dir = pos - listener->position;
|
dir -= listener->position;
|
||||||
|
|
||||||
float mindist = rolloff->MinDistance/distscale;
|
float mindist = rolloff->MinDistance/distscale;
|
||||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
|
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
|
||||||
|
@ -1424,10 +1477,9 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
dir = amb + (dir-amb)*a;
|
dir = amb + (dir-amb)*a;
|
||||||
|
|
||||||
dir += listener->position;
|
dir += listener->position;
|
||||||
|
}
|
||||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
|
||||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||||
alSource3f(source, AL_DIRECTION, 0.f, 0.f, 0.f);
|
alSource3f(source, AL_DIRECTION, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
|
@ -1456,7 +1508,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
else
|
else
|
||||||
alSourcef(source, AL_PITCH, PITCH(pitch));
|
alSourcef(source, AL_PITCH, PITCH(pitch));
|
||||||
|
|
||||||
if(!reuse_chan)
|
if(!reuse_chan || reuse_chan->StartTime.AsOne == 0)
|
||||||
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
alSourcef(source, AL_SEC_OFFSET, 0.f);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1464,8 +1516,11 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
alSourcef(source, AL_SEC_OFFSET, reuse_chan->StartTime.Lo/1000.f);
|
alSourcef(source, AL_SEC_OFFSET, reuse_chan->StartTime.Lo/1000.f);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// FIXME: set offset based on the current time and the StartTime
|
float offset = std::chrono::duration_cast<std::chrono::duration<float>>(
|
||||||
alSourcef(source, AL_SAMPLE_OFFSET, 0.f);
|
std::chrono::steady_clock::now().time_since_epoch() -
|
||||||
|
std::chrono::steady_clock::time_point::duration(reuse_chan->StartTime.AsOne)
|
||||||
|
).count();
|
||||||
|
if(offset > 0.f) alSourcef(source, AL_SEC_OFFSET, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(getALError() != AL_NO_ERROR)
|
if(getALError() != AL_NO_ERROR)
|
||||||
|
@ -1493,7 +1548,6 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
else chan->SysChannel = MAKE_PTRID(source);
|
else chan->SysChannel = MAKE_PTRID(source);
|
||||||
|
|
||||||
chan->Rolloff = *rolloff;
|
chan->Rolloff = *rolloff;
|
||||||
chan->DistanceScale = distscale;
|
|
||||||
chan->DistanceSqr = dist_sqr;
|
chan->DistanceSqr = dist_sqr;
|
||||||
chan->ManualRolloff = manualRolloff;
|
chan->ManualRolloff = manualRolloff;
|
||||||
|
|
||||||
|
@ -1579,10 +1633,20 @@ void OpenALSoundRenderer::SetInactive(SoundRenderer::EInactiveState state)
|
||||||
{
|
{
|
||||||
case SoundRenderer::INACTIVE_Active:
|
case SoundRenderer::INACTIVE_Active:
|
||||||
alListenerf(AL_GAIN, 1.0f);
|
alListenerf(AL_GAIN, 1.0f);
|
||||||
|
if(ALC.SOFT_pause_device)
|
||||||
|
{
|
||||||
|
alcDeviceResumeSOFT(Device);
|
||||||
|
getALCError(Device);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* FIXME: This doesn't stop anything. */
|
|
||||||
case SoundRenderer::INACTIVE_Complete:
|
case SoundRenderer::INACTIVE_Complete:
|
||||||
|
if(ALC.SOFT_pause_device)
|
||||||
|
{
|
||||||
|
alcDevicePauseSOFT(Device);
|
||||||
|
getALCError(Device);
|
||||||
|
}
|
||||||
|
/* fall-through */
|
||||||
case SoundRenderer::INACTIVE_Mute:
|
case SoundRenderer::INACTIVE_Mute:
|
||||||
alListenerf(AL_GAIN, 0.0f);
|
alListenerf(AL_GAIN, 0.0f);
|
||||||
break;
|
break;
|
||||||
|
@ -1631,26 +1695,26 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
||||||
if(chan == NULL || chan->SysChannel == NULL)
|
if(chan == NULL || chan->SysChannel == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
alDeferUpdatesSOFT();
|
|
||||||
|
|
||||||
FVector3 dir = pos - listener->position;
|
FVector3 dir = pos - listener->position;
|
||||||
chan->DistanceSqr = (float)dir.LengthSquared();
|
chan->DistanceSqr = (float)dir.LengthSquared();
|
||||||
|
|
||||||
if(chan->ManualRolloff)
|
if(chan->ManualRolloff)
|
||||||
{
|
{
|
||||||
if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f)))
|
if(!AL.EXT_SOURCE_RADIUS && areasound &&
|
||||||
{
|
chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||||
float gain = GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr) * chan->DistanceScale);
|
|
||||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
|
||||||
}
|
|
||||||
if(areasound && chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
|
||||||
{
|
{
|
||||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
|
FVector3 amb(0.f, !(dir.Y>=0.f) ? -1.f : 1.f, 0.f);
|
||||||
float a = sqrtf(chan->DistanceSqr) / AREA_SOUND_RADIUS;
|
float a = sqrtf(chan->DistanceSqr) / AREA_SOUND_RADIUS;
|
||||||
dir = amb + (dir-amb)*a;
|
dir = amb + (dir-amb)*a;
|
||||||
}
|
}
|
||||||
|
if(dir.DoesNotApproximatelyEqual(FVector3(0.f, 0.f, 0.f)))
|
||||||
|
{
|
||||||
|
float gain = GetRolloff(&chan->Rolloff, sqrtf(chan->DistanceSqr)*chan->DistanceScale);
|
||||||
|
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
||||||
}
|
}
|
||||||
else if(areasound && chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
}
|
||||||
|
else if(!AL.EXT_SOURCE_RADIUS && areasound &&
|
||||||
|
chan->DistanceSqr < AREA_SOUND_RADIUS*AREA_SOUND_RADIUS)
|
||||||
{
|
{
|
||||||
float mindist = chan->Rolloff.MinDistance / chan->DistanceScale;
|
float mindist = chan->Rolloff.MinDistance / chan->DistanceScale;
|
||||||
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
|
FVector3 amb(0.f, !(dir.Y>=0.f) ? -mindist : mindist, 0.f);
|
||||||
|
@ -1659,6 +1723,8 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
||||||
}
|
}
|
||||||
dir += listener->position;
|
dir += listener->position;
|
||||||
|
|
||||||
|
alDeferUpdatesSOFT();
|
||||||
|
|
||||||
ALuint source = GET_PTRID(chan->SysChannel);
|
ALuint source = GET_PTRID(chan->SysChannel);
|
||||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
||||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||||
|
@ -1802,7 +1868,7 @@ void OpenALSoundRenderer::MarkStartTime(FISoundChannel *chan)
|
||||||
{
|
{
|
||||||
// FIXME: Get current time (preferably from the audio clock, but the system
|
// FIXME: Get current time (preferably from the audio clock, but the system
|
||||||
// time will have to do)
|
// time will have to do)
|
||||||
chan->StartTime.AsOne = 0;
|
chan->StartTime.AsOne = std::chrono::steady_clock::now().time_since_epoch().count();
|
||||||
}
|
}
|
||||||
|
|
||||||
float OpenALSoundRenderer::GetAudibility(FISoundChannel *chan)
|
float OpenALSoundRenderer::GetAudibility(FISoundChannel *chan)
|
||||||
|
|
|
@ -58,6 +58,11 @@
|
||||||
#define AL_FORMAT_71CHN32 0x1212
|
#define AL_FORMAT_71CHN32 0x1212
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef AL_EXT_SOURCE_RADIUS
|
||||||
|
#define AL_EXT_SOURCE_RADIUS 1
|
||||||
|
#define AL_SOURCE_RADIUS 0x1031
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "efx.h"
|
#include "efx.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,9 +129,11 @@ private:
|
||||||
struct {
|
struct {
|
||||||
bool EXT_EFX;
|
bool EXT_EFX;
|
||||||
bool EXT_disconnect;
|
bool EXT_disconnect;
|
||||||
|
bool SOFT_pause_device;
|
||||||
} ALC;
|
} ALC;
|
||||||
struct {
|
struct {
|
||||||
bool EXT_source_distance_model;
|
bool EXT_source_distance_model;
|
||||||
|
bool EXT_SOURCE_RADIUS;
|
||||||
bool SOFT_deferred_updates;
|
bool SOFT_deferred_updates;
|
||||||
bool SOFT_loop_points;
|
bool SOFT_loop_points;
|
||||||
} AL;
|
} AL;
|
||||||
|
@ -174,6 +181,9 @@ private:
|
||||||
ALvoid (AL_APIENTRY*alDeferUpdatesSOFT)(void);
|
ALvoid (AL_APIENTRY*alDeferUpdatesSOFT)(void);
|
||||||
ALvoid (AL_APIENTRY*alProcessUpdatesSOFT)(void);
|
ALvoid (AL_APIENTRY*alProcessUpdatesSOFT)(void);
|
||||||
|
|
||||||
|
void (ALC_APIENTRY*alcDevicePauseSOFT)(ALCdevice *device);
|
||||||
|
void (ALC_APIENTRY*alcDeviceResumeSOFT)(ALCdevice *device);
|
||||||
|
|
||||||
void LoadReverb(const ReverbContainer *env);
|
void LoadReverb(const ReverbContainer *env);
|
||||||
void PurgeStoppedSources();
|
void PurgeStoppedSources();
|
||||||
static FSoundChan *FindLowestChannel();
|
static FSoundChan *FindLowestChannel();
|
||||||
|
|
|
@ -2433,12 +2433,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SpawnItem)
|
||||||
ACTION_RETURN_BOOL(true);
|
ACTION_RETURN_BOOL(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (distance == 0)
|
|
||||||
{
|
|
||||||
// use the minimum distance that does not result in an overlap
|
|
||||||
distance = (self->radius + GetDefaultByType(missile)->radius);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ACTION_CALL_FROM_WEAPON())
|
if (ACTION_CALL_FROM_WEAPON())
|
||||||
{
|
{
|
||||||
// Used from a weapon, so use some ammo
|
// Used from a weapon, so use some ammo
|
||||||
|
|
Loading…
Reference in a new issue