|
94 | 94 | #define ALC_CONNECTED 0x313 |
95 | 95 | #endif |
96 | 96 |
|
| 97 | +// AL_EXT_source_distance_model support... |
| 98 | +#ifndef AL_SOURCE_DISTANCE_MODEL |
| 99 | +#define AL_SOURCE_DISTANCE_MODEL 0x200 |
| 100 | +#endif |
97 | 101 |
|
98 | 102 | /* |
99 | 103 | The locking strategy for this OpenAL implementation: |
@@ -516,6 +520,7 @@ struct SDL_ALIGNED(16) ALsource // aligned to 16 bytes for SIMD support |
516 | 520 | ALfloat cone_inner_angle; |
517 | 521 | ALfloat cone_outer_angle; |
518 | 522 | ALfloat cone_outer_gain; |
| 523 | + ALenum distance_model; |
519 | 524 | ALbuffer *buffer; |
520 | 525 | SDL_AudioStream *stream; // for conversion, resampling, pitch, etc. ALL DATA GOES THROUGH HERE NOW. |
521 | 526 | SDL_AtomicInt total_queued_buffers; // everything queued, playing and processed. AL_BUFFERS_QUEUED value. |
@@ -599,6 +604,7 @@ struct ALCcontext_struct |
599 | 604 | ALCsizei attributes_count; |
600 | 605 |
|
601 | 606 | ALCboolean recalc; |
| 607 | + ALCboolean source_distance_model; |
602 | 608 | ALenum distance_model; |
603 | 609 | ALfloat doppler_factor; |
604 | 610 | ALfloat doppler_velocity; |
@@ -762,6 +768,7 @@ static ALfloat calculate_distance_attenuation(const ALCcontext *ctx, const ALsou |
762 | 768 | // error in it. In this case, there is no attenuation for that source." |
763 | 769 | FIXME("check divisions by zero"); |
764 | 770 |
|
| 771 | + const ALenum distance_model = ctx->source_distance_model ? src->distance_model : ctx->distance_model; |
765 | 772 | switch (ctx->distance_model) { |
766 | 773 | case AL_INVERSE_DISTANCE_CLAMPED: |
767 | 774 | 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 |
989 | 996 | static void calculate_channel_gains(const ALCcontext *ctx, ALsource *src) |
990 | 997 | { |
991 | 998 | // 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) && |
993 | 1001 | (src->queue_channels == 1) && |
994 | 1002 | (src->rolloff_factor != 0.0f); |
995 | 1003 |
|
@@ -1895,7 +1903,8 @@ static ALCenum null_device_error = ALC_NO_ERROR; |
1895 | 1903 |
|
1896 | 1904 | #define AL_EXTENSION_ITEMS \ |
1897 | 1905 | 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) |
1899 | 1908 |
|
1900 | 1909 |
|
1901 | 1910 | static void set_alc_error(ALCdevice *device, const ALCenum error) |
@@ -2963,23 +2972,54 @@ static void _alDistanceModel(const ALenum model) |
2963 | 2972 | ENTRYPOINTVOID(alDistanceModel,(ALenum model),(model)) |
2964 | 2973 |
|
2965 | 2974 |
|
| 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 | + |
2966 | 2995 | static void _alEnable(const ALenum capability) |
2967 | 2996 | { |
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); |
2969 | 2998 | } |
2970 | 2999 | ENTRYPOINTVOID(alEnable,(ALenum capability),(capability)) |
2971 | 3000 |
|
2972 | 3001 |
|
2973 | 3002 | static void _alDisable(const ALenum capability) |
2974 | 3003 | { |
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); |
2976 | 3005 | } |
2977 | 3006 | ENTRYPOINTVOID(alDisable,(ALenum capability),(capability)) |
2978 | 3007 |
|
2979 | 3008 |
|
2980 | 3009 | static ALboolean _alIsEnabled(const ALenum capability) |
2981 | 3010 | { |
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); |
2983 | 3023 | return AL_FALSE; |
2984 | 3024 | } |
2985 | 3025 | ENTRYPOINT(ALboolean,alIsEnabled,(ALenum capability),(capability)) |
@@ -3300,6 +3340,7 @@ static ALenum _alGetEnumValue(const ALchar *enumname) |
3300 | 3340 | ENUM_TEST(AL_FORMAT_STEREO_FLOAT32); |
3301 | 3341 | ENUM_TEST(AL_FORMAT_MONO_I32); |
3302 | 3342 | ENUM_TEST(AL_FORMAT_STEREO_I32); |
| 3343 | + ENUM_TEST(AL_SOURCE_DISTANCE_MODEL); |
3303 | 3344 | #undef ENUM_TEST |
3304 | 3345 |
|
3305 | 3346 | set_al_error(ctx, AL_INVALID_VALUE); |
@@ -3727,6 +3768,7 @@ static void _alGenSources(const ALsizei n, ALuint *names) |
3727 | 3768 | src->pitch = 1.0f; |
3728 | 3769 | src->cone_inner_angle = 360.0f; |
3729 | 3770 | src->cone_outer_angle = 360.0f; |
| 3771 | + src->distance_model = AL_INVERSE_DISTANCE_CLAMPED; |
3730 | 3772 | source_needs_recalc(src); |
3731 | 3773 | src->allocated = AL_TRUE; // we officially own it. |
3732 | 3774 | } |
|
0 commit comments