diff options
-rw-r--r-- | al/extension.cpp | 12 | ||||
-rw-r--r-- | al/state.cpp | 2 | ||||
-rw-r--r-- | alc/context.cpp | 166 | ||||
-rw-r--r-- | alc/context.h | 7 |
4 files changed, 85 insertions, 102 deletions
diff --git a/al/extension.cpp b/al/extension.cpp index 3ead0af8..dbaf4d5f 100644 --- a/al/extension.cpp +++ b/al/extension.cpp @@ -46,18 +46,10 @@ START_API_FUNC } size_t len{strlen(extName)}; - const char *ptr{context->mExtensionList}; - while(ptr && *ptr) + for(std::string_view ext : context->mExtensions) { - if(al::strncasecmp(ptr, extName, len) == 0 && (ptr[len] == '\0' || isspace(ptr[len]))) + if(len == ext.length() && al::strncasecmp(ext.data(), extName, len) == 0) return AL_TRUE; - - if((ptr=strchr(ptr, ' ')) != nullptr) - { - do { - ++ptr; - } while(isspace(*ptr)); - } } return AL_FALSE; diff --git a/al/state.cpp b/al/state.cpp index fb3186c7..cb2afd6c 100644 --- a/al/state.cpp +++ b/al/state.cpp @@ -560,7 +560,7 @@ START_API_FUNC break; case AL_EXTENSIONS: - value = context->mExtensionList; + value = context->mExtensionsString.c_str(); break; case AL_NO_ERROR: diff --git a/alc/context.cpp b/alc/context.cpp index 2fbf67af..d920d4b6 100644 --- a/alc/context.cpp +++ b/alc/context.cpp @@ -11,6 +11,7 @@ #include <numeric> #include <stddef.h> #include <stdexcept> +#include <string_view> #include <utility> #include "AL/efx.h" @@ -48,48 +49,52 @@ using namespace std::placeholders; using voidp = void*; /* Default context extensions */ -constexpr ALchar alExtList[] = - "AL_EXT_ALAW " - "AL_EXT_BFORMAT " - "AL_EXTX_debug " - "AL_EXT_DOUBLE " - "AL_EXT_EXPONENT_DISTANCE " - "AL_EXT_FLOAT32 " - "AL_EXT_IMA4 " - "AL_EXT_LINEAR_DISTANCE " - "AL_EXT_MCFORMATS " - "AL_EXT_MULAW " - "AL_EXT_MULAW_BFORMAT " - "AL_EXT_MULAW_MCFORMATS " - "AL_EXT_OFFSET " - "AL_EXT_source_distance_model " - "AL_EXT_SOURCE_RADIUS " - "AL_EXT_STATIC_BUFFER " - "AL_EXT_STEREO_ANGLES " - "AL_LOKI_quadriphonic " - "AL_SOFT_bformat_ex " - "AL_SOFTX_bformat_hoa " - "AL_SOFT_block_alignment " - "AL_SOFT_buffer_length_query " - "AL_SOFT_callback_buffer " - "AL_SOFTX_convolution_reverb " - "AL_SOFT_deferred_updates " - "AL_SOFT_direct_channels " - "AL_SOFT_direct_channels_remix " - "AL_SOFT_effect_target " - "AL_SOFT_events " - "AL_SOFT_gain_clamp_ex " - "AL_SOFTX_hold_on_disconnect " - "AL_SOFT_loop_points " - "AL_SOFTX_map_buffer " - "AL_SOFT_MSADPCM " - "AL_SOFT_source_latency " - "AL_SOFT_source_length " - "AL_SOFT_source_resampler " - "AL_SOFT_source_spatialize " - "AL_SOFT_source_start_delay " - "AL_SOFT_UHJ " - "AL_SOFT_UHJ_ex"; +std::vector<std::string_view> getContextExtensions() noexcept +{ + return std::vector<std::string_view>{ + "AL_EXT_ALAW", + "AL_EXT_BFORMAT", + "AL_EXTX_debug", + "AL_EXT_DOUBLE", + "AL_EXT_EXPONENT_DISTANCE", + "AL_EXT_FLOAT32", + "AL_EXT_IMA4", + "AL_EXT_LINEAR_DISTANCE", + "AL_EXT_MCFORMATS", + "AL_EXT_MULAW", + "AL_EXT_MULAW_BFORMAT", + "AL_EXT_MULAW_MCFORMATS", + "AL_EXT_OFFSET", + "AL_EXT_source_distance_model", + "AL_EXT_SOURCE_RADIUS", + "AL_EXT_STATIC_BUFFER", + "AL_EXT_STEREO_ANGLES", + "AL_LOKI_quadriphonic", + "AL_SOFT_bformat_ex", + "AL_SOFTX_bformat_hoa", + "AL_SOFT_block_alignment", + "AL_SOFT_buffer_length_query", + "AL_SOFT_callback_buffer", + "AL_SOFTX_convolution_reverb", + "AL_SOFT_deferred_updates", + "AL_SOFT_direct_channels", + "AL_SOFT_direct_channels_remix", + "AL_SOFT_effect_target", + "AL_SOFT_events", + "AL_SOFT_gain_clamp_ex", + "AL_SOFTX_hold_on_disconnect", + "AL_SOFT_loop_points", + "AL_SOFTX_map_buffer", + "AL_SOFT_MSADPCM", + "AL_SOFT_source_latency", + "AL_SOFT_source_length", + "AL_SOFT_source_resampler", + "AL_SOFT_source_spatialize", + "AL_SOFT_source_start_delay", + "AL_SOFT_UHJ", + "AL_SOFT_UHJ_ex", + }; +} } // namespace @@ -179,26 +184,41 @@ void ALCcontext::init() mCurrentVoiceChange.store(cur, std::memory_order_relaxed); } - mExtensionList = alExtList; + mExtensions = getContextExtensions(); if(sBufferSubDataCompat) { - std::string extlist{mExtensionList}; - - const auto pos = extlist.find("AL_EXT_SOURCE_RADIUS "); - if(pos != std::string::npos) - extlist.replace(pos, 20, "AL_SOFT_buffer_sub_data"); - else - extlist += " AL_SOFT_buffer_sub_data"; - - mExtensionListOverride = std::move(extlist); - mExtensionList = mExtensionListOverride.c_str(); + auto iter = std::find(mExtensions.begin(), mExtensions.end(), "AL_EXT_SOURCE_RADIUS"); + if(iter != mExtensions.end()) mExtensions.erase(iter); + /* TODO: Would be nice to sort this alphabetically. Needs case- + * insensitive searching. + */ + mExtensions.emplace_back("AL_SOFT_buffer_sub_data"); } #ifdef ALSOFT_EAX eax_initialize_extensions(); #endif // ALSOFT_EAX + if(!mExtensions.empty()) + { + const size_t len{std::accumulate(mExtensions.cbegin()+1, mExtensions.cend(), + mExtensions.front().length(), + [](size_t current, std::string_view ext) noexcept + { return current + ext.length() + 1; })}; + + std::string extensions; + extensions.reserve(len); + extensions += mExtensions.front(); + for(std::string_view ext : al::span{mExtensions}.subspan<1>()) + { + extensions += ' '; + extensions += ext; + } + + mExtensionsString = std::move(extensions); + } + mParams.Position = alu::Vector{0.0f, 0.0f, 0.0f, 1.0f}; mParams.Matrix = alu::Matrix::Identity(); mParams.Velocity = alu::Vector{}; @@ -457,43 +477,15 @@ void ALCcontext::eax_initialize_extensions() if(!eax_g_is_enabled) return; - const auto string_max_capacity = - std::strlen(mExtensionList) + 1 + - std::strlen(eax1_ext_name) + 1 + - std::strlen(eax2_ext_name) + 1 + - std::strlen(eax3_ext_name) + 1 + - std::strlen(eax4_ext_name) + 1 + - std::strlen(eax5_ext_name) + 1 + - std::strlen(eax_x_ram_ext_name) + 1; - - std::string extlist; - extlist.reserve(string_max_capacity); - + mExtensions.emplace(mExtensions.begin(), eax_x_ram_ext_name); if(eaxIsCapable()) { - extlist += eax1_ext_name; - extlist += ' '; - - extlist += eax2_ext_name; - extlist += ' '; - - extlist += eax3_ext_name; - extlist += ' '; - - extlist += eax4_ext_name; - extlist += ' '; - - extlist += eax5_ext_name; - extlist += ' '; + mExtensions.emplace(mExtensions.begin(), eax5_ext_name); + mExtensions.emplace(mExtensions.begin(), eax4_ext_name); + mExtensions.emplace(mExtensions.begin(), eax3_ext_name); + mExtensions.emplace(mExtensions.begin(), eax2_ext_name); + mExtensions.emplace(mExtensions.begin(), eax1_ext_name); } - - extlist += eax_x_ram_ext_name; - extlist += ' '; - - extlist += mExtensionList; - - mExtensionListOverride = std::move(extlist); - mExtensionList = mExtensionListOverride.c_str(); } void ALCcontext::eax_initialize() diff --git a/alc/context.h b/alc/context.h index 402794eb..acbb3788 100644 --- a/alc/context.h +++ b/alc/context.h @@ -7,7 +7,7 @@ #include <mutex> #include <stdint.h> #include <string> -#include <unordered_map> +#include <string_view> #include <utility> #include "AL/al.h" @@ -143,9 +143,8 @@ struct ALCcontext : public al::intrusive_ref<ALCcontext>, ContextBase { /* Default effect slot */ std::unique_ptr<ALeffectslot> mDefaultSlot; - const char *mExtensionList{nullptr}; - - std::string mExtensionListOverride{}; + std::vector<std::string_view> mExtensions; + std::string mExtensionsString{}; ALCcontext(al::intrusive_ptr<ALCdevice> device, ContextFlagBitset flags); |