diff options
author | Boris I. Bendovsky <[email protected]> | 2022-01-30 14:47:32 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2022-01-30 04:47:32 -0800 |
commit | 19ed994dc30ed84ea7cbbb5152577669fc25caf6 (patch) | |
tree | f68933bf8f778806618bd6c0b1bf9ced1b0ccf08 /al/eax_utils.h | |
parent | 619249371a40f03cf988d1f5750d643df797c485 (diff) |
Add EAX extensions (EAX 2.0-5.0, X-RAM) (#632)
* Add EAX extensions (EAX 2.0-5.0, X-RAM)
* Comment out C++17 leftovers
* Remove everything related to patching
* Update alsoftrc.sample
* Rewrite integration
* Fix GCC compilation under Linux
* Always reset EAX effect properties when loading it into FX slot
Diffstat (limited to 'al/eax_utils.h')
-rw-r--r-- | al/eax_utils.h | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/al/eax_utils.h b/al/eax_utils.h new file mode 100644 index 00000000..68e35fcd --- /dev/null +++ b/al/eax_utils.h @@ -0,0 +1,164 @@ +#ifndef EAX_UTILS_INCLUDED +#define EAX_UTILS_INCLUDED + + +#include <cstdint> + +#include <algorithm> +#include <string> +#include <type_traits> + + +struct ALCcontext; + + +struct EaxAlLowPassParam +{ + float gain; + float gain_hf; +}; // EaxAlLowPassParam + + +// Required to call macro `DO_UPDATEPROPS`. +class EaxAlContextWrapper +{ +public: + explicit EaxAlContextWrapper( + ALCcontext& al_context) noexcept + : + al_context_{&al_context} + { + } + + constexpr ALCcontext* get() noexcept + { + return al_context_; + } + + constexpr ALCcontext* operator->() noexcept + { + return al_context_; + } + + +private: + ALCcontext* al_context_; +}; // EaxAlContextWrapper + + +void eax_log_exception( + const char* message = nullptr) noexcept; + + +template< + typename TException, + typename TValue +> +void eax_validate_range( + const char* value_name, + const TValue& value, + const TValue& min_value, + const TValue& max_value) +{ + if (value >= min_value && value <= max_value) + { + return; + } + + const auto message = + std::string{value_name} + + " out of range (value: " + + std::to_string(value) + "; min: " + + std::to_string(min_value) + "; max: " + + std::to_string(max_value) + ")."; + + throw TException{message.c_str()}; +} + + +namespace detail +{ + + +template< + typename T +> +struct EaxIsBitFieldStruct +{ +private: + using yes = std::true_type; + using no = std::false_type; + + template< + typename U + > + static auto test(int) -> decltype(std::declval<typename U::EaxIsBitFieldStruct>(), yes{}); + + template< + typename + > + static no test(...); + + +public: + static constexpr auto value = std::is_same<decltype(test<T>(0)), yes>::value; +}; // EaxIsBitFieldStruct + + +template< + typename T, + typename TValue +> +inline bool eax_bit_fields_are_equal( + const T& lhs, + const T& rhs) noexcept +{ + static_assert(sizeof(T) == sizeof(TValue), "Invalid type size."); + + return reinterpret_cast<const TValue&>(lhs) == reinterpret_cast<const TValue&>(rhs); +} + + +} // namespace detail + + +template< + typename T, + std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0 +> +inline bool operator==( + const T& lhs, + const T& rhs) noexcept +{ + using Value = std::conditional_t< + sizeof(T) == 1, + std::uint8_t, + std::conditional_t< + sizeof(T) == 2, + std::uint16_t, + std::conditional_t< + sizeof(T) == 4, + std::uint32_t, + void + > + > + >; + + static_assert(!std::is_same<Value, void>::value, "Unsupported type."); + + return detail::eax_bit_fields_are_equal<T, Value>(lhs, rhs); +} + +template< + typename T, + std::enable_if_t<detail::EaxIsBitFieldStruct<T>::value, int> = 0 +> +inline bool operator!=( + const T& lhs, + const T& rhs) noexcept +{ + return !(lhs == rhs); +} + + +#endif // !EAX_UTILS_INCLUDED |