Skip to content

Commit dc99a52

Browse files
committed
extensions: Implemented AL_EXT_source_distance_model.
Reference Issue #36.
1 parent ac516f5 commit dc99a52

File tree

1 file changed

+47
-5
lines changed

1 file changed

+47
-5
lines changed

mojoal.c

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@
9494
#define ALC_CONNECTED 0x313
9595
#endif
9696

97+
// AL_EXT_source_distance_model support...
98+
#ifndef AL_SOURCE_DISTANCE_MODEL
99+
#define AL_SOURCE_DISTANCE_MODEL 0x200
100+
#endif
97101

98102
/*
99103
The locking strategy for this OpenAL implementation:
@@ -516,6 +520,7 @@ struct SDL_ALIGNED(16) ALsource // aligned to 16 bytes for SIMD support
516520
ALfloat cone_inner_angle;
517521
ALfloat cone_outer_angle;
518522
ALfloat cone_outer_gain;
523+
ALenum distance_model;
519524
ALbuffer *buffer;
520525
SDL_AudioStream *stream; // for conversion, resampling, pitch, etc. ALL DATA GOES THROUGH HERE NOW.
521526
SDL_AtomicInt total_queued_buffers; // everything queued, playing and processed. AL_BUFFERS_QUEUED value.
@@ -599,6 +604,7 @@ struct ALCcontext_struct
599604
ALCsizei attributes_count;
600605

601606
ALCboolean recalc;
607+
ALCboolean source_distance_model;
602608
ALenum distance_model;
603609
ALfloat doppler_factor;
604610
ALfloat doppler_velocity;
@@ -762,6 +768,7 @@ static ALfloat calculate_distance_attenuation(const ALCcontext *ctx, const ALsou
762768
// error in it. In this case, there is no attenuation for that source."
763769
FIXME("check divisions by zero");
764770

771+
const ALenum distance_model = ctx->source_distance_model ? src->distance_model : ctx->distance_model;
765772
switch (ctx->distance_model) {
766773
case AL_INVERSE_DISTANCE_CLAMPED:
767774
distance = SDL_min(SDL_max(distance, src->reference_distance), src->max_distance);
@@ -989,7 +996,8 @@ static void calculate_distance_attenuation_and_angle(const ALCcontext *ctx, cons
989996
static void calculate_channel_gains(const ALCcontext *ctx, ALsource *src)
990997
{
991998
// rolloff==0.0f makes all distance models result in 1.0f, and we never spatialize non-mono sources, per the AL spec.
992-
const ALboolean spatialize = (ctx->distance_model != AL_NONE) &&
999+
const ALenum distance_model = ctx->source_distance_model ? src->distance_model : ctx->distance_model;
1000+
const ALboolean spatialize = (distance_model != AL_NONE) &&
9931001
(src->queue_channels == 1) &&
9941002
(src->rolloff_factor != 0.0f);
9951003

@@ -1895,7 +1903,8 @@ static ALCenum null_device_error = ALC_NO_ERROR;
18951903

18961904
#define AL_EXTENSION_ITEMS \
18971905
AL_EXTENSION_ITEM(AL_EXT_FLOAT32) \
1898-
AL_EXTENSION_ITEM(AL_EXT_32bit_formats)
1906+
AL_EXTENSION_ITEM(AL_EXT_32bit_formats) \
1907+
AL_EXTENSION_ITEM(AL_EXT_source_distance_model)
18991908

19001909

19011910
static void set_alc_error(ALCdevice *device, const ALCenum error)
@@ -2963,23 +2972,54 @@ static void _alDistanceModel(const ALenum model)
29632972
ENTRYPOINTVOID(alDistanceModel,(ALenum model),(model))
29642973

29652974

2975+
static void enable_disable_toggle(const ALenum capability, const ALboolean toggle)
2976+
{
2977+
ALCcontext *ctx = get_current_context();
2978+
if (!ctx) {
2979+
set_al_error(ctx, AL_INVALID_OPERATION);
2980+
return;
2981+
}
2982+
2983+
switch (capability)
2984+
{
2985+
case AL_SOURCE_DISTANCE_MODEL:
2986+
ctx->source_distance_model = toggle ? ALC_TRUE : ALC_FALSE;
2987+
context_needs_recalc(ctx);
2988+
break;
2989+
2990+
default: break;
2991+
}
2992+
set_al_error(ctx, AL_INVALID_ENUM);
2993+
}
2994+
29662995
static void _alEnable(const ALenum capability)
29672996
{
2968-
set_al_error(get_current_context(), AL_INVALID_ENUM); // nothing in core OpenAL 1.1 uses this
2997+
enable_disable_toggle(capability, AL_TRUE);
29692998
}
29702999
ENTRYPOINTVOID(alEnable,(ALenum capability),(capability))
29713000

29723001

29733002
static void _alDisable(const ALenum capability)
29743003
{
2975-
set_al_error(get_current_context(), AL_INVALID_ENUM); // nothing in core OpenAL 1.1 uses this
3004+
enable_disable_toggle(capability, AL_FALSE);
29763005
}
29773006
ENTRYPOINTVOID(alDisable,(ALenum capability),(capability))
29783007

29793008

29803009
static ALboolean _alIsEnabled(const ALenum capability)
29813010
{
2982-
set_al_error(get_current_context(), AL_INVALID_ENUM); // nothing in core OpenAL 1.1 uses this
3011+
ALCcontext *ctx = get_current_context();
3012+
if (!ctx) {
3013+
set_al_error(ctx, AL_INVALID_OPERATION);
3014+
return AL_FALSE;
3015+
}
3016+
3017+
switch (capability)
3018+
{
3019+
case AL_SOURCE_DISTANCE_MODEL: return ctx->source_distance_model;
3020+
default: break;
3021+
}
3022+
set_al_error(ctx, AL_INVALID_ENUM);
29833023
return AL_FALSE;
29843024
}
29853025
ENTRYPOINT(ALboolean,alIsEnabled,(ALenum capability),(capability))
@@ -3300,6 +3340,7 @@ static ALenum _alGetEnumValue(const ALchar *enumname)
33003340
ENUM_TEST(AL_FORMAT_STEREO_FLOAT32);
33013341
ENUM_TEST(AL_FORMAT_MONO_I32);
33023342
ENUM_TEST(AL_FORMAT_STEREO_I32);
3343+
ENUM_TEST(AL_SOURCE_DISTANCE_MODEL);
33033344
#undef ENUM_TEST
33043345

33053346
set_al_error(ctx, AL_INVALID_VALUE);
@@ -3727,6 +3768,7 @@ static void _alGenSources(const ALsizei n, ALuint *names)
37273768
src->pitch = 1.0f;
37283769
src->cone_inner_angle = 360.0f;
37293770
src->cone_outer_angle = 360.0f;
3771+
src->distance_model = AL_INVERSE_DISTANCE_CLAMPED;
37303772
source_needs_recalc(src);
37313773
src->allocated = AL_TRUE; // we officially own it.
37323774
}

0 commit comments

Comments
 (0)